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

Commit f9fafbe6 authored by Joanne Chung's avatar Joanne Chung Committed by skxu
Browse files

Provide AutofillService to know how the dataset was shown to user

We introduce a filed for ui presentation in FillEventHistory.Event,
the type will be set for TYPE_DATASET_SHOWN and TYPE_DATASET_SELECTED.
The AutofillService can know which dataset is shown to user and which
type dataset user is clicked.

This change defines the definition and apply to TYPE_DATASET_SHOWN,
the TYPE_DATASET_SELECTED will be implemented on the follow up
change.

Bug: 223472350
Test: manual. build and boot pass. Test app and see dumpsys autofill
CTS-Coverage-Bug: 225310516

Change-Id: Ic221bd79e2ad512db5cd1ef8fd96c6bfae2ca616
parent faaf1983
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -38205,6 +38205,7 @@ package android.service.autofill {
    method public int getNoSaveUiReason();
    method @NonNull public java.util.Set<java.lang.String> getSelectedDatasetIds();
    method public int getType();
    method public int getUiType();
    field public static final int NO_SAVE_UI_REASON_DATASET_MATCH = 6; // 0x6
    field public static final int NO_SAVE_UI_REASON_FIELD_VALIDATION_FAILED = 5; // 0x5
    field public static final int NO_SAVE_UI_REASON_HAS_EMPTY_REQUIRED = 3; // 0x3
@@ -38218,6 +38219,10 @@ 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 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
    field public static final int UI_TYPE_UNKNOWN = 0; // 0x0
  }
  public final class FillRequest implements android.os.Parcelable {
+127 −6
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ public final class FillEventHistory implements Parcelable {
                            event.mDetectedFieldClassifications);
                }
                parcel.writeInt(event.mSaveDialogNotShowReason);
                parcel.writeInt(event.mUiType);
            }
        }
    }
