1 /*
2  * Copyright 2014, 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 com.android.internal.util.Preconditions.checkNotNull;
20 
21 import android.app.admin.DevicePolicyManager;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.pm.PackageManager;
25 
26 import com.android.internal.annotations.VisibleForTesting;
27 import com.android.managedprovisioning.analytics.MetricsWriterFactory;
28 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
29 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
30 import com.android.managedprovisioning.common.ProvisionLogger;
31 import com.android.managedprovisioning.R;
32 import com.android.managedprovisioning.common.SettingsFacade;
33 import com.android.managedprovisioning.common.Utils;
34 import com.android.managedprovisioning.model.ProvisioningParams;
35 
36 /**
37  * This tasks sets a given component as the device or profile owner. It also enables the management
38  * app if it's not currently enabled and sets the component as active admin.
39  */
40 public class SetDevicePolicyTask extends AbstractProvisioningTask {
41 
42     private final PackageManager mPackageManager;
43     private final DevicePolicyManager mDevicePolicyManager;
44     private final Utils mUtils;
45 
SetDevicePolicyTask( Context context, ProvisioningParams params, Callback callback)46     public SetDevicePolicyTask(
47             Context context,
48             ProvisioningParams params,
49             Callback callback) {
50         this(new Utils(), context, params, callback,
51                 new ProvisioningAnalyticsTracker(
52                         MetricsWriterFactory.getMetricsWriter(context, new SettingsFacade()),
53                         new ManagedProvisioningSharedPreferences(context)));
54     }
55 
56     @VisibleForTesting
SetDevicePolicyTask(Utils utils, Context context, ProvisioningParams params, Callback callback, ProvisioningAnalyticsTracker provisioningAnalyticsTracker)57     SetDevicePolicyTask(Utils utils,
58                         Context context,
59                         ProvisioningParams params,
60                         Callback callback,
61                         ProvisioningAnalyticsTracker provisioningAnalyticsTracker) {
62         super(context, params, callback, provisioningAnalyticsTracker);
63 
64         mUtils = checkNotNull(utils);
65         mPackageManager = mContext.getPackageManager();
66         mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(
67                 Context.DEVICE_POLICY_SERVICE);
68     }
69 
70     @Override
getStatusMsgId()71     public int getStatusMsgId() {
72         return R.string.progress_set_owner;
73     }
74 
75     @Override
run(int userId)76     public void run(int userId) {
77         boolean success;
78         try {
79             ComponentName adminComponent =
80                     mProvisioningParams.inferDeviceAdminComponentName(mUtils, mContext, userId);
81             String adminPackage = adminComponent.getPackageName();
82 
83             enableDevicePolicyApp(adminPackage);
84             setActiveAdmin(adminComponent, userId);
85             if (mUtils.isProfileOwnerAction(mProvisioningParams.provisioningAction)) {
86                 success = setProfileOwner(adminComponent, userId);
87             } else {
88                 success = setDeviceOwner(adminComponent,
89                         mContext.getResources().getString(R.string.default_owned_device_username),
90                         userId);
91             }
92         } catch (Exception e) {
93             ProvisionLogger.loge("Failure setting device or profile owner", e);
94             error(0);
95             return;
96         }
97 
98         if (success) {
99             success();
100         } else {
101             ProvisionLogger.loge("Error when setting device or profile owner.");
102             error(0);
103         }
104     }
105 
enableDevicePolicyApp(String packageName)106     private void enableDevicePolicyApp(String packageName) {
107         int enabledSetting = mPackageManager.getApplicationEnabledSetting(packageName);
108         if (enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
109                 && enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
110             mPackageManager.setApplicationEnabledSetting(packageName,
111                     PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
112                     // Device policy app may have launched ManagedProvisioning, play nice and don't
113                     // kill it as a side-effect of this call.
114                     PackageManager.DONT_KILL_APP);
115         }
116     }
117 
setActiveAdmin(ComponentName component, int userId)118     private void setActiveAdmin(ComponentName component, int userId) {
119         ProvisionLogger.logd("Setting " + component + " as active admin.");
120         mDevicePolicyManager.setActiveAdmin(component, true, userId);
121     }
122 
setDeviceOwner(ComponentName component, String owner, int userId)123     private boolean setDeviceOwner(ComponentName component, String owner, int userId) {
124         ProvisionLogger.logd("Setting " + component + " as device owner of user " + userId);
125         if (!component.equals(mDevicePolicyManager.getDeviceOwnerComponentOnCallingUser())) {
126             return mDevicePolicyManager.setDeviceOwner(component, owner, userId);
127         }
128         return true;
129     }
130 
setProfileOwner(ComponentName component, int userId)131     private boolean setProfileOwner(ComponentName component, int userId) {
132         ProvisionLogger.logd("Setting " + component + " as profile owner of user " + userId);
133         if (!component.equals(mDevicePolicyManager.getProfileOwnerAsUser(userId))) {
134             return mDevicePolicyManager.setProfileOwner(component, component.getPackageName(),
135                     userId);
136         }
137         return true;
138     }
139 }
140