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

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

Issue 1589953005: Support InputMethodManager#updateCursorAnchorInfo for Android 5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Findbugs warning / Simplify the state transition. Created 4 years, 10 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
index 75bb44fae0d3d228394b0e9bef71477c02904a08..050e170031e297f6d6650e49f6c528ae2671507b 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
@@ -18,7 +18,9 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;
+import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
import org.chromium.base.Log;
import org.chromium.base.VisibleForTesting;
@@ -26,6 +28,7 @@ import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.blink_public.web.WebInputEventModifier;
import org.chromium.blink_public.web.WebInputEventType;
+import org.chromium.content.browser.RenderCoordinates;
import org.chromium.ui.base.ime.TextInputType;
import org.chromium.ui.picker.InputDialogContainer;
@@ -101,6 +104,14 @@ public class ImeAdapter {
// Every time the user, IME, javascript (Blink), autofill etc. modifies the content, the new
// state must be reflected to this to keep consistency.
private final Editable mEditable;
+ // This holds the information necessary for constructing CursorAnchorInfo, and notifies to
+ // InputMethodManager on appropriate timing, depending on how IME requested the information
+ // via InputConnection. The update request is per InputConnection, hence for each time it is
+ // re-created, the monitoring status will be reset.
+ private final CursorAnchorInfoController mCursorAnchorInfoController;
+
+ @VisibleForTesting
+ int mLastSyntheticKeyCode;
private int mTextInputType = TextInputType.NONE;
private int mTextInputFlags;
@@ -122,6 +133,7 @@ public class ImeAdapter {
// Deep copy newConfig so that we can notice the difference.
mCurrentConfig = new Configuration(
mViewEmbedder.getAttachedView().getResources().getConfiguration());
+ mCursorAnchorInfoController = CursorAnchorInfoController.create(wrapper);
}
/**
@@ -162,6 +174,9 @@ public class ImeAdapter {
int initialSelEnd = outAttrs.initialSelEnd = Selection.getSelectionEnd(mEditable);
mInputConnection = mInputConnectionFactory.get(
mViewEmbedder.getAttachedView(), this, initialSelStart, initialSelEnd, outAttrs);
+ if (mCursorAnchorInfoController != null) {
+ mCursorAnchorInfoController.resetMonitoringState();
aelias_OOO_until_Jul13 2016/02/10 08:23:42 Anything else needs to be reset here? How about m
kinaba 2016/02/19 12:28:29 Done (mHasPendingImmediateRequest will also be res
+ }
if (DEBUG_LOGS) Log.w(TAG, "onCreateInputConnection");
return mInputConnection;
}
@@ -174,6 +189,9 @@ public class ImeAdapter {
@VisibleForTesting
public void setInputMethodManagerWrapperForTest(InputMethodManagerWrapper immw) {
mInputMethodManagerWrapper = immw;
+ if (mCursorAnchorInfoController != null) {
+ mCursorAnchorInfoController.setInputMethodManagerWrapper(immw);
+ }
}
@VisibleForTesting
@@ -562,11 +580,64 @@ public class ImeAdapter {
@CalledByNative
private void focusedNodeChanged(boolean isEditable) {
if (DEBUG_LOGS) Log.w(TAG, "focusedNodeChanged: isEditable [%b]", isEditable);
+
+ // Update controller before the connection is restarted.
+ if (mCursorAnchorInfoController != null) {
+ mCursorAnchorInfoController.focusedNodeChanged(isEditable);
+ }
+
if (mTextInputType != TextInputType.NONE && mInputConnection != null && isEditable) {
restartInput();
}
}
+ public boolean onRequestCursorUpdates(int cursorUpdateMode) {
+ if (mCursorAnchorInfoController == null) return false;
+ return mCursorAnchorInfoController.onRequestCursorUpdates(cursorUpdateMode,
+ mViewEmbedder.getAttachedView());
+ }
+
+ /**
+ * Update the parameters that are to be passed to the IME through
+ * {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)}.
+ * @param text Text in the focused text field.
+ * @param selectionStart Index where the text selection starts. {@code -1} if there is no
+ * selection.
+ * @param selectionEnd Index where the text selection ends. {@code -1} if there is no
+ * selection.
+ * @param compositionStart Index where the text composition starts. {@code -1} if there is no
+ * selection.
+ * @param compositionEnd Index where the text composition ends. {@code -1} if there is no
+ * selection.
+ */
+ public void updateTextAndSelection(String text, int selectionStart, int selectionEnd,
+ int compositionStart, int compositionEnd) {
+ if (mCursorAnchorInfoController == null) return;
+ mCursorAnchorInfoController.updateTextAndSelection(text, compositionStart, compositionEnd,
+ selectionStart, selectionEnd);
+ }
+
+ /**
+ * Notify the location of composing characters to the IME if it explicitly requested them.
+ * @param renderCoordinates coordinate information to convert CSS (document) coordinates to
+ * View-local Physical (screen) coordinates
+ * @param hasInsertionMarker Whether the insertion marker is visible or not.
+ * @param insertionMarkerHorizontal X coordinates (in view-local DIP pixels) of the insertion
+ * marker if it exists. Will be ignored otherwise.
+ * @param insertionMarkerTop Y coordinates (in view-local DIP pixels) of the top of the
+ * insertion marker if it exists. Will be ignored otherwise.
+ * @param insertionMarkerBottom Y coordinates (in view-local DIP pixels) of the bottom of
+ * the insertion marker if it exists. Will be ignored otherwise.
+ */
+ public void onUpdateFrameInfo(RenderCoordinates renderCoordinates, boolean hasInsertionMarker,
+ boolean isInsertionMarkerVisible, float insertionMarkerHorizontal,
+ float insertionMarkerTop, float insertionMarkerBottom) {
+ if (mCursorAnchorInfoController == null) return;
+ mCursorAnchorInfoController.onUpdateFrameInfo(renderCoordinates, hasInsertionMarker,
+ isInsertionMarkerVisible, insertionMarkerHorizontal, insertionMarkerTop,
+ insertionMarkerBottom, mViewEmbedder.getAttachedView());
+ }
+
@CalledByNative
private void populateUnderlinesFromSpans(CharSequence text, long underlines) {
if (DEBUG_LOGS) {
@@ -596,9 +667,19 @@ public class ImeAdapter {
}
@CalledByNative
+ private void setCharacterBounds(float[] characterBounds) {
+ if (mCursorAnchorInfoController == null) return;
+ mCursorAnchorInfoController.setCompositionCharacterBounds(characterBounds);
+ }
+
+ @CalledByNative
private void detach() {
if (DEBUG_LOGS) Log.w(TAG, "detach");
mNativeImeAdapterAndroid = 0;
+ mTextInputType = 0;
+ if (mCursorAnchorInfoController != null) {
+ mCursorAnchorInfoController.focusedNodeChanged(false);
+ }
}
private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndroid,

Powered by Google App Engine
This is Rietveld 408576698