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

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

Issue 699333003: Support InputMethodManager#updateCursorAnchorInfo for Android 5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed "just-in-case" checks for the simplicity Created 6 years, 1 month 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 e075d8e4d400dbef2f502c3f262b3455eed249a6..4d8c29efedf345c6bcb566e4e03bac29a54ba49a 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
@@ -4,6 +4,8 @@
package org.chromium.content.browser.input;
+import android.graphics.Matrix;
+import android.os.Build;
import android.os.Handler;
import android.os.ResultReceiver;
import android.os.SystemClock;
@@ -15,7 +17,10 @@ import android.text.style.UnderlineSpan;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
+import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
@@ -143,6 +148,53 @@ public class ImeAdapter {
private int mTextInputFlags;
private String mLastComposeText;
+ private static class CursorAnchorInfoSource {
+ private String mText;
+ private int mSelectionStart;
+ private int mSelectionEnd;
+ private int mCompositionStart;
+ private int mCompositionEnd;
+ private float[] mLastCharacterBounds;
+ }
+ private CursorAnchorInfoSource mCursorAnchorInfoSource = new CursorAnchorInfoSource();
+
+ private static class CursorAnchorInfoBuilderWrapper {
+
+ public static boolean isSupported() {
+ return false;
+ }
+
+ public static CursorAnchorInfoBuilderWrapper create() {
+ return new CursorAnchorInfoBuilderWrapper();
+ }
+
+ protected CursorAnchorInfoBuilderWrapper() {
+ }
+
+ public void update(CursorAnchorInfoSource source, Matrix matrix, boolean hasInertionMarker,
+ float insertionMarkerX, float insertionMarkerTop, float insertionMarkerBottom) {
+ // This is a stub for platforms that do not support CursorAnchorInfo.
+ }
+
+ public boolean hasData() {
+ // This is a stub for platforms that do not support CursorAnchorInfo.
+ return false;
+ }
+
+ public void reset() {
+ // This is a stub for platforms that do not support CursorAnchorInfo.
+ }
+
+ public void send(InputMethodManagerWrapper inputMethodManagerWrapper, View view) {
+ // This is a stub for platforms that do not support CursorAnchorInfo.
+ }
+ }
+
+ private CursorAnchorInfoBuilderWrapper mCursorAnchorInfoBuilder =
+ CursorAnchorInfoBuilderWrapper.create();
+ private boolean mCursorAnchorInfoMonitorEnabled = false;
+ private boolean mOneshotUpdateCursorAnchorInfoEnabled = false;
+
@VisibleForTesting
int mLastSyntheticKeyCode;
@@ -621,6 +673,82 @@ public class ImeAdapter {
return true;
}
+ /**
+ * @return Whether the {@link CursorAnchorInfo} is available or not on this device.
+ */
+ public boolean isCursorAnchorInfoSupported() {
+ return CursorAnchorInfoBuilderWrapper.isSupported();
+ }
+
+ /**
+ * Start or stop calling
+ * {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)}.
+ * @param enabled {@code true} if {@link InputConnection#requestCursorUpdates(int)} is called
+ * with {@link InputConnection#CURSOR_UPDATE_MONITOR} bit.
+ */
+ public void setCursorAnchorInfoMonitorEnabled(boolean enabled) {
+ mCursorAnchorInfoMonitorEnabled = enabled;
+ }
+
+ /**
+ * Make sure {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)} is called
+ * at least once immediately when the latest position becomes available.
+ * @param view The view to be passed to
+ * {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)} if the latest
+ * position is already available. Otherwise ignored.
+ */
+ public void scheduleOneshotUpdateCursorAnchorInfo(View view) {
+ if (!mCursorAnchorInfoBuilder.hasData()) {
+ // If there is no data, send the data later when it becomes available.
+ mOneshotUpdateCursorAnchorInfoEnabled = true;
+ return;
+ }
+ mCursorAnchorInfoBuilder.send(mInputMethodManagerWrapper, view);
+ mOneshotUpdateCursorAnchorInfoEnabled = false;
+ }
+
+ /**
+ * Update the parameters that are to be passed to the IME through
+ * {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)}.
+ * @param text The 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 updateCursorAnchorInfoSource(String text, int selectionStart, int selectionEnd,
+ int compositionStart, int compositionEnd) {
+ mCursorAnchorInfoSource.mText = text;
+ mCursorAnchorInfoSource.mSelectionStart = selectionStart;
+ mCursorAnchorInfoSource.mSelectionEnd = selectionEnd;
+ mCursorAnchorInfoSource.mCompositionStart = compositionStart;
+ mCursorAnchorInfoSource.mCompositionEnd = compositionEnd;
+ }
+
+ /**
+ * Call {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)} if it is
+ * available and the active IME is actually requested it.
+ * @param view The view to be passed to
+ * {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)}
+ * @param matrix The matrix from CSS coordinates to the absolute display coordinates.
+ * @param hasInsertionMaerker Whether the insertion marker exists or not.
+ * @param insertionMarkerX The X position of the insertion marker, in CSS coordinates.
+ * @param insertionMarkerTop The top position of the insertion marker, in CSS coordinates.
+ * @param insertionMarkerBottom The bottom position of the insertion marker, in CSS coordinates.
+ */
+ public void updateCursorAnchorInfo(View view, Matrix matrix, boolean hasInsertionMaerker,
+ float insertionMarkerX, float insertionMarkerTop, float insertionMarkerBottom) {
+ mCursorAnchorInfoBuilder.update(mCursorAnchorInfoSource, matrix, hasInsertionMaerker,
+ insertionMarkerX, insertionMarkerTop, insertionMarkerBottom);
+ if (!mCursorAnchorInfoMonitorEnabled && !mOneshotUpdateCursorAnchorInfoEnabled) return;
+ mCursorAnchorInfoBuilder.send(mInputMethodManagerWrapper, view);
+ mOneshotUpdateCursorAnchorInfoEnabled = false;
+ }
+
// Calls from C++ to Java
@CalledByNative
@@ -699,7 +827,7 @@ public class ImeAdapter {
@CalledByNative
private void setCharacterBounds(float[] characterBounds) {
- // TODO(yukawa): Implement this.
+ mCursorAnchorInfoSource.mLastCharacterBounds = characterBounds;
}
@CalledByNative
@@ -710,6 +838,7 @@ public class ImeAdapter {
}
mNativeImeAdapterAndroid = 0;
mTextInputType = 0;
+ mCursorAnchorInfoBuilder.reset();
}
private native boolean nativeSendSyntheticKeyEvent(long nativeImeAdapterAndroid,

Powered by Google App Engine
This is Rietveld 408576698