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

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

Issue 1278593004: Introduce ThreadedInputConnection behind a switch (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 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.Handler; 8 import android.os.Handler;
9 import android.os.ResultReceiver; 9 import android.os.ResultReceiver;
10 import android.os.SystemClock; 10 import android.os.SystemClock;
11 import android.text.Editable;
12 import android.text.SpannableString; 11 import android.text.SpannableString;
13 import android.text.style.BackgroundColorSpan; 12 import android.text.style.BackgroundColorSpan;
14 import android.text.style.CharacterStyle; 13 import android.text.style.CharacterStyle;
15 import android.text.style.UnderlineSpan; 14 import android.text.style.UnderlineSpan;
16 import android.view.KeyCharacterMap; 15 import android.view.KeyCharacterMap;
17 import android.view.KeyEvent; 16 import android.view.KeyEvent;
18 import android.view.View; 17 import android.view.View;
19 import android.view.inputmethod.BaseInputConnection; 18 import android.view.inputmethod.BaseInputConnection;
20 import android.view.inputmethod.EditorInfo;
21 19
22 import org.chromium.base.Log; 20 import org.chromium.base.Log;
23 import org.chromium.base.VisibleForTesting; 21 import org.chromium.base.VisibleForTesting;
24 import org.chromium.base.annotations.CalledByNative; 22 import org.chromium.base.annotations.CalledByNative;
25 import org.chromium.base.annotations.JNINamespace; 23 import org.chromium.base.annotations.JNINamespace;
26 import org.chromium.blink_public.web.WebInputEventModifier; 24 import org.chromium.blink_public.web.WebInputEventModifier;
27 import org.chromium.blink_public.web.WebInputEventType; 25 import org.chromium.blink_public.web.WebInputEventType;
28 import org.chromium.blink_public.web.WebTextInputFlags; 26 import org.chromium.blink_public.web.WebTextInputFlags;
29 import org.chromium.ui.base.ime.TextInputType; 27 import org.chromium.ui.base.ime.TextInputType;
30 import org.chromium.ui.picker.InputDialogContainer; 28 import org.chromium.ui.picker.InputDialogContainer;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 public void run() { 95 public void run() {
98 hideSoftKeyboard(); 96 hideSoftKeyboard();
99 } 97 }
100 }; 98 };
101 99
102 static char[] sSingleCharArray = new char[1]; 100 static char[] sSingleCharArray = new char[1];
103 static KeyCharacterMap sKeyCharacterMap; 101 static KeyCharacterMap sKeyCharacterMap;
104 102
105 private long mNativeImeAdapterAndroid; 103 private long mNativeImeAdapterAndroid;
106 private InputMethodManagerWrapper mInputMethodManagerWrapper; 104 private InputMethodManagerWrapper mInputMethodManagerWrapper;
107 private AdapterInputConnection mInputConnection; 105 public ChromiumBaseInputConnection mInputConnection;
108 private final ImeAdapterDelegate mViewEmbedder; 106 private final ImeAdapterDelegate mViewEmbedder;
109 private final Handler mHandler; 107 private final Handler mHandler;
110 private int mTextInputType; 108 private int mTextInputType;
111 private int mTextInputFlags; 109 private int mTextInputFlags;
112 private String mLastComposeText; 110 private String mLastComposeText;
111 private final Object mLock = new Object();
aelias_OOO_until_Jul13 2015/09/30 00:10:04 This lock doesn't seem to protect against anything
Changwan Ryu 2016/01/19 07:31:53 Removed.
113 112
114 @VisibleForTesting 113 @VisibleForTesting
115 int mLastSyntheticKeyCode; 114 int mLastSyntheticKeyCode;
116 115
117 @VisibleForTesting 116 @VisibleForTesting
118 boolean mIsShowWithoutHideOutstanding = false; 117 boolean mIsShowWithoutHideOutstanding = false;
119 118
120 /** 119 /**
121 * @param wrapper InputMethodManagerWrapper that should receive all the call directed to 120 * @param wrapper InputMethodManagerWrapper that should receive all the call directed to
122 * InputMethodManager. 121 * InputMethodManager.
123 * @param embedder The view that is used for callbacks from ImeAdapter. 122 * @param embedder The view that is used for callbacks from ImeAdapter.
124 */ 123 */
125 public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embe dder) { 124 public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embe dder) {
126 mInputMethodManagerWrapper = wrapper; 125 mInputMethodManagerWrapper = wrapper;
127 mViewEmbedder = embedder; 126 mViewEmbedder = embedder;
128 mHandler = new Handler(); 127 mHandler = new Handler();
129 } 128 }
130 129
131 /** 130 /**
132 * Default factory for AdapterInputConnection classes.
133 */
134 public static class AdapterInputConnectionFactory {
135 public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
136 Editable editable, EditorInfo outAttrs) {
137 return new AdapterInputConnection(view, imeAdapter, editable, outAtt rs);
138 }
139 }
140
141 /**
142 * Overrides the InputMethodManagerWrapper that ImeAdapter uses to make call s to 131 * Overrides the InputMethodManagerWrapper that ImeAdapter uses to make call s to
143 * InputMethodManager. 132 * InputMethodManager.
144 * @param immw InputMethodManagerWrapper that should be used to call InputMe thodManager. 133 * @param immw InputMethodManagerWrapper that should be used to call InputMe thodManager.
145 */ 134 */
146 @VisibleForTesting 135 @VisibleForTesting
147 public void setInputMethodManagerWrapper(InputMethodManagerWrapper immw) { 136 public void setInputMethodManagerWrapper(InputMethodManagerWrapper immw) {
148 mInputMethodManagerWrapper = immw; 137 mInputMethodManagerWrapper = immw;
149 } 138 }
150 139
151 /** 140 /**
152 * Should be only used by AdapterInputConnection. 141 * Should be only used by AdapterInputConnection.
153 * @return InputMethodManagerWrapper that should receive all the calls direc ted to 142 * @return InputMethodManagerWrapper that should receive all the calls direc ted to
154 * InputMethodManager. 143 * InputMethodManager.
155 */ 144 */
156 InputMethodManagerWrapper getInputMethodManagerWrapper() { 145 InputMethodManagerWrapper getInputMethodManagerWrapper() {
157 return mInputMethodManagerWrapper; 146 return mInputMethodManagerWrapper;
158 } 147 }
159 148
160 /** 149 /**
161 * Set the current active InputConnection when a new InputConnection is cons tructed. 150 * Set the current active InputConnection when a new InputConnection is cons tructed.
162 * @param inputConnection The input connection that is currently used with I ME. 151 * @param inputConnection The input connection that is currently used with I ME.
163 */ 152 */
164 void setInputConnection(AdapterInputConnection inputConnection) { 153 void setInputConnection(ChromiumBaseInputConnection inputConnection) {
165 mInputConnection = inputConnection; 154 synchronized (mLock) {
155 mInputConnection = inputConnection;
156 }
166 mLastComposeText = null; 157 mLastComposeText = null;
167 } 158 }
168 159
160 boolean checkInputConnection(ChromiumBaseInputConnection inputConnection) {
aelias_OOO_until_Jul13 2015/09/30 00:10:04 This method is unused, please delete.
Changwan Ryu 2016/01/19 07:31:53 Removed
161 return mInputConnection == inputConnection;
162 }
163
169 /** 164 /**
170 * Should be used only by AdapterInputConnection. 165 * Should be used only by AdapterInputConnection.
171 * @return The input type of currently focused element. 166 * @return The input type of currently focused element.
172 */ 167 */
173 int getTextInputType() { 168 int getTextInputType() {
174 return mTextInputType; 169 return mTextInputType;
175 } 170 }
176 171
177 /** 172 /**
178 * Should be used only by AdapterInputConnection. 173 * Should be used only by AdapterInputConnection.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 } 214 }
220 215
221 if (mNativeImeAdapterAndroid != nativeImeAdapter || mTextInputType != te xtInputType) { 216 if (mNativeImeAdapterAndroid != nativeImeAdapter || mTextInputType != te xtInputType) {
222 // We have to attach immediately, even if we're going to delay the d ismissing of 217 // We have to attach immediately, even if we're going to delay the d ismissing of
223 // currently visible keyboard because otherwise we have a race condi tion: If the 218 // currently visible keyboard because otherwise we have a race condi tion: If the
224 // native IME adapter gets destructed before the delayed-dismiss fir es, we'll access 219 // native IME adapter gets destructed before the delayed-dismiss fir es, we'll access
225 // an object that has been already released. http://crbug.com/44728 7 220 // an object that has been already released. http://crbug.com/44728 7
226 attach(nativeImeAdapter, textInputType, textInputFlags, true); 221 attach(nativeImeAdapter, textInputType, textInputFlags, true);
227 222
228 if (mTextInputType != TextInputType.NONE) { 223 if (mTextInputType != TextInputType.NONE) {
229 mInputMethodManagerWrapper.restartInput(mViewEmbedder.getAttache dView()); 224 restartInput();
230 if (showIfNeeded) { 225 if (showIfNeeded) {
231 showSoftKeyboard(); 226 showSoftKeyboard();
232 } 227 }
233 } 228 }
234 } else if (hasInputType() && showIfNeeded) { 229 } else if (hasInputType() && showIfNeeded) {
235 showSoftKeyboard(); 230 showSoftKeyboard();
236 } 231 }
237 } 232 }
238 233
239 private void attach(long nativeImeAdapter, int textInputType, int textInputF lags, 234 private void attach(long nativeImeAdapter, int textInputType, int textInputF lags,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 return type != TextInputType.NONE && !InputDialogContainer.isDialogInput Type(type); 300 return type != TextInputType.NONE && !InputDialogContainer.isDialogInput Type(type);
306 } 301 }
307 302
308 public boolean hasTextInputType() { 303 public boolean hasTextInputType() {
309 return isTextInputType(mTextInputType); 304 return isTextInputType(mTextInputType);
310 } 305 }
311 306
312 public boolean dispatchKeyEvent(KeyEvent event) { 307 public boolean dispatchKeyEvent(KeyEvent event) {
313 Log.d(TAG, "dispatchKeyEvent: action [%d], keycode [%d]", event.getActio n(), 308 Log.d(TAG, "dispatchKeyEvent: action [%d], keycode [%d]", event.getActio n(),
314 event.getKeyCode()); 309 event.getKeyCode());
315 if (mInputConnection != null) { 310 synchronized (mLock) {
316 return mInputConnection.sendKeyEvent(event); 311 if (mInputConnection != null) return mInputConnection.dispatchKeyEve nt(event);
317 } 312 }
318 return translateAndSendNativeEvents(event); 313 return translateAndSendNativeEvents(event);
319 } 314 }
320 315
321 private int shouldSendKeyEventWithKeyCode(String text) { 316 private int shouldSendKeyEventWithKeyCode(String text) {
322 if (text.length() != 1) return COMPOSITION_KEY_CODE; 317 if (text.length() != 1) return COMPOSITION_KEY_CODE;
323 318
324 if (text.equals("\n")) { 319 if (text.equals("\n")) {
325 return KeyEvent.KEYCODE_ENTER; 320 return KeyEvent.KEYCODE_ENTER;
326 } else if (text.equals("\t")) { 321 } else if (text.equals("\t")) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 // The content has shrunk in length: assume that backspace was pressed. 380 // The content has shrunk in length: assume that backspace was pressed.
386 if (oldtext.length() > newtext.length() && oldtext.startsWith(newtext)) { 381 if (oldtext.length() > newtext.length() && oldtext.startsWith(newtext)) {
387 return new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL); 382 return new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
388 } 383 }
389 384
390 // The content is unchanged or has undergone a complex change (i.e. not a simple tail 385 // The content is unchanged or has undergone a complex change (i.e. not a simple tail
391 // modification) so return an unknown key-code. 386 // modification) so return an unknown key-code.
392 return null; 387 return null;
393 } 388 }
394 389
395 void sendKeyEventWithKeyCode(int keyCode, int flags) { 390 boolean sendKeyEventWithKeyCode(int keyCode, int flags) {
396 long eventTime = SystemClock.uptimeMillis(); 391 long eventTime = SystemClock.uptimeMillis();
397 mLastSyntheticKeyCode = keyCode; 392 mLastSyntheticKeyCode = keyCode;
398 translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime, 393 boolean result = translateAndSendNativeEvents(new KeyEvent(eventTime, ev entTime,
399 KeyEvent.ACTION_DOWN, keyCode, 0, 0, 394 KeyEvent.ACTION_DOWN, keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEY BOARD, 0, flags));
400 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 395 if (!result) return false;
401 flags)); 396 result = translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMil lis(), eventTime,
402 translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), ev entTime, 397 KeyEvent.ACTION_UP, keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBO ARD, 0, flags));
403 KeyEvent.ACTION_UP, keyCode, 0, 0, 398 return result;
404 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
405 flags));
406 } 399 }
407 400
408 // Calls from Java to C++ 401 // Calls from Java to C++
409 // TODO: Add performance tracing to more complicated functions. 402 // TODO: Add performance tracing to more complicated functions.
410 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP osition, 403 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP osition,
411 boolean isCommit) { 404 boolean isCommit) {
412 if (mNativeImeAdapterAndroid == 0) return false; 405 if (mNativeImeAdapterAndroid == 0) return false;
413 mViewEmbedder.onImeEvent(); 406 mViewEmbedder.onImeEvent();
414 407
415 String textStr = text.toString(); 408 String textStr = text.toString();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 } 474 }
482 475
483 mLastSyntheticKeyCode = keyCode; 476 mLastSyntheticKeyCode = keyCode;
484 } 477 }
485 478
486 mLastComposeText = textStr; 479 mLastComposeText = textStr;
487 return true; 480 return true;
488 } 481 }
489 482
490 @VisibleForTesting 483 @VisibleForTesting
491 protected void finishComposingText() { 484 protected boolean finishComposingText() {
492 mLastComposeText = null; 485 mLastComposeText = null;
493 if (mNativeImeAdapterAndroid == 0) return; 486 if (mNativeImeAdapterAndroid == 0) return false;
494 nativeFinishComposingText(mNativeImeAdapterAndroid); 487 nativeFinishComposingText(mNativeImeAdapterAndroid);
488 return true;
495 } 489 }
496 490
497 boolean translateAndSendNativeEvents(KeyEvent event) { 491 boolean translateAndSendNativeEvents(KeyEvent event) {
498 if (mNativeImeAdapterAndroid == 0) return false; 492 if (mNativeImeAdapterAndroid == 0) return false;
499 493
500 int action = event.getAction(); 494 int action = event.getAction();
501 if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) { 495 if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) {
502 // action == KeyEvent.ACTION_MULTIPLE 496 // action == KeyEvent.ACTION_MULTIPLE
503 // TODO(bulach): confirm the actual behavior. Apparently: 497 // TODO(bulach): confirm the actual behavior. Apparently:
504 // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a 498 // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 boolean setComposingRegion(CharSequence text, int start, int end) { 556 boolean setComposingRegion(CharSequence text, int start, int end) {
563 if (mNativeImeAdapterAndroid == 0) return false; 557 if (mNativeImeAdapterAndroid == 0) return false;
564 nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end); 558 nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
565 mLastComposeText = text != null ? text.toString() : null; 559 mLastComposeText = text != null ? text.toString() : null;
566 return true; 560 return true;
567 } 561 }
568 562
569 @CalledByNative 563 @CalledByNative
570 private void focusedNodeChanged(boolean isEditable) { 564 private void focusedNodeChanged(boolean isEditable) {
571 Log.d(TAG, "focusedNodeChanged"); 565 Log.d(TAG, "focusedNodeChanged");
572 if (mInputConnection != null && isEditable) mInputConnection.restartInpu t(); 566 if (isEditable) restartInput();
567 }
568
569 /**
570 * Restart input connection. You should call this function whenever you need to call
571 * InputMethodManager#restartInput().
572 */
573 public void restartInput() {
574 synchronized (mLock) {
575 if (mInputConnection != null) mInputConnection.restartInput();
576 }
577 }
578
579 /**
580 * Send a request to the native counterpart to give the latest text input st ate update.
581 */
582 boolean requestTextInputStateUpdate() {
583 if (mNativeImeAdapterAndroid == 0) return false;
584 nativeRequestTextInputStateUpdate(mNativeImeAdapterAndroid);
585 return true;
573 } 586 }
574 587
575 @CalledByNative 588 @CalledByNative
576 private void populateUnderlinesFromSpans(CharSequence text, long underlines) { 589 private void populateUnderlinesFromSpans(CharSequence text, long underlines) {
577 Log.d(TAG, "populateUnderlinesFromSpans: text [%s], underlines [%d]", te xt, underlines); 590 Log.d(TAG, "populateUnderlinesFromSpans: text [%s], underlines [%d]", te xt, underlines);
578 if (!(text instanceof SpannableString)) return; 591 if (!(text instanceof SpannableString)) return;
579 592
580 SpannableString spannableString = ((SpannableString) text); 593 SpannableString spannableString = ((SpannableString) text);
581 CharacterStyle spans[] = 594 CharacterStyle spans[] =
582 spannableString.getSpans(0, text.length(), CharacterStyle.class) ; 595 spannableString.getSpans(0, text.length(), CharacterStyle.class) ;
583 for (CharacterStyle span : spans) { 596 for (CharacterStyle span : spans) {
584 if (span instanceof BackgroundColorSpan) { 597 if (span instanceof BackgroundColorSpan) {
585 nativeAppendBackgroundColorSpan(underlines, spannableString.getS panStart(span), 598 nativeAppendBackgroundColorSpan(underlines, spannableString.getS panStart(span),
586 spannableString.getSpanEnd(span), 599 spannableString.getSpanEnd(span),
587 ((BackgroundColorSpan) span).getBackgroundColor()); 600 ((BackgroundColorSpan) span).getBackgroundColor());
588 } else if (span instanceof UnderlineSpan) { 601 } else if (span instanceof UnderlineSpan) {
589 nativeAppendUnderlineSpan(underlines, spannableString.getSpanSta rt(span), 602 nativeAppendUnderlineSpan(underlines, spannableString.getSpanSta rt(span),
590 spannableString.getSpanEnd(span)); 603 spannableString.getSpanEnd(span));
591 } 604 }
592 } 605 }
593 } 606 }
594 607
595 @CalledByNative 608 @CalledByNative
596 private void cancelComposition() { 609 private void cancelComposition() {
597 Log.d(TAG, "cancelComposition"); 610 Log.d(TAG, "cancelComposition");
598 if (mInputConnection != null) mInputConnection.restartInput(); 611 restartInput();
599 mLastComposeText = null; 612 mLastComposeText = null;
600 } 613 }
601 614
602 @CalledByNative 615 @CalledByNative
603 void detach() { 616 void detach() {
604 Log.d(TAG, "detach"); 617 Log.d(TAG, "detach");
605 mHandler.removeCallbacks(mDismissInputRunnable); 618 mHandler.removeCallbacks(mDismissInputRunnable);
606 mNativeImeAdapterAndroid = 0; 619 mNativeImeAdapterAndroid = 0;
607 mTextInputType = 0; 620 mTextInputType = 0;
608 } 621 }
609 622
610 private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndr oid, 623 private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndr oid,
611 int eventType, long timestampMs, int keyCode, int modifiers, int uni codeChar); 624 int eventType, long timestampMs, int keyCode, int modifiers, int uni codeChar);
612
613 private native boolean nativeSendKeyEvent(long nativeImeAdapterAndroid, KeyE vent event, 625 private native boolean nativeSendKeyEvent(long nativeImeAdapterAndroid, KeyE vent event,
614 int action, int modifiers, long timestampMs, int keyCode, int scanCo de, 626 int action, int modifiers, long timestampMs, int keyCode, int scanCo de,
615 boolean isSystemKey, int unicodeChar); 627 boolean isSystemKey, int unicodeChar);
616
617 private static native void nativeAppendUnderlineSpan(long underlinePtr, int start, int end); 628 private static native void nativeAppendUnderlineSpan(long underlinePtr, int start, int end);
618
619 private static native void nativeAppendBackgroundColorSpan(long underlinePtr , int start, 629 private static native void nativeAppendBackgroundColorSpan(long underlinePtr , int start,
620 int end, int backgroundColor); 630 int end, int backgroundColor);
621
622 private native void nativeSetComposingText(long nativeImeAdapterAndroid, Cha rSequence text, 631 private native void nativeSetComposingText(long nativeImeAdapterAndroid, Cha rSequence text,
623 String textStr, int newCursorPosition); 632 String textStr, int newCursorPosition);
624
625 private native void nativeCommitText(long nativeImeAdapterAndroid, String te xtStr); 633 private native void nativeCommitText(long nativeImeAdapterAndroid, String te xtStr);
626
627 private native void nativeFinishComposingText(long nativeImeAdapterAndroid); 634 private native void nativeFinishComposingText(long nativeImeAdapterAndroid);
628
629 private native void nativeAttachImeAdapter(long nativeImeAdapterAndroid); 635 private native void nativeAttachImeAdapter(long nativeImeAdapterAndroid);
630
631 private native void nativeSetEditableSelectionOffsets(long nativeImeAdapterA ndroid, 636 private native void nativeSetEditableSelectionOffsets(long nativeImeAdapterA ndroid,
632 int start, int end); 637 int start, int end);
633
634 private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, i nt start, int end); 638 private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, i nt start, int end);
635
636 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid , 639 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid ,
637 int before, int after); 640 int before, int after);
638
639 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid); 641 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid);
642 private native void nativeRequestTextInputStateUpdate(long nativeImeAdapterA ndroid);
640 } 643 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698