Merge "Reset Autofill dialog if the content is changed" into tm-qpr-dev
This commit is contained in:
@@ -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() {}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -715,7 +716,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;
|
||||
|
||||
@@ -728,6 +729,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 {
|
||||
/**
|
||||
@@ -1173,6 +1178,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;
|
||||
@@ -1299,6 +1314,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);
|
||||
@@ -2165,6 +2184,7 @@ public final class AutofillManager {
|
||||
mIsFillRequested.set(false);
|
||||
mShowAutofillDialogCalled = false;
|
||||
mFillDialogTriggerIds = null;
|
||||
mAllTrackedViews.clear();
|
||||
if (resetEnteredIds) {
|
||||
mEnteredIds = null;
|
||||
}
|
||||
@@ -2702,14 +2722,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) {
|
||||
@@ -2731,6 +2746,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3502,10 +3538,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.
|
||||
@@ -3571,43 +3616,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;
|
||||
TrackedViews(@Nullable AutofillId[] trackedIds, @Nullable AutofillId[] allTrackedIds) {
|
||||
mVisibleTrackedIds = new ArraySet<>();
|
||||
mInvisibleTrackedIds = new ArraySet<>();
|
||||
if (!ArrayUtils.isEmpty(trackedIds)) {
|
||||
mIsTrackedSaveView = true;
|
||||
initialTrackedViews(trackedIds, mVisibleTrackedIds, mInvisibleTrackedIds);
|
||||
}
|
||||
|
||||
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]) {
|
||||
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.
|
||||
*
|
||||
@@ -3624,22 +3691,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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3653,66 +3735,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mVisibleTrackedIds != null) {
|
||||
final ArrayList<AutofillId> orderedVisibleIds =
|
||||
new ArrayList<>(mVisibleTrackedIds);
|
||||
final boolean[] isVisible = client.autofillClientGetViewVisibility(
|
||||
Helper.toArray(orderedVisibleIds));
|
||||
|
||||
final int numVisibleTrackedIds = orderedVisibleIds.size();
|
||||
for (int i = 0; i < numVisibleTrackedIds; i++) {
|
||||
final AutofillId id = orderedVisibleIds.get(i);
|
||||
|
||||
if (isVisible[i]) {
|
||||
updatedVisibleTrackedIds = addToSet(updatedVisibleTrackedIds, id);
|
||||
} else {
|
||||
updatedInvisibleTrackedIds = addToSet(updatedInvisibleTrackedIds, id);
|
||||
|
||||
if (sDebug) {
|
||||
Log.d(TAG, "onVisibleForAutofill() " + id + " became invisible");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mInvisibleTrackedIds = updatedInvisibleTrackedIds;
|
||||
mVisibleTrackedIds = updatedVisibleTrackedIds;
|
||||
onVisibleForAutofillChangedInternalLocked(mVisibleTrackedIds, mInvisibleTrackedIds);
|
||||
onVisibleForAutofillChangedInternalLocked(
|
||||
mVisibleDialogTrackedIds, mInvisibleDialogTrackedIds);
|
||||
}
|
||||
|
||||
if (mVisibleTrackedIds == null) {
|
||||
if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
|
||||
if (sVerbose) {
|
||||
Log.v(TAG, "onVisibleForAutofillChangedLocked(): no more visible ids");
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
ArraySet<AutofillId> allTrackedIds = new ArraySet<>();
|
||||
allTrackedIds.addAll(visibleSet);
|
||||
allTrackedIds.addAll(invisibleSet);
|
||||
if (!allTrackedIds.isEmpty()) {
|
||||
visibleSet.clear();
|
||||
invisibleSet.clear();
|
||||
initialTrackedViews(Helper.toArray(allTrackedIds), visibleSet, invisibleSet);
|
||||
}
|
||||
}
|
||||
|
||||
private void processNoVisibleTrackedAllViews() {
|
||||
mShowAutofillDialogCalled = false;
|
||||
}
|
||||
|
||||
void checkViewState(AutofillId id) {
|
||||
if (mAllTrackedViews.contains(id)) {
|
||||
return;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -411,6 +412,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
@GuardedBy("mLock")
|
||||
private boolean mStartedLogEventWithoutFocus;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -1171,6 +1180,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.");
|
||||
@@ -1277,6 +1288,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);
|
||||
@@ -2973,6 +2985,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.
|
||||
@@ -3402,10 +3419,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3431,14 +3446,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,
|
||||
@@ -4278,6 +4304,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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user