From 3103c63b2d47a51ad5a39309c91130aecc06665d Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 18 Dec 2017 15:05:14 -0800 Subject: [PATCH] Support new Autofill session after service returns a null FillResponse. When the AutofillService returns a null FillResponse for onFillRequest(), AutofillManager was ignoring any further view calls backs (other than a manual request to start a session) to optimize performance by avoiding unnecessary IPCs to system_server (and then from system_server to the Autofill Service process). But this optimization has a drawback: it makes it harder for the service to handle cases where the activitity dynamically added new views after a view has been focused. This CL offers a compromise to fix both problems: it removes the optimization for notifyViewEntered() calls (as that's what triggers autofill), but still ignores the other calls once the session is on finished state. Test: atest CtsAutoFillServiceTestCases:LoginActivityTest#testAutofillAutomaticallyAfterServiceReturnedNoDatasets Test: atest CtsAutoFillServiceTestCases:LoginActivityTest#testAutofillAutomaticallyAndSaveAfterServiceReturnedNoDatasets Test: atest CtsAutoFillServiceTestCases:LoginActivityTest Fixes: 70046972 For optimization purposes, AutofillManager was ignoring all request Changed AutofillManager to start a new session after service returns a null Change-Id: Iaae9ed7f8b12ebc9da13e990ef468d9019d5c6ca --- .../view/autofill/AutofillManager.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index d0dbff0e23f37..81b065cfdb338 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -530,10 +530,13 @@ public final class AutofillManager { * @return whether autofill is enabled for the current user. */ public boolean isEnabled() { - if (!hasAutofillFeature() || isDisabledByService()) { + if (!hasAutofillFeature()) { return false; } synchronized (mLock) { + if (isDisabledByServiceLocked()) { + return false; + } ensureServiceClientAddedIfNeededLocked(); return mEnabled; } @@ -605,19 +608,16 @@ public final class AutofillManager { } private boolean shouldIgnoreViewEnteredLocked(@NonNull View view, int flags) { - if (isDisabledByService()) { + if (isDisabledByServiceLocked()) { if (sVerbose) { Log.v(TAG, "ignoring notifyViewEntered(flags=" + flags + ", view=" + view + ") on state " + getStateAsStringLocked()); } return true; } - if (mState == STATE_FINISHED && (flags & FLAG_MANUAL_REQUEST) == 0) { - if (sVerbose) { - Log.v(TAG, "ignoring notifyViewEntered(flags=" + flags + ", view=" + view - + ") on state " + getStateAsStringLocked()); - } - return true; + if (sVerbose && isFinishedLocked()) { + Log.v(TAG, "not ignoring notifyViewEntered(flags=" + flags + ", view=" + view + + ") on state " + getStateAsStringLocked()); } return false; } @@ -1139,10 +1139,10 @@ public final class AutofillManager { Log.v(TAG, "startSessionLocked(): id=" + id + ", bounds=" + bounds + ", value=" + value + ", flags=" + flags + ", state=" + getStateAsStringLocked()); } - if (mState != STATE_UNKNOWN && (flags & FLAG_MANUAL_REQUEST) == 0) { + if (mState != STATE_UNKNOWN && !isFinishedLocked() && (flags & FLAG_MANUAL_REQUEST) == 0) { if (sVerbose) { Log.v(TAG, "not automatically starting session for " + id - + " on state " + getStateAsStringLocked()); + + " on state " + getStateAsStringLocked() + " and flags " + flags); } return; } @@ -1744,10 +1744,14 @@ public final class AutofillManager { return mState == STATE_ACTIVE; } - private boolean isDisabledByService() { + private boolean isDisabledByServiceLocked() { return mState == STATE_DISABLED_BY_SERVICE; } + private boolean isFinishedLocked() { + return mState == STATE_FINISHED; + } + private void post(Runnable runnable) { final AutofillClient client = getClient(); if (client == null) {