Chromium Code Reviews| OLD | NEW |
|---|---|
| 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; | 7 import android.app.Activity; |
| 8 import android.app.AlertDialog; | 8 import android.app.AlertDialog; |
| 9 import android.app.ProgressDialog; | 9 import android.app.ProgressDialog; |
| 10 import android.content.Context; | 10 import android.content.Context; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 | 31 |
| 32 /** | 32 /** |
| 33 * Initializes the Chromium remoting library, and provides JNI calls into it. | 33 * Initializes the Chromium remoting library, and provides JNI calls into it. |
| 34 * All interaction with the native code is centralized in this class. | 34 * All interaction with the native code is centralized in this class. |
| 35 */ | 35 */ |
| 36 @JNINamespace("remoting") | 36 @JNINamespace("remoting") |
| 37 public class JniInterface { | 37 public class JniInterface { |
| 38 /** The status code indicating successful connection. */ | 38 /** The status code indicating successful connection. */ |
| 39 private static final int SUCCESSFUL_CONNECTION = 3; | 39 private static final int SUCCESSFUL_CONNECTION = 3; |
| 40 | 40 |
| 41 /** The application context. */ | |
| 42 private static Activity sContext = null; | |
| 43 | |
| 44 /* | 41 /* |
| 45 * Library-loading state machine. | 42 * Library-loading state machine. |
| 46 */ | 43 */ |
| 47 /** Whether we've already loaded the library. */ | 44 /** Whether we've already loaded the library. */ |
| 48 private static boolean sLoaded = false; | 45 private static boolean sLoaded = false; |
| 49 | 46 |
| 47 /** The application context. */ | |
| 48 private static Activity sContext = null; | |
| 49 | |
| 50 /* | |
| 51 * Connection-initiating state machine. | |
| 52 */ | |
| 53 /** Whether the native code is attempting a connection. */ | |
| 54 private static boolean sConnected = false; | |
| 55 | |
| 56 /** Callback to signal upon successful connection. */ | |
| 57 private static Runnable sSuccessCallback = null; | |
| 58 | |
| 59 /** Dialog for reporting connection progress. */ | |
| 60 private static ProgressDialog sProgressIndicator = null; | |
| 61 | |
| 62 /** Callback to signal whenever we need to redraw. */ | |
| 63 private static Runnable sRedrawCallback = null; | |
| 64 | |
| 65 /** Bitmap holding a copy of the latest video frame. */ | |
| 66 private static Bitmap sFrameBitmap = null; | |
| 67 | |
| 68 /** Lock to protect the frame bitmap reference. */ | |
| 69 private static final Object sFrameLock = new Object(); | |
| 70 | |
| 71 /** Position of cursor hot-spot. */ | |
| 72 private static Point sCursorHotspot = new Point(); | |
| 73 | |
| 74 /** Bitmap holding the cursor shape. */ | |
| 75 private static Bitmap sCursorBitmap = null; | |
| 76 | |
| 50 /** | 77 /** |
| 51 * To be called once from the main Activity. Any subsequent calls will updat e the application | 78 * To be called once from the main Activity. Any subsequent calls will updat e the application |
| 52 * context, but not reload the library. This is useful e.g. when the activit y is closed and the | 79 * context, but not reload the library. This is useful e.g. when the activit y is closed and the |
| 53 * user later wants to return to the application. | 80 * user later wants to return to the application. |
| 54 */ | 81 */ |
| 55 public static void loadLibrary(Activity context) { | 82 public static void loadLibrary(Activity context) { |
| 56 sContext = context; | 83 sContext = context; |
| 57 | 84 |
| 58 synchronized(JniInterface.class) { | 85 synchronized(JniInterface.class) { |
| 59 if (sLoaded) return; | 86 if (sLoaded) return; |
| 60 } | 87 } |
| 61 | 88 |
| 62 System.loadLibrary("remoting_client_jni"); | 89 System.loadLibrary("remoting_client_jni"); |
| 63 | 90 |
| 64 nativeLoadNative(context); | 91 nativeLoadNative(context); |
| 65 sLoaded = true; | 92 sLoaded = true; |
| 66 } | 93 } |
| 67 | 94 |
| 68 /** Performs the native portion of the initialization. */ | 95 /** Performs the native portion of the initialization. */ |
| 69 private static native void nativeLoadNative(Context context); | 96 private static native void nativeLoadNative(Context context); |
| 70 | 97 |
| 71 /* | 98 /* |
| 72 * API/OAuth2 keys access. | 99 * API/OAuth2 keys access. |
| 73 */ | 100 */ |
| 74 public static native String nativeGetApiKey(); | 101 public static native String nativeGetApiKey(); |
| 75 public static native String nativeGetClientId(); | 102 public static native String nativeGetClientId(); |
| 76 public static native String nativeGetClientSecret(); | 103 public static native String nativeGetClientSecret(); |
| 77 | 104 |
| 78 /* | |
| 79 * Connection-initiating state machine. | |
| 80 */ | |
| 81 /** Whether the native code is attempting a connection. */ | |
| 82 private static boolean sConnected = false; | |
| 83 | |
| 84 /** Callback to signal upon successful connection. */ | |
| 85 private static Runnable sSuccessCallback = null; | |
| 86 | |
| 87 /** Dialog for reporting connection progress. */ | |
| 88 private static ProgressDialog sProgressIndicator = null; | |
| 89 | |
| 90 /** Attempts to form a connection to the user-selected host. */ | 105 /** Attempts to form a connection to the user-selected host. */ |
| 91 public static void connectToHost(String username, String authToken, | 106 public static void connectToHost(String username, String authToken, |
| 92 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) { | 107 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) { |
| 93 synchronized(JniInterface.class) { | 108 synchronized(JniInterface.class) { |
| 94 if (!sLoaded) return; | 109 if (!sLoaded) return; |
| 95 | 110 |
| 96 if (sConnected) { | 111 if (sConnected) { |
| 97 disconnectFromHost(); | 112 disconnectFromHost(); |
| 98 } | 113 } |
| 99 } | 114 } |
| 100 | 115 |
| 101 sSuccessCallback = successCallback; | 116 sSuccessCallback = successCallback; |
| 102 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; | 117 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; |
| 103 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, | 118 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, |
| 104 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); | 119 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); |
| 105 sConnected = true; | 120 sConnected = true; |
| 106 } | 121 } |
| 107 | 122 |
| 123 /** Performs the native portion of the connection. */ | |
| 124 private static native void nativeConnect(String username, String authToken, String hostJid, | |
| 125 String hostId, String hostPubkey, String pairId, String pairSecret); | |
| 126 | |
| 108 /** Severs the connection and cleans up. */ | 127 /** Severs the connection and cleans up. */ |
| 109 public static void disconnectFromHost() { | 128 public static void disconnectFromHost() { |
| 110 synchronized(JniInterface.class) { | 129 synchronized(JniInterface.class) { |
| 111 if (!sLoaded || !sConnected) return; | 130 if (!sLoaded || !sConnected) return; |
| 112 | 131 |
| 113 if (sProgressIndicator != null) { | 132 if (sProgressIndicator != null) { |
| 114 sProgressIndicator.dismiss(); | 133 sProgressIndicator.dismiss(); |
| 115 sProgressIndicator = null; | 134 sProgressIndicator = null; |
| 116 } | 135 } |
| 117 } | 136 } |
| 118 | 137 |
| 119 nativeDisconnect(); | 138 nativeDisconnect(); |
| 120 sSuccessCallback = null; | 139 sSuccessCallback = null; |
| 121 sConnected = false; | 140 sConnected = false; |
| 122 | 141 |
| 123 // Drop the reference to free the Bitmap for GC. | 142 // Drop the reference to free the Bitmap for GC. |
| 124 synchronized (sFrameLock) { | 143 synchronized (sFrameLock) { |
| 125 sFrameBitmap = null; | 144 sFrameBitmap = null; |
| 126 } | 145 } |
| 127 } | 146 } |
| 128 | 147 |
| 129 /** Performs the native portion of the connection. */ | |
| 130 private static native void nativeConnect(String username, String authToken, String hostJid, | |
| 131 String hostId, String hostPubkey, String pairId, String pairSecret); | |
| 132 | |
| 133 /** Performs the native portion of the cleanup. */ | 148 /** Performs the native portion of the cleanup. */ |
| 134 private static native void nativeDisconnect(); | 149 private static native void nativeDisconnect(); |
| 135 | 150 |
| 136 /** Position of cursor hotspot within cursor image. */ | |
| 137 public static Point getCursorHotspot() { return sCursorHotspot; } | |
| 138 | |
| 139 /** Returns the current cursor shape. */ | |
| 140 public static Bitmap getCursorBitmap() { return sCursorBitmap; } | |
| 141 | |
| 142 /* | |
| 143 * Entry points *from* the native code. | |
| 144 */ | |
|
Lambros
2013/11/15 19:36:28
I removed this comment, which accounts for the mis
| |
| 145 /** Callback to signal whenever we need to redraw. */ | |
| 146 private static Runnable sRedrawCallback = null; | |
| 147 | |
| 148 /** Bitmap holding a copy of the latest video frame. */ | |
| 149 private static Bitmap sFrameBitmap = null; | |
| 150 | |
| 151 /** Lock to protect the frame bitmap reference. */ | |
| 152 private static final Object sFrameLock = new Object(); | |
| 153 | |
| 154 /** Position of cursor hot-spot. */ | |
| 155 private static Point sCursorHotspot = new Point(); | |
| 156 | |
| 157 /** Bitmap holding the cursor shape. */ | |
| 158 private static Bitmap sCursorBitmap = null; | |
| 159 | |
| 160 /** Reports whenever the connection status changes. */ | 151 /** Reports whenever the connection status changes. */ |
| 161 @CalledByNative | 152 @CalledByNative |
| 162 private static void reportConnectionStatus(int state, int error) { | 153 private static void reportConnectionStatus(int state, int error) { |
| 163 if (state < SUCCESSFUL_CONNECTION && error == 0) { | 154 if (state < SUCCESSFUL_CONNECTION && error == 0) { |
| 164 // The connection is still being established, so we'll report the cu rrent progress. | 155 // The connection is still being established, so we'll report the cu rrent progress. |
| 165 synchronized (JniInterface.class) { | 156 synchronized (JniInterface.class) { |
| 166 if (sProgressIndicator == null) { | 157 if (sProgressIndicator == null) { |
| 167 sProgressIndicator = ProgressDialog.show(sContext, sContext. | 158 sProgressIndicator = ProgressDialog.show(sContext, sContext. |
| 168 getString(R.string.progress_title), sContext.getReso urces(). | 159 getString(R.string.progress_title), sContext.getReso urces(). |
| 169 getStringArray(R.array.protoc_states)[state], true, true, | 160 getStringArray(R.array.protoc_states)[state], true, true, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 @Override | 255 @Override |
| 265 public void onCancel(DialogInterface dialog) { | 256 public void onCancel(DialogInterface dialog) { |
| 266 // The user backed out of the dialog (equivalent to the cancel button). | 257 // The user backed out of the dialog (equivalent to the cancel button). |
| 267 pinDialog.getButton(AlertDialog.BUTTON_NEGATIVE).perform Click(); | 258 pinDialog.getButton(AlertDialog.BUTTON_NEGATIVE).perform Click(); |
| 268 } | 259 } |
| 269 }); | 260 }); |
| 270 | 261 |
| 271 pinDialog.show(); | 262 pinDialog.show(); |
| 272 } | 263 } |
| 273 | 264 |
| 265 /** Performs the native response to the user's PIN. */ | |
| 266 private static native void nativeAuthenticationResponse(String pin, boolean createPair); | |
| 267 | |
| 274 /** Saves newly-received pairing credentials to permanent storage. */ | 268 /** Saves newly-received pairing credentials to permanent storage. */ |
| 275 @CalledByNative | 269 @CalledByNative |
| 276 private static void commitPairingCredentials(String host, byte[] id, byte[] secret) { | 270 private static void commitPairingCredentials(String host, byte[] id, byte[] secret) { |
| 277 synchronized (sContext) { | 271 synchronized (sContext) { |
| 278 sContext.getPreferences(Activity.MODE_PRIVATE).edit(). | 272 sContext.getPreferences(Activity.MODE_PRIVATE).edit(). |
| 279 putString(host + "_id", new String(id)). | 273 putString(host + "_id", new String(id)). |
| 280 putString(host + "_secret", new String(secret)). | 274 putString(host + "_secret", new String(secret)). |
| 281 apply(); | 275 apply(); |
| 282 } | 276 } |
| 283 } | 277 } |
| 284 | 278 |
| 279 /** Moves the mouse cursor, possibly while clicking the specified (nonnegati ve) button. */ | |
| 280 public static void mouseAction(int x, int y, int whichButton, boolean button Down) { | |
| 281 if (!sConnected) { | |
| 282 return; | |
| 283 } | |
| 284 | |
| 285 nativeMouseAction(x, y, whichButton, buttonDown); | |
| 286 } | |
| 287 | |
| 288 /** Passes mouse information to the native handling code. */ | |
| 289 private static native void nativeMouseAction(int x, int y, int whichButton, boolean buttonDown); | |
| 290 | |
| 291 /** Presses and releases the specified (nonnegative) key. */ | |
| 292 public static void keyboardAction(int keyCode, boolean keyDown) { | |
| 293 if (!sConnected) { | |
| 294 return; | |
| 295 } | |
| 296 | |
| 297 nativeKeyboardAction(keyCode, keyDown); | |
| 298 } | |
| 299 | |
| 300 /** Passes key press information to the native handling code. */ | |
| 301 private static native void nativeKeyboardAction(int keyCode, boolean keyDown ); | |
| 302 | |
| 285 /** | 303 /** |
| 286 * Sets the redraw callback to the provided functor. Provide a value of null whenever the | 304 * Sets the redraw callback to the provided functor. Provide a value of null whenever the |
| 287 * window is no longer visible so that we don't continue to draw onto it. | 305 * window is no longer visible so that we don't continue to draw onto it. |
| 288 */ | 306 */ |
| 289 public static void provideRedrawCallback(Runnable redrawCallback) { | 307 public static void provideRedrawCallback(Runnable redrawCallback) { |
| 290 sRedrawCallback = redrawCallback; | 308 sRedrawCallback = redrawCallback; |
| 291 } | 309 } |
| 292 | 310 |
| 293 /** Forces the native graphics thread to redraw to the canvas. */ | 311 /** Forces the native graphics thread to redraw to the canvas. */ |
| 294 public static boolean redrawGraphics() { | 312 public static boolean redrawGraphics() { |
| 295 synchronized(JniInterface.class) { | 313 synchronized(JniInterface.class) { |
| 296 if (!sConnected || sRedrawCallback == null) return false; | 314 if (!sConnected || sRedrawCallback == null) return false; |
| 297 } | 315 } |
| 298 | 316 |
| 299 nativeScheduleRedraw(); | 317 nativeScheduleRedraw(); |
| 300 return true; | 318 return true; |
| 301 } | 319 } |
| 302 | 320 |
| 321 /** Schedules a redraw on the native graphics thread. */ | |
| 322 private static native void nativeScheduleRedraw(); | |
| 323 | |
| 303 /** Performs the redrawing callback. This is a no-op if the window isn't vis ible. */ | 324 /** Performs the redrawing callback. This is a no-op if the window isn't vis ible. */ |
| 304 @CalledByNative | 325 @CalledByNative |
| 305 private static void redrawGraphicsInternal() { | 326 private static void redrawGraphicsInternal() { |
| 306 if (sRedrawCallback != null) { | 327 if (sRedrawCallback != null) { |
| 307 sRedrawCallback.run(); | 328 sRedrawCallback.run(); |
| 308 } | 329 } |
| 309 } | 330 } |
| 310 | 331 |
| 311 /** | 332 /** |
| 312 * Returns a bitmap of the latest video frame. Called on the native graphics thread when | 333 * Returns a bitmap of the latest video frame. Called on the native graphics thread when |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 public static void updateCursorShape(int width, int height, int hotspotX, in t hotspotY, | 378 public static void updateCursorShape(int width, int height, int hotspotX, in t hotspotY, |
| 358 ByteBuffer buffer) { | 379 ByteBuffer buffer) { |
| 359 sCursorHotspot = new Point(hotspotX, hotspotY); | 380 sCursorHotspot = new Point(hotspotX, hotspotY); |
| 360 | 381 |
| 361 int[] data = new int[width * height]; | 382 int[] data = new int[width * height]; |
| 362 buffer.order(ByteOrder.LITTLE_ENDIAN); | 383 buffer.order(ByteOrder.LITTLE_ENDIAN); |
| 363 buffer.asIntBuffer().get(data, 0, data.length); | 384 buffer.asIntBuffer().get(data, 0, data.length); |
| 364 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); | 385 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); |
| 365 } | 386 } |
| 366 | 387 |
| 367 /** Moves the mouse cursor, possibly while clicking the specified (nonnegati ve) button. */ | 388 /** Position of cursor hotspot within cursor image. */ |
| 368 public static void mouseAction(int x, int y, int whichButton, boolean button Down) { | 389 public static Point getCursorHotspot() { return sCursorHotspot; } |
| 369 if (!sConnected) { | |
| 370 return; | |
| 371 } | |
| 372 | 390 |
| 373 nativeMouseAction(x, y, whichButton, buttonDown); | 391 /** Returns the current cursor shape. */ |
| 374 } | 392 public static Bitmap getCursorBitmap() { return sCursorBitmap; } |
| 375 | |
| 376 /** Presses and releases the specified (nonnegative) key. */ | |
| 377 public static void keyboardAction(int keyCode, boolean keyDown) { | |
| 378 if (!sConnected) { | |
| 379 return; | |
| 380 } | |
| 381 | |
| 382 nativeKeyboardAction(keyCode, keyDown); | |
| 383 } | |
| 384 | |
| 385 /** Performs the native response to the user's PIN. */ | |
| 386 private static native void nativeAuthenticationResponse(String pin, boolean createPair); | |
| 387 | |
| 388 /** Schedules a redraw on the native graphics thread. */ | |
| 389 private static native void nativeScheduleRedraw(); | |
| 390 | |
| 391 /** Passes mouse information to the native handling code. */ | |
| 392 private static native void nativeMouseAction(int x, int y, int whichButton, boolean buttonDown); | |
| 393 | |
| 394 /** Passes key press information to the native handling code. */ | |
| 395 private static native void nativeKeyboardAction(int keyCode, boolean keyDown ); | |
| 396 } | 393 } |
| OLD | NEW |