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

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

Issue 29583003: Use jni_generator in Chromoting Android client (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed Created 7 years, 1 month 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.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;
11 import android.content.DialogInterface; 11 import android.content.DialogInterface;
12 import android.content.SharedPreferences; 12 import android.content.SharedPreferences;
13 import android.graphics.Bitmap; 13 import android.graphics.Bitmap;
14 import android.graphics.Point; 14 import android.graphics.Point;
15 import android.os.Looper; 15 import android.os.Looper;
16 import android.text.InputType; 16 import android.text.InputType;
17 import android.util.Log; 17 import android.util.Log;
18 import android.view.KeyEvent; 18 import android.view.KeyEvent;
19 import android.view.View; 19 import android.view.View;
20 import android.view.inputmethod.EditorInfo; 20 import android.view.inputmethod.EditorInfo;
21 import android.widget.CheckBox; 21 import android.widget.CheckBox;
22 import android.widget.TextView; 22 import android.widget.TextView;
23 import android.widget.Toast; 23 import android.widget.Toast;
24 24
25 import org.chromium.base.CalledByNative;
26 import org.chromium.base.JNINamespace;
25 import org.chromium.chromoting.R; 27 import org.chromium.chromoting.R;
26 28
27 import java.nio.ByteBuffer; 29 import java.nio.ByteBuffer;
28 import java.nio.ByteOrder; 30 import java.nio.ByteOrder;
29 31
30 /** 32 /**
31 * Initializes the Chromium remoting library, and provides JNI calls into it. 33 * Initializes the Chromium remoting library, and provides JNI calls into it.
32 * All interaction with the native code is centralized in this class. 34 * All interaction with the native code is centralized in this class.
33 */ 35 */
36 @JNINamespace("remoting")
34 public class JniInterface { 37 public class JniInterface {
35 /** The status code indicating successful connection. */ 38 /** The status code indicating successful connection. */
36 private static final int SUCCESSFUL_CONNECTION = 3; 39 private static final int SUCCESSFUL_CONNECTION = 3;
37 40
38 /** The application context. */ 41 /** The application context. */
39 private static Activity sContext = null; 42 private static Activity sContext = null;
40 43
41 /* 44 /*
42 * Library-loading state machine. 45 * Library-loading state machine.
43 */ 46 */
44 /** Whether we've already loaded the library. */ 47 /** Whether we've already loaded the library. */
45 private static boolean sLoaded = false; 48 private static boolean sLoaded = false;
46 49
47 /** 50 /**
48 * To be called once from the main Activity. Any subsequent calls will updat e the application 51 * To be called once from the main Activity. Any subsequent calls will updat e the application
49 * context, but not reload the library. This is useful e.g. when the activit y is closed and the 52 * context, but not reload the library. This is useful e.g. when the activit y is closed and the
50 * user later wants to return to the application. 53 * user later wants to return to the application.
51 */ 54 */
52 public static void loadLibrary(Activity context) { 55 public static void loadLibrary(Activity context) {
53 sContext = context; 56 sContext = context;
54 57
55 synchronized(JniInterface.class) { 58 synchronized(JniInterface.class) {
56 if (sLoaded) return; 59 if (sLoaded) return;
57 } 60 }
58 61
59 System.loadLibrary("remoting_client_jni"); 62 System.loadLibrary("remoting_client_jni");
60 loadNative(context); 63
64 nativeLoadNative(context);
61 sLoaded = true; 65 sLoaded = true;
62 } 66 }
63 67
64 /** Performs the native portion of the initialization. */ 68 /** Performs the native portion of the initialization. */
65 private static native void loadNative(Context context); 69 private static native void nativeLoadNative(Context context);
66 70
67 /* 71 /*
68 * API/OAuth2 keys access. 72 * API/OAuth2 keys access.
69 */ 73 */
70 public static native String getApiKey(); 74 public static native String nativeGetApiKey();
71 public static native String getClientId(); 75 public static native String nativeGetClientId();
72 public static native String getClientSecret(); 76 public static native String nativeGetClientSecret();
73 77
74 /* 78 /*
75 * Connection-initiating state machine. 79 * Connection-initiating state machine.
76 */ 80 */
77 /** Whether the native code is attempting a connection. */ 81 /** Whether the native code is attempting a connection. */
78 private static boolean sConnected = false; 82 private static boolean sConnected = false;
79 83
80 /** Callback to signal upon successful connection. */ 84 /** Callback to signal upon successful connection. */
81 private static Runnable sSuccessCallback = null; 85 private static Runnable sSuccessCallback = null;
82 86
83 /** Dialog for reporting connection progress. */ 87 /** Dialog for reporting connection progress. */
84 private static ProgressDialog sProgressIndicator = null; 88 private static ProgressDialog sProgressIndicator = null;
85 89
86 /** Attempts to form a connection to the user-selected host. */ 90 /** Attempts to form a connection to the user-selected host. */
87 public static void connectToHost(String username, String authToken, 91 public static void connectToHost(String username, String authToken,
88 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) { 92 String hostJid, String hostId, String hostPubkey, Runnable successCa llback) {
89 synchronized(JniInterface.class) { 93 synchronized(JniInterface.class) {
90 if (!sLoaded) return; 94 if (!sLoaded) return;
91 95
92 if (sConnected) { 96 if (sConnected) {
93 disconnectFromHost(); 97 disconnectFromHost();
94 } 98 }
95 } 99 }
96 100
97 sSuccessCallback = successCallback; 101 sSuccessCallback = successCallback;
98 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ; 102 SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE) ;
99 connectNative(username, authToken, hostJid, hostId, hostPubkey, 103 nativeConnect(username, authToken, hostJid, hostId, hostPubkey,
100 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", "")); 104 prefs.getString(hostId + "_id", ""), prefs.getString(hostId + "_ secret", ""));
101 sConnected = true; 105 sConnected = true;
102 } 106 }
103 107
104 /** Severs the connection and cleans up. */ 108 /** Severs the connection and cleans up. */
105 public static void disconnectFromHost() { 109 public static void disconnectFromHost() {
106 synchronized(JniInterface.class) { 110 synchronized(JniInterface.class) {
107 if (!sLoaded || !sConnected) return; 111 if (!sLoaded || !sConnected) return;
108 112
109 if (sProgressIndicator != null) { 113 if (sProgressIndicator != null) {
110 sProgressIndicator.dismiss(); 114 sProgressIndicator.dismiss();
111 sProgressIndicator = null; 115 sProgressIndicator = null;
112 } 116 }
113 } 117 }
114 118
115 disconnectNative(); 119 nativeDisconnect();
116 sSuccessCallback = null; 120 sSuccessCallback = null;
117 sConnected = false; 121 sConnected = false;
118 122
119 // Drop the reference to free the Bitmap for GC. 123 // Drop the reference to free the Bitmap for GC.
120 synchronized (sFrameLock) { 124 synchronized (sFrameLock) {
121 sFrameBitmap = null; 125 sFrameBitmap = null;
122 } 126 }
123 } 127 }
124 128
125 /** Performs the native portion of the connection. */ 129 /** Performs the native portion of the connection. */
126 private static native void connectNative(String username, String authToken, String hostJid, 130 private static native void nativeConnect(String username, String authToken, String hostJid,
127 String hostId, String hostPubkey, String pairId, String pairSecret); 131 String hostId, String hostPubkey, String pairId, String pairSecret);
128 132
129 /** Performs the native portion of the cleanup. */ 133 /** Performs the native portion of the cleanup. */
130 private static native void disconnectNative(); 134 private static native void nativeDisconnect();
131 135
132 /** Position of cursor hotspot within cursor image. */ 136 /** Position of cursor hotspot within cursor image. */
133 public static Point getCursorHotspot() { return sCursorHotspot; } 137 public static Point getCursorHotspot() { return sCursorHotspot; }
134 138
135 /** Returns the current cursor shape. */ 139 /** Returns the current cursor shape. */
136 public static Bitmap getCursorBitmap() { return sCursorBitmap; } 140 public static Bitmap getCursorBitmap() { return sCursorBitmap; }
137 141
138 /* 142 /*
139 * Entry points *from* the native code. 143 * Entry points *from* the native code.
140 */ 144 */
141 /** Callback to signal whenever we need to redraw. */ 145 /** Callback to signal whenever we need to redraw. */
142 private static Runnable sRedrawCallback = null; 146 private static Runnable sRedrawCallback = null;
143 147
144 /** Bitmap holding a copy of the latest video frame. */ 148 /** Bitmap holding a copy of the latest video frame. */
145 private static Bitmap sFrameBitmap = null; 149 private static Bitmap sFrameBitmap = null;
146 150
147 /** Lock to protect the frame bitmap reference. */ 151 /** Lock to protect the frame bitmap reference. */
148 private static final Object sFrameLock = new Object(); 152 private static final Object sFrameLock = new Object();
149 153
150 /** Position of cursor hot-spot. */ 154 /** Position of cursor hot-spot. */
151 private static Point sCursorHotspot = new Point(); 155 private static Point sCursorHotspot = new Point();
152 156
153 /** Bitmap holding the cursor shape. */ 157 /** Bitmap holding the cursor shape. */
154 private static Bitmap sCursorBitmap = null; 158 private static Bitmap sCursorBitmap = null;
155 159
156 /** Reports whenever the connection status changes. */ 160 /** Reports whenever the connection status changes. */
161 @CalledByNative
157 private static void reportConnectionStatus(int state, int error) { 162 private static void reportConnectionStatus(int state, int error) {
158 if (state < SUCCESSFUL_CONNECTION && error == 0) { 163 if (state < SUCCESSFUL_CONNECTION && error == 0) {
159 // The connection is still being established, so we'll report the cu rrent progress. 164 // The connection is still being established, so we'll report the cu rrent progress.
160 synchronized (JniInterface.class) { 165 synchronized (JniInterface.class) {
161 if (sProgressIndicator == null) { 166 if (sProgressIndicator == null) {
162 sProgressIndicator = ProgressDialog.show(sContext, sContext. 167 sProgressIndicator = ProgressDialog.show(sContext, sContext.
163 getString(R.string.progress_title), sContext.getReso urces(). 168 getString(R.string.progress_title), sContext.getReso urces().
164 getStringArray(R.array.protoc_states)[state], true, true, 169 getStringArray(R.array.protoc_states)[state], true, true,
165 new DialogInterface.OnCancelListener() { 170 new DialogInterface.OnCancelListener() {
166 @Override 171 @Override
(...skipping 27 matching lines...) Expand all
194 } else { 199 } else {
195 Toast.makeText(sContext, sContext.getResources().getStringArray( 200 Toast.makeText(sContext, sContext.getResources().getStringArray(
196 R.array.protoc_states)[state] + (error == 0 ? "" : ": " + 201 R.array.protoc_states)[state] + (error == 0 ? "" : ": " +
197 sContext.getResources().getStringArray(R.array.protoc_er rors)[error]), 202 sContext.getResources().getStringArray(R.array.protoc_er rors)[error]),
198 Toast.LENGTH_LONG).show(); 203 Toast.LENGTH_LONG).show();
199 } 204 }
200 } 205 }
201 } 206 }
202 207
203 /** Prompts the user to enter a PIN. */ 208 /** Prompts the user to enter a PIN. */
209 @CalledByNative
204 private static void displayAuthenticationPrompt(boolean pairingSupported) { 210 private static void displayAuthenticationPrompt(boolean pairingSupported) {
205 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext); 211 AlertDialog.Builder pinPrompt = new AlertDialog.Builder(sContext);
206 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title)); 212 pinPrompt.setTitle(sContext.getString(R.string.pin_entry_title));
207 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message)); 213 pinPrompt.setMessage(sContext.getString(R.string.pin_entry_message));
208 pinPrompt.setIcon(android.R.drawable.ic_lock_lock); 214 pinPrompt.setIcon(android.R.drawable.ic_lock_lock);
209 215
210 final View pinEntry = sContext.getLayoutInflater().inflate(R.layout.pin_ dialog, null); 216 final View pinEntry = sContext.getLayoutInflater().inflate(R.layout.pin_ dialog, null);
211 pinPrompt.setView(pinEntry); 217 pinPrompt.setView(pinEntry);
212 218
213 final TextView pinTextView = (TextView)pinEntry.findViewById(R.id.pin_di alog_text); 219 final TextView pinTextView = (TextView)pinEntry.findViewById(R.id.pin_di alog_text);
214 final CheckBox pinCheckBox = (CheckBox)pinEntry.findViewById(R.id.pin_di alog_check); 220 final CheckBox pinCheckBox = (CheckBox)pinEntry.findViewById(R.id.pin_di alog_check);
215 221
216 if (!pairingSupported) { 222 if (!pairingSupported) {
217 pinCheckBox.setChecked(false); 223 pinCheckBox.setChecked(false);
218 pinCheckBox.setVisibility(View.GONE); 224 pinCheckBox.setVisibility(View.GONE);
219 } 225 }
220 226
221 pinPrompt.setPositiveButton( 227 pinPrompt.setPositiveButton(
222 R.string.pin_entry_connect, new DialogInterface.OnClickListener( ) { 228 R.string.pin_entry_connect, new DialogInterface.OnClickListener( ) {
223 @Override 229 @Override
224 public void onClick(DialogInterface dialog, int which) { 230 public void onClick(DialogInterface dialog, int which) {
225 Log.i("jniiface", "User provided a PIN code"); 231 Log.i("jniiface", "User provided a PIN code");
226 authenticationResponse(String.valueOf(pinTextView.getTex t()), 232 nativeAuthenticationResponse(String.valueOf(pinTextView. getText()),
227 pinCheckBox.isChecked()); 233 pinCheckBox.isChecked());
228 } 234 }
229 }); 235 });
230 236
231 pinPrompt.setNegativeButton( 237 pinPrompt.setNegativeButton(
232 R.string.pin_entry_cancel, new DialogInterface.OnClickListener() { 238 R.string.pin_entry_cancel, new DialogInterface.OnClickListener() {
233 @Override 239 @Override
234 public void onClick(DialogInterface dialog, int which) { 240 public void onClick(DialogInterface dialog, int which) {
235 Log.i("jniiface", "User canceled pin entry prompt"); 241 Log.i("jniiface", "User canceled pin entry prompt");
236 Toast.makeText(sContext, 242 Toast.makeText(sContext,
237 sContext.getString(R.string.msg_pin_canceled), 243 sContext.getString(R.string.msg_pin_canceled),
(...skipping 21 matching lines...) Expand all
259 public void onCancel(DialogInterface dialog) { 265 public void onCancel(DialogInterface dialog) {
260 // The user backed out of the dialog (equivalent to the cancel button). 266 // The user backed out of the dialog (equivalent to the cancel button).
261 pinDialog.getButton(AlertDialog.BUTTON_NEGATIVE).perform Click(); 267 pinDialog.getButton(AlertDialog.BUTTON_NEGATIVE).perform Click();
262 } 268 }
263 }); 269 });
264 270
265 pinDialog.show(); 271 pinDialog.show();
266 } 272 }
267 273
268 /** Saves newly-received pairing credentials to permanent storage. */ 274 /** Saves newly-received pairing credentials to permanent storage. */
275 @CalledByNative
269 private static void commitPairingCredentials(String host, byte[] id, byte[] secret) { 276 private static void commitPairingCredentials(String host, byte[] id, byte[] secret) {
270 synchronized (sContext) { 277 synchronized (sContext) {
271 sContext.getPreferences(Activity.MODE_PRIVATE).edit(). 278 sContext.getPreferences(Activity.MODE_PRIVATE).edit().
272 putString(host + "_id", new String(id)). 279 putString(host + "_id", new String(id)).
273 putString(host + "_secret", new String(secret)). 280 putString(host + "_secret", new String(secret)).
274 apply(); 281 apply();
275 } 282 }
276 } 283 }
277 284
278 /** 285 /**
279 * Sets the redraw callback to the provided functor. Provide a value of null whenever the 286 * Sets the redraw callback to the provided functor. Provide a value of null whenever the
280 * window is no longer visible so that we don't continue to draw onto it. 287 * window is no longer visible so that we don't continue to draw onto it.
281 */ 288 */
282 public static void provideRedrawCallback(Runnable redrawCallback) { 289 public static void provideRedrawCallback(Runnable redrawCallback) {
283 sRedrawCallback = redrawCallback; 290 sRedrawCallback = redrawCallback;
284 } 291 }
285 292
286 /** Forces the native graphics thread to redraw to the canvas. */ 293 /** Forces the native graphics thread to redraw to the canvas. */
287 public static boolean redrawGraphics() { 294 public static boolean redrawGraphics() {
288 synchronized(JniInterface.class) { 295 synchronized(JniInterface.class) {
289 if (!sConnected || sRedrawCallback == null) return false; 296 if (!sConnected || sRedrawCallback == null) return false;
290 } 297 }
291 298
292 scheduleRedrawNative(); 299 nativeScheduleRedraw();
293 return true; 300 return true;
294 } 301 }
295 302
296 /** Performs the redrawing callback. This is a no-op if the window isn't vis ible. */ 303 /** Performs the redrawing callback. This is a no-op if the window isn't vis ible. */
304 @CalledByNative
297 private static void redrawGraphicsInternal() { 305 private static void redrawGraphicsInternal() {
298 if (sRedrawCallback != null) 306 if (sRedrawCallback != null) {
299 sRedrawCallback.run(); 307 sRedrawCallback.run();
308 }
300 } 309 }
301 310
302 /** 311 /**
303 * Returns a bitmap of the latest video frame. Called on the native graphics thread when 312 * Returns a bitmap of the latest video frame. Called on the native graphics thread when
304 * DesktopView is repainted. 313 * DesktopView is repainted.
305 */ 314 */
306 public static Bitmap getVideoFrame() { 315 public static Bitmap getVideoFrame() {
307 if (Looper.myLooper() == Looper.getMainLooper()) { 316 if (Looper.myLooper() == Looper.getMainLooper()) {
308 Log.w("jniiface", "Canvas being redrawn on UI thread"); 317 Log.w("jniiface", "Canvas being redrawn on UI thread");
309 } 318 }
310 319
311 if (!sConnected) { 320 if (!sConnected) {
312 return null; 321 return null;
313 } 322 }
314 323
315 synchronized (sFrameLock) { 324 synchronized (sFrameLock) {
316 return sFrameBitmap; 325 return sFrameBitmap;
317 } 326 }
318 } 327 }
319 328
320 /** 329 /**
321 * Sets a new video frame. Called from native code on the native graphics th read when a new 330 * Sets a new video frame. Called on the native graphics thread when a new f rame is allocated.
322 * frame is allocated.
323 */ 331 */
332 @CalledByNative
324 private static void setVideoFrame(Bitmap bitmap) { 333 private static void setVideoFrame(Bitmap bitmap) {
325 if (Looper.myLooper() == Looper.getMainLooper()) { 334 if (Looper.myLooper() == Looper.getMainLooper()) {
326 Log.w("jniiface", "Video frame updated on UI thread"); 335 Log.w("jniiface", "Video frame updated on UI thread");
327 } 336 }
328 337
329 synchronized (sFrameLock) { 338 synchronized (sFrameLock) {
330 sFrameBitmap = bitmap; 339 sFrameBitmap = bitmap;
331 } 340 }
332 } 341 }
333 342
334 /** 343 /**
335 * Creates a new Bitmap to hold video frame pixels. Called by native code wh ich stores a global 344 * 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. 345 * reference to the Bitmap and writes the decoded frame pixels to it.
337 */ 346 */
347 @CalledByNative
338 private static Bitmap newBitmap(int width, int height) { 348 private static Bitmap newBitmap(int width, int height) {
339 return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 349 return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
340 } 350 }
341 351
342 /** 352 /**
343 * Updates the cursor shape. This is called from native code on the graphics thread when 353 * Updates the cursor shape. This is called on the graphics thread when rece iving a new cursor
344 * receiving a new cursor shape from the host. 354 * shape from the host.
345 */ 355 */
356 @CalledByNative
346 public static void updateCursorShape(int width, int height, int hotspotX, in t hotspotY, 357 public static void updateCursorShape(int width, int height, int hotspotX, in t hotspotY,
347 ByteBuffer buffer) { 358 ByteBuffer buffer) {
348 sCursorHotspot = new Point(hotspotX, hotspotY); 359 sCursorHotspot = new Point(hotspotX, hotspotY);
349 360
350 int[] data = new int[width * height]; 361 int[] data = new int[width * height];
351 buffer.order(ByteOrder.LITTLE_ENDIAN); 362 buffer.order(ByteOrder.LITTLE_ENDIAN);
352 buffer.asIntBuffer().get(data, 0, data.length); 363 buffer.asIntBuffer().get(data, 0, data.length);
353 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888); 364 sCursorBitmap = Bitmap.createBitmap(data, width, height, Bitmap.Config.A RGB_8888);
354 } 365 }
355 366
356 /** Moves the mouse cursor, possibly while clicking the specified (nonnegati ve) button. */ 367 /** Moves the mouse cursor, possibly while clicking the specified (nonnegati ve) button. */
357 public static void mouseAction(int x, int y, int whichButton, boolean button Down) { 368 public static void mouseAction(int x, int y, int whichButton, boolean button Down) {
358 if (!sConnected) { 369 if (!sConnected) {
359 return; 370 return;
360 } 371 }
361 372
362 mouseActionNative(x, y, whichButton, buttonDown); 373 nativeMouseAction(x, y, whichButton, buttonDown);
363 } 374 }
364 375
365 /** Presses and releases the specified (nonnegative) key. */ 376 /** Presses and releases the specified (nonnegative) key. */
366 public static void keyboardAction(int keyCode, boolean keyDown) { 377 public static void keyboardAction(int keyCode, boolean keyDown) {
367 if (!sConnected) { 378 if (!sConnected) {
368 return; 379 return;
369 } 380 }
370 381
371 keyboardActionNative(keyCode, keyDown); 382 nativeKeyboardAction(keyCode, keyDown);
372 } 383 }
373 384
374 /** Performs the native response to the user's PIN. */ 385 /** Performs the native response to the user's PIN. */
375 private static native void authenticationResponse(String pin, boolean create Pair); 386 private static native void nativeAuthenticationResponse(String pin, boolean createPair);
376 387
377 /** Schedules a redraw on the native graphics thread. */ 388 /** Schedules a redraw on the native graphics thread. */
378 private static native void scheduleRedrawNative(); 389 private static native void nativeScheduleRedraw();
379 390
380 /** Passes mouse information to the native handling code. */ 391 /** Passes mouse information to the native handling code. */
381 private static native void mouseActionNative(int x, int y, int whichButton, boolean buttonDown); 392 private static native void nativeMouseAction(int x, int y, int whichButton, boolean buttonDown);
382 393
383 /** Passes key press information to the native handling code. */ 394 /** Passes key press information to the native handling code. */
384 private static native void keyboardActionNative(int keyCode, boolean keyDown ); 395 private static native void nativeKeyboardAction(int keyCode, boolean keyDown );
385 } 396 }
OLDNEW
« no previous file with comments | « remoting/android/java/src/org/chromium/chromoting/Chromoting.java ('k') | remoting/client/jni/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698