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

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

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

Powered by Google App Engine
This is Rietveld 408576698