From 2f1efa1d5d63b9ce9c5ae55510dc7e29327969dd Mon Sep 17 00:00:00 2001 From: Simranjit Kohli Date: Tue, 28 Feb 2023 14:17:39 -0800 Subject: [PATCH] [Autofill PCC]: API for setting all types Introduce API to set field that's applicable to any detection type. In the absence of this, providers would've to set helper hints for all types. Test: atest android.autofillservice.cts.unittests.DatasetTest android.autofillservice.cts.inline.InlineLoginActivityTest android.autofillservice.cts.dropdown.LoginActivityTest android.autofillservice.cts.dialog.LoginActivityTest BUG: 271346008 Change-Id: I1429cd465cf9458f18b7a460557cca2f5b42b582 --- core/api/current.txt | 1 + core/api/test-current.txt | 13 +++++ .../android/service/autofill/Dataset.java | 49 +++++++++++++++---- .../view/autofill/AutofillManager.java | 8 +++ 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 2db3eae5fab6c..604ebbc5cea3f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -39758,6 +39758,7 @@ package android.service.autofill { method @NonNull public android.service.autofill.Dataset.Builder setAuthentication(@Nullable android.content.IntentSender); method @NonNull public android.service.autofill.Dataset.Builder setField(@NonNull android.view.autofill.AutofillId, @Nullable android.service.autofill.Field); method @NonNull public android.service.autofill.Dataset.Builder setField(@NonNull String, @NonNull android.service.autofill.Field); + method @NonNull public android.service.autofill.Dataset.Builder setFieldForAllHints(@NonNull android.service.autofill.Field); method @NonNull public android.service.autofill.Dataset.Builder setId(@Nullable String); method @Deprecated @NonNull public android.service.autofill.Dataset.Builder setInlinePresentation(@NonNull android.service.autofill.InlinePresentation); method @Deprecated @NonNull public android.service.autofill.Dataset.Builder setInlinePresentation(@NonNull android.service.autofill.InlinePresentation, @NonNull android.service.autofill.InlinePresentation); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 43fa6e262a145..03a1f5efe6ca7 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2629,8 +2629,13 @@ package android.service.autofill { method @Nullable public android.content.IntentSender getAuthentication(); method @Nullable public java.util.ArrayList getAutofillDatatypes(); method @Nullable public android.content.ClipData getFieldContent(); + method @Nullable public android.widget.RemoteViews getFieldDialogPresentation(int); method @Nullable public java.util.ArrayList getFieldIds(); + method @Nullable public android.service.autofill.InlinePresentation getFieldInlinePresentation(int); + method @Nullable public android.service.autofill.InlinePresentation getFieldInlineTooltipPresentation(int); + method @Nullable public android.widget.RemoteViews getFieldPresentation(int); method @Nullable public java.util.ArrayList getFieldValues(); + method @Nullable public android.service.autofill.Dataset.DatasetFieldFilter getFilter(int); method @Nullable public String getId(); method public boolean isEmpty(); } @@ -2639,6 +2644,13 @@ package android.service.autofill { method @NonNull public android.service.autofill.Dataset.Builder setContent(@NonNull android.view.autofill.AutofillId, @Nullable android.content.ClipData); } + public static final class Dataset.DatasetFieldFilter implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public java.util.regex.Pattern getPattern(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public final class DateTransformation extends android.service.autofill.InternalTransformation implements android.os.Parcelable android.service.autofill.Transformation { method public void apply(@NonNull android.service.autofill.ValueFinder, @NonNull android.widget.RemoteViews, int) throws java.lang.Exception; } @@ -3418,6 +3430,7 @@ package android.view.autofill { } public final class AutofillManager { + field public static final String ANY_HINT = "any"; field public static final int FLAG_SMART_SUGGESTION_OFF = 0; // 0x0 field public static final int FLAG_SMART_SUGGESTION_SYSTEM = 1; // 0x1 field public static final int MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS = 120000; // 0x1d4c0 diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java index d943bf9ac872b..0ef8bb64acafe 100644 --- a/core/java/android/service/autofill/Dataset.java +++ b/core/java/android/service/autofill/Dataset.java @@ -29,6 +29,7 @@ import android.content.IntentSender; import android.os.Parcel; import android.os.Parcelable; import android.view.autofill.AutofillId; +import android.view.autofill.AutofillManager; import android.view.autofill.AutofillValue; import android.widget.RemoteViews; @@ -283,24 +284,28 @@ public final class Dataset implements Parcelable { } /** @hide */ - public RemoteViews getFieldPresentation(int index) { + @TestApi + public @Nullable RemoteViews getFieldPresentation(int index) { final RemoteViews customPresentation = mFieldPresentations.get(index); return customPresentation != null ? customPresentation : mPresentation; } /** @hide */ - public RemoteViews getFieldDialogPresentation(int index) { + @TestApi + public @Nullable RemoteViews getFieldDialogPresentation(int index) { final RemoteViews customPresentation = mFieldDialogPresentations.get(index); return customPresentation != null ? customPresentation : mDialogPresentation; } /** @hide */ + @TestApi public @Nullable InlinePresentation getFieldInlinePresentation(int index) { final InlinePresentation inlinePresentation = mFieldInlinePresentations.get(index); return inlinePresentation != null ? inlinePresentation : mInlinePresentation; } /** @hide */ + @TestApi public @Nullable InlinePresentation getFieldInlineTooltipPresentation(int index) { final InlinePresentation inlineTooltipPresentation = mFieldInlineTooltipPresentations.get(index); @@ -309,6 +314,7 @@ public final class Dataset implements Parcelable { } /** @hide */ + @TestApi public @Nullable DatasetFieldFilter getFilter(int index) { return mFieldFilters.get(index); } @@ -389,6 +395,9 @@ public final class Dataset implements Parcelable { if (mAuthentication != null) { builder.append(", hasAuthentication"); } + if (mAutofillDatatypes != null) { + builder.append(", autofillDatatypes=").append(mAutofillDatatypes); + } return builder.append(']').toString(); } @@ -1090,8 +1099,7 @@ public final class Dataset implements Parcelable { * * @return this builder. */ - public @NonNull Dataset.Builder setField( - @NonNull String hint, @NonNull Field field) { + public @NonNull Dataset.Builder setField(@NonNull String hint, @NonNull Field field) { throwIfDestroyed(); final DatasetFieldFilter filter = field.getDatasetFieldFilter(); @@ -1110,6 +1118,23 @@ public final class Dataset implements Parcelable { return this; } + /** + * Adds a field to this Dataset that is relevant to all applicable hints. This is used to + * provide field information when autofill with platform detections is enabled. + * Platform detections are on when receiving a populated list from + * FillRequest#getHints(). + * + * @param field the fill information about the field. + * + * @throws IllegalStateException if {@link #build()} was already called + * or this builder also contains AutofillId information + * + * @return this builder. + */ + public @NonNull Dataset.Builder setFieldForAllHints(@NonNull Field field) { + return setField(AutofillManager.ANY_HINT, field); + } + /** * Sets the value of a field with an explicit filter, and using an * {@link InlinePresentation} to visualize it as an inline suggestion. @@ -1304,7 +1329,7 @@ public final class Dataset implements Parcelable { parcel.createTypedArrayList(InlinePresentation.CREATOR); final ArrayList filters = parcel.createTypedArrayList(DatasetFieldFilter.CREATOR); - final ArrayList datatypes = + final ArrayList autofillDatatypes = parcel.createStringArrayList(); final ClipData fieldContent = parcel.readParcelable(null, android.content.ClipData.class); @@ -1341,9 +1366,9 @@ public final class Dataset implements Parcelable { } final int inlinePresentationsSize = inlinePresentations.size(); - if (ids.size() == 0 && datatypes.size() > 0) { - for (int i = 0; i < ids.size(); i++) { - final String datatype = datatypes.get(i); + if (ids.size() == 0 && autofillDatatypes.size() > 0) { + for (int i = 0; i < autofillDatatypes.size(); i++) { + final String datatype = autofillDatatypes.get(i); final AutofillValue value = values.get(i); final RemoteViews fieldPresentation = presentations.get(i); final RemoteViews fieldDialogPresentation = dialogPresentations.get(i); @@ -1393,8 +1418,10 @@ public final class Dataset implements Parcelable { * * @hide */ + @TestApi public static final class DatasetFieldFilter implements Parcelable { + /** @hide */ @Nullable public final Pattern pattern; @@ -1402,6 +1429,10 @@ public final class Dataset implements Parcelable { this.pattern = pattern; } + public @Nullable Pattern getPattern() { + return pattern; + } + @Override public String toString() { if (!sDebug) return super.toString(); @@ -1416,7 +1447,7 @@ public final class Dataset implements Parcelable { } @Override - public void writeToParcel(Parcel parcel, int flags) { + public void writeToParcel(@NonNull Parcel parcel, int flags) { parcel.writeSerializable(pattern); } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index aef0e651ff8dd..ab9f492694f57 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -301,6 +301,14 @@ public final class AutofillManager { public static final String EXTRA_AUGMENTED_AUTOFILL_CLIENT = "android.view.autofill.extra.AUGMENTED_AUTOFILL_CLIENT"; + /** + * Autofill Hint to indicate that it can match any field. + * + * @hide + */ + @TestApi + public static final String ANY_HINT = "any"; + private static final String SESSION_ID_TAG = "android:sessionId"; private static final String STATE_TAG = "android:state"; private static final String LAST_AUTOFILLED_DATA_TAG = "android:lastAutoFilledData";