@@ -278,6 +279,29 @@ public final class FillEventHistory implements Parcelable {
        @Retention(RetentionPolicy.SOURCE)
        public @interface NoSaveReason{}

        /** The autofill suggestion presentation is unknown, this will be set for the event
         * that is unrelated to fill Ui presentation */
        public static final int UI_TYPE_UNKNOWN = 0;

        /** The autofill suggestion is shown as a menu popup presentation. */
        public static final int UI_TYPE_MENU = 1;

        /** The autofill suggestion is shown as a keyboard inline presentation. */
        public static final int UI_TYPE_INLINE = 2;

        /** The autofill suggestion is shown as a dialog presentation. */
        public static final int UI_TYPE_DIALOG = 3;

        /** @hide */
        @IntDef(prefix = { "UI_TYPE_" }, value = {
                UI_TYPE_UNKNOWN,
                UI_TYPE_MENU,
                UI_TYPE_INLINE,
                UI_TYPE_DIALOG
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface UiType {}

        @EventIds private final int mEventType;
        @Nullable private final String mDatasetId;
        @Nullable private final Bundle mClientState;
@@ -298,6 +322,10 @@ public final class FillEventHistory implements Parcelable {

        @NoSaveReason private final int mSaveDialogNotShowReason;


        @UiType
        private final int mUiType;

        /**
         * Returns the type of the event.
         *
@@ -497,6 +525,21 @@ public final class FillEventHistory implements Parcelable {
            return mSaveDialogNotShowReason;
        }

        /**
         * Returns fill suggestion ui presentation type which corresponds to types
         * defined in {@link android.service.autofill.Presentations).
         *
         * <p><b>Note: </b>Only set on events of type {@link #TYPE_DATASETS_SHOWN} and
         * {@link #TYPE_DATASET_SELECTED}. For the other event types, the type is set to
         * {@link #UI_TYPE_UNKNOWN }.
         *
         * @return The ui presentation type shown for user.
         */
        @UiType
        public int getUiType() {
            return mUiType;
        }

        /**
         * Creates a new event.
         *
@@ -573,6 +616,49 @@ public final class FillEventHistory implements Parcelable {
                @Nullable AutofillId[] detectedFieldIds,
                @Nullable FieldClassification[] detectedFieldClassifications,
                int saveDialogNotShowReason) {
            this(eventType, datasetId, clientState, selectedDatasetIds, ignoredDatasetIds,
                    changedFieldIds, changedDatasetIds, manuallyFilledFieldIds,
                    manuallyFilledDatasetIds, detectedFieldIds, detectedFieldClassifications,
                    saveDialogNotShowReason, UI_TYPE_UNKNOWN);
        }

        /**
         * Creates a new event.
         *
         * @param eventType The type of the event
         * @param datasetId The dataset the event was on, or {@code null} if the event was on the
         *                  whole response.
         * @param clientState The client state associated with the event.
         * @param selectedDatasetIds The ids of datasets selected by the user.
         * @param ignoredDatasetIds The ids of datasets NOT select by the user.
         * @param changedFieldIds The ids of fields changed by the user.
         * @param changedDatasetIds The ids of the datasets that havd values matching the
         * respective entry on {@code changedFieldIds}.
         * @param manuallyFilledFieldIds The ids of fields that were manually entered by the user
         * and belonged to datasets.
         * @param manuallyFilledDatasetIds The ids of datasets that had values matching the
         * respective entry on {@code manuallyFilledFieldIds}.
         * @param detectedFieldClassifications the field classification matches.
         * @param saveDialogNotShowReason The reason why a save dialog was not shown.
         * @param uiType The ui presentation type for fill suggestion.
         *
         * @throws IllegalArgumentException If the length of {@code changedFieldIds} and
         * {@code changedDatasetIds} doesn't match.
         * @throws IllegalArgumentException If the length of {@code manuallyFilledFieldIds} and
         * {@code manuallyFilledDatasetIds} doesn't match.
         *
         * @hide
         */
        public Event(int eventType, @Nullable String datasetId, @Nullable Bundle clientState,
                @Nullable List<String> selectedDatasetIds,
                @Nullable ArraySet<String> ignoredDatasetIds,
                @Nullable ArrayList<AutofillId> changedFieldIds,
                @Nullable ArrayList<String> changedDatasetIds,
                @Nullable ArrayList<AutofillId> manuallyFilledFieldIds,
                @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
                @Nullable AutofillId[] detectedFieldIds,
                @Nullable FieldClassification[] detectedFieldClassifications,
                int saveDialogNotShowReason, int uiType) {
            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_DATASETS_SHOWN,
                    "eventType");
            mDatasetId = datasetId;
@@ -602,12 +688,14 @@ public final class FillEventHistory implements Parcelable {
            mSaveDialogNotShowReason = Preconditions.checkArgumentInRange(saveDialogNotShowReason,
                    NO_SAVE_UI_REASON_NONE, NO_SAVE_UI_REASON_DATASET_MATCH,
                    "saveDialogNotShowReason");
            mUiType = uiType;
        }

        @Override
        public String toString() {
            return "FillEvent [datasetId=" + mDatasetId
                    + ", type=" + mEventType
                    + ", type=" + eventToString(mEventType)
                    + ", uiType=" + uiTypeToString(mUiType)
                    + ", selectedDatasets=" + mSelectedDatasetIds
                    + ", ignoredDatasetIds=" + mIgnoredDatasetIds
                    + ", changedFieldIds=" + mChangedFieldIds
@@ -620,6 +708,38 @@ public final class FillEventHistory implements Parcelable {
                    + ", saveDialogNotShowReason=" + mSaveDialogNotShowReason
                    + "]";
        }

        private static String eventToString(int eventType) {
            switch (eventType) {
                case TYPE_DATASET_SELECTED:
                    return "TYPE_DATASET_SELECTED";
                case TYPE_DATASET_AUTHENTICATION_SELECTED:
                    return "TYPE_DATASET_AUTHENTICATION_SELECTED";
                case TYPE_AUTHENTICATION_SELECTED:
                    return "TYPE_AUTHENTICATION_SELECTED";
                case TYPE_SAVE_SHOWN:
                    return "TYPE_SAVE_SHOWN";
                case TYPE_CONTEXT_COMMITTED:
                    return "TYPE_CONTEXT_COMMITTED";
                case TYPE_DATASETS_SHOWN:
                    return "TYPE_DATASETS_SHOWN";
                default:
                    return "TYPE_UNKNOWN";
            }
        }

        private static String uiTypeToString(int uiType) {
            switch (uiType) {
                case UI_TYPE_MENU:
                    return "UI_TYPE_MENU";
                case UI_TYPE_INLINE:
                    return "UI_TYPE_INLINE";
                case UI_TYPE_DIALOG:
                    return "UI_TYPE_FILL_DIALOG";
                default:
                    return "UI_TYPE_UNKNOWN";
            }
        }
    }

    public static final @android.annotation.NonNull Parcelable.Creator<FillEventHistory> CREATOR =
@@ -660,13 +780,14 @@ public final class FillEventHistory implements Parcelable {
                                ? FieldClassification.readArrayFromParcel(parcel)
                                : null;
                        final int saveDialogNotShowReason = parcel.readInt();
                        final int uiType = parcel.readInt();

                        selection.addEvent(new Event(eventType, datasetId, clientState,
                                selectedDatasetIds, ignoredDatasets,
                                changedFieldIds, changedDatasetIds,
                                manuallyFilledFieldIds, manuallyFilledDatasetIds,
                                detectedFieldIds, detectedFieldClassifications,
                                saveDialogNotShowReason));
                                saveDialogNotShowReason, uiType));
                    }
                    return selection;
                }
+9 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.autofill;

import static android.service.autofill.FillEventHistory.Event.NO_SAVE_UI_REASON_NONE;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.view.autofill.AutofillManager.ACTION_START_SESSION;
import static android.view.autofill.AutofillManager.FLAG_ADD_CLIENT_ENABLED;
@@ -816,12 +818,13 @@ final class AutofillManagerServiceImpl
    /**
     * Updates the last fill response when a dataset is shown.
     */
    void logDatasetShown(int sessionId, @Nullable Bundle clientState) {
    void logDatasetShown(int sessionId, @Nullable Bundle clientState, int presentationType) {
        synchronized (mLock) {
            if (isValidEventLocked("logDatasetShown", sessionId)) {
                mEventHistory.addEvent(
                        new Event(Event.TYPE_DATASETS_SHOWN, null, clientState, null, null, null,
                                null, null, null, null, null));
                                null, null, null, null, null, NO_SAVE_UI_REASON_NONE,
                                presentationType));
            }
        }
    }
