From 71aa1a31d1bcb5780829cf963740a8e905175e0d Mon Sep 17 00:00:00 2001 From: Taran Singh Date: Wed, 19 Jan 2022 23:05:25 +0000 Subject: [PATCH] Scribe in IMF: Automatically sub to CAI w/ Stylus 4/N When Stylus handwriting mode is about to be used, automatically subscribe IME to CursorAnchroInfo updates. This helps speed-up stylus tasks in IME Bug: 203086136 Bug: 210039666 Bug: 215533103 Test: atest CtsInputMethodTestCases Change-Id: I3d6b1728d62139785593af14c24cb52bf2c91e31 --- .../view/inputmethod/InputMethodManager.java | 18 +++++-- .../RemoteInputConnectionImpl.java | 52 +++++++++++++------ 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 6a22023dc9da5..849f3c95d1917 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -18,6 +18,8 @@ package android.view.inputmethod; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.WRITE_SECURE_SETTINGS; +import static android.view.inputmethod.InputConnection.CURSOR_UPDATE_IMMEDIATE; +import static android.view.inputmethod.InputConnection.CURSOR_UPDATE_MONITOR; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.DISPLAY_ID; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.EDITOR_INFO; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_INSETS_SOURCE_CONSUMER; @@ -1793,6 +1795,14 @@ public final class InputMethodManager { Log.w(TAG, "Ignoring startStylusHandwriting: View's window does not have focus."); return; } + if (mServedInputConnection != null && getDelegate().hasActiveConnection(view)) { + // TODO (b/210039666): optimize CURSOR_UPDATE_IMMEDIATE. + // TODO (b/215533103): Introduce new modes in requestCursorUpdates(). + // TODO (b/210039666): Pipe IME displayId from InputBindResult and use it here. + // instead of mDisplayId. + mServedInputConnection.requestCursorUpdatesFromImm( + CURSOR_UPDATE_IMMEDIATE | CURSOR_UPDATE_MONITOR, mDisplayId); + } try { mService.startStylusHandwriting(mClient); @@ -2419,9 +2429,9 @@ public final class InputMethodManager { public boolean isCursorAnchorInfoEnabled() { synchronized (mH) { final boolean isImmediate = (mRequestUpdateCursorAnchorInfoMonitorMode & - InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0; + CURSOR_UPDATE_IMMEDIATE) != 0; final boolean isMonitoring = (mRequestUpdateCursorAnchorInfoMonitorMode & - InputConnection.CURSOR_UPDATE_MONITOR) != 0; + CURSOR_UPDATE_MONITOR) != 0; return isImmediate || isMonitoring; } } @@ -2493,7 +2503,7 @@ public final class InputMethodManager { // If immediate bit is set, we will call updateCursorAnchorInfo() even when the data has // not been changed from the previous call. final boolean isImmediate = (mRequestUpdateCursorAnchorInfoMonitorMode & - InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0; + CURSOR_UPDATE_IMMEDIATE) != 0; if (!isImmediate && Objects.equals(mCursorAnchorInfo, cursorAnchorInfo)) { // TODO: Consider always emitting this message once we have addressed redundant // calls of this method from android.widget.Editor. @@ -2507,7 +2517,7 @@ public final class InputMethodManager { mCurrentInputMethodSession.updateCursorAnchorInfo(cursorAnchorInfo); mCursorAnchorInfo = cursorAnchorInfo; // Clear immediate bit (if any). - mRequestUpdateCursorAnchorInfoMonitorMode &= ~InputConnection.CURSOR_UPDATE_IMMEDIATE; + mRequestUpdateCursorAnchorInfoMonitorMode &= ~CURSOR_UPDATE_IMMEDIATE; } } diff --git a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java index 0470444a16e8a..d1942ac26aff3 100644 --- a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java +++ b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java @@ -932,6 +932,24 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub { }); } + /** + * Dispatches {@link InputConnection#requestCursorUpdates(int)}. + * + *

This method is intended to be called only from {@link InputMethodManager}.

+ * @param cursorUpdateMode the mode for {@link InputConnection#requestCursorUpdates(int)} + * @param imeDisplayId displayId on which IME is displayed. + */ + @Dispatching(cancellable = true) + public void requestCursorUpdatesFromImm(int cursorUpdateMode, int imeDisplayId) { + final int currentSessionId = mCurrentSessionId.get(); + dispatchWithTracing("requestCursorUpdatesFromImm", () -> { + if (currentSessionId != mCurrentSessionId.get()) { + return; // cancelled + } + requestCursorUpdatesInternal(cursorUpdateMode, imeDisplayId); + }); + } + @Dispatching(cancellable = true) @Override public void requestCursorUpdates(InputConnectionCommandHeader header, int cursorUpdateMode, @@ -940,24 +958,28 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub { if (header.mSessionId != mCurrentSessionId.get()) { return false; // cancelled } - final InputConnection ic = getInputConnection(); - if (ic == null || !isActive()) { - Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection"); - return false; - } - if (mParentInputMethodManager.getDisplayId() != imeDisplayId) { - // requestCursorUpdates() is not currently supported across displays. - return false; - } - try { - return ic.requestCursorUpdates(cursorUpdateMode); - } catch (AbstractMethodError ignored) { - // TODO(b/199934664): See if we can remove this by providing a default impl. - return false; - } + return requestCursorUpdatesInternal(cursorUpdateMode, imeDisplayId); }); } + private boolean requestCursorUpdatesInternal(int cursorUpdateMode, int imeDisplayId) { + final InputConnection ic = getInputConnection(); + if (ic == null || !isActive()) { + Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection"); + return false; + } + if (mParentInputMethodManager.getDisplayId() != imeDisplayId) { + // requestCursorUpdates() is not currently supported across displays. + return false; + } + try { + return ic.requestCursorUpdates(cursorUpdateMode); + } catch (AbstractMethodError ignored) { + // TODO(b/199934664): See if we can remove this by providing a default impl. + return false; + } + } + @Dispatching(cancellable = true) @Override public void commitContent(InputConnectionCommandHeader header,