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

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

Issue 14100003: [Android] Moving input related files to a separate input/ directory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 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 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/ImeAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
similarity index 48%
rename from content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java
rename to content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
index 1f73502d70a17ff4705137121f602660c23553eb..1ea57b4a105d086d732c319d68876474f895155f 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java
@@ -2,22 +2,15 @@
// 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;
+package org.chromium.content.browser.input;
import android.content.Context;
import android.os.Handler;
import android.os.ResultReceiver;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.Selection;
-import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
-import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.ExtractedText;
-import android.view.inputmethod.ExtractedTextRequest;
import com.google.common.annotations.VisibleForTesting;
@@ -46,25 +39,44 @@ import org.chromium.base.JNINamespace;
* lifetime of the object.
*/
@JNINamespace("content")
-class ImeAdapter {
- interface ViewEmbedder {
+public class ImeAdapter {
+ public interface ViewEmbedder {
/**
* @param isFinish whether the event is occurring because input is finished.
*/
- public void onImeEvent(boolean isFinish);
- public void onSetFieldValue();
- public void onDismissInput();
- public View getAttachedView();
- public ResultReceiver getNewShowKeyboardReceiver();
+ void onImeEvent(boolean isFinish);
+ void onSetFieldValue();
+ void onDismissInput();
+ View getAttachedView();
+ ResultReceiver getNewShowKeyboardReceiver();
}
- static final int COMPOSITION_KEY_CODE = 229;
- /**
- * Selection value should be -1 if not known. See EditorInfo.java for details.
- */
- static final int INVALID_SELECTION = -1;
- static final int INVALID_COMPOSITION = -1;
+ private class DelayedDismissInput implements Runnable {
+ private final int mNativeImeAdapter;
+
+ DelayedDismissInput(int 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;
@@ -85,80 +97,29 @@ class ImeAdapter {
static int sModifierCapsLockOn;
static int sModifierNumLockOn;
- @CalledByNative
- 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
- static void initializeTextInputTypes(int textInputTypeNone, int textInputTypeText,
- int textInputTypeTextArea, int textInputTypePassword, int textInputTypeSearch,
- int textInputTypeUrl, int textInputTypeEmail, int textInputTypeTel,
- int textInputTypeNumber, int textInputTypeDate, int textInputTypeDateTime,
- int textInputTypeDateTimeLocal, int textInputTypeMonth, int textInputTypeTime,
- int textInputTypeWeek, int textInputTypeContentEditable) {
- sTextInputTypeNone = textInputTypeNone;
- sTextInputTypeText = textInputTypeText;
- sTextInputTypeTextArea = textInputTypeTextArea;
- sTextInputTypePassword = textInputTypePassword;
- sTextInputTypeSearch = textInputTypeSearch;
- sTextInputTypeUrl = textInputTypeUrl;
- sTextInputTypeEmail = textInputTypeEmail;
- sTextInputTypeTel = textInputTypeTel;
- sTextInputTypeNumber = textInputTypeNumber;
- sTextInputTypeWeek = textInputTypeWeek;
- sTextInputTypeContentEditable = textInputTypeContentEditable;
- }
-
private int mNativeImeAdapterAndroid;
- private int mTextInputType;
- private int mInitialSelectionStart;
- private int mInitialSelectionEnd;
-
private final Context mContext;
private InputMethodManagerWrapper mInputMethodManagerWrapper;
- private final SelectionHandleController mSelectionHandleController;
- private final InsertionHandleController mInsertionHandleController;
private AdapterInputConnection mInputConnection;
private final ViewEmbedder mViewEmbedder;
private final Handler mHandler;
-
- private class DelayedDismissInput implements Runnable {
- private final int mNativeImeAdapter;
-
- DelayedDismissInput(int nativeImeAdapter) {
- mNativeImeAdapter = nativeImeAdapter;
- }
-
- @Override
- public void run() {
- attach(mNativeImeAdapter, sTextInputTypeNone, INVALID_SELECTION, INVALID_SELECTION);
- dismissInput(true);
- }
- }
-
private DelayedDismissInput mDismissInput = null;
+ private final SelectionHandleController mSelectionHandleController;
+ private final InsertionHandleController mInsertionHandleController;
+ private int mTextInputType;
+ private int mInitialSelectionStart;
+ private int mInitialSelectionEnd;
@VisibleForTesting
- protected boolean mIsShowWithoutHideOutstanding = false;
+ boolean mIsShowWithoutHideOutstanding = false;
- // 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;
-
- ImeAdapter(Context context, SelectionHandleController selectionHandleController,
+ /**
+ * @param context View context.
+ * @param selectionHandleController The controller that handles selection.
+ * @param insertionHandleController The controller that handles insertion.
+ * @param embedder The view that is used for callbacks from ImeAdapter.
+ */
+ public ImeAdapter(Context context, SelectionHandleController selectionHandleController,
InsertionHandleController insertionHandleController, ViewEmbedder embedder) {
mContext = context;
mInputMethodManagerWrapper = new InputMethodManagerWrapper(context);
@@ -168,9 +129,11 @@ class ImeAdapter {
mHandler = new Handler();
}
- boolean isFor(int nativeImeAdapter, int textInputType) {
- return mNativeImeAdapterAndroid == nativeImeAdapter &&
- mTextInputType == textInputType;
+ public static class AdapterInputConnectionFactory {
+ public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
+ EditorInfo outAttrs) {
+ return new AdapterInputConnection(view, imeAdapter, outAttrs);
+ }
}
@VisibleForTesting
@@ -178,11 +141,86 @@ class ImeAdapter {
mInputMethodManagerWrapper = immw;
}
- private InputMethodManagerWrapper getInputMethodManagerWrapper() {
+ /**
+ * Should be only used by AdapterInputConnection.
+ * @return InputMethodManagerWrapper that should receive all the calls directed to
+ * InputMethodManager.
+ */
+ InputMethodManagerWrapper getInputMethodManagerWrapper() {
return mInputMethodManagerWrapper;
}
- void attachAndShowIfNeeded(int nativeImeAdapter, int textInputType,
+ /**
+ * 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;
+ }
+
+ void hideSelectionAndInsertionHandleControllers() {
+ mSelectionHandleController.hideAndDisallowAutomaticShowing();
+ mInsertionHandleController.hideAndDisallowAutomaticShowing();
+ }
+
+ 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);
@@ -213,7 +251,8 @@ class ImeAdapter {
}
}
- void attach(int nativeImeAdapter, int textInputType, int selectionStart, int selectionEnd) {
+ public void attach(int nativeImeAdapter, int textInputType, int selectionStart,
+ int selectionEnd) {
mNativeImeAdapterAndroid = nativeImeAdapter;
mTextInputType = textInputType;
mInitialSelectionStart = selectionStart;
@@ -226,7 +265,7 @@ class ImeAdapter {
* keyboard events to WebKit.
* @param nativeImeAdapter The pointer to the native ImeAdapter object.
*/
- void attach(int nativeImeAdapter) {
+ public void attach(int nativeImeAdapter) {
mNativeImeAdapterAndroid = nativeImeAdapter;
if (nativeImeAdapter != 0) {
nativeAttachImeAdapter(mNativeImeAdapterAndroid);
@@ -237,7 +276,7 @@ class ImeAdapter {
* Used to check whether the native counterpart of the ImeAdapter has been attached yet.
* @return Whether native ImeAdapter has been attached and its pointer is currently nonzero.
*/
- boolean isNativeImeAdapterAttached() {
+ public boolean isNativeImeAdapterAttached() {
return mNativeImeAdapterAndroid != 0;
}
@@ -261,13 +300,7 @@ class ImeAdapter {
}
}
- @CalledByNative
- void detach() {
- mNativeImeAdapterAndroid = 0;
- mTextInputType = 0;
- }
-
- boolean hasInputType() {
+ private boolean hasInputType() {
return mTextInputType != sTextInputTypeNone;
}
@@ -275,35 +308,41 @@ class ImeAdapter {
return type != sTextInputTypeNone && !InputDialogContainer.isDialogInputType(type);
}
- boolean hasTextInputType() {
+ public boolean hasTextInputType() {
return isTextInputType(mTextInputType);
}
- boolean dispatchKeyEvent(KeyEvent event) {
+ public boolean dispatchKeyEvent(KeyEvent event) {
return translateAndSendNativeEvents(event);
}
- void commitText() {
- cancelComposition();
- if (mNativeImeAdapterAndroid != 0) {
- nativeCommitText(mNativeImeAdapterAndroid, "");
- }
+ 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;
}
- @SuppressWarnings("unused")
- @CalledByNative
- private void cancelComposition() {
- if (mInputConnection != null) {
- mInputConnection.restartInput();
- }
+ 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++
+
@VisibleForTesting
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();
if (!isFinish) {
@@ -332,27 +371,7 @@ class ImeAdapter {
return true;
}
- 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;
- }
-
- private 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));
- }
-
- private boolean translateAndSendNativeEvents(KeyEvent event) {
+ boolean translateAndSendNativeEvents(KeyEvent event) {
if (mNativeImeAdapterAndroid == 0) return false;
int action = event.getAction();
@@ -376,35 +395,7 @@ class ImeAdapter {
event.isSystem(), event.getUnicodeChar());
}
- private void setInputConnection(AdapterInputConnection inputConnection) {
- mInputConnection = inputConnection;
- }
-
- 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;
- }
-
- boolean isActive() {
- return mInputConnection != null && mInputConnection.isActive();
- }
-
- private boolean sendSyntheticKeyEvent(
+ boolean sendSyntheticKeyEvent(
int eventType, long timestampMs, int keyCode, int unicodeChar) {
if (mNativeImeAdapterAndroid == 0) return false;
@@ -413,9 +404,8 @@ class ImeAdapter {
return true;
}
- private boolean deleteSurroundingText(int leftLength, int rightLength) {
+ boolean deleteSurroundingText(int leftLength, int rightLength) {
if (mNativeImeAdapterAndroid == 0) return false;
-
nativeDeleteSurroundingText(mNativeImeAdapterAndroid, leftLength, rightLength);
return true;
}
@@ -423,407 +413,131 @@ class ImeAdapter {
@VisibleForTesting
protected boolean setEditableSelectionOffsets(int start, int end) {
if (mNativeImeAdapterAndroid == 0) return false;
-
nativeSetEditableSelectionOffsets(mNativeImeAdapterAndroid, start, end);
return true;
}
- private void batchStateChanged(boolean isBegin) {
+ void batchStateChanged(boolean isBegin) {
if (mNativeImeAdapterAndroid == 0) return;
nativeImeBatchStateChanged(mNativeImeAdapterAndroid, isBegin);
}
- private boolean setComposingRegion(int start, int end) {
- if (mNativeImeAdapterAndroid == 0) return false;
+ void commitText() {
+ cancelComposition();
+ if (mNativeImeAdapterAndroid != 0) {
+ nativeCommitText(mNativeImeAdapterAndroid, "");
+ }
+ }
+ /**
+ * 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;
}
- boolean unselect() {
+ /**
+ * 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;
}
- boolean selectAll() {
+ /**
+ * 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;
}
- boolean cut() {
+ /**
+ * 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;
}
- boolean copy() {
+ /**
+ * 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;
}
- boolean paste() {
+ /**
+ * 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;
}
- public static class AdapterInputConnectionFactory {
- public AdapterInputConnection get(View view, ImeAdapter imeAdapter,
- EditorInfo outAttrs) {
- return new AdapterInputConnection(view, imeAdapter, outAttrs);
- }
- }
-
- // This InputConnection is created by ContentView.onCreateInputConnection.
- // It then adapts android's IME to chrome's RenderWidgetHostView using the
- // native ImeAdapterAndroid via the outer class ImeAdapter.
- public static class AdapterInputConnection extends BaseInputConnection {
- private static final String TAG =
- "org.chromium.content.browser.ImeAdapter$AdapterInputConnection";
- private static final boolean DEBUG = false;
- private final View mInternalView;
- private final ImeAdapter mImeAdapter;
-
- private boolean mSingleLine;
- private int mNumNestedBatchEdits = 0;
- private boolean mIgnoreTextInputStateUpdates = false;
-
- private int mLastUpdateSelectionStart = INVALID_SELECTION;
- private int mLastUpdateSelectionEnd = INVALID_SELECTION;
- private int mLastUpdateCompositionStart = INVALID_COMPOSITION;
- private int mLastUpdateCompositionEnd = INVALID_COMPOSITION;
-
- /**
- * Updates the AdapterInputConnection's internal representation of the text
- * being edited and its selection and composition properties. The resulting
- * Editable is accessible through the getEditable() method.
- * If the text has not changed, this also calls updateSelection on the InputMethodManager.
- * @param text The String contents of the field being edited
- * @param selectionStart The character offset of the selection start, or the caret
- * position if there is no selection
- * @param selectionEnd The character offset of the selection end, or the caret
- * position if there is no selection
- * @param compositionStart The character offset of the composition start, or -1
- * if there is no composition
- * @param compositionEnd The character offset of the composition end, or -1
- * if there is no selection
- */
- public void setEditableText(String text, int selectionStart, int selectionEnd,
- int compositionStart, int compositionEnd) {
- if (DEBUG) {
- Log.w(TAG, "setEditableText [" + text + "] [" + selectionStart + " " + selectionEnd
- + "] [" + compositionStart + " " + compositionEnd + "]");
- }
- Editable editable = getEditable();
-
- int prevSelectionStart = Selection.getSelectionStart(editable);
- int prevSelectionEnd = Selection.getSelectionEnd(editable);
- int prevCompositionStart = getComposingSpanStart(editable);
- int prevCompositionEnd = getComposingSpanEnd(editable);
- String prevText = editable.toString();
-
- selectionStart = Math.min(selectionStart, text.length());
- selectionEnd = Math.min(selectionEnd, text.length());
- compositionStart = Math.min(compositionStart, text.length());
- compositionEnd = Math.min(compositionEnd, text.length());
-
- boolean textUnchanged = prevText.equals(text);
-
- if (!textUnchanged) {
- editable.replace(0, editable.length(), text);
- }
-
- if (prevSelectionStart == selectionStart && prevSelectionEnd == selectionEnd
- && prevCompositionStart == compositionStart
- && prevCompositionEnd == compositionEnd) {
- // Nothing has changed; don't need to do anything
- return;
- }
-
- Selection.setSelection(editable, selectionStart, selectionEnd);
- super.setComposingRegion(compositionStart, compositionEnd);
-
- if (mIgnoreTextInputStateUpdates) return;
- updateSelection(selectionStart, selectionEnd, compositionStart, compositionEnd);
- }
-
- @VisibleForTesting
- protected void updateSelection(
- int selectionStart, int selectionEnd,
- int compositionStart, int compositionEnd) {
- // Avoid sending update if we sent an exact update already previously.
- if (mLastUpdateSelectionStart == selectionStart &&
- mLastUpdateSelectionEnd == selectionEnd &&
- mLastUpdateCompositionStart == compositionStart &&
- mLastUpdateCompositionEnd == compositionEnd) {
- return;
- }
- if (DEBUG) {
- Log.w(TAG, "updateSelection [" + selectionStart + " " + selectionEnd + "] ["
- + compositionStart + " " + compositionEnd + "]");
- }
- // updateSelection should be called every time the selection or composition changes
- // if it happens not within a batch edit, or at the end of each top level batch edit.
- getInputMethodManagerWrapper().updateSelection(mInternalView,
- selectionStart, selectionEnd, compositionStart, compositionEnd);
- mLastUpdateSelectionStart = selectionStart;
- mLastUpdateSelectionEnd = selectionEnd;
- mLastUpdateCompositionStart = compositionStart;
- mLastUpdateCompositionEnd = compositionEnd;
- }
-
- @Override
- public boolean setComposingText(CharSequence text, int newCursorPosition) {
- if (DEBUG) Log.w(TAG, "setComposingText [" + text + "] [" + newCursorPosition + "]");
- super.setComposingText(text, newCursorPosition);
- return mImeAdapter.checkCompositionQueueAndCallNative(text.toString(),
- newCursorPosition, false);
- }
-
- @Override
- public boolean commitText(CharSequence text, int newCursorPosition) {
- if (DEBUG) Log.w(TAG, "commitText [" + text + "] [" + newCursorPosition + "]");
- super.commitText(text, newCursorPosition);
- return mImeAdapter.checkCompositionQueueAndCallNative(text.toString(),
- newCursorPosition, text.length() > 0);
- }
-
- @Override
- public boolean performEditorAction(int actionCode) {
- if (DEBUG) Log.w(TAG, "performEditorAction [" + actionCode + "]");
- if (actionCode == EditorInfo.IME_ACTION_NEXT) {
- restartInput();
- // Send TAB key event
- long timeStampMs = System.currentTimeMillis();
- mImeAdapter.sendSyntheticKeyEvent(
- sEventTypeRawKeyDown, timeStampMs, KeyEvent.KEYCODE_TAB, 0);
- } else {
- mImeAdapter.sendKeyEventWithKeyCode(KeyEvent.KEYCODE_ENTER,
- KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
- | KeyEvent.FLAG_EDITOR_ACTION);
- }
- return true;
- }
-
- @Override
- public boolean performContextMenuAction(int id) {
- if (DEBUG) Log.w(TAG, "performContextMenuAction [" + id + "]");
- switch (id) {
- case android.R.id.selectAll:
- return mImeAdapter.selectAll();
- case android.R.id.cut:
- return mImeAdapter.cut();
- case android.R.id.copy:
- return mImeAdapter.copy();
- case android.R.id.paste:
- return mImeAdapter.paste();
- default:
- return false;
- }
- }
-
- @Override
- public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
- if (DEBUG) Log.w(TAG, "getExtractedText");
- ExtractedText et = new ExtractedText();
- Editable editable = getEditable();
- et.text = editable.toString();
- et.partialEndOffset = editable.length();
- et.selectionStart = Selection.getSelectionStart(editable);
- et.selectionEnd = Selection.getSelectionEnd(editable);
- et.flags = mSingleLine ? ExtractedText.FLAG_SINGLE_LINE : 0;
- return et;
- }
-
- @Override
- public boolean beginBatchEdit() {
- if (DEBUG) Log.w(TAG, "beginBatchEdit [" + (mNumNestedBatchEdits == 0) + "]");
- if (mNumNestedBatchEdits == 0) mImeAdapter.batchStateChanged(true);
-
- mNumNestedBatchEdits++;
- return false;
- }
-
- @Override
- public boolean endBatchEdit() {
- if (mNumNestedBatchEdits == 0) return false;
-
- --mNumNestedBatchEdits;
- if (DEBUG) Log.w(TAG, "endBatchEdit [" + (mNumNestedBatchEdits == 0) + "]");
- if (mNumNestedBatchEdits == 0) mImeAdapter.batchStateChanged(false);
- return false;
- }
-
- @Override
- public boolean deleteSurroundingText(int leftLength, int rightLength) {
- if (DEBUG) {
- Log.w(TAG, "deleteSurroundingText [" + leftLength + " " + rightLength + "]");
- }
- if (!super.deleteSurroundingText(leftLength, rightLength)) {
- return false;
- }
- return mImeAdapter.deleteSurroundingText(leftLength, rightLength);
- }
-
- @Override
- public boolean sendKeyEvent(KeyEvent event) {
- if (DEBUG) Log.w(TAG, "sendKeyEvent [" + event.getAction() + "]");
- mImeAdapter.mSelectionHandleController.hideAndDisallowAutomaticShowing();
- mImeAdapter.mInsertionHandleController.hideAndDisallowAutomaticShowing();
-
- // If this is a key-up, and backspace/del or if the key has a character representation,
- // need to update the underlying Editable (i.e. the local representation of the text
- // being edited).
- if (event.getAction() == KeyEvent.ACTION_UP) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
- super.deleteSurroundingText(1, 0);
- } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
- super.deleteSurroundingText(0, 1);
- } else {
- int unicodeChar = event.getUnicodeChar();
- if (unicodeChar != 0) {
- Editable editable = getEditable();
- int selectionStart = Selection.getSelectionStart(editable);
- int selectionEnd = Selection.getSelectionEnd(editable);
- if (selectionStart > selectionEnd) {
- int temp = selectionStart;
- selectionStart = selectionEnd;
- selectionEnd = temp;
- }
- editable.replace(selectionStart, selectionEnd,
- Character.toString((char)unicodeChar));
- }
- }
- }
- mImeAdapter.translateAndSendNativeEvents(event);
- return true;
- }
-
- @Override
- public boolean finishComposingText() {
- if (DEBUG) Log.w(TAG, "finishComposingText");
- Editable editable = getEditable();
- if (getComposingSpanStart(editable) == getComposingSpanEnd(editable)) {
- return true;
- }
- super.finishComposingText();
- return mImeAdapter.checkCompositionQueueAndCallNative("", 0, true);
- }
-
- @Override
- public boolean setSelection(int start, int end) {
- if (DEBUG) Log.w(TAG, "setSelection");
- if (start < 0 || end < 0) return true;
- super.setSelection(start, end);
- return mImeAdapter.setEditableSelectionOffsets(start, end);
- }
-
- /**
- * Informs the InputMethodManager and InputMethodSession (i.e. the IME) that the text
- * state is no longer what the IME has and that it needs to be updated.
- */
- void restartInput() {
- if (DEBUG) Log.w(TAG, "restartInput");
- getInputMethodManagerWrapper().restartInput(mInternalView);
- mIgnoreTextInputStateUpdates = false;
- mNumNestedBatchEdits = 0;
- }
-
- @Override
- public boolean setComposingRegion(int start, int end) {
- if (DEBUG) Log.w(TAG, "setComposingRegion [" + start + " " + end + "]");
- int a = Math.min(start, end);
- int b = Math.max(start, end);
- super.setComposingRegion(a, b);
- return mImeAdapter.setComposingRegion(a, b);
- }
-
- boolean isActive() {
- return getInputMethodManagerWrapper().isActive(mInternalView);
- }
-
- void setIgnoreTextInputStateUpdates(boolean shouldIgnore) {
- mIgnoreTextInputStateUpdates = shouldIgnore;
- if (shouldIgnore) return;
+ // Calls from C++ to Java
- Editable editable = getEditable();
- updateSelection(Selection.getSelectionStart(editable),
- Selection.getSelectionEnd(editable),
- getComposingSpanStart(editable),
- getComposingSpanEnd(editable));
- }
+ @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;
+ }
- @VisibleForTesting
- protected boolean isIgnoringTextInputStateUpdates() {
- return mIgnoreTextInputStateUpdates;
- }
+ @CalledByNative
+ private static void initializeTextInputTypes(int textInputTypeNone, int textInputTypeText,
+ int textInputTypeTextArea, int textInputTypePassword, int textInputTypeSearch,
+ int textInputTypeUrl, int textInputTypeEmail, int textInputTypeTel,
+ int textInputTypeNumber, int textInputTypeDate, int textInputTypeDateTime,
+ int textInputTypeDateTimeLocal, int textInputTypeMonth, int textInputTypeTime,
+ int textInputTypeWeek, int textInputTypeContentEditable) {
+ sTextInputTypeNone = textInputTypeNone;
+ sTextInputTypeText = textInputTypeText;
+ sTextInputTypeTextArea = textInputTypeTextArea;
+ sTextInputTypePassword = textInputTypePassword;
+ sTextInputTypeSearch = textInputTypeSearch;
+ sTextInputTypeUrl = textInputTypeUrl;
+ sTextInputTypeEmail = textInputTypeEmail;
+ sTextInputTypeTel = textInputTypeTel;
+ sTextInputTypeNumber = textInputTypeNumber;
+ sTextInputTypeWeek = textInputTypeWeek;
+ sTextInputTypeContentEditable = textInputTypeContentEditable;
+ }
- private InputMethodManagerWrapper getInputMethodManagerWrapper() {
- return mImeAdapter.getInputMethodManagerWrapper();
+ @CalledByNative
+ private void cancelComposition() {
+ if (mInputConnection != null) {
+ mInputConnection.restartInput();
}
+ }
- @VisibleForTesting
- protected AdapterInputConnection(View view, ImeAdapter imeAdapter, EditorInfo outAttrs) {
- super(view, true);
- mInternalView = view;
- mImeAdapter = imeAdapter;
- mImeAdapter.setInputConnection(this);
- mSingleLine = true;
- outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
- outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
- if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeText) {
- // Normal text field
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeTextArea ||
- imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeContentEditable) {
- // TextArea or contenteditable.
- outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
- | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
- | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_NONE;
- mSingleLine = false;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypePassword) {
- // Password
- outAttrs.inputType = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeSearch) {
- // Search
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_SEARCH;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeUrl) {
- // Url
- // TYPE_TEXT_VARIATION_URI prevents Tab key from showing, so
- // exclude it for now.
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeEmail) {
- // Email
- outAttrs.inputType = InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeTel) {
- // Telephone
- // Number and telephone do not have both a Tab key and an
- // action in default OSK, so set the action to NEXT
- outAttrs.inputType = InputType.TYPE_CLASS_PHONE;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
- } else if (imeAdapter.mTextInputType == ImeAdapter.sTextInputTypeNumber) {
- // Number
- outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
- | InputType.TYPE_NUMBER_VARIATION_NORMAL;
- outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
- }
- outAttrs.initialSelStart = imeAdapter.mInitialSelectionStart;
- outAttrs.initialSelEnd = imeAdapter.mInitialSelectionStart;
- }
+ @CalledByNative
+ void detach() {
+ mNativeImeAdapterAndroid = 0;
+ mTextInputType = 0;
}
private native boolean nativeSendSyntheticKeyEvent(int nativeImeAdapterAndroid,

Powered by Google App Engine
This is Rietveld 408576698