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; | |
| 10 import android.content.Context; | 9 import android.content.Context; |
| 11 import android.content.DialogInterface; | 10 import android.content.DialogInterface; |
| 12 import android.content.SharedPreferences; | 11 import android.content.SharedPreferences; |
| 13 import android.graphics.Bitmap; | 12 import android.graphics.Bitmap; |
| 14 import android.graphics.Point; | 13 import android.graphics.Point; |
| 15 import android.os.Looper; | 14 import android.os.Looper; |
| 16 import android.util.Log; | 15 import android.util.Log; |
| 17 import android.view.KeyEvent; | 16 import android.view.KeyEvent; |
| 18 import android.view.View; | 17 import android.view.View; |
| 19 import android.widget.CheckBox; | 18 import android.widget.CheckBox; |
| 20 import android.widget.TextView; | 19 import android.widget.TextView; |
| 21 import android.widget.Toast; | 20 import android.widget.Toast; |
| 22 | 21 |
| 23 import org.chromium.base.CalledByNative; | 22 import org.chromium.base.CalledByNative; |
| 24 import org.chromium.base.JNINamespace; | 23 import org.chromium.base.JNINamespace; |
| 25 import org.chromium.chromoting.R; | 24 import org.chromium.chromoting.R; |
| 26 | 25 |
| 27 import java.nio.ByteBuffer; | 26 import java.nio.ByteBuffer; |
| 28 import java.nio.ByteOrder; | 27 import java.nio.ByteOrder; |
| 29 | 28 |
| 30 /** | 29 /** |
| 31 * Initializes the Chromium remoting library, and provides JNI calls into it. | 30 * Initializes the Chromium remoting library, and provides JNI calls into it. |
| 32 * All interaction with the native code is centralized in this class. | 31 * All interaction with the native code is centralized in this class. |
| 33 */ | 32 */ |
| 34 @JNINamespace("remoting") | 33 @JNINamespace("remoting") |
| 35 public class JniInterface { | 34 public class JniInterface { |
| 36 /** The status code indicating successful connection. */ | |
| 37 private static final int SUCCESSFUL_CONNECTION = 3; | |
| 38 | |
| 39 /* | 35 /* |
| 40 * Library-loading state machine. | 36 * Library-loading state machine. |
| 41 */ | 37 */ |
| 42 /** Whether the library has been loaded. Accessed on the UI thread. */ | 38 /** Whether the library has been loaded. Accessed on the UI thread. */ |
| 43 private static boolean sLoaded = false; | 39 private static boolean sLoaded = false; |
| 44 | 40 |
| 45 /** The application context. Accessed on the UI thread. */ | 41 /** The application context. Accessed on the UI thread. */ |
| 46 private static Activity sContext = null; | 42 private static Activity sContext = null; |
| 47 | 43 |
| 44 /** Interface used for connection state notifications. */ | |
| 45 public interface ConnectionListener { | |
| 46 /** | |
| 47 * The status code indicating successful connection. States less than th is indicate | |
| 48 * stages of establishing a connection. States greater than this indicat e disconnection | |
|
Sergey Ulanov
2014/01/03 00:01:51
Why not declare constant for all states, not only
Lambros
2014/01/04 01:59:46
Done.
| |
| 49 * or connection failure. These constants must match the corresponding C ++ enumeration. | |
| 50 */ | |
| 51 int SUCCESSFUL_CONNECTION = 3; | |
| 52 | |
| 53 /** The status code indicating disconnection. */ | |
| 54 int CONNECTION_CLOSED = 5; | |
| 55 | |
| 56 /** | |
| 57 * Notified on connection state change. | |
| 58 * @param state The new connection state, as defined in the C++ enumerat ion | |
| 59 * remoting::protocol::ConnectionToHost::State. | |
| 60 * @param error The error code, as defined in the C++ enumeration | |
| 61 * remoting::protocol::ErrorCode. | |
| 62 */ | |
| 63 void onConnectionState(int state, int error); | |
|
Sergey Ulanov
2014/01/03 00:01:51
Also please copy enum values for the errors from r
Lambros
2014/01/04 01:59:46
Second argument is used in an array lookup, loaded
| |
| 64 } | |
| 65 | |
| 48 /* | 66 /* |
| 49 * Connection-initiating state machine. | 67 * Connection-initiating state machine. |
| 50 */ | 68 */ |
| 51 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */ | 69 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */ |
| 52 private static boolean sConnected = false; | 70 private static boolean sConnected = false; |
| 53 | 71 |
| 54 /** Callback to signal upon successful connection. Accessed on the UI thread . */ | 72 /** Notified upon successful connection or disconnection. Accessed on the UI thread. */ |
| 55 private static Runnable sSuccessCallback = null; | 73 private static ConnectionListener sConnectionListener = null; |
| 56 | |
| 57 /** Dialog for reporting connection progress. Accessed on the UI thread. */ | |
| 58 private static ProgressDialog sProgressIndicator = null; | |
| 59 | |
| 60 // Protects access to |sProgressIndicator|. Used only to silence FindBugs wa rnings - the | |
| 61 // variable it protects is only accessed on a single thread. | |
| 62 // TODO(lambroslambrou): Refactor the ProgressIndicator into a separate clas s. | |
| 63 private static Object sProgressIndicatorLock = new Object(); | |
| 64 | 74 |
| 65 /** | 75 /** |
| 66 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and | 76 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and |
| 67 * graphics threads. | 77 * graphics threads. |
| 68 */ | 78 */ |
| 69 private static Runnable sRedrawCallback = null; | 79 private static Runnable sRedrawCallback = null; |
| 70 | 80 |
| 71 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */ | 81 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */ |
| 72 private static Bitmap sFrameBitmap = null; | 82 private static Bitmap sFrameBitmap = null; |
| 73 | 83 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 101 | 111 |
| 102 /* | 112 /* |
| 103 * API/OAuth2 keys access. | 113 * API/OAuth2 keys access. |
| 104 */ | 114 */ |
| 105 public static native String nativeGetApiKey(); | 115 public static native String nativeGetApiKey(); |
| 106 public static native String nativeGetClientId(); | 116 public static native String nativeGetClientId(); |
| 107 public static native String nativeGetClientSecret(); | 117 public static native String nativeGetClientSecret(); |
| 108 | 118 |
| 109 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */ | 119 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */ |
| 110 public static void connectToHost(String username, String authToken, | 120 public static void connectToHost(String username, String authToken, |
| 111 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) { | 121 String hostJid, String hostId, String hostPubkey, ConnectionListener listener) { |
| 112 disconnectFromHost(); | 122 disconnectFromHost(); |
| 113 | 123 |
| 114 sSuccessCallback = successCallback; | 124 sConnectionListener = listener; |
| 115 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; | 125 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; |
| 116 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, | 126 nativeConnect(username, authToken, hostJid, hostId, hostPubkey, |
| 117 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); | 127 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); |
| 118 sConnected = true; | 128 sConnected = true; |
| 119 } | 129 } |
| 120 | 130 |
| 121 /** Performs the native portion of the connection. */ | 131 /** Performs the native portion of the connection. */ |
| 122 private static native void nativeConnect(String username, String authToken, String hostJid, | 132 private static native void nativeConnect(String username, String authToken, String hostJid, |
| 123 String hostId, String hostPubkey, String pairId, String pairSecret); | 133 String hostId, String hostPubkey, String pairId, String pairSecret); |
| 124 | 134 |
| 125 /** Severs the connection and cleans up. Called on the UI thread. */ | 135 /** Severs the connection and cleans up. Called on the UI thread. */ |
| 126 public static void disconnectFromHost() { | 136 public static void disconnectFromHost() { |
| 127 if (!sConnected) return; | 137 if (!sConnected) return; |
| 128 | 138 |
| 129 synchronized (sProgressIndicatorLock) { | 139 sConnectionListener.onConnectionState(ConnectionListener.CONNECTION_CLOS ED, 0); |
| 130 if (sProgressIndicator != null) { | |
| 131 sProgressIndicator.dismiss(); | |
| 132 sProgressIndicator = null; | |
| 133 } | |
| 134 } | |
| 135 | 140 |
| 136 nativeDisconnect(); | 141 nativeDisconnect(); |
| 137 sSuccessCallback = null; | 142 sConnectionListener = null; |
| 138 sConnected = false; | 143 sConnected = false; |
| 139 | 144 |
| 140 // Drop the reference to free the Bitmap for GC. | 145 // Drop the reference to free the Bitmap for GC. |
| 141 synchronized (sFrameLock) { | 146 synchronized (sFrameLock) { |
| 142 sFrameBitmap = null; | 147 sFrameBitmap = null; |
| 143 } | 148 } |
| 144 } | 149 } |
| 145 | 150 |
| 146 /** Performs the native portion of the cleanup. */ | 151 /** Performs the native portion of the cleanup. */ |
| 147 private static native void nativeDisconnect(); | 152 private static native void nativeDisconnect(); |
| 148 | 153 |
| 149 /** Reports whenever the connection status changes. Called on the UI thread. */ | 154 /** Reports whenever the connection status changes. Called on the UI thread. */ |
| 150 @CalledByNative | 155 @CalledByNative |
| 151 private static void reportConnectionStatus(int state, int error) { | 156 private static void reportConnectionStatus(int state, int error) { |
| 152 if (state < SUCCESSFUL_CONNECTION && error == 0) { | 157 sConnectionListener.onConnectionState(state, error); |
| 153 // The connection is still being established, so we'll report the cu rrent progress. | |
| 154 synchronized (sProgressIndicatorLock) { | |
| 155 if (sProgressIndicator == null) { | |
| 156 sProgressIndicator = ProgressDialog.show(sContext, sContext. | |
| 157 getString(R.string.progress_title), sContext.getReso urces(). | |
| 158 getStringArray(R.array.protoc_states)[state], true, true, | |
| 159 new DialogInterface.OnCancelListener() { | |
| 160 @Override | |
| 161 public void onCancel(DialogInterface dialog) { | |
| 162 Log.i("jniiface", "User canceled connection initiation"); | |
| 163 disconnectFromHost(); | |
| 164 } | |
| 165 }); | |
| 166 } else { | |
| 167 sProgressIndicator.setMessage( | |
| 168 sContext.getResources().getStringArray(R.array.proto c_states)[state]); | |
| 169 } | |
| 170 } | |
| 171 } else { | |
| 172 // The connection is complete or has failed, so we can lose the prog ress indicator. | |
| 173 synchronized (sProgressIndicatorLock) { | |
| 174 if (sProgressIndicator != null) { | |
| 175 sProgressIndicator.dismiss(); | |
| 176 sProgressIndicator = null; | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 if (state == SUCCESSFUL_CONNECTION) { | |
| 181 Toast.makeText(sContext, sContext.getResources(). | |
| 182 getStringArray(R.array.protoc_states)[state], Toast.LENG TH_SHORT).show(); | |
| 183 | |
| 184 // Actually display the remote desktop. | |
| 185 sSuccessCallback.run(); | |
| 186 } else { | |
| 187 Toast.makeText(sContext, sContext.getResources().getStringArray( | |
| 188 R.array.protoc_states)[state] + (error == 0 ? "" : ": " + | |
| 189 sContext.getResources().getStringArray(R.array.protoc_er rors)[error]), | |
| 190 Toast.LENGTH_LONG).show(); | |
| 191 } | |
| 192 } | |
| 193 } | 158 } |
| 194 | 159 |
| 195 /** Prompts the user to enter a PIN. Called on the UI thread. */ | 160 /** Prompts the user to enter a PIN. Called on the UI thread. */ |
| 196 @CalledByNative | 161 @CalledByNative |
| 197 private static void displayAuthenticationPrompt(boolean pairingSupported) { | 162 private static void displayAuthenticationPrompt(boolean pairingSupported) { |
| 198 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); | 163 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); |
| 199 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title)); | 164 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title)); |
| 200 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message)); | 165 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message)); |
| 201 pinPrompt.setIcon(android.R.drawable.ic_lock_lock); | 166 pinPrompt.setIcon(android.R.drawable.ic_lock_lock); |
| 202 | 167 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 buffer.asIntBuffer().get(data, 0, data.length); | 357 buffer.asIntBuffer().get(data, 0, data.length); |
| 393 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); | 358 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); |
| 394 } | 359 } |
| 395 | 360 |
| 396 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */ | 361 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */ |
| 397 public static Point getCursorHotspot() { return sCursorHotspot; } | 362 public static Point getCursorHotspot() { return sCursorHotspot; } |
| 398 | 363 |
| 399 /** Returns the current cursor shape. Called on the graphics thread. */ | 364 /** Returns the current cursor shape. Called on the graphics thread. */ |
| 400 public static Bitmap getCursorBitmap() { return sCursorBitmap; } | 365 public static Bitmap getCursorBitmap() { return sCursorBitmap; } |
| 401 } | 366 } |
| OLD | NEW |