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

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

Issue 1321223003: Use scan codes when sending keyboard events froms physical keyboard. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « no previous file | remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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; 5 package org.chromium.chromoting;
6 6
7 import android.annotation.SuppressLint; 7 import android.annotation.SuppressLint;
8 import android.content.Intent; 8 import android.content.Intent;
9 import android.content.pm.ApplicationInfo; 9 import android.content.pm.ApplicationInfo;
10 import android.content.pm.PackageManager; 10 import android.content.pm.PackageManager;
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 JniInterface.disconnectFromHost(); 221 JniInterface.disconnectFromHost();
222 return true; 222 return true;
223 } 223 }
224 if (id == R.id.actionbar_send_ctrl_alt_del) { 224 if (id == R.id.actionbar_send_ctrl_alt_del) {
225 int[] keys = { 225 int[] keys = {
226 KeyEvent.KEYCODE_CTRL_LEFT, 226 KeyEvent.KEYCODE_CTRL_LEFT,
227 KeyEvent.KEYCODE_ALT_LEFT, 227 KeyEvent.KEYCODE_ALT_LEFT,
228 KeyEvent.KEYCODE_FORWARD_DEL, 228 KeyEvent.KEYCODE_FORWARD_DEL,
229 }; 229 };
230 for (int key : keys) { 230 for (int key : keys) {
231 JniInterface.sendKeyEvent(key, true); 231 JniInterface.sendKeyEvent(0, key, true);
232 } 232 }
233 for (int key : keys) { 233 for (int key : keys) {
234 JniInterface.sendKeyEvent(key, false); 234 JniInterface.sendKeyEvent(0, key, false);
235 } 235 }
236 return true; 236 return true;
237 } 237 }
238 if (id == R.id.actionbar_help) { 238 if (id == R.id.actionbar_help) {
239 HelpActivity.launch(this, HELP_URL); 239 HelpActivity.launch(this, HELP_URL);
240 return true; 240 return true;
241 } 241 }
242 return super.onOptionsItemSelected(item); 242 return super.onOptionsItemSelected(item);
243 } 243 }
244 244
245 /** 245 /**
246 * Called once when a keyboard key is pressed, then again when that same key is released. This 246 * Called once when a keyboard key is pressed, then again when that same key is released. This
247 * is not guaranteed to be notified of all soft keyboard events: certian key boards might not 247 * is not guaranteed to be notified of all soft keyboard events: certian key boards might not
248 * call it at all, while others might skip it in certain situations (e.g. sw ipe input). 248 * call it at all, while others might skip it in certain situations (e.g. sw ipe input).
249 */ 249 */
250 @Override 250 @Override
251 public boolean dispatchKeyEvent(KeyEvent event) { 251 public boolean dispatchKeyEvent(KeyEvent event) {
252 int keyCode = event.getKeyCode(); 252 int keyCode = event.getKeyCode();
253 253
254 // Dispatch the back button to the system to handle navigation 254 // Dispatch the back button to the system to handle navigation
255 if (keyCode == KeyEvent.KEYCODE_BACK) { 255 if (keyCode == KeyEvent.KEYCODE_BACK) {
256 return super.dispatchKeyEvent(event); 256 return super.dispatchKeyEvent(event);
257 } 257 }
258 258
259 // Send TextEvent in two cases: 259 boolean pressed = event.getAction() == KeyEvent.ACTION_DOWN;
260
261 // Physical keyboard must work as if it is connected to the remote host
262 // and so events coming from physical keyboard never generate text
263 // events. Also scan codes must be used instead of key code, so that
264 // the keyboard layout selected on the client doesn't affect the key
265 // codes sent to the host.
266 if (event.getDeviceId() != KeyCharacterMap.VIRTUAL_KEYBOARD) {
267 return JniInterface.sendKeyEvent(event.getScanCode(), 0, pressed);
268 }
269
270 // Events received from software keyboards generate TextEvent in two
271 // cases:
260 // 1. This is an ACTION_MULTIPLE event. 272 // 1. This is an ACTION_MULTIPLE event.
261 // 2. The event was generated by on-screen keyboard and Ctrl, Alt and 273 // 2. Ctrl, Alt and Meta are not pressed.
262 // Meta are not pressed.
263 // This ensures that on-screen keyboard always injects input that 274 // This ensures that on-screen keyboard always injects input that
264 // correspond to what user sees on the screen, while physical keyboard 275 // correspond to what user sees on the screen, while physical keyboard
265 // acts as if it is connected to the remote host. 276 // acts as if it is connected to the remote host.
266 if (event.getAction() == KeyEvent.ACTION_MULTIPLE) { 277 if (event.getAction() == KeyEvent.ACTION_MULTIPLE) {
267 JniInterface.sendTextEvent(event.getCharacters()); 278 JniInterface.sendTextEvent(event.getCharacters());
268 return true; 279 return true;
269 } 280 }
270 281
271 boolean pressed = event.getAction() == KeyEvent.ACTION_DOWN;
272
273 // For Enter getUnicodeChar() returns 10 (line feed), but we still 282 // For Enter getUnicodeChar() returns 10 (line feed), but we still
274 // want to send it as KeyEvent. 283 // want to send it as KeyEvent.
275 int unicode = keyCode != KeyEvent.KEYCODE_ENTER ? event.getUnicodeChar() : 0; 284 int unicode = keyCode != KeyEvent.KEYCODE_ENTER ? event.getUnicodeChar() : 0;
276 285
277 boolean no_modifiers = !event.isAltPressed() 286 boolean no_modifiers = !event.isAltPressed()
278 && !event.isCtrlPressed() && !event.isMetaPressed(); 287 && !event.isCtrlPressed() && !event.isMetaPressed();
279 288
280 if (event.getDeviceId() == KeyCharacterMap.VIRTUAL_KEYBOARD 289 if (pressed && unicode != 0 && no_modifiers) {
281 && pressed && unicode != 0 && no_modifiers) {
282 mPressedTextKeys.add(keyCode); 290 mPressedTextKeys.add(keyCode);
283 int[] codePoints = { unicode }; 291 int[] codePoints = { unicode };
284 JniInterface.sendTextEvent(new String(codePoints, 0, 1)); 292 JniInterface.sendTextEvent(new String(codePoints, 0, 1));
285 return true; 293 return true;
286 } 294 }
287 295
288 if (!pressed && mPressedTextKeys.contains(keyCode)) { 296 if (!pressed && mPressedTextKeys.contains(keyCode)) {
289 mPressedTextKeys.remove(keyCode); 297 mPressedTextKeys.remove(keyCode);
290 return true; 298 return true;
291 } 299 }
292 300
293 switch (keyCode) { 301 switch (keyCode) {
302 // KEYCODE_AT, KEYCODE_POUND, KEYCODE_STAR and KEYCODE_PLUS are
303 // deprecated, but they still need to be here for older devices and
304 // third-party keyboards that may still generate these events. See
305 // https://source.android.com/devices/input/keyboard-devices.html#le gacy-unsupported-keys
294 case KeyEvent.KEYCODE_AT: 306 case KeyEvent.KEYCODE_AT:
295 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed); 307 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, presse d);
296 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_2, pressed); 308 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_2, pressed);
297 return true; 309 return true;
298 310
299 case KeyEvent.KEYCODE_POUND: 311 case KeyEvent.KEYCODE_POUND:
300 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed); 312 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, presse d);
301 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_3, pressed); 313 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_3, pressed);
302 return true; 314 return true;
303 315
304 case KeyEvent.KEYCODE_STAR: 316 case KeyEvent.KEYCODE_STAR:
305 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed); 317 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, presse d);
306 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_8, pressed); 318 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_8, pressed);
307 return true; 319 return true;
308 320
309 case KeyEvent.KEYCODE_PLUS: 321 case KeyEvent.KEYCODE_PLUS:
310 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed); 322 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, presse d);
311 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_EQUALS, pressed); 323 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_EQUALS, pressed);
312 return true; 324 return true;
313 325
314 default: 326 default:
315 // We try to send all other key codes to the host directly. 327 // We try to send all other key codes to the host directly.
316 return JniInterface.sendKeyEvent(keyCode, pressed); 328 return JniInterface.sendKeyEvent(0, keyCode, pressed);
317 } 329 }
318 } 330 }
319 } 331 }
OLDNEW
« no previous file with comments | « no previous file | remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698