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 |