| Index: content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
|
| index db0e84c923bdc66a374a3c3260a6a03482da1809..912e9b6dfac0f29f72bd57a40d54609c737beef9 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
|
| @@ -29,6 +29,7 @@ import org.chromium.blink_public.web.WebInputEventType;
|
| import org.chromium.blink_public.web.WebTextInputMode;
|
| import org.chromium.content.browser.RenderCoordinates;
|
| import org.chromium.content.browser.picker.InputDialogContainer;
|
| +import org.chromium.content_public.browser.WebContents;
|
| import org.chromium.ui.base.ime.TextInputType;
|
|
|
| /**
|
| @@ -118,12 +119,17 @@ public class ImeAdapter {
|
| private int mLastCompositionEnd;
|
| private boolean mRestartInputOnNextStateUpdate;
|
|
|
| + // True if ImeAdapter is connected to render process.
|
| + private boolean mIsConnected;
|
| +
|
| /**
|
| + * @param webContents WebContents instance with which this ImeAdapter is associated.
|
| * @param wrapper InputMethodManagerWrapper that should receive all the call directed to
|
| * InputMethodManager.
|
| * @param embedder The view that is used for callbacks from ImeAdapter.
|
| */
|
| - public ImeAdapter(InputMethodManagerWrapper wrapper, ImeAdapterDelegate embedder) {
|
| + public ImeAdapter(WebContents webContents, InputMethodManagerWrapper wrapper,
|
| + ImeAdapterDelegate embedder) {
|
| mInputMethodManagerWrapper = wrapper;
|
| mViewEmbedder = embedder;
|
| // Deep copy newConfig so that we can notice the difference.
|
| @@ -157,6 +163,7 @@ public class ImeAdapter {
|
| } else {
|
| mCursorAnchorInfoController = null;
|
| }
|
| + mNativeImeAdapterAndroid = nativeInit(webContents);
|
| }
|
|
|
| private void createInputConnectionFactory() {
|
| @@ -164,6 +171,13 @@ public class ImeAdapter {
|
| mInputConnectionFactory = new ThreadedInputConnectionFactory(mInputMethodManagerWrapper);
|
| }
|
|
|
| + // Tells if the ImeAdapter in valid state (i.e. not in destroyed state), and is
|
| + // connected to render process. The former check guards against the call via
|
| + // ThreadedInputConnection from Android framework after ImeAdapter.destroy() is called.
|
| + private boolean isValid() {
|
| + return mNativeImeAdapterAndroid != 0 && mIsConnected;
|
| + }
|
| +
|
| /**
|
| * @see View#onCreateInputConnection(EditorInfo)
|
| */
|
| @@ -190,7 +204,7 @@ public class ImeAdapter {
|
| false /* not an immediate request */, false /* disable monitoring */,
|
| mViewEmbedder.getAttachedView());
|
| }
|
| - if (mNativeImeAdapterAndroid != 0) {
|
| + if (isValid()) {
|
| nativeRequestCursorUpdate(mNativeImeAdapterAndroid,
|
| false /* not an immediate request */, false /* disable monitoring */);
|
| }
|
| @@ -325,27 +339,6 @@ public class ImeAdapter {
|
| }
|
|
|
| /**
|
| - * Attaches the imeAdapter to its native counterpart. This is needed to start forwarding
|
| - * keyboard events to WebKit.
|
| - * @param nativeImeAdapter The pointer to the native ImeAdapter object.
|
| - */
|
| - public void attach(long nativeImeAdapter) {
|
| - if (DEBUG_LOGS) Log.i(TAG, "attach");
|
| - if (mNativeImeAdapterAndroid == nativeImeAdapter) return;
|
| - if (mNativeImeAdapterAndroid != 0) {
|
| - nativeResetImeAdapter(mNativeImeAdapterAndroid);
|
| - }
|
| - if (nativeImeAdapter != 0) {
|
| - nativeAttachImeAdapter(nativeImeAdapter);
|
| - }
|
| - mNativeImeAdapterAndroid = nativeImeAdapter;
|
| - if (nativeImeAdapter != 0) {
|
| - createInputConnectionFactory();
|
| - }
|
| - resetAndHideKeyboard();
|
| - }
|
| -
|
| - /**
|
| * Show soft keyboard only if it is the current keyboard configuration.
|
| */
|
| private void showSoftKeyboard() {
|
| @@ -485,6 +478,16 @@ public class ImeAdapter {
|
| hideKeyboard();
|
| }
|
|
|
| + @CalledByNative
|
| + private void destroy() {
|
| + resetAndHideKeyboard();
|
| + mNativeImeAdapterAndroid = 0;
|
| + mIsConnected = false;
|
| + if (mCursorAnchorInfoController != null) {
|
| + mCursorAnchorInfoController.focusedNodeChanged(false);
|
| + }
|
| + }
|
| +
|
| /**
|
| * Update selection to input method manager.
|
| *
|
| @@ -517,7 +520,7 @@ public class ImeAdapter {
|
| }
|
|
|
| boolean performEditorAction(int actionCode) {
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
| if (actionCode == EditorInfo.IME_ACTION_NEXT) {
|
| sendSyntheticKeyPress(KeyEvent.KEYCODE_TAB,
|
| KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
|
| @@ -549,7 +552,7 @@ public class ImeAdapter {
|
|
|
| boolean sendCompositionToNative(
|
| CharSequence text, int newCursorPosition, boolean isCommit, int unicodeFromKeyEvent) {
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
|
|
| // One WebView app detects Enter in JS by looking at KeyDown (http://crbug/577967).
|
| if (TextUtils.equals(text, "\n")) {
|
| @@ -577,13 +580,13 @@ public class ImeAdapter {
|
|
|
| @VisibleForTesting
|
| boolean finishComposingText() {
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
| nativeFinishComposingText(mNativeImeAdapterAndroid);
|
| return true;
|
| }
|
|
|
| boolean sendKeyEvent(KeyEvent event) {
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
|
|
| int action = event.getAction();
|
| int type;
|
| @@ -615,7 +618,7 @@ public class ImeAdapter {
|
| */
|
| boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
| mViewEmbedder.onImeEvent();
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
| nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.RawKeyDown, 0,
|
| SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0);
|
| nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afterLength);
|
| @@ -634,7 +637,7 @@ public class ImeAdapter {
|
| */
|
| boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
|
| mViewEmbedder.onImeEvent();
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
| nativeSendKeyEvent(mNativeImeAdapterAndroid, null, WebInputEventType.RawKeyDown, 0,
|
| SystemClock.uptimeMillis(), COMPOSITION_KEY_CODE, 0, false, 0);
|
| nativeDeleteSurroundingTextInCodePoints(
|
| @@ -651,7 +654,7 @@ public class ImeAdapter {
|
| * @return Whether the native counterpart of ImeAdapter received the call.
|
| */
|
| boolean setEditableSelectionOffsets(int start, int end) {
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
| nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end);
|
| return true;
|
| }
|
| @@ -663,7 +666,7 @@ public class ImeAdapter {
|
| * @return Whether the native counterpart of ImeAdapter received the call.
|
| */
|
| boolean setComposingRegion(int start, int end) {
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
| if (start <= end) {
|
| nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
|
| } else {
|
| @@ -690,7 +693,7 @@ public class ImeAdapter {
|
| * Send a request to the native counterpart to give the latest text input state update.
|
| */
|
| boolean requestTextInputStateUpdate() {
|
| - if (mNativeImeAdapterAndroid == 0) return false;
|
| + if (!isValid()) return false;
|
| // You won't get state update anyways.
|
| if (mInputConnection == null) return false;
|
| return nativeRequestTextInputStateUpdate(mNativeImeAdapterAndroid);
|
| @@ -705,7 +708,7 @@ public class ImeAdapter {
|
| final boolean monitorRequest =
|
| (cursorUpdateMode & InputConnection.CURSOR_UPDATE_MONITOR) != 0;
|
|
|
| - if (mNativeImeAdapterAndroid != 0) {
|
| + if (isValid()) {
|
| nativeRequestCursorUpdate(mNativeImeAdapterAndroid, immediateRequest, monitorRequest);
|
| }
|
| if (mCursorAnchorInfoController == null) return false;
|
| @@ -770,14 +773,14 @@ public class ImeAdapter {
|
| }
|
|
|
| @CalledByNative
|
| - private void detach() {
|
| - if (DEBUG_LOGS) Log.i(TAG, "detach");
|
| - mNativeImeAdapterAndroid = 0;
|
| - if (mCursorAnchorInfoController != null) {
|
| - mCursorAnchorInfoController.focusedNodeChanged(false);
|
| - }
|
| + private void onConnectedToRenderProcess() {
|
| + if (DEBUG_LOGS) Log.i(TAG, "onConnectedToRenderProcess");
|
| + mIsConnected = true;
|
| + createInputConnectionFactory();
|
| + resetAndHideKeyboard();
|
| }
|
|
|
| + private native long nativeInit(WebContents webContents);
|
| private native boolean nativeSendKeyEvent(long nativeImeAdapterAndroid, KeyEvent event,
|
| int type, int modifiers, long timestampMs, int keyCode, int scanCode,
|
| boolean isSystemKey, int unicodeChar);
|
| @@ -789,7 +792,6 @@ public class ImeAdapter {
|
| private native void nativeCommitText(
|
| long nativeImeAdapterAndroid, CharSequence text, String textStr, int newCursorPosition);
|
| private native void nativeFinishComposingText(long nativeImeAdapterAndroid);
|
| - private native void nativeAttachImeAdapter(long nativeImeAdapterAndroid);
|
| private native void nativeSetEditableSelectionOffsets(long nativeImeAdapterAndroid,
|
| int start, int end);
|
| private native void nativeSetComposingRegion(long nativeImeAdapterAndroid, int start, int end);
|
| @@ -797,7 +799,6 @@ public class ImeAdapter {
|
| int before, int after);
|
| private native void nativeDeleteSurroundingTextInCodePoints(
|
| long nativeImeAdapterAndroid, int before, int after);
|
| - private native void nativeResetImeAdapter(long nativeImeAdapterAndroid);
|
| private native boolean nativeRequestTextInputStateUpdate(long nativeImeAdapterAndroid);
|
| private native void nativeRequestCursorUpdate(long nativeImeAdapterAndroid,
|
| boolean immediateRequest, boolean monitorRequest);
|
|
|