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

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

Issue 1537183002: Refactor Chromoting JNI code to use jni/Client (Java changes only). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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.content.Context; 7 import android.content.Context;
8 import android.graphics.Bitmap; 8 import android.graphics.Bitmap;
9 import android.graphics.Point;
10 import android.os.Looper;
11 9
12 import org.chromium.base.ContextUtils; 10 import org.chromium.base.ContextUtils;
13 import org.chromium.base.Log;
14 import org.chromium.base.annotations.CalledByNative; 11 import org.chromium.base.annotations.CalledByNative;
15 import org.chromium.base.annotations.JNINamespace; 12 import org.chromium.base.annotations.JNINamespace;
16 import org.chromium.chromoting.CapabilityManager;
17 import org.chromium.chromoting.SessionAuthenticator;
18 13
19 import java.nio.ByteBuffer; 14 import java.nio.ByteBuffer;
20 import java.nio.ByteOrder;
21 15
22 /** 16 /**
23 * Initializes the Chromium remoting library, and provides JNI calls into it. 17 * Initializes the Chromium remoting library, and provides JNI calls into it.
24 * All interaction with the native code is centralized in this class. 18 * All interaction with the native code is centralized in this class.
25 */ 19 */
26 @JNINamespace("remoting") 20 @JNINamespace("remoting")
27 public class JniInterface { 21 public class JniInterface {
28 private static final String TAG = "Chromoting";
29
30 /* 22 /*
31 * Library-loading state machine. 23 * Library-loading state machine.
32 */ 24 */
33 /** Whether the library has been loaded. Accessed on the UI thread. */ 25 /** Whether the library has been loaded. Accessed on the UI thread. */
34 private static boolean sLoaded = false; 26 private static boolean sLoaded = false;
35 27
36 /** Used for authentication-related UX during connection. Accessed on the UI thread. */
37 private static SessionAuthenticator sAuthenticator;
38
39 /*
40 * Connection-initiating state machine.
41 */
42 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */
43 private static boolean sConnected = false;
44
45 /** Notified upon successful connection or disconnection. Accessed on the UI thread. */
46 private static ConnectionListener sConnectionListener = null;
47
48 /**
49 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and
50 * graphics threads.
51 */
52 private static Runnable sRedrawCallback = null;
53
54 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */
55 private static Bitmap sFrameBitmap = null;
56
57 /** Protects access to sFrameBitmap. */
58 private static final Object sFrameLock = new Object();
59
60 /** Position of cursor hot-spot. Accessed on the graphics thread. */
61 private static Point sCursorHotspot = new Point();
62
63 /** Bitmap holding the cursor shape. Accessed on the graphics thread. */
64 private static Bitmap sCursorBitmap = null;
65
66 /** Capability Manager through which capabilities and extensions are handled . */
67 private static CapabilityManager sCapabilityManager = CapabilityManager.getI nstance();
68
69 /** 28 /**
70 * To be called once from the main Activity. Loads and initializes the nativ e code. 29 * To be called once from the main Activity. Loads and initializes the nativ e code.
71 * Called on the UI thread. 30 * Called on the UI thread.
72 */ 31 */
73 public static void loadLibrary(Context context) { 32 public static void loadLibrary(Context context) {
74 if (sLoaded) return; 33 if (sLoaded) return;
75 34
76 System.loadLibrary("remoting_client_jni"); 35 System.loadLibrary("remoting_client_jni");
77 36
78 ContextUtils.initApplicationContext(context.getApplicationContext()); 37 ContextUtils.initApplicationContext(context.getApplicationContext());
79 nativeLoadNative(); 38 nativeLoadNative();
80 sLoaded = true; 39 sLoaded = true;
81 } 40 }
82 41
83 /** Performs the native portion of the initialization. */ 42 /** Performs the native portion of the initialization. */
84 private static native void nativeLoadNative(); 43 private static native void nativeLoadNative();
85 44
45 /**
46 * Object representing the current connection to a host (may be null). This needs to be a
47 * global singleton so that the Client can be passed between Activities.
48 */
49 private static Client sClient;
50
51 /** Returns the current Client, or null. Called on the UI thread. */
52 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.
53 return sClient;
54 }
55
56 /** Creates a new Client, destroying any previous one. Called on the UI thre ad. */
57 public static Client createClient() {
58 destroyClient();
59 sClient = new Client();
60 return sClient;
61 }
62
63 /** Disconnects and destroys any current Client. Called on the UI thread. */
64 public static void destroyClient() {
65 if (sClient != null) {
66 sClient.destroy();
67 sClient = null;
68 }
69 }
70
86 /* 71 /*
87 * API/OAuth2 keys access. 72 * API/OAuth2 keys access.
88 */ 73 */
89 public static native String nativeGetApiKey(); 74 public static native String nativeGetApiKey();
90 public static native String nativeGetClientId(); 75 public static native String nativeGetClientId();
91 public static native String nativeGetClientSecret(); 76 public static native String nativeGetClientSecret();
92 77
93 /** Returns whether the client is connected. */
94 public static boolean isConnected() {
95 return sConnected;
96 }
97
98 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */
99 public static void connectToHost(String username, String authToken, String h ostJid,
100 String hostId, String hostPubkey, ConnectionListener listener,
101 SessionAuthenticator authenticator) {
102 disconnectFromHost();
103
104 sConnectionListener = listener;
105 sAuthenticator = authenticator;
106 nativeConnect(username, authToken, hostJid, hostId, hostPubkey,
107 sAuthenticator.getPairingId(hostId), sAuthenticator.getPairingSe cret(hostId),
108 sCapabilityManager.getLocalCapabilities());
109 sConnected = true;
110 }
111
112 /** Performs the native portion of the connection. */ 78 /** Performs the native portion of the connection. */
113 private static native void nativeConnect(String username, String authToken, String hostJid, 79 static native void nativeConnect(String username, String authToken, String h ostJid,
114 String hostId, String hostPubkey, String pairId, String pairSecret, 80 String hostId, String hostPubkey, String pairId, String pairSecret,
115 String capabilities); 81 String capabilities);
116 82
117 /** Severs the connection and cleans up. Called on the UI thread. */
118 public static void disconnectFromHost() {
119 if (!sConnected) {
120 return;
121 }
122
123 sConnectionListener.onConnectionState(
124 ConnectionListener.State.CLOSED, ConnectionListener.Error.OK);
125
126 disconnectFromHostWithoutNotification();
127 }
128
129 /** Same as disconnectFromHost() but without notifying the ConnectionListene r. */
130 private static void disconnectFromHostWithoutNotification() {
131 if (!sConnected) {
132 return;
133 }
134
135 nativeDisconnect();
136 sConnectionListener = null;
137 sConnected = false;
138 sCapabilityManager.onHostDisconnect();
139
140 // Drop the reference to free the Bitmap for GC.
141 synchronized (sFrameLock) {
142 sFrameBitmap = null;
143 }
144 }
145
146 /** Performs the native portion of the cleanup. */ 83 /** Performs the native portion of the cleanup. */
147 private static native void nativeDisconnect(); 84 static native void nativeDisconnect();
148 85
149 /** Called by native code whenever the connection status changes. Called on the UI thread. */ 86 /** Called by native code whenever the connection status changes. Called on the UI thread. */
150 @CalledByNative 87 @CalledByNative
151 private static void onConnectionState(int stateCode, int errorCode) { 88 private static void onConnectionState(int stateCode, int errorCode) {
152 ConnectionListener.State state = ConnectionListener.State.fromValue(stat eCode); 89 if (sClient != null) {
153 ConnectionListener.Error error = ConnectionListener.Error.fromValue(erro rCode); 90 sClient.onConnectionState(stateCode, errorCode);
154 sConnectionListener.onConnectionState(state, error);
155 if (state == ConnectionListener.State.FAILED || state == ConnectionListe ner.State.CLOSED) {
156 // Disconnect from the host here, otherwise the next time connectToH ost() is called,
157 // it will try to disconnect, triggering an incorrect status notific ation.
158 disconnectFromHostWithoutNotification();
159 } 91 }
160 } 92 }
161 93
162 /** Prompts the user to enter a PIN. Called on the UI thread. */ 94 /** Prompts the user to enter a PIN. Called on the UI thread. */
163 @CalledByNative 95 @CalledByNative
164 private static void displayAuthenticationPrompt(boolean pairingSupported) { 96 private static void displayAuthenticationPrompt(boolean pairingSupported) {
165 sAuthenticator.displayAuthenticationPrompt(pairingSupported); 97 if (sClient != null) {
98 sClient.displayAuthenticationPrompt(pairingSupported);
99 }
166 } 100 }
167 101
168 /** 102 /** Native implementation of Client.handleAuthenticationResponse(). */
169 * Performs the native response to the user's PIN. 103 static native void nativeAuthenticationResponse(
170 * @param pin The entered PIN.
171 * @param createPair Whether to create a new pairing for this client.
172 * @param deviceName The device name to appear in the pairing registry. Only used if createPair
173 * is true.
174 */
175 public static void handleAuthenticationResponse(
176 String pin, boolean createPair, String deviceName) {
177 assert sConnected;
178 nativeAuthenticationResponse(pin, createPair, deviceName);
179 }
180
181 /** Native implementation of handleAuthenticationResponse(). */
182 private static native void nativeAuthenticationResponse(
183 String pin, boolean createPair, String deviceName); 104 String pin, boolean createPair, String deviceName);
184 105
185 /** Saves newly-received pairing credentials to permanent storage. Called on the UI thread. */ 106 /** Saves newly-received pairing credentials to permanent storage. Called on the UI thread. */
186 @CalledByNative 107 @CalledByNative
187 private static void commitPairingCredentials(String host, String id, String secret) { 108 private static void commitPairingCredentials(String host, String id, String secret) {
188 sAuthenticator.commitPairingCredentials(host, id, secret); 109 if (sClient != null) {
189 } 110 sClient.commitPairingCredentials(host, id, secret);
190
191 /**
192 * Moves the mouse cursor, possibly while clicking the specified (nonnegativ e) button. Called
193 * on the UI thread.
194 */
195 public static void sendMouseEvent(int x, int y, int whichButton, boolean but tonDown) {
196 if (!sConnected) {
197 return;
198 } 111 }
199
200 nativeSendMouseEvent(x, y, whichButton, buttonDown);
201 } 112 }
202 113
203 /** Passes mouse information to the native handling code. */ 114 /** Passes mouse information to the native handling code. */
204 private static native void nativeSendMouseEvent( 115 static native void nativeSendMouseEvent(
205 int x, int y, int whichButton, boolean buttonDown); 116 int x, int y, int whichButton, boolean buttonDown);
206 117
207 /** Injects a mouse-wheel event with delta values. Called on the UI thread. */
208 public static void sendMouseWheelEvent(int deltaX, int deltaY) {
209 if (!sConnected) {
210 return;
211 }
212
213 nativeSendMouseWheelEvent(deltaX, deltaY);
214 }
215
216 /** Passes mouse-wheel information to the native handling code. */ 118 /** Passes mouse-wheel information to the native handling code. */
217 private static native void nativeSendMouseWheelEvent(int deltaX, int deltaY) ; 119 static native void nativeSendMouseWheelEvent(int deltaX, int deltaY);
218
219 /**
220 * Presses or releases the specified (nonnegative) key. Called on the UI thr ead. If scanCode
221 * is not zero then keyCode is ignored.
222 */
223 public static boolean sendKeyEvent(int scanCode, int keyCode, boolean keyDow n) {
224 if (!sConnected) {
225 return false;
226 }
227
228 return nativeSendKeyEvent(scanCode, keyCode, keyDown);
229 }
230 120
231 /** 121 /**
232 * Passes key press information to the native handling code. 122 * Passes key press information to the native handling code.
233 */ 123 */
234 private static native boolean nativeSendKeyEvent(int scanCode, int keyCode, boolean keyDown); 124 static native boolean nativeSendKeyEvent(int scanCode, int keyCode, boolean keyDown);
235
236 /** Sends TextEvent to the host. Called on the UI thread. */
237 public static void sendTextEvent(String text) {
238 if (!sConnected) {
239 return;
240 }
241
242 nativeSendTextEvent(text);
243 }
244 125
245 /** Passes text event information to the native handling code. */ 126 /** Passes text event information to the native handling code. */
246 private static native void nativeSendTextEvent(String text); 127 static native void nativeSendTextEvent(String text);
247
248 /** Sends an array of TouchEvents to the host. Called on the UI thread. */
249 public static void sendTouchEvent(TouchEventData.EventType eventType, TouchE ventData[] data) {
250 nativeSendTouchEvent(eventType.value(), data);
251 }
252 128
253 /** Passes touch event information to the native handling code. */ 129 /** Passes touch event information to the native handling code. */
254 private static native void nativeSendTouchEvent(int eventType, TouchEventDat a[] data); 130 static native void nativeSendTouchEvent(int eventType, TouchEventData[] data );
255 131
256 /** 132 /** Native implementation of Client.enableVideoChannel() */
257 * Enables or disables the video channel. Called on the UI thread in respons e to Activity 133 static native void nativeEnableVideoChannel(boolean enable);
258 * lifecycle events.
259 */
260 public static void enableVideoChannel(boolean enable) {
261 if (!sConnected) {
262 return;
263 }
264
265 nativeEnableVideoChannel(enable);
266 }
267
268 /** Native implementation of enableVideoChannel() */
269 private static native void nativeEnableVideoChannel(boolean enable);
270
271 /**
272 * Sets the redraw callback to the provided functor. Provide a value of null whenever the
273 * window is no longer visible so that we don't continue to draw onto it. Ca lled on the UI
274 * thread.
275 */
276 public static void provideRedrawCallback(Runnable redrawCallback) {
277 sRedrawCallback = redrawCallback;
278 }
279
280 /** Forces the native graphics thread to redraw to the canvas. Called on the UI thread. */
281 public static boolean redrawGraphics() {
282 if (!sConnected || sRedrawCallback == null) return false;
283
284 nativeScheduleRedraw();
285 return true;
286 }
287 134
288 /** Schedules a redraw on the native graphics thread. */ 135 /** Schedules a redraw on the native graphics thread. */
289 private static native void nativeScheduleRedraw(); 136 static native void nativeScheduleRedraw();
290 137
291 /** 138 /**
292 * Performs the redrawing callback. This is a no-op if the window isn't visi ble. Called on the 139 * Performs the redrawing callback. This is a no-op if the window isn't visi ble. Called on the
293 * graphics thread. 140 * graphics thread.
294 */ 141 */
295 @CalledByNative 142 @CalledByNative
296 private static void redrawGraphicsInternal() { 143 private static void redrawGraphicsInternal() {
297 Runnable callback = sRedrawCallback; 144 Client client = sClient;
298 if (callback != null) { 145 if (client != null) {
299 callback.run(); 146 client.redrawGraphicsInternal();
300 } 147 }
301 } 148 }
302 149
303 /**
304 * Returns a bitmap of the latest video frame. Called on the native graphics thread when
305 * DesktopView is repainted.
306 */
307 public static Bitmap getVideoFrame() {
308 if (Looper.myLooper() == Looper.getMainLooper()) {
309 Log.w(TAG, "Canvas being redrawn on UI thread");
310 }
311
312 synchronized (sFrameLock) {
313 return sFrameBitmap;
314 }
315 }
316
317 /** 150 /**
318 * Sets a new video frame. Called on the native graphics thread when a new f rame is allocated. 151 * Sets a new video frame. Called on the native graphics thread when a new f rame is allocated.
319 */ 152 */
320 @CalledByNative 153 @CalledByNative
321 private static void setVideoFrame(Bitmap bitmap) { 154 private static void setVideoFrame(Bitmap bitmap) {
322 if (Looper.myLooper() == Looper.getMainLooper()) { 155 Client client = sClient;
323 Log.w(TAG, "Video frame updated on UI thread"); 156 if (client != null) {
324 } 157 client.setVideoFrame(bitmap);
325
326 synchronized (sFrameLock) {
327 sFrameBitmap = bitmap;
328 } 158 }
329 } 159 }
330 160
331 /** 161 /**
332 * Creates a new Bitmap to hold video frame pixels. Called by native code wh ich stores a global 162 * Creates a new Bitmap to hold video frame pixels. Called by native code wh ich stores a global
333 * reference to the Bitmap and writes the decoded frame pixels to it. 163 * reference to the Bitmap and writes the decoded frame pixels to it.
334 */ 164 */
335 @CalledByNative 165 @CalledByNative
336 private static Bitmap newBitmap(int width, int height) { 166 private static Bitmap newBitmap(int width, int height) {
337 return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 167 return Client.newBitmap(width, height);
338 } 168 }
339 169
340 /** 170 /**
341 * Updates the cursor shape. This is called on the graphics thread when rece iving a new cursor 171 * Updates the cursor shape. This is called on the graphics thread when rece iving a new cursor
342 * shape from the host. 172 * shape from the host.
343 */ 173 */
344 @CalledByNative 174 @CalledByNative
345 public static void updateCursorShape( 175 private static void updateCursorShape(
346 int width, int height, int hotspotX, int hotspotY, ByteBuffer buffer ) { 176 int width, int height, int hotspotX, int hotspotY, ByteBuffer buffer ) {
347 sCursorHotspot = new Point(hotspotX, hotspotY); 177 Client client = sClient;
348 178 if (client != null) {
349 int[] data = new int[width * height]; 179 client.updateCursorShape(width, height, hotspotX, hotspotY, buffer);
350 buffer.order(ByteOrder.LITTLE_ENDIAN); 180 }
351 buffer.asIntBuffer().get(data, 0, data.length);
352 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888);
353 }
354
355 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */
356 public static Point getCursorHotspot() {
357 return sCursorHotspot;
358 }
359
360 /** Returns the current cursor shape. Called on the graphics thread. */
361 public static Bitmap getCursorBitmap() {
362 return sCursorBitmap;
363 } 181 }
364 182
365 // 183 //
366 // Third Party Authentication 184 // Third Party Authentication
367 // 185 //
368 186
369 /** Pops up a third party login page to fetch the token required for authent ication. */ 187 /** Pops up a third party login page to fetch the token required for authent ication. */
370 @CalledByNative 188 @CalledByNative
371 public static void fetchThirdPartyToken(String tokenUrl, String clientId, St ring scope) { 189 private static void fetchThirdPartyToken(String tokenUrl, String clientId, S tring scope) {
372 sAuthenticator.fetchThirdPartyToken(tokenUrl, clientId, scope); 190 if (sClient != null) {
373 } 191 sClient.fetchThirdPartyToken(tokenUrl, clientId, scope);
374
375 /**
376 * Notify the native code to continue authentication with the |token| and th e |sharedSecret|.
377 */
378 public static void onThirdPartyTokenFetched(String token, String sharedSecre t) {
379 if (!sConnected) {
380 return;
381 } 192 }
382
383 nativeOnThirdPartyTokenFetched(token, sharedSecret);
384 } 193 }
385 194
386 /** Passes authentication data to the native handling code. */ 195 /** Passes authentication data to the native handling code. */
387 private static native void nativeOnThirdPartyTokenFetched(String token, Stri ng sharedSecret); 196 static native void nativeOnThirdPartyTokenFetched(String token, String share dSecret);
388 197
389 // 198 //
390 // Host and Client Capabilities 199 // Host and Client Capabilities
391 // 200 //
392 201
393 /** Set the list of negotiated capabilities between host and client. Called on the UI thread. */ 202 /** Set the list of negotiated capabilities between host and client. Called on the UI thread. */
394 @CalledByNative 203 @CalledByNative
395 public static void setCapabilities(String capabilities) { 204 private static void setCapabilities(String capabilities) {
396 sCapabilityManager.setNegotiatedCapabilities(capabilities); 205 if (sClient != null) {
206 sClient.setCapabilities(capabilities);
207 }
397 } 208 }
398 209
399 // 210 //
400 // Extension Message Handling 211 // Extension Message Handling
401 // 212 //
402 213
403 /** Passes on the deconstructed ExtensionMessage to the app. Called on the U I thread. */ 214 /** Passes on the deconstructed ExtensionMessage to the app. Called on the U I thread. */
404 @CalledByNative 215 @CalledByNative
405 public static void handleExtensionMessage(String type, String data) { 216 private static void handleExtensionMessage(String type, String data) {
406 sCapabilityManager.onExtensionMessage(type, data); 217 if (sClient != null) {
218 sClient.handleExtensionMessage(type, data);
219 }
407 } 220 }
408 221
409 /** Sends an extension message to the Chromoting host. Called on the UI thre ad. */ 222 /** Passes extension message to the native code. */
410 public static void sendExtensionMessage(String type, String data) { 223 static native void nativeSendExtensionMessage(String type, String data);
411 if (!sConnected) {
412 return;
413 }
414
415 nativeSendExtensionMessage(type, data);
416 }
417
418 private static native void nativeSendExtensionMessage(String type, String da ta);
419 } 224 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698