Chromium Code Reviews| Index: remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java |
| diff --git a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java |
| index 90c76e1d45db5369a53332cd00ca33735a2928ef..83be0be4b8a9885c33432ee01be7b2be5266038e 100644 |
| --- a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java |
| +++ b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java |
| @@ -6,18 +6,12 @@ package org.chromium.chromoting.jni; |
| import android.content.Context; |
| import android.graphics.Bitmap; |
| -import android.graphics.Point; |
| -import android.os.Looper; |
| import org.chromium.base.ContextUtils; |
| -import org.chromium.base.Log; |
| import org.chromium.base.annotations.CalledByNative; |
| import org.chromium.base.annotations.JNINamespace; |
| -import org.chromium.chromoting.CapabilityManager; |
| -import org.chromium.chromoting.SessionAuthenticator; |
| import java.nio.ByteBuffer; |
| -import java.nio.ByteOrder; |
| /** |
| * Initializes the Chromium remoting library, and provides JNI calls into it. |
| @@ -25,47 +19,12 @@ import java.nio.ByteOrder; |
| */ |
| @JNINamespace("remoting") |
| public class JniInterface { |
| - private static final String TAG = "Chromoting"; |
| - |
| /* |
| * Library-loading state machine. |
| */ |
| /** Whether the library has been loaded. Accessed on the UI thread. */ |
| private static boolean sLoaded = false; |
| - /** Used for authentication-related UX during connection. Accessed on the UI thread. */ |
| - private static SessionAuthenticator sAuthenticator; |
| - |
| - /* |
| - * Connection-initiating state machine. |
| - */ |
| - /** Whether the native code is attempting a connection. Accessed on the UI thread. */ |
| - private static boolean sConnected = false; |
| - |
| - /** Notified upon successful connection or disconnection. Accessed on the UI thread. */ |
| - private static ConnectionListener sConnectionListener = null; |
| - |
| - /** |
| - * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and |
| - * graphics threads. |
| - */ |
| - private static Runnable sRedrawCallback = null; |
| - |
| - /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */ |
| - private static Bitmap sFrameBitmap = null; |
| - |
| - /** Protects access to sFrameBitmap. */ |
| - private static final Object sFrameLock = new Object(); |
| - |
| - /** Position of cursor hot-spot. Accessed on the graphics thread. */ |
| - private static Point sCursorHotspot = new Point(); |
| - |
| - /** Bitmap holding the cursor shape. Accessed on the graphics thread. */ |
| - private static Bitmap sCursorBitmap = null; |
| - |
| - /** Capability Manager through which capabilities and extensions are handled. */ |
| - private static CapabilityManager sCapabilityManager = CapabilityManager.getInstance(); |
| - |
| /** |
| * To be called once from the main Activity. Loads and initializes the native code. |
| * Called on the UI thread. |
| @@ -83,210 +42,98 @@ public class JniInterface { |
| /** Performs the native portion of the initialization. */ |
| private static native void nativeLoadNative(); |
| - /* |
| - * API/OAuth2 keys access. |
| + /** |
| + * Object representing the current connection to a host (may be null). This needs to be a |
| + * global singleton so that the Client can be passed between Activities. |
| */ |
| - public static native String nativeGetApiKey(); |
| - public static native String nativeGetClientId(); |
| - public static native String nativeGetClientSecret(); |
| + private static Client sClient; |
| - /** Returns whether the client is connected. */ |
| - public static boolean isConnected() { |
| - return sConnected; |
| + /** Returns the current Client, or null. Called on the UI thread. */ |
| + public static Client getClient() { |
|
Sergey Ulanov
2015/12/21 17:58:15
These look out of place here. Move to the Client c
Lambros
2016/01/29 23:58:26
Done.
|
| + return sClient; |
| } |
| - /** Attempts to form a connection to the user-selected host. Called on the UI thread. */ |
| - public static void connectToHost(String username, String authToken, String hostJid, |
| - String hostId, String hostPubkey, ConnectionListener listener, |
| - SessionAuthenticator authenticator) { |
| - disconnectFromHost(); |
| - |
| - sConnectionListener = listener; |
| - sAuthenticator = authenticator; |
| - nativeConnect(username, authToken, hostJid, hostId, hostPubkey, |
| - sAuthenticator.getPairingId(hostId), sAuthenticator.getPairingSecret(hostId), |
| - sCapabilityManager.getLocalCapabilities()); |
| - sConnected = true; |
| + /** Creates a new Client, destroying any previous one. Called on the UI thread. */ |
| + public static Client createClient() { |
| + destroyClient(); |
| + sClient = new Client(); |
| + return sClient; |
| } |
| - /** Performs the native portion of the connection. */ |
| - private static native void nativeConnect(String username, String authToken, String hostJid, |
| - String hostId, String hostPubkey, String pairId, String pairSecret, |
| - String capabilities); |
| - |
| - /** Severs the connection and cleans up. Called on the UI thread. */ |
| - public static void disconnectFromHost() { |
| - if (!sConnected) { |
| - return; |
| + /** Disconnects and destroys any current Client. Called on the UI thread. */ |
| + public static void destroyClient() { |
| + if (sClient != null) { |
| + sClient.destroy(); |
| + sClient = null; |
| } |
| - |
| - sConnectionListener.onConnectionState( |
| - ConnectionListener.State.CLOSED, ConnectionListener.Error.OK); |
| - |
| - disconnectFromHostWithoutNotification(); |
| } |
| - /** Same as disconnectFromHost() but without notifying the ConnectionListener. */ |
| - private static void disconnectFromHostWithoutNotification() { |
| - if (!sConnected) { |
| - return; |
| - } |
| - |
| - nativeDisconnect(); |
| - sConnectionListener = null; |
| - sConnected = false; |
| - sCapabilityManager.onHostDisconnect(); |
| + /* |
| + * API/OAuth2 keys access. |
| + */ |
| + public static native String nativeGetApiKey(); |
| + public static native String nativeGetClientId(); |
| + public static native String nativeGetClientSecret(); |
| - // Drop the reference to free the Bitmap for GC. |
| - synchronized (sFrameLock) { |
| - sFrameBitmap = null; |
| - } |
| - } |
| + /** Performs the native portion of the connection. */ |
| + static native void nativeConnect(String username, String authToken, String hostJid, |
| + String hostId, String hostPubkey, String pairId, String pairSecret, |
| + String capabilities); |
| /** Performs the native portion of the cleanup. */ |
| - private static native void nativeDisconnect(); |
| + static native void nativeDisconnect(); |
| /** Called by native code whenever the connection status changes. Called on the UI thread. */ |
| @CalledByNative |
| private static void onConnectionState(int stateCode, int errorCode) { |
| - ConnectionListener.State state = ConnectionListener.State.fromValue(stateCode); |
| - ConnectionListener.Error error = ConnectionListener.Error.fromValue(errorCode); |
| - sConnectionListener.onConnectionState(state, error); |
| - if (state == ConnectionListener.State.FAILED || state == ConnectionListener.State.CLOSED) { |
| - // Disconnect from the host here, otherwise the next time connectToHost() is called, |
| - // it will try to disconnect, triggering an incorrect status notification. |
| - disconnectFromHostWithoutNotification(); |
| + if (sClient != null) { |
| + sClient.onConnectionState(stateCode, errorCode); |
| } |
| } |
| /** Prompts the user to enter a PIN. Called on the UI thread. */ |
| @CalledByNative |
| private static void displayAuthenticationPrompt(boolean pairingSupported) { |
| - sAuthenticator.displayAuthenticationPrompt(pairingSupported); |
| - } |
| - |
| - /** |
| - * Performs the native response to the user's PIN. |
| - * @param pin The entered PIN. |
| - * @param createPair Whether to create a new pairing for this client. |
| - * @param deviceName The device name to appear in the pairing registry. Only used if createPair |
| - * is true. |
| - */ |
| - public static void handleAuthenticationResponse( |
| - String pin, boolean createPair, String deviceName) { |
| - assert sConnected; |
| - nativeAuthenticationResponse(pin, createPair, deviceName); |
| + if (sClient != null) { |
| + sClient.displayAuthenticationPrompt(pairingSupported); |
| + } |
| } |
| - /** Native implementation of handleAuthenticationResponse(). */ |
| - private static native void nativeAuthenticationResponse( |
| + /** Native implementation of Client.handleAuthenticationResponse(). */ |
| + static native void nativeAuthenticationResponse( |
| String pin, boolean createPair, String deviceName); |
| /** Saves newly-received pairing credentials to permanent storage. Called on the UI thread. */ |
| @CalledByNative |
| private static void commitPairingCredentials(String host, String id, String secret) { |
| - sAuthenticator.commitPairingCredentials(host, id, secret); |
| - } |
| - |
| - /** |
| - * Moves the mouse cursor, possibly while clicking the specified (nonnegative) button. Called |
| - * on the UI thread. |
| - */ |
| - public static void sendMouseEvent(int x, int y, int whichButton, boolean buttonDown) { |
| - if (!sConnected) { |
| - return; |
| + if (sClient != null) { |
| + sClient.commitPairingCredentials(host, id, secret); |
| } |
| - |
| - nativeSendMouseEvent(x, y, whichButton, buttonDown); |
| } |
| /** Passes mouse information to the native handling code. */ |
| - private static native void nativeSendMouseEvent( |
| + static native void nativeSendMouseEvent( |
| int x, int y, int whichButton, boolean buttonDown); |
| - /** Injects a mouse-wheel event with delta values. Called on the UI thread. */ |
| - public static void sendMouseWheelEvent(int deltaX, int deltaY) { |
| - if (!sConnected) { |
| - return; |
| - } |
| - |
| - nativeSendMouseWheelEvent(deltaX, deltaY); |
| - } |
| - |
| /** Passes mouse-wheel information to the native handling code. */ |
| - private static native void nativeSendMouseWheelEvent(int deltaX, int deltaY); |
| - |
| - /** |
| - * Presses or releases the specified (nonnegative) key. Called on the UI thread. If scanCode |
| - * is not zero then keyCode is ignored. |
| - */ |
| - public static boolean sendKeyEvent(int scanCode, int keyCode, boolean keyDown) { |
| - if (!sConnected) { |
| - return false; |
| - } |
| - |
| - return nativeSendKeyEvent(scanCode, keyCode, keyDown); |
| - } |
| + static native void nativeSendMouseWheelEvent(int deltaX, int deltaY); |
| /** |
| * Passes key press information to the native handling code. |
| */ |
| - private static native boolean nativeSendKeyEvent(int scanCode, int keyCode, boolean keyDown); |
| - |
| - /** Sends TextEvent to the host. Called on the UI thread. */ |
| - public static void sendTextEvent(String text) { |
| - if (!sConnected) { |
| - return; |
| - } |
| - |
| - nativeSendTextEvent(text); |
| - } |
| + static native boolean nativeSendKeyEvent(int scanCode, int keyCode, boolean keyDown); |
| /** Passes text event information to the native handling code. */ |
| - private static native void nativeSendTextEvent(String text); |
| - |
| - /** Sends an array of TouchEvents to the host. Called on the UI thread. */ |
| - public static void sendTouchEvent(TouchEventData.EventType eventType, TouchEventData[] data) { |
| - nativeSendTouchEvent(eventType.value(), data); |
| - } |
| + static native void nativeSendTextEvent(String text); |
| /** Passes touch event information to the native handling code. */ |
| - private static native void nativeSendTouchEvent(int eventType, TouchEventData[] data); |
| - |
| - /** |
| - * Enables or disables the video channel. Called on the UI thread in response to Activity |
| - * lifecycle events. |
| - */ |
| - public static void enableVideoChannel(boolean enable) { |
| - if (!sConnected) { |
| - return; |
| - } |
| - |
| - nativeEnableVideoChannel(enable); |
| - } |
| + static native void nativeSendTouchEvent(int eventType, TouchEventData[] data); |
| - /** Native implementation of enableVideoChannel() */ |
| - private static native void nativeEnableVideoChannel(boolean enable); |
| - |
| - /** |
| - * Sets the redraw callback to the provided functor. Provide a value of null whenever the |
| - * window is no longer visible so that we don't continue to draw onto it. Called on the UI |
| - * thread. |
| - */ |
| - public static void provideRedrawCallback(Runnable redrawCallback) { |
| - sRedrawCallback = redrawCallback; |
| - } |
| - |
| - /** Forces the native graphics thread to redraw to the canvas. Called on the UI thread. */ |
| - public static boolean redrawGraphics() { |
| - if (!sConnected || sRedrawCallback == null) return false; |
| - |
| - nativeScheduleRedraw(); |
| - return true; |
| - } |
| + /** Native implementation of Client.enableVideoChannel() */ |
| + static native void nativeEnableVideoChannel(boolean enable); |
| /** Schedules a redraw on the native graphics thread. */ |
| - private static native void nativeScheduleRedraw(); |
| + static native void nativeScheduleRedraw(); |
| /** |
| * Performs the redrawing callback. This is a no-op if the window isn't visible. Called on the |
| @@ -294,23 +141,9 @@ public class JniInterface { |
| */ |
| @CalledByNative |
| private static void redrawGraphicsInternal() { |
| - Runnable callback = sRedrawCallback; |
| - if (callback != null) { |
| - callback.run(); |
| - } |
| - } |
| - |
| - /** |
| - * Returns a bitmap of the latest video frame. Called on the native graphics thread when |
| - * DesktopView is repainted. |
| - */ |
| - public static Bitmap getVideoFrame() { |
| - if (Looper.myLooper() == Looper.getMainLooper()) { |
| - Log.w(TAG, "Canvas being redrawn on UI thread"); |
| - } |
| - |
| - synchronized (sFrameLock) { |
| - return sFrameBitmap; |
| + Client client = sClient; |
| + if (client != null) { |
| + client.redrawGraphicsInternal(); |
| } |
| } |
| @@ -319,12 +152,9 @@ public class JniInterface { |
| */ |
| @CalledByNative |
| private static void setVideoFrame(Bitmap bitmap) { |
| - if (Looper.myLooper() == Looper.getMainLooper()) { |
| - Log.w(TAG, "Video frame updated on UI thread"); |
| - } |
| - |
| - synchronized (sFrameLock) { |
| - sFrameBitmap = bitmap; |
| + Client client = sClient; |
| + if (client != null) { |
| + client.setVideoFrame(bitmap); |
| } |
| } |
| @@ -334,7 +164,7 @@ public class JniInterface { |
| */ |
| @CalledByNative |
| private static Bitmap newBitmap(int width, int height) { |
| - return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); |
| + return Client.newBitmap(width, height); |
| } |
| /** |
| @@ -342,24 +172,12 @@ public class JniInterface { |
| * shape from the host. |
| */ |
| @CalledByNative |
| - public static void updateCursorShape( |
| + private static void updateCursorShape( |
| int width, int height, int hotspotX, int hotspotY, ByteBuffer buffer) { |
| - sCursorHotspot = new Point(hotspotX, hotspotY); |
| - |
| - int[] data = new int[width * height]; |
| - buffer.order(ByteOrder.LITTLE_ENDIAN); |
| - buffer.asIntBuffer().get(data, 0, data.length); |
| - sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.ARGB_8888); |
| - } |
| - |
| - /** Position of cursor hotspot within cursor image. Called on the graphics thread. */ |
| - public static Point getCursorHotspot() { |
| - return sCursorHotspot; |
| - } |
| - |
| - /** Returns the current cursor shape. Called on the graphics thread. */ |
| - public static Bitmap getCursorBitmap() { |
| - return sCursorBitmap; |
| + Client client = sClient; |
| + if (client != null) { |
| + client.updateCursorShape(width, height, hotspotX, hotspotY, buffer); |
| + } |
| } |
| // |
| @@ -368,23 +186,14 @@ public class JniInterface { |
| /** Pops up a third party login page to fetch the token required for authentication. */ |
| @CalledByNative |
| - public static void fetchThirdPartyToken(String tokenUrl, String clientId, String scope) { |
| - sAuthenticator.fetchThirdPartyToken(tokenUrl, clientId, scope); |
| - } |
| - |
| - /** |
| - * Notify the native code to continue authentication with the |token| and the |sharedSecret|. |
| - */ |
| - public static void onThirdPartyTokenFetched(String token, String sharedSecret) { |
| - if (!sConnected) { |
| - return; |
| + private static void fetchThirdPartyToken(String tokenUrl, String clientId, String scope) { |
| + if (sClient != null) { |
| + sClient.fetchThirdPartyToken(tokenUrl, clientId, scope); |
| } |
| - |
| - nativeOnThirdPartyTokenFetched(token, sharedSecret); |
| } |
| /** Passes authentication data to the native handling code. */ |
| - private static native void nativeOnThirdPartyTokenFetched(String token, String sharedSecret); |
| + static native void nativeOnThirdPartyTokenFetched(String token, String sharedSecret); |
| // |
| // Host and Client Capabilities |
| @@ -392,8 +201,10 @@ public class JniInterface { |
| /** Set the list of negotiated capabilities between host and client. Called on the UI thread. */ |
| @CalledByNative |
| - public static void setCapabilities(String capabilities) { |
| - sCapabilityManager.setNegotiatedCapabilities(capabilities); |
| + private static void setCapabilities(String capabilities) { |
| + if (sClient != null) { |
| + sClient.setCapabilities(capabilities); |
| + } |
| } |
| // |
| @@ -402,18 +213,12 @@ public class JniInterface { |
| /** Passes on the deconstructed ExtensionMessage to the app. Called on the UI thread. */ |
| @CalledByNative |
| - public static void handleExtensionMessage(String type, String data) { |
| - sCapabilityManager.onExtensionMessage(type, data); |
| - } |
| - |
| - /** Sends an extension message to the Chromoting host. Called on the UI thread. */ |
| - public static void sendExtensionMessage(String type, String data) { |
| - if (!sConnected) { |
| - return; |
| + private static void handleExtensionMessage(String type, String data) { |
| + if (sClient != null) { |
| + sClient.handleExtensionMessage(type, data); |
| } |
| - |
| - nativeSendExtensionMessage(type, data); |
| } |
| - private static native void nativeSendExtensionMessage(String type, String data); |
| + /** Passes extension message to the native code. */ |
| + static native void nativeSendExtensionMessage(String type, String data); |
| } |