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

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: 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
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; 16 import org.chromium.chromoting.Chromoting;
27 import org.chromium.chromoting.R; 17 import org.chromium.chromoting.R;
18 import org.chromium.chromoting.SessionAuthenticator;
28 19
29 import java.nio.ByteBuffer; 20 import java.nio.ByteBuffer;
30 import java.nio.ByteOrder; 21 import java.nio.ByteOrder;
31 22
32 /** 23 /**
33 * Initializes the Chromium remoting library, and provides JNI calls into it. 24 * Initializes the Chromium remoting library, and provides JNI calls into it.
34 * All interaction with the native code is centralized in this class. 25 * All interaction with the native code is centralized in this class.
35 */ 26 */
36 @JNINamespace("remoting") 27 @JNINamespace("remoting")
37 public class JniInterface { 28 public class JniInterface {
38 /* 29 /*
39 * Library-loading state machine. 30 * Library-loading state machine.
40 */ 31 */
41 /** Whether the library has been loaded. Accessed on the UI thread. */ 32 /** Whether the library has been loaded. Accessed on the UI thread. */
42 private static boolean sLoaded = false; 33 private static boolean sLoaded = false;
43 34
44 /** The application context. Accessed on the UI thread. */ 35 /** Used for authentication-related UX during connection. Accessed on the UI thread. */
45 private static Activity sContext = null; 36 private static SessionAuthenticator sAuthenticator = null;
46 37
47 /** Interface used for connection state notifications. */ 38 /** Interface used for connection state notifications. */
48 public interface ConnectionListener { 39 public interface ConnectionListener {
49 /** 40 /**
50 * This enum must match the C++ enumeration remoting::protocol::Connecti onToHost::State. 41 * This enum must match the C++ enumeration remoting::protocol::Connecti onToHost::State.
51 */ 42 */
52 public enum State { 43 public enum State {
53 INITIALIZING(0), 44 INITIALIZING(0),
54 CONNECTING(1), 45 CONNECTING(1),
55 AUTHENTICATED(2), 46 AUTHENTICATED(2),
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 private static Bitmap sCursorBitmap = null; 136 private static Bitmap sCursorBitmap = null;
146 137
147 /** Capability Manager through which capabilities and extensions are handled . */ 138 /** Capability Manager through which capabilities and extensions are handled . */
148 private static CapabilityManager sCapabilityManager = CapabilityManager.getI nstance(); 139 private static CapabilityManager sCapabilityManager = CapabilityManager.getI nstance();
149 140
150 /** 141 /**
151 * To be called once from the main Activity. Any subsequent calls will updat e the application 142 * 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 143 * 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. 144 * user later wants to return to the application. Called on the UI thread.
154 */ 145 */
155 public static void loadLibrary(Activity context) { 146 public static void loadLibrary(Chromoting context) {
156 sContext = context; 147 sAuthenticator = new SessionAuthenticator(context);
Sergey Ulanov 2015/03/09 18:14:53 Ideally SessionAuthenticator should be an interfac
Lambros 2015/03/14 00:42:18 Done, except for making SessionAuthenticator an in
157 148
158 if (sLoaded) return; 149 if (sLoaded) return;
159 150
160 System.loadLibrary("remoting_client_jni"); 151 System.loadLibrary("remoting_client_jni");
161 152
162 nativeLoadNative(context); 153 nativeLoadNative(context);
163 sLoaded = true; 154 sLoaded = true;
164 } 155 }
165 156
166 /** Performs the native portion of the initialization. */ 157 /** Performs the native portion of the initialization. */
167 private static native void nativeLoadNative(Context context); 158 private static native void nativeLoadNative(Context context);
168 159
169 /* 160 /*
170 * API/OAuth2 keys access. 161 * API/OAuth2 keys access.
171 */ 162 */
172 public static native String nativeGetApiKey(); 163 public static native String nativeGetApiKey();
173 public static native String nativeGetClientId(); 164 public static native String nativeGetClientId();
174 public static native String nativeGetClientSecret(); 165 public static native String nativeGetClientSecret();
175 166
167 /** Returns whether the client is connected. */
168 public static boolean isConnected() {
169 return sConnected;
170 }
171
176 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */ 172 /** 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, 173 public static void connectToHost(String username, String authToken,
178 String hostJid, String hostId, String hostPubkey, ConnectionListener listener) { 174 String hostJid, String hostId, String hostPubkey, ConnectionListener listener) {
179 disconnectFromHost(); 175 disconnectFromHost();
180 176
181 sConnectionListener = listener; 177 sConnectionListener = listener;
182 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ;
183 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, 178 nativeConnect(username, authToken, hostJid, hostId, hostPubkey,
184 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", ""), 179 sAuthenticator.getPairingId(hostId), sAuthenticator.getPairingSe cret(hostId),
185 sCapabilityManager.getLocalCapabilities()); 180 sCapabilityManager.getLocalCapabilities());
186 sConnected = true; 181 sConnected = true;
187 } 182 }
188 183
189 /** Performs the native portion of the connection. */ 184 /** Performs the native portion of the connection. */
190 private static native void nativeConnect(String username, String authToken, String hostJid, 185 private static native void nativeConnect(String username, String authToken, String hostJid,
191 String hostId, String hostPubkey, String pairId, String pairSecret, 186 String hostId, String hostPubkey, String pairId, String pairSecret,
192 String capabilities); 187 String capabilities);
193 188
194 /** Severs the connection and cleans up. Called on the UI thread. */ 189 /** 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) { 226 if (state == ConnectionListener.State.FAILED || state == ConnectionListe ner.State.CLOSED) {
232 // Disconnect from the host here, otherwise the next time connectToH ost() is called, 227 // 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. 228 // it will try to disconnect, triggering an incorrect status notific ation.
234 disconnectFromHostWithoutNotification(); 229 disconnectFromHostWithoutNotification();
235 } 230 }
236 } 231 }
237 232
238 /** Prompts the user to enter a PIN. Called on the UI thread. */ 233 /** Prompts the user to enter a PIN. Called on the UI thread. */
239 @CalledByNative 234 @CalledByNative
240 private static void displayAuthenticationPrompt(boolean pairingSupported) { 235 private static void displayAuthenticationPrompt(boolean pairingSupported) {
241 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); 236 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 } 237 }
305 238
306 /** 239 /**
307 * Performs the native response to the user's PIN. 240 * Performs the native response to the user's PIN.
308 * @param pin The entered PIN. 241 * @param pin The entered PIN.
309 * @param createPair Whether to create a new pairing for this client. 242 * @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 243 * @param deviceName The device name to appear in the pairing registry. Only used if createPair
311 * is true. 244 * is true.
312 */ 245 */
246 public static void handleAuthenticationResponse(String pin, boolean createPa ir,
247 String deviceName) {
248 assert sConnected;
249 nativeAuthenticationResponse(pin, createPair, deviceName);
250 }
251
252 /** Native implementation of handleAuthenticationResponse(). */
313 private static native void nativeAuthenticationResponse(String pin, boolean createPair, 253 private static native void nativeAuthenticationResponse(String pin, boolean createPair,
314 String deviceName); 254 String deviceName);
315 255
316 /** Saves newly-received pairing credentials to permanent storage. Called on the UI thread. */ 256 /** Saves newly-received pairing credentials to permanent storage. Called on the UI thread. */
317 @CalledByNative 257 @CalledByNative
318 private static void commitPairingCredentials(String host, String id, String secret) { 258 private static void commitPairingCredentials(String host, String id, String secret) {
319 // Empty |id| indicates that pairing needs to be removed. 259 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 } 260 }
332 261
333 /** 262 /**
334 * Moves the mouse cursor, possibly while clicking the specified (nonnegativ e) button. Called 263 * Moves the mouse cursor, possibly while clicking the specified (nonnegativ e) button. Called
335 * on the UI thread. 264 * on the UI thread.
336 */ 265 */
337 public static void sendMouseEvent(int x, int y, int whichButton, boolean but tonDown) { 266 public static void sendMouseEvent(int x, int y, int whichButton, boolean but tonDown) {
338 if (!sConnected) { 267 if (!sConnected) {
339 return; 268 return;
340 } 269 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 return sCursorBitmap; 420 return sCursorBitmap;
492 } 421 }
493 422
494 // 423 //
495 // Third Party Authentication 424 // Third Party Authentication
496 // 425 //
497 426
498 /** Pops up a third party login page to fetch the token required for authent ication. */ 427 /** Pops up a third party login page to fetch the token required for authent ication. */
499 @CalledByNative 428 @CalledByNative
500 public static void fetchThirdPartyToken(String tokenUrl, String clientId, St ring scope) { 429 public static void fetchThirdPartyToken(String tokenUrl, String clientId, St ring scope) {
501 Chromoting app = (Chromoting) sContext; 430 sAuthenticator.fetchThirdPartyToken(tokenUrl, clientId, scope);
502 app.fetchThirdPartyToken(tokenUrl, clientId, scope);
503 } 431 }
504 432
505 /** 433 /**
506 * Notify the native code to continue authentication with the |token| and th e |sharedSecret|. 434 * Notify the native code to continue authentication with the |token| and th e |sharedSecret|.
507 */ 435 */
508 public static void onThirdPartyTokenFetched(String token, String sharedSecre t) { 436 public static void onThirdPartyTokenFetched(String token, String sharedSecre t) {
509 if (!sConnected) { 437 if (!sConnected) {
510 return; 438 return;
511 } 439 }
512 440
(...skipping 27 matching lines...) Expand all
540 public static void sendExtensionMessage(String type, String data) { 468 public static void sendExtensionMessage(String type, String data) {
541 if (!sConnected) { 469 if (!sConnected) {
542 return; 470 return;
543 } 471 }
544 472
545 nativeSendExtensionMessage(type, data); 473 nativeSendExtensionMessage(type, data);
546 } 474 }
547 475
548 private static native void nativeSendExtensionMessage(String type, String da ta); 476 private static native void nativeSendExtensionMessage(String type, String da ta);
549 } 477 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698