1 /* 2 * Copyright (C) 2021 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.task; 18 19 import static android.app.admin.DevicePolicyManager.STATUS_HEADLESS_SYSTEM_USER_MODE_NOT_SUPPORTED; 20 21 import static java.util.Objects.requireNonNull; 22 23 import android.annotation.UserIdInt; 24 import android.app.admin.DevicePolicyManager; 25 import android.app.admin.FullyManagedDeviceProvisioningParams; 26 import android.app.admin.ProvisioningException; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.stats.devicepolicy.DevicePolicyEnums; 30 31 import com.android.internal.annotations.VisibleForTesting; 32 import com.android.managedprovisioning.R; 33 import com.android.managedprovisioning.analytics.MetricsWriterFactory; 34 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 35 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException; 36 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences; 37 import com.android.managedprovisioning.common.ProvisionLogger; 38 import com.android.managedprovisioning.common.SettingsFacade; 39 import com.android.managedprovisioning.common.Utils; 40 import com.android.managedprovisioning.model.ProvisioningParams; 41 42 /** 43 * Task to provision a fully managed device. 44 */ 45 public class ProvisionFullyManagedDeviceTask extends AbstractProvisioningTask { 46 47 public static final int ERROR_FULLY_MANAGED_MODE_UNSUPPORTED_IN_HEADLESS = 1; 48 private final DevicePolicyManager mDpm; 49 private final Utils mUtils; 50 ProvisionFullyManagedDeviceTask( Context context, ProvisioningParams params, Callback callback)51 public ProvisionFullyManagedDeviceTask( 52 Context context, 53 ProvisioningParams params, 54 Callback callback) { 55 this( 56 new Utils(), 57 context, 58 params, 59 callback, 60 new ProvisioningAnalyticsTracker( 61 MetricsWriterFactory.getMetricsWriter(context, new SettingsFacade()), 62 new ManagedProvisioningSharedPreferences(context))); 63 } 64 65 @VisibleForTesting ProvisionFullyManagedDeviceTask( Utils utils, Context context, ProvisioningParams params, Callback callback, ProvisioningAnalyticsTracker provisioningAnalyticsTracker)66 ProvisionFullyManagedDeviceTask( 67 Utils utils, 68 Context context, 69 ProvisioningParams params, 70 Callback callback, 71 ProvisioningAnalyticsTracker provisioningAnalyticsTracker) { 72 super(context, params, callback, provisioningAnalyticsTracker); 73 74 mDpm = requireNonNull(context.getSystemService(DevicePolicyManager.class)); 75 mUtils = requireNonNull(utils); 76 } 77 78 @Override run(@serIdInt int userId)79 public void run(@UserIdInt int userId) { 80 startTaskTimer(); 81 FullyManagedDeviceProvisioningParams params; 82 83 try { 84 params = buildManagedDeviceProvisioningParams(userId); 85 } catch (IllegalProvisioningArgumentException e) { 86 ProvisionLogger.loge("Failure provisioning managed device, failed to " 87 + "infer the device admin component name", e); 88 error(/* resultCode= */ 0); 89 return; 90 } 91 92 try { 93 mDpm.provisionFullyManagedDevice(params); 94 } catch (ProvisioningException provisioningException) { 95 ProvisionLogger.loge("Failure provisioning device owner", provisioningException); 96 int resultCode = provisioningException.getProvisioningError() 97 == STATUS_HEADLESS_SYSTEM_USER_MODE_NOT_SUPPORTED 98 ? ERROR_FULLY_MANAGED_MODE_UNSUPPORTED_IN_HEADLESS : 0; 99 error(resultCode, provisioningException.getMessage()); 100 return; 101 } catch (Exception e) { 102 // Catching all Exceptions to allow Managed Provisioning to handle any failure 103 // during provisioning properly and perform any necessary cleanup. 104 ProvisionLogger.loge("Failure provisioning device owner", e); 105 error(/* resultCode= */ 0); 106 return; 107 } 108 109 stopTaskTimer(); 110 success(); 111 } 112 buildManagedDeviceProvisioningParams( @serIdInt int userId)113 private FullyManagedDeviceProvisioningParams buildManagedDeviceProvisioningParams( 114 @UserIdInt int userId) 115 throws IllegalProvisioningArgumentException { 116 ComponentName adminComponent = mProvisioningParams.inferDeviceAdminComponentName( 117 mUtils, mContext, userId); 118 return new FullyManagedDeviceProvisioningParams.Builder( 119 adminComponent, 120 mContext.getResources().getString( 121 R.string.default_owned_device_username)) 122 .setLeaveAllSystemAppsEnabled( 123 mProvisioningParams.leaveAllSystemAppsEnabled) 124 .setTimeZone(mProvisioningParams.timeZone) 125 .setLocalTime(mProvisioningParams.localTime) 126 .setLocale(mProvisioningParams.locale) 127 // The device owner can grant sensors permissions if it has not opted 128 // out of controlling them. 129 .setCanDeviceOwnerGrantSensorsPermissions( 130 !mProvisioningParams.deviceOwnerPermissionGrantOptOut) 131 .setAdminExtras(mProvisioningParams.adminExtrasBundle) 132 .build(); 133 } 134 135 @Override getMetricsCategory()136 protected int getMetricsCategory() { 137 return DevicePolicyEnums.PROVISIONING_PROVISION_FULLY_MANAGED_DEVICE_TASK_MS; 138 } 139 } 140