Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / remoting / android / java / src / org / chromium / chromoting / SessionAuthenticator.java
bloba18c2f463782a5a430a090b226c7908d05be9d07
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.chromoting;
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.content.DialogInterface;
10 import android.content.Intent;
11 import android.content.SharedPreferences;
12 import android.os.Build;
13 import android.view.KeyEvent;
14 import android.view.View;
15 import android.widget.CheckBox;
16 import android.widget.TextView;
17 import android.widget.Toast;
19 import org.chromium.chromoting.jni.JniInterface;
21 /**
22 * This class performs the user-interaction needed to authenticate the session connection. This
23 * includes showing the PIN prompt and requesting tokens for third-party authentication.
25 public class SessionAuthenticator {
26 /**
27 * Application context used for getting user preferences, displaying UI, and fetching
28 * third-party tokens.
30 private Chromoting mApplicationContext;
32 /** Provides the tokenUrlPatterns for this host during fetchThirdPartyTokens(). */
33 private HostInfo mHost;
35 /** Object for fetching OAuth2 access tokens from third party authorization servers. */
36 private ThirdPartyTokenFetcher mTokenFetcher;
38 public SessionAuthenticator(Chromoting context, HostInfo host) {
39 mApplicationContext = context;
40 mHost = host;
43 public void displayAuthenticationPrompt(boolean pairingSupported) {
44 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(mApplicationContext);
45 pinPrompt.setTitle(mApplicationContext.getString(R.string.title_authenticate));
46 pinPrompt.setMessage(mApplicationContext.getString(R.string.pin_message_android));
47 pinPrompt.setIcon(android.R.drawable.ic_lock_lock);
49 final View pinEntry =
50 mApplicationContext.getLayoutInflater().inflate(R.layout.pin_dialog, null);
51 pinPrompt.setView(pinEntry);
53 final TextView pinTextView = (TextView) pinEntry.findViewById(R.id.pin_dialog_text);
54 final CheckBox pinCheckBox = (CheckBox) pinEntry.findViewById(R.id.pin_dialog_check);
56 if (!pairingSupported) {
57 pinCheckBox.setChecked(false);
58 pinCheckBox.setVisibility(View.GONE);
61 pinPrompt.setPositiveButton(
62 R.string.connect_button, new DialogInterface.OnClickListener() {
63 @Override
64 public void onClick(DialogInterface dialog, int which) {
65 if (JniInterface.isConnected()) {
66 JniInterface.handleAuthenticationResponse(
67 String.valueOf(pinTextView.getText()),
68 pinCheckBox.isChecked(), Build.MODEL);
69 } else {
70 String message =
71 mApplicationContext.getString(R.string.error_network_error);
72 Toast.makeText(mApplicationContext, message, Toast.LENGTH_LONG).show();
75 });
77 pinPrompt.setNegativeButton(
78 R.string.cancel, new DialogInterface.OnClickListener() {
79 @Override
80 public void onClick(DialogInterface dialog, int which) {
81 JniInterface.disconnectFromHost();
83 });
85 final AlertDialog pinDialog = pinPrompt.create();
87 pinTextView.setOnEditorActionListener(
88 new TextView.OnEditorActionListener() {
89 @Override
90 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
91 // The user pressed enter on the keypad (equivalent to the connect button).
92 pinDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
93 pinDialog.dismiss();
94 return true;
96 });
98 pinDialog.setOnCancelListener(
99 new DialogInterface.OnCancelListener() {
100 @Override
101 public void onCancel(DialogInterface dialog) {
102 // The user backed out of the dialog (equivalent to the cancel button).
103 pinDialog.getButton(AlertDialog.BUTTON_NEGATIVE).performClick();
107 pinDialog.show();
110 /** Saves newly-received pairing credentials to permanent storage. */
111 public void commitPairingCredentials(String host, String id, String secret) {
112 // Empty |id| indicates that pairing needs to be removed.
113 if (id.isEmpty()) {
114 mApplicationContext.getPreferences(Activity.MODE_PRIVATE).edit()
115 .remove(host + "_id")
116 .remove(host + "_secret")
117 .apply();
118 } else {
119 mApplicationContext.getPreferences(Activity.MODE_PRIVATE).edit()
120 .putString(host + "_id", id)
121 .putString(host + "_secret", secret)
122 .apply();
126 public void fetchThirdPartyToken(String tokenUrl, String clientId, String scope) {
127 assert mTokenFetcher == null;
129 ThirdPartyTokenFetcher.Callback callback = new ThirdPartyTokenFetcher.Callback() {
130 @Override
131 public void onTokenFetched(String code, String accessToken) {
132 // The native client sends the OAuth authorization code to the host as the token so
133 // that the host can obtain the shared secret from the third party authorization
134 // server.
135 String token = code;
137 // The native client uses the OAuth access token as the shared secret to
138 // authenticate itself with the host using spake.
139 String sharedSecret = accessToken;
141 JniInterface.onThirdPartyTokenFetched(token, sharedSecret);
144 mTokenFetcher = new ThirdPartyTokenFetcher(mApplicationContext, mHost.getTokenUrlPatterns(),
145 callback);
146 mTokenFetcher.fetchToken(tokenUrl, clientId, scope);
149 public void onNewIntent(Intent intent) {
150 if (mTokenFetcher != null) {
151 if (mTokenFetcher.handleTokenFetched(intent)) {
152 mTokenFetcher = null;
157 /** Returns the pairing ID for the given host, or an empty string if not set. */
158 public String getPairingId(String hostId) {
159 SharedPreferences prefs = mApplicationContext.getPreferences(Activity.MODE_PRIVATE);
160 return prefs.getString(hostId + "_id", "");
163 /** Returns the pairing secret for the given host, or an empty string if not set. */
164 public String getPairingSecret(String hostId) {
165 SharedPreferences prefs = mApplicationContext.getPreferences(Activity.MODE_PRIVATE);
166 return prefs.getString(hostId + "_secret", "");