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

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/jni/Client.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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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.graphics.Bitmap;
8 import android.graphics.Point;
9 import android.os.Looper;
10
11 import org.chromium.base.Log;
7 import org.chromium.base.annotations.JNINamespace; 12 import org.chromium.base.annotations.JNINamespace;
13 import org.chromium.chromoting.CapabilityManager;
14 import org.chromium.chromoting.SessionAuthenticator;
15
16 import java.nio.ByteBuffer;
17 import java.nio.ByteOrder;
8 18
9 /** 19 /**
10 * Class to manage a client connection to the host. This class controls the life time of the 20 * Class to manage a client connection to the host. This class controls the life time of the
11 * corresponding C++ object which implements the connection. A new object should be created for 21 * corresponding C++ object which implements the connection. A new object should be created for
12 * each connection to the host, so that notifications from a connection are alwa ys sent to the 22 * each connection to the host, so that notifications from a connection are alwa ys sent to the
13 * right object. 23 * right object.
14 */ 24 */
15 @JNINamespace("remoting") 25 @JNINamespace("remoting")
16 public class Client { 26 public class Client {
Sergey Ulanov 2015/12/21 17:58:15 maybe not for this CL: define abstract interface f
Lambros 2016/01/29 23:58:25 Acknowledged.
27 private static final String TAG = "Chromoting";
28
17 // Pointer to the C++ object, cast to a |long|. 29 // Pointer to the C++ object, cast to a |long|.
18 private long mNativeJniClient; 30 private long mNativeJniClient;
19 31
20 public void init() { 32 public Client() {
21 mNativeJniClient = nativeInit(); 33 mNativeJniClient = nativeInit();
22 } 34 }
23 35
24 private native long nativeInit(); 36 private native long nativeInit();
25 37
26 public void destroy() { 38 public void destroy() {
39 disconnectFromHost();
27 nativeDestroy(mNativeJniClient); 40 nativeDestroy(mNativeJniClient);
28 } 41 }
29 42
30 private native void nativeDestroy(long nativeJniClient); 43 private native void nativeDestroy(long nativeJniClient);
44
45 /** Used for authentication-related UX during connection. Accessed on the UI thread. */
46 private SessionAuthenticator mAuthenticator;
47
48 /** Whether the native code is attempting a connection. Accessed on the UI t hread. */
joedow 2016/01/19 16:35:06 Should this be 'attempting' a connection or 'estab
Lambros 2016/01/29 23:58:25 I'd prefer to clean this up in a followup CL - I m
49 private boolean mConnected;
50
51 /** Notified upon successful connection or disconnection. Accessed on the UI thread. */
52 private ConnectionListener mConnectionListener;
53
54 /**
55 * Callback invoked on the graphics thread to repaint the desktop. Accessed on the UI and
56 * graphics threads.
57 */
58 private Runnable mRedrawCallback;
59
60 /** Bitmap holding a copy of the latest video frame. Accessed on the UI and graphics threads. */
61 private Bitmap mFrameBitmap;
62
63 /** Protects access to {@link mFrameBitmap}. */
64 private final Object mFrameLock = new Object();
65
66 /** Position of cursor hot-spot. Accessed on the graphics thread. */
67 private Point mCursorHotspot = new Point();
68
69 /** Bitmap holding the cursor shape. Accessed on the graphics thread. */
70 private Bitmap mCursorBitmap;
71
72 /** Capability Manager through which capabilities and extensions are handled . */
73 private CapabilityManager mCapabilityManager = new CapabilityManager();
74
75 public CapabilityManager getCapabilityManager() {
76 return mCapabilityManager;
77 }
78
79 /** Returns whether the client is connected. */
80 public boolean isConnected() {
81 return mConnected;
82 }
83
84 /** Attempts to form a connection to the user-selected host. Called on the U I thread. */
85 public void connectToHost(String username, String authToken, String hostJid,
86 String hostId, String hostPubkey, ConnectionListener listener,
87 SessionAuthenticator authenticator) {
88 disconnectFromHost();
89
90 mConnectionListener = listener;
91 mAuthenticator = authenticator;
92 JniInterface.nativeConnect(username, authToken, hostJid, hostId, hostPub key,
93 mAuthenticator.getPairingId(hostId), mAuthenticator.getPairingSe cret(hostId),
94 mCapabilityManager.getLocalCapabilities());
95 mConnected = true;
96 }
97
98 /** Severs the connection and cleans up. Called on the UI thread. */
99 public void disconnectFromHost() {
100 if (!mConnected) {
101 return;
102 }
103
104 mConnectionListener.onConnectionState(
105 ConnectionListener.State.CLOSED, ConnectionListener.Error.OK);
joedow 2016/01/19 16:35:06 Should this event get fired after the connection w
Lambros 2016/01/29 23:58:25 I'm not certain that changing this won't break any
106
107 disconnectFromHostWithoutNotification();
joedow 2016/01/19 16:35:06 It looks like 'onConnectionState()' already has th
Lambros 2016/01/29 23:58:25 I don't follow? This code looks fine to me, it's j
108 }
109
110 /** Same as disconnectFromHost() but without notifying the ConnectionListene r. */
111 private void disconnectFromHostWithoutNotification() {
112 if (!mConnected) {
113 return;
114 }
115
116 JniInterface.nativeDisconnect();
117 mConnectionListener = null;
118 mConnected = false;
119 mCapabilityManager.onHostDisconnect();
120
121 // Drop the reference to free the Bitmap for GC.
122 synchronized (mFrameLock) {
123 mFrameBitmap = null;
124 }
125 }
126
127 /** Called by native code whenever the connection status changes. Called on the UI thread. */
128 void onConnectionState(int stateCode, int errorCode) {
129 ConnectionListener.State state = ConnectionListener.State.fromValue(stat eCode);
130 ConnectionListener.Error error = ConnectionListener.Error.fromValue(erro rCode);
131 mConnectionListener.onConnectionState(state, error);
132 if (state == ConnectionListener.State.FAILED || state == ConnectionListe ner.State.CLOSED) {
133 // Disconnect from the host here, otherwise the next time connectToH ost() is called,
134 // it will try to disconnect, triggering an incorrect status notific ation.
135 disconnectFromHostWithoutNotification();
136 }
137 }
138
139 /** Called from native code to prompt the user to enter a PIN. Called on the UI thread. */
140 void displayAuthenticationPrompt(boolean pairingSupported) {
141 mAuthenticator.displayAuthenticationPrompt(pairingSupported);
142 }
143
144 /**
145 * Performs the native response to the user's PIN.
Sergey Ulanov 2015/12/21 17:58:15 Reword this. E.g. "Called by mAuthenticator after
Lambros 2016/01/29 23:58:25 Done.
146 * @param pin The entered PIN.
147 * @param createPair Whether to create a new pairing for this client.
148 * @param deviceName The device name to appear in the pairing registry. Only used if createPair
149 * is true.
150 */
151 public void handleAuthenticationResponse(
152 String pin, boolean createPair, String deviceName) {
153 assert mConnected;
154 JniInterface.nativeAuthenticationResponse(pin, createPair, deviceName);
155 }
156
157 /**
158 * Called from native code, to save newly-received pairing credentials to pe rmanent storage.
Sergey Ulanov 2015/12/21 17:58:15 many of these comments need to be rewritten. E.g.
Lambros 2016/01/29 23:58:25 Done.
159 * Called on the UI thread.
160 */
161 void commitPairingCredentials(String host, String id, String secret) {
162 mAuthenticator.commitPairingCredentials(host, id, secret);
163 }
164
165 /**
166 * Moves the mouse cursor, possibly while clicking the specified (nonnegativ e) button. Called
167 * on the UI thread.
168 */
169 public void sendMouseEvent(int x, int y, int whichButton, boolean buttonDown ) {
170 if (!mConnected) {
171 return;
172 }
173
174 JniInterface.nativeSendMouseEvent(x, y, whichButton, buttonDown);
175 }
176
177 /** Injects a mouse-wheel event with delta values. Called on the UI thread. */
178 public void sendMouseWheelEvent(int deltaX, int deltaY) {
179 if (!mConnected) {
180 return;
181 }
182
183 JniInterface.nativeSendMouseWheelEvent(deltaX, deltaY);
184 }
185
186 /**
187 * Presses or releases the specified (nonnegative) key. Called on the UI thr ead. If scanCode
joedow 2016/01/19 16:35:06 Does it make sense to check the keypress value to
Lambros 2016/01/29 23:58:26 I'm not sure why "nonnegative" appears here - I'll
188 * is not zero then keyCode is ignored.
189 */
190 public boolean sendKeyEvent(int scanCode, int keyCode, boolean keyDown) {
191 if (!mConnected) {
192 return false;
193 }
194
195 return JniInterface.nativeSendKeyEvent(scanCode, keyCode, keyDown);
196 }
197
198 /** Sends TextEvent to the host. Called on the UI thread. */
199 public void sendTextEvent(String text) {
200 if (!mConnected) {
201 return;
202 }
203
204 JniInterface.nativeSendTextEvent(text);
205 }
206
207 /** Sends an array of TouchEvents to the host. Called on the UI thread. */
208 public void sendTouchEvent(TouchEventData.EventType eventType, TouchEventDat a[] data) {
209 if (!mConnected) {
210 return;
211 }
212
213 JniInterface.nativeSendTouchEvent(eventType.value(), data);
214 }
215
216 /**
217 * Enables or disables the video channel. Called on the UI thread in respons e to Activity
218 * lifecycle events.
219 */
220 public void enableVideoChannel(boolean enable) {
221 if (!mConnected) {
222 return;
223 }
224
225 JniInterface.nativeEnableVideoChannel(enable);
226 }
227
228 /**
229 * Sets the redraw callback to the provided functor. Provide a value of null whenever the
230 * window is no longer visible so that we don't continue to draw onto it. Ca lled on the UI
231 * thread.
232 */
233 public void provideRedrawCallback(Runnable redrawCallback) {
234 mRedrawCallback = redrawCallback;
235 }
236
237 /** Forces the native graphics thread to redraw to the canvas. Called on the UI thread. */
238 public boolean redrawGraphics() {
239 if (!mConnected || mRedrawCallback == null) return false;
240
241 JniInterface.nativeScheduleRedraw();
242 return true;
243 }
244
245 /**
246 * Called by native code to perform the redrawing callback. This is a no-op if the window isn't
247 * visible. Called on the graphics thread.
248 */
249 void redrawGraphicsInternal() {
250 Runnable callback = mRedrawCallback;
251 if (callback != null) {
252 callback.run();
253 }
254 }
255
256 /**
257 * Returns a bitmap of the latest video frame. Called on the native graphics thread when
258 * DesktopView is repainted.
259 */
260 public Bitmap getVideoFrame() {
261 if (Looper.myLooper() == Looper.getMainLooper()) {
262 Log.w(TAG, "Canvas being redrawn on UI thread");
263 }
264
265 synchronized (mFrameLock) {
266 return mFrameBitmap;
267 }
268 }
269
270 /**
271 * Called by native code to set a new video frame. Called on the native grap hics thread when a
272 * new frame is allocated.
273 */
274 void setVideoFrame(Bitmap bitmap) {
275 if (Looper.myLooper() == Looper.getMainLooper()) {
276 Log.w(TAG, "Video frame updated on UI thread");
277 }
278
279 synchronized (mFrameLock) {
280 mFrameBitmap = bitmap;
281 }
282 }
283
284 /**
285 * Creates a new Bitmap to hold video frame pixels. Called by native code wh ich stores a global
286 * reference to the Bitmap and writes the decoded frame pixels to it.
287 */
288 static Bitmap newBitmap(int width, int height) {
289 return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
290 }
291
292 /**
293 * Called by native code to update the cursor shape. This is called on the g raphics thread when
294 * receiving a new cursor shape from the host.
295 */
296 void updateCursorShape(
297 int width, int height, int hotspotX, int hotspotY, ByteBuffer buffer ) {
298 mCursorHotspot = new Point(hotspotX, hotspotY);
299
300 int[] data = new int[width * height];
301 buffer.order(ByteOrder.LITTLE_ENDIAN);
302 buffer.asIntBuffer().get(data, 0, data.length);
303 mCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888);
304 }
305
306 /** Position of cursor hotspot within cursor image. Called on the graphics t hread. */
307 public Point getCursorHotspot() {
308 return mCursorHotspot;
309 }
310
311 /** Returns the current cursor shape. Called on the graphics thread. */
312 public Bitmap getCursorBitmap() {
313 return mCursorBitmap;
314 }
315
316 //
317 // Third Party Authentication
318 //
319
320 /**
321 * Called by native code, to pop up a third party login page to fetch the to ken required for
322 * authentication.
323 */
324 void fetchThirdPartyToken(String tokenUrl, String clientId, String scope) {
325 mAuthenticator.fetchThirdPartyToken(tokenUrl, clientId, scope);
326 }
327
328 /**
329 * Notify the native code to continue authentication with the |token| and th e |sharedSecret|.
330 */
331 public void onThirdPartyTokenFetched(String token, String sharedSecret) {
332 if (!mConnected) {
333 return;
334 }
335
336 JniInterface.nativeOnThirdPartyTokenFetched(token, sharedSecret);
337 }
338
339 //
340 // Host and Client Capabilities
341 //
342
343 /**
344 * Called by native code to set the list of negotiated capabilities between host and client.
345 * Called on the UI thread.
346 */
347 void setCapabilities(String capabilities) {
348 mCapabilityManager.setNegotiatedCapabilities(capabilities);
349 }
350
351 //
352 // Extension Message Handling
353 //
354
355 /**
356 * Called by native code, to pass on the deconstructed ExtensionMessage to t he app. Called on
357 * the UI thread.
358 */
359 void handleExtensionMessage(String type, String data) {
360 mCapabilityManager.onExtensionMessage(type, data);
361 }
362
363 /** Sends an extension message to the Chromoting host. Called on the UI thre ad. */
364 public void sendExtensionMessage(String type, String data) {
365 if (!mConnected) {
366 return;
367 }
368
369 JniInterface.nativeSendExtensionMessage(type, data);
370 }
31 } 371 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698