Loading core/java/android/service/autofill/Dataset.java +6 −1 Original line number Original line Diff line number Diff line Loading @@ -312,7 +312,12 @@ public final class Dataset implements Parcelable { * setting it to the {@link * setting it to the {@link * android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra. If you * android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra. If you * provide a dataset in the result, it will replace the authenticated dataset and * provide a dataset in the result, it will replace the authenticated dataset and * will be immediately filled in. If you provide a response, it will replace the * will be immediately filled in. An exception to this behavior is if the original * dataset represents a pinned inline suggestion (i.e. any of the field in the dataset * has a pinned inline presentation, see {@link InlinePresentation#isPinned()}), then * the original dataset will not be replaced, * so that it can be triggered as a pending intent again. * If you provide a response, it will replace the * current response and the UI will be refreshed. For example, if you provided * current response and the UI will be refreshed. For example, if you provided * credit card information without the CVV for the data set in the {@link FillResponse * credit card information without the CVV for the data set in the {@link FillResponse * response} then the returned data set should contain the CVV entry. * response} then the returned data set should contain the CVV entry. Loading core/java/android/service/autofill/InlinePresentation.java +16 −4 Original line number Original line Diff line number Diff line Loading @@ -50,7 +50,11 @@ public final class InlinePresentation implements Parcelable { /** /** * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * host. * host. However, it's eventually up to the host whether the UI is pinned or not. * * <p> Also a {@link Dataset} with a pinned inline presentation will not be replaced by the * new data set returned from authentication intent. See * {@link Dataset.Builder#setAuthentication(android.content.IntentSender)} for more information. */ */ private final boolean mPinned; private final boolean mPinned; Loading Loading @@ -90,7 +94,11 @@ public final class InlinePresentation implements Parcelable { * Specifies the UI specification for the inline suggestion. * Specifies the UI specification for the inline suggestion. * @param pinned * @param pinned * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * host. * host. However, it's eventually up to the host whether the UI is pinned or not. * * <p> Also a {@link Dataset} with a pinned inline presentation will not be replaced by the * new data set returned from authentication intent. See * {@link Dataset.Builder#setAuthentication(android.content.IntentSender)} for more information. */ */ @DataClass.Generated.Member @DataClass.Generated.Member public InlinePresentation( public InlinePresentation( Loading Loading @@ -126,7 +134,11 @@ public final class InlinePresentation implements Parcelable { /** /** * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * host. * host. However, it's eventually up to the host whether the UI is pinned or not. * * <p> Also a {@link Dataset} with a pinned inline presentation will not be replaced by the * new data set returned from authentication intent. See * {@link Dataset.Builder#setAuthentication(android.content.IntentSender)} for more information. */ */ @DataClass.Generated.Member @DataClass.Generated.Member public boolean isPinned() { public boolean isPinned() { Loading Loading @@ -232,7 +244,7 @@ public final class InlinePresentation implements Parcelable { }; }; @DataClass.Generated( @DataClass.Generated( time = 1586992400667L, time = 1593131904745L, codegenVersion = "1.0.15", codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/service/autofill/InlinePresentation.java", sourceFile = "frameworks/base/core/java/android/service/autofill/InlinePresentation.java", inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size(min=0L) java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)") inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size(min=0L) java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)") Loading services/autofill/java/com/android/server/autofill/Session.java +26 −1 Original line number Original line Diff line number Diff line Loading @@ -73,6 +73,7 @@ import android.service.autofill.FieldClassificationUserData; import android.service.autofill.FillContext; import android.service.autofill.FillContext; import android.service.autofill.FillRequest; import android.service.autofill.FillRequest; import android.service.autofill.FillResponse; import android.service.autofill.FillResponse; import android.service.autofill.InlinePresentation; import android.service.autofill.InternalSanitizer; import android.service.autofill.InternalSanitizer; import android.service.autofill.InternalValidator; import android.service.autofill.InternalValidator; import android.service.autofill.SaveInfo; import android.service.autofill.SaveInfo; Loading Loading @@ -1437,7 +1438,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mClientState = newClientState; mClientState = newClientState; } } final Dataset dataset = (Dataset) result; final Dataset dataset = (Dataset) result; final Dataset oldDataset = authenticatedResponse.getDatasets().get(datasetIdx); if (!isPinnedDataset(oldDataset)) { authenticatedResponse.getDatasets().set(datasetIdx, dataset); authenticatedResponse.getDatasets().set(datasetIdx, dataset); } autoFill(requestId, datasetIdx, dataset, false); autoFill(requestId, datasetIdx, dataset, false); } else { } else { Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id " Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id " Loading @@ -1455,6 +1459,27 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } } } } /** * A dataset can potentially have multiple fields, and it's possible that some of the fields' * has inline presentation and some don't. It's also possible that some of the fields' * inline presentation is pinned and some isn't. So the concept of whether a dataset is * pinned or not is ill-defined. Here we say a dataset is pinned if any of the field has a * pinned inline presentation in the dataset. It's not ideal but hopefully it is sufficient * for most of the cases. */ private static boolean isPinnedDataset(@Nullable Dataset dataset) { if (dataset != null && dataset.getFieldIds() != null) { final int numOfFields = dataset.getFieldIds().size(); for (int i = 0; i < numOfFields; i++) { final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(i); if (inlinePresentation != null && inlinePresentation.isPinned()) { return true; } } } return false; } @GuardedBy("mLock") @GuardedBy("mLock") void setAuthenticationResultForAugmentedAutofillLocked(Bundle data, int authId) { void setAuthenticationResultForAugmentedAutofillLocked(Bundle data, int authId) { final Dataset dataset = (data == null) ? null : final Dataset dataset = (data == null) ? null : Loading Loading
core/java/android/service/autofill/Dataset.java +6 −1 Original line number Original line Diff line number Diff line Loading @@ -312,7 +312,12 @@ public final class Dataset implements Parcelable { * setting it to the {@link * setting it to the {@link * android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra. If you * android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra. If you * provide a dataset in the result, it will replace the authenticated dataset and * provide a dataset in the result, it will replace the authenticated dataset and * will be immediately filled in. If you provide a response, it will replace the * will be immediately filled in. An exception to this behavior is if the original * dataset represents a pinned inline suggestion (i.e. any of the field in the dataset * has a pinned inline presentation, see {@link InlinePresentation#isPinned()}), then * the original dataset will not be replaced, * so that it can be triggered as a pending intent again. * If you provide a response, it will replace the * current response and the UI will be refreshed. For example, if you provided * current response and the UI will be refreshed. For example, if you provided * credit card information without the CVV for the data set in the {@link FillResponse * credit card information without the CVV for the data set in the {@link FillResponse * response} then the returned data set should contain the CVV entry. * response} then the returned data set should contain the CVV entry. Loading
core/java/android/service/autofill/InlinePresentation.java +16 −4 Original line number Original line Diff line number Diff line Loading @@ -50,7 +50,11 @@ public final class InlinePresentation implements Parcelable { /** /** * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * host. * host. However, it's eventually up to the host whether the UI is pinned or not. * * <p> Also a {@link Dataset} with a pinned inline presentation will not be replaced by the * new data set returned from authentication intent. See * {@link Dataset.Builder#setAuthentication(android.content.IntentSender)} for more information. */ */ private final boolean mPinned; private final boolean mPinned; Loading Loading @@ -90,7 +94,11 @@ public final class InlinePresentation implements Parcelable { * Specifies the UI specification for the inline suggestion. * Specifies the UI specification for the inline suggestion. * @param pinned * @param pinned * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * host. * host. However, it's eventually up to the host whether the UI is pinned or not. * * <p> Also a {@link Dataset} with a pinned inline presentation will not be replaced by the * new data set returned from authentication intent. See * {@link Dataset.Builder#setAuthentication(android.content.IntentSender)} for more information. */ */ @DataClass.Generated.Member @DataClass.Generated.Member public InlinePresentation( public InlinePresentation( Loading Loading @@ -126,7 +134,11 @@ public final class InlinePresentation implements Parcelable { /** /** * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * Indicates whether the UI should be pinned, hence non-scrollable and non-filterable, in the * host. * host. However, it's eventually up to the host whether the UI is pinned or not. * * <p> Also a {@link Dataset} with a pinned inline presentation will not be replaced by the * new data set returned from authentication intent. See * {@link Dataset.Builder#setAuthentication(android.content.IntentSender)} for more information. */ */ @DataClass.Generated.Member @DataClass.Generated.Member public boolean isPinned() { public boolean isPinned() { Loading Loading @@ -232,7 +244,7 @@ public final class InlinePresentation implements Parcelable { }; }; @DataClass.Generated( @DataClass.Generated( time = 1586992400667L, time = 1593131904745L, codegenVersion = "1.0.15", codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/service/autofill/InlinePresentation.java", sourceFile = "frameworks/base/core/java/android/service/autofill/InlinePresentation.java", inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size(min=0L) java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)") inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size(min=0L) java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)") Loading
services/autofill/java/com/android/server/autofill/Session.java +26 −1 Original line number Original line Diff line number Diff line Loading @@ -73,6 +73,7 @@ import android.service.autofill.FieldClassificationUserData; import android.service.autofill.FillContext; import android.service.autofill.FillContext; import android.service.autofill.FillRequest; import android.service.autofill.FillRequest; import android.service.autofill.FillResponse; import android.service.autofill.FillResponse; import android.service.autofill.InlinePresentation; import android.service.autofill.InternalSanitizer; import android.service.autofill.InternalSanitizer; import android.service.autofill.InternalValidator; import android.service.autofill.InternalValidator; import android.service.autofill.SaveInfo; import android.service.autofill.SaveInfo; Loading Loading @@ -1437,7 +1438,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mClientState = newClientState; mClientState = newClientState; } } final Dataset dataset = (Dataset) result; final Dataset dataset = (Dataset) result; final Dataset oldDataset = authenticatedResponse.getDatasets().get(datasetIdx); if (!isPinnedDataset(oldDataset)) { authenticatedResponse.getDatasets().set(datasetIdx, dataset); authenticatedResponse.getDatasets().set(datasetIdx, dataset); } autoFill(requestId, datasetIdx, dataset, false); autoFill(requestId, datasetIdx, dataset, false); } else { } else { Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id " Slog.w(TAG, "invalid index (" + datasetIdx + ") for authentication id " Loading @@ -1455,6 +1459,27 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } } } } /** * A dataset can potentially have multiple fields, and it's possible that some of the fields' * has inline presentation and some don't. It's also possible that some of the fields' * inline presentation is pinned and some isn't. So the concept of whether a dataset is * pinned or not is ill-defined. Here we say a dataset is pinned if any of the field has a * pinned inline presentation in the dataset. It's not ideal but hopefully it is sufficient * for most of the cases. */ private static boolean isPinnedDataset(@Nullable Dataset dataset) { if (dataset != null && dataset.getFieldIds() != null) { final int numOfFields = dataset.getFieldIds().size(); for (int i = 0; i < numOfFields; i++) { final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(i); if (inlinePresentation != null && inlinePresentation.isPinned()) { return true; } } } return false; } @GuardedBy("mLock") @GuardedBy("mLock") void setAuthenticationResultForAugmentedAutofillLocked(Bundle data, int authId) { void setAuthenticationResultForAugmentedAutofillLocked(Bundle data, int authId) { final Dataset dataset = (data == null) ? null : final Dataset dataset = (data == null) ? null : Loading