@@ -858,9 +861,12 @@ final class AutofillManagerServiceImpl
                    || mAugmentedAutofillEventHistory.getSessionId() != sessionId) {
                return;
            }
            // Augmented Autofill only logs for inline now, so set UI_TYPE_INLINE here.
            // Ideally should not hardcode here and should also log for menu presentation.
            mAugmentedAutofillEventHistory.addEvent(
                    new Event(Event.TYPE_DATASETS_SHOWN, null, clientState, null, null, null,
                            null, null, null, null, null));
                            null, null, null, null, null, NO_SAVE_UI_REASON_NONE,
                            UI_TYPE_INLINE));

        }
    }
+8 −3
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.server.autofill;

import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES;
import static android.service.autofill.AutofillService.EXTRA_FILL_RESPONSE;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_INLINE;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_MENU;
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_SUPPORTS_FILL_DIALOG;
@@ -3290,7 +3293,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
            synchronized (mLock) {
                final ViewState currentView = mViewStates.get(mCurrentViewId);
                currentView.setState(ViewState.STATE_FILL_DIALOG_SHOWN);
                mService.logDatasetShown(id, mClientState);
                mService.logDatasetShown(id, mClientState, UI_TYPE_DIALOG);
            }
            return;
        }
@@ -3304,7 +3307,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                    currentView.setState(ViewState.STATE_INLINE_SHOWN);
                    //TODO(b/137800469): Fix it to log showed only when IME asks for inflation,
                    // rather than here where framework sends back the response.
                    mService.logDatasetShown(id, mClientState);
                    mService.logDatasetShown(id, mClientState, UI_TYPE_INLINE);
                    return;
                }
            }
@@ -3314,7 +3317,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                mService.getServicePackageName(), mComponentName,
                targetLabel, targetIcon, this, id, mCompatMode);

        mService.logDatasetShown(id, mClientState);
        synchronized (mLock) {
            mService.logDatasetShown(id, mClientState, UI_TYPE_MENU);
        }

        synchronized (mLock) {
            if (mUiShownTime == 0) {