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

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java

Issue 373523002: Send correct key-codes when doing composition events instead of always 0. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed style of Java member variables Created 6 years, 5 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 | content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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.content.browser.input; 5 package org.chromium.content.browser.input;
6 6
7 import android.os.Handler; 7 import android.os.Handler;
8 import android.os.ResultReceiver; 8 import android.os.ResultReceiver;
9 import android.os.SystemClock; 9 import android.os.SystemClock;
10 import android.text.Editable; 10 import android.text.Editable;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 static int sModifierCapsLockOn; 117 static int sModifierCapsLockOn;
118 static int sModifierNumLockOn; 118 static int sModifierNumLockOn;
119 119
120 private long mNativeImeAdapterAndroid; 120 private long mNativeImeAdapterAndroid;
121 private InputMethodManagerWrapper mInputMethodManagerWrapper; 121 private InputMethodManagerWrapper mInputMethodManagerWrapper;
122 private AdapterInputConnection mInputConnection; 122 private AdapterInputConnection mInputConnection;
123 private final ImeAdapterDelegate mViewEmbedder; 123 private final ImeAdapterDelegate mViewEmbedder;
124 private final Handler mHandler; 124 private final Handler mHandler;
125 private DelayedDismissInput mDismissInput = null; 125 private DelayedDismissInput mDismissInput = null;
126 private int mTextInputType; 126 private int mTextInputType;
127 private String mLastComposeText;
128
129 @VisibleForTesting
130 int mLastComposeKeyCode;
127 131
128 @VisibleForTesting 132 @VisibleForTesting
129 boolean mIsShowWithoutHideOutstanding = false; 133 boolean mIsShowWithoutHideOutstanding = false;
130 134
131 /** 135 /**
132 * @param wrapper InputMethodManagerWrapper that should receive all the call directed to 136 * @param wrapper InputMethodManagerWrapper that should receive all the call directed to
133 * InputMethodManager. 137 * InputMethodManager.
134 * @param embedder The view that is used for callbacks from ImeAdapter. 138 * @param embedder The view that is used for callbacks from ImeAdapter.
135 */ 139 */
136 public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embe dder) { 140 public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embe dder) {
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 314 }
311 315
312 private int shouldSendKeyEventWithKeyCode(String text) { 316 private int shouldSendKeyEventWithKeyCode(String text) {
313 if (text.length() != 1) return COMPOSITION_KEY_CODE; 317 if (text.length() != 1) return COMPOSITION_KEY_CODE;
314 318
315 if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER; 319 if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER;
316 else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB; 320 else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB;
317 else return COMPOSITION_KEY_CODE; 321 else return COMPOSITION_KEY_CODE;
318 } 322 }
319 323
324 private int androidKeyCodeForCharacter(char chr) {
325 // This is currently only called for letters due to the nature of
326 // composition on Android.
327 switch (chr) {
328 case 'A':
329 case 'a':
330 return KeyEvent.KEYCODE_A;
331 case 'B':
332 case 'b':
333 return KeyEvent.KEYCODE_B;
334 case 'C':
335 case 'c':
336 return KeyEvent.KEYCODE_C;
337 case 'D':
338 case 'd':
339 return KeyEvent.KEYCODE_D;
340 case 'E':
341 case 'e':
342 return KeyEvent.KEYCODE_E;
343 case 'F':
344 case 'f':
345 return KeyEvent.KEYCODE_F;
346 case 'G':
347 case 'g':
348 return KeyEvent.KEYCODE_G;
349 case 'H':
350 case 'h':
351 return KeyEvent.KEYCODE_H;
352 case 'I':
353 case 'i':
354 return KeyEvent.KEYCODE_I;
355 case 'J':
356 case 'j':
357 return KeyEvent.KEYCODE_J;
358 case 'K':
359 case 'k':
360 return KeyEvent.KEYCODE_K;
361 case 'L':
362 case 'l':
363 return KeyEvent.KEYCODE_L;
364 case 'M':
365 case 'm':
366 return KeyEvent.KEYCODE_M;
367 case 'N':
368 case 'n':
369 return KeyEvent.KEYCODE_N;
370 case 'O':
371 case 'o':
372 return KeyEvent.KEYCODE_O;
373 case 'P':
374 case 'p':
375 return KeyEvent.KEYCODE_P;
376 case 'Q':
377 case 'q':
378 return KeyEvent.KEYCODE_Q;
379 case 'R':
380 case 'r':
381 return KeyEvent.KEYCODE_R;
382 case 'S':
383 case 's':
384 return KeyEvent.KEYCODE_S;
385 case 'T':
386 case 't':
387 return KeyEvent.KEYCODE_T;
388 case 'U':
389 case 'u':
390 return KeyEvent.KEYCODE_U;
391 case 'V':
392 case 'v':
393 return KeyEvent.KEYCODE_V;
394 case 'W':
395 case 'w':
396 return KeyEvent.KEYCODE_W;
397 case 'X':
398 case 'x':
399 return KeyEvent.KEYCODE_X;
400 case 'Y':
401 case 'y':
402 return KeyEvent.KEYCODE_Y;
403 case 'Z':
404 case 'z':
405 return KeyEvent.KEYCODE_Z;
406
407 default:
408 return 0;
409 }
410 }
411
320 void sendKeyEventWithKeyCode(int keyCode, int flags) { 412 void sendKeyEventWithKeyCode(int keyCode, int flags) {
321 long eventTime = SystemClock.uptimeMillis(); 413 long eventTime = SystemClock.uptimeMillis();
322 translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime, 414 translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
323 KeyEvent.ACTION_DOWN, keyCode, 0, 0, 415 KeyEvent.ACTION_DOWN, keyCode, 0, 0,
324 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 416 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
325 flags)); 417 flags));
326 translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), ev entTime, 418 translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), ev entTime,
327 KeyEvent.ACTION_UP, keyCode, 0, 0, 419 KeyEvent.ACTION_UP, keyCode, 0, 0,
328 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 420 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
329 flags)); 421 flags));
330 } 422 }
331 423
332 // Calls from Java to C++ 424 // Calls from Java to C++
333 425
334 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP osition, 426 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP osition,
335 boolean isCommit) { 427 boolean isCommit) {
336 if (mNativeImeAdapterAndroid == 0) return false; 428 if (mNativeImeAdapterAndroid == 0) return false;
337 String textStr = text.toString(); 429 String textStr = text.toString();
338 430
339 // Committing an empty string finishes the current composition. 431 // Committing an empty string finishes the current composition.
340 boolean isFinish = textStr.isEmpty(); 432 boolean isFinish = textStr.isEmpty();
341 mViewEmbedder.onImeEvent(isFinish); 433 mViewEmbedder.onImeEvent(isFinish);
342 int keyCode = shouldSendKeyEventWithKeyCode(textStr); 434 int keyCode = shouldSendKeyEventWithKeyCode(textStr);
343 long timeStampMs = SystemClock.uptimeMillis(); 435 long timeStampMs = SystemClock.uptimeMillis();
344 436
345 if (keyCode != COMPOSITION_KEY_CODE) { 437 if (keyCode != COMPOSITION_KEY_CODE) {
346 sendKeyEventWithKeyCode(keyCode, 438 sendKeyEventWithKeyCode(keyCode,
347 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE) ; 439 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE) ;
348 } else { 440 } else {
441 if (mLastComposeText == null) {
442 if (textStr.length() == 1)
443 keyCode = androidKeyCodeForCharacter(textStr.charAt(0));
aurimas (slooooooooow) 2014/07/07 17:05:20 Android already has tools to convert characters to
bcwhite 2014/07/08 18:56:03 A little convoluted what with creating the event a
jdduke (slow) 2014/07/08 19:53:54 Hmm, should we be using that function even though
444 } else {
445 if (textStr.length() == mLastComposeText.length() + 1)
446 keyCode = androidKeyCodeForCharacter(textStr.charAt(textStr. length() - 1));
447 else if (textStr.length() == mLastComposeText.length() - 1)
448 keyCode = KeyEvent.KEYCODE_DEL;
449 }
guohui 2014/07/04 21:56:13 we can get more accurate results if you check both
450 mLastComposeText = textStr;
451 mLastComposeKeyCode = keyCode;
452
349 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawK eyDown, 453 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawK eyDown,
350 timeStampMs, keyCode, 0); 454 timeStampMs, keyCode, 0);
351 if (isCommit) { 455 if (isCommit) {
352 nativeCommitText(mNativeImeAdapterAndroid, textStr); 456 nativeCommitText(mNativeImeAdapterAndroid, textStr);
353 } else { 457 } else {
354 nativeSetComposingText(mNativeImeAdapterAndroid, text, textStr, newCursorPosition); 458 nativeSetComposingText(mNativeImeAdapterAndroid, text, textStr, newCursorPosition);
355 } 459 }
356 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyU p, 460 nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyU p,
357 timeStampMs, keyCode, 0); 461 timeStampMs, keyCode, 0);
358 } 462 }
359 463
360 return true; 464 return true;
361 } 465 }
362 466
363 void finishComposingText() { 467 void finishComposingText() {
364 if (mNativeImeAdapterAndroid == 0) return; 468 if (mNativeImeAdapterAndroid == 0) return;
469 mLastComposeText = null;
365 nativeFinishComposingText(mNativeImeAdapterAndroid); 470 nativeFinishComposingText(mNativeImeAdapterAndroid);
366 } 471 }
367 472
368 boolean translateAndSendNativeEvents(KeyEvent event) { 473 boolean translateAndSendNativeEvents(KeyEvent event) {
369 if (mNativeImeAdapterAndroid == 0) return false; 474 if (mNativeImeAdapterAndroid == 0) return false;
370 475
371 int action = event.getAction(); 476 int action = event.getAction();
372 if (action != KeyEvent.ACTION_DOWN && 477 if (action != KeyEvent.ACTION_DOWN &&
373 action != KeyEvent.ACTION_UP) { 478 action != KeyEvent.ACTION_UP) {
374 // action == KeyEvent.ACTION_MULTIPLE 479 // action == KeyEvent.ACTION_MULTIPLE
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 } else if (span instanceof UnderlineSpan) { 651 } else if (span instanceof UnderlineSpan) {
547 nativeAppendUnderlineSpan(underlines, spannableString.getSpanSta rt(span), 652 nativeAppendUnderlineSpan(underlines, spannableString.getSpanSta rt(span),
548 spannableString.getSpanEnd(span)); 653 spannableString.getSpanEnd(span));
549 } 654 }
550 } 655 }
551 } 656 }
552 657
553 @CalledByNative 658 @CalledByNative
554 private void cancelComposition() { 659 private void cancelComposition() {
555 if (mInputConnection != null) mInputConnection.restartInput(); 660 if (mInputConnection != null) mInputConnection.restartInput();
661 mLastComposeText = null;
556 } 662 }
557 663
558 @CalledByNative 664 @CalledByNative
559 void detach() { 665 void detach() {
560 if (mDismissInput != null) mHandler.removeCallbacks(mDismissInput); 666 if (mDismissInput != null) mHandler.removeCallbacks(mDismissInput);
561 mNativeImeAdapterAndroid = 0; 667 mNativeImeAdapterAndroid = 0;
562 mTextInputType = 0; 668 mTextInputType = 0;
563 } 669 }
564 670
565 private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndr oid, 671 private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndr oid,
(...skipping 25 matching lines...) Expand all
591 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid , 697 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid ,
592 int before, int after); 698 int before, int after);
593 699
594 private native void nativeUnselect(long nativeImeAdapterAndroid); 700 private native void nativeUnselect(long nativeImeAdapterAndroid);
595 private native void nativeSelectAll(long nativeImeAdapterAndroid); 701 private native void nativeSelectAll(long nativeImeAdapterAndroid);
596 private native void nativeCut(long nativeImeAdapterAndroid); 702 private native void nativeCut(long nativeImeAdapterAndroid);
597 private native void nativeCopy(long nativeImeAdapterAndroid); 703 private native void nativeCopy(long nativeImeAdapterAndroid);
598 private native void nativePaste(long nativeImeAdapterAndroid); 704 private native void nativePaste(long nativeImeAdapterAndroid);
599 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid); 705 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid);
600 } 706 }
OLDNEW
« no previous file with comments | « no previous file | content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698