From 523dca0729e243849906d4a4b2fc1756ff4c8dda Mon Sep 17 00:00:00 2001 From: Feng Cao Date: Wed, 20 May 2020 19:36:15 -0700 Subject: [PATCH] Fix a bug where autofill resends inline suggestions in the wrong app * This is broken by ag/11443581 where we remove clearing the suggestions when view exit. The problem is that we cache the suggestions across onFinishInput/onStartInput events and resends the suggestions when autofill id matches. But the autofill id can be the same for different apps, so we ended up resending the old suggestion in the new app field with the same autofill id but doesn't have its own autofill suggestions. * The fix is to clear the suggestions cache in the autofill side, but to avoid flickering the IME UI we don't send an empty response to the IME when observing ACTION_VIEW_EXITED Test: atest android.autofillservice.cts.inline Bug: 157174936 Change-Id: I156eecab3cae0b0684f3c5f5e0f852bf73e93a19 --- .../AutofillInlineSessionController.java | 16 ++++++++++++++++ .../AutofillInlineSuggestionsRequestSession.java | 10 ++++++++++ .../com/android/server/autofill/Session.java | 3 +++ 3 files changed, 29 insertions(+) diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java index 3dd2433ac2bdb..23bb9d63d6fad 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java +++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java @@ -126,6 +126,22 @@ final class AutofillInlineSessionController { return hideInlineSuggestionsUiLocked(autofillId); } + /** + * Clear the locally cached inline fill UI, but don't clear the suggestion in the IME. + * + *

This is called to invalid the locally cached inline suggestions so we don't resend them + * to the IME, while assuming that the IME will clean up suggestion on their own when the input + * connection is finished. We don't send an empty response to IME so that it doesn't cause UI + * flicker on the IME side if it arrives before the input view is finished on the IME. + */ + @GuardedBy("mLock") + void resetInlineFillUiLocked() { + mInlineFillUi = null; + if (mSession != null) { + mSession.resetInlineFillUiLocked(); + } + } + /** * Updates the inline fill UI with the filter text. It'll send updated inline suggestions to * the IME. diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java index 1a3baba1ff193..687b75a8b9495 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java +++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java @@ -190,6 +190,16 @@ final class AutofillInlineSuggestionsRequestSession { new InlineSuggestionsRequestCallbackImpl(this)); } + /** + * Clear the locally cached inline fill UI, but don't clear the suggestion in IME. + * + * See also {@link AutofillInlineSessionController#resetInlineFillUiLocked()} + */ + @GuardedBy("mLock") + void resetInlineFillUiLocked() { + mInlineFillUi = null; + } + /** * Optionally sends inline response to the IME, depending on the current state. */ diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 1d3ab9b7e24b3..558acfa3ed196 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -2581,6 +2581,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (sVerbose) Slog.v(TAG, "Exiting view " + id); mUi.hideFillUi(this); hideAugmentedAutofillLocked(viewState); + // We don't send an empty response to IME so that it doesn't cause UI flicker + // on the IME side if it arrives before the input view is finished on the IME. + mInlineSessionController.resetInlineFillUiLocked(); mCurrentViewId = null; } break;