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; | 9 import android.app.ProgressDialog; |
10 import android.content.Context; | 10 import android.content.Context; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 | 108 |
109 if (sProgressIndicator != null) { | 109 if (sProgressIndicator != null) { |
110 sProgressIndicator.dismiss(); | 110 sProgressIndicator.dismiss(); |
111 sProgressIndicator = null; | 111 sProgressIndicator = null; |
112 } | 112 } |
113 } | 113 } |
114 | 114 |
115 disconnectNative(); | 115 disconnectNative(); |
116 sSuccessCallback = null; | 116 sSuccessCallback = null; |
117 sConnected = false; | 117 sConnected = false; |
| 118 |
| 119 // Drop the reference to free the Bitmap for GC. |
| 120 synchronized (sFrameLock) { |
| 121 sFrameBitmap = null; |
| 122 } |
118 } | 123 } |
119 | 124 |
120 /** Performs the native portion of the connection. */ | 125 /** Performs the native portion of the connection. */ |
121 private static native void connectNative(String username, String authToken,
String hostJid, | 126 private static native void connectNative(String username, String authToken,
String hostJid, |
122 String hostId, String hostPubkey, String pairId, String pairSecret); | 127 String hostId, String hostPubkey, String pairId, String pairSecret); |
123 | 128 |
124 /** Performs the native portion of the cleanup. */ | 129 /** Performs the native portion of the cleanup. */ |
125 private static native void disconnectNative(); | 130 private static native void disconnectNative(); |
126 | 131 |
127 /** Position of cursor hotspot within cursor image. */ | 132 /** Position of cursor hotspot within cursor image. */ |
128 public static Point getCursorHotspot() { return sCursorHotspot; } | 133 public static Point getCursorHotspot() { return sCursorHotspot; } |
129 | 134 |
130 /** Returns the current cursor shape. */ | 135 /** Returns the current cursor shape. */ |
131 public static Bitmap getCursorBitmap() { return sCursorBitmap; } | 136 public static Bitmap getCursorBitmap() { return sCursorBitmap; } |
132 | 137 |
133 /* | 138 /* |
134 * Entry points *from* the native code. | 139 * Entry points *from* the native code. |
135 */ | 140 */ |
136 /** Callback to signal whenever we need to redraw. */ | 141 /** Callback to signal whenever we need to redraw. */ |
137 private static Runnable sRedrawCallback = null; | 142 private static Runnable sRedrawCallback = null; |
138 | 143 |
139 /** Screen width of the video feed. */ | 144 /** Bitmap holding a copy of the latest video frame. */ |
140 private static int sWidth = 0; | 145 private static Bitmap sFrameBitmap = null; |
141 | 146 |
142 /** Screen height of the video feed. */ | 147 /** Lock to protect the frame bitmap reference. */ |
143 private static int sHeight = 0; | 148 private static final Object sFrameLock = new Object(); |
144 | |
145 /** Bitmap holding the latest screen image. */ | |
146 private static Bitmap sBitmap = null; | |
147 | |
148 /** Buffer holding the video feed. */ | |
149 private static ByteBuffer sBuffer = null; | |
150 | 149 |
151 /** Position of cursor hot-spot. */ | 150 /** Position of cursor hot-spot. */ |
152 private static Point sCursorHotspot = new Point(); | 151 private static Point sCursorHotspot = new Point(); |
153 | 152 |
154 /** Bitmap holding the cursor shape. */ | 153 /** Bitmap holding the cursor shape. */ |
155 private static Bitmap sCursorBitmap = null; | 154 private static Bitmap sCursorBitmap = null; |
156 | 155 |
157 /** Reports whenever the connection status changes. */ | 156 /** Reports whenever the connection status changes. */ |
158 private static void reportConnectionStatus(int state, int error) { | 157 private static void reportConnectionStatus(int state, int error) { |
159 if (state < SUCCESSFUL_CONNECTION && error == 0) { | 158 if (state < SUCCESSFUL_CONNECTION && error == 0) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 return true; | 293 return true; |
295 } | 294 } |
296 | 295 |
297 /** Performs the redrawing callback. This is a no-op if the window isn't vis
ible. */ | 296 /** Performs the redrawing callback. This is a no-op if the window isn't vis
ible. */ |
298 private static void redrawGraphicsInternal() { | 297 private static void redrawGraphicsInternal() { |
299 if (sRedrawCallback != null) | 298 if (sRedrawCallback != null) |
300 sRedrawCallback.run(); | 299 sRedrawCallback.run(); |
301 } | 300 } |
302 | 301 |
303 /** | 302 /** |
304 * Obtains the image buffer. | 303 * Returns a bitmap of the latest video frame. Called on the native graphics
thread when |
305 * This should not be called from the UI thread. (We prefer the native graph
ics thread.) | 304 * DesktopView is repainted. |
306 */ | 305 */ |
307 public static Bitmap retrieveVideoFrame() { | 306 public static Bitmap getVideoFrame() { |
308 if (Looper.myLooper() == Looper.getMainLooper()) { | 307 if (Looper.myLooper() == Looper.getMainLooper()) { |
309 Log.w("jniiface", "Canvas being redrawn on UI thread"); | 308 Log.w("jniiface", "Canvas being redrawn on UI thread"); |
310 } | 309 } |
311 | 310 |
312 if (!sConnected) { | 311 if (!sConnected) { |
313 return null; | 312 return null; |
314 } | 313 } |
315 | 314 |
316 // This is synchronized only to silence a findbugs warning about incorre
ct initialization of | 315 synchronized (sFrameLock) { |
317 // |sBitmap|. | 316 return sFrameBitmap; |
318 // TODO(lambroslambrou): Annotate this class as @NotThreadSafe to preven
t similar warnings | |
319 // in future. | |
320 synchronized (JniInterface.class) { | |
321 if (sBitmap == null || sBitmap.getWidth() != sWidth || sBitmap.getHe
ight() != sHeight) { | |
322 sBitmap = Bitmap.createBitmap(sWidth, sHeight, Bitmap.Config.ARG
B_8888); | |
323 } | |
324 } | 317 } |
325 | |
326 sBuffer.rewind(); | |
327 sBitmap.copyPixelsFromBuffer(sBuffer); | |
328 return sBitmap; | |
329 } | 318 } |
330 | 319 |
331 /** | 320 /** |
| 321 * Sets a new video frame. Called from native code on the native graphics th
read when a new |
| 322 * frame is allocated. |
| 323 */ |
| 324 private static void setVideoFrame(Bitmap bitmap) { |
| 325 if (Looper.myLooper() == Looper.getMainLooper()) { |
| 326 Log.w("jniiface", "Video frame updated on UI thread"); |
| 327 } |
| 328 |
| 329 synchronized (sFrameLock) { |
| 330 sFrameBitmap = bitmap; |
| 331 } |
| 332 } |
| 333 |
| 334 /** |
| 335 * Creates a new Bitmap to hold video frame pixels. Called by native code wh
ich stores a global |
| 336 * reference to the Bitmap and writes the decoded frame pixels to it. |
| 337 */ |
| 338 private static Bitmap newBitmap(int width, int height) { |
| 339 return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); |
| 340 } |
| 341 |
| 342 /** |
332 * Updates the cursor shape. This is called from native code on the graphics
thread when | 343 * Updates the cursor shape. This is called from native code on the graphics
thread when |
333 * receiving a new cursor shape from the host. | 344 * receiving a new cursor shape from the host. |
334 */ | 345 */ |
335 public static void updateCursorShape(int width, int height, int hotspotX, in
t hotspotY, | 346 public static void updateCursorShape(int width, int height, int hotspotX, in
t hotspotY, |
336 ByteBuffer buffer) { | 347 ByteBuffer buffer) { |
337 sCursorHotspot = new Point(hotspotX, hotspotY); | 348 sCursorHotspot = new Point(hotspotX, hotspotY); |
338 | 349 |
339 int[] data = new int[width * height]; | 350 int[] data = new int[width * height]; |
340 buffer.order(ByteOrder.LITTLE_ENDIAN); | 351 buffer.order(ByteOrder.LITTLE_ENDIAN); |
341 buffer.asIntBuffer().get(data, 0, data.length); | 352 buffer.asIntBuffer().get(data, 0, data.length); |
(...skipping 23 matching lines...) Expand all Loading... |
365 | 376 |
366 /** Schedules a redraw on the native graphics thread. */ | 377 /** Schedules a redraw on the native graphics thread. */ |
367 private static native void scheduleRedrawNative(); | 378 private static native void scheduleRedrawNative(); |
368 | 379 |
369 /** Passes mouse information to the native handling code. */ | 380 /** Passes mouse information to the native handling code. */ |
370 private static native void mouseActionNative(int x, int y, int whichButton,
boolean buttonDown); | 381 private static native void mouseActionNative(int x, int y, int whichButton,
boolean buttonDown); |
371 | 382 |
372 /** Passes key press information to the native handling code. */ | 383 /** Passes key press information to the native handling code. */ |
373 private static native void keyboardActionNative(int keyCode, boolean keyDown
); | 384 private static native void keyboardActionNative(int keyCode, boolean keyDown
); |
374 } | 385 } |
OLD | NEW |