SetDevicePolicyTask.java revision 91e23dddc899165feb982b181629c23dba310d8e
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
17package com.android.managedprovisioning.task;
18
19import android.app.AppGlobals;
20import android.app.admin.DevicePolicyManager;
21import android.content.ComponentName;
22import android.content.Context;
23import android.content.pm.IPackageManager;
24import android.content.pm.PackageManager;
25import android.os.RemoteException;
26import android.os.UserHandle;
27
28import com.android.managedprovisioning.ProvisionLogger;
29
30/**
31 * This tasks sets a given component as the owner of the device. If provided it also sets a given
32 * component as the device initializer, which can perform additional setup steps at the end of
33 * provisioning before setting the device as provisioned.
34 */
35public class SetDevicePolicyTask {
36    public static final int ERROR_PACKAGE_NOT_INSTALLED = 0;
37    public static final int ERROR_NO_RECEIVER = 1;
38    public static final int ERROR_OTHER = 2;
39
40    private final Callback mCallback;
41    private final Context mContext;
42    private String mAdminPackage;
43    private ComponentName mAdminComponent;
44    private final String mOwnerName;
45    private ComponentName mInitializerComponent;
46    private String mInitializerPackageName;
47
48    private PackageManager mPackageManager;
49    private DevicePolicyManager mDevicePolicyManager;
50
51    public SetDevicePolicyTask(Context context, String ownerName,
52            ComponentName initializerComponent, Callback callback) {
53        mCallback = callback;
54        mContext = context;
55        mOwnerName = ownerName;
56        mInitializerComponent = initializerComponent;
57        if (mInitializerComponent != null) {
58            mInitializerPackageName = initializerComponent.getPackageName();
59        }
60
61        mPackageManager = mContext.getPackageManager();
62        mDevicePolicyManager = (DevicePolicyManager) mContext.
63                getSystemService(Context.DEVICE_POLICY_SERVICE);
64    }
65
66    public void run(ComponentName adminComponent) {
67        try {
68            mAdminComponent = adminComponent;
69            mAdminPackage = mAdminComponent.getPackageName();
70
71            enableDevicePolicyApp(mAdminPackage);
72            setActiveAdmin(mAdminComponent);
73            setDeviceOwner(mAdminPackage, mOwnerName);
74
75            if (mInitializerComponent != null) {
76                enableDevicePolicyApp(mInitializerPackageName);
77                setActiveAdmin(mInitializerComponent);
78                if (!setDeviceInitializer(mInitializerComponent)) {
79                    // error reported in setDeviceInitializer
80                    return;
81                }
82            }
83        } catch (Exception e) {
84            ProvisionLogger.loge("Failure setting device owner or initializer", e);
85            mCallback.onError(ERROR_OTHER);
86            return;
87        }
88
89        mCallback.onSuccess();
90    }
91
92    private void enableDevicePolicyApp(String packageName) {
93        int enabledSetting = mPackageManager.getApplicationEnabledSetting(packageName);
94        if (enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
95            mPackageManager.setApplicationEnabledSetting(packageName,
96                    PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
97                    // Device policy app may have launched ManagedProvisioning, play nice and don't
98                    // kill it as a side-effect of this call.
99                    PackageManager.DONT_KILL_APP);
100        }
101    }
102
103    public void setActiveAdmin(ComponentName component) {
104        ProvisionLogger.logd("Setting " + component + " as active admin.");
105        mDevicePolicyManager.setActiveAdmin(component, true);
106    }
107
108    public void setDeviceOwner(String packageName, String owner) {
109        ProvisionLogger.logd("Setting " + packageName + " as device owner " + owner + ".");
110        if (!mDevicePolicyManager.isDeviceOwner(packageName)) {
111            mDevicePolicyManager.setDeviceOwner(packageName, owner);
112        }
113    }
114
115    public boolean setDeviceInitializer(ComponentName component) {
116        ProvisionLogger.logd("Setting " + component + " as device initializer.");
117        if (!mDevicePolicyManager.isDeviceInitializerApp(component.getPackageName())) {
118            mDevicePolicyManager.setDeviceInitializer(null, component);
119        }
120        IPackageManager pm = AppGlobals.getPackageManager();
121        try {
122            pm.setBlockUninstallForUser(component.getPackageName(), true,
123                    UserHandle.getCallingUserId());
124        } catch (RemoteException e) {
125            ProvisionLogger.loge("Failed to block uninstall of device initializer app", e);
126            mCallback.onError(ERROR_OTHER);
127            return false;
128        }
129        return true;
130    }
131
132    public abstract static class Callback {
133        public abstract void onSuccess();
134        public abstract void onError(int errorCode);
135    }
136}
137