Revert "Revert "Add Autofill PCC Detection APIs for Autofill Pro..."
Revert submission 21336058-revert-21047830-autofill-pcc-apis-MBFYLBLCKB Reason for revert: Reverting the revert with fixes: I36b5ea0d846bc1922ab981910cbe1061bd3a3163 Reverted changes: /q/submissionid:21336058-revert-21047830-autofill-pcc-apis-MBFYLBLCKB Test: None Change-Id: I2bed3f1c859a7461e0f232f3797d6d0ec922f129
This commit is contained in:
@@ -39475,6 +39475,7 @@ package android.service.autofill {
|
||||
method @NonNull public android.service.autofill.Dataset build();
|
||||
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 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);
|
||||
@@ -39583,6 +39584,7 @@ package android.service.autofill {
|
||||
method @Nullable public android.content.IntentSender getDelayedFillIntentSender();
|
||||
method @NonNull public java.util.List<android.service.autofill.FillContext> getFillContexts();
|
||||
method public int getFlags();
|
||||
method @NonNull public java.util.List<java.lang.String> getHints();
|
||||
method public int getId();
|
||||
method @Nullable public android.view.inputmethod.InlineSuggestionsRequest getInlineSuggestionsRequest();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
|
||||
@@ -2529,6 +2529,7 @@ package android.service.autofill {
|
||||
|
||||
public final class Dataset implements android.os.Parcelable {
|
||||
method @Nullable public android.content.IntentSender getAuthentication();
|
||||
method @Nullable public java.util.ArrayList<java.lang.String> getAutofillDatatypes();
|
||||
method @Nullable public android.content.ClipData getFieldContent();
|
||||
method @Nullable public java.util.ArrayList<android.view.autofill.AutofillId> getFieldIds();
|
||||
method @Nullable public java.util.ArrayList<android.view.autofill.AutofillValue> getFieldValues();
|
||||
@@ -3279,6 +3280,7 @@ package android.view.autofill {
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_IGNORE_VIEWS = "autofill_credential_manager_ignore_views";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED = "autofill_dialog_enabled";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED = "pcc_classification_enabled";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS = "pcc_classification_hints";
|
||||
field public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES = "smart_suggestion_supported_modes";
|
||||
field public static final String DEVICE_CONFIG_NON_AUTOFILLABLE_IME_ACTION_IDS = "non_autofillable_ime_action_ids";
|
||||
field public static final String DEVICE_CONFIG_PACKAGE_DENYLIST_FOR_UNIMPORTANT_VIEW = "package_deny_list_for_unimportant_view";
|
||||
|
||||
@@ -120,6 +120,8 @@ public final class Dataset implements Parcelable {
|
||||
private final ArrayList<InlinePresentation> mFieldInlinePresentations;
|
||||
private final ArrayList<InlinePresentation> mFieldInlineTooltipPresentations;
|
||||
private final ArrayList<DatasetFieldFilter> mFieldFilters;
|
||||
private final ArrayList<String> mAutofillDatatypes;
|
||||
|
||||
@Nullable private final ClipData mFieldContent;
|
||||
private final RemoteViews mPresentation;
|
||||
private final RemoteViews mDialogPresentation;
|
||||
@@ -143,6 +145,14 @@ public final class Dataset implements Parcelable {
|
||||
mInlineTooltipPresentation = builder.mInlineTooltipPresentation;
|
||||
mAuthentication = builder.mAuthentication;
|
||||
mId = builder.mId;
|
||||
mAutofillDatatypes = builder.mAutofillDatatypes;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@TestApi
|
||||
@SuppressLint({"ConcreteCollection", "NullableCollection"})
|
||||
public @Nullable ArrayList<String> getAutofillDatatypes() {
|
||||
return mAutofillDatatypes;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -293,6 +303,7 @@ public final class Dataset implements Parcelable {
|
||||
private ArrayList<InlinePresentation> mFieldInlinePresentations;
|
||||
private ArrayList<InlinePresentation> mFieldInlineTooltipPresentations;
|
||||
private ArrayList<DatasetFieldFilter> mFieldFilters;
|
||||
private ArrayList<String> mAutofillDatatypes;
|
||||
@Nullable private ClipData mFieldContent;
|
||||
private RemoteViews mPresentation;
|
||||
private RemoteViews mDialogPresentation;
|
||||
@@ -921,6 +932,55 @@ public final class Dataset implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a field to this Dataset with a specific type and no
|
||||
* AutofillId. This is used to send back Field information
|
||||
* when Autofilling with platform detections is on.
|
||||
* Platform detections are on when receiving a populated list from
|
||||
* FillRequest#getHints().
|
||||
*
|
||||
* Populate every field/type known for this user for this app.
|
||||
*
|
||||
* For example, if getHints() contains "username" and "password",
|
||||
* a new Dataset should be created that calls this method twice,
|
||||
* one for the username, then another for the password (assuming
|
||||
* the only one credential pair is found for the user). If a user
|
||||
* has two credential pairs, then two Datasets should be created,
|
||||
* and so on.
|
||||
*
|
||||
* Using this will remove any data populated with
|
||||
* setField(@NonNull AutofillId id, @Nullable Field field).
|
||||
*
|
||||
* @param hint An autofill hint returned from {@link
|
||||
* 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 setField(
|
||||
@NonNull String hint, @NonNull Field field) {
|
||||
throwIfDestroyed();
|
||||
|
||||
final DatasetFieldFilter filter = field.getDatasetFieldFilter();
|
||||
final Presentations presentations = field.getPresentations();
|
||||
if (presentations == null) {
|
||||
setLifeTheUniverseAndEverything(hint, field.getValue(), null, null, null,
|
||||
filter, null);
|
||||
} else {
|
||||
setLifeTheUniverseAndEverything(hint, field.getValue(),
|
||||
presentations.getMenuPresentation(),
|
||||
presentations.getInlinePresentation(),
|
||||
presentations.getInlineTooltipPresentation(), filter,
|
||||
presentations.getDialogPresentation());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a field with an <a href="#Filtering">explicit filter</a>, and using an
|
||||
* {@link InlinePresentation} to visualize it as an inline suggestion.
|
||||
@@ -958,6 +1018,32 @@ public final class Dataset implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
private void setLifeTheUniverseAndEverything(String datatype,
|
||||
@Nullable AutofillValue value,
|
||||
@Nullable RemoteViews presentation,
|
||||
@Nullable InlinePresentation inlinePresentation,
|
||||
@Nullable InlinePresentation tooltip,
|
||||
@Nullable DatasetFieldFilter filter,
|
||||
@Nullable RemoteViews dialogPresentation) {
|
||||
if (mAutofillDatatypes == null) {
|
||||
mFieldValues = new ArrayList<>();
|
||||
mFieldPresentations = new ArrayList<>();
|
||||
mFieldDialogPresentations = new ArrayList<>();
|
||||
mFieldInlinePresentations = new ArrayList<>();
|
||||
mFieldInlineTooltipPresentations = new ArrayList<>();
|
||||
mFieldFilters = new ArrayList<>();
|
||||
mAutofillDatatypes = new ArrayList<>();
|
||||
mFieldIds = null;
|
||||
}
|
||||
mFieldValues.add(value);
|
||||
mFieldPresentations.add(presentation);
|
||||
mFieldDialogPresentations.add(dialogPresentation);
|
||||
mFieldInlinePresentations.add(inlinePresentation);
|
||||
mFieldInlineTooltipPresentations.add(tooltip);
|
||||
mFieldFilters.add(filter);
|
||||
mAutofillDatatypes.add(datatype);
|
||||
}
|
||||
|
||||
private void setLifeTheUniverseAndEverything(@NonNull AutofillId id,
|
||||
@Nullable AutofillValue value, @Nullable RemoteViews presentation,
|
||||
@Nullable InlinePresentation inlinePresentation,
|
||||
@@ -984,6 +1070,7 @@ public final class Dataset implements Parcelable {
|
||||
mFieldInlinePresentations = new ArrayList<>();
|
||||
mFieldInlineTooltipPresentations = new ArrayList<>();
|
||||
mFieldFilters = new ArrayList<>();
|
||||
mAutofillDatatypes = null;
|
||||
}
|
||||
mFieldIds.add(id);
|
||||
mFieldValues.add(value);
|
||||
@@ -1007,9 +1094,14 @@ public final class Dataset implements Parcelable {
|
||||
public @NonNull Dataset build() {
|
||||
throwIfDestroyed();
|
||||
mDestroyed = true;
|
||||
if (mFieldIds == null) {
|
||||
if (mFieldIds == null && mAutofillDatatypes == null) {
|
||||
throw new IllegalStateException("at least one value must be set");
|
||||
}
|
||||
if (mFieldIds != null && mAutofillDatatypes != null) {
|
||||
if (mFieldIds.size() > 0 && mAutofillDatatypes.size() > 0) {
|
||||
throw new IllegalStateException("both field and datatype were populated");
|
||||
}
|
||||
}
|
||||
if (mFieldContent != null) {
|
||||
if (mFieldIds.size() > 1) {
|
||||
throw new IllegalStateException(
|
||||
@@ -1051,6 +1143,7 @@ public final class Dataset implements Parcelable {
|
||||
parcel.writeTypedList(mFieldInlinePresentations, flags);
|
||||
parcel.writeTypedList(mFieldInlineTooltipPresentations, flags);
|
||||
parcel.writeTypedList(mFieldFilters, flags);
|
||||
parcel.writeStringList(mAutofillDatatypes);
|
||||
parcel.writeParcelable(mFieldContent, flags);
|
||||
parcel.writeParcelable(mAuthentication, flags);
|
||||
parcel.writeString(mId);
|
||||
@@ -1081,6 +1174,8 @@ public final class Dataset implements Parcelable {
|
||||
parcel.createTypedArrayList(InlinePresentation.CREATOR);
|
||||
final ArrayList<DatasetFieldFilter> filters =
|
||||
parcel.createTypedArrayList(DatasetFieldFilter.CREATOR);
|
||||
final ArrayList<String> datatypes =
|
||||
parcel.createStringArrayList();
|
||||
final ClipData fieldContent = parcel.readParcelable(null,
|
||||
android.content.ClipData.class);
|
||||
final IntentSender authentication = parcel.readParcelable(null,
|
||||
@@ -1114,19 +1209,37 @@ public final class Dataset implements Parcelable {
|
||||
builder.setContent(ids.get(0), fieldContent);
|
||||
}
|
||||
final int inlinePresentationsSize = inlinePresentations.size();
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
final AutofillId id = ids.get(i);
|
||||
final AutofillValue value = values.get(i);
|
||||
final RemoteViews fieldPresentation = presentations.get(i);
|
||||
final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
|
||||
final InlinePresentation fieldInlinePresentation =
|
||||
i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
|
||||
final InlinePresentation fieldInlineTooltipPresentation =
|
||||
i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
|
||||
final DatasetFieldFilter filter = filters.get(i);
|
||||
builder.setLifeTheUniverseAndEverything(id, value, fieldPresentation,
|
||||
fieldInlinePresentation, fieldInlineTooltipPresentation, filter,
|
||||
fieldDialogPresentation);
|
||||
|
||||
if (ids.size() == 0 && datatypes.size() > 0) {
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
final String datatype = datatypes.get(i);
|
||||
final AutofillValue value = values.get(i);
|
||||
final RemoteViews fieldPresentation = presentations.get(i);
|
||||
final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
|
||||
final InlinePresentation fieldInlinePresentation =
|
||||
i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
|
||||
final InlinePresentation fieldInlineTooltipPresentation =
|
||||
i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
|
||||
final DatasetFieldFilter filter = filters.get(i);
|
||||
builder.setLifeTheUniverseAndEverything(
|
||||
datatype, value, fieldPresentation, fieldInlinePresentation,
|
||||
fieldInlineTooltipPresentation, filter, fieldDialogPresentation);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
final AutofillId id = ids.get(i);
|
||||
final AutofillValue value = values.get(i);
|
||||
final RemoteViews fieldPresentation = presentations.get(i);
|
||||
final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
|
||||
final InlinePresentation fieldInlinePresentation =
|
||||
i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
|
||||
final InlinePresentation fieldInlineTooltipPresentation =
|
||||
i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
|
||||
final DatasetFieldFilter filter = filters.get(i);
|
||||
builder.setLifeTheUniverseAndEverything(id, value, fieldPresentation,
|
||||
fieldInlinePresentation, fieldInlineTooltipPresentation, filter,
|
||||
fieldDialogPresentation);
|
||||
}
|
||||
}
|
||||
builder.setAuthentication(authentication);
|
||||
builder.setId(datasetId);
|
||||
|
||||
@@ -140,6 +140,19 @@ public final class FillRequest implements Parcelable {
|
||||
*/
|
||||
private final @NonNull List<FillContext> mFillContexts;
|
||||
|
||||
/**
|
||||
* Sends a list of datatypes for the Autofill Provider.
|
||||
*
|
||||
* If this is populated, Autofill Provider should return data
|
||||
* for the autofill hints requested here,
|
||||
* even though the Autofill Provider may not have detected these types.
|
||||
* The hints would be part of HintConstants:
|
||||
* https://developer.android.com/reference/androidx/autofill/HintConstants
|
||||
*
|
||||
* This is populated if the platform's field detection is enabled.
|
||||
*/
|
||||
private final @NonNull List<String> mHints;
|
||||
|
||||
/**
|
||||
* Gets the latest client state bundle set by the service in a
|
||||
* {@link FillResponse.Builder#setClientState(Bundle) fill response}.
|
||||
@@ -196,6 +209,7 @@ public final class FillRequest implements Parcelable {
|
||||
|
||||
private void onConstructed() {
|
||||
Preconditions.checkCollectionElementsNotNull(mFillContexts, "contexts");
|
||||
Preconditions.checkCollectionElementsNotNull(mHints, "hints");
|
||||
}
|
||||
|
||||
|
||||
@@ -269,6 +283,11 @@ public final class FillRequest implements Parcelable {
|
||||
* <p><b>Note:</b> Starting on Android {@link android.os.Build.VERSION_CODES#Q}, it could also
|
||||
* include contexts from requests whose {@link SaveInfo} had the
|
||||
* {@link SaveInfo#FLAG_DELAY_SAVE} flag.
|
||||
* @param hints
|
||||
* Autofill Provider should return data for the autofill hints requested here,
|
||||
* even though the Autofill Provider may not have detected these types.
|
||||
* The hints would be part of HintConstants:
|
||||
* https://developer.android.com/reference/androidx/autofill/HintConstants
|
||||
* @param clientState
|
||||
* Gets the latest client state bundle set by the service in a
|
||||
* {@link FillResponse.Builder#setClientState(Bundle) fill response}.
|
||||
@@ -312,6 +331,7 @@ public final class FillRequest implements Parcelable {
|
||||
public FillRequest(
|
||||
int id,
|
||||
@NonNull List<FillContext> fillContexts,
|
||||
@NonNull List<String> hints,
|
||||
@Nullable Bundle clientState,
|
||||
@RequestFlags int flags,
|
||||
@Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
|
||||
@@ -320,6 +340,9 @@ public final class FillRequest implements Parcelable {
|
||||
this.mFillContexts = fillContexts;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mFillContexts);
|
||||
this.mHints = hints;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mHints);
|
||||
this.mClientState = clientState;
|
||||
this.mFlags = flags;
|
||||
|
||||
@@ -359,6 +382,17 @@ public final class FillRequest implements Parcelable {
|
||||
return mFillContexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autofill Provider should return data for the autofill hints requested here,
|
||||
* even though the Autofill Provider may not have detected these types.
|
||||
* The hints would be part of HintConstants:
|
||||
* https://developer.android.com/reference/androidx/autofill/HintConstants
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull List<String> getHints() {
|
||||
return mHints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the latest client state bundle set by the service in a
|
||||
* {@link FillResponse.Builder#setClientState(Bundle) fill response}.
|
||||
@@ -433,6 +467,7 @@ public final class FillRequest implements Parcelable {
|
||||
return "FillRequest { " +
|
||||
"id = " + mId + ", " +
|
||||
"fillContexts = " + mFillContexts + ", " +
|
||||
"hints = " + mHints + ", " +
|
||||
"clientState = " + mClientState + ", " +
|
||||
"flags = " + requestFlagsToString(mFlags) + ", " +
|
||||
"inlineSuggestionsRequest = " + mInlineSuggestionsRequest + ", " +
|
||||
@@ -447,12 +482,13 @@ public final class FillRequest implements Parcelable {
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
byte flg = 0;
|
||||
if (mClientState != null) flg |= 0x4;
|
||||
if (mInlineSuggestionsRequest != null) flg |= 0x10;
|
||||
if (mDelayedFillIntentSender != null) flg |= 0x20;
|
||||
if (mClientState != null) flg |= 0x8;
|
||||
if (mInlineSuggestionsRequest != null) flg |= 0x20;
|
||||
if (mDelayedFillIntentSender != null) flg |= 0x40;
|
||||
dest.writeByte(flg);
|
||||
dest.writeInt(mId);
|
||||
dest.writeParcelableList(mFillContexts, flags);
|
||||
dest.writeStringList(mHints);
|
||||
if (mClientState != null) dest.writeBundle(mClientState);
|
||||
dest.writeInt(mFlags);
|
||||
if (mInlineSuggestionsRequest != null) dest.writeTypedObject(mInlineSuggestionsRequest, flags);
|
||||
@@ -474,15 +510,20 @@ public final class FillRequest implements Parcelable {
|
||||
int id = in.readInt();
|
||||
List<FillContext> fillContexts = new ArrayList<>();
|
||||
in.readParcelableList(fillContexts, FillContext.class.getClassLoader());
|
||||
Bundle clientState = (flg & 0x4) == 0 ? null : in.readBundle();
|
||||
List<String> hints = new ArrayList<>();
|
||||
in.readStringList(hints);
|
||||
Bundle clientState = (flg & 0x8) == 0 ? null : in.readBundle();
|
||||
int flags = in.readInt();
|
||||
InlineSuggestionsRequest inlineSuggestionsRequest = (flg & 0x10) == 0 ? null : (InlineSuggestionsRequest) in.readTypedObject(InlineSuggestionsRequest.CREATOR);
|
||||
IntentSender delayedFillIntentSender = (flg & 0x20) == 0 ? null : (IntentSender) in.readTypedObject(IntentSender.CREATOR);
|
||||
InlineSuggestionsRequest inlineSuggestionsRequest = (flg & 0x20) == 0 ? null : (InlineSuggestionsRequest) in.readTypedObject(InlineSuggestionsRequest.CREATOR);
|
||||
IntentSender delayedFillIntentSender = (flg & 0x40) == 0 ? null : (IntentSender) in.readTypedObject(IntentSender.CREATOR);
|
||||
|
||||
this.mId = id;
|
||||
this.mFillContexts = fillContexts;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mFillContexts);
|
||||
this.mHints = hints;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, mHints);
|
||||
this.mClientState = clientState;
|
||||
this.mFlags = flags;
|
||||
|
||||
@@ -517,10 +558,10 @@ public final class FillRequest implements Parcelable {
|
||||
};
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1675460688829L,
|
||||
time = 1675711417112L,
|
||||
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 @android.service.autofill.FillRequest.RequestFlags int FLAG_RESET_FILL_DIALOG_STATE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PCC_DETECTION\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 @android.service.autofill.FillRequest.RequestFlags int FLAG_PCC_DETECTION\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.NonNull java.util.List<java.lang.String> mHints\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() {}
|
||||
|
||||
|
||||
@@ -308,7 +308,7 @@ public final class SaveInfo implements Parcelable {
|
||||
* username field, another for password).
|
||||
*/
|
||||
// TODO(b/113281366): improve documentation: add example, document relationship with other
|
||||
// flagss, etc...
|
||||
// flags, etc...
|
||||
public static final int FLAG_DELAY_SAVE = 0x4;
|
||||
|
||||
/** @hide */
|
||||
@@ -777,17 +777,13 @@ public final class SaveInfo implements Parcelable {
|
||||
/**
|
||||
* Builds a new {@link SaveInfo} instance.
|
||||
*
|
||||
* @throws IllegalStateException if no
|
||||
* {@link #Builder(int, AutofillId[]) required ids},
|
||||
* If no {@link #Builder(int, AutofillId[]) required ids},
|
||||
* or {@link #setOptionalIds(AutofillId[]) optional ids}, or {@link #FLAG_DELAY_SAVE}
|
||||
* were set
|
||||
* were set, Save Dialog will only be triggered if platform detection is enabled, which
|
||||
* is indicated when {@link FillRequest.getHints()} is not empty.
|
||||
*/
|
||||
public SaveInfo build() {
|
||||
throwIfDestroyed();
|
||||
Preconditions.checkState(
|
||||
!ArrayUtils.isEmpty(mRequiredIds) || !ArrayUtils.isEmpty(mOptionalIds)
|
||||
|| (mFlags & FLAG_DELAY_SAVE) != 0,
|
||||
"must have at least one required or optional id or FLAG_DELAYED_SAVE");
|
||||
mDestroyed = true;
|
||||
return new SaveInfo(this);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,12 @@ public class AutofillFeatureFlags {
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED =
|
||||
"autofill_dialog_enabled";
|
||||
|
||||
/**
|
||||
* Indicates that PCC Autofill detection feature is enabled or not.
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS =
|
||||
"pcc_classification_hints";
|
||||
|
||||
/**
|
||||
* Sets the autofill hints allowed list for the fields that can trigger the fill dialog
|
||||
* feature at Activity starting.
|
||||
@@ -178,6 +184,22 @@ public class AutofillFeatureFlags {
|
||||
public static final String DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED =
|
||||
"pcc_classification_enabled";
|
||||
|
||||
/**
|
||||
* Give preference to autofill provider's detection.
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_PREFER_PROVIDER_OVER_PCC = "prefer_provider_over_pcc";
|
||||
|
||||
|
||||
/**
|
||||
* Use data from secondary source if primary not present .
|
||||
* For eg: if we prefer PCC over provider, and PCC detection didn't classify a field, however,
|
||||
* autofill provider did, this flag would decide whether we use that result, and show some
|
||||
* presentation for that particular field.
|
||||
* @hide
|
||||
*/
|
||||
public static final String DEVICE_CONFIG_PCC_USE_FALLBACK = "pcc_use_fallback";
|
||||
|
||||
// END AUTOFILL PCC CLASSIFICATION FLAGS
|
||||
|
||||
|
||||
@@ -190,9 +212,11 @@ public class AutofillFeatureFlags {
|
||||
"autofill_inline_tooltip_first_show_delay";
|
||||
|
||||
private static final String DIALOG_HINTS_DELIMITER = ":";
|
||||
private static final String PCC_HINTS_DELIMITER = ",";
|
||||
|
||||
private static final boolean DEFAULT_HAS_FILL_DIALOG_UI_FEATURE = false;
|
||||
private static final String DEFAULT_FILL_DIALOG_ENABLED_HINTS = "";
|
||||
private static final String DEFAULT_PCC_FEATURE_PROVIDER_HINTS = "";
|
||||
|
||||
|
||||
// CREDENTIAL MANAGER DEFAULTS
|
||||
@@ -206,7 +230,8 @@ public class AutofillFeatureFlags {
|
||||
|
||||
// AUTOFILL PCC CLASSIFICATION FLAGS DEFAULTS
|
||||
// Default for whether the pcc classification is enabled for autofill.
|
||||
private static final boolean DEFAULT_AUTOFILL_PCC_CLASSIFICATION_ENABLED = false;
|
||||
/** @hide */
|
||||
public static final boolean DEFAULT_AUTOFILL_PCC_CLASSIFICATION_ENABLED = false;
|
||||
// END AUTOFILL PCC CLASSIFICATION FLAGS DEFAULTS
|
||||
|
||||
|
||||
@@ -224,6 +249,25 @@ public class AutofillFeatureFlags {
|
||||
DEFAULT_HAS_FILL_DIALOG_UI_FEATURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of datatypes that is supported by framework
|
||||
* detection.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static String[] getTypeHintsForProvider() {
|
||||
final String typeHints = DeviceConfig.getString(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS,
|
||||
DEFAULT_PCC_FEATURE_PROVIDER_HINTS);
|
||||
if (TextUtils.isEmpty(typeHints)) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
return ArrayUtils.filter(typeHints.split(PCC_HINTS_DELIMITER), String[]::new,
|
||||
(str) -> !TextUtils.isEmpty(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets fill dialog enabled hints.
|
||||
*
|
||||
|
||||
@@ -193,6 +193,32 @@ public final class AutofillManagerService
|
||||
|
||||
final AugmentedAutofillState mAugmentedAutofillState = new AugmentedAutofillState();
|
||||
|
||||
/**
|
||||
* Lock used to synchronize access to flags.
|
||||
*/
|
||||
private final Object mFlagLock = new Object();
|
||||
|
||||
// Flag holders for Autofill PCC classification
|
||||
|
||||
@GuardedBy("mFlagLock")
|
||||
private boolean mPccClassificationEnabled;
|
||||
|
||||
@GuardedBy("mFlagLock")
|
||||
private boolean mPccPreferProviderOverPcc;
|
||||
|
||||
@GuardedBy("mFlagLock")
|
||||
private boolean mPccUseFallbackDetection;
|
||||
|
||||
@GuardedBy("mFlagLock")
|
||||
private String mPccProviderHints;
|
||||
|
||||
// Default flag values for Autofill PCC
|
||||
|
||||
private static final String DEFAULT_PCC_FEATURE_PROVIDER_HINTS = "";
|
||||
private static final boolean DEFAULT_PREFER_PROVIDER_OVER_PCC = true;
|
||||
|
||||
private static final boolean DEFAULT_PCC_USE_FALLBACK = true;
|
||||
|
||||
public AutofillManagerService(Context context) {
|
||||
super(context,
|
||||
new SecureSettingsServiceNameResolver(context, Settings.Secure.AUTOFILL_SERVICE),
|
||||
@@ -302,6 +328,10 @@ public final class AutofillManagerService
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_PREFER_PROVIDER_OVER_PCC:
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_PCC_USE_FALLBACK:
|
||||
setDeviceConfigProperties();
|
||||
break;
|
||||
case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES:
|
||||
@@ -579,13 +609,38 @@ public final class AutofillManagerService
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES,
|
||||
AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM);
|
||||
if (verbose) {
|
||||
Slog.v(mTag, "setDeviceConfigProperties(): "
|
||||
Slog.v(mTag, "setDeviceConfigProperties() for AugmentedAutofill: "
|
||||
+ "augmentedIdleTimeout=" + mAugmentedServiceIdleUnbindTimeoutMs
|
||||
+ ", augmentedRequestTimeout=" + mAugmentedServiceRequestTimeoutMs
|
||||
+ ", smartSuggestionMode="
|
||||
+ getSmartSuggestionModeToString(mSupportedSmartSuggestionModes));
|
||||
}
|
||||
}
|
||||
synchronized (mFlagLock) {
|
||||
mPccClassificationEnabled = DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED,
|
||||
AutofillFeatureFlags.DEFAULT_AUTOFILL_PCC_CLASSIFICATION_ENABLED);
|
||||
mPccPreferProviderOverPcc = DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_PREFER_PROVIDER_OVER_PCC,
|
||||
DEFAULT_PREFER_PROVIDER_OVER_PCC);
|
||||
mPccUseFallbackDetection = DeviceConfig.getBoolean(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_PCC_USE_FALLBACK,
|
||||
DEFAULT_PCC_USE_FALLBACK);
|
||||
mPccProviderHints = DeviceConfig.getString(
|
||||
DeviceConfig.NAMESPACE_AUTOFILL,
|
||||
AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS,
|
||||
DEFAULT_PCC_FEATURE_PROVIDER_HINTS);
|
||||
if (verbose) {
|
||||
Slog.v(mTag, "setDeviceConfigProperties() for PCC: "
|
||||
+ "mPccClassificationEnabled=" + mPccClassificationEnabled
|
||||
+ ", mPccPreferProviderOverPcc=" + mPccPreferProviderOverPcc
|
||||
+ ", mPccUseFallbackDetection=" + mPccUseFallbackDetection
|
||||
+ ", mPccProviderHints=" + mPccProviderHints);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCachedServices() {
|
||||
@@ -791,6 +846,46 @@ public final class AutofillManagerService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the Autofill PCC Classification feature is enabled.
|
||||
*/
|
||||
public boolean isPccClassificationEnabled() {
|
||||
synchronized (mFlagLock) {
|
||||
return mPccClassificationEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the Autofill Provider shouldbe preferred over PCC results for selecting datasets.
|
||||
*/
|
||||
public boolean preferProviderOverPcc() {
|
||||
synchronized (mFlagLock) {
|
||||
return mPccPreferProviderOverPcc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use the fallback for detection.
|
||||
* If true, use data from secondary source if primary not present .
|
||||
* For eg: if we prefer PCC over provider, and PCC detection didn't classify a field, however,
|
||||
* autofill provider did, this flag would decide whether we use that result, and show some
|
||||
* presentation for that particular field.
|
||||
*/
|
||||
public boolean shouldUsePccFallback() {
|
||||
synchronized (mFlagLock) {
|
||||
return mPccUseFallbackDetection;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides Autofill Hints that would be requested by the service from the Autofill Provider.
|
||||
*/
|
||||
public String getPccProviderHints() {
|
||||
synchronized (mFlagLock) {
|
||||
return mPccProviderHints;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@VisibleForTesting
|
||||
static Map<String, String[]> getAllowedCompatModePackages(String setting) {
|
||||
|
||||
@@ -170,6 +170,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
"android.service.autofill.action.DELAYED_FILL";
|
||||
private static final String EXTRA_REQUEST_ID = "android.service.autofill.extra.REQUEST_ID";
|
||||
|
||||
private static final String PCC_HINTS_DELIMITER = ",";
|
||||
|
||||
final Object mLock;
|
||||
|
||||
private final AutofillManagerServiceImpl mService;
|
||||
@@ -564,6 +566,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
if (mPendingInlineSuggestionsRequest.isServiceSupported()) {
|
||||
mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
|
||||
mPendingFillRequest.getFillContexts(),
|
||||
mPendingFillRequest.getHints(),
|
||||
mPendingFillRequest.getClientState(),
|
||||
mPendingFillRequest.getFlags(),
|
||||
mPendingInlineSuggestionsRequest,
|
||||
@@ -672,8 +675,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
|
||||
final ArrayList<FillContext> contexts =
|
||||
mergePreviousSessionLocked(/* forSave= */ false);
|
||||
final List<String> hints = getTypeHintsForProvider();
|
||||
|
||||
mDelayedFillPendingIntent = createPendingIntent(requestId);
|
||||
request = new FillRequest(requestId, contexts, mClientState, flags,
|
||||
request = new FillRequest(requestId, contexts, hints, mClientState, flags,
|
||||
/*inlineSuggestionsRequest=*/ null,
|
||||
/*delayedFillIntentSender=*/ mDelayedFillPendingIntent == null
|
||||
? null
|
||||
@@ -704,6 +709,22 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of valid autofill hint types from Device flags
|
||||
* Returns empty list if PCC is off or no types available
|
||||
*/
|
||||
private List<String> getTypeHintsForProvider() {
|
||||
if (!mService.getMaster().isPccClassificationEnabled()) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
final String typeHints = mService.getMaster().getPccProviderHints();
|
||||
if (TextUtils.isEmpty(typeHints)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return List.of(typeHints.split(PCC_HINTS_DELIMITER));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assist Data Receiver for PCC
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user