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

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

Issue 2791603002: Revert of Let ImeAdapterAndroid have the same lifecycle as its Java peer (Closed)
Patch Set: Created 3 years, 8 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
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.content.res.Configuration; 7 import android.content.res.Configuration;
8 import android.os.Build; 8 import android.os.Build;
9 import android.os.ResultReceiver; 9 import android.os.ResultReceiver;
10 import android.os.SystemClock; 10 import android.os.SystemClock;
(...skipping 11 matching lines...) Expand all
22 22
23 import org.chromium.base.Log; 23 import org.chromium.base.Log;
24 import org.chromium.base.VisibleForTesting; 24 import org.chromium.base.VisibleForTesting;
25 import org.chromium.base.annotations.CalledByNative; 25 import org.chromium.base.annotations.CalledByNative;
26 import org.chromium.base.annotations.JNINamespace; 26 import org.chromium.base.annotations.JNINamespace;
27 import org.chromium.blink_public.web.WebInputEventModifier; 27 import org.chromium.blink_public.web.WebInputEventModifier;
28 import org.chromium.blink_public.web.WebInputEventType; 28 import org.chromium.blink_public.web.WebInputEventType;
29 import org.chromium.blink_public.web.WebTextInputMode; 29 import org.chromium.blink_public.web.WebTextInputMode;
30 import org.chromium.content.browser.RenderCoordinates; 30 import org.chromium.content.browser.RenderCoordinates;
31 import org.chromium.content.browser.picker.InputDialogContainer; 31 import org.chromium.content.browser.picker.InputDialogContainer;
32 import org.chromium.content_public.browser.WebContents;
33 import org.chromium.ui.base.ime.TextInputType; 32 import org.chromium.ui.base.ime.TextInputType;
34 33
35 /** 34 /**
36 * Adapts and plumbs android IME service onto the chrome text input API. 35 * Adapts and plumbs android IME service onto the chrome text input API.
37 * ImeAdapter provides an interface in both ways native <-> java: 36 * ImeAdapter provides an interface in both ways native <-> java:
38 * 1. InputConnectionAdapter notifies native code of text composition state and 37 * 1. InputConnectionAdapter notifies native code of text composition state and
39 * dispatch key events from java -> WebKit. 38 * dispatch key events from java -> WebKit.
40 * 2. Native ImeAdapter notifies java side to clear composition text. 39 * 2. Native ImeAdapter notifies java side to clear composition text.
41 * 40 *
42 * The basic flow is: 41 * The basic flow is:
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 // Keep the current configuration to detect the change when onConfigurationC hanged() is called. 111 // Keep the current configuration to detect the change when onConfigurationC hanged() is called.
113 private Configuration mCurrentConfig; 112 private Configuration mCurrentConfig;
114 113
115 private int mLastSelectionStart; 114 private int mLastSelectionStart;
116 private int mLastSelectionEnd; 115 private int mLastSelectionEnd;
117 private String mLastText; 116 private String mLastText;
118 private int mLastCompositionStart; 117 private int mLastCompositionStart;
119 private int mLastCompositionEnd; 118 private int mLastCompositionEnd;
120 private boolean mRestartInputOnNextStateUpdate; 119 private boolean mRestartInputOnNextStateUpdate;
121 120
122 // True if ImeAdapter is connected to render process.
123 private boolean mIsConnected;
124
125 /** 121 /**
126 * @param webContents WebContents instance with which this ImeAdapter is ass ociated.
127 * @param wrapper InputMethodManagerWrapper that should receive all the call directed to 122 * @param wrapper InputMethodManagerWrapper that should receive all the call directed to
128 * InputMethodManager. 123 * InputMethodManager.
129 * @param embedder The view that is used for callbacks from ImeAdapter. 124 * @param embedder The view that is used for callbacks from ImeAdapter.
130 */ 125 */
131 public ImeAdapter(WebContents webContents, InputMethodManagerWrapper wrapper , 126 public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embe dder) {
132 ImeAdapterDelegate embedder) {
133 mInputMethodManagerWrapper = wrapper; 127 mInputMethodManagerWrapper = wrapper;
134 mViewEmbedder = embedder; 128 mViewEmbedder = embedder;
135 // Deep copy newConfig so that we can notice the difference. 129 // Deep copy newConfig so that we can notice the difference.
136 mCurrentConfig = new Configuration( 130 mCurrentConfig = new Configuration(
137 mViewEmbedder.getAttachedView().getResources().getConfiguration( )); 131 mViewEmbedder.getAttachedView().getResources().getConfiguration( ));
138 // CursorAnchroInfo is supported only after L. 132 // CursorAnchroInfo is supported only after L.
139 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 133 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
140 mCursorAnchorInfoController = CursorAnchorInfoController.create(wrap per, 134 mCursorAnchorInfoController = CursorAnchorInfoController.create(wrap per,
141 new CursorAnchorInfoController.ComposingTextDelegate() { 135 new CursorAnchorInfoController.ComposingTextDelegate() {
142 @Override 136 @Override
(...skipping 13 matching lines...) Expand all
156 return mLastCompositionStart; 150 return mLastCompositionStart;
157 } 151 }
158 @Override 152 @Override
159 public int getComposingTextEnd() { 153 public int getComposingTextEnd() {
160 return mLastCompositionEnd; 154 return mLastCompositionEnd;
161 } 155 }
162 }); 156 });
163 } else { 157 } else {
164 mCursorAnchorInfoController = null; 158 mCursorAnchorInfoController = null;
165 } 159 }
166 mNativeImeAdapterAndroid = nativeInit(webContents);
167 } 160 }
168 161
169 private void createInputConnectionFactory() { 162 private void createInputConnectionFactory() {
170 if (mInputConnectionFactory != null) return; 163 if (mInputConnectionFactory != null) return;
171 mInputConnectionFactory = new ThreadedInputConnectionFactory(mInputMetho dManagerWrapper); 164 mInputConnectionFactory = new ThreadedInputConnectionFactory(mInputMetho dManagerWrapper);
172 } 165 }
173 166
174 // Tells if the ImeAdapter in valid state (i.e. not in destroyed state), and is
175 // connected to render process. The former check guards against the call via
176 // ThreadedInputConnection from Android framework after ImeAdapter.destroy() is called.
177 private boolean isValid() {
178 return mNativeImeAdapterAndroid != 0 && mIsConnected;
179 }
180
181 /** 167 /**
182 * @see View#onCreateInputConnection(EditorInfo) 168 * @see View#onCreateInputConnection(EditorInfo)
183 */ 169 */
184 public ChromiumBaseInputConnection onCreateInputConnection(EditorInfo outAtt rs) { 170 public ChromiumBaseInputConnection onCreateInputConnection(EditorInfo outAtt rs) {
185 // InputMethodService evaluates fullscreen mode even when the new input connection is 171 // InputMethodService evaluates fullscreen mode even when the new input connection is
186 // null. This makes sure IME doesn't enter fullscreen mode or open custo m UI. 172 // null. This makes sure IME doesn't enter fullscreen mode or open custo m UI.
187 outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME _FLAG_NO_EXTRACT_UI; 173 outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME _FLAG_NO_EXTRACT_UI;
188 // Without this line, some third-party IMEs will try to compose text eve n when 174 // Without this line, some third-party IMEs will try to compose text eve n when
189 // not on an editable node. Even when we return null here, key events ca n still go 175 // not on an editable node. Even when we return null here, key events ca n still go
190 // through ImeAdapter#dispatchKeyEvent(). 176 // through ImeAdapter#dispatchKeyEvent().
191 if (mTextInputType == TextInputType.NONE) { 177 if (mTextInputType == TextInputType.NONE) {
192 setInputConnection(null); 178 setInputConnection(null);
193 if (DEBUG_LOGS) Log.i(TAG, "onCreateInputConnection returns null."); 179 if (DEBUG_LOGS) Log.i(TAG, "onCreateInputConnection returns null.");
194 return null; 180 return null;
195 } 181 }
196 if (mInputConnectionFactory == null) return null; 182 if (mInputConnectionFactory == null) return null;
197 setInputConnection(mInputConnectionFactory.initializeAndGet(mViewEmbedde r.getAttachedView(), 183 setInputConnection(mInputConnectionFactory.initializeAndGet(mViewEmbedde r.getAttachedView(),
198 this, mTextInputType, mTextInputFlags, mTextInputMode, mLastSele ctionStart, 184 this, mTextInputType, mTextInputFlags, mTextInputMode, mLastSele ctionStart,
199 mLastSelectionEnd, outAttrs)); 185 mLastSelectionEnd, outAttrs));
200 if (DEBUG_LOGS) Log.i(TAG, "onCreateInputConnection: " + mInputConnectio n); 186 if (DEBUG_LOGS) Log.i(TAG, "onCreateInputConnection: " + mInputConnectio n);
201 187
202 if (mCursorAnchorInfoController != null) { 188 if (mCursorAnchorInfoController != null) {
203 mCursorAnchorInfoController.onRequestCursorUpdates( 189 mCursorAnchorInfoController.onRequestCursorUpdates(
204 false /* not an immediate request */, false /* disable monit oring */, 190 false /* not an immediate request */, false /* disable monit oring */,
205 mViewEmbedder.getAttachedView()); 191 mViewEmbedder.getAttachedView());
206 } 192 }
207 if (isValid()) { 193 if (mNativeImeAdapterAndroid != 0) {
208 nativeRequestCursorUpdate(mNativeImeAdapterAndroid, 194 nativeRequestCursorUpdate(mNativeImeAdapterAndroid,
209 false /* not an immediate request */, false /* disable monit oring */); 195 false /* not an immediate request */, false /* disable monit oring */);
210 } 196 }
211 return mInputConnection; 197 return mInputConnection;
212 } 198 }
213 199
214 private void setInputConnection(ChromiumBaseInputConnection inputConnection) { 200 private void setInputConnection(ChromiumBaseInputConnection inputConnection) {
215 if (mInputConnection == inputConnection) return; 201 if (mInputConnection == inputConnection) return;
216 // The previous input connection might be waiting for state update. 202 // The previous input connection might be waiting for state update.
217 if (mInputConnection != null) mInputConnection.unblockOnUiThread(); 203 if (mInputConnection != null) mInputConnection.unblockOnUiThread();
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 } 318 }
333 319
334 if (mInputConnection == null) return; 320 if (mInputConnection == null) return;
335 boolean singleLine = mTextInputType != TextInputType.TEXT_AREA 321 boolean singleLine = mTextInputType != TextInputType.TEXT_AREA
336 && mTextInputType != TextInputType.CONTENT_EDITABLE; 322 && mTextInputType != TextInputType.CONTENT_EDITABLE;
337 mInputConnection.updateStateOnUiThread(text, selectionStart, selectionEn d, compositionStart, 323 mInputConnection.updateStateOnUiThread(text, selectionStart, selectionEn d, compositionStart,
338 compositionEnd, singleLine, replyToRequest); 324 compositionEnd, singleLine, replyToRequest);
339 } 325 }
340 326
341 /** 327 /**
328 * Attaches the imeAdapter to its native counterpart. This is needed to star t forwarding
329 * keyboard events to WebKit.
330 * @param nativeImeAdapter The pointer to the native ImeAdapter object.
331 */
332 public void attach(long nativeImeAdapter) {
333 if (DEBUG_LOGS) Log.i(TAG, "attach");
334 if (mNativeImeAdapterAndroid == nativeImeAdapter) return;
335 if (mNativeImeAdapterAndroid != 0) {
336 nativeResetImeAdapter(mNativeImeAdapterAndroid);
337 }
338 if (nativeImeAdapter != 0) {
339 nativeAttachImeAdapter(nativeImeAdapter);
340 }
341 mNativeImeAdapterAndroid = nativeImeAdapter;
342 if (nativeImeAdapter != 0) {
343 createInputConnectionFactory();
344 }
345 resetAndHideKeyboard();
346 }
347
348 /**
342 * Show soft keyboard only if it is the current keyboard configuration. 349 * Show soft keyboard only if it is the current keyboard configuration.
343 */ 350 */
344 private void showSoftKeyboard() { 351 private void showSoftKeyboard() {
345 if (DEBUG_LOGS) Log.i(TAG, "showSoftKeyboard"); 352 if (DEBUG_LOGS) Log.i(TAG, "showSoftKeyboard");
346 mInputMethodManagerWrapper.showSoftInput( 353 mInputMethodManagerWrapper.showSoftInput(
347 mViewEmbedder.getAttachedView(), 0, mViewEmbedder.getNewShowKeyb oardReceiver()); 354 mViewEmbedder.getAttachedView(), 0, mViewEmbedder.getNewShowKeyb oardReceiver());
348 if (mViewEmbedder.getAttachedView().getResources().getConfiguration().ke yboard 355 if (mViewEmbedder.getAttachedView().getResources().getConfiguration().ke yboard
349 != Configuration.KEYBOARD_NOKEYS) { 356 != Configuration.KEYBOARD_NOKEYS) {
350 mViewEmbedder.onKeyboardBoundsUnchanged(); 357 mViewEmbedder.onKeyboardBoundsUnchanged();
351 } 358 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 public void resetAndHideKeyboard() { 478 public void resetAndHideKeyboard() {
472 if (DEBUG_LOGS) Log.i(TAG, "resetAndHideKeyboard"); 479 if (DEBUG_LOGS) Log.i(TAG, "resetAndHideKeyboard");
473 mTextInputType = TextInputType.NONE; 480 mTextInputType = TextInputType.NONE;
474 mTextInputFlags = 0; 481 mTextInputFlags = 0;
475 mTextInputMode = WebTextInputMode.kDefault; 482 mTextInputMode = WebTextInputMode.kDefault;
476 mRestartInputOnNextStateUpdate = false; 483 mRestartInputOnNextStateUpdate = false;
477 // This will trigger unblocking if necessary. 484 // This will trigger unblocking if necessary.
478 hideKeyboard(); 485 hideKeyboard();
479 } 486 }
480 487
481 @CalledByNative
482 private void destroy() {
483 resetAndHideKeyboard();
484 mNativeImeAdapterAndroid = 0;
485 mIsConnected = false;
486 if (mCursorAnchorInfoController != null) {
487 mCursorAnchorInfoController.focusedNodeChanged(false);
488 }
489 }
490
491 /** 488 /**
492 * Update selection to input method manager. 489 * Update selection to input method manager.
493 * 490 *
494 * @param selectionStart The selection start. 491 * @param selectionStart The selection start.
495 * @param selectionEnd The selection end. 492 * @param selectionEnd The selection end.
496 * @param compositionStart The composition start. 493 * @param compositionStart The composition start.
497 * @param compositionEnd The composition end. 494 * @param compositionEnd The composition end.
498 */ 495 */
499 void updateSelection( 496 void updateSelection(
500 int selectionStart, int selectionEnd, int compositionStart, int comp ositionEnd) { 497 int selectionStart, int selectionEnd, int compositionStart, int comp ositionEnd) {
(...skipping 12 matching lines...) Expand all
513 510
514 /** 511 /**
515 * @see BaseInputConnection#performContextMenuAction(int) 512 * @see BaseInputConnection#performContextMenuAction(int)
516 */ 513 */
517 boolean performContextMenuAction(int id) { 514 boolean performContextMenuAction(int id) {
518 if (DEBUG_LOGS) Log.i(TAG, "performContextMenuAction: id [%d]", id); 515 if (DEBUG_LOGS) Log.i(TAG, "performContextMenuAction: id [%d]", id);
519 return mViewEmbedder.performContextMenuAction(id); 516 return mViewEmbedder.performContextMenuAction(id);
520 } 517 }
521 518
522 boolean performEditorAction(int actionCode) { 519 boolean performEditorAction(int actionCode) {
523 if (!isValid()) return false; 520 if (mNativeImeAdapterAndroid == 0) return false;
524 if (actionCode == EditorInfo.IME_ACTION_NEXT) { 521 if (actionCode == EditorInfo.IME_ACTION_NEXT) {
525 sendSyntheticKeyPress(KeyEvent.KEYCODE_TAB, 522 sendSyntheticKeyPress(KeyEvent.KEYCODE_TAB,
526 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE 523 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
527 | KeyEvent.FLAG_EDITOR_ACTION); 524 | KeyEvent.FLAG_EDITOR_ACTION);
528 } else { 525 } else {
529 sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER, 526 sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER,
530 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE 527 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
531 | KeyEvent.FLAG_EDITOR_ACTION); 528 | KeyEvent.FLAG_EDITOR_ACTION);
532 } 529 }
533 return true; 530 return true;
(...skipping 11 matching lines...) Expand all
545 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 542 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
546 flags)); 543 flags));
547 sendKeyEvent(new KeyEvent(eventTime, eventTime, 544 sendKeyEvent(new KeyEvent(eventTime, eventTime,
548 KeyEvent.ACTION_UP, keyCode, 0, 0, 545 KeyEvent.ACTION_UP, keyCode, 0, 0,
549 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 546 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
550 flags)); 547 flags));
551 } 548 }
552 549
553 boolean sendCompositionToNative( 550 boolean sendCompositionToNative(
554 CharSequence text, int newCursorPosition, boolean isCommit, int unic odeFromKeyEvent) { 551 CharSequence text, int newCursorPosition, boolean isCommit, int unic odeFromKeyEvent) {
555 if (!isValid()) return false; 552 if (mNativeImeAdapterAndroid == 0) return false;
556 553
557 // One WebView app detects Enter in JS by looking at KeyDown (http://crb ug/577967). 554 // One WebView app detects Enter in JS by looking at KeyDown (http://crb ug/577967).
558 if (TextUtils.equals(text, "\n")) { 555 if (TextUtils.equals(text, "\n")) {
559 sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER, 556 sendSyntheticKeyPress(KeyEvent.KEYCODE_ENTER,
560 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE) ; 557 KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE) ;
561 return true; 558 return true;
562 } 559 }
563 560
564 mViewEmbedder.onImeEvent(); 561 mViewEmbedder.onImeEvent();
565 long timestampMs = SystemClock.uptimeMillis(); 562 long timestampMs = SystemClock.uptimeMillis();
566 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Raw KeyDown, 0, 563 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Raw KeyDown, 0,
567 timestampMs, COMPOSITION_KEY_CODE, 0, false, unicodeFromKeyEvent ); 564 timestampMs, COMPOSITION_KEY_CODE, 0, false, unicodeFromKeyEvent );
568 565
569 if (isCommit) { 566 if (isCommit) {
570 nativeCommitText(mNativeImeAdapterAndroid, text, text.toString(), ne wCursorPosition); 567 nativeCommitText(mNativeImeAdapterAndroid, text, text.toString(), ne wCursorPosition);
571 } else { 568 } else {
572 nativeSetComposingText( 569 nativeSetComposingText(
573 mNativeImeAdapterAndroid, text, text.toString(), newCursorPo sition); 570 mNativeImeAdapterAndroid, text, text.toString(), newCursorPo sition);
574 } 571 }
575 572
576 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Key Up, 0, timestampMs, 573 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Key Up, 0, timestampMs,
577 COMPOSITION_KEY_CODE, 0, false, unicodeFromKeyEvent); 574 COMPOSITION_KEY_CODE, 0, false, unicodeFromKeyEvent);
578 return true; 575 return true;
579 } 576 }
580 577
581 @VisibleForTesting 578 @VisibleForTesting
582 boolean finishComposingText() { 579 boolean finishComposingText() {
583 if (!isValid()) return false; 580 if (mNativeImeAdapterAndroid == 0) return false;
584 nativeFinishComposingText(mNativeImeAdapterAndroid); 581 nativeFinishComposingText(mNativeImeAdapterAndroid);
585 return true; 582 return true;
586 } 583 }
587 584
588 boolean sendKeyEvent(KeyEvent event) { 585 boolean sendKeyEvent(KeyEvent event) {
589 if (!isValid()) return false; 586 if (mNativeImeAdapterAndroid == 0) return false;
590 587
591 int action = event.getAction(); 588 int action = event.getAction();
592 int type; 589 int type;
593 if (action == KeyEvent.ACTION_DOWN) { 590 if (action == KeyEvent.ACTION_DOWN) {
594 type = WebInputEventType.KeyDown; 591 type = WebInputEventType.KeyDown;
595 } else if (action == KeyEvent.ACTION_UP) { 592 } else if (action == KeyEvent.ACTION_UP) {
596 type = WebInputEventType.KeyUp; 593 type = WebInputEventType.KeyUp;
597 } else { 594 } else {
598 // In theory, KeyEvent.ACTION_MULTIPLE is a valid value, but in prac tice 595 // In theory, KeyEvent.ACTION_MULTIPLE is a valid value, but in prac tice
599 // this seems to have been quietly deprecated and we've never observ ed 596 // this seems to have been quietly deprecated and we've never observ ed
(...skipping 11 matching lines...) Expand all
611 /** 608 /**
612 * Send a request to the native counterpart to delete a given range of chara cters. 609 * Send a request to the native counterpart to delete a given range of chara cters.
613 * @param beforeLength Number of characters to extend the selection by befor e the existing 610 * @param beforeLength Number of characters to extend the selection by befor e the existing
614 * selection. 611 * selection.
615 * @param afterLength Number of characters to extend the selection by after the existing 612 * @param afterLength Number of characters to extend the selection by after the existing
616 * selection. 613 * selection.
617 * @return Whether the native counterpart of ImeAdapter received the call. 614 * @return Whether the native counterpart of ImeAdapter received the call.
618 */ 615 */
619 boolean deleteSurroundingText(int beforeLength, int afterLength) { 616 boolean deleteSurroundingText(int beforeLength, int afterLength) {
620 mViewEmbedder.onImeEvent(); 617 mViewEmbedder.onImeEvent();
621 if (!isValid()) return false; 618 if (mNativeImeAdapterAndroid == 0) return false;
622 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Raw KeyDown, 0, 619 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Raw KeyDown, 0,
623 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); 620 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0);
624 nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afte rLength); 621 nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afte rLength);
625 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Key Up, 0, 622 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Key Up, 0,
626 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); 623 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0);
627 return true; 624 return true;
628 } 625 }
629 626
630 /** 627 /**
631 * Send a request to the native counterpart to delete a given range of chara cters. 628 * Send a request to the native counterpart to delete a given range of chara cters.
632 * @param beforeLength Number of code points to extend the selection by befo re the existing 629 * @param beforeLength Number of code points to extend the selection by befo re the existing
633 * selection. 630 * selection.
634 * @param afterLength Number of code points to extend the selection by after the existing 631 * @param afterLength Number of code points to extend the selection by after the existing
635 * selection. 632 * selection.
636 * @return Whether the native counterpart of ImeAdapter received the call. 633 * @return Whether the native counterpart of ImeAdapter received the call.
637 */ 634 */
638 boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) { 635 boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
639 mViewEmbedder.onImeEvent(); 636 mViewEmbedder.onImeEvent();
640 if (!isValid()) return false; 637 if (mNativeImeAdapterAndroid == 0) return false;
641 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Raw KeyDown, 0, 638 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Raw KeyDown, 0,
642 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); 639 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0);
643 nativeDeleteSurroundingTextInCodePoints( 640 nativeDeleteSurroundingTextInCodePoints(
644 mNativeImeAdapterAndroid, beforeLength, afterLength); 641 mNativeImeAdapterAndroid, beforeLength, afterLength);
645 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Key Up, 0, 642 nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.Key Up, 0,
646 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0); 643 SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0);
647 return true; 644 return true;
648 } 645 }
649 646
650 /** 647 /**
651 * Send a request to the native counterpart to set the selection to given ra nge. 648 * Send a request to the native counterpart to set the selection to given ra nge.
652 * @param start Selection start index. 649 * @param start Selection start index.
653 * @param end Selection end index. 650 * @param end Selection end index.
654 * @return Whether the native counterpart of ImeAdapter received the call. 651 * @return Whether the native counterpart of ImeAdapter received the call.
655 */ 652 */
656 boolean setEditableSelectionOffsets(int start, int end) { 653 boolean setEditableSelectionOffsets(int start, int end) {
657 if (!isValid()) return false; 654 if (mNativeImeAdapterAndroid == 0) return false;
658 nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end); 655 nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end);
659 return true; 656 return true;
660 } 657 }
661 658
662 /** 659 /**
663 * Send a request to the native counterpart to set composing region to given indices. 660 * Send a request to the native counterpart to set composing region to given indices.
664 * @param start The start of the composition. 661 * @param start The start of the composition.
665 * @param end The end of the composition. 662 * @param end The end of the composition.
666 * @return Whether the native counterpart of ImeAdapter received the call. 663 * @return Whether the native counterpart of ImeAdapter received the call.
667 */ 664 */
668 boolean setComposingRegion(int start, int end) { 665 boolean setComposingRegion(int start, int end) {
669 if (!isValid()) return false; 666 if (mNativeImeAdapterAndroid == 0) return false;
670 if (start <= end) { 667 if (start <= end) {
671 nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end); 668 nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
672 } else { 669 } else {
673 nativeSetComposingRegion(mNativeImeAdapterAndroid, end, start); 670 nativeSetComposingRegion(mNativeImeAdapterAndroid, end, start);
674 } 671 }
675 return true; 672 return true;
676 } 673 }
677 674
678 @CalledByNative 675 @CalledByNative
679 private void focusedNodeChanged(boolean isEditable) { 676 private void focusedNodeChanged(boolean isEditable) {
680 if (DEBUG_LOGS) Log.i(TAG, "focusedNodeChanged: isEditable [%b]", isEdit able); 677 if (DEBUG_LOGS) Log.i(TAG, "focusedNodeChanged: isEditable [%b]", isEdit able);
681 678
682 // Update controller before the connection is restarted. 679 // Update controller before the connection is restarted.
683 if (mCursorAnchorInfoController != null) { 680 if (mCursorAnchorInfoController != null) {
684 mCursorAnchorInfoController.focusedNodeChanged(isEditable); 681 mCursorAnchorInfoController.focusedNodeChanged(isEditable);
685 } 682 }
686 683
687 if (mTextInputType != TextInputType.NONE && mInputConnection != null && isEditable) { 684 if (mTextInputType != TextInputType.NONE && mInputConnection != null && isEditable) {
688 mRestartInputOnNextStateUpdate = true; 685 mRestartInputOnNextStateUpdate = true;
689 } 686 }
690 } 687 }
691 688
692 /** 689 /**
693 * Send a request to the native counterpart to give the latest text input st ate update. 690 * Send a request to the native counterpart to give the latest text input st ate update.
694 */ 691 */
695 boolean requestTextInputStateUpdate() { 692 boolean requestTextInputStateUpdate() {
696 if (!isValid()) return false; 693 if (mNativeImeAdapterAndroid == 0) return false;
697 // You won't get state update anyways. 694 // You won't get state update anyways.
698 if (mInputConnection == null) return false; 695 if (mInputConnection == null) return false;
699 return nativeRequestTextInputStateUpdate(mNativeImeAdapterAndroid); 696 return nativeRequestTextInputStateUpdate(mNativeImeAdapterAndroid);
700 } 697 }
701 698
702 /** 699 /**
703 * Notified when IME requested Chrome to change the cursor update mode. 700 * Notified when IME requested Chrome to change the cursor update mode.
704 */ 701 */
705 public boolean onRequestCursorUpdates(int cursorUpdateMode) { 702 public boolean onRequestCursorUpdates(int cursorUpdateMode) {
706 final boolean immediateRequest = 703 final boolean immediateRequest =
707 (cursorUpdateMode & InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0; 704 (cursorUpdateMode & InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0;
708 final boolean monitorRequest = 705 final boolean monitorRequest =
709 (cursorUpdateMode & InputConnection.CURSOR_UPDATE_MONITOR) != 0; 706 (cursorUpdateMode & InputConnection.CURSOR_UPDATE_MONITOR) != 0;
710 707
711 if (isValid()) { 708 if (mNativeImeAdapterAndroid != 0) {
712 nativeRequestCursorUpdate(mNativeImeAdapterAndroid, immediateRequest , monitorRequest); 709 nativeRequestCursorUpdate(mNativeImeAdapterAndroid, immediateRequest , monitorRequest);
713 } 710 }
714 if (mCursorAnchorInfoController == null) return false; 711 if (mCursorAnchorInfoController == null) return false;
715 return mCursorAnchorInfoController.onRequestCursorUpdates(immediateReque st, monitorRequest, 712 return mCursorAnchorInfoController.onRequestCursorUpdates(immediateReque st, monitorRequest,
716 mViewEmbedder.getAttachedView()); 713 mViewEmbedder.getAttachedView());
717 } 714 }
718 715
719 /** 716 /**
720 * Notified when a frame has been produced by the renderer and all the assoc iated metadata. 717 * Notified when a frame has been produced by the renderer and all the assoc iated metadata.
721 * @param renderCoordinates coordinate information to convert CSS (document) coordinates to 718 * @param renderCoordinates coordinate information to convert CSS (document) coordinates to
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 } 763 }
767 764
768 @CalledByNative 765 @CalledByNative
769 private void setCharacterBounds(float[] characterBounds) { 766 private void setCharacterBounds(float[] characterBounds) {
770 if (mCursorAnchorInfoController == null) return; 767 if (mCursorAnchorInfoController == null) return;
771 mCursorAnchorInfoController.setCompositionCharacterBounds(characterBound s, 768 mCursorAnchorInfoController.setCompositionCharacterBounds(characterBound s,
772 mViewEmbedder.getAttachedView()); 769 mViewEmbedder.getAttachedView());
773 } 770 }
774 771
775 @CalledByNative 772 @CalledByNative
776 private void onConnectedToRenderProcess() { 773 private void detach() {
777 if (DEBUG_LOGS) Log.i(TAG, "onConnectedToRenderProcess"); 774 if (DEBUG_LOGS) Log.i(TAG, "detach");
778 mIsConnected = true; 775 mNativeImeAdapterAndroid = 0;
779 createInputConnectionFactory(); 776 if (mCursorAnchorInfoController != null) {
780 resetAndHideKeyboard(); 777 mCursorAnchorInfoController.focusedNodeChanged(false);
778 }
781 } 779 }
782 780
783 private native long nativeInit(WebContents webContents);
784 private native boolean nativeSendKeyEvent(long nativeImeAdapterAndroid, KeyE vent event, 781 private native boolean nativeSendKeyEvent(long nativeImeAdapterAndroid, KeyE vent event,
785 int type, int modifiers, long timestampMs, int keyCode, int scanCode , 782 int type, int modifiers, long timestampMs, int keyCode, int scanCode ,
786 boolean isSystemKey, int unicodeChar); 783 boolean isSystemKey, int unicodeChar);
787 private static native void nativeAppendUnderlineSpan(long underlinePtr, int start, int end); 784 private static native void nativeAppendUnderlineSpan(long underlinePtr, int start, int end);
788 private static native void nativeAppendBackgroundColorSpan(long underlinePtr , int start, 785 private static native void nativeAppendBackgroundColorSpan(long underlinePtr , int start,
789 int end, int backgroundColor); 786 int end, int backgroundColor);
790 private native void nativeSetComposingText(long nativeImeAdapterAndroid, Cha rSequence text, 787 private native void nativeSetComposingText(long nativeImeAdapterAndroid, Cha rSequence text,
791 String textStr, int newCursorPosition); 788 String textStr, int newCursorPosition);
792 private native void nativeCommitText( 789 private native void nativeCommitText(
793 long nativeImeAdapterAndroid, CharSequence text, String textStr, int newCursorPosition); 790 long nativeImeAdapterAndroid, CharSequence text, String textStr, int newCursorPosition);
794 private native void nativeFinishComposingText(long nativeImeAdapterAndroid); 791 private native void nativeFinishComposingText(long nativeImeAdapterAndroid);
792 private native void nativeAttachImeAdapter(long nativeImeAdapterAndroid);
795 private native void nativeSetEditableSelectionOffsets(long nativeImeAdapterA ndroid, 793 private native void nativeSetEditableSelectionOffsets(long nativeImeAdapterA ndroid,
796 int start, int end); 794 int start, int end);
797 private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, i nt start, int end); 795 private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, i nt start, int end);
798 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid , 796 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid ,
799 int before, int after); 797 int before, int after);
800 private native void nativeDeleteSurroundingTextInCodePoints( 798 private native void nativeDeleteSurroundingTextInCodePoints(
801 long nativeImeAdapterAndroid, int before, int after); 799 long nativeImeAdapterAndroid, int before, int after);
800 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid);
802 private native boolean nativeRequestTextInputStateUpdate(long nativeImeAdapt erAndroid); 801 private native boolean nativeRequestTextInputStateUpdate(long nativeImeAdapt erAndroid);
803 private native void nativeRequestCursorUpdate(long nativeImeAdapterAndroid, 802 private native void nativeRequestCursorUpdate(long nativeImeAdapterAndroid,
804 boolean immediateRequest, boolean monitorRequest); 803 boolean immediateRequest, boolean monitorRequest);
805 } 804 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698