Dataset.java revision eb49515abd2353f32e0eb7b3964847c6399986c9
16d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme/*
26d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * Copyright (C) 2016 The Android Open Source Project
36d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *
46d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License");
56d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * you may not use this file except in compliance with the License.
66d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * You may obtain a copy of the License at
76d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *
86d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *      http://www.apache.org/licenses/LICENSE-2.0
96d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *
106d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * Unless required by applicable law or agreed to in writing, software
116d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS,
126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * See the License for the specific language governing permissions and
146d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * limitations under the License.
156d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme */
166d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
17782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovpackage android.service.autofill;
186d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
19d633f072552815301a559520a1f93eb7e79ba319Felipe Lemeimport static android.view.autofill.Helper.DEBUG;
20d633f072552815301a559520a1f93eb7e79ba319Felipe Leme
210f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganovimport android.annotation.NonNull;
22436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Lemeimport android.annotation.Nullable;
230f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganovimport android.content.IntentSender;
246d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.os.Parcel;
256d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.os.Parcelable;
26782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.view.autofill.AutoFillId;
27782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.view.autofill.AutoFillValue;
2800c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganovimport android.widget.RemoteViews;
296d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport com.android.internal.util.Preconditions;
306d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
316d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport java.util.ArrayList;
326d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
336d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme/**
34782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * A set of data that can be used to auto-fill an {@link android.app.Activity}.
356d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *
366d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * <p>It contains:
376d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *
386d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * <ol>
3900c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov *   <li>A list of values for input fields.
4000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov *   <li>A presentation view to visualize.
4100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov *   <li>An optional intent to authenticate.
426d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * </ol>
436d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *
44782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * @see android.service.autofill.FillResponse for examples.
456d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme */
466d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemepublic final class Dataset implements Parcelable {
47782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
480f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final ArrayList<AutoFillId> mFieldIds;
490f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final ArrayList<AutoFillValue> mFieldValues;
5000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov    private final RemoteViews mPresentation;
510f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final IntentSender mAuthentication;
526d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
530f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private Dataset(Builder builder) {
540f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mFieldIds = builder.mFieldIds;
550f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mFieldValues = builder.mFieldValues;
5600c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov        mPresentation = builder.mPresentation;
570f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mAuthentication = builder.mAuthentication;
586d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
596d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
606d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /** @hide */
610f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    public @Nullable ArrayList<AutoFillId> getFieldIds() {
620f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        return mFieldIds;
63436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
64436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
65436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    /** @hide */
660f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    public @Nullable ArrayList<AutoFillValue> getFieldValues() {
670f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        return mFieldValues;
68436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
69436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
70436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    /** @hide */
7100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov    public @Nullable RemoteViews getPresentation() {
7200c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov        return mPresentation;
7300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov    }
7400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov
7500c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov    /** @hide */
760f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    public @Nullable IntentSender getAuthentication() {
770f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        return mAuthentication;
78436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
79436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
80436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    /** @hide */
810f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    public boolean isEmpty() {
820f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        return mFieldIds == null || mFieldIds.isEmpty();
83436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
84436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
856d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    @Override
866d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    public String toString() {
876d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        if (!DEBUG) return super.toString();
886d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
8900c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov        return new StringBuilder("Dataset [")
900f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                .append(", fieldIds=").append(mFieldIds)
910f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                .append(", fieldValues=").append(mFieldValues)
9200c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov                .append(", hasPresentation=").append(mPresentation != null)
9300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov                .append(", hasAuthentication=").append(mAuthentication != null)
9400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov                .append(']').toString();
956d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
966d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
976d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /**
980f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov     * A builder for {@link Dataset} objects. You must to provide at least
990f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov     * one value for a field or set an authentication intent.
1006d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     */
1016d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    public static final class Builder {
1020f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private ArrayList<AutoFillId> mFieldIds;
1030f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private ArrayList<AutoFillValue> mFieldValues;
10400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov        private RemoteViews mPresentation;
1050f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private IntentSender mAuthentication;
1060f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private boolean mDestroyed;
1070f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov
1086d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        /**
109eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov         * Creates a new builder.
11000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         *
111eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov         * @param presentation The presentation used to visualize this dataset.
1126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         */
113eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov        public Builder(@NonNull RemoteViews presentation) {
114eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov            Preconditions.checkNotNull(presentation, "presentation must be non-null");
11500c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov            mPresentation = presentation;
1166d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
1176d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
1186d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        /**
1190f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * Requires a dataset authentication before auto-filling the activity with this dataset.
120436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme         *
1210f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * <p>This method is called when you need to provide an authentication
122782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * UI for the data set. For example, when a data set contains credit card information
1230f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * (such as number, expiration date, and verification code), you can display UI
12400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         * asking for the verification code before filing in the data. Even if the
125782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * data set is completely populated the system will launch the specified authentication
126782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * intent and will need your approval to fill it in. Since the data set is "locked"
127782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * until the user authenticates it, typically this data set name is masked
128782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * (for example, "VISA....1234"). Typically you would want to store the data set
129782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * labels non-encrypted and the actual sensitive data encrypted and not in memory.
1300f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * This allows showing the labels in the UI while involving the user if one of
1310f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * the items with these labels is chosen. Note that if you use sensitive data as
132782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * a label, for example an email address, then it should also be encrypted.</p>
133436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme         *
134782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * <p>When a user triggers auto-fill, the system launches the provided intent
135782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * whose extras will have the {@link
136782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * android.view.autofill.AutoFillManager#EXTRA_ASSIST_STRUCTURE screen content}. Once
137782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * you complete your authentication flow you should set the activity result to {@link
138782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * android.app.Activity#RESULT_OK} and provide the fully populated {@link Dataset
139782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * dataset} by setting it to the {@link
140782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * android.view.autofill.AutoFillManager#EXTRA_AUTHENTICATION_RESULT} extra. For example,
14100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         * if you provided credit card information without the CVV for the data set in the
142782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * {@link FillResponse response} then the returned data set should contain the
143782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * CVV entry.</p>
144436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme         *
145782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * <p></><strong>Note:</strong> Do not make the provided pending intent
1460f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
1470f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * platform needs to fill in the authentication arguments.</p>
148436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme         *
149782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * @param authentication Intent to an activity with your authentication flow.
15000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         * @return This builder.
151436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme         *
152782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * @see android.app.PendingIntent
153436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme         */
1540f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        public @NonNull Builder setAuthentication(@Nullable IntentSender authentication) {
1550f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            throwIfDestroyed();
1560f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            mAuthentication = authentication;
157436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            return this;
158436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme        }
159436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
160436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme        /**
1616d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         * Sets the value of a field.
1626d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         *
163782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * @param id id returned by {@link
164782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         *         android.app.assist.AssistStructure.ViewNode#getAutoFillId()}.
1656d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         * @param value value to be auto filled.
16600c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         * @return This builder.
1676d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         */
1680f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) {
1690f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            throwIfDestroyed();
1700f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            Preconditions.checkNotNull(id, "id cannot be null");
1710f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            Preconditions.checkNotNull(value, "value cannot be null");
1720f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            if (mFieldIds != null) {
1730f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                final int existingIdx = mFieldIds.indexOf(id);
1740f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                if (existingIdx >= 0) {
1750f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                    mFieldValues.set(existingIdx, value);
1760f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                    return this;
1770f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                }
1780f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            } else {
1790f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                mFieldIds = new ArrayList<>();
1800f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                mFieldValues = new ArrayList<>();
1810f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            }
1820f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            mFieldIds.add(id);
1830f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            mFieldValues.add(value);
1846d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            return this;
1856d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
1866d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
1876d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        /**
1880f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * Creates a new {@link Dataset} instance. You should not interact
18900c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         * with this builder once this method is called. It is required
19000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         * that you specified at least one field. Also it is mandatory to
19100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         * provide a presentation view to visualize the data set in the UI.
19200c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         *
19300c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov         * @return The built dataset.
1946d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         */
1950f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        public @NonNull Dataset build() {
1960f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            throwIfDestroyed();
1970f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            mDestroyed = true;
19800c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov            if (mFieldIds == null) {
1990f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                throw new IllegalArgumentException(
20000c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov                        "at least one value must be set");
20100c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov            }
2020f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            return new Dataset(this);
2036d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
2046d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2050f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private void throwIfDestroyed() {
2060f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            if (mDestroyed) {
2070f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                throw new IllegalStateException("Already called #build()");
2080f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            }
2096d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
2106d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
2116d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /////////////////////////////////////
2136d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    //  Parcelable "contract" methods. //
2146d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /////////////////////////////////////
2156d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2166d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    @Override
2176d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    public int describeContents() {
2186d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        return 0;
2196d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
2206d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2216d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    @Override
2226d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    public void writeToParcel(Parcel parcel, int flags) {
223eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov        parcel.writeParcelable(mPresentation, flags);
22400c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov        parcel.writeTypedArrayList(mFieldIds, flags);
22500c771dc7d8242362f1491ae4ce3efd641235b36Svet Ganov        parcel.writeTypedArrayList(mFieldValues, flags);
2260f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        parcel.writeParcelable(mAuthentication, flags);
2276d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
2286d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
229782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    public static final Creator<Dataset> CREATOR = new Creator<Dataset>() {
2306d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        @Override
2310f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        public Dataset createFromParcel(Parcel parcel) {
2320f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            // Always go through the builder to ensure the data ingested by
2330f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            // the system obeys the contract of the builder to avoid attacks
2340f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            // using specially crafted parcels.
235eb49515abd2353f32e0eb7b3964847c6399986c9Svet Ganov            final Builder builder = new Builder(parcel.readParcelable(null));
2360f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            final ArrayList<AutoFillId> ids = parcel.readTypedArrayList(null);
2370f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            final ArrayList<AutoFillValue> values = parcel.readTypedArrayList(null);
2380f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            final int idCount = (ids != null) ? ids.size() : 0;
2390f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            final int valueCount = (values != null) ? values.size() : 0;
2400f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            for (int i = 0; i < idCount; i++) {
2410f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                AutoFillId id = ids.get(i);
2420f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                AutoFillValue value = (valueCount > i) ? values.get(i) : null;
2430f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                builder.setValue(id, value);
2440f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            }
2450f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            builder.setAuthentication(parcel.readParcelable(null));
2460f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            return builder.build();
2476d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
2486d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2496d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        @Override
2506d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        public Dataset[] newArray(int size) {
2516d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            return new Dataset[size];
2526d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
2536d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    };
2546d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme}
255