1 /*
2  * Copyright 2016, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.managedprovisioning.model;
18 
19 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
20 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
21 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
22 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI;
23 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL;
24 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
25 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMERS;
26 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION;
27 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED;
28 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
29 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME;
30 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_MAIN_COLOR;
31 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ORGANIZATION_NAME;
32 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION;
33 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_CONSENT;
34 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS;
35 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_SETUP;
36 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SUPPORT_URL;
37 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
38 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_USE_MOBILE_DATA;
39 
40 import static com.android.internal.util.Preconditions.checkArgument;
41 import static com.android.internal.util.Preconditions.checkNotNull;
42 import static com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences.DEFAULT_PROVISIONING_ID;
43 import static com.android.managedprovisioning.common.StoreUtils.accountToPersistableBundle;
44 import static com.android.managedprovisioning.common.StoreUtils.getIntegerAttrFromPersistableBundle;
45 import static com.android.managedprovisioning.common.StoreUtils.getObjectAttrFromPersistableBundle;
46 import static com.android.managedprovisioning.common.StoreUtils.getStringAttrFromPersistableBundle;
47 import static com.android.managedprovisioning.common.StoreUtils.putIntegerIfNotNull;
48 import static com.android.managedprovisioning.common.StoreUtils.putPersistableBundlableIfNotNull;
49 
50 import android.accounts.Account;
51 import android.annotation.IntDef;
52 import android.content.ComponentName;
53 import android.content.Context;
54 import android.os.Parcel;
55 import android.os.Parcelable;
56 import android.os.PersistableBundle;
57 import android.util.AtomicFile;
58 import android.util.Xml;
59 
60 import androidx.annotation.Nullable;
61 
62 import com.android.internal.util.FastXmlSerializer;
63 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
64 import com.android.managedprovisioning.common.PersistableBundlable;
65 import com.android.managedprovisioning.common.ProvisionLogger;
66 import com.android.managedprovisioning.common.StoreUtils;
67 import com.android.managedprovisioning.common.Utils;
68 
69 import org.xmlpull.v1.XmlPullParser;
70 import org.xmlpull.v1.XmlPullParserException;
71 import org.xmlpull.v1.XmlSerializer;
72 
73 import java.io.File;
74 import java.io.FileInputStream;
75 import java.io.FileOutputStream;
76 import java.io.IOException;
77 import java.lang.annotation.Retention;
78 import java.lang.annotation.RetentionPolicy;
79 import java.nio.charset.StandardCharsets;
80 import java.util.Locale;
81 
82 /**
83  * Provisioning parameters for Device Owner and Profile Owner provisioning.
84  */
85 public final class ProvisioningParams extends PersistableBundlable {
86     public static final long DEFAULT_LOCAL_TIME = -1;
87     public static final Integer DEFAULT_MAIN_COLOR = null;
88     public static final boolean DEFAULT_STARTED_BY_TRUSTED_SOURCE = false;
89     public static final boolean DEFAULT_IS_NFC = false;
90     public static final boolean DEFAULT_IS_CLOUD_ENROLLMENT = false;
91     public static final boolean DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED = false;
92     public static final boolean DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION = false;
93     public static final boolean DEFAULT_EXTRA_PROVISIONING_SKIP_USER_CONSENT = false;
94     public static final boolean DEFAULT_EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS = false;
95     public static final boolean DEFAULT_EXTRA_PROVISIONING_KEEP_ACCOUNT_MIGRATED = false;
96     public static final boolean DEFAULT_SKIP_USER_SETUP = true;
97     public static final boolean DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA = false;
98     // Intent extra used internally for passing data between activities and service.
99     public static final String EXTRA_PROVISIONING_PARAMS = "provisioningParams";
100 
101     // Possible provisioning modes for organization owned provisioning.
102     public static final int PROVISIONING_MODE_UNDECIDED = 0;
103     public static final int PROVISIONING_MODE_FULLY_MANAGED_DEVICE = 1;
104     public static final int PROVISIONING_MODE_MANAGED_PROFILE = 2;
105     public static final int PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_NAMAGED_DEVICE = 3;
106     public static final int PROVISIONING_MODE_FULLY_MANAGED_DEVICE_LEGACY = 4;
107 
108     @IntDef(prefix = { "PROVISIONING_MODE_" }, value = {
109             PROVISIONING_MODE_UNDECIDED,
110             PROVISIONING_MODE_FULLY_MANAGED_DEVICE,
111             PROVISIONING_MODE_MANAGED_PROFILE,
112             PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_NAMAGED_DEVICE,
113             PROVISIONING_MODE_FULLY_MANAGED_DEVICE_LEGACY
114     })
115     @Retention(RetentionPolicy.SOURCE)
116     public @interface ProvisioningMode {}
117 
118     private static final String TAG_PROVISIONING_ID = "provisioning-id";
119     private static final String TAG_PROVISIONING_PARAMS = "provisioning-params";
120     private static final String TAG_WIFI_INFO = "wifi-info";
121     private static final String TAG_PACKAGE_DOWNLOAD_INFO = "download-info";
122     private static final String TAG_STARTED_BY_TRUSTED_SOURCE = "started-by-trusted-source";
123     private static final String TAG_IS_NFC = "started-is-nfc";
124     private static final String TAG_IS_CLOUD_ENROLLMENT = "is-cloud-enrollment";
125     private static final String TAG_PROVISIONING_ACTION = "provisioning-action";
126     private static final String TAG_IS_ORGANIZATION_OWNED_PROVISIONING =
127             "is-organization-owned-provisioning";
128     private static final String TAG_PROVISIONING_MODE = "provisioning-mode";
129 
130     public static final Parcelable.Creator<ProvisioningParams> CREATOR
131             = new Parcelable.Creator<ProvisioningParams>() {
132         @Override
133         public ProvisioningParams createFromParcel(Parcel in) {
134             return new ProvisioningParams(in);
135         }
136 
137         @Override
138         public ProvisioningParams[] newArray(int size) {
139             return new ProvisioningParams[size];
140         }
141     };
142 
143     public final long provisioningId;
144 
145     @Nullable
146     public final String timeZone;
147 
148     public final long localTime;
149 
150     @Nullable
151     public final Locale locale;
152 
153     /** WiFi configuration. */
154     @Nullable
155     public final WifiInfo wifiInfo;
156 
157     public final boolean useMobileData;
158 
159     /**
160      * Package name of the device admin package.
161      *
162      * <p>At least one one of deviceAdminPackageName and deviceAdminComponentName should be
163      * non-null.
164      * <p>
165      * In most cases, it is preferable to access the admin package name using
166      * {@link #inferDeviceAdminPackageName}.
167      */
168     @Deprecated
169     @Nullable
170     public final String deviceAdminPackageName;
171 
172     /**
173      * {@link ComponentName} of the device admin package.
174      *
175      * <p>At least one one of deviceAdminPackageName and deviceAdminComponentName should be
176      * non-null.
177      * <p>
178      * In most cases, it is preferable to access the admin component name using
179      * {@link #inferDeviceAdminComponentName(Utils, Context, int)} .
180      */
181     @Nullable
182     public final ComponentName deviceAdminComponentName;
183 
184     public final String deviceAdminLabel;
185     public final String organizationName;
186     public final String supportUrl;
187     public final String deviceAdminIconFilePath;
188 
189     /** {@link Account} that should be migrated to the managed profile. */
190     @Nullable
191     public final Account accountToMigrate;
192 
193     /** True if the account will not be removed from the calling user after it is migrated. */
194     public final boolean keepAccountMigrated;
195 
196     /** Provisioning action comes along with the provisioning data. */
197     public final String provisioningAction;
198 
199     /**
200      * The main color theme used in managed profile only.
201      *
202      * <p>{@code null} means the default value.
203      */
204     @Nullable
205     public final Integer mainColor;
206 
207     /** The download information of device admin package. */
208     @Nullable
209     public final PackageDownloadInfo deviceAdminDownloadInfo;
210 
211     /** List of disclaimers */
212     @Nullable
213     public final DisclaimersParam disclaimersParam;
214 
215     /**
216      * Custom key-value pairs from enterprise mobility management which are passed to device admin
217      * package after provisioning.
218      *
219      * <p>Note that {@link ProvisioningParams} is not immutable because this field is mutable.
220      */
221     @Nullable
222     public final PersistableBundle adminExtrasBundle;
223 
224     /**
225      * True iff provisioning flow was started by a trusted app. This includes Nfc bump and QR code.
226      */
227     public final boolean startedByTrustedSource;
228 
229     public final boolean isNfc;
230 
231     public final boolean isCloudEnrollment;
232 
233     /** True if all system apps should be enabled after provisioning. */
234     public final boolean leaveAllSystemAppsEnabled;
235 
236     /** True if device encryption should be skipped. */
237     public final boolean skipEncryption;
238 
239     /** True if user setup can be skipped. */
240     public final boolean skipUserSetup;
241 
242     public final boolean skipEducationScreens;
243 
244     /** True if user consent page in pre-provisioning can be skipped. */
245     public final boolean skipUserConsent;
246 
247     /** True if the provisioning is done on a device owned by the organization. */
248     public final boolean isOrganizationOwnedProvisioning;
249 
250     /**
251      * The provisioning mode for organization owned provisioning. This is only used for
252      * admin integrated flow.
253      */
254     public final @ProvisioningMode int provisioningMode;
255 
inferStaticDeviceAdminPackageName(ComponentName deviceAdminComponentName, String deviceAdminPackageName)256     public static String inferStaticDeviceAdminPackageName(ComponentName deviceAdminComponentName,
257             String deviceAdminPackageName) {
258         if (deviceAdminComponentName != null) {
259             return deviceAdminComponentName.getPackageName();
260         }
261         return deviceAdminPackageName;
262     }
263 
inferDeviceAdminPackageName()264     public String inferDeviceAdminPackageName() {
265         return inferStaticDeviceAdminPackageName(deviceAdminComponentName, deviceAdminPackageName);
266     }
267 
268     /**
269      * Due to legacy reason, DPC is allowed to provide either package name or the component name.
270      * If component name is not {@code null}, we will return it right away. Otherwise, we will
271      * infer the component name.
272      * <p>
273      * In most cases, it is preferable to access the admin component name using this method.
274      * But if the purpose is to verify the device admin component name, you should use
275      * {@link Utils#findDeviceAdmin(String, ComponentName, Context, int)} instead.
276      */
inferDeviceAdminComponentName(Utils utils, Context context, int userId)277     public ComponentName inferDeviceAdminComponentName(Utils utils, Context context, int userId)
278             throws IllegalProvisioningArgumentException {
279         if (deviceAdminComponentName != null) {
280             return deviceAdminComponentName;
281         }
282         return utils.findDeviceAdmin(
283                 deviceAdminPackageName, deviceAdminComponentName, context, userId);
284     }
285 
ProvisioningParams(Builder builder)286     private ProvisioningParams(Builder builder) {
287         provisioningId = builder.mProvisioningId;
288         timeZone = builder.mTimeZone;
289         localTime = builder.mLocalTime;
290         locale = builder.mLocale;
291 
292         wifiInfo = builder.mWifiInfo;
293         useMobileData = builder.mUseMobileData;
294 
295         deviceAdminComponentName = builder.mDeviceAdminComponentName;
296         deviceAdminPackageName = builder.mDeviceAdminPackageName;
297         deviceAdminLabel = builder.mDeviceAdminLabel;
298         organizationName = builder.mOrganizationName;
299         supportUrl = builder.mSupportUrl;
300         deviceAdminIconFilePath = builder.mDeviceAdminIconFilePath;
301 
302         deviceAdminDownloadInfo = builder.mDeviceAdminDownloadInfo;
303         disclaimersParam = builder.mDisclaimersParam;
304 
305         adminExtrasBundle = builder.mAdminExtrasBundle;
306 
307         startedByTrustedSource = builder.mStartedByTrustedSource;
308         isNfc = builder.mIsNfc;
309         isCloudEnrollment = builder.mIsCloudEnrollment;
310         leaveAllSystemAppsEnabled = builder.mLeaveAllSystemAppsEnabled;
311         skipEncryption = builder.mSkipEncryption;
312         accountToMigrate = builder.mAccountToMigrate;
313         provisioningAction = checkNotNull(builder.mProvisioningAction);
314         mainColor = builder.mMainColor;
315         skipUserConsent = builder.mSkipUserConsent;
316         skipUserSetup = builder.mSkipUserSetup;
317         skipEducationScreens = builder.mSkipEducationScreens;
318         keepAccountMigrated = builder.mKeepAccountMigrated;
319 
320         isOrganizationOwnedProvisioning = builder.mIsOrganizationOwnedProvisioning;
321         provisioningMode = builder.mProvisioningMode;
322 
323         validateFields();
324     }
325 
ProvisioningParams(Parcel in)326     private ProvisioningParams(Parcel in) {
327         this(createBuilderFromPersistableBundle(
328                 PersistableBundlable.getPersistableBundleFromParcel(in)));
329     }
330 
validateFields()331     private void validateFields() {
332         checkArgument(deviceAdminPackageName != null || deviceAdminComponentName != null);
333     }
334 
335     @Override
toPersistableBundle()336     public PersistableBundle toPersistableBundle() {
337         final PersistableBundle bundle = new PersistableBundle();
338 
339         bundle.putLong(TAG_PROVISIONING_ID, provisioningId);
340         bundle.putString(EXTRA_PROVISIONING_TIME_ZONE, timeZone);
341         bundle.putLong(EXTRA_PROVISIONING_LOCAL_TIME, localTime);
342         bundle.putString(EXTRA_PROVISIONING_LOCALE, StoreUtils.localeToString(locale));
343         putPersistableBundlableIfNotNull(bundle, TAG_WIFI_INFO, wifiInfo);
344         bundle.putBoolean(EXTRA_PROVISIONING_USE_MOBILE_DATA, useMobileData);
345         bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, deviceAdminPackageName);
346         bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
347                 StoreUtils.componentNameToString(deviceAdminComponentName));
348         bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL, deviceAdminLabel);
349         bundle.putString(EXTRA_PROVISIONING_ORGANIZATION_NAME, organizationName);
350         bundle.putString(EXTRA_PROVISIONING_SUPPORT_URL, supportUrl);
351         bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI, deviceAdminIconFilePath);
352         bundle.putPersistableBundle(EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, accountToMigrate == null
353                 ? null : accountToPersistableBundle(accountToMigrate));
354         bundle.putString(TAG_PROVISIONING_ACTION, provisioningAction);
355         putIntegerIfNotNull(bundle, EXTRA_PROVISIONING_MAIN_COLOR, mainColor);
356         putPersistableBundlableIfNotNull(bundle, TAG_PACKAGE_DOWNLOAD_INFO,
357                 deviceAdminDownloadInfo);
358         putPersistableBundlableIfNotNull(bundle, EXTRA_PROVISIONING_DISCLAIMERS,
359                 disclaimersParam);
360         bundle.putPersistableBundle(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, adminExtrasBundle);
361         bundle.putBoolean(TAG_STARTED_BY_TRUSTED_SOURCE, startedByTrustedSource);
362         bundle.putBoolean(TAG_IS_NFC, isNfc);
363         bundle.putBoolean(TAG_IS_CLOUD_ENROLLMENT, isCloudEnrollment);
364         bundle.putBoolean(EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED,
365                 leaveAllSystemAppsEnabled);
366         bundle.putBoolean(EXTRA_PROVISIONING_SKIP_ENCRYPTION, skipEncryption);
367         bundle.putBoolean(EXTRA_PROVISIONING_SKIP_USER_SETUP, skipUserSetup);
368         bundle.putBoolean(EXTRA_PROVISIONING_SKIP_USER_CONSENT, skipUserConsent);
369         bundle.putBoolean(EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS, skipEducationScreens);
370         bundle.putBoolean(EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION, keepAccountMigrated);
371         bundle.putBoolean(TAG_IS_ORGANIZATION_OWNED_PROVISIONING, isOrganizationOwnedProvisioning);
372         bundle.putInt(TAG_PROVISIONING_MODE, provisioningMode);
373         return bundle;
374     }
375 
fromPersistableBundle(PersistableBundle bundle)376     /* package */ static ProvisioningParams fromPersistableBundle(PersistableBundle bundle) {
377         return createBuilderFromPersistableBundle(bundle).build();
378     }
379 
createBuilderFromPersistableBundle(PersistableBundle bundle)380     private static Builder createBuilderFromPersistableBundle(PersistableBundle bundle) {
381         Builder builder = new Builder();
382         builder.setProvisioningId(bundle.getLong(TAG_PROVISIONING_ID, DEFAULT_PROVISIONING_ID));
383         builder.setTimeZone(bundle.getString(EXTRA_PROVISIONING_TIME_ZONE));
384         builder.setLocalTime(bundle.getLong(EXTRA_PROVISIONING_LOCAL_TIME));
385         builder.setLocale(getStringAttrFromPersistableBundle(bundle,
386                 EXTRA_PROVISIONING_LOCALE, StoreUtils::stringToLocale));
387         builder.setUseMobileData(bundle.getBoolean(EXTRA_PROVISIONING_USE_MOBILE_DATA));
388         builder.setWifiInfo(getObjectAttrFromPersistableBundle(bundle,
389                 TAG_WIFI_INFO, WifiInfo::fromPersistableBundle));
390         builder.setDeviceAdminPackageName(bundle.getString(
391                 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME));
392         builder.setDeviceAdminComponentName(getStringAttrFromPersistableBundle(bundle,
393                 EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, StoreUtils::stringToComponentName));
394         builder.setDeviceAdminLabel(bundle.getString(
395                 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_LABEL));
396         builder.setOrganizationName(bundle.getString(EXTRA_PROVISIONING_ORGANIZATION_NAME));
397         builder.setSupportUrl(bundle.getString(EXTRA_PROVISIONING_SUPPORT_URL));
398         builder.setDeviceAdminIconFilePath(bundle.getString(
399                 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_ICON_URI));
400         builder.setAccountToMigrate(getObjectAttrFromPersistableBundle(bundle,
401                 EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, StoreUtils::persistableBundleToAccount));
402         builder.setProvisioningAction(bundle.getString(TAG_PROVISIONING_ACTION));
403         builder.setMainColor(getIntegerAttrFromPersistableBundle(bundle,
404                 EXTRA_PROVISIONING_MAIN_COLOR));
405         builder.setDeviceAdminDownloadInfo(getObjectAttrFromPersistableBundle(bundle,
406                 TAG_PACKAGE_DOWNLOAD_INFO, PackageDownloadInfo::fromPersistableBundle));
407         builder.setDisclaimersParam(getObjectAttrFromPersistableBundle(bundle,
408                 EXTRA_PROVISIONING_DISCLAIMERS, DisclaimersParam::fromPersistableBundle));
409         builder.setAdminExtrasBundle(bundle.getPersistableBundle(
410                 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE));
411         builder.setStartedByTrustedSource(bundle.getBoolean(TAG_STARTED_BY_TRUSTED_SOURCE));
412         builder.setIsNfc(bundle.getBoolean(TAG_IS_NFC));
413         builder.setIsCloudEnrollment(bundle.getBoolean(TAG_IS_CLOUD_ENROLLMENT));
414         builder.setSkipEncryption(bundle.getBoolean(EXTRA_PROVISIONING_SKIP_ENCRYPTION));
415         builder.setLeaveAllSystemAppsEnabled(bundle.getBoolean(
416                 EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED));
417         builder.setSkipUserSetup(bundle.getBoolean(EXTRA_PROVISIONING_SKIP_USER_SETUP));
418         builder.setSkipUserConsent(bundle.getBoolean(EXTRA_PROVISIONING_SKIP_USER_CONSENT));
419         builder.setSkipEducationScreens(bundle.getBoolean(EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS));
420         builder.setKeepAccountMigrated(bundle.getBoolean(
421                 EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION));
422         builder.setIsOrganizationOwnedProvisioning(bundle.getBoolean(
423                 TAG_IS_ORGANIZATION_OWNED_PROVISIONING));
424         builder.setProvisioningMode(bundle.getInt(TAG_PROVISIONING_MODE));
425         return builder;
426     }
427 
toBuilder()428     public Builder toBuilder() {
429         return createBuilderFromPersistableBundle(toPersistableBundle());
430     }
431 
432     @Override
toString()433     public String toString() {
434         return "ProvisioningParams values: " + toPersistableBundle().toString();
435     }
436 
437     /**
438      * Saves the ProvisioningParams to the specified file.
439      */
save(File file)440     public void save(File file) {
441         ProvisionLogger.logd("Saving ProvisioningParams to " + file);
442         AtomicFile atomicFile = null;
443         FileOutputStream stream = null;
444         try {
445             atomicFile = new AtomicFile(file);
446             stream = atomicFile.startWrite();
447             XmlSerializer serializer = new FastXmlSerializer();
448             serializer.setOutput(stream, StandardCharsets.UTF_8.name());
449             serializer.startDocument(null, true);
450             serializer.startTag(null, TAG_PROVISIONING_PARAMS);
451             toPersistableBundle().saveToXml(serializer);
452             serializer.endTag(null, TAG_PROVISIONING_PARAMS);
453             serializer.endDocument();
454             atomicFile.finishWrite(stream);
455         } catch (IOException | XmlPullParserException e) {
456             ProvisionLogger.loge("Caught exception while trying to save Provisioning Params to "
457                     + " file " + file, e);
458             file.delete();
459             if (atomicFile != null) {
460                 atomicFile.failWrite(stream);
461             }
462         }
463     }
464 
cleanUp()465     public void cleanUp() {
466         if (disclaimersParam != null) {
467             disclaimersParam.cleanUp();
468         }
469         if (deviceAdminIconFilePath != null) {
470             new File(deviceAdminIconFilePath).delete();
471         }
472     }
473 
474     /**
475      * Loads the ProvisioningParams From the specified file.
476      */
load(File file)477     public static ProvisioningParams load(File file) {
478         if (!file.exists()) {
479             return null;
480         }
481         ProvisionLogger.logd("Loading ProvisioningParams from " + file);
482         try (FileInputStream stream = new FileInputStream(file)) {
483             XmlPullParser parser = Xml.newPullParser();
484             parser.setInput(stream, null);
485             return load(parser);
486         } catch (IOException | XmlPullParserException e) {
487             ProvisionLogger.loge("Caught exception while trying to load the provisioning params"
488                     + " from file " + file, e);
489             return null;
490         }
491     }
492 
load(XmlPullParser parser)493     private static ProvisioningParams load(XmlPullParser parser) throws XmlPullParserException,
494             IOException {
495         int type;
496         int outerDepth = parser.getDepth();
497         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
498                 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
499              if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
500                  continue;
501              }
502              String tag = parser.getName();
503              switch (tag) {
504                  case TAG_PROVISIONING_PARAMS:
505                      return createBuilderFromPersistableBundle(
506                              PersistableBundle.restoreFromXml(parser)).build();
507              }
508         }
509         return new Builder().build();
510     }
511 
512     public final static class Builder {
513         private long mProvisioningId;
514         private String mTimeZone;
515         private long mLocalTime = DEFAULT_LOCAL_TIME;
516         private Locale mLocale;
517         private WifiInfo mWifiInfo;
518         private String mDeviceAdminPackageName;
519         private ComponentName mDeviceAdminComponentName;
520         private String mDeviceAdminLabel;
521         private String mOrganizationName;
522         private String mSupportUrl;
523         private String mDeviceAdminIconFilePath;
524         private Account mAccountToMigrate;
525         private String mProvisioningAction;
526         private Integer mMainColor = DEFAULT_MAIN_COLOR;
527         private PackageDownloadInfo mDeviceAdminDownloadInfo;
528         private DisclaimersParam mDisclaimersParam;
529         private PersistableBundle mAdminExtrasBundle;
530         private boolean mStartedByTrustedSource = DEFAULT_STARTED_BY_TRUSTED_SOURCE;
531         private boolean mIsNfc = DEFAULT_IS_NFC;
532         private boolean mIsCloudEnrollment = DEFAULT_IS_CLOUD_ENROLLMENT;
533         private boolean mLeaveAllSystemAppsEnabled = DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED;
534         private boolean mSkipEncryption = DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION;
535         private boolean mSkipUserConsent = DEFAULT_EXTRA_PROVISIONING_SKIP_USER_CONSENT;
536         private boolean mSkipEducationScreens = DEFAULT_EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS;
537         private boolean mSkipUserSetup = DEFAULT_SKIP_USER_SETUP;
538         private boolean mKeepAccountMigrated = DEFAULT_EXTRA_PROVISIONING_KEEP_ACCOUNT_MIGRATED;
539         private boolean mUseMobileData = DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA;
540         private boolean mIsOrganizationOwnedProvisioning = false;
541         private @ProvisioningMode int mProvisioningMode = PROVISIONING_MODE_UNDECIDED;
542 
setProvisioningId(long provisioningId)543         public Builder setProvisioningId(long provisioningId) {
544             mProvisioningId = provisioningId;
545             return this;
546         }
547 
setTimeZone(String timeZone)548         public Builder setTimeZone(String timeZone) {
549             mTimeZone = timeZone;
550             return this;
551         }
552 
setLocalTime(long localTime)553         public Builder setLocalTime(long localTime) {
554             mLocalTime = localTime;
555             return this;
556         }
557 
setLocale(Locale locale)558         public Builder setLocale(Locale locale) {
559             mLocale = locale;
560             return this;
561         }
562 
setWifiInfo(WifiInfo wifiInfo)563         public Builder setWifiInfo(WifiInfo wifiInfo) {
564             mWifiInfo = wifiInfo;
565             return this;
566         }
567 
568         @Deprecated
setDeviceAdminPackageName(String deviceAdminPackageName)569         public Builder setDeviceAdminPackageName(String deviceAdminPackageName) {
570             mDeviceAdminPackageName = deviceAdminPackageName;
571             return this;
572         }
573 
setDeviceAdminComponentName(ComponentName deviceAdminComponentName)574         public Builder setDeviceAdminComponentName(ComponentName deviceAdminComponentName) {
575             mDeviceAdminComponentName = deviceAdminComponentName;
576             return this;
577         }
578 
setDeviceAdminLabel(String deviceAdminLabel)579         public Builder setDeviceAdminLabel(String deviceAdminLabel) {
580             mDeviceAdminLabel = deviceAdminLabel;
581             return this;
582         }
583 
setOrganizationName(String organizationName)584         public Builder setOrganizationName(String organizationName) {
585             mOrganizationName = organizationName;
586             return this;
587         }
588 
setSupportUrl(String supportUrl)589         public Builder setSupportUrl(String supportUrl) {
590             mSupportUrl = supportUrl;
591             return this;
592         }
593 
setDeviceAdminIconFilePath(String deviceAdminIconFilePath)594         public Builder setDeviceAdminIconFilePath(String deviceAdminIconFilePath) {
595             mDeviceAdminIconFilePath = deviceAdminIconFilePath;
596             return this;
597         }
598 
setAccountToMigrate(Account accountToMigrate)599         public Builder setAccountToMigrate(Account accountToMigrate) {
600             mAccountToMigrate = accountToMigrate;
601             return this;
602         }
603 
setProvisioningAction(String provisioningAction)604         public Builder setProvisioningAction(String provisioningAction) {
605             mProvisioningAction = provisioningAction;
606             return this;
607         }
608 
setMainColor(Integer mainColor)609         public Builder setMainColor(Integer mainColor) {
610             mMainColor = mainColor;
611             return this;
612         }
613 
setDeviceAdminDownloadInfo(PackageDownloadInfo deviceAdminDownloadInfo)614         public Builder setDeviceAdminDownloadInfo(PackageDownloadInfo deviceAdminDownloadInfo) {
615             mDeviceAdminDownloadInfo = deviceAdminDownloadInfo;
616             return this;
617         }
618 
setDisclaimersParam(DisclaimersParam disclaimersParam)619         public Builder setDisclaimersParam(DisclaimersParam disclaimersParam) {
620             mDisclaimersParam = disclaimersParam;
621             return this;
622         }
623 
setAdminExtrasBundle(PersistableBundle adminExtrasBundle)624         public Builder setAdminExtrasBundle(PersistableBundle adminExtrasBundle) {
625             mAdminExtrasBundle = adminExtrasBundle;
626             return this;
627         }
628 
setStartedByTrustedSource(boolean startedByTrustedSource)629         public Builder setStartedByTrustedSource(boolean startedByTrustedSource) {
630             mStartedByTrustedSource = startedByTrustedSource;
631             return this;
632         }
633 
setIsNfc(boolean isNfc)634         public Builder setIsNfc(boolean isNfc) {
635             mIsNfc = isNfc;
636             return this;
637         }
638 
setIsCloudEnrollment(boolean isCloudEnrollment)639         public Builder setIsCloudEnrollment(boolean isCloudEnrollment) {
640             mIsCloudEnrollment = isCloudEnrollment;
641             return this;
642         }
643 
setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled)644         public Builder setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled) {
645             mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled;
646             return this;
647         }
648 
setSkipEncryption(boolean skipEncryption)649         public Builder setSkipEncryption(boolean skipEncryption) {
650             mSkipEncryption = skipEncryption;
651             return this;
652         }
653 
setSkipUserConsent(boolean skipUserConsent)654         public Builder setSkipUserConsent(boolean skipUserConsent) {
655             mSkipUserConsent = skipUserConsent;
656             return this;
657         }
658 
setSkipEducationScreens(boolean skipEducationScreens)659         public Builder setSkipEducationScreens(boolean skipEducationScreens) {
660             mSkipEducationScreens = skipEducationScreens;
661             return this;
662         }
663 
setSkipUserSetup(boolean skipUserSetup)664         public Builder setSkipUserSetup(boolean skipUserSetup) {
665             mSkipUserSetup = skipUserSetup;
666             return this;
667         }
668 
setKeepAccountMigrated(boolean keepAccountMigrated)669         public Builder setKeepAccountMigrated(boolean keepAccountMigrated) {
670             mKeepAccountMigrated = keepAccountMigrated;
671             return this;
672         }
673 
setUseMobileData(boolean useMobileData)674         public Builder setUseMobileData(boolean useMobileData) {
675             mUseMobileData = useMobileData;
676             return this;
677         }
678 
setIsOrganizationOwnedProvisioning(boolean isOrganizationOwnedProvisioning)679         public Builder setIsOrganizationOwnedProvisioning(boolean isOrganizationOwnedProvisioning) {
680             mIsOrganizationOwnedProvisioning = isOrganizationOwnedProvisioning;
681             return this;
682         }
683 
setProvisioningMode(@rovisioningMode int provisioningMode)684         public Builder setProvisioningMode(@ProvisioningMode int provisioningMode) {
685             mProvisioningMode = provisioningMode;
686             return this;
687         }
688 
689         /**
690          * Builds the {@link ProvisioningParams} object. Note that {@link
691          * #setProvisioningAction(String)} and {@link #setDeviceAdminComponentName(ComponentName)}
692          * methods must be called with a non-null parameter before this is called.
693          */
build()694         public ProvisioningParams build() {
695             return new ProvisioningParams(this);
696         }
697 
builder()698         public static Builder builder() {
699             return new Builder();
700         }
701     }
702 }
703