Dataset.java revision 782043caf81055aa1c331e9cc15b24a10e1bf17a
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 190f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganovimport android.annotation.NonNull; 20436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Lemeimport android.annotation.Nullable; 210f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganovimport android.content.IntentSender; 226d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.os.Parcel; 236d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.os.Parcelable; 24782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.view.autofill.AutoFillId; 25782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.view.autofill.AutoFillValue; 266d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport com.android.internal.util.Preconditions; 276d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 286d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport java.util.ArrayList; 296d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 306d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme/** 31782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * A set of data that can be used to auto-fill an {@link android.app.Activity}. 326d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * 336d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * <p>It contains: 346d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * 356d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * <ol> 366d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * <li>A name used to identify the dataset in the UI. 376d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * <li>A list of id/value pairs for the fields that can be auto-filled. 38782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * <li>A list of savable ids in addition to the ones with a provided value. 396d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * </ol> 406d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * 41782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * @see android.service.autofill.FillResponse for examples. 426d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme */ 436d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemepublic final class Dataset implements Parcelable { 44782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov private static final boolean DEBUG = false; 45782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov 466d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme private final CharSequence mName; 470f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private final ArrayList<AutoFillId> mFieldIds; 480f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private final ArrayList<AutoFillValue> mFieldValues; 490f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private final IntentSender mAuthentication; 506d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 510f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private Dataset(Builder builder) { 526d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme mName = builder.mName; 530f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mFieldIds = builder.mFieldIds; 540f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mFieldValues = builder.mFieldValues; 550f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mAuthentication = builder.mAuthentication; 566d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 576d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 586d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme /** @hide */ 590f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public @NonNull CharSequence getName() { 600f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return mName; 616d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 626d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 63436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme /** @hide */ 640f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public @Nullable ArrayList<AutoFillId> getFieldIds() { 650f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return mFieldIds; 66436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme } 67436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme 68436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme /** @hide */ 690f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public @Nullable ArrayList<AutoFillValue> getFieldValues() { 700f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return mFieldValues; 71436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme } 72436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme 73436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme /** @hide */ 740f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public @Nullable IntentSender getAuthentication() { 750f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return mAuthentication; 76436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme } 77436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme 78436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme /** @hide */ 790f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public boolean isEmpty() { 800f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return mFieldIds == null || mFieldIds.isEmpty(); 81436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme } 82436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme 836d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme @Override 846d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme public String toString() { 856d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme if (!DEBUG) return super.toString(); 866d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 87782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov final StringBuilder builder = new StringBuilder("Dataset [name=").append(mName) 880f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov .append(", fieldIds=").append(mFieldIds) 890f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov .append(", fieldValues=").append(mFieldValues) 90782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov .append(", hasAuthentication=").append(mAuthentication != null); 916d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme return builder.append(']').toString(); 926d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 936d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 946d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme /** 950f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * A builder for {@link Dataset} objects. You must to provide at least 960f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * one value for a field or set an authentication intent. 976d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme */ 986d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme public static final class Builder { 996d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme private CharSequence mName; 1000f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private ArrayList<AutoFillId> mFieldIds; 1010f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private ArrayList<AutoFillValue> mFieldValues; 1020f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private IntentSender mAuthentication; 1030f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private boolean mDestroyed; 1040f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov 1056d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme /** 1066d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * Creates a new builder. 1076d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * 1086d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * @param name Name used to identify the dataset in the UI. Typically it's the same value as 1090f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * the first field in the dataset (like username or email address) or a user-provided name 1106d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * (like "My Work Address"). 1116d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme */ 112782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov public Builder(@NonNull CharSequence name) { 1136d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme mName = Preconditions.checkStringNotEmpty(name, "name cannot be empty or null"); 1146d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 1156d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 1166d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme /** 1170f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * Requires a dataset authentication before auto-filling the activity with this dataset. 118436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme * 1190f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * <p>This method is called when you need to provide an authentication 120782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * UI for the data set. For example, when a data set contains credit card information 1210f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * (such as number, expiration date, and verification code), you can display UI 1220f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * asking for the verification code to before filing in the data). Even if the 123782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * data set is completely populated the system will launch the specified authentication 124782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * intent and will need your approval to fill it in. Since the data set is "locked" 125782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * until the user authenticates it, typically this data set name is masked 126782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * (for example, "VISA....1234"). Typically you would want to store the data set 127782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * labels non-encrypted and the actual sensitive data encrypted and not in memory. 1280f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * This allows showing the labels in the UI while involving the user if one of 1290f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * the items with these labels is chosen. Note that if you use sensitive data as 130782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * a label, for example an email address, then it should also be encrypted.</p> 131436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme * 132782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * <p>When a user triggers auto-fill, the system launches the provided intent 133782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * whose extras will have the {@link 134782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * android.view.autofill.AutoFillManager#EXTRA_ASSIST_STRUCTURE screen content}. Once 135782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * you complete your authentication flow you should set the activity result to {@link 136782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * android.app.Activity#RESULT_OK} and provide the fully populated {@link Dataset 137782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * dataset} by setting it to the {@link 138782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * android.view.autofill.AutoFillManager#EXTRA_AUTHENTICATION_RESULT} extra. For example, 139782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * if you provided an credit card information without the CVV for the data set in the 140782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * {@link FillResponse response} then the returned data set should contain the 141782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * CVV entry.</p> 142436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme * 143782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * <p></><strong>Note:</strong> Do not make the provided pending intent 1440f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the 1450f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * platform needs to fill in the authentication arguments.</p> 146436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme * 147782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * @param authentication Intent to an activity with your authentication flow. 148436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme * 149782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * @see android.app.PendingIntent 150436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme */ 1510f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public @NonNull Builder setAuthentication(@Nullable IntentSender authentication) { 1520f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov throwIfDestroyed(); 1530f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mAuthentication = authentication; 154436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme return this; 155436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme } 156436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme 157436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme /** 1586d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * Sets the value of a field. 1596d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * 160782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * @param id id returned by {@link 161782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov * android.app.assist.AssistStructure.ViewNode#getAutoFillId()}. 1626d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme * @param value value to be auto filled. 1636d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme */ 1640f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) { 1650f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov throwIfDestroyed(); 1660f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov Preconditions.checkNotNull(id, "id cannot be null"); 1670f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov Preconditions.checkNotNull(value, "value cannot be null"); 1680f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov if (mFieldIds != null) { 1690f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov final int existingIdx = mFieldIds.indexOf(id); 1700f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov if (existingIdx >= 0) { 1710f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mFieldValues.set(existingIdx, value); 1720f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return this; 1730f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 1740f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } else { 1750f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mFieldIds = new ArrayList<>(); 1760f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mFieldValues = new ArrayList<>(); 1770f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 1780f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mFieldIds.add(id); 1790f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mFieldValues.add(value); 1806d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme return this; 1816d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 1826d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 1836d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme /** 1840f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * Creates a new {@link Dataset} instance. You should not interact 1850f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov * with this builder once this method is called. 1866d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme */ 1870f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public @NonNull Dataset build() { 1880f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov throwIfDestroyed(); 1890f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov mDestroyed = true; 1900f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov if (mFieldIds == null && mAuthentication == null) { 1910f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov throw new IllegalArgumentException( 1920f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov "at least one value or an authentication must be set"); 1930f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 1940f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return new Dataset(this); 1956d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 1966d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 1970f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov private void throwIfDestroyed() { 1980f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov if (mDestroyed) { 1990f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov throw new IllegalStateException("Already called #build()"); 2000f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 2016d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 2026d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 2036d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2046d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme ///////////////////////////////////// 2056d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme // Parcelable "contract" methods. // 2066d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme ///////////////////////////////////// 2076d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2086d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme @Override 2096d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme public int describeContents() { 2106d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme return 0; 2116d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 2126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2136d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme @Override 2146d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme public void writeToParcel(Parcel parcel, int flags) { 2156d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme parcel.writeCharSequence(mName); 2160f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov parcel.writeTypedArrayList(mFieldIds, 0); 2170f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov parcel.writeTypedArrayList(mFieldValues, 0); 2180f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov parcel.writeParcelable(mAuthentication, flags); 2196d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 2206d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 221782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov public static final Creator<Dataset> CREATOR = new Creator<Dataset>() { 2226d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme @Override 2230f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov public Dataset createFromParcel(Parcel parcel) { 2240f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov // Always go through the builder to ensure the data ingested by 2250f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov // the system obeys the contract of the builder to avoid attacks 2260f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov // using specially crafted parcels. 227782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov final Builder builder = new Builder(parcel.readCharSequence()); 2280f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov final ArrayList<AutoFillId> ids = parcel.readTypedArrayList(null); 2290f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov final ArrayList<AutoFillValue> values = parcel.readTypedArrayList(null); 2300f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov final int idCount = (ids != null) ? ids.size() : 0; 2310f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov final int valueCount = (values != null) ? values.size() : 0; 2320f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov for (int i = 0; i < idCount; i++) { 2330f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov AutoFillId id = ids.get(i); 2340f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov AutoFillValue value = (valueCount > i) ? values.get(i) : null; 2350f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov builder.setValue(id, value); 2360f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov } 2370f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov builder.setAuthentication(parcel.readParcelable(null)); 2380f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov return builder.build(); 2396d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 2406d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme 2416d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme @Override 2426d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme public Dataset[] newArray(int size) { 2436d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme return new Dataset[size]; 2446d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme } 2456d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme }; 2466d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme} 247