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

Commit cb96f391 authored by Felipe Leme's avatar Felipe Leme
Browse files

Uses ParceledListSlice to allow larger number of datasets.

Test: cts-tradefed run commandAndExit cts-dev -m CtsAutoFillServiceTestCases -t android.autofillservice.cts.LoginActivityTest#testAutofillLargeNumberOfDatasets
Test: cts-tradefed run commandAndExit cts-dev -m CtsAutoFillServiceTestCases

Fixes: 63669555

Change-Id: If0847da3bafa1bfd80ee8925e17aace82010aec9
parent 1807d585
Loading
Loading
Loading
Loading
+22 −10
Original line number Original line Diff line number Diff line
@@ -23,15 +23,16 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.Activity;
import android.content.IntentSender;
import android.content.IntentSender;
import android.content.pm.ParceledListSlice;
import android.os.Bundle;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.widget.RemoteViews;
import android.widget.RemoteViews;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.List;


/**
/**
 * Response for a {@link
 * Response for a {@link
@@ -41,7 +42,7 @@ import java.util.Arrays;
 */
 */
public final class FillResponse implements Parcelable {
public final class FillResponse implements Parcelable {


    private final @Nullable ArrayList<Dataset> mDatasets;
    private final @Nullable ParceledListSlice<Dataset> mDatasets;
    private final @Nullable SaveInfo mSaveInfo;
    private final @Nullable SaveInfo mSaveInfo;
    private final @Nullable Bundle mClientState;
    private final @Nullable Bundle mClientState;
    private final @Nullable RemoteViews mPresentation;
    private final @Nullable RemoteViews mPresentation;
@@ -51,7 +52,7 @@ public final class FillResponse implements Parcelable {
    private int mRequestId;
    private int mRequestId;


    private FillResponse(@NonNull Builder builder) {
    private FillResponse(@NonNull Builder builder) {
        mDatasets = builder.mDatasets;
        mDatasets = (builder.mDatasets != null) ? new ParceledListSlice<>(builder.mDatasets) : null;
        mSaveInfo = builder.mSaveInfo;
        mSaveInfo = builder.mSaveInfo;
        mClientState = builder.mCLientState;
        mClientState = builder.mCLientState;
        mPresentation = builder.mPresentation;
        mPresentation = builder.mPresentation;
@@ -67,8 +68,8 @@ public final class FillResponse implements Parcelable {
    }
    }


    /** @hide */
    /** @hide */
    public @Nullable ArrayList<Dataset> getDatasets() {
    public @Nullable List<Dataset> getDatasets() {
        return mDatasets;
        return (mDatasets != null) ? mDatasets.getList() : null;
    }
    }


    /** @hide */
    /** @hide */
@@ -143,12 +144,13 @@ public final class FillResponse implements Parcelable {
         * for the user to trigger your authentication flow.
         * for the user to trigger your authentication flow.
         *
         *
         * <p>When a user triggers autofill, the system launches the provided intent
         * <p>When a user triggers autofill, the system launches the provided intent
         * whose extras will have the {@link AutofillManager#EXTRA_ASSIST_STRUCTURE screen
         * whose extras will have the
         * {@link android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen
         * content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
         * content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
         * client state}. Once you complete your authentication flow you should set the
         * client state}. Once you complete your authentication flow you should set the
         * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and provide the fully
         * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and provide the fully
         * populated {@link FillResponse response} by setting it to the {@link
         * populated {@link FillResponse response} by setting it to the
         * AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
         * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
         * For example, if you provided an empty {@link FillResponse resppnse} because the
         * For example, if you provided an empty {@link FillResponse resppnse} because the
         * user's data was locked and marked that the response needs an authentication then
         * user's data was locked and marked that the response needs an authentication then
         * in the response returned if authentication succeeds you need to provide all
         * in the response returned if authentication succeeds you need to provide all
@@ -205,6 +207,15 @@ public final class FillResponse implements Parcelable {
        /**
        /**
         * Adds a new {@link Dataset} to this response.
         * Adds a new {@link Dataset} to this response.
         *
         *
         * <p><b>Note: </b> on Android {@link android.os.Build.VERSION_CODES#O}, the total number of
         * datasets is limited by the Binder transaction size, so it's recommended to keep it
         * small (in the range of 10-20 at most) and use pagination by adding a fake
         * {@link Dataset.Builder#setAuthentication(IntentSender) authenticated} at the end with
         * a presentation string like "Next 10" that would return a new {@link FillResponse} with
         * the next 10 datasets, and so on. This limitation was lifted on
         * Android {@link android.os.Build.VERSION_CODES#O_MR1}, although the Binder transaction
         * size can still be reached if each dataset itself is too big.
         *
         * @return This builder.
         * @return This builder.
         */
         */
        public @NonNull Builder addDataset(@Nullable Dataset dataset) {
        public @NonNull Builder addDataset(@Nullable Dataset dataset) {
@@ -313,7 +324,7 @@ public final class FillResponse implements Parcelable {


    @Override
    @Override
    public void writeToParcel(Parcel parcel, int flags) {
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeTypedArrayList(mDatasets, flags);
        parcel.writeParcelable(mDatasets, flags);
        parcel.writeParcelable(mSaveInfo, flags);
        parcel.writeParcelable(mSaveInfo, flags);
        parcel.writeParcelable(mClientState, flags);
        parcel.writeParcelable(mClientState, flags);
        parcel.writeParcelableArray(mAuthenticationIds, flags);
        parcel.writeParcelableArray(mAuthenticationIds, flags);
@@ -331,7 +342,8 @@ public final class FillResponse implements Parcelable {
            // the system obeys the contract of the builder to avoid attacks
            // the system obeys the contract of the builder to avoid attacks
            // using specially crafted parcels.
            // using specially crafted parcels.
            final Builder builder = new Builder();
            final Builder builder = new Builder();
            final ArrayList<Dataset> datasets = parcel.readTypedArrayList(null);
            final ParceledListSlice<Dataset> datasetSlice = parcel.readParcelable(null);
            final List<Dataset> datasets = (datasetSlice != null) ? datasetSlice.getList() : null;
            final int datasetCount = (datasets != null) ? datasets.size() : 0;
            final int datasetCount = (datasets != null) ? datasets.size() : 0;
            for (int i = 0; i < datasetCount; i++) {
            for (int i = 0; i < datasetCount; i++) {
                builder.addDataset(datasets.get(i));
                builder.addDataset(datasets.get(i));
+4 −4
Original line number Original line Diff line number Diff line
@@ -928,7 +928,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState


                // Make sure the service doesn't have the fields already by checking the datasets
                // Make sure the service doesn't have the fields already by checking the datasets
                // content.
                // content.
                final ArrayList<Dataset> datasets = response.getDatasets();
                final List<Dataset> datasets = response.getDatasets();
                if (datasets != null) {
                if (datasets != null) {
                    datasets_loop: for (int i = 0; i < datasets.size(); i++) {
                    datasets_loop: for (int i = 0; i < datasets.size(); i++) {
                        final Dataset dataset = datasets.get(i);
                        final Dataset dataset = datasets.get(i);
@@ -1157,7 +1157,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
                }
                }
            }
            }


            final ArrayList<Dataset> datasets = response.getDatasets();
            final List<Dataset> datasets = response.getDatasets();
            if (datasets != null) {
            if (datasets != null) {
                final int numDatasets = datasets.size();
                final int numDatasets = datasets.size();


@@ -1353,7 +1353,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
        // Must also track that are part of datasets, otherwise the FillUI won't be hidden when
        // Must also track that are part of datasets, otherwise the FillUI won't be hidden when
        // they go away (if they're not savable).
        // they go away (if they're not savable).


        final ArrayList<Dataset> datasets = response.getDatasets();
        final List<Dataset> datasets = response.getDatasets();
        ArraySet<AutofillId> fillableIds = null;
        ArraySet<AutofillId> fillableIds = null;
        if (datasets != null) {
        if (datasets != null) {
            for (int i = 0; i < datasets.size(); i++) {
            for (int i = 0; i < datasets.size(); i++) {
@@ -1426,7 +1426,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
     * Sets the state of all views in the given response.
     * Sets the state of all views in the given response.
     */
     */
    private void setViewStatesLocked(FillResponse response, int state, boolean clearResponse) {
    private void setViewStatesLocked(FillResponse response, int state, boolean clearResponse) {
        final ArrayList<Dataset> datasets = response.getDatasets();
        final List<Dataset> datasets = response.getDatasets();
        if (datasets != null) {
        if (datasets != null) {
            for (int i = 0; i < datasets.size(); i++) {
            for (int i = 0; i < datasets.size(); i++) {
                final Dataset dataset = datasets.get(i);
                final Dataset dataset = datasets.get(i);