Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1263)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java

Issue 981783003: Pull authentication UX code out of JniInterface (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix-jni-initialization
Patch Set: Fix comment Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/android/java/src/org/chromium/chromoting/SessionConnector.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chromoting.jni; 5 package org.chromium.chromoting.jni;
6 6
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.content.Context; 7 import android.content.Context;
10 import android.content.DialogInterface;
11 import android.content.SharedPreferences;
12 import android.graphics.Bitmap; 8 import android.graphics.Bitmap;
13 import android.graphics.Point; 9 import android.graphics.Point;
14 import android.os.Build;
15 import android.os.Looper; 10 import android.os.Looper;
16 import android.util.Log; 11 import android.util.Log;
17 import android.view.KeyEvent;
18 import android.view.View;
19 import android.widget.CheckBox;
20 import android.widget.TextView;
21 import android.widget.Toast;
22 12
23 import org.chromium.base.CalledByNative; 13 import org.chromium.base.CalledByNative;
24 import org.chromium.base.JNINamespace; 14 import org.chromium.base.JNINamespace;
25 import org.chromium.chromoting.CapabilityManager; 15 import org.chromium.chromoting.CapabilityManager;
26 import org.chromium.chromoting.Chromoting;
27 import org.chromium.chromoting.R; 16 import org.chromium.chromoting.R;
17 import org.chromium.chromoting.SessionAuthenticator;
28 18
29 import java.nio.ByteBuffer; 19 import java.nio.ByteBuffer;
30 import java.nio.ByteOrder; 20 import java.nio.ByteOrder;
31 21
32 /** 22 /**
33 * Initializes the Chromium remoting library, and provides JNI calls into it. 23 * Initializes the Chromium remoting library, and provides JNI calls into it.
34 * All interaction with the native code is centralized in this class. 24 * All interaction with the native code is centralized in this class.
35 */ 25 */
36 @JNINamespace("remoting") 26 @JNINamespace("remoting")
37 public class JniInterface { 27 public class JniInterface {
38 /* 28 /*
39 * Library-loading state machine. 29 * Library-loading state machine.
40 */ 30 */
41 /** Whether the library has been loaded. Accessed on the UI thread. */ 31 /** Whether the library has been loaded. Accessed on the UI thread. */
42 private static boolean sLoaded = false; 32 private static boolean sLoaded = false;
43 33
44 /** The application context. Accessed on the UI thread. */ 34 /** Used for authentication-related UX during connection. Accessed on the UI thread. */
45 private static Activity sContext = null; 35 private static SessionAuthenticator sAuthenticator;
46 36
47 /** Interface used for connection state notifications. */ 37 /** Interface used for connection state notifications. */
48 public interface ConnectionListener { 38 public interface ConnectionListener {
49 /** 39 /**
50 * This enum must match the C++ enumeration remoting::protocol::Connecti onToHost::State. 40 * This enum must match the C++ enumeration remoting::protocol::Connecti onToHost::State.
51 */ 41 */
52 public enum State { 42 public enum State {
53 INITIALIZING(0), 43 INITIALIZING(0),
54 CONNECTING(1), 44 CONNECTING(1),
55 AUTHENTICATED(2), 45 AUTHENTICATED(2),
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 private static Bitmap sCursorBitmap = null; 135 private static Bitmap sCursorBitmap = null;
146 136
147 /** Capability Manager through which capabilities and extensions are handled . */ 137 /** Capability Manager through which capabilities and extensions are handled . */
148 private static CapabilityManager sCapabilityManager = CapabilityManager.getI nstance(); 138 private static CapabilityManager sCapabilityManager = CapabilityManager.getI nstance();
149 139
150 /** 140 /**
151 * To be called once from the main Activity. Any subsequent calls will updat e the application 141 * To be called once from the main Activity. Any subsequent calls will updat e the application
152 * context, but not reload the library. This is useful e.g. when the activit y is closed and the 142 * context, but not reload the library. This is useful e.g. when the activit y is closed and the
153 * user later wants to return to the application. Called on the UI thread. 143 * user later wants to return to the application. Called on the UI thread.
154 */ 144 */
155 public static void loadLibrary(Activity context) { 145 public static void loadLibrary(Context context) {
156 sContext = context;
157
158 if (sLoaded) return; 146 if (sLoaded) return;
159 147
160 System.loadLibrary("remoting_client_jni"); 148 System.loadLibrary("remoting_client_jni");
161 149
162 nativeLoadNative(context); 150 nativeLoadNative(context);
163 sLoaded = true; 151 sLoaded = true;
164 } 152 }
165 153
166 /** Performs the native portion of the initialization. */ 154 /** Performs the native portion of the initialization. */
167 private static native void nativeLoadNative(Context context); 155 private static native void nativeLoadNative(Context context);
168 156
169 /* 157 /*
170 * API/OAuth2 keys access. 158 * API/OAuth2 keys access.
171 */ 159 */
172 public static native String nativeGetApiKey(); 160 public static native String nativeGetApiKey();
173 public static native String nativeGetClientId(); 161 public static native String nativeGetClientId();
174 public static native String nativeGetClientSecret(); 162 public static native String nativeGetClientSecret();
175 163
164 /** Returns whether the client is connected. */
165 public static boolean isConnected() {
166 return sConnected;
167 }
168
176 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */ 169 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */
177 public static void connectToHost(String username, String authToken, 170 public static void connectToHost(String username, String authToken,
178 String hostJid, String hostId, String hostPubkey, ConnectionListener listener) { 171 String hostJid, String hostId, String hostPubkey, ConnectionListener listener,
172 SessionAuthenticator authenticator) {
179 disconnectFromHost(); 173 disconnectFromHost();
180 174
181 sConnectionListener = listener; 175 sConnectionListener = listener;
182 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; 176 sAuthenticator = authenticator;
183 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, 177 nativeConnect(username, authToken, hostJid, hostId, hostPubkey,
184 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", ""), 178 sAuthenticator.getPairingId(hostId), sAuthenticator.getPairingSe cret(hostId),
185 sCapabilityManager.getLocalCapabilities()); 179 sCapabilityManager.getLocalCapabilities());
186 sConnected = true; 180 sConnected = true;
187 } 181 }
188 182
189 /** Performs the native portion of the connection. */ 183 /** Performs the native portion of the connection. */
190 private static native void nativeConnect(String username, String authToken, String hostJid, 184 private static native void nativeConnect(String username, String authToken, String hostJid,
191 String hostId, String hostPubkey, String pairId, String pairSecret, 185 String hostId, String hostPubkey, String pairId, String pairSecret,
192 String capabilities); 186 String capabilities);
193 187
194 /** Severs the connection and cleans up. Called on the UI thread. */ 188 /** Severs the connection and cleans up. Called on the UI thread. */
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 if (state == ConnectionListener.State.FAILED || state == ConnectionListe ner.State.CLOSED) { 225 if (state == ConnectionListener.State.FAILED || state == ConnectionListe ner.State.CLOSED) {
232 // Disconnect from the host here, otherwise the next time connectToH ost() is called, 226 // Disconnect from the host here, otherwise the next time connectToH ost() is called,
233 // it will try to disconnect, triggering an incorrect status notific ation. 227 // it will try to disconnect, triggering an incorrect status notific ation.
234 disconnectFromHostWithoutNotification(); 228 disconnectFromHostWithoutNotification();
235 } 229 }
236 } 230 }
237 231
238 /** Prompts the user to enter a PIN. Called on the UI thread. */ 232 /** Prompts the user to enter a PIN. Called on the UI thread. */
239 @CalledByNative 233 @CalledByNative
240 private static void displayAuthenticationPrompt(boolean pairingSupported) { 234 private static void displayAuthenticationPrompt(boolean pairingSupported) {
241 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); 235 sAuthenticator.displayAuthenticationPrompt(pairingSupported);
242 pinPrompt.setTitle(sContext.getString(R.string.title_authenticate));
243 pinPrompt.setMessage(sContext.getString(R.string.pin_message_android));
244 pinPrompt.setIcon(android.R.drawable.ic_lock_lock);
245
246 final View pinEntry = sContext.getLayoutInflater().inflate(R.layout.pin_ dialog, null);
247 pinPrompt.setView(pinEntry);
248
249 final TextView pinTextView = (TextView) pinEntry.findViewById(R.id.pin_d ialog_text);
250 final CheckBox pinCheckBox = (CheckBox) pinEntry.findViewById(R.id.pin_d ialog_check);
251
252 if (!pairingSupported) {
253 pinCheckBox.setChecked(false);
254 pinCheckBox.setVisibility(View.GONE);
255 }
256
257 pinPrompt.setPositiveButton(
258 R.string.connect_button, new DialogInterface.OnClickListener() {
259 @Override
260 public void onClick(DialogInterface dialog, int which) {
261 Log.i("jniiface", "User provided a PIN code");
262 if (sConnected) {
263 nativeAuthenticationResponse(String.valueOf(pinTextV iew.getText()),
264 pinCheckBox.isChecked(), Build.MODEL);
265 } else {
266 String message = sContext.getString(R.string.error_n etwork_error);
267 Toast.makeText(sContext, message, Toast.LENGTH_LONG) .show();
268 }
269 }
270 });
271
272 pinPrompt.setNegativeButton(
273 R.string.cancel, new DialogInterface.OnClickListener() {
274 @Override
275 public void onClick(DialogInterface dialog, int which) {
276 Log.i("jniiface", "User canceled pin entry prompt");
277 disconnectFromHost();
278 }
279 });
280
281 final AlertDialog pinDialog = pinPrompt.create();
282
283 pinTextView.setOnEditorActionListener(
284 new TextView.OnEditorActionListener() {
285 @Override
286 public boolean onEditorAction(TextView v, int actionId, KeyE vent event) {
287 // The user pressed enter on the keypad (equivalent to t he connect button).
288 pinDialog.getButton(AlertDialog.BUTTON_POSITIVE).perform Click();
289 pinDialog.dismiss();
290 return true;
291 }
292 });
293
294 pinDialog.setOnCancelListener(
295 new DialogInterface.OnCancelListener() {
296 @Override
297 public void onCancel(DialogInterface dialog) {
298 // The user backed out of the dialog (equivalent to the cancel button).
299 pinDialog.getButton(AlertDialog.BUTTON_NEGATIVE).perform Click();
300 }
301 });
302
303 pinDialog.show();
304 } 236 }
305 237
306 /** 238 /**
307 * Performs the native response to the user's PIN. 239 * Performs the native response to the user's PIN.
308 * @param pin The entered PIN. 240 * @param pin The entered PIN.
309 * @param createPair Whether to create a new pairing for this client. 241 * @param createPair Whether to create a new pairing for this client.
310 * @param deviceName The device name to appear in the pairing registry. Only used if createPair 242 * @param deviceName The device name to appear in the pairing registry. Only used if createPair
311 * is true. 243 * is true.
312 */ 244 */
245 public static void handleAuthenticationResponse(String pin, boolean createPa ir,
246 String deviceName) {
247 assert sConnected;
248 nativeAuthenticationResponse(pin, createPair, deviceName);
249 }
250
251 /** Native implementation of handleAuthenticationResponse(). */
313 private static native void nativeAuthenticationResponse(String pin, boolean createPair, 252 private static native void nativeAuthenticationResponse(String pin, boolean createPair,
314 String deviceName); 253 String deviceName);
315 254
316 /** Saves newly-received pairing credentials to permanent storage. Called on the UI thread. */ 255 /** Saves newly-received pairing credentials to permanent storage. Called on the UI thread. */
317 @CalledByNative 256 @CalledByNative
318 private static void commitPairingCredentials(String host, String id, String secret) { 257 private static void commitPairingCredentials(String host, String id, String secret) {
319 // Empty |id| indicates that pairing needs to be removed. 258 sAuthenticator.commitPairingCredentials(host, id, secret);
320 if (id.isEmpty()) {
321 sContext.getPreferences(Activity.MODE_PRIVATE).edit()
322 .remove(host + "_id")
323 .remove(host + "_secret")
324 .apply();
325 } else {
326 sContext.getPreferences(Activity.MODE_PRIVATE).edit()
327 .putString(host + "_id", id)
328 .putString(host + "_secret", secret)
329 .apply();
330 }
331 } 259 }
332 260
333 /** 261 /**
334 * Moves the mouse cursor, possibly while clicking the specified (nonnegativ e) button. Called 262 * Moves the mouse cursor, possibly while clicking the specified (nonnegativ e) button. Called
335 * on the UI thread. 263 * on the UI thread.
336 */ 264 */
337 public static void sendMouseEvent(int x, int y, int whichButton, boolean but tonDown) { 265 public static void sendMouseEvent(int x, int y, int whichButton, boolean but tonDown) {
338 if (!sConnected) { 266 if (!sConnected) {
339 return; 267 return;
340 } 268 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 return sCursorBitmap; 419 return sCursorBitmap;
492 } 420 }
493 421
494 // 422 //
495 // Third Party Authentication 423 // Third Party Authentication
496 // 424 //
497 425
498 /** Pops up a third party login page to fetch the token required for authent ication. */ 426 /** Pops up a third party login page to fetch the token required for authent ication. */
499 @CalledByNative 427 @CalledByNative
500 public static void fetchThirdPartyToken(String tokenUrl, String clientId, St ring scope) { 428 public static void fetchThirdPartyToken(String tokenUrl, String clientId, St ring scope) {
501 Chromoting app = (Chromoting) sContext; 429 sAuthenticator.fetchThirdPartyToken(tokenUrl, clientId, scope);
502 app.fetchThirdPartyToken(tokenUrl, clientId, scope);
503 } 430 }
504 431
505 /** 432 /**
506 * Notify the native code to continue authentication with the |token| and th e |sharedSecret|. 433 * Notify the native code to continue authentication with the |token| and th e |sharedSecret|.
507 */ 434 */
508 public static void onThirdPartyTokenFetched(String token, String sharedSecre t) { 435 public static void onThirdPartyTokenFetched(String token, String sharedSecre t) {
509 if (!sConnected) { 436 if (!sConnected) {
510 return; 437 return;
511 } 438 }
512 439
(...skipping 27 matching lines...) Expand all
540 public static void sendExtensionMessage(String type, String data) { 467 public static void sendExtensionMessage(String type, String data) {
541 if (!sConnected) { 468 if (!sConnected) {
542 return; 469 return;
543 } 470 }
544 471
545 nativeSendExtensionMessage(type, data); 472 nativeSendExtensionMessage(type, data);
546 } 473 }
547 474
548 private static native void nativeSendExtensionMessage(String type, String da ta); 475 private static native void nativeSendExtensionMessage(String type, String da ta);
549 } 476 }
OLDNEW
« no previous file with comments | « remoting/android/java/src/org/chromium/chromoting/SessionConnector.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698