Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8132b1c authored by Tim Yu's avatar Tim Yu Committed by Android (Google) Code Review
Browse files

Merge "Add a new Autofill FillEvent - for when the user taps a field. Test:...

Merge "Add a new Autofill FillEvent - for when the user taps a field. Test: atest android.autofillservice.cts.inline.InlineFillEventHistoryTest" into udc-dev
parents 018ea2e7 84484c13
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39862,6 +39862,7 @@ package android.service.autofill {
    field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
    field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
    field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
    field public static final int TYPE_VIEW_REQUESTED_AUTOFILL = 6; // 0x6
    field public static final int UI_TYPE_DIALOG = 3; // 0x3
    field public static final int UI_TYPE_INLINE = 2; // 0x2
    field public static final int UI_TYPE_MENU = 1; // 0x1
+22 −3
Original line number Diff line number Diff line
@@ -233,6 +233,22 @@ public final class FillEventHistory implements Parcelable {
         */
        public static final int TYPE_DATASETS_SHOWN = 5;

        /**
         * The app/user requested for a field to be Autofilled.
         *
         * This event is fired when the view has been entered (by user or app) in order
         * to differentiate from FillRequests that have been pretriggered for FillDialogs.
         *
         * For example, the user might navigate away from a screen without tapping any
         * fields. In this case, a FillRequest/FillResponse has been generated, but was
         * not used for Autofilling. The user did not intend to see an Autofill result,
         * but a FillRequest was still generated. This is different from when the user
         * did tap on a field after the pretriggered FillRequest, this event will appear
         * in the FillEventHistory, signaling that the user did intend to Autofill
         * something.
         */
        public static final int TYPE_VIEW_REQUESTED_AUTOFILL = 6;

        /** @hide */
        @IntDef(prefix = { "TYPE_" }, value = {
                TYPE_DATASET_SELECTED,
@@ -240,7 +256,8 @@ public final class FillEventHistory implements Parcelable {
                TYPE_AUTHENTICATION_SELECTED,
                TYPE_SAVE_SHOWN,
                TYPE_CONTEXT_COMMITTED,
                TYPE_DATASETS_SHOWN
                TYPE_DATASETS_SHOWN,
                TYPE_VIEW_REQUESTED_AUTOFILL
        })
        @Retention(RetentionPolicy.SOURCE)
        @interface EventIds{}
@@ -659,8 +676,8 @@ public final class FillEventHistory implements Parcelable {
                @Nullable AutofillId[] detectedFieldIds,
                @Nullable FieldClassification[] detectedFieldClassifications,
                int saveDialogNotShowReason, int uiType) {
            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_DATASETS_SHOWN,
                    "eventType");
            mEventType = Preconditions.checkArgumentInRange(eventType, 0,
                    TYPE_VIEW_REQUESTED_AUTOFILL, "eventType");
            mDatasetId = datasetId;
            mClientState = clientState;
            mSelectedDatasetIds = selectedDatasetIds;
@@ -723,6 +740,8 @@ public final class FillEventHistory implements Parcelable {
                    return "TYPE_CONTEXT_COMMITTED";
                case TYPE_DATASETS_SHOWN:
                    return "TYPE_DATASETS_SHOWN";
                case TYPE_VIEW_REQUESTED_AUTOFILL:
                    return "TYPE_VIEW_REQUESTED_AUTOFILL";
                default:
                    return "TYPE_UNKNOWN";
            }
+26 −0
Original line number Diff line number Diff line
@@ -849,6 +849,32 @@ final class AutofillManagerServiceImpl
        }
    }


    /**
     * Updates the last fill response when a view was entered.
     */
    void logViewEntered(int sessionId, @Nullable Bundle clientState) {
        synchronized (mLock) {
            if (!isValidEventLocked("logViewEntered", sessionId)) {
                return;
            }

            if (mEventHistory.getEvents() != null) {
                // Do not log this event more than once
                for (Event event : mEventHistory.getEvents()) {
                    if (event.getType() == Event.TYPE_VIEW_REQUESTED_AUTOFILL) {
                        Slog.v(TAG, "logViewEntered: already logged TYPE_VIEW_REQUESTED_AUTOFILL");
                        return;
                    }
                }
            }

            mEventHistory.addEvent(
                    new Event(Event.TYPE_VIEW_REQUESTED_AUTOFILL, null, clientState, null,
                            null, null, null, null, null, null, null));
        }
    }

    void logAugmentedAutofillAuthenticationSelected(int sessionId, @Nullable String selectedDataset,
            @Nullable Bundle clientState) {
        synchronized (mLock) {
+43 −0
Original line number Diff line number Diff line
@@ -441,6 +441,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
    @GuardedBy("mLock")
    private boolean mPreviouslyFillDialogPotentiallyStarted;

    /**
     * Keeps track of if the user entered view, this is used to
     * distinguish Fill Request that did not have user interaction
     * with ones that did.
     *
     * This is set to true when entering view - after FillDialog FillRequest
     * or on plain user tap.
     */
    @NonNull
    @GuardedBy("mLock")
    private boolean mLogViewEntered;

    /**
     * Keeps the fill dialog trigger ids of the last response. This invalidates
     * the trigger ids of the previous response.
@@ -1289,6 +1301,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState

        mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED)
                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags));
        mLogViewEntered = false;
    }

    /**
@@ -1413,6 +1426,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState

        mService.setLastResponse(id, response);

        synchronized (mLock) {
            if (mLogViewEntered) {
                mLogViewEntered = false;
                mService.logViewEntered(id, null);
            }
        }


        final long disableDuration = response.getDisableDuration();
        final boolean autofillDisabled = disableDuration > 0;
        if (autofillDisabled) {
@@ -3545,6 +3566,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                    return;
                }

                synchronized (mLock) {
                    if (!mLogViewEntered) {
                        // If the current request is for FillDialog (preemptive)
                        // then this is the first time that the view is entered
                        // (mLogViewEntered == false) in this case, setLastResponse()
                        // has already been called, so just log here.
                        // If the current request is not and (mLogViewEntered == false)
                        // then the last session is being tracked (setLastResponse not called)
                        // so this calling logViewEntered will be a nop.
                        // Calling logViewEntered() twice will only log it once
                        // TODO(271181979): this is broken for multiple partitions
                        mService.logViewEntered(this.id, null);
                    }

                    // If this is the first time view is entered for inline, the last
                    // session is still being tracked, so logViewEntered() needs
                    // to be delayed until setLastResponse is called.
                    // For fill dialog requests case logViewEntered is already called above
                    // so this will do nothing. Assumption: only one fill dialog per session
                    mLogViewEntered = true;
                }

                // Previously, fill request will only start whenever a view is entered.
                // With Fill Dialog, request starts prior to view getting entered. So, we can't end
                // the event at this moment, otherwise we will be wrongly attributing fill dialog