Dataset.java revision d633f072552815301a559520a1f93eb7e79ba319
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;
28d633f072552815301a559520a1f93eb7e79ba319Felipe Leme
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>
396d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *   <li>A name used to identify the dataset in the UI.
406d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme *   <li>A list of id/value pairs for the fields that can be auto-filled.
41782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov *   <li>A list of savable ids in addition to the ones with a provided value.
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
486d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    private final CharSequence mName;
490f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final ArrayList<AutoFillId> mFieldIds;
500f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final ArrayList<AutoFillValue> mFieldValues;
510f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final IntentSender mAuthentication;
526d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
530f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private Dataset(Builder builder) {
546d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        mName = builder.mName;
550f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mFieldIds = builder.mFieldIds;
560f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mFieldValues = builder.mFieldValues;
570f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mAuthentication = builder.mAuthentication;
586d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
596d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
606d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /** @hide */
610f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    public @NonNull CharSequence getName() {
620f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        return mName;
636d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
646d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
65436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    /** @hide */
660f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    public @Nullable ArrayList<AutoFillId> getFieldIds() {
670f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        return mFieldIds;
68436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
69436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
70436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    /** @hide */
710f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    public @Nullable ArrayList<AutoFillValue> getFieldValues() {
720f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        return mFieldValues;
73436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
74436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
75436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    /** @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
89782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        final StringBuilder builder = new StringBuilder("Dataset [name=").append(mName)
900f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                .append(", fieldIds=").append(mFieldIds)
910f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                .append(", fieldValues=").append(mFieldValues)
92782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                .append(", hasAuthentication=").append(mAuthentication != null);
936d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        return builder.append(']').toString();
946d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
956d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
966d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /**
970f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov     * A builder for {@link Dataset} objects. You must to provide at least
980f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov     * one value for a field or set an authentication intent.
996d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     */
1006d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    public static final class Builder {
1016d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        private CharSequence mName;
1020f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private ArrayList<AutoFillId> mFieldIds;
1030f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private ArrayList<AutoFillValue> mFieldValues;
1040f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private IntentSender mAuthentication;
1050f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private boolean mDestroyed;
1060f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov
1076d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        /**
1086d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         * Creates a new builder.
1096d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         *
1106d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         * @param name Name used to identify the dataset in the UI. Typically it's the same value as
1110f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * the first field in the dataset (like username or email address) or a user-provided name
1126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         * (like "My Work Address").
1136d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         */
114782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        public Builder(@NonNull CharSequence name) {
1156d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            mName = Preconditions.checkStringNotEmpty(name, "name cannot be empty or null");
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
1240f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * asking for the verification code to 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,
141782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * if you provided an 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.
150436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme         *
151782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * @see android.app.PendingIntent
152436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme         */
1530f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        public @NonNull Builder setAuthentication(@Nullable IntentSender authentication) {
1540f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            throwIfDestroyed();
1550f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            mAuthentication = authentication;
156436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            return this;
157436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme        }
158436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
159436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme        /**
1606d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         * Sets the value of a field.
1616d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         *
162782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         * @param id id returned by {@link
163782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov         *         android.app.assist.AssistStructure.ViewNode#getAutoFillId()}.
1646d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         * @param value value to be auto filled.
1656d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         */
1660f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) {
1670f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            throwIfDestroyed();
1680f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            Preconditions.checkNotNull(id, "id cannot be null");
1690f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            Preconditions.checkNotNull(value, "value cannot be null");
1700f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            if (mFieldIds != null) {
1710f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                final int existingIdx = mFieldIds.indexOf(id);
1720f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                if (existingIdx >= 0) {
1730f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                    mFieldValues.set(existingIdx, value);
1740f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                    return this;
1750f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                }
1760f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            } else {
1770f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                mFieldIds = new ArrayList<>();
1780f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                mFieldValues = new ArrayList<>();
1790f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            }
1800f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            mFieldIds.add(id);
1810f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            mFieldValues.add(value);
1826d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            return this;
1836d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
1846d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
1856d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        /**
1860f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * Creates a new {@link Dataset} instance. You should not interact
1870f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov         * with this builder once this method is called.
1886d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme         */
1890f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        public @NonNull Dataset build() {
1900f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            throwIfDestroyed();
1910f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            mDestroyed = true;
1920f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            if (mFieldIds == null && mAuthentication == null) {
1930f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                throw new IllegalArgumentException(
1940f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                        "at least one value or an authentication must be set");
1950f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            }
1960f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            return new Dataset(this);
1976d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
1986d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
1990f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        private void throwIfDestroyed() {
2000f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            if (mDestroyed) {
2010f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                throw new IllegalStateException("Already called #build()");
2020f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            }
2036d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
2046d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
2056d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2066d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /////////////////////////////////////
2076d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    //  Parcelable "contract" methods. //
2086d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /////////////////////////////////////
2096d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2106d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    @Override
2116d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    public int describeContents() {
2126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        return 0;
2136d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
2146d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2156d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    @Override
2166d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    public void writeToParcel(Parcel parcel, int flags) {
2176d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        parcel.writeCharSequence(mName);
2180f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        parcel.writeTypedArrayList(mFieldIds, 0);
2190f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        parcel.writeTypedArrayList(mFieldValues, 0);
2200f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        parcel.writeParcelable(mAuthentication, flags);
2216d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    }
2226d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
223782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    public static final Creator<Dataset> CREATOR = new Creator<Dataset>() {
2246d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        @Override
2250f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        public Dataset createFromParcel(Parcel parcel) {
2260f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            // Always go through the builder to ensure the data ingested by
2270f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            // the system obeys the contract of the builder to avoid attacks
2280f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            // using specially crafted parcels.
229782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            final Builder builder = new Builder(parcel.readCharSequence());
2300f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            final ArrayList<AutoFillId> ids = parcel.readTypedArrayList(null);
2310f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            final ArrayList<AutoFillValue> values = parcel.readTypedArrayList(null);
2320f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            final int idCount = (ids != null) ? ids.size() : 0;
2330f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            final int valueCount = (values != null) ? values.size() : 0;
2340f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            for (int i = 0; i < idCount; i++) {
2350f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                AutoFillId id = ids.get(i);
2360f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                AutoFillValue value = (valueCount > i) ? values.get(i) : null;
2370f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                builder.setValue(id, value);
2380f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            }
2390f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            builder.setAuthentication(parcel.readParcelable(null));
2400f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            return builder.build();
2416d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
2426d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
2436d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        @Override
2446d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        public Dataset[] newArray(int size) {
2456d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            return new Dataset[size];
2466d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
2476d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    };
2486d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme}
249