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
      3d2cc0fffd
 [2]: I3c58fadd924fad72cb984f0c23d3099fd0295c64
      19a80a1e80

Bug: 131368625
Bug: 194110780
Test: atest CtsInputMethodTestCases
Test: atest MultiDisplaySystemDecorationTests#testCrossDisplayBasicImeOperations
Change-Id: Iec12733d37e112b7271436bba15094ae2a55a450
This commit is contained in:
Yohei Yukawa
2021-09-10 11:37:40 -07:00
parent 95d4f0dc17
commit 6d2e9786b4
5 changed files with 20 additions and 11 deletions

View File

@@ -393,7 +393,15 @@ final class RemoteInputConnection implements InputConnection {
// This method is not implemented.
return false;
}
final CompletableFuture<Boolean> value = mInvoker.requestCursorUpdates(cursorUpdateMode);
final InputMethodServiceInternal ims = mImsInternal.getAndWarnIfNull();
if (ims == null) {
return false;
}
final int displayId = ims.getContext().getDisplayId();
final CompletableFuture<Boolean> value =
mInvoker.requestCursorUpdates(cursorUpdateMode, displayId);
return CompletableFutureUtil.getResultOrFalse(value, TAG, "requestCursorUpdates()",
mCancellationGroup, MAX_WAIT_TIME_MILLIS);
}

View File

@@ -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<Boolean>} that can be used to retrieve the invocation
* result. {@link RemoteException} will be treated as an error.
*/
@AnyThread
@NonNull
public AndroidFuture<Boolean> requestCursorUpdates(int cursorUpdateMode) {
public AndroidFuture<Boolean> requestCursorUpdates(int cursorUpdateMode, int imeDisplayId) {
final AndroidFuture<Boolean> future = new AndroidFuture<>();
try {
mIInputContext.requestCursorUpdates(cursorUpdateMode, future);
mIInputContext.requestCursorUpdates(cursorUpdateMode, imeDisplayId, future);
} catch (RemoteException e) {
future.completeExceptionally(e);
}

View File

@@ -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);
});
}

View File

@@ -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 */);

View File

@@ -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;