Loading java-overridable/src/com/android/inputmethod/latin/define/ProductionFlags.java +4 −13 Original line number Diff line number Diff line Loading @@ -25,21 +25,12 @@ public final class ProductionFlags { /** * When true, enable {@link InputMethodService#onUpdateCursorAnchorInfo} callback via * {@link InputConnection#requestCursorAnchorInfo}. This flag has no effect in API Level 20 * and prior. In general, this callback provides more detailed positional information, * {@link InputConnection#requestUpdateCursorAnchorInfo}. This flag has no effect in API * Level 20 and prior. In general, this callback provides detailed positional information, * even though an explicit support is required by the editor. */ public static final boolean ENABLE_CURSOR_ANCHOR_INFO_CALLBACK = true; /** * When true, enable {@link InputMethodService#onUpdateCursor} callback via * {@link InputConnection#requestCursorAnchorInfo}. Although this callback has been available * since API Level 3, the callback has never been used until API Level 20. Thus it may or may * not work well as expected. Should rely on {@link InputMethodService#onUpdateCursorAnchorInfo} * whenever possible since it is supposed to be more reliable and accurate. */ public static final boolean ENABLE_CURSOR_RECT_CALLBACK = false; /** * Include all suggestions from all dictionaries in {@link SuggestedWords#mRawSuggestions}. */ Loading java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java +19 −87 Original line number Diff line number Diff line Loading @@ -16,67 +16,35 @@ package com.android.inputmethod.compat; import android.util.Log; import android.view.inputmethod.InputConnection; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import android.view.inputmethod.InputMethodManager; public final class InputConnectionCompatUtils { private static final String TAG = InputConnectionCompatUtils.class.getSimpleName(); // Note that CursorAnchorInfoRequest is supposed to be available in API level 21 and later. private static Class<?> getCursorAnchorInfoRequestClass() { try { return Class.forName("android.view.inputmethod.CursorAnchorInfoRequest"); } catch (ClassNotFoundException e) { return null; } } private static final Class<?> TYPE_CursorAnchorInfoRequest; private static final Constructor<?> CONSTRUCTOR_CursorAnchorInfoRequest; private static final Method METHOD_requestCursorAnchorInfo; private static final CompatUtils.ClassWrapper sInputConnectionType; private static final CompatUtils.ToBooleanMethodWrapper sRequestUpdateCursorAnchorInfoMethod; static { TYPE_CursorAnchorInfoRequest = getCursorAnchorInfoRequestClass(); CONSTRUCTOR_CursorAnchorInfoRequest = CompatUtils.getConstructor( TYPE_CursorAnchorInfoRequest, int.class, int.class); METHOD_requestCursorAnchorInfo = CompatUtils.getMethod(InputConnection.class, "requestCursorAnchorInfo", TYPE_CursorAnchorInfoRequest); sInputConnectionType = new CompatUtils.ClassWrapper(InputConnection.class); sRequestUpdateCursorAnchorInfoMethod = sInputConnectionType.getPrimitiveMethod( "requestUpdateCursorAnchorInfo", false, int.class); } public static boolean isRequestCursorAnchorInfoAvailable() { return METHOD_requestCursorAnchorInfo != null && CONSTRUCTOR_CursorAnchorInfoRequest != null; public static boolean isRequestUpdateCursorAnchorInfoAvailable() { return sRequestUpdateCursorAnchorInfoMethod != null; } /** * Local copies of some constants in CursorAnchorInfoRequest until the SDK becomes publicly * available. */ private final static int RESULT_NOT_HANDLED = 0; private final static int RESULT_SCHEDULED = 1; private final static int TYPE_CURSOR_ANCHOR_INFO = 1; private final static int FLAG_CURSOR_ANCHOR_INFO_MONITOR = 1; private final static int FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE = 2; private final static int TYPE_CURSOR_RECT = 2; private final static int FLAG_CURSOR_RECT_MONITOR = 1; private final static int FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES = 2; private final static int FLAG_CURSOR_RECT_WITH_VIEW_MATRIX = 4; private static int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1 << 0; private static int REQUEST_UPDATE_CURSOR_UPDATE_MONITOR = 1 << 1; private static int requestCursorAnchorInfoImpl(final InputConnection inputConnection, final int type, final int flags) { if (!isRequestCursorAnchorInfoAvailable()) { return RESULT_NOT_HANDLED; } final Object requestObject = CompatUtils.newInstance( CONSTRUCTOR_CursorAnchorInfoRequest, type, flags); if (requestObject == null) { return RESULT_NOT_HANDLED; private static boolean requestUpdateCursorAnchorInfoImpl(final InputConnection inputConnection, final int cursorUpdateMode) { if (!isRequestUpdateCursorAnchorInfoAvailable()) { return false; } return (Integer) CompatUtils.invoke(inputConnection, RESULT_NOT_HANDLED /* defaultValue */, METHOD_requestCursorAnchorInfo, requestObject); return sRequestUpdateCursorAnchorInfoMethod.invoke(inputConnection, cursorUpdateMode); } /** Loading @@ -88,47 +56,11 @@ public final class InputConnectionCompatUtils { * as soon as possible to notify the current cursor/anchor position to the input method. * @return {@code false} if the request is not handled. Otherwise returns {@code true}. */ public static boolean requestCursorAnchorInfo(final InputConnection inputConnection, public static boolean requestUpdateCursorAnchorInfo(final InputConnection inputConnection, final boolean enableMonitor, final boolean requestImmediateCallback) { final int requestFlags = (enableMonitor ? FLAG_CURSOR_ANCHOR_INFO_MONITOR : 0) | (requestImmediateCallback ? FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE : 0); final int requestResult = requestCursorAnchorInfoImpl(inputConnection, TYPE_CURSOR_ANCHOR_INFO, requestFlags); switch (requestResult) { case RESULT_NOT_HANDLED: return false; case RESULT_SCHEDULED: return true; default: Log.w(TAG, "requestCursorAnchorInfo returned unknown result=" + requestResult + " for type=TYPE_CURSOR_ANCHOR_INFO flags=" + requestFlags); return true; } final int cursorUpdateMode = (enableMonitor ? REQUEST_UPDATE_CURSOR_UPDATE_MONITOR : 0) | (requestImmediateCallback ? REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE : 0); return requestUpdateCursorAnchorInfoImpl(inputConnection, cursorUpdateMode); } /** * Requests the editor to call back {@link InputMethodManager#updateCursor}. * @param inputConnection the input connection to which the request is to be sent. * @param enableMonitor {@code true} to request the editor to call back the method whenever the * cursor position is changed. * @return {@code false} if the request is not handled. Otherwise returns {@code true}. */ public static boolean requestCursorRect(final InputConnection inputConnection, final boolean enableMonitor) { final int requestFlags = enableMonitor ? FLAG_CURSOR_RECT_MONITOR | FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES | FLAG_CURSOR_RECT_WITH_VIEW_MATRIX : 0; final int requestResult = requestCursorAnchorInfoImpl(inputConnection, TYPE_CURSOR_RECT, requestFlags); switch (requestResult) { case RESULT_NOT_HANDLED: return false; case RESULT_SCHEDULED: return true; default: Log.w(TAG, "requestCursorAnchorInfo returned unknown result=" + requestResult + " for type=TYPE_CURSOR_RECT flags=" + requestFlags); return true; } } } java/src/com/android/inputmethod/latin/LatinIME.java +1 −13 Original line number Diff line number Diff line Loading @@ -755,14 +755,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInput(editorInfo, restarting); if (ProductionFlags.ENABLE_CURSOR_RECT_CALLBACK) { InputConnectionCompatUtils.requestCursorRect(getCurrentInputConnection(), true /* enableMonitor */); } if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) { // AcceptTypedWord feature relies on CursorAnchorInfo. if (mSettings.getCurrent().mShouldShowUiToAcceptTypedWord) { InputConnectionCompatUtils.requestCursorAnchorInfo( InputConnectionCompatUtils.requestUpdateCursorAnchorInfo( getCurrentInputConnection(), true /* enableMonitor */, true /* requestImmediateCallback */); } Loading Loading @@ -971,14 +967,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } @Override public void onUpdateCursor(final Rect rect) { if (DEBUG) { Log.i(TAG, "onUpdateCursor:" + rect.toShortString()); } super.onUpdateCursor(rect); } // We cannot mark this method as @Override until new SDK becomes publicly available. // @Override public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) { Loading Loading
java-overridable/src/com/android/inputmethod/latin/define/ProductionFlags.java +4 −13 Original line number Diff line number Diff line Loading @@ -25,21 +25,12 @@ public final class ProductionFlags { /** * When true, enable {@link InputMethodService#onUpdateCursorAnchorInfo} callback via * {@link InputConnection#requestCursorAnchorInfo}. This flag has no effect in API Level 20 * and prior. In general, this callback provides more detailed positional information, * {@link InputConnection#requestUpdateCursorAnchorInfo}. This flag has no effect in API * Level 20 and prior. In general, this callback provides detailed positional information, * even though an explicit support is required by the editor. */ public static final boolean ENABLE_CURSOR_ANCHOR_INFO_CALLBACK = true; /** * When true, enable {@link InputMethodService#onUpdateCursor} callback via * {@link InputConnection#requestCursorAnchorInfo}. Although this callback has been available * since API Level 3, the callback has never been used until API Level 20. Thus it may or may * not work well as expected. Should rely on {@link InputMethodService#onUpdateCursorAnchorInfo} * whenever possible since it is supposed to be more reliable and accurate. */ public static final boolean ENABLE_CURSOR_RECT_CALLBACK = false; /** * Include all suggestions from all dictionaries in {@link SuggestedWords#mRawSuggestions}. */ Loading
java/src/com/android/inputmethod/compat/InputConnectionCompatUtils.java +19 −87 Original line number Diff line number Diff line Loading @@ -16,67 +16,35 @@ package com.android.inputmethod.compat; import android.util.Log; import android.view.inputmethod.InputConnection; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import android.view.inputmethod.InputMethodManager; public final class InputConnectionCompatUtils { private static final String TAG = InputConnectionCompatUtils.class.getSimpleName(); // Note that CursorAnchorInfoRequest is supposed to be available in API level 21 and later. private static Class<?> getCursorAnchorInfoRequestClass() { try { return Class.forName("android.view.inputmethod.CursorAnchorInfoRequest"); } catch (ClassNotFoundException e) { return null; } } private static final Class<?> TYPE_CursorAnchorInfoRequest; private static final Constructor<?> CONSTRUCTOR_CursorAnchorInfoRequest; private static final Method METHOD_requestCursorAnchorInfo; private static final CompatUtils.ClassWrapper sInputConnectionType; private static final CompatUtils.ToBooleanMethodWrapper sRequestUpdateCursorAnchorInfoMethod; static { TYPE_CursorAnchorInfoRequest = getCursorAnchorInfoRequestClass(); CONSTRUCTOR_CursorAnchorInfoRequest = CompatUtils.getConstructor( TYPE_CursorAnchorInfoRequest, int.class, int.class); METHOD_requestCursorAnchorInfo = CompatUtils.getMethod(InputConnection.class, "requestCursorAnchorInfo", TYPE_CursorAnchorInfoRequest); sInputConnectionType = new CompatUtils.ClassWrapper(InputConnection.class); sRequestUpdateCursorAnchorInfoMethod = sInputConnectionType.getPrimitiveMethod( "requestUpdateCursorAnchorInfo", false, int.class); } public static boolean isRequestCursorAnchorInfoAvailable() { return METHOD_requestCursorAnchorInfo != null && CONSTRUCTOR_CursorAnchorInfoRequest != null; public static boolean isRequestUpdateCursorAnchorInfoAvailable() { return sRequestUpdateCursorAnchorInfoMethod != null; } /** * Local copies of some constants in CursorAnchorInfoRequest until the SDK becomes publicly * available. */ private final static int RESULT_NOT_HANDLED = 0; private final static int RESULT_SCHEDULED = 1; private final static int TYPE_CURSOR_ANCHOR_INFO = 1; private final static int FLAG_CURSOR_ANCHOR_INFO_MONITOR = 1; private final static int FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE = 2; private final static int TYPE_CURSOR_RECT = 2; private final static int FLAG_CURSOR_RECT_MONITOR = 1; private final static int FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES = 2; private final static int FLAG_CURSOR_RECT_WITH_VIEW_MATRIX = 4; private static int REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE = 1 << 0; private static int REQUEST_UPDATE_CURSOR_UPDATE_MONITOR = 1 << 1; private static int requestCursorAnchorInfoImpl(final InputConnection inputConnection, final int type, final int flags) { if (!isRequestCursorAnchorInfoAvailable()) { return RESULT_NOT_HANDLED; } final Object requestObject = CompatUtils.newInstance( CONSTRUCTOR_CursorAnchorInfoRequest, type, flags); if (requestObject == null) { return RESULT_NOT_HANDLED; private static boolean requestUpdateCursorAnchorInfoImpl(final InputConnection inputConnection, final int cursorUpdateMode) { if (!isRequestUpdateCursorAnchorInfoAvailable()) { return false; } return (Integer) CompatUtils.invoke(inputConnection, RESULT_NOT_HANDLED /* defaultValue */, METHOD_requestCursorAnchorInfo, requestObject); return sRequestUpdateCursorAnchorInfoMethod.invoke(inputConnection, cursorUpdateMode); } /** Loading @@ -88,47 +56,11 @@ public final class InputConnectionCompatUtils { * as soon as possible to notify the current cursor/anchor position to the input method. * @return {@code false} if the request is not handled. Otherwise returns {@code true}. */ public static boolean requestCursorAnchorInfo(final InputConnection inputConnection, public static boolean requestUpdateCursorAnchorInfo(final InputConnection inputConnection, final boolean enableMonitor, final boolean requestImmediateCallback) { final int requestFlags = (enableMonitor ? FLAG_CURSOR_ANCHOR_INFO_MONITOR : 0) | (requestImmediateCallback ? FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE : 0); final int requestResult = requestCursorAnchorInfoImpl(inputConnection, TYPE_CURSOR_ANCHOR_INFO, requestFlags); switch (requestResult) { case RESULT_NOT_HANDLED: return false; case RESULT_SCHEDULED: return true; default: Log.w(TAG, "requestCursorAnchorInfo returned unknown result=" + requestResult + " for type=TYPE_CURSOR_ANCHOR_INFO flags=" + requestFlags); return true; } final int cursorUpdateMode = (enableMonitor ? REQUEST_UPDATE_CURSOR_UPDATE_MONITOR : 0) | (requestImmediateCallback ? REQUEST_UPDATE_CURSOR_UPDATE_IMMEDIATE : 0); return requestUpdateCursorAnchorInfoImpl(inputConnection, cursorUpdateMode); } /** * Requests the editor to call back {@link InputMethodManager#updateCursor}. * @param inputConnection the input connection to which the request is to be sent. * @param enableMonitor {@code true} to request the editor to call back the method whenever the * cursor position is changed. * @return {@code false} if the request is not handled. Otherwise returns {@code true}. */ public static boolean requestCursorRect(final InputConnection inputConnection, final boolean enableMonitor) { final int requestFlags = enableMonitor ? FLAG_CURSOR_RECT_MONITOR | FLAG_CURSOR_RECT_IN_SCREEN_COORDINATES | FLAG_CURSOR_RECT_WITH_VIEW_MATRIX : 0; final int requestResult = requestCursorAnchorInfoImpl(inputConnection, TYPE_CURSOR_RECT, requestFlags); switch (requestResult) { case RESULT_NOT_HANDLED: return false; case RESULT_SCHEDULED: return true; default: Log.w(TAG, "requestCursorAnchorInfo returned unknown result=" + requestResult + " for type=TYPE_CURSOR_RECT flags=" + requestFlags); return true; } } }
java/src/com/android/inputmethod/latin/LatinIME.java +1 −13 Original line number Diff line number Diff line Loading @@ -755,14 +755,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInput(editorInfo, restarting); if (ProductionFlags.ENABLE_CURSOR_RECT_CALLBACK) { InputConnectionCompatUtils.requestCursorRect(getCurrentInputConnection(), true /* enableMonitor */); } if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) { // AcceptTypedWord feature relies on CursorAnchorInfo. if (mSettings.getCurrent().mShouldShowUiToAcceptTypedWord) { InputConnectionCompatUtils.requestCursorAnchorInfo( InputConnectionCompatUtils.requestUpdateCursorAnchorInfo( getCurrentInputConnection(), true /* enableMonitor */, true /* requestImmediateCallback */); } Loading Loading @@ -971,14 +967,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } @Override public void onUpdateCursor(final Rect rect) { if (DEBUG) { Log.i(TAG, "onUpdateCursor:" + rect.toShortString()); } super.onUpdateCursor(rect); } // We cannot mark this method as @Override until new SDK becomes publicly available. // @Override public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) { Loading