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

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

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

Powered by Google App Engine
This is Rietveld 408576698