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

Commit 24604a3a authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "New Autofill API: TYPE_CONTEXT_COMMITTED events."

parents bbe20b0d 59c44640
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -37283,10 +37283,15 @@ package android.service.autofill {
  }
  public static final class FillEventHistory.Event {
    method public java.util.Map<android.view.autofill.AutofillId, java.lang.String> getChangedFields();
    method public android.os.Bundle getClientState();
    method public java.lang.String getDatasetId();
    method public java.util.Set<java.lang.String> getIgnoredDatasetIds();
    method public java.util.Map<android.view.autofill.AutofillId, java.util.Set<java.lang.String>> getManuallyEnteredField();
    method public java.util.Set<java.lang.String> getSelectedDatasetIds();
    method public int getType();
    field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
    field public static final int TYPE_CONTEXT_COMMITTED = 4; // 0x4
    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
@@ -37307,6 +37312,7 @@ package android.service.autofill {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.service.autofill.FillResponse> CREATOR;
    field public static final int FLAG_TRACK_CONTEXT_COMMITED = 1; // 0x1
  }
  public static final class FillResponse.Builder {
@@ -37315,6 +37321,7 @@ package android.service.autofill {
    method public android.service.autofill.FillResponse build();
    method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
    method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
    method public android.service.autofill.FillResponse.Builder setFlags(int);
    method public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
    method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
  }
@@ -52062,6 +52069,7 @@ package android.widget {
    method public android.graphics.Typeface getTypeface();
    method public android.text.style.URLSpan[] getUrls();
    method public boolean hasSelection();
    method public void invalidate(int, int, int, int);
    method public boolean isAllCaps();
    method public boolean isCursorVisible();
    method public boolean isElegantTextHeight();
+8 −0
Original line number Diff line number Diff line
@@ -40385,10 +40385,15 @@ package android.service.autofill {
  }
  public static final class FillEventHistory.Event {
    method public java.util.Map<android.view.autofill.AutofillId, java.lang.String> getChangedFields();
    method public android.os.Bundle getClientState();
    method public java.lang.String getDatasetId();
    method public java.util.Set<java.lang.String> getIgnoredDatasetIds();
    method public java.util.Map<android.view.autofill.AutofillId, java.util.Set<java.lang.String>> getManuallyEnteredField();
    method public java.util.Set<java.lang.String> getSelectedDatasetIds();
    method public int getType();
    field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
    field public static final int TYPE_CONTEXT_COMMITTED = 4; // 0x4
    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
@@ -40409,6 +40414,7 @@ package android.service.autofill {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.service.autofill.FillResponse> CREATOR;
    field public static final int FLAG_TRACK_CONTEXT_COMMITED = 1; // 0x1
  }
  public static final class FillResponse.Builder {
@@ -40417,6 +40423,7 @@ package android.service.autofill {
    method public android.service.autofill.FillResponse build();
    method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
    method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
    method public android.service.autofill.FillResponse.Builder setFlags(int);
    method public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
    method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
  }
@@ -56165,6 +56172,7 @@ package android.widget {
    method public android.graphics.Typeface getTypeface();
    method public android.text.style.URLSpan[] getUrls();
    method public boolean hasSelection();
    method public void invalidate(int, int, int, int);
    method public boolean isAllCaps();
    method public boolean isCursorVisible();
    method public boolean isElegantTextHeight();
+8 −0
Original line number Diff line number Diff line
@@ -37575,10 +37575,15 @@ package android.service.autofill {
  }
  public static final class FillEventHistory.Event {
    method public java.util.Map<android.view.autofill.AutofillId, java.lang.String> getChangedFields();
    method public android.os.Bundle getClientState();
    method public java.lang.String getDatasetId();
    method public java.util.Set<java.lang.String> getIgnoredDatasetIds();
    method public java.util.Map<android.view.autofill.AutofillId, java.util.Set<java.lang.String>> getManuallyEnteredField();
    method public java.util.Set<java.lang.String> getSelectedDatasetIds();
    method public int getType();
    field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
    field public static final int TYPE_CONTEXT_COMMITTED = 4; // 0x4
    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
@@ -37599,6 +37604,7 @@ package android.service.autofill {
    method public int describeContents();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.service.autofill.FillResponse> CREATOR;
    field public static final int FLAG_TRACK_CONTEXT_COMMITED = 1; // 0x1
  }
  public static final class FillResponse.Builder {
@@ -37607,6 +37613,7 @@ package android.service.autofill {
    method public android.service.autofill.FillResponse build();
    method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
    method public android.service.autofill.FillResponse.Builder setClientState(android.os.Bundle);
    method public android.service.autofill.FillResponse.Builder setFlags(int);
    method public android.service.autofill.FillResponse.Builder setIgnoredIds(android.view.autofill.AutofillId...);
    method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
  }
@@ -52670,6 +52677,7 @@ package android.widget {
    method public android.graphics.Typeface getTypeface();
    method public android.text.style.URLSpan[] getUrls();
    method public boolean hasSelection();
    method public void invalidate(int, int, int, int);
    method public boolean isAllCaps();
    method public boolean isCursorVisible();
    method public boolean isElegantTextHeight();
+272 −11
Original line number Diff line number Diff line
@@ -17,19 +17,27 @@
package android.service.autofill;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.IntentSender;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;

import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Describes what happened after the last
@@ -136,9 +144,21 @@ public final class FillEventHistory implements Parcelable {
            int numEvents = mEvents.size();
            for (int i = 0; i < numEvents; i++) {
                Event event = mEvents.get(i);
                dest.writeInt(event.getType());
                dest.writeString(event.getDatasetId());
                dest.writeBundle(event.getClientState());
                dest.writeInt(event.mEventType);
                dest.writeString(event.mDatasetId);
                dest.writeBundle(event.mClientState);
                dest.writeStringList(event.mSelectedDatasetIds);
                dest.writeArraySet(event.mIgnoredDatasetIds);
                dest.writeTypedList(event.mChangedFieldIds);
                dest.writeStringList(event.mChangedDatasetIds);

                dest.writeTypedList(event.mManuallyFilledFieldIds);
                if (event.mManuallyFilledFieldIds != null) {
                    final int size = event.mManuallyFilledFieldIds.size();
                    for (int j = 0; j < size; j++) {
                        dest.writeStringList(event.mManuallyFilledDatasetIds.get(j));
                    }
                }
            }
        }
    }
@@ -176,12 +196,40 @@ public final class FillEventHistory implements Parcelable {
        /** A save UI was shown. */
        public static final int TYPE_SAVE_SHOWN = 3;

        /**
         * A committed autofill context for which the autofill service provided datasets.
         *
         * <p>This event is useful to track:
         * <ul>
         *   <li>Which datasets (if any) were selected by the user
         *       ({@link #getSelectedDatasetIds()}).
         *   <li>Which datasets (if any) were NOT selected by the user
         *       ({@link #getIgnoredDatasetIds()}).
         *   <li>Which fields in the selected datasets were changed by the user after the dataset
         *       was selected ({@link #getChangedFields()}.
         * </ul>
         *
         * <p><b>Note: </b>This event is only generated when:
         * <ul>
         *   <li>The autofill context is committed.
         *   <li>The service provides at least one dataset in the
         *       {@link FillResponse fill responses} associated with the context.
         *   <li>The last {@link FillResponse fill responses} associated with the context has the
         *       {@link FillResponse#FLAG_TRACK_CONTEXT_COMMITED} flag.
         * </ul>
         *
         * <p>See {@link android.view.autofill.AutofillManager} for more information about autofill
         * contexts.
         */
        public static final int TYPE_CONTEXT_COMMITTED = 4;

        /** @hide */
        @IntDef(
                value = {TYPE_DATASET_SELECTED,
                        TYPE_DATASET_AUTHENTICATION_SELECTED,
                        TYPE_AUTHENTICATION_SELECTED,
                        TYPE_SAVE_SHOWN})
                        TYPE_SAVE_SHOWN,
                        TYPE_CONTEXT_COMMITTED})
        @Retention(RetentionPolicy.SOURCE)
        @interface EventIds{}

@@ -189,6 +237,17 @@ public final class FillEventHistory implements Parcelable {
        @Nullable private final String mDatasetId;
        @Nullable private final Bundle mClientState;

        // Note: mSelectedDatasetIds is stored as List<> instead of Set because Session already
        // stores it as List
        @Nullable private final List<String> mSelectedDatasetIds;
        @Nullable private final ArraySet<String> mIgnoredDatasetIds;

        @Nullable private final ArrayList<AutofillId> mChangedFieldIds;
        @Nullable private final ArrayList<String> mChangedDatasetIds;

        @Nullable private final ArrayList<AutofillId> mManuallyFilledFieldIds;
        @Nullable private final ArrayList<ArrayList<String>> mManuallyFilledDatasetIds;

        /**
         * Returns the type of the event.
         *
@@ -219,6 +278,137 @@ public final class FillEventHistory implements Parcelable {
            return mClientState;
        }

        /**
         * Returns which datasets were selected by the user.
         *
         * <p><b>Note: </b>Only set on events of type {@link #TYPE_CONTEXT_COMMITTED}.
         */
        @NonNull public Set<String> getSelectedDatasetIds() {
            return mSelectedDatasetIds == null ? Collections.emptySet()
                    : new ArraySet<>(mSelectedDatasetIds);
        }

        /**
         * Returns which datasets were NOT selected by the user.
         *
         * <p><b>Note: </b>Only set on events of type {@link #TYPE_CONTEXT_COMMITTED}.
         */
        @NonNull public Set<String> getIgnoredDatasetIds() {
            return mIgnoredDatasetIds == null ? Collections.emptySet() : mIgnoredDatasetIds;
        }

        /**
         * Returns which fields in the selected datasets were changed by the user after the dataset
         * was selected.
         *
         * <p>For example, server provides:
         *
         * <pre class="prettyprint">
         *  FillResponse response = new FillResponse.Builder()
         *      .addDataset(new Dataset.Builder(presentation1)
         *          .setId("4815")
         *          .setValue(usernameId, AutofillValue.forText("MrPlow"))
         *          .build())
         *      .addDataset(new Dataset.Builder(presentation2)
         *          .setId("162342")
         *          .setValue(passwordId, AutofillValue.forText("D'OH"))
         *          .build())
         *      .build();
         * </pre>
         *
         * <p>User select both datasets (for username and password) but after the fields are
         * autofilled, user changes them to:
         *
         * <pre class="prettyprint">
         *   username = "ElBarto";
         *   password = "AyCaramba";
         * </pre>
         *
         * <p>Then the result is the following map:
         *
         * <pre class="prettyprint">
         *   usernameId => "4815"
         *   passwordId => "162342"
         * </pre>
         *
         * <p><b>Note: </b>Only set on events of type {@link #TYPE_CONTEXT_COMMITTED}.
         *
         * @return map map whose key is the id of the change fields, and value is the id of
         * dataset that has that field and was selected by the user.
         */
        @NonNull public Map<AutofillId, String> getChangedFields() {
            if (mChangedFieldIds == null || mChangedDatasetIds == null) {
                return Collections.emptyMap();
            }

            final int size = mChangedFieldIds.size();
            final ArrayMap<AutofillId, String> changedFields = new ArrayMap<>(size);
            for (int i = 0; i < size; i++) {
                changedFields.put(mChangedFieldIds.get(i), mChangedDatasetIds.get(i));
            }
            return changedFields;
        }

        /**
         * Returns which fields were available on datasets provided by the service but manually
         * entered by the user.
         *
         * <p>For example, server provides:
         *
         * <pre class="prettyprint">
         *  FillResponse response = new FillResponse.Builder()
         *      .addDataset(new Dataset.Builder(presentation1)
         *          .setId("4815")
         *          .setValue(usernameId, AutofillValue.forText("MrPlow"))
         *          .setValue(passwordId, AutofillValue.forText("AyCaramba"))
         *          .build())
         *      .addDataset(new Dataset.Builder(presentation2)
         *          .setId("162342")
         *          .setValue(usernameId, AutofillValue.forText("ElBarto"))
         *          .setValue(passwordId, AutofillValue.forText("D'OH"))
         *          .build())
         *      .addDataset(new Dataset.Builder(presentation3)
         *          .setId("108")
         *          .setValue(usernameId, AutofillValue.forText("MrPlow"))
         *          .setValue(passwordId, AutofillValue.forText("D'OH"))
         *          .build())
         *      .build();
         * </pre>
         *
         * <p>User doesn't select a dataset but manually enters:
         *
         * <pre class="prettyprint">
         *   username = "MrPlow";
         *   password = "D'OH";
         * </pre>
         *
         * <p>Then the result is the following map:
         *
         * <pre class="prettyprint">
         *   usernameId => { "4815", "108"}
         *   passwordId => { "162342", "108" }
         * </pre>
         *
         * <p><b>Note: </b>Only set on events of type {@link #TYPE_CONTEXT_COMMITTED}.
         *
         * @return map map whose key is the id of the manually-entered field, and value is the
         * ids of the datasets that have that value but were not selected by the user.
         */
        @Nullable public Map<AutofillId, Set<String>> getManuallyEnteredField() {
            if (mManuallyFilledFieldIds == null || mManuallyFilledDatasetIds == null) {
                return Collections.emptyMap();
            }

            final int size = mManuallyFilledFieldIds.size();
            final Map<AutofillId, Set<String>> manuallyFilledFields = new ArrayMap<>(size);
            for (int i = 0; i < size; i++) {
                final AutofillId fieldId = mManuallyFilledFieldIds.get(i);
                final ArrayList<String> datasetIds = mManuallyFilledDatasetIds.get(i);
                manuallyFilledFields.put(fieldId, new ArraySet<>(datasetIds));
            }
            return manuallyFilledFields;
        }

        /**
         * Creates a new event.
         *
@@ -226,19 +416,65 @@ public final class FillEventHistory implements Parcelable {
         * @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}.
         *
         * @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) {
            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_SAVE_SHOWN,
        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) {
            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_CONTEXT_COMMITTED,
                    "eventType");
            mDatasetId = datasetId;
            mClientState = clientState;
            mSelectedDatasetIds = selectedDatasetIds;
            mIgnoredDatasetIds = ignoredDatasetIds;
            if (changedFieldIds != null) {
                Preconditions.checkArgument(!ArrayUtils.isEmpty(changedFieldIds)
                        && changedDatasetIds != null
                        && changedFieldIds.size() == changedDatasetIds.size(),
                        "changed ids must have same length and not be empty");
            }
            mChangedFieldIds = changedFieldIds;
            mChangedDatasetIds = changedDatasetIds;
            if (manuallyFilledFieldIds != null) {
                Preconditions.checkArgument(!ArrayUtils.isEmpty(manuallyFilledFieldIds)
                        && manuallyFilledDatasetIds != null
                        && manuallyFilledFieldIds.size() == manuallyFilledDatasetIds.size(),
                        "manually filled ids must have same length and not be empty");
            }
            mManuallyFilledFieldIds = manuallyFilledFieldIds;
            mManuallyFilledDatasetIds = manuallyFilledDatasetIds;
        }

        @Override
        public String toString() {
            return "FillEvent [datasetId=" + mDatasetId + ", type=" + mEventType + "]";
            return "FillEvent [datasetId=" + mDatasetId
                    + ", type=" + mEventType
                    + ", selectedDatasets=" + mSelectedDatasetIds
                    + ", ignoredDatasetIds=" + mIgnoredDatasetIds
                    + ", changedFieldIds=" + mChangedFieldIds
                    + ", changedDatasetsIds=" + mChangedDatasetIds
                    + ", manuallyFilledFieldIds=" + mManuallyFilledFieldIds
                    + ", manuallyFilledDatasetIds=" + mManuallyFilledDatasetIds
                    + "]";
        }
    }

@@ -248,12 +484,37 @@ public final class FillEventHistory implements Parcelable {
                public FillEventHistory createFromParcel(Parcel parcel) {
                    FillEventHistory selection = new FillEventHistory(0, 0, parcel.readBundle());

                    int numEvents = parcel.readInt();
                    final int numEvents = parcel.readInt();
                    for (int i = 0; i < numEvents; i++) {
                        selection.addEvent(new Event(parcel.readInt(), parcel.readString(),
                                parcel.readBundle()));
                        final int eventType = parcel.readInt();
                        final String datasetId = parcel.readString();
                        final Bundle clientState = parcel.readBundle();
                        final ArrayList<String> selectedDatasetIds = parcel.createStringArrayList();
                        @SuppressWarnings("unchecked")
                        final ArraySet<String> ignoredDatasets =
                                (ArraySet<String>) parcel.readArraySet(null);
                        final ArrayList<AutofillId> changedFieldIds =
                                parcel.createTypedArrayList(AutofillId.CREATOR);
                        final ArrayList<String> changedDatasetIds = parcel.createStringArrayList();

                        final ArrayList<AutofillId> manuallyFilledFieldIds =
                                parcel.createTypedArrayList(AutofillId.CREATOR);
                        final ArrayList<ArrayList<String>> manuallyFilledDatasetIds;
                        if (manuallyFilledFieldIds != null) {
                            final int size = manuallyFilledFieldIds.size();
                            manuallyFilledDatasetIds = new ArrayList<>(size);
                            for (int j = 0; j < size; j++) {
                                manuallyFilledDatasetIds.add(parcel.createStringArrayList());
                            }
                        } else {
                            manuallyFilledDatasetIds = null;
                        }

                        selection.addEvent(new Event(eventType, datasetId, clientState,
                                selectedDatasetIds, ignoredDatasets,
                                changedFieldIds, changedDatasetIds,
                                manuallyFilledFieldIds, manuallyFilledDatasetIds));
                    }
                    return selection;
                }

+41 −1

File changed.

Preview size limit exceeded, changes collapsed.

Loading