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