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

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

Issue 141533006: [Android] Move the java content/ package to content_public/ to start the split. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Small fixes and findbugs line update Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
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
deleted file mode 100644
index b4e41b99537acdb459bf5b73df5d05e6b3596395..0000000000000000000000000000000000000000
--- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
+++ /dev/null
@@ -1,546 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.content.browser.input;
-
-import android.os.Handler;
-import android.os.ResultReceiver;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.inputmethod.EditorInfo;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import org.chromium.base.CalledByNative;
-import org.chromium.base.JNINamespace;
-
-/**
- * Adapts and plumbs android IME service onto the chrome text input API.
- * ImeAdapter provides an interface in both ways native <-> java:
- * 1. InputConnectionAdapter notifies native code of text composition state and
- * dispatch key events from java -> WebKit.
- * 2. Native ImeAdapter notifies java side to clear composition text.
- *
- * The basic flow is:
- * 1. When InputConnectionAdapter gets called with composition or result text:
- * If we receive a composition text or a result text, then we just need to
- * dispatch a synthetic key event with special keycode 229, and then dispatch
- * the composition or result text.
- * 2. Intercept dispatchKeyEvent() method for key events not handled by IME, we
- * need to dispatch them to webkit and check webkit's reply. Then inject a
- * new key event for further processing if webkit didn't handle it.
- *
- * Note that the native peer object does not take any strong reference onto the
- * instance of this java object, hence it is up to the client of this class (e.g.
- * the ViewEmbedder implementor) to hold a strong reference to it for the required
- * lifetime of the object.
- */
-@JNINamespace("content")
-public class ImeAdapter {
- /**
- * Interface for the delegate that needs to be notified of IME changes.
- */
- public interface ImeAdapterDelegate {
- /**
- * @param isFinish whether the event is occurring because input is finished.
- */
- void onImeEvent(boolean isFinish);
- void onSetFieldValue();
- void onDismissInput();
- View getAttachedView();
- ResultReceiver getNewShowKeyboardReceiver();
- }
-
- private class DelayedDismissInput implements Runnable {
- private final long mNativeImeAdapter;
-
- DelayedDismissInput(long nativeImeAdapter) {
- mNativeImeAdapter = nativeImeAdapter;
- }
-
- @Override
- public void run() {
- attach(mNativeImeAdapter, sTextInputTypeNone, AdapterInputConnection.INVALID_SELECTION,
- AdapterInputConnection.INVALID_SELECTION);
- dismissInput(true);
- }
- }
-
- private static final int COMPOSITION_KEY_CODE = 229;
-
- // Delay introduced to avoid hiding the keyboard if new show requests are received.
- // The time required by the unfocus-focus events triggered by tab has been measured in soju:
- // Mean: 18.633 ms, Standard deviation: 7.9837 ms.
- // The value here should be higher enough to cover these cases, but not too high to avoid
- // letting the user perceiving important delays.
- private static final int INPUT_DISMISS_DELAY = 150;
-
- // All the constants that are retrieved from the C++ code.
- // They get set through initializeWebInputEvents and initializeTextInputTypes calls.
- static int sEventTypeRawKeyDown;
- static int sEventTypeKeyUp;
- static int sEventTypeChar;
- static int sTextInputTypeNone;
- static int sTextInputTypeText;
- static int sTextInputTypeTextArea;
- static int sTextInputTypePassword;
- static int sTextInputTypeSearch;
- static int sTextInputTypeUrl;
- static int sTextInputTypeEmail;
- static int sTextInputTypeTel;
- static int sTextInputTypeNumber;
- static int sTextInputTypeContentEditable;
- static int sModifierShift;
- static int sModifierAlt;
- static int sModifierCtrl;
- static int sModifierCapsLockOn;
- static int sModifierNumLockOn;
-
- private long mNativeImeAdapterAndroid;
- private InputMethodManagerWrapper mInputMethodManagerWrapper;
- private AdapterInputConnection mInputConnection;
- private final ImeAdapterDelegate mViewEmbedder;
- private final Handler mHandler;
- private DelayedDismissInput mDismissInput = null;
- private int mTextInputType;
- private int mInitialSelectionStart;
- private int mInitialSelectionEnd;
-
- @VisibleForTesting
- boolean mIsShowWithoutHideOutstanding = false;
-
- /**
- * @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) {
- mInputMethodManagerWrapper = wrapper;
- mViewEmbedder = embedder;
- mHandler = new Handler();
- }
-
- /**
- * Default factory for AdapterInputConnection classes.
- */
- public static class AdapterInputConnectionFactory {
- public AdapterInputConnection get(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
- return new AdapterInputConnection(view, imeAdapter, outAttrs);
- }
- }
-
- @VisibleForTesting
- public void setInputMethodManagerWrapper(InputMethodManagerWrapper immw) {
- mInputMethodManagerWrapper = immw;
- }
-
- /**
- * Should be only used by AdapterInputConnection.
- * @return InputMethodManagerWrapper that should receive all the calls directed to
- * InputMethodManager.
- */
- InputMethodManagerWrapper getInputMethodManagerWrapper() {
- return mInputMethodManagerWrapper;
- }
-
- /**
- * Set the current active InputConnection when a new InputConnection is constructed.
- * @param inputConnection The input connection that is currently used with IME.
- */
- void setInputConnection(AdapterInputConnection inputConnection) {
- mInputConnection = inputConnection;
- }
-
- /**
- * Should be only used by AdapterInputConnection.
- * @return The input type of currently focused element.
- */
- int getTextInputType() {
- return mTextInputType;
- }
-
- /**
- * Should be only used by AdapterInputConnection.
- * @return The starting index of the initial text selection.
- */
- int getInitialSelectionStart() {
- return mInitialSelectionStart;
- }
-
- /**
- * Should be only used by AdapterInputConnection.
- * @return The ending index of the initial text selection.
- */
- int getInitialSelectionEnd() {
- return mInitialSelectionEnd;
- }
-
- public static int getTextInputTypeNone() {
- return sTextInputTypeNone;
- }
-
- private static int getModifiers(int metaState) {
- int modifiers = 0;
- if ((metaState & KeyEvent.META_SHIFT_ON) != 0) {
- modifiers |= sModifierShift;
- }
- if ((metaState & KeyEvent.META_ALT_ON) != 0) {
- modifiers |= sModifierAlt;
- }
- if ((metaState & KeyEvent.META_CTRL_ON) != 0) {
- modifiers |= sModifierCtrl;
- }
- if ((metaState & KeyEvent.META_CAPS_LOCK_ON) != 0) {
- modifiers |= sModifierCapsLockOn;
- }
- if ((metaState & KeyEvent.META_NUM_LOCK_ON) != 0) {
- modifiers |= sModifierNumLockOn;
- }
- return modifiers;
- }
-
- public boolean isActive() {
- return mInputConnection != null && mInputConnection.isActive();
- }
-
- private boolean isFor(int nativeImeAdapter, int textInputType) {
- return mNativeImeAdapterAndroid == nativeImeAdapter &&
- mTextInputType == textInputType;
- }
-
- public void attachAndShowIfNeeded(int nativeImeAdapter, int textInputType,
- int selectionStart, int selectionEnd, boolean showIfNeeded) {
- mHandler.removeCallbacks(mDismissInput);
-
- // If current input type is none and showIfNeeded is false, IME should not be shown
- // and input type should remain as none.
- if (mTextInputType == sTextInputTypeNone && !showIfNeeded) {
- return;
- }
-
- if (!isFor(nativeImeAdapter, textInputType)) {
- // Set a delayed task to perform unfocus. This avoids hiding the keyboard when tabbing
- // through text inputs or when JS rapidly changes focus to another text element.
- if (textInputType == sTextInputTypeNone) {
- mDismissInput = new DelayedDismissInput(nativeImeAdapter);
- mHandler.postDelayed(mDismissInput, INPUT_DISMISS_DELAY);
- return;
- }
-
- attach(nativeImeAdapter, textInputType, selectionStart, selectionEnd);
-
- mInputMethodManagerWrapper.restartInput(mViewEmbedder.getAttachedView());
- if (showIfNeeded) {
- showKeyboard();
- }
- } else if (hasInputType() && showIfNeeded) {
- showKeyboard();
- }
- }
-
- public void attach(long nativeImeAdapter, int textInputType, int selectionStart,
- int selectionEnd) {
- if (mNativeImeAdapterAndroid != 0) {
- nativeResetImeAdapter(mNativeImeAdapterAndroid);
- }
- mNativeImeAdapterAndroid = nativeImeAdapter;
- mTextInputType = textInputType;
- mInitialSelectionStart = selectionStart;
- mInitialSelectionEnd = selectionEnd;
- if (nativeImeAdapter != 0) {
- nativeAttachImeAdapter(mNativeImeAdapterAndroid);
- }
- }
-
- /**
- * 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 (mNativeImeAdapterAndroid != 0) {
- nativeResetImeAdapter(mNativeImeAdapterAndroid);
- }
- mNativeImeAdapterAndroid = nativeImeAdapter;
- if (nativeImeAdapter != 0) {
- nativeAttachImeAdapter(mNativeImeAdapterAndroid);
- }
- }
-
- private void showKeyboard() {
- mIsShowWithoutHideOutstanding = true;
- mInputMethodManagerWrapper.showSoftInput(mViewEmbedder.getAttachedView(), 0,
- mViewEmbedder.getNewShowKeyboardReceiver());
- }
-
- private void dismissInput(boolean unzoomIfNeeded) {
- mIsShowWithoutHideOutstanding = false;
- View view = mViewEmbedder.getAttachedView();
- if (mInputMethodManagerWrapper.isActive(view)) {
- mInputMethodManagerWrapper.hideSoftInputFromWindow(view.getWindowToken(), 0,
- unzoomIfNeeded ? mViewEmbedder.getNewShowKeyboardReceiver() : null);
- }
- mViewEmbedder.onDismissInput();
- }
-
- private boolean hasInputType() {
- return mTextInputType != sTextInputTypeNone;
- }
-
- private static boolean isTextInputType(int type) {
- return type != sTextInputTypeNone && !InputDialogContainer.isDialogInputType(type);
- }
-
- public boolean hasTextInputType() {
- return isTextInputType(mTextInputType);
- }
-
- public boolean dispatchKeyEvent(KeyEvent event) {
- return translateAndSendNativeEvents(event);
- }
-
- private int shouldSendKeyEventWithKeyCode(String text) {
- if (text.length() != 1) return COMPOSITION_KEY_CODE;
-
- if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER;
- else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB;
- else return COMPOSITION_KEY_CODE;
- }
-
- void sendKeyEventWithKeyCode(int keyCode, int flags) {
- long eventTime = System.currentTimeMillis();
- translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
- KeyEvent.ACTION_DOWN, keyCode, 0, 0,
- KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- flags));
- translateAndSendNativeEvents(new KeyEvent(System.currentTimeMillis(), eventTime,
- KeyEvent.ACTION_UP, keyCode, 0, 0,
- KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- flags));
- }
-
- // Calls from Java to C++
-
- boolean checkCompositionQueueAndCallNative(String text, int newCursorPosition,
- boolean isCommit) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- // Committing an empty string finishes the current composition.
- boolean isFinish = text.isEmpty();
- mViewEmbedder.onImeEvent(isFinish);
- int keyCode = shouldSendKeyEventWithKeyCode(text);
- long timeStampMs = System.currentTimeMillis();
-
- if (keyCode != COMPOSITION_KEY_CODE) {
- sendKeyEventWithKeyCode(keyCode,
- KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
- } else {
- nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeRawKeyDown,
- timeStampMs, keyCode, 0);
- if (isCommit) {
- nativeCommitText(mNativeImeAdapterAndroid, text);
- } else {
- nativeSetComposingText(mNativeImeAdapterAndroid, text, newCursorPosition);
- }
- nativeSendSyntheticKeyEvent(mNativeImeAdapterAndroid, sEventTypeKeyUp,
- timeStampMs, keyCode, 0);
- }
-
- return true;
- }
-
- void finishComposingText() {
- if (mNativeImeAdapterAndroid == 0) return;
- nativeFinishComposingText(mNativeImeAdapterAndroid);
- }
-
- boolean translateAndSendNativeEvents(KeyEvent event) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- int action = event.getAction();
- if (action != KeyEvent.ACTION_DOWN &&
- action != KeyEvent.ACTION_UP) {
- // action == KeyEvent.ACTION_MULTIPLE
- // TODO(bulach): confirm the actual behavior. Apparently:
- // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a
- // composition key down (229) followed by a commit text with the
- // string from event.getUnicodeChars().
- // Otherwise, we'd need to send an event with a
- // WebInputEvent::IsAutoRepeat modifier. We also need to verify when
- // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOWN,
- // and if that's the case, we'll need to review when to send the Char
- // event.
- return false;
- }
- mViewEmbedder.onImeEvent(false);
- return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getAction(),
- getModifiers(event.getMetaState()), event.getEventTime(), event.getKeyCode(),
- event.isSystem(), event.getUnicodeChar());
- }
-
- boolean sendSyntheticKeyEvent(
- int eventType, long timestampMs, int keyCode, int unicodeChar) {
- if (mNativeImeAdapterAndroid == 0) return false;
-
- nativeSendSyntheticKeyEvent(
- mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, unicodeChar);
- return true;
- }
-
- boolean deleteSurroundingText(int beforeLength, int afterLength) {
- if (mNativeImeAdapterAndroid == 0) return false;
- nativeDeleteSurroundingText(mNativeImeAdapterAndroid, beforeLength, afterLength);
- return true;
- }
-
- boolean setEditableSelectionOffsets(int start, int end) {
- if (mNativeImeAdapterAndroid == 0) return false;
- nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end);
- return true;
- }
-
- /**
- * Send a request to the native counterpart to set compositing region to given indices.
- * @param start The start of the composition.
- * @param end The end of the composition.
- * @return Whether the native counterpart of ImeAdapter received the call.
- */
- boolean setComposingRegion(int start, int end) {
- if (mNativeImeAdapterAndroid == 0) return false;
- nativeSetComposingRegion(mNativeImeAdapterAndroid, start, end);
- return true;
- }
-
- /**
- * Send a request to the native counterpart to unselect text.
- * @return Whether the native counterpart of ImeAdapter received the call.
- */
- public boolean unselect() {
- if (mNativeImeAdapterAndroid == 0) return false;
- nativeUnselect(mNativeImeAdapterAndroid);
- return true;
- }
-
- /**
- * Send a request to the native counterpart of ImeAdapter to select all the text.
- * @return Whether the native counterpart of ImeAdapter received the call.
- */
- public boolean selectAll() {
- if (mNativeImeAdapterAndroid == 0) return false;
- nativeSelectAll(mNativeImeAdapterAndroid);
- return true;
- }
-
- /**
- * Send a request to the native counterpart of ImeAdapter to cut the selected text.
- * @return Whether the native counterpart of ImeAdapter received the call.
- */
- public boolean cut() {
- if (mNativeImeAdapterAndroid == 0) return false;
- nativeCut(mNativeImeAdapterAndroid);
- return true;
- }
-
- /**
- * Send a request to the native counterpart of ImeAdapter to copy the selected text.
- * @return Whether the native counterpart of ImeAdapter received the call.
- */
- public boolean copy() {
- if (mNativeImeAdapterAndroid == 0) return false;
- nativeCopy(mNativeImeAdapterAndroid);
- return true;
- }
-
- /**
- * Send a request to the native counterpart of ImeAdapter to paste the text from the clipboard.
- * @return Whether the native counterpart of ImeAdapter received the call.
- */
- public boolean paste() {
- if (mNativeImeAdapterAndroid == 0) return false;
- nativePaste(mNativeImeAdapterAndroid);
- return true;
- }
-
- // Calls from C++ to Java
-
- @CalledByNative
- private static void initializeWebInputEvents(int eventTypeRawKeyDown, int eventTypeKeyUp,
- int eventTypeChar, int modifierShift, int modifierAlt, int modifierCtrl,
- int modifierCapsLockOn, int modifierNumLockOn) {
- sEventTypeRawKeyDown = eventTypeRawKeyDown;
- sEventTypeKeyUp = eventTypeKeyUp;
- sEventTypeChar = eventTypeChar;
- sModifierShift = modifierShift;
- sModifierAlt = modifierAlt;
- sModifierCtrl = modifierCtrl;
- sModifierCapsLockOn = modifierCapsLockOn;
- sModifierNumLockOn = modifierNumLockOn;
- }
-
- @CalledByNative
- private static void initializeTextInputTypes(int textInputTypeNone, int textInputTypeText,
- int textInputTypeTextArea, int textInputTypePassword, int textInputTypeSearch,
- int textInputTypeUrl, int textInputTypeEmail, int textInputTypeTel,
- int textInputTypeNumber, int textInputTypeContentEditable) {
- sTextInputTypeNone = textInputTypeNone;
- sTextInputTypeText = textInputTypeText;
- sTextInputTypeTextArea = textInputTypeTextArea;
- sTextInputTypePassword = textInputTypePassword;
- sTextInputTypeSearch = textInputTypeSearch;
- sTextInputTypeUrl = textInputTypeUrl;
- sTextInputTypeEmail = textInputTypeEmail;
- sTextInputTypeTel = textInputTypeTel;
- sTextInputTypeNumber = textInputTypeNumber;
- sTextInputTypeContentEditable = textInputTypeContentEditable;
- }
-
- @CalledByNative
- private void focusedNodeChanged(boolean isEditable) {
- if (mInputConnection != null && isEditable) mInputConnection.restartInput();
- }
-
- @CalledByNative
- private void cancelComposition() {
- if (mInputConnection != null) mInputConnection.restartInput();
- }
-
- @CalledByNative
- void detach() {
- if (mDismissInput != null) mHandler.removeCallbacks(mDismissInput);
- mNativeImeAdapterAndroid = 0;
- mTextInputType = 0;
- }
-
- private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndroid,
- int eventType, long timestampMs, int keyCode, int unicodeChar);
-
- private native boolean nativeSendKeyEvent(long nativeImeAdapterAndroid, KeyEvent event,
- int action, int modifiers, long timestampMs, int keyCode, boolean isSystemKey,
- int unicodeChar);
-
- private native void nativeSetComposingText(long nativeImeAdapterAndroid, String text,
- int newCursorPosition);
-
- private native void nativeCommitText(long nativeImeAdapterAndroid, String text);
-
- 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);
-
- private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid,
- int before, int after);
-
- private native void nativeUnselect(long nativeImeAdapterAndroid);
- private native void nativeSelectAll(long nativeImeAdapterAndroid);
- private native void nativeCut(long nativeImeAdapterAndroid);
- private native void nativeCopy(long nativeImeAdapterAndroid);
- private native void nativePaste(long nativeImeAdapterAndroid);
- private native void nativeResetImeAdapter(long nativeImeAdapterAndroid);
-}

Powered by Google App Engine
This is Rietveld 408576698