From 6d2e9786b47650b1e74729f5609ebe0982c2f86c Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Fri, 10 Sep 2021 11:37:40 -0700 Subject: [PATCH] Stop lying about MissingMethodFlags.REQUEST_CURSOR_UPDATES This is a follow up CL to my previous CL [1], which used MissingMethodFlags mechanism [2] to let that API fail when the IME and the target app are not running on the same display. As discussed in Bug 194110780, however, there is a problem in the MissingMethodFlags mechanism that it could have caused unexpected task reordarings from the IME developer when sync InputConnection APIs immediatelly fail without waiting for those tasks to be scheduled to the target app then handled. As a preparation to fully deprecate MissingMethodFlags, this CL enables InputMethodManagerService to stop lying about MissingMethodFlags.REQUEST_CURSOR_UPDATES when the IME is rendered on a diffirent display than the target app. Such check is now explicitly implemented in RemoteInputConnectionImpl. Other than that, there is no observable behavior change. [1]: Ie2f7a5117cff3a13ad5c5806fd4b3abef7569549 3d2cc0fffd13f46923d0fcfdd73d375ebbe955ce [2]: I3c58fadd924fad72cb984f0c23d3099fd0295c64 19a80a1e807acd00bec999eaac7812da6ffce954 Bug: 131368625 Bug: 194110780 Test: atest CtsInputMethodTestCases Test: atest MultiDisplaySystemDecorationTests#testCrossDisplayBasicImeOperations Change-Id: Iec12733d37e112b7271436bba15094ae2a55a450 --- .../inputmethodservice/RemoteInputConnection.java | 10 +++++++++- .../internal/inputmethod/IInputContextInvoker.java | 5 +++-- .../inputmethod/RemoteInputConnectionImpl.java | 7 ++++++- core/java/com/android/internal/view/IInputContext.aidl | 3 ++- .../server/inputmethod/InputMethodManagerService.java | 6 ------ 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/core/java/android/inputmethodservice/RemoteInputConnection.java b/core/java/android/inputmethodservice/RemoteInputConnection.java index 1065d041713f0..589dd7255a62d 100644 --- a/core/java/android/inputmethodservice/RemoteInputConnection.java +++ b/core/java/android/inputmethodservice/RemoteInputConnection.java @@ -393,7 +393,15 @@ final class RemoteInputConnection implements InputConnection { // This method is not implemented. return false; } - final CompletableFuture value = mInvoker.requestCursorUpdates(cursorUpdateMode); + + final InputMethodServiceInternal ims = mImsInternal.getAndWarnIfNull(); + if (ims == null) { + return false; + } + + final int displayId = ims.getContext().getDisplayId(); + final CompletableFuture value = + mInvoker.requestCursorUpdates(cursorUpdateMode, displayId); return CompletableFutureUtil.getResultOrFalse(value, TAG, "requestCursorUpdates()", mCancellationGroup, MAX_WAIT_TIME_MILLIS); } diff --git a/core/java/com/android/internal/inputmethod/IInputContextInvoker.java b/core/java/com/android/internal/inputmethod/IInputContextInvoker.java index 0cbdc132e66fb..2fde98177fa7c 100644 --- a/core/java/com/android/internal/inputmethod/IInputContextInvoker.java +++ b/core/java/com/android/internal/inputmethod/IInputContextInvoker.java @@ -477,15 +477,16 @@ public final class IInputContextInvoker { * Invokes {@link IInputContext#requestCursorUpdates(int, IIntResultCallback)}. * * @param cursorUpdateMode {@code cursorUpdateMode} parameter to be passed. + * @param imeDisplayId the display ID that is associated with the IME. * @return {@link AndroidFuture} that can be used to retrieve the invocation * result. {@link RemoteException} will be treated as an error. */ @AnyThread @NonNull - public AndroidFuture requestCursorUpdates(int cursorUpdateMode) { + public AndroidFuture requestCursorUpdates(int cursorUpdateMode, int imeDisplayId) { final AndroidFuture future = new AndroidFuture<>(); try { - mIInputContext.requestCursorUpdates(cursorUpdateMode, future); + mIInputContext.requestCursorUpdates(cursorUpdateMode, imeDisplayId, future); } catch (RemoteException e) { future.completeExceptionally(e); } diff --git a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java index 662bd288df950..c2e56365c9b69 100644 --- a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java +++ b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java @@ -567,13 +567,18 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub { } @Override - public void requestCursorUpdates(int cursorUpdateMode, AndroidFuture future /* T=Boolean */) { + public void requestCursorUpdates(int cursorUpdateMode, int imeDisplayId, + AndroidFuture future /* T=Boolean */) { dispatchWithTracing("requestCursorUpdates", future, () -> { 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; + } return ic.requestCursorUpdates(cursorUpdateMode); }); } diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl index 12a98c17b3f01..2e6f9e537b002 100644 --- a/core/java/com/android/internal/view/IInputContext.aidl +++ b/core/java/com/android/internal/view/IInputContext.aidl @@ -75,7 +75,8 @@ import com.android.internal.infra.AndroidFuture; void getSelectedText(int flags, in AndroidFuture future /* T=CharSequence */); - void requestCursorUpdates(int cursorUpdateMode, in AndroidFuture future /* T=Boolean */); + void requestCursorUpdates(int cursorUpdateMode, int imeDisplayId, + in AndroidFuture future /* T=Boolean */); void commitContent(in InputContentInfo inputContentInfo, int flags, in Bundle opts, in AndroidFuture future /* T=Boolean */); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 2813236fd91d0..28261e826efd9 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -2384,12 +2384,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (mCurSeq <= 0) mCurSeq = 1; mCurClient = cs; mCurInputContext = inputContext; - if (cs.selfReportedDisplayId != displayIdToShowIme) { - // CursorAnchorInfo API does not work as-is for cross-display scenario. Pretend that - // InputConnection#requestCursorUpdates() is not implemented in the application so that - // IMEs will always receive false from this API. - missingMethods |= MissingMethodFlags.REQUEST_CURSOR_UPDATES; - } mCurInputContextMissingMethods = missingMethods; mCurAttribute = attribute;