| OLD | NEW |
| 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.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
| 8 import android.content.res.Configuration; | 8 import android.content.res.Configuration; |
| 9 import android.graphics.Rect; | 9 import android.graphics.Rect; |
| 10 import android.os.Build; | 10 import android.os.Build; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 // This holds the information necessary for constructing CursorAnchorInfo, a
nd notifies to | 90 // This holds the information necessary for constructing CursorAnchorInfo, a
nd notifies to |
| 91 // InputMethodManager on appropriate timing, depending on how IME requested
the information | 91 // InputMethodManager on appropriate timing, depending on how IME requested
the information |
| 92 // via InputConnection. The update request is per InputConnection, hence for
each time it is | 92 // via InputConnection. The update request is per InputConnection, hence for
each time it is |
| 93 // re-created, the monitoring status will be reset. | 93 // re-created, the monitoring status will be reset. |
| 94 private final CursorAnchorInfoController mCursorAnchorInfoController; | 94 private final CursorAnchorInfoController mCursorAnchorInfoController; |
| 95 | 95 |
| 96 private final List<ImeEventObserver> mEventObservers = new ArrayList<>(); | 96 private final List<ImeEventObserver> mEventObservers = new ArrayList<>(); |
| 97 | 97 |
| 98 private int mTextInputType = TextInputType.NONE; | 98 private int mTextInputType = TextInputType.NONE; |
| 99 private int mTextInputFlags; | 99 private int mTextInputFlags; |
| 100 private int mTextInputMode = WebTextInputMode.kDefault; | 100 private int mTextInputMode = WebTextInputMode.DEFAULT; |
| 101 private boolean mNodeEditable; | 101 private boolean mNodeEditable; |
| 102 private boolean mNodePassword; | 102 private boolean mNodePassword; |
| 103 | 103 |
| 104 // Viewport rect before the OSK was brought up. | 104 // Viewport rect before the OSK was brought up. |
| 105 // Used to tell View#onSizeChanged to focus a form element. | 105 // Used to tell View#onSizeChanged to focus a form element. |
| 106 private final Rect mFocusPreOSKViewportRect = new Rect(); | 106 private final Rect mFocusPreOSKViewportRect = new Rect(); |
| 107 | 107 |
| 108 // Keep the current configuration to detect the change when onConfigurationC
hanged() is called. | 108 // Keep the current configuration to detect the change when onConfigurationC
hanged() is called. |
| 109 private Configuration mCurrentConfig; | 109 private Configuration mCurrentConfig; |
| 110 | 110 |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 * Get the current input connection for testing purposes. | 280 * Get the current input connection for testing purposes. |
| 281 */ | 281 */ |
| 282 @VisibleForTesting | 282 @VisibleForTesting |
| 283 public ChromiumBaseInputConnection getInputConnectionForTest() { | 283 public ChromiumBaseInputConnection getInputConnectionForTest() { |
| 284 return mInputConnection; | 284 return mInputConnection; |
| 285 } | 285 } |
| 286 | 286 |
| 287 private static int getModifiers(int metaState) { | 287 private static int getModifiers(int metaState) { |
| 288 int modifiers = 0; | 288 int modifiers = 0; |
| 289 if ((metaState & KeyEvent.META_SHIFT_ON) != 0) { | 289 if ((metaState & KeyEvent.META_SHIFT_ON) != 0) { |
| 290 modifiers |= WebInputEventModifier.kShiftKey; | 290 modifiers |= WebInputEventModifier.SHIFT_KEY; |
| 291 } | 291 } |
| 292 if ((metaState & KeyEvent.META_ALT_ON) != 0) { | 292 if ((metaState & KeyEvent.META_ALT_ON) != 0) { |
| 293 modifiers |= WebInputEventModifier.kAltKey; | 293 modifiers |= WebInputEventModifier.ALT_KEY; |
| 294 } | 294 } |
| 295 if ((metaState & KeyEvent.META_CTRL_ON) != 0) { | 295 if ((metaState & KeyEvent.META_CTRL_ON) != 0) { |
| 296 modifiers |= WebInputEventModifier.kControlKey; | 296 modifiers |= WebInputEventModifier.CONTROL_KEY; |
| 297 } | 297 } |
| 298 if ((metaState & KeyEvent.META_CAPS_LOCK_ON) != 0) { | 298 if ((metaState & KeyEvent.META_CAPS_LOCK_ON) != 0) { |
| 299 modifiers |= WebInputEventModifier.kCapsLockOn; | 299 modifiers |= WebInputEventModifier.CAPS_LOCK_ON; |
| 300 } | 300 } |
| 301 if ((metaState & KeyEvent.META_NUM_LOCK_ON) != 0) { | 301 if ((metaState & KeyEvent.META_NUM_LOCK_ON) != 0) { |
| 302 modifiers |= WebInputEventModifier.kNumLockOn; | 302 modifiers |= WebInputEventModifier.NUM_LOCK_ON; |
| 303 } | 303 } |
| 304 return modifiers; | 304 return modifiers; |
| 305 } | 305 } |
| 306 | 306 |
| 307 /** | 307 /** |
| 308 * Updates internal representation of the text being edited and its selectio
n and composition | 308 * Updates internal representation of the text being edited and its selectio
n and composition |
| 309 * properties. | 309 * properties. |
| 310 * | 310 * |
| 311 * @param textInputType Text input type for the currently focused field in r
enderer. | 311 * @param textInputType Text input type for the currently focused field in r
enderer. |
| 312 * @param textInputFlags Text input flags. | 312 * @param textInputFlags Text input flags. |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 return sendKeyEvent(event); | 550 return sendKeyEvent(event); |
| 551 } | 551 } |
| 552 | 552 |
| 553 /** | 553 /** |
| 554 * Resets IME adapter and hides keyboard. Note that this will also unblock i
nput connection. | 554 * Resets IME adapter and hides keyboard. Note that this will also unblock i
nput connection. |
| 555 */ | 555 */ |
| 556 public void resetAndHideKeyboard() { | 556 public void resetAndHideKeyboard() { |
| 557 if (DEBUG_LOGS) Log.i(TAG, "resetAndHideKeyboard"); | 557 if (DEBUG_LOGS) Log.i(TAG, "resetAndHideKeyboard"); |
| 558 mTextInputType = TextInputType.NONE; | 558 mTextInputType = TextInputType.NONE; |
| 559 mTextInputFlags = 0; | 559 mTextInputFlags = 0; |
| 560 mTextInputMode = WebTextInputMode.kDefault; | 560 mTextInputMode = WebTextInputMode.DEFAULT; |
| 561 mRestartInputOnNextStateUpdate = false; | 561 mRestartInputOnNextStateUpdate = false; |
| 562 // This will trigger unblocking if necessary. | 562 // This will trigger unblocking if necessary. |
| 563 hideKeyboard(); | 563 hideKeyboard(); |
| 564 } | 564 } |
| 565 | 565 |
| 566 @CalledByNative | 566 @CalledByNative |
| 567 private void destroy() { | 567 private void destroy() { |
| 568 resetAndHideKeyboard(); | 568 resetAndHideKeyboard(); |
| 569 mNativeImeAdapterAndroid = 0; | 569 mNativeImeAdapterAndroid = 0; |
| 570 mIsConnected = false; | 570 mIsConnected = false; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 | 661 |
| 662 // One WebView app detects Enter in JS by looking at KeyDown (http://crb
ug/577967). | 662 // One WebView app detects Enter in JS by looking at KeyDown (http://crb
ug/577967). |
| 663 if (TextUtils.equals(text, "\n")) { | 663 if (TextUtils.equals(text, "\n")) { |
| 664 sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER, | 664 sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER, |
| 665 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE)
; | 665 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE)
; |
| 666 return true; | 666 return true; |
| 667 } | 667 } |
| 668 | 668 |
| 669 onImeEvent(); | 669 onImeEvent(); |
| 670 long timestampMs = SystemClock.uptimeMillis(); | 670 long timestampMs = SystemClock.uptimeMillis(); |
| 671 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.kRa
wKeyDown, 0, | 671 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.RAW
_KEY_DOWN, 0, |
| 672 timestampMs, COMPOSITION_KEY_CODE, 0, false, unicodeFromKeyEvent
); | 672 timestampMs, COMPOSITION_KEY_CODE, 0, false, unicodeFromKeyEvent
); |
| 673 | 673 |
| 674 if (isCommit) { | 674 if (isCommit) { |
| 675 nativeCommitText(mNativeImeAdapterAndroid, text, text.toString(), ne
wCursorPosition); | 675 nativeCommitText(mNativeImeAdapterAndroid, text, text.toString(), ne
wCursorPosition); |
| 676 } else { | 676 } else { |
| 677 nativeSetComposingText( | 677 nativeSetComposingText( |
| 678 mNativeImeAdapterAndroid, text, text.toString(), newCursorPo
sition); | 678 mNativeImeAdapterAndroid, text, text.toString(), newCursorPo
sition); |
| 679 } | 679 } |
| 680 | 680 |
| 681 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.kKe
yUp, 0, timestampMs, | 681 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.KEY
_UP, 0, timestampMs, |
| 682 COMPOSITION_KEY_CODE, 0, false, unicodeFromKeyEvent); | 682 COMPOSITION_KEY_CODE, 0, false, unicodeFromKeyEvent); |
| 683 return true; | 683 return true; |
| 684 } | 684 } |
| 685 | 685 |
| 686 @VisibleForTesting | 686 @VisibleForTesting |
| 687 boolean finishComposingText() { | 687 boolean finishComposingText() { |
| 688 if (!isValid()) return false; | 688 if (!isValid()) return false; |
| 689 nativeFinishComposingText(mNativeImeAdapterAndroid); | 689 nativeFinishComposingText(mNativeImeAdapterAndroid); |
| 690 return true; | 690 return true; |
| 691 } | 691 } |
| 692 | 692 |
| 693 boolean sendKeyEvent(KeyEvent event) { | 693 boolean sendKeyEvent(KeyEvent event) { |
| 694 if (!isValid()) return false; | 694 if (!isValid()) return false; |
| 695 | 695 |
| 696 int action = event.getAction(); | 696 int action = event.getAction(); |
| 697 int type; | 697 int type; |
| 698 if (action == KeyEvent.ACTION_DOWN) { | 698 if (action == KeyEvent.ACTION_DOWN) { |
| 699 type = WebInputEventType.kKeyDown; | 699 type = WebInputEventType.KEY_DOWN; |
| 700 } else if (action == KeyEvent.ACTION_UP) { | 700 } else if (action == KeyEvent.ACTION_UP) { |
| 701 type = WebInputEventType.kKeyUp; | 701 type = WebInputEventType.KEY_UP; |
| 702 } else { | 702 } else { |
| 703 // In theory, KeyEvent.ACTION_MULTIPLE is a valid value, but in prac
tice | 703 // In theory, KeyEvent.ACTION_MULTIPLE is a valid value, but in prac
tice |
| 704 // this seems to have been quietly deprecated and we've never observ
ed | 704 // this seems to have been quietly deprecated and we've never observ
ed |
| 705 // a case where it's sent (holding down physical keyboard key also | 705 // a case where it's sent (holding down physical keyboard key also |
| 706 // sends ACTION_DOWN), so it's fine to silently drop it. | 706 // sends ACTION_DOWN), so it's fine to silently drop it. |
| 707 return false; | 707 return false; |
| 708 } | 708 } |
| 709 onImeEvent(); | 709 onImeEvent(); |
| 710 | 710 |
| 711 return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, type, | 711 return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, type, |
| 712 getModifiers(event.getMetaState()), event.getEventTime(), event.
getKeyCode(), | 712 getModifiers(event.getMetaState()), event.getEventTime(), event.
getKeyCode(), |
| 713 event.getScanCode(), /*isSystemKey=*/false, event.g
etUnicodeChar()); | 713 event.getScanCode(), /*isSystemKey=*/false, event.g
etUnicodeChar()); |
| 714 } | 714 } |
| 715 | 715 |
| 716 /** | 716 /** |
| 717 * Send a request to the native counterpart to delete a given range of chara
cters. | 717 * Send a request to the native counterpart to delete a given range of chara
cters. |
| 718 * @param beforeLength Number of characters to extend the selection by befor
e the existing | 718 * @param beforeLength Number of characters to extend the selection by befor
e the existing |
| 719 * selection. | 719 * selection. |
| 720 * @param afterLength Number of characters to extend the selection by after
the existing | 720 * @param afterLength Number of characters to extend the selection by after
the existing |
| 721 * selection. | 721 * selection. |
| 722 * @return Whether the native counterpart of ImeAdapter received the call. | 722 * @return Whether the native counterpart of ImeAdapter received the call. |
| 723 */ | 723 */ |
| 724 boolean deleteSurroundingText(int beforeLength, int afterLength) { | 724 boolean deleteSurroundingText(int beforeLength, int afterLength) { |
| 725 onImeEvent(); | 725 onImeEvent(); |
| 726 if (!isValid()) return false; | 726 if (!isValid()) return false; |
| 727 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.kRa
wKeyDown, 0, | 727 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.RAW
_KEY_DOWN, 0, |
| 728 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); | 728 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); |
| 729 nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afte
rLength); | 729 nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afte
rLength); |
| 730 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.kKe
yUp, 0, | 730 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.KEY
_UP, 0, |
| 731 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); | 731 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); |
| 732 return true; | 732 return true; |
| 733 } | 733 } |
| 734 | 734 |
| 735 /** | 735 /** |
| 736 * Send a request to the native counterpart to delete a given range of chara
cters. | 736 * Send a request to the native counterpart to delete a given range of chara
cters. |
| 737 * @param beforeLength Number of code points to extend the selection by befo
re the existing | 737 * @param beforeLength Number of code points to extend the selection by befo
re the existing |
| 738 * selection. | 738 * selection. |
| 739 * @param afterLength Number of code points to extend the selection by after
the existing | 739 * @param afterLength Number of code points to extend the selection by after
the existing |
| 740 * selection. | 740 * selection. |
| 741 * @return Whether the native counterpart of ImeAdapter received the call. | 741 * @return Whether the native counterpart of ImeAdapter received the call. |
| 742 */ | 742 */ |
| 743 boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength)
{ | 743 boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength)
{ |
| 744 onImeEvent(); | 744 onImeEvent(); |
| 745 if (!isValid()) return false; | 745 if (!isValid()) return false; |
| 746 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.kRa
wKeyDown, 0, | 746 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.RAW
_KEY_DOWN, 0, |
| 747 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); | 747 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); |
| 748 nativeDeleteSurroundingTextInCodePoints( | 748 nativeDeleteSurroundingTextInCodePoints( |
| 749 mNativeImeAdapterAndroid, beforeLength, afterLength); | 749 mNativeImeAdapterAndroid, beforeLength, afterLength); |
| 750 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.kKe
yUp, 0, | 750 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.KEY
_UP, 0, |
| 751 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); | 751 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); |
| 752 return true; | 752 return true; |
| 753 } | 753 } |
| 754 | 754 |
| 755 /** | 755 /** |
| 756 * Send a request to the native counterpart to set the selection to given ra
nge. | 756 * Send a request to the native counterpart to set the selection to given ra
nge. |
| 757 * @param start Selection start index. | 757 * @param start Selection start index. |
| 758 * @param end Selection end index. | 758 * @param end Selection end index. |
| 759 * @return Whether the native counterpart of ImeAdapter received the call. | 759 * @return Whether the native counterpart of ImeAdapter received the call. |
| 760 */ | 760 */ |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 int start, int end); | 900 int start, int end); |
| 901 private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, i
nt start, int end); | 901 private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, i
nt start, int end); |
| 902 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid
, | 902 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid
, |
| 903 int before, int after); | 903 int before, int after); |
| 904 private native void nativeDeleteSurroundingTextInCodePoints( | 904 private native void nativeDeleteSurroundingTextInCodePoints( |
| 905 long nativeImeAdapterAndroid, int before, int after); | 905 long nativeImeAdapterAndroid, int before, int after); |
| 906 private native boolean nativeRequestTextInputStateUpdate(long nativeImeAdapt
erAndroid); | 906 private native boolean nativeRequestTextInputStateUpdate(long nativeImeAdapt
erAndroid); |
| 907 private native void nativeRequestCursorUpdate(long nativeImeAdapterAndroid, | 907 private native void nativeRequestCursorUpdate(long nativeImeAdapterAndroid, |
| 908 boolean immediateRequest, boolean monitorRequest); | 908 boolean immediateRequest, boolean monitorRequest); |
| 909 } | 909 } |
| OLD | NEW |