| 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.content.browser.input; | 5 package org.chromium.content.browser.input; |
| 6 | 6 |
| 7 import android.os.SystemClock; | 7 import android.os.SystemClock; |
| 8 import android.text.Editable; | 8 import android.text.Editable; |
| 9 import android.text.InputType; | 9 import android.text.InputType; |
| 10 import android.text.Selection; | 10 import android.text.Selection; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 import org.chromium.base.VisibleForTesting; | 22 import org.chromium.base.VisibleForTesting; |
| 23 import org.chromium.blink_public.web.WebInputEventType; | 23 import org.chromium.blink_public.web.WebInputEventType; |
| 24 import org.chromium.blink_public.web.WebTextInputFlags; | 24 import org.chromium.blink_public.web.WebTextInputFlags; |
| 25 import org.chromium.ui.base.ime.TextInputType; | 25 import org.chromium.ui.base.ime.TextInputType; |
| 26 | 26 |
| 27 /** | 27 /** |
| 28 * InputConnection is created by ContentView.onCreateInputConnection. | 28 * InputConnection is created by ContentView.onCreateInputConnection. |
| 29 * It then adapts android's IME to chrome's RenderWidgetHostView using the | 29 * It then adapts android's IME to chrome's RenderWidgetHostView using the |
| 30 * native ImeAdapterAndroid via the class ImeAdapter. | 30 * native ImeAdapterAndroid via the class ImeAdapter. |
| 31 */ | 31 */ |
| 32 public class AdapterInputConnection extends BaseInputConnection { | 32 public class AdapterInputConnection |
| 33 extends BaseInputConnection implements ChromiumBaseInputConnection { |
| 33 private static final String TAG = "cr.Ime"; | 34 private static final String TAG = "cr.Ime"; |
| 34 /** | 35 /** |
| 35 * Selection value should be -1 if not known. See EditorInfo.java for detail
s. | 36 * Selection value should be -1 if not known. See EditorInfo.java for detail
s. |
| 36 */ | 37 */ |
| 37 public static final int INVALID_SELECTION = -1; | 38 public static final int INVALID_SELECTION = -1; |
| 38 public static final int INVALID_COMPOSITION = -1; | 39 public static final int INVALID_COMPOSITION = -1; |
| 39 | 40 |
| 40 private final View mInternalView; | 41 private final View mInternalView; |
| 41 private final ImeAdapter mImeAdapter; | 42 private final ImeAdapter mImeAdapter; |
| 42 private final Editable mEditable; | 43 private final Editable mEditable; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 updateSelectionIfRequired(); | 149 updateSelectionIfRequired(); |
| 149 } | 150 } |
| 150 | 151 |
| 151 private String dumpEditorInfo(EditorInfo editorInfo) { | 152 private String dumpEditorInfo(EditorInfo editorInfo) { |
| 152 StringBuilder builder = new StringBuilder(); | 153 StringBuilder builder = new StringBuilder(); |
| 153 StringBuilderPrinter printer = new StringBuilderPrinter(builder); | 154 StringBuilderPrinter printer = new StringBuilderPrinter(builder); |
| 154 editorInfo.dump(printer, ""); | 155 editorInfo.dump(printer, ""); |
| 155 return builder.toString(); | 156 return builder.toString(); |
| 156 } | 157 } |
| 157 | 158 |
| 158 /** | 159 @Override |
| 159 * Updates the AdapterInputConnection's internal representation of the text
being edited and | |
| 160 * its selection and composition properties. The resulting Editable is acces
sible through the | |
| 161 * getEditable() method. If the text has not changed, this also calls update
Selection on the | |
| 162 * InputMethodManager. | |
| 163 * | |
| 164 * @param text The String contents of the field being edited. | |
| 165 * @param selectionStart The character offset of the selection start, or the
caret position if | |
| 166 * there is no selection. | |
| 167 * @param selectionEnd The character offset of the selection end, or the car
et position if there | |
| 168 * is no selection. | |
| 169 * @param compositionStart The character offset of the composition start, or
-1 if there is no | |
| 170 * composition. | |
| 171 * @param compositionEnd The character offset of the composition end, or -1
if there is no | |
| 172 * selection. | |
| 173 * @param isNonImeChange True when the update was caused by non-IME (e.g. Ja
vascript). | |
| 174 */ | |
| 175 @VisibleForTesting | |
| 176 public void updateState(String text, int selectionStart, int selectionEnd, i
nt compositionStart, | 160 public void updateState(String text, int selectionStart, int selectionEnd, i
nt compositionStart, |
| 177 int compositionEnd, boolean isNonImeChange) { | 161 int compositionEnd, boolean isNonImeChange) { |
| 178 Log.d(TAG, "updateState [%s] [%s %s] [%s %s] [%b]", text, selectionStart
, | 162 Log.d(TAG, "updateState [%s] [%s %s] [%s %s] [%b]", text, selectionStart
, |
| 179 selectionEnd, compositionStart, compositionEnd, isNonImeChange); | 163 selectionEnd, compositionStart, compositionEnd, isNonImeChange); |
| 180 // If this update is from the IME, no further state modification is nece
ssary because the | 164 // If this update is from the IME, no further state modification is nece
ssary because the |
| 181 // state should have been updated already by the IM framework directly. | 165 // state should have been updated already by the IM framework directly. |
| 182 if (!isNonImeChange) return; | 166 if (!isNonImeChange) return; |
| 183 | 167 |
| 184 // Non-breaking spaces can cause the IME to get confused. Replace with n
ormal spaces. | 168 // Non-breaking spaces can cause the IME to get confused. Replace with n
ormal spaces. |
| 185 text = text.replace('\u00A0', ' '); | 169 text = text.replace('\u00A0', ' '); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 text.length() > 0); | 254 text.length() > 0); |
| 271 } | 255 } |
| 272 | 256 |
| 273 /** | 257 /** |
| 274 * @see BaseInputConnection#performEditorAction(int) | 258 * @see BaseInputConnection#performEditorAction(int) |
| 275 */ | 259 */ |
| 276 @Override | 260 @Override |
| 277 public boolean performEditorAction(int actionCode) { | 261 public boolean performEditorAction(int actionCode) { |
| 278 Log.d(TAG, "performEditorAction [%d]", actionCode); | 262 Log.d(TAG, "performEditorAction [%d]", actionCode); |
| 279 if (actionCode == EditorInfo.IME_ACTION_NEXT) { | 263 if (actionCode == EditorInfo.IME_ACTION_NEXT) { |
| 280 restartInput(); | 264 getInputMethodManagerWrapper().restartInput(mInternalView); |
| 281 // Send TAB key event | 265 // Send TAB key event |
| 282 long timeStampMs = SystemClock.uptimeMillis(); | 266 long timeStampMs = SystemClock.uptimeMillis(); |
| 283 mImeAdapter.sendSyntheticKeyEvent( | 267 mImeAdapter.sendSyntheticKeyEvent( |
| 284 WebInputEventType.RawKeyDown, timeStampMs, KeyEvent.KEYCODE_
TAB, 0, 0); | 268 WebInputEventType.RawKeyDown, timeStampMs, KeyEvent.KEYCODE_
TAB, 0, 0); |
| 285 } else { | 269 } else { |
| 286 mImeAdapter.sendKeyEventWithKeyCode(KeyEvent.KEYCODE_ENTER, | 270 mImeAdapter.sendKeyEventWithKeyCode(KeyEvent.KEYCODE_ENTER, |
| 287 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE | 271 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE |
| 288 | KeyEvent.FLAG_EDITOR_ACTION); | 272 | KeyEvent.FLAG_EDITOR_ACTION); |
| 289 } | 273 } |
| 290 return true; | 274 return true; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 result &= mImeAdapter.sendSyntheticKeyEvent( | 394 result &= mImeAdapter.sendSyntheticKeyEvent( |
| 411 WebInputEventType.KeyUp, SystemClock.uptimeMillis(), keyCode
, 0, 0); | 395 WebInputEventType.KeyUp, SystemClock.uptimeMillis(), keyCode
, 0, 0); |
| 412 } else { | 396 } else { |
| 413 mImeAdapter.sendKeyEventWithKeyCode( | 397 mImeAdapter.sendKeyEventWithKeyCode( |
| 414 keyCode, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TO
UCH_MODE); | 398 keyCode, KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TO
UCH_MODE); |
| 415 } | 399 } |
| 416 return result; | 400 return result; |
| 417 } | 401 } |
| 418 | 402 |
| 419 /** | 403 /** |
| 404 * @see ChromiumBaseInputConnection#dispatchKeyEvent(KeyEvent) |
| 405 */ |
| 406 @Override |
| 407 public boolean dispatchKeyEvent(KeyEvent event) { |
| 408 return sendKeyEvent(event); |
| 409 } |
| 410 |
| 411 /** |
| 420 * @see BaseInputConnection#sendKeyEvent(android.view.KeyEvent) | 412 * @see BaseInputConnection#sendKeyEvent(android.view.KeyEvent) |
| 421 */ | 413 */ |
| 422 @Override | 414 @Override |
| 423 public boolean sendKeyEvent(KeyEvent event) { | 415 public boolean sendKeyEvent(KeyEvent event) { |
| 424 Log.d(TAG, "sendKeyEvent [%d] [%d] [%d]", event.getAction(), event.getKe
yCode(), | 416 Log.d(TAG, "sendKeyEvent [%d] [%d] [%d]", event.getAction(), event.getKe
yCode(), |
| 425 event.getUnicodeChar()); | 417 event.getUnicodeChar()); |
| 426 | 418 |
| 427 int action = event.getAction(); | 419 int action = event.getAction(); |
| 428 int keycode = event.getKeyCode(); | 420 int keycode = event.getKeyCode(); |
| 429 int unicodeChar = event.getUnicodeChar(); | 421 int unicodeChar = event.getUnicodeChar(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 if (start < 0 || end < 0 || start > textLength || end > textLength) retu
rn true; | 512 if (start < 0 || end < 0 || start > textLength || end > textLength) retu
rn true; |
| 521 super.setSelection(start, end); | 513 super.setSelection(start, end); |
| 522 updateSelectionIfRequired(); | 514 updateSelectionIfRequired(); |
| 523 return mImeAdapter.setEditableSelectionOffsets(start, end); | 515 return mImeAdapter.setEditableSelectionOffsets(start, end); |
| 524 } | 516 } |
| 525 | 517 |
| 526 /** | 518 /** |
| 527 * Informs the InputMethodManager and InputMethodSession (i.e. the IME) that
the text | 519 * Informs the InputMethodManager and InputMethodSession (i.e. the IME) that
the text |
| 528 * state is no longer what the IME has and that it needs to be updated. | 520 * state is no longer what the IME has and that it needs to be updated. |
| 529 */ | 521 */ |
| 530 void restartInput() { | 522 @Override |
| 523 public void restartInput() { |
| 531 Log.d(TAG, "restartInput"); | 524 Log.d(TAG, "restartInput"); |
| 532 getInputMethodManagerWrapper().restartInput(mInternalView); | 525 getInputMethodManagerWrapper().restartInput(mInternalView); |
| 533 mNumNestedBatchEdits = 0; | 526 mNumNestedBatchEdits = 0; |
| 534 mPendingAccent = 0; | 527 mPendingAccent = 0; |
| 535 } | 528 } |
| 536 | 529 |
| 537 /** | 530 /** |
| 538 * @see BaseInputConnection#setComposingRegion(int, int) | 531 * @see BaseInputConnection#setComposingRegion(int, int) |
| 539 */ | 532 */ |
| 540 @Override | 533 @Override |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 @VisibleForTesting | 620 @VisibleForTesting |
| 628 ImeState getImeStateForTesting() { | 621 ImeState getImeStateForTesting() { |
| 629 String text = mEditable.toString(); | 622 String text = mEditable.toString(); |
| 630 int selectionStart = Selection.getSelectionStart(mEditable); | 623 int selectionStart = Selection.getSelectionStart(mEditable); |
| 631 int selectionEnd = Selection.getSelectionEnd(mEditable); | 624 int selectionEnd = Selection.getSelectionEnd(mEditable); |
| 632 int compositionStart = getComposingSpanStart(mEditable); | 625 int compositionStart = getComposingSpanStart(mEditable); |
| 633 int compositionEnd = getComposingSpanEnd(mEditable); | 626 int compositionEnd = getComposingSpanEnd(mEditable); |
| 634 return new ImeState(text, selectionStart, selectionEnd, compositionStart
, compositionEnd); | 627 return new ImeState(text, selectionStart, selectionEnd, compositionStart
, compositionEnd); |
| 635 } | 628 } |
| 636 } | 629 } |
| OLD | NEW |