From e81ef8b88855c7103782977a3e20c45d37cbe2e0 Mon Sep 17 00:00:00 2001 From: Nikolas Havrikov Date: Tue, 5 Apr 2022 18:37:56 +0200 Subject: [PATCH] Bind IME and retry creating inline suggestions This CL adds a field in the IMMS to store an autofill suggestions request in case the IME is not bound when it comes in. The stored request is fulfilled once the IME rebinds. Bug: 226240255 Test: atest DatasetFilteringInlineTest Change-Id: I2b31d9593b79a8475e17faf189ee94fcd36d55bb --- .../InputMethodBindingController.java | 1 + .../InputMethodManagerService.java | 74 +++++++++++++++++-- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java index 0de523c5f3f62..c4ff4ac6c981c 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java @@ -313,6 +313,7 @@ final class InputMethodBindingController { mSupportsStylusHw); mService.scheduleNotifyImeUidToAudioService(mCurMethodUid); mService.reRequestCurrentClientSessionLocked(); + mService.performOnCreateInlineSuggestionsRequestLocked(); } // reset Handwriting event receiver. diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 3c3140551bc31..bcebcb4c74d4d 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -286,6 +286,30 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @NonNull private final Set mNonPreemptibleInputMethods; + private static final class CreateInlineSuggestionsRequest { + @NonNull final InlineSuggestionsRequestInfo mRequestInfo; + @NonNull final IInlineSuggestionsRequestCallback mCallback; + @NonNull final String mPackageName; + + CreateInlineSuggestionsRequest( + @NonNull InlineSuggestionsRequestInfo requestInfo, + @NonNull IInlineSuggestionsRequestCallback callback, + @NonNull String packageName) { + mRequestInfo = requestInfo; + mCallback = callback; + mPackageName = packageName; + } + } + + /** + * If a request to create inline autofill suggestions comes in while the IME is unbound + * due to {@link #mPreventImeStartupUnlessTextEditor}, this is where it is stored, so + * that it may be fulfilled once the IME rebinds. + */ + @GuardedBy("ImfLock.class") + @Nullable + private CreateInlineSuggestionsRequest mPendingInlineSuggestionsRequest; + @UserIdInt private int mLastSwitchUserId; @@ -2137,16 +2161,24 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub private void onCreateInlineSuggestionsRequestLocked(@UserIdInt int userId, InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback callback, boolean touchExplorationEnabled) { + clearPendingInlineSuggestionsRequestLocked(); final InputMethodInfo imi = mMethodMap.get(getSelectedMethodIdLocked()); try { - IInputMethodInvoker curMethod = getCurMethodLocked(); - if (userId == mSettings.getCurrentUserId() && curMethod != null + if (userId == mSettings.getCurrentUserId() && imi != null && isInlineSuggestionsEnabled(imi, touchExplorationEnabled)) { - final IInlineSuggestionsRequestCallback callbackImpl = - new InlineSuggestionsRequestCallbackDecorator(callback, - imi.getPackageName(), mCurTokenDisplayId, getCurTokenLocked(), - this); - curMethod.onCreateInlineSuggestionsRequest(requestInfo, callbackImpl); + mPendingInlineSuggestionsRequest = new CreateInlineSuggestionsRequest( + requestInfo, callback, imi.getPackageName()); + if (getCurMethodLocked() != null) { + // In the normal case when the IME is connected, we can make the request here. + performOnCreateInlineSuggestionsRequestLocked(); + } else { + // Otherwise, the next time the IME connection is established, + // InputMethodBindingController.mMainConnection#onServiceConnected() will call + // into #performOnCreateInlineSuggestionsRequestLocked() to make the request. + if (DEBUG) { + Slog.d(TAG, "IME not connected. Delaying inline suggestions request."); + } + } } else { callback.onInlineSuggestionsUnsupported(); } @@ -2155,6 +2187,34 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } } + @GuardedBy("ImfLock.class") + void performOnCreateInlineSuggestionsRequestLocked() { + if (mPendingInlineSuggestionsRequest == null) { + return; + } + IInputMethodInvoker curMethod = getCurMethodLocked(); + if (DEBUG) { + Slog.d(TAG, "Performing onCreateInlineSuggestionsRequest. mCurMethod = " + curMethod); + } + if (curMethod != null) { + final IInlineSuggestionsRequestCallback callback = + new InlineSuggestionsRequestCallbackDecorator( + mPendingInlineSuggestionsRequest.mCallback, + mPendingInlineSuggestionsRequest.mPackageName, + mCurTokenDisplayId, getCurTokenLocked(), this); + curMethod.onCreateInlineSuggestionsRequest( + mPendingInlineSuggestionsRequest.mRequestInfo, callback); + } else { + Slog.w(TAG, "No IME connected! Abandoning inline suggestions creation request."); + } + clearPendingInlineSuggestionsRequestLocked(); + } + + @GuardedBy("ImfLock.class") + private void clearPendingInlineSuggestionsRequestLocked() { + mPendingInlineSuggestionsRequest = null; + } + private static boolean isInlineSuggestionsEnabled(InputMethodInfo imi, boolean touchExplorationEnabled) { return imi.isInlineSuggestionsEnabled()