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

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: Addressed comments in #38 Created 4 years, 9 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 a1bf512541883a0f92238bd21d01574a8a03e924..f00e77085e78bef527b756d08495b780ff824b23 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
@@ -5,6 +5,7 @@
package org.chromium.content.browser.input;
import android.content.res.Configuration;
+import android.os.Build;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.text.SpannableString;
@@ -24,6 +25,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;
@@ -94,6 +96,11 @@ public class ImeAdapter {
private ChromiumBaseInputConnection.Factory mInputConnectionFactory;
private final ImeAdapterDelegate mViewEmbedder;
+ // 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;
private int mTextInputType = TextInputType.NONE;
private int mTextInputFlags;
@@ -103,6 +110,9 @@ public class ImeAdapter {
private int mLastSelectionStart;
private int mLastSelectionEnd;
+ private String mLastText;
+ private int mLastCompositionStart;
+ private int mLastCompositionEnd;
/**
* @param wrapper InputMethodManagerWrapper that should receive all the call directed to
@@ -116,6 +126,34 @@ public class ImeAdapter {
// Deep copy newConfig so that we can notice the difference.
mCurrentConfig = new Configuration(
mViewEmbedder.getAttachedView().getResources().getConfiguration());
+ // CursorAnchroInfo is supported only after L.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ mCursorAnchorInfoController = CursorAnchorInfoController.create(wrapper,
+ new CursorAnchorInfoController.ComposingTextDelegate() {
+ @Override
+ public CharSequence getText() {
+ return mLastText;
+ }
+ @Override
+ public int getSelectionStart() {
+ return mLastSelectionStart;
+ }
+ @Override
+ public int getSelectionEnd() {
+ return mLastSelectionEnd;
+ }
+ @Override
+ public int getComposingTextStart() {
+ return mLastCompositionStart;
+ }
+ @Override
+ public int getComposingTextEnd() {
+ return mLastCompositionEnd;
+ }
+ });
+ } else {
+ mCursorAnchorInfoController = null;
+ }
}
private boolean isImeThreadEnabled() {
@@ -155,6 +193,9 @@ public class ImeAdapter {
mViewEmbedder.getAttachedView(), this, mTextInputType, mTextInputFlags,
mLastSelectionStart, mLastSelectionEnd, outAttrs);
if (DEBUG_LOGS) Log.w(TAG, "onCreateInputConnection: " + mInputConnection);
+ if (mCursorAnchorInfoController != null) {
+ mCursorAnchorInfoController.resetMonitoringState();
+ }
return mInputConnection;
}
@@ -166,6 +207,9 @@ public class ImeAdapter {
@VisibleForTesting
public void setInputMethodManagerWrapperForTest(InputMethodManagerWrapper immw) {
mInputMethodManagerWrapper = immw;
+ if (mCursorAnchorInfoController != null) {
+ mCursorAnchorInfoController.setInputMethodManagerWrapperForTest(immw);
+ }
}
@VisibleForTesting
@@ -251,8 +295,18 @@ public class ImeAdapter {
*/
public void updateState(String text, int selectionStart, int selectionEnd, int compositionStart,
int compositionEnd, boolean isNonImeChange) {
+ if (mCursorAnchorInfoController != null && (!TextUtils.equals(mLastText, text)
+ || mLastSelectionStart != selectionStart || mLastSelectionEnd != selectionEnd
+ || mLastCompositionStart != compositionStart
+ || mLastCompositionEnd != compositionEnd)) {
+ mCursorAnchorInfoController.invalidateLastCursorAnchorInfo();
+ }
+ mLastText = text;
mLastSelectionStart = selectionStart;
mLastSelectionEnd = selectionEnd;
+ mLastCompositionStart = compositionStart;
+ mLastCompositionEnd = compositionEnd;
+
if (mInputConnection == null) return;
boolean singleLine = mTextInputType != TextInputType.TEXT_AREA
&& mTextInputType != TextInputType.CONTENT_EDITABLE;
@@ -549,6 +603,12 @@ 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();
}
@@ -564,6 +624,36 @@ public class ImeAdapter {
return nativeRequestTextInputStateUpdate(mNativeImeAdapterAndroid);
}
+ /**
+ * Notified when IME requested Chrome to change the cursor update mode.
+ */
+ public boolean onRequestCursorUpdates(int cursorUpdateMode) {
+ if (mCursorAnchorInfoController == null) return false;
+ return mCursorAnchorInfoController.onRequestCursorUpdates(cursorUpdateMode,
+ mViewEmbedder.getAttachedView());
+ }
+
+ /**
+ * Notified when a frame has been produced by the renderer and all the associated metadata.
+ * @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) {
@@ -593,9 +683,18 @@ 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;
+ if (mCursorAnchorInfoController != null) {
+ mCursorAnchorInfoController.focusedNodeChanged(false);
+ }
}
private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndroid,

Powered by Google App Engine
This is Rietveld 408576698