summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TYM Tsai <tymtsai@google.com> 2022-08-31 21:22:38 +0000
committer TYM Tsai <tymtsai@google.com> 2022-10-21 06:13:37 +0800
commit2db6d6767c0e708eb73b32d8a3de1bc39562c449 (patch)
treea9716ce6005bc5d44e681d953dd14fac1b1bb8bb
parent2dbc157f98d5b8df9c277ee803418a012cadb996 (diff)
Reset Autofill dialog if the content is changed
If the content of activity is changed, may fill dialog be requested to show up again. Tracks all fillable views to know the content is changed, and then reset all flags for the fill dialog. Bug: 236237955 Test: atest CtsAutoFillServiceTestCases Change-Id: I58503dd4021021d4bdc8d5114ff7255178fe5408
-rw-r--r--core/java/android/service/autofill/FillRequest.java21
-rw-r--r--core/java/android/view/autofill/AutofillManager.java254
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java40
3 files changed, 221 insertions, 94 deletions
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index b4010a4eefda..0f7c9b63dac0 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -111,6 +111,12 @@ public final class FillRequest implements Parcelable {
*/
public static final @RequestFlags int FLAG_IME_SHOWING = 0x80;
+ /**
+ * Indicates whether autofill session should reset the fill dialog state.
+ * @hide
+ */
+ public static final @RequestFlags int FLAG_RESET_FILL_DIALOG_STATE = 0x100;
+
/** @hide */
public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE;
@@ -208,7 +214,8 @@ public final class FillRequest implements Parcelable {
FLAG_PASSWORD_INPUT_TYPE,
FLAG_VIEW_NOT_FOCUSED,
FLAG_SUPPORTS_FILL_DIALOG,
- FLAG_IME_SHOWING
+ FLAG_IME_SHOWING,
+ FLAG_RESET_FILL_DIALOG_STATE
})
@Retention(RetentionPolicy.SOURCE)
@DataClass.Generated.Member
@@ -236,6 +243,8 @@ public final class FillRequest implements Parcelable {
return "FLAG_SUPPORTS_FILL_DIALOG";
case FLAG_IME_SHOWING:
return "FLAG_IME_SHOWING";
+ case FLAG_RESET_FILL_DIALOG_STATE:
+ return "FLAG_RESET_FILL_DIALOG_STATE";
default: return Integer.toHexString(value);
}
}
@@ -312,7 +321,8 @@ public final class FillRequest implements Parcelable {
| FLAG_PASSWORD_INPUT_TYPE
| FLAG_VIEW_NOT_FOCUSED
| FLAG_SUPPORTS_FILL_DIALOG
- | FLAG_IME_SHOWING);
+ | FLAG_IME_SHOWING
+ | FLAG_RESET_FILL_DIALOG_STATE);
this.mInlineSuggestionsRequest = inlineSuggestionsRequest;
this.mDelayedFillIntentSender = delayedFillIntentSender;
@@ -473,7 +483,8 @@ public final class FillRequest implements Parcelable {
| FLAG_PASSWORD_INPUT_TYPE
| FLAG_VIEW_NOT_FOCUSED
| FLAG_SUPPORTS_FILL_DIALOG
- | FLAG_IME_SHOWING);
+ | FLAG_IME_SHOWING
+ | FLAG_RESET_FILL_DIALOG_STATE);
this.mInlineSuggestionsRequest = inlineSuggestionsRequest;
this.mDelayedFillIntentSender = delayedFillIntentSender;
@@ -495,10 +506,10 @@ public final class FillRequest implements Parcelable {
};
@DataClass.Generated(
- time = 1647856966565L,
+ time = 1663290803064L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/service/autofill/FillRequest.java",
- inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SUPPORTS_FILL_DIALOG\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_IME_SHOWING\npublic static final int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate final @android.annotation.Nullable android.content.IntentSender mDelayedFillIntentSender\nprivate void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
+ inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SUPPORTS_FILL_DIALOG\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_IME_SHOWING\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_RESET_FILL_DIALOG_STATE\npublic static final int INVALID_REQUEST_ID\nprivate final int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate final @android.annotation.Nullable android.content.IntentSender mDelayedFillIntentSender\nprivate void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index dbefcfb5ef17..927ac8b79d6f 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -19,6 +19,7 @@ package android.view.autofill;
import static android.service.autofill.FillRequest.FLAG_IME_SHOWING;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
+import static android.service.autofill.FillRequest.FLAG_RESET_FILL_DIALOG_STATE;
import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED;
import static android.view.ContentInfo.SOURCE_AUTOFILL;
@@ -735,7 +736,7 @@ public final class AutofillManager {
* Autofill will automatically trigger a fill request after activity
* start if there is any field is autofillable. But if there is a field that
* triggered autofill, it is unnecessary to trigger again through
- * AutofillManager#notifyViewEnteredForActivityStarted.
+ * AutofillManager#notifyViewEnteredForFillDialog.
*/
private AtomicBoolean mIsFillRequested;
@@ -748,6 +749,10 @@ public final class AutofillManager {
private final String[] mFillDialogEnabledHints;
+ // Tracked all views that have appeared, including views that there are no
+ // dataset in responses. Used to avoid request pre-fill request again and again.
+ private final ArraySet<AutofillId> mAllTrackedViews = new ArraySet<>();
+
/** @hide */
public interface AutofillClient {
/**
@@ -1193,6 +1198,16 @@ public final class AutofillManager {
* @hide
*/
public void notifyViewEnteredForFillDialog(View v) {
+ synchronized (mLock) {
+ if (mTrackedViews != null) {
+ // To support the fill dialog can show for the autofillable Views in
+ // different pages but in the same Activity. We need to reset the
+ // mIsFillRequested flag to allow asking for a new FillRequest when
+ // user switches to other page
+ mTrackedViews.checkViewState(v.getAutofillId());
+ }
+ }
+
// Skip if the fill request has been performed for a view.
if (mIsFillRequested.get()) {
return;
@@ -1319,6 +1334,10 @@ public final class AutofillManager {
}
mForAugmentedAutofillOnly = false;
}
+
+ if ((flags & FLAG_SUPPORTS_FILL_DIALOG) != 0) {
+ flags |= FLAG_RESET_FILL_DIALOG_STATE;
+ }
updateSessionLocked(id, null, value, ACTION_VIEW_ENTERED, flags);
}
addEnteredIdLocked(id);
@@ -2218,6 +2237,7 @@ public final class AutofillManager {
mIsFillRequested.set(false);
mShowAutofillDialogCalled = false;
mFillDialogTriggerIds = null;
+ mAllTrackedViews.clear();
if (resetEnteredIds) {
mEnteredIds = null;
}
@@ -2777,14 +2797,9 @@ public final class AutofillManager {
+ ", mFillableIds=" + mFillableIds
+ ", mEnabled=" + mEnabled
+ ", mSessionId=" + mSessionId);
-
}
+
if (mEnabled && mSessionId == sessionId) {
- if (saveOnAllViewsInvisible) {
- mTrackedViews = new TrackedViews(trackedIds);
- } else {
- mTrackedViews = null;
- }
mSaveOnFinish = saveOnFinish;
if (fillableIds != null) {
if (mFillableIds == null) {
@@ -2806,6 +2821,27 @@ public final class AutofillManager {
mSaveTriggerId = saveTriggerId;
setNotifyOnClickLocked(mSaveTriggerId, true);
}
+
+ if (!saveOnAllViewsInvisible) {
+ trackedIds = null;
+ }
+
+ final ArraySet<AutofillId> allFillableIds = new ArraySet<>();
+ if (mFillableIds != null) {
+ allFillableIds.addAll(mFillableIds);
+ }
+ if (trackedIds != null) {
+ for (AutofillId id : trackedIds) {
+ id.resetSessionId();
+ allFillableIds.add(id);
+ }
+ }
+
+ if (!allFillableIds.isEmpty()) {
+ mTrackedViews = new TrackedViews(trackedIds, Helper.toArray(allFillableIds));
+ } else {
+ mTrackedViews = null;
+ }
}
}
}
@@ -3577,10 +3613,19 @@ public final class AutofillManager {
*/
private class TrackedViews {
/** Visible tracked views */
- @Nullable private ArraySet<AutofillId> mVisibleTrackedIds;
+ @NonNull private final ArraySet<AutofillId> mVisibleTrackedIds;
/** Invisible tracked views */
- @Nullable private ArraySet<AutofillId> mInvisibleTrackedIds;
+ @NonNull private final ArraySet<AutofillId> mInvisibleTrackedIds;
+
+ /** Visible tracked views for fill dialog */
+ @NonNull private final ArraySet<AutofillId> mVisibleDialogTrackedIds;
+
+ /** Invisible tracked views for fill dialog */
+ @NonNull private final ArraySet<AutofillId> mInvisibleDialogTrackedIds;
+
+ boolean mHasNewTrackedView;
+ boolean mIsTrackedSaveView;
/**
* Check if set is null or value is in set.
@@ -3646,43 +3691,65 @@ public final class AutofillManager {
*
* @param trackedIds The views to be tracked
*/
- TrackedViews(@Nullable AutofillId[] trackedIds) {
- final AutofillClient client = getClient();
- if (!ArrayUtils.isEmpty(trackedIds) && client != null) {
- final boolean[] isVisible;
-
- if (client.autofillClientIsVisibleForAutofill()) {
- if (sVerbose) Log.v(TAG, "client is visible, check tracked ids");
- isVisible = client.autofillClientGetViewVisibility(trackedIds);
- } else {
- // All false
- isVisible = new boolean[trackedIds.length];
- }
-
- final int numIds = trackedIds.length;
- for (int i = 0; i < numIds; i++) {
- final AutofillId id = trackedIds[i];
- id.resetSessionId();
+ TrackedViews(@Nullable AutofillId[] trackedIds, @Nullable AutofillId[] allTrackedIds) {
+ mVisibleTrackedIds = new ArraySet<>();
+ mInvisibleTrackedIds = new ArraySet<>();
+ if (!ArrayUtils.isEmpty(trackedIds)) {
+ mIsTrackedSaveView = true;
+ initialTrackedViews(trackedIds, mVisibleTrackedIds, mInvisibleTrackedIds);
+ }
- if (isVisible[i]) {
- mVisibleTrackedIds = addToSet(mVisibleTrackedIds, id);
- } else {
- mInvisibleTrackedIds = addToSet(mInvisibleTrackedIds, id);
- }
- }
+ mVisibleDialogTrackedIds = new ArraySet<>();
+ mInvisibleDialogTrackedIds = new ArraySet<>();
+ if (!ArrayUtils.isEmpty(allTrackedIds)) {
+ initialTrackedViews(allTrackedIds, mVisibleDialogTrackedIds,
+ mInvisibleDialogTrackedIds);
+ mAllTrackedViews.addAll(Arrays.asList(allTrackedIds));
}
if (sVerbose) {
Log.v(TAG, "TrackedViews(trackedIds=" + Arrays.toString(trackedIds) + "): "
+ " mVisibleTrackedIds=" + mVisibleTrackedIds
- + " mInvisibleTrackedIds=" + mInvisibleTrackedIds);
+ + " mInvisibleTrackedIds=" + mInvisibleTrackedIds
+ + " allTrackedIds=" + Arrays.toString(allTrackedIds)
+ + " mVisibleDialogTrackedIds=" + mVisibleDialogTrackedIds
+ + " mInvisibleDialogTrackedIds=" + mInvisibleDialogTrackedIds);
}
- if (mVisibleTrackedIds == null) {
+ if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
}
}
+ private void initialTrackedViews(AutofillId[] trackedIds,
+ @NonNull ArraySet<AutofillId> visibleSet,
+ @NonNull ArraySet<AutofillId> invisibleSet) {
+ final boolean[] isVisible;
+ final AutofillClient client = getClient();
+ if (ArrayUtils.isEmpty(trackedIds) || client == null) {
+ return;
+ }
+ if (client.autofillClientIsVisibleForAutofill()) {
+ if (sVerbose) Log.v(TAG, "client is visible, check tracked ids");
+ isVisible = client.autofillClientGetViewVisibility(trackedIds);
+ } else {
+ // All false
+ isVisible = new boolean[trackedIds.length];
+ }
+
+ final int numIds = trackedIds.length;
+ for (int i = 0; i < numIds; i++) {
+ final AutofillId id = trackedIds[i];
+ id.resetSessionId();
+
+ if (isVisible[i]) {
+ addToSet(visibleSet, id);
+ } else {
+ addToSet(invisibleSet, id);
+ }
+ }
+ }
+
/**
* Called when a {@link View view's} visibility changes.
*
@@ -3699,22 +3766,37 @@ public final class AutofillManager {
if (isClientVisibleForAutofillLocked()) {
if (isVisible) {
if (isInSet(mInvisibleTrackedIds, id)) {
- mInvisibleTrackedIds = removeFromSet(mInvisibleTrackedIds, id);
- mVisibleTrackedIds = addToSet(mVisibleTrackedIds, id);
+ removeFromSet(mInvisibleTrackedIds, id);
+ addToSet(mVisibleTrackedIds, id);
+ }
+ if (isInSet(mInvisibleDialogTrackedIds, id)) {
+ removeFromSet(mInvisibleDialogTrackedIds, id);
+ addToSet(mVisibleDialogTrackedIds, id);
}
} else {
if (isInSet(mVisibleTrackedIds, id)) {
- mVisibleTrackedIds = removeFromSet(mVisibleTrackedIds, id);
- mInvisibleTrackedIds = addToSet(mInvisibleTrackedIds, id);
+ removeFromSet(mVisibleTrackedIds, id);
+ addToSet(mInvisibleTrackedIds, id);
+ }
+ if (isInSet(mVisibleDialogTrackedIds, id)) {
+ removeFromSet(mVisibleDialogTrackedIds, id);
+ addToSet(mInvisibleDialogTrackedIds, id);
}
}
}
- if (mVisibleTrackedIds == null) {
+ if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
if (sVerbose) {
Log.v(TAG, "No more visible ids. Invisible = " + mInvisibleTrackedIds);
}
finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
+
+ }
+ if (mVisibleDialogTrackedIds.isEmpty()) {
+ if (sVerbose) {
+ Log.v(TAG, "No more visible ids. Invisible = " + mInvisibleDialogTrackedIds);
+ }
+ processNoVisibleTrackedAllViews();
}
}
@@ -3728,66 +3810,66 @@ public final class AutofillManager {
// The visibility of the views might have changed while the client was not be visible,
// hence update the visibility state for all views.
AutofillClient client = getClient();
- ArraySet<AutofillId> updatedVisibleTrackedIds = null;
- ArraySet<AutofillId> updatedInvisibleTrackedIds = null;
if (client != null) {
if (sVerbose) {
Log.v(TAG, "onVisibleForAutofillChangedLocked(): inv= " + mInvisibleTrackedIds
+ " vis=" + mVisibleTrackedIds);
}
- if (mInvisibleTrackedIds != null) {
- final ArrayList<AutofillId> orderedInvisibleIds =
- new ArrayList<>(mInvisibleTrackedIds);
- final boolean[] isVisible = client.autofillClientGetViewVisibility(
- Helper.toArray(orderedInvisibleIds));
-
- final int numInvisibleTrackedIds = orderedInvisibleIds.size();
- for (int i = 0; i < numInvisibleTrackedIds; i++) {
- final AutofillId id = orderedInvisibleIds.get(i);
- if (isVisible[i]) {
- updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
- if (sDebug) {
- Log.d(TAG, "onVisibleForAutofill() " + id + " became visible");
- }
- } else {
- updatedInvisibleTrackedIds = addToSet(updatedInvisibleTrackedIds, id);
- }
- }
- }
+ onVisibleForAutofillChangedInternalLocked(mVisibleTrackedIds, mInvisibleTrackedIds);
+ onVisibleForAutofillChangedInternalLocked(
+ mVisibleDialogTrackedIds, mInvisibleDialogTrackedIds);
+ }
- if (mVisibleTrackedIds != null) {
- final ArrayList<AutofillId> orderedVisibleIds =
- new ArrayList<>(mVisibleTrackedIds);
- final boolean[] isVisible = client.autofillClientGetViewVisibility(
- Helper.toArray(orderedVisibleIds));
+ if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
+ if (sVerbose) {
+ Log.v(TAG, "onVisibleForAutofillChangedLocked(): no more visible ids");
+ }
+ finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
+ }
+ if (mVisibleDialogTrackedIds.isEmpty()) {
+ if (sVerbose) {
+ Log.v(TAG, "onVisibleForAutofillChangedLocked(): no more visible ids");
+ }
+ processNoVisibleTrackedAllViews();
+ }
+ }
- final int numVisibleTrackedIds = orderedVisibleIds.size();
- for (int i = 0; i < numVisibleTrackedIds; i++) {
- final AutofillId id = orderedVisibleIds.get(i);
+ void onVisibleForAutofillChangedInternalLocked(@NonNull ArraySet<AutofillId> visibleSet,
+ @NonNull ArraySet<AutofillId> invisibleSet) {
+ // The visibility of the views might have changed while the client was not be visible,
+ // hence update the visibility state for all views.
+ if (sVerbose) {
+ Log.v(TAG, "onVisibleForAutofillChangedLocked(): inv= " + invisibleSet
+ + " vis=" + visibleSet);
+ }
- if (isVisible[i]) {
- updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
- } else {
- updatedInvisibleTrackedIds = addToSet(updatedInvisibleTrackedIds, id);
+ ArraySet<AutofillId> allTrackedIds = new ArraySet<>();
+ allTrackedIds.addAll(visibleSet);
+ allTrackedIds.addAll(invisibleSet);
+ if (!allTrackedIds.isEmpty()) {
+ visibleSet.clear();
+ invisibleSet.clear();
+ initialTrackedViews(Helper.toArray(allTrackedIds), visibleSet, invisibleSet);
+ }
+ }
- if (sDebug) {
- Log.d(TAG, "onVisibleForAutofill() " + id + " became invisible");
- }
- }
- }
- }
+ private void processNoVisibleTrackedAllViews() {
+ mShowAutofillDialogCalled = false;
+ }
- mInvisibleTrackedIds = updatedInvisibleTrackedIds;
- mVisibleTrackedIds = updatedVisibleTrackedIds;
+ void checkViewState(AutofillId id) {
+ if (mAllTrackedViews.contains(id)) {
+ return;
}
-
- if (mVisibleTrackedIds == null) {
- if (sVerbose) {
- Log.v(TAG, "onVisibleForAutofillChangedLocked(): no more visible ids");
- }
- finishSessionLocked(/* commitReason= */ COMMIT_REASON_VIEW_CHANGED);
+ // Add the id as tracked to avoid triggering fill request again and again.
+ mAllTrackedViews.add(id);
+ if (mHasNewTrackedView) {
+ return;
}
+ // First one new tracks view
+ mIsFillRequested.set(false);
+ mHasNewTrackedView = true;
}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 47ce5928c0be..64b7688cc196 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -24,6 +24,7 @@ import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_UNKNOWN;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
+import static android.service.autofill.FillRequest.FLAG_RESET_FILL_DIALOG_STATE;
import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED;
import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
@@ -416,6 +417,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@GuardedBy("mLock")
private boolean mPreviouslyFillDialogPotentiallyStarted;
+ /**
+ * Keeps the fill dialog trigger ids of the last response. This invalidates
+ * the trigger ids of the previous response.
+ */
+ @Nullable
+ @GuardedBy("mLock")
+ private AutofillId[] mLastFillDialogTriggerIds;
+
void onSwitchInputMethodLocked() {
// One caveat is that for the case where the focus is on a field for which regular autofill
// returns null, and augmented autofill is triggered, and then the user switches the input
@@ -1222,6 +1231,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return;
}
+ mLastFillDialogTriggerIds = response.getFillDialogTriggerIds();
+
final int flags = response.getFlags();
if ((flags & FillResponse.FLAG_DELAY_FILL) != 0) {
Slog.v(TAG, "Service requested to wait for delayed fill response.");
@@ -1310,6 +1321,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// fallback to the default platform password manager
mSessionFlags.mClientSuggestionsEnabled = false;
+ mLastFillDialogTriggerIds = null;
final InlineSuggestionsRequest inlineRequest =
(mLastInlineSuggestionsRequest != null
@@ -1348,6 +1360,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
+ (timedOut ? "timeout" : "failure"));
}
mService.resetLastResponse();
+ mLastFillDialogTriggerIds = null;
final LogMaker requestLog = mRequestLogs.get(requestId);
if (requestLog == null) {
Slog.w(TAG, "onFillRequestFailureOrTimeout(): no log for id " + requestId);
@@ -3049,6 +3062,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
}
+ if ((flags & FLAG_RESET_FILL_DIALOG_STATE) != 0) {
+ if (sDebug) Log.d(TAG, "force to reset fill dialog state");
+ mSessionFlags.mFillDialogDisabled = false;
+ }
+
switch(action) {
case ACTION_START_SESSION:
// View is triggering autofill.
@@ -3488,10 +3506,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
private boolean isFillDialogUiEnabled() {
- // TODO read from Settings or somewhere
- final boolean isSettingsEnabledFillDialog = true;
synchronized (mLock) {
- return isSettingsEnabledFillDialog && !mSessionFlags.mFillDialogDisabled;
+ return !mSessionFlags.mFillDialogDisabled;
}
}
@@ -3517,14 +3533,25 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
AutofillId filledId, String filterText, int flags) {
if (!isFillDialogUiEnabled()) {
// Unsupported fill dialog UI
+ if (sDebug) Log.w(TAG, "requestShowFillDialog: fill dialog is disabled");
return false;
}
if ((flags & FillRequest.FLAG_IME_SHOWING) != 0) {
// IME is showing, fallback to normal suggestions UI
+ if (sDebug) Log.w(TAG, "requestShowFillDialog: IME is showing");
return false;
}
+ synchronized (mLock) {
+ if (mLastFillDialogTriggerIds == null
+ || !ArrayUtils.contains(mLastFillDialogTriggerIds, filledId)) {
+ // Last fill dialog triggered ids are changed.
+ if (sDebug) Log.w(TAG, "Last fill dialog triggered ids are changed.");
+ return false;
+ }
+ }
+
final Drawable serviceIcon = getServiceIcon();
getUiForShowing().showFillDialog(filledId, response, filterText,
@@ -4394,6 +4421,13 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (mSessionFlags.mAugmentedAutofillOnly) {
pw.print(prefix); pw.println("For Augmented Autofill Only");
}
+ if (mSessionFlags.mFillDialogDisabled) {
+ pw.print(prefix); pw.println("Fill Dialog disabled");
+ }
+ if (mLastFillDialogTriggerIds != null) {
+ pw.print(prefix); pw.println("Last Fill Dialog trigger ids: ");
+ pw.println(mSelectedDatasetIds);
+ }
if (mAugmentedAutofillDestroyer != null) {
pw.print(prefix); pw.println("has mAugmentedAutofillDestroyer");
}