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_NAME; 23 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DISCLAIMERS; 24 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION; 25 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED; 26 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE; 27 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME; 28 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ORGANIZATION_NAME; 29 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS; 30 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION; 31 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_SUPPORT_URL; 32 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE; 33 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_USE_MOBILE_DATA; 34 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_CLOUD_ENROLLMENT; 35 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_MANAGED_ACCOUNT; 36 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_QR_CODE; 37 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_UNSPECIFIED; 38 39 import static com.android.internal.util.Preconditions.checkArgument; 40 import static com.android.internal.util.Preconditions.checkNotNull; 41 import static com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences.DEFAULT_PROVISIONING_ID; 42 import static com.android.managedprovisioning.common.StoreUtils.accountToPersistableBundle; 43 import static com.android.managedprovisioning.common.StoreUtils.getObjectAttrFromPersistableBundle; 44 import static com.android.managedprovisioning.common.StoreUtils.getStringAttrFromPersistableBundle; 45 import static com.android.managedprovisioning.common.StoreUtils.putPersistableBundlableIfNotNull; 46 47 import android.accounts.Account; 48 import android.annotation.IntDef; 49 import android.app.admin.DevicePolicyManager; 50 import android.content.ComponentName; 51 import android.content.Context; 52 import android.os.Parcel; 53 import android.os.Parcelable; 54 import android.os.PersistableBundle; 55 import android.util.AtomicFile; 56 import android.util.Xml; 57 58 import androidx.annotation.Nullable; 59 60 import com.android.internal.util.FastXmlSerializer; 61 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException; 62 import com.android.managedprovisioning.common.PersistableBundlable; 63 import com.android.managedprovisioning.common.ProvisionLogger; 64 import com.android.managedprovisioning.common.StoreUtils; 65 import com.android.managedprovisioning.common.Utils; 66 67 import org.xmlpull.v1.XmlPullParser; 68 import org.xmlpull.v1.XmlPullParserException; 69 import org.xmlpull.v1.XmlSerializer; 70 71 import java.io.File; 72 import java.io.FileInputStream; 73 import java.io.FileOutputStream; 74 import java.io.IOException; 75 import java.lang.annotation.Retention; 76 import java.lang.annotation.RetentionPolicy; 77 import java.nio.charset.StandardCharsets; 78 import java.util.ArrayList; 79 import java.util.Arrays; 80 import java.util.Locale; 81 import java.util.stream.Collectors; 82 83 /** 84 * Provisioning parameters for Device Owner and Profile Owner provisioning. 85 */ 86 public final class ProvisioningParams extends PersistableBundlable { 87 public static final long DEFAULT_LOCAL_TIME = -1; 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_QR_PROVISIONING = 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_EDUCATION_SCREENS = false; 94 public static final boolean DEFAULT_EXTRA_PROVISIONING_KEEP_ACCOUNT_MIGRATED = false; 95 public static final boolean DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA = false; 96 public static final boolean DEFAULT_EXTRA_PROVISIONING_IS_ORGANIZATION_OWNED = false; 97 public static final ArrayList<Integer> DEFAULT_EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES = 98 new ArrayList<>(); 99 public static final int DEFAULT_EXTRA_PROVISIONING_SUPPORTED_MODES = 0; 100 public static final boolean DEFAULT_EXTRA_PROVISIONING_SKIP_OWNERSHIP_DISCLAIMER = false; 101 public static final boolean DEFAULT_EXTRA_PROVISIONING_RETURN_BEFORE_POLICY_COMPLIANCE = false; 102 public static final boolean DEFAULT_EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT = false; 103 104 // Intent extra used internally for passing data between activities and service. 105 public static final String EXTRA_PROVISIONING_PARAMS = "provisioningParams"; 106 107 public static final int FLOW_TYPE_UNSPECIFIED = 0; 108 public static final int FLOW_TYPE_LEGACY = 1; 109 public static final int FLOW_TYPE_ADMIN_INTEGRATED = 2; 110 111 @IntDef(prefix = { "PROVISIONING_TRIGGER_" }, value = { 112 PROVISIONING_TRIGGER_UNSPECIFIED, 113 PROVISIONING_TRIGGER_CLOUD_ENROLLMENT, 114 PROVISIONING_TRIGGER_QR_CODE, 115 PROVISIONING_TRIGGER_MANAGED_ACCOUNT 116 }) 117 @Retention(RetentionPolicy.SOURCE) 118 public @interface ProvisioningTrigger {} 119 120 @IntDef(prefix = { "FLOW_TYPE_" }, value = { 121 FLOW_TYPE_UNSPECIFIED, 122 FLOW_TYPE_LEGACY, 123 FLOW_TYPE_ADMIN_INTEGRATED 124 }) 125 @Retention(RetentionPolicy.SOURCE) 126 public @interface FlowType {} 127 128 private static final String TAG_PROVISIONING_ID = "provisioning-id"; 129 private static final String TAG_PROVISIONING_PARAMS = "provisioning-params"; 130 private static final String TAG_WIFI_INFO = "wifi-info"; 131 private static final String TAG_PACKAGE_DOWNLOAD_INFO = "download-info"; 132 private static final String TAG_STARTED_BY_TRUSTED_SOURCE = "started-by-trusted-source"; 133 private static final String TAG_IS_NFC = "started-is-nfc"; 134 private static final String TAG_IS_QR_PROVISIONING = "is-qr-provisioning"; 135 private static final String TAG_PROVISIONING_ACTION = "provisioning-action"; 136 private static final String TAG_IS_ORGANIZATION_OWNED_PROVISIONING = 137 "is-organization-owned-provisioning"; 138 private static final String TAG_ALLOWED_PROVISIONING_MODES = 139 "allowed-provisioning-modes"; 140 private static final String TAG_INITIATOR_REQUESTED_PROVISIONING_MODES = 141 "initiator-requested-provisioning-modes"; 142 private static final String TAG_FLOW_TYPE = "flow-type"; 143 private static final String TAG_ALLOW_PROVISIONING_AFTER_USER_SETUP_COMPLETE = 144 "allow-provisioning-after-user-setup-complete"; 145 private static final String TAG_PROVISIONING_TRIGGER = "provisioning-trigger"; 146 private static final String TAG_SKIP_OWNERSHIP_DISCLAIMER = "skip-ownership-disclaimer"; 147 private static final String TAG_PROVISIONING_RETURN_BEFORE_POLICY_COMPLIANCE = 148 "provisioning-return-before-policy-compliance"; 149 private static final String TAG_DEVICE_OWNER_PERMISSION_GRANT_OPT_OUT = 150 "device-owner-opt-out-of-permission-grants"; 151 152 public static final Parcelable.Creator<ProvisioningParams> CREATOR 153 = new Parcelable.Creator<ProvisioningParams>() { 154 @Override 155 public ProvisioningParams createFromParcel(Parcel in) { 156 return new ProvisioningParams(in); 157 } 158 159 @Override 160 public ProvisioningParams[] newArray(int size) { 161 return new ProvisioningParams[size]; 162 } 163 }; 164 165 public final long provisioningId; 166 167 @Nullable 168 public final String timeZone; 169 170 public final long localTime; 171 172 @Nullable 173 public final Locale locale; 174 175 /** WiFi configuration. */ 176 @Nullable 177 public final WifiInfo wifiInfo; 178 179 public final boolean useMobileData; 180 181 /** 182 * Package name of the device admin package. 183 * 184 * <p>At least one one of deviceAdminPackageName and deviceAdminComponentName should be 185 * non-null. 186 * <p> 187 * In most cases, it is preferable to access the admin package name using 188 * {@link #inferDeviceAdminPackageName}. 189 */ 190 @Deprecated 191 @Nullable 192 public final String deviceAdminPackageName; 193 194 /** 195 * {@link ComponentName} of the device admin package. 196 * 197 * <p>At least one one of deviceAdminPackageName and deviceAdminComponentName should be 198 * non-null. 199 * <p> 200 * In most cases, it is preferable to access the admin component name using 201 * {@link #inferDeviceAdminComponentName(Utils, Context, int)} . 202 */ 203 @Nullable 204 public final ComponentName deviceAdminComponentName; 205 206 public final String organizationName; 207 public final String supportUrl; 208 209 /** {@link Account} that should be migrated to the managed profile. */ 210 @Nullable 211 public final Account accountToMigrate; 212 213 /** True if the account will not be removed from the calling user after it is migrated. */ 214 public final boolean keepAccountMigrated; 215 216 /** Provisioning action comes along with the provisioning data. */ 217 public final String provisioningAction; 218 219 /** The download information of device admin package. */ 220 @Nullable 221 public final PackageDownloadInfo deviceAdminDownloadInfo; 222 223 /** List of disclaimers */ 224 @Nullable 225 public final DisclaimersParam disclaimersParam; 226 227 /** 228 * Custom key-value pairs from enterprise mobility management which are passed to device admin 229 * package after provisioning. 230 * 231 * <p>Note that {@link ProvisioningParams} is not immutable because this field is mutable. 232 */ 233 @Nullable 234 public final PersistableBundle adminExtrasBundle; 235 236 /** 237 * True iff provisioning flow was started by a trusted app. This includes Nfc bump and QR code. 238 */ 239 public final boolean startedByTrustedSource; 240 241 public final boolean isNfc; 242 243 public final boolean isQrProvisioning; 244 245 /** True if all system apps should be enabled after provisioning. */ 246 public final boolean leaveAllSystemAppsEnabled; 247 248 /** True if device encryption should be skipped. */ 249 public final boolean skipEncryption; 250 251 public final boolean skipEducationScreens; 252 253 /** 254 * True if the provisioning is done on a device owned by the organization. 255 * 256 * <p>For the admin-integrated flow, this field is only set after the admin app 257 * picks a provisioning mode. 258 */ 259 public final boolean isOrganizationOwnedProvisioning; 260 261 /** 262 * {@link ArrayList} of {@link Integer} containing a subset of {{@link 263 * DevicePolicyManager#PROVISIONING_MODE_MANAGED_PROFILE}, {@link 264 * DevicePolicyManager#PROVISIONING_MODE_FULLY_MANAGED_DEVICE}, {@link 265 * DevicePolicyManager#PROVISIONING_MODE_MANAGED_PROFILE_ON_PERSONAL_DEVICE}}. 266 **/ 267 public final ArrayList<Integer> allowedProvisioningModes; 268 269 /** 270 * Integer specifying what provisioning modes have been specified by the provisioning 271 * initiator. 272 * 273 * <p>Can be a combination of {@link 274 * DevicePolicyManager#FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED}, {@link 275 * DevicePolicyManager#FLAG_SUPPORTED_MODES_PERSONALLY_OWNED}, {@link 276 * DevicePolicyManager#FLAG_SUPPORTED_MODES_DEVICE_OWNER} or if not relevant to the 277 * admin-integrated flow, {@link ProvisioningParams#DEFAULT_EXTRA_PROVISIONING_SUPPORTED_MODES}. 278 * 279 */ 280 public final int initiatorRequestedProvisioningModes; 281 282 /** True if provisioning after user setup complete should be allowed. */ 283 public final boolean allowProvisioningAfterUserSetupComplete; 284 285 /** 286 * The type of flow to be performed. 287 * <p>Must be one of {@link #FLOW_TYPE_UNSPECIFIED}, {@link #FLOW_TYPE_LEGACY} or {@link 288 * #FLOW_TYPE_ADMIN_INTEGRATED}. 289 **/ 290 public final @FlowType int flowType; 291 292 /** 293 * The way provisioning was started. 294 * <p>Can be one of {@link DevicePolicyManager#PROVISIONING_TRIGGER_CLOUD_ENROLLMENT}, {@link 295 * DevicePolicyManager#PROVISIONING_TRIGGER_QR_CODE}, {@link 296 * DevicePolicyManager#PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER} or {@link 297 * DevicePolicyManager#PROVISIONING_TRIGGER_UNSPECIFIED}. 298 */ 299 public final @ProvisioningTrigger int provisioningTrigger; 300 301 /** 302 * Whether to skip the ownership disclaimer. 303 */ 304 public final boolean skipOwnershipDisclaimer; 305 306 /** 307 * True if the provisioning flow should return before starting the admin app's {@link 308 * DevicePolicyManager#ACTION_ADMIN_POLICY_COMPLIANCE} handler. Default value is {@code true}. 309 */ 310 public final boolean returnBeforePolicyCompliance; 311 312 /** 313 * True if the device owner has opted out of controlling permission grants for 314 * sensors-related permissions. See {@link DevicePolicyManager#setPermissionGrantState} 315 */ 316 public final boolean deviceOwnerPermissionGrantOptOut; 317 inferStaticDeviceAdminPackageName(ComponentName deviceAdminComponentName, String deviceAdminPackageName)318 public static String inferStaticDeviceAdminPackageName(ComponentName deviceAdminComponentName, 319 String deviceAdminPackageName) { 320 if (deviceAdminComponentName != null) { 321 return deviceAdminComponentName.getPackageName(); 322 } 323 return deviceAdminPackageName; 324 } 325 inferDeviceAdminPackageName()326 public String inferDeviceAdminPackageName() { 327 return inferStaticDeviceAdminPackageName(deviceAdminComponentName, deviceAdminPackageName); 328 } 329 330 /** 331 * Due to legacy reason, DPC is allowed to provide either package name or the component name. 332 * If component name is not {@code null}, we will return it right away. Otherwise, we will 333 * infer the component name. 334 * <p> 335 * In most cases, it is preferable to access the admin component name using this method. 336 * But if the purpose is to verify the device admin component name, you should use 337 * {@link Utils#findDeviceAdmin(String, ComponentName, Context, int)} instead. 338 */ inferDeviceAdminComponentName(Utils utils, Context context, int userId)339 public ComponentName inferDeviceAdminComponentName(Utils utils, Context context, int userId) 340 throws IllegalProvisioningArgumentException { 341 if (deviceAdminComponentName != null) { 342 return deviceAdminComponentName; 343 } 344 return utils.findDeviceAdmin( 345 deviceAdminPackageName, deviceAdminComponentName, context, userId); 346 } 347 ProvisioningParams(Builder builder)348 private ProvisioningParams(Builder builder) { 349 provisioningId = builder.mProvisioningId; 350 timeZone = builder.mTimeZone; 351 localTime = builder.mLocalTime; 352 locale = builder.mLocale; 353 354 wifiInfo = builder.mWifiInfo; 355 useMobileData = builder.mUseMobileData; 356 357 deviceAdminComponentName = builder.mDeviceAdminComponentName; 358 deviceAdminPackageName = builder.mDeviceAdminPackageName; 359 organizationName = builder.mOrganizationName; 360 supportUrl = builder.mSupportUrl; 361 362 deviceAdminDownloadInfo = builder.mDeviceAdminDownloadInfo; 363 disclaimersParam = builder.mDisclaimersParam; 364 365 adminExtrasBundle = builder.mAdminExtrasBundle; 366 367 startedByTrustedSource = builder.mStartedByTrustedSource; 368 isNfc = builder.mIsNfc; 369 isQrProvisioning = builder.mIsQrProvisioning; 370 leaveAllSystemAppsEnabled = builder.mLeaveAllSystemAppsEnabled; 371 skipEncryption = builder.mSkipEncryption; 372 accountToMigrate = builder.mAccountToMigrate; 373 provisioningAction = checkNotNull(builder.mProvisioningAction); 374 skipEducationScreens = builder.mSkipEducationScreens; 375 keepAccountMigrated = builder.mKeepAccountMigrated; 376 377 isOrganizationOwnedProvisioning = builder.mIsOrganizationOwnedProvisioning; 378 allowedProvisioningModes = builder.mAllowedProvisioningModes; 379 initiatorRequestedProvisioningModes = builder.mInitiatorRequestedProvisioningModes; 380 flowType = builder.mFlowType; 381 allowProvisioningAfterUserSetupComplete = builder.mAllowProvisioningAfterUserSetupComplete; 382 provisioningTrigger = builder.mProvisioningTrigger; 383 skipOwnershipDisclaimer = builder.mSkipOwnershipDisclaimer; 384 returnBeforePolicyCompliance = builder.mReturnBeforePolicyCompliance; 385 deviceOwnerPermissionGrantOptOut = builder.mDeviceOwnerPermissionGrantOptOut; 386 387 validateFields(); 388 } 389 ProvisioningParams(Parcel in)390 private ProvisioningParams(Parcel in) { 391 this(createBuilderFromPersistableBundle( 392 PersistableBundlable.getPersistableBundleFromParcel(in))); 393 } 394 validateFields()395 private void validateFields() { 396 checkArgument(deviceAdminPackageName != null || deviceAdminComponentName != null); 397 } 398 399 @Override toPersistableBundle()400 public PersistableBundle toPersistableBundle() { 401 final PersistableBundle bundle = new PersistableBundle(); 402 403 bundle.putLong(TAG_PROVISIONING_ID, provisioningId); 404 bundle.putString(EXTRA_PROVISIONING_TIME_ZONE, timeZone); 405 bundle.putLong(EXTRA_PROVISIONING_LOCAL_TIME, localTime); 406 bundle.putString(EXTRA_PROVISIONING_LOCALE, StoreUtils.localeToString(locale)); 407 putPersistableBundlableIfNotNull(bundle, TAG_WIFI_INFO, wifiInfo); 408 bundle.putBoolean(EXTRA_PROVISIONING_USE_MOBILE_DATA, useMobileData); 409 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, deviceAdminPackageName); 410 bundle.putString(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, 411 StoreUtils.componentNameToString(deviceAdminComponentName)); 412 bundle.putString(EXTRA_PROVISIONING_ORGANIZATION_NAME, organizationName); 413 bundle.putString(EXTRA_PROVISIONING_SUPPORT_URL, supportUrl); 414 bundle.putPersistableBundle(EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, accountToMigrate == null 415 ? null : accountToPersistableBundle(accountToMigrate)); 416 bundle.putString(TAG_PROVISIONING_ACTION, provisioningAction); 417 putPersistableBundlableIfNotNull(bundle, TAG_PACKAGE_DOWNLOAD_INFO, 418 deviceAdminDownloadInfo); 419 putPersistableBundlableIfNotNull(bundle, EXTRA_PROVISIONING_DISCLAIMERS, 420 disclaimersParam); 421 bundle.putPersistableBundle(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, adminExtrasBundle); 422 bundle.putBoolean(TAG_STARTED_BY_TRUSTED_SOURCE, startedByTrustedSource); 423 bundle.putBoolean(TAG_IS_NFC, isNfc); 424 bundle.putBoolean(TAG_IS_QR_PROVISIONING, isQrProvisioning); 425 bundle.putBoolean(EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED, 426 leaveAllSystemAppsEnabled); 427 bundle.putBoolean(EXTRA_PROVISIONING_SKIP_ENCRYPTION, skipEncryption); 428 bundle.putBoolean(EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS, skipEducationScreens); 429 bundle.putBoolean(EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION, keepAccountMigrated); 430 bundle.putBoolean(TAG_IS_ORGANIZATION_OWNED_PROVISIONING, isOrganizationOwnedProvisioning); 431 bundle.putIntArray(TAG_ALLOWED_PROVISIONING_MODES, 432 integerArrayListToIntArray(allowedProvisioningModes)); 433 bundle.putInt(TAG_INITIATOR_REQUESTED_PROVISIONING_MODES, 434 initiatorRequestedProvisioningModes); 435 bundle.putInt(TAG_FLOW_TYPE, flowType); 436 bundle.putBoolean(TAG_ALLOW_PROVISIONING_AFTER_USER_SETUP_COMPLETE, 437 allowProvisioningAfterUserSetupComplete); 438 bundle.putInt(TAG_PROVISIONING_TRIGGER, provisioningTrigger); 439 bundle.putBoolean(TAG_SKIP_OWNERSHIP_DISCLAIMER, skipOwnershipDisclaimer); 440 bundle.putBoolean(TAG_PROVISIONING_RETURN_BEFORE_POLICY_COMPLIANCE, 441 returnBeforePolicyCompliance); 442 bundle.putBoolean(TAG_DEVICE_OWNER_PERMISSION_GRANT_OPT_OUT, 443 deviceOwnerPermissionGrantOptOut); 444 return bundle; 445 } 446 fromPersistableBundle(PersistableBundle bundle)447 /* package */ static ProvisioningParams fromPersistableBundle(PersistableBundle bundle) { 448 return createBuilderFromPersistableBundle(bundle).build(); 449 } 450 createBuilderFromPersistableBundle(PersistableBundle bundle)451 private static Builder createBuilderFromPersistableBundle(PersistableBundle bundle) { 452 Builder builder = new Builder(); 453 builder.setProvisioningId(bundle.getLong(TAG_PROVISIONING_ID, DEFAULT_PROVISIONING_ID)); 454 builder.setTimeZone(bundle.getString(EXTRA_PROVISIONING_TIME_ZONE)); 455 builder.setLocalTime(bundle.getLong(EXTRA_PROVISIONING_LOCAL_TIME)); 456 builder.setLocale(getStringAttrFromPersistableBundle(bundle, 457 EXTRA_PROVISIONING_LOCALE, StoreUtils::stringToLocale)); 458 builder.setUseMobileData(bundle.getBoolean(EXTRA_PROVISIONING_USE_MOBILE_DATA)); 459 builder.setWifiInfo(getObjectAttrFromPersistableBundle(bundle, 460 TAG_WIFI_INFO, WifiInfo::fromPersistableBundle)); 461 builder.setDeviceAdminPackageName(bundle.getString( 462 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME)); 463 builder.setDeviceAdminComponentName(getStringAttrFromPersistableBundle(bundle, 464 EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, StoreUtils::stringToComponentName)); 465 builder.setOrganizationName(bundle.getString(EXTRA_PROVISIONING_ORGANIZATION_NAME)); 466 builder.setSupportUrl(bundle.getString(EXTRA_PROVISIONING_SUPPORT_URL)); 467 builder.setAccountToMigrate(getObjectAttrFromPersistableBundle(bundle, 468 EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE, StoreUtils::persistableBundleToAccount)); 469 builder.setProvisioningAction(bundle.getString(TAG_PROVISIONING_ACTION)); 470 builder.setDeviceAdminDownloadInfo(getObjectAttrFromPersistableBundle(bundle, 471 TAG_PACKAGE_DOWNLOAD_INFO, PackageDownloadInfo::fromPersistableBundle)); 472 builder.setDisclaimersParam(getObjectAttrFromPersistableBundle(bundle, 473 EXTRA_PROVISIONING_DISCLAIMERS, DisclaimersParam::fromPersistableBundle)); 474 builder.setAdminExtrasBundle(bundle.getPersistableBundle( 475 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)); 476 builder.setStartedByTrustedSource(bundle.getBoolean(TAG_STARTED_BY_TRUSTED_SOURCE)); 477 builder.setIsNfc(bundle.getBoolean(TAG_IS_NFC)); 478 builder.setIsQrProvisioning(bundle.getBoolean(TAG_IS_QR_PROVISIONING)); 479 builder.setSkipEncryption(bundle.getBoolean(EXTRA_PROVISIONING_SKIP_ENCRYPTION)); 480 builder.setLeaveAllSystemAppsEnabled(bundle.getBoolean( 481 EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED)); 482 builder.setSkipEducationScreens(bundle.getBoolean(EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS)); 483 builder.setKeepAccountMigrated(bundle.getBoolean( 484 EXTRA_PROVISIONING_KEEP_ACCOUNT_ON_MIGRATION)); 485 builder.setIsOrganizationOwnedProvisioning(bundle.getBoolean( 486 TAG_IS_ORGANIZATION_OWNED_PROVISIONING)); 487 builder.setAllowedProvisioningModes( 488 intArrayToIntegerArrayList(bundle.getIntArray(TAG_ALLOWED_PROVISIONING_MODES))); 489 builder.setInitiatorRequestedProvisioningModes(bundle.getInt( 490 TAG_INITIATOR_REQUESTED_PROVISIONING_MODES)); 491 builder.setFlowType(bundle.getInt(TAG_FLOW_TYPE)); 492 builder.setAllowProvisioningAfterUserSetupComplete(bundle.getBoolean( 493 TAG_ALLOW_PROVISIONING_AFTER_USER_SETUP_COMPLETE)); 494 builder.setProvisioningTrigger(bundle.getInt(TAG_PROVISIONING_TRIGGER)); 495 builder.setSkipOwnershipDisclaimer(bundle.getBoolean(TAG_SKIP_OWNERSHIP_DISCLAIMER)); 496 builder.setReturnBeforePolicyCompliance(bundle.getBoolean( 497 TAG_PROVISIONING_RETURN_BEFORE_POLICY_COMPLIANCE)); 498 builder.setDeviceOwnerPermissionGrantOptOut( 499 bundle.getBoolean(TAG_DEVICE_OWNER_PERMISSION_GRANT_OPT_OUT)); 500 return builder; 501 } 502 intArrayToIntegerArrayList(int[] intArray)503 private static ArrayList<Integer> intArrayToIntegerArrayList(int[] intArray) { 504 return Arrays.stream(intArray).boxed().collect(Collectors.toCollection(ArrayList::new)); 505 } 506 integerArrayListToIntArray(ArrayList<Integer> arrayList)507 private static int[] integerArrayListToIntArray(ArrayList<Integer> arrayList) { 508 return arrayList.stream().mapToInt(Integer::valueOf).toArray(); 509 } 510 toBuilder()511 public Builder toBuilder() { 512 return createBuilderFromPersistableBundle(toPersistableBundle()); 513 } 514 515 @Override toString()516 public String toString() { 517 return "ProvisioningParams values: " + toPersistableBundle().toString(); 518 } 519 520 /** 521 * Saves the ProvisioningParams to the specified file. 522 */ save(File file)523 public void save(File file) { 524 ProvisionLogger.logd("Saving ProvisioningParams to " + file); 525 AtomicFile atomicFile = null; 526 FileOutputStream stream = null; 527 try { 528 atomicFile = new AtomicFile(file); 529 stream = atomicFile.startWrite(); 530 XmlSerializer serializer = new FastXmlSerializer(); 531 serializer.setOutput(stream, StandardCharsets.UTF_8.name()); 532 serializer.startDocument(null, true); 533 serializer.startTag(null, TAG_PROVISIONING_PARAMS); 534 toPersistableBundle().saveToXml(serializer); 535 serializer.endTag(null, TAG_PROVISIONING_PARAMS); 536 serializer.endDocument(); 537 atomicFile.finishWrite(stream); 538 } catch (IOException | XmlPullParserException e) { 539 ProvisionLogger.loge("Caught exception while trying to save Provisioning Params to " 540 + " file " + file, e); 541 file.delete(); 542 if (atomicFile != null) { 543 atomicFile.failWrite(stream); 544 } 545 } 546 } 547 cleanUp()548 public void cleanUp() { 549 if (disclaimersParam != null) { 550 disclaimersParam.cleanUp(); 551 } 552 } 553 554 /** 555 * Loads the ProvisioningParams From the specified file. 556 */ load(File file)557 public static ProvisioningParams load(File file) { 558 if (!file.exists()) { 559 return null; 560 } 561 ProvisionLogger.logd("Loading ProvisioningParams from " + file); 562 try (FileInputStream stream = new FileInputStream(file)) { 563 XmlPullParser parser = Xml.newPullParser(); 564 parser.setInput(stream, null); 565 return load(parser); 566 } catch (IOException | XmlPullParserException e) { 567 ProvisionLogger.loge("Caught exception while trying to load the provisioning params" 568 + " from file " + file, e); 569 return null; 570 } 571 } 572 load(XmlPullParser parser)573 private static ProvisioningParams load(XmlPullParser parser) throws XmlPullParserException, 574 IOException { 575 int type; 576 int outerDepth = parser.getDepth(); 577 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 578 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 579 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 580 continue; 581 } 582 String tag = parser.getName(); 583 switch (tag) { 584 case TAG_PROVISIONING_PARAMS: 585 return createBuilderFromPersistableBundle( 586 PersistableBundle.restoreFromXml(parser)).build(); 587 } 588 } 589 return new Builder().build(); 590 } 591 592 public final static class Builder { 593 private long mProvisioningId; 594 private String mTimeZone; 595 private long mLocalTime = DEFAULT_LOCAL_TIME; 596 private Locale mLocale; 597 private WifiInfo mWifiInfo; 598 private String mDeviceAdminPackageName; 599 private ComponentName mDeviceAdminComponentName; 600 private String mOrganizationName; 601 private String mSupportUrl; 602 private Account mAccountToMigrate; 603 private String mProvisioningAction; 604 private PackageDownloadInfo mDeviceAdminDownloadInfo; 605 private DisclaimersParam mDisclaimersParam; 606 private PersistableBundle mAdminExtrasBundle; 607 private boolean mStartedByTrustedSource = DEFAULT_STARTED_BY_TRUSTED_SOURCE; 608 private boolean mIsNfc = DEFAULT_IS_NFC; 609 private boolean mIsQrProvisioning = DEFAULT_IS_QR_PROVISIONING; 610 private boolean mLeaveAllSystemAppsEnabled = DEFAULT_LEAVE_ALL_SYSTEM_APPS_ENABLED; 611 private boolean mSkipEncryption = DEFAULT_EXTRA_PROVISIONING_SKIP_ENCRYPTION; 612 private boolean mSkipEducationScreens = DEFAULT_EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS; 613 private boolean mKeepAccountMigrated = DEFAULT_EXTRA_PROVISIONING_KEEP_ACCOUNT_MIGRATED; 614 private boolean mUseMobileData = DEFAULT_EXTRA_PROVISIONING_USE_MOBILE_DATA; 615 private boolean mIsOrganizationOwnedProvisioning = 616 DEFAULT_EXTRA_PROVISIONING_IS_ORGANIZATION_OWNED; 617 private ArrayList<Integer> mAllowedProvisioningModes = 618 DEFAULT_EXTRA_PROVISIONING_ALLOWED_PROVISIONING_MODES; 619 private int mInitiatorRequestedProvisioningModes = 620 DEFAULT_EXTRA_PROVISIONING_SUPPORTED_MODES; 621 private @FlowType int mFlowType = FLOW_TYPE_UNSPECIFIED; 622 private boolean mAllowProvisioningAfterUserSetupComplete = false; 623 private @ProvisioningTrigger int mProvisioningTrigger = PROVISIONING_TRIGGER_UNSPECIFIED; 624 private boolean mSkipOwnershipDisclaimer = 625 DEFAULT_EXTRA_PROVISIONING_SKIP_OWNERSHIP_DISCLAIMER; 626 private boolean mReturnBeforePolicyCompliance = 627 DEFAULT_EXTRA_PROVISIONING_RETURN_BEFORE_POLICY_COMPLIANCE; 628 private boolean mDeviceOwnerPermissionGrantOptOut = 629 DEFAULT_EXTRA_PROVISIONING_PERMISSION_GRANT_OPT_OUT; 630 setProvisioningId(long provisioningId)631 public Builder setProvisioningId(long provisioningId) { 632 mProvisioningId = provisioningId; 633 return this; 634 } 635 setTimeZone(String timeZone)636 public Builder setTimeZone(String timeZone) { 637 mTimeZone = timeZone; 638 return this; 639 } 640 setLocalTime(long localTime)641 public Builder setLocalTime(long localTime) { 642 mLocalTime = localTime; 643 return this; 644 } 645 setLocale(Locale locale)646 public Builder setLocale(Locale locale) { 647 mLocale = locale; 648 return this; 649 } 650 setWifiInfo(WifiInfo wifiInfo)651 public Builder setWifiInfo(WifiInfo wifiInfo) { 652 mWifiInfo = wifiInfo; 653 return this; 654 } 655 656 @Deprecated setDeviceAdminPackageName(String deviceAdminPackageName)657 public Builder setDeviceAdminPackageName(String deviceAdminPackageName) { 658 mDeviceAdminPackageName = deviceAdminPackageName; 659 return this; 660 } 661 setDeviceAdminComponentName(ComponentName deviceAdminComponentName)662 public Builder setDeviceAdminComponentName(ComponentName deviceAdminComponentName) { 663 mDeviceAdminComponentName = deviceAdminComponentName; 664 return this; 665 } 666 setOrganizationName(String organizationName)667 public Builder setOrganizationName(String organizationName) { 668 mOrganizationName = organizationName; 669 return this; 670 } 671 setSupportUrl(String supportUrl)672 public Builder setSupportUrl(String supportUrl) { 673 mSupportUrl = supportUrl; 674 return this; 675 } 676 setAccountToMigrate(Account accountToMigrate)677 public Builder setAccountToMigrate(Account accountToMigrate) { 678 mAccountToMigrate = accountToMigrate; 679 return this; 680 } 681 setProvisioningAction(String provisioningAction)682 public Builder setProvisioningAction(String provisioningAction) { 683 mProvisioningAction = provisioningAction; 684 return this; 685 } 686 setDeviceAdminDownloadInfo(PackageDownloadInfo deviceAdminDownloadInfo)687 public Builder setDeviceAdminDownloadInfo(PackageDownloadInfo deviceAdminDownloadInfo) { 688 mDeviceAdminDownloadInfo = deviceAdminDownloadInfo; 689 return this; 690 } 691 setDisclaimersParam(DisclaimersParam disclaimersParam)692 public Builder setDisclaimersParam(DisclaimersParam disclaimersParam) { 693 mDisclaimersParam = disclaimersParam; 694 return this; 695 } 696 setAdminExtrasBundle(PersistableBundle adminExtrasBundle)697 public Builder setAdminExtrasBundle(PersistableBundle adminExtrasBundle) { 698 mAdminExtrasBundle = adminExtrasBundle; 699 return this; 700 } 701 setStartedByTrustedSource(boolean startedByTrustedSource)702 public Builder setStartedByTrustedSource(boolean startedByTrustedSource) { 703 mStartedByTrustedSource = startedByTrustedSource; 704 return this; 705 } 706 setIsNfc(boolean isNfc)707 public Builder setIsNfc(boolean isNfc) { 708 mIsNfc = isNfc; 709 return this; 710 } 711 setIsQrProvisioning(boolean qrProvisioning)712 public Builder setIsQrProvisioning(boolean qrProvisioning) { 713 mIsQrProvisioning = qrProvisioning; 714 return this; 715 } 716 setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled)717 public Builder setLeaveAllSystemAppsEnabled(boolean leaveAllSystemAppsEnabled) { 718 mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled; 719 return this; 720 } 721 setSkipEncryption(boolean skipEncryption)722 public Builder setSkipEncryption(boolean skipEncryption) { 723 mSkipEncryption = skipEncryption; 724 return this; 725 } 726 setSkipEducationScreens(boolean skipEducationScreens)727 public Builder setSkipEducationScreens(boolean skipEducationScreens) { 728 mSkipEducationScreens = skipEducationScreens; 729 return this; 730 } 731 setKeepAccountMigrated(boolean keepAccountMigrated)732 public Builder setKeepAccountMigrated(boolean keepAccountMigrated) { 733 mKeepAccountMigrated = keepAccountMigrated; 734 return this; 735 } 736 setUseMobileData(boolean useMobileData)737 public Builder setUseMobileData(boolean useMobileData) { 738 mUseMobileData = useMobileData; 739 return this; 740 } 741 setIsOrganizationOwnedProvisioning(boolean isOrganizationOwnedProvisioning)742 public Builder setIsOrganizationOwnedProvisioning(boolean isOrganizationOwnedProvisioning) { 743 mIsOrganizationOwnedProvisioning = isOrganizationOwnedProvisioning; 744 return this; 745 } 746 setFlowType(@lowType int flowType)747 public Builder setFlowType(@FlowType int flowType) { 748 mFlowType = flowType; 749 return this; 750 } 751 setAllowProvisioningAfterUserSetupComplete( boolean allowProvisioningAfterUserSetupComplete)752 public Builder setAllowProvisioningAfterUserSetupComplete( 753 boolean allowProvisioningAfterUserSetupComplete) { 754 mAllowProvisioningAfterUserSetupComplete = allowProvisioningAfterUserSetupComplete; 755 return this; 756 } 757 setProvisioningTrigger(@rovisioningTrigger int provisioningTrigger)758 public Builder setProvisioningTrigger(@ProvisioningTrigger int provisioningTrigger) { 759 mProvisioningTrigger = provisioningTrigger; 760 return this; 761 } 762 setAllowedProvisioningModes(ArrayList<Integer> provisioningModes)763 public Builder setAllowedProvisioningModes(ArrayList<Integer> provisioningModes) { 764 mAllowedProvisioningModes = new ArrayList<>(provisioningModes); 765 return this; 766 } 767 setInitiatorRequestedProvisioningModes( int initiatorRequestedProvisioningModes)768 public Builder setInitiatorRequestedProvisioningModes( 769 int initiatorRequestedProvisioningModes) { 770 mInitiatorRequestedProvisioningModes = initiatorRequestedProvisioningModes; 771 return this; 772 } 773 774 /** 775 * See {@link ProvisioningParams#skipOwnershipDisclaimer}. 776 */ setSkipOwnershipDisclaimer(boolean skipOwnershipDisclaimer)777 public Builder setSkipOwnershipDisclaimer(boolean skipOwnershipDisclaimer) { 778 mSkipOwnershipDisclaimer = skipOwnershipDisclaimer; 779 return this; 780 } 781 782 /** 783 * Setter for {@link #returnBeforePolicyCompliance}. 784 */ setReturnBeforePolicyCompliance(boolean returnBeforePolicyCompliance)785 public Builder setReturnBeforePolicyCompliance(boolean returnBeforePolicyCompliance) { 786 mReturnBeforePolicyCompliance = returnBeforePolicyCompliance; 787 return this; 788 } 789 790 /** 791 * Setter for whether the admin has opted out of controlling permission grants. 792 */ setDeviceOwnerPermissionGrantOptOut(boolean optout)793 public Builder setDeviceOwnerPermissionGrantOptOut(boolean optout) { 794 mDeviceOwnerPermissionGrantOptOut = optout; 795 return this; 796 } 797 798 /** 799 * Builds the {@link ProvisioningParams} object. Note that {@link 800 * #setProvisioningAction(String)} and {@link #setDeviceAdminComponentName(ComponentName)} 801 * methods must be called with a non-null parameter before this is called. 802 */ build()803 public ProvisioningParams build() { 804 return new ProvisioningParams(this); 805 } 806 builder()807 public static Builder builder() { 808 return new Builder(); 809 } 810 } 811 } 812