15f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot/*
25f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * Copyright 2014, The Android Open Source Project
35f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot *
45f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * Licensed under the Apache License, Version 2.0 (the "License");
55f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * you may not use this file except in compliance with the License.
65f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * You may obtain a copy of the License at
75f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot *
85f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot *     http://www.apache.org/licenses/LICENSE-2.0
95f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot *
105f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * Unless required by applicable law or agreed to in writing, software
115f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * distributed under the License is distributed on an "AS IS" BASIS,
125f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * See the License for the specific language governing permissions and
145f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * limitations under the License.
155f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot */
165f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot
1714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelpackage com.android.managedprovisioning;
1814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
1914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE;
20f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnseimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
2114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
2215b7de6bdebf32729320f510165769b67b04cadeJessica Hummelimport static android.Manifest.permission.BIND_DEVICE_ADMIN;
2314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
2415b7de6bdebf32729320f510165769b67b04cadeJessica Hummelimport android.app.Activity;
2514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.app.ActivityManagerNative;
2614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.app.IActivityManager;
2714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.app.Service;
2814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.app.admin.DevicePolicyManager;
2915b7de6bdebf32729320f510165769b67b04cadeJessica Hummelimport android.content.BroadcastReceiver;
3014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.content.ComponentName;
3114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.content.Context;
3214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.content.Intent;
3314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.content.IntentFilter;
342e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummelimport android.content.pm.ActivityInfo;
3514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.content.pm.IPackageManager;
362e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummelimport android.content.pm.PackageInfo;
3714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.content.pm.PackageManager;
382e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummelimport android.content.pm.PackageManager.NameNotFoundException;
3914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.content.pm.UserInfo;
403da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummelimport android.os.AsyncTask;
41f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnseimport android.os.Parcelable;
42f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnseimport android.os.PersistableBundle;
4314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.os.IBinder;
4414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.os.Process;
4514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.os.RemoteException;
4614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.os.ServiceManager;
4714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.os.UserHandle;
4814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.os.UserManager;
49d6157a089c45d67d0250272cc87899b573d459f5Nicolas Prevotimport android.provider.MediaStore;
501350a21bf52e2e5fae569ffb0e3d1daa9d3252bbKenny Guyimport android.provider.Settings;
5181fe104ecfc98f1fb4356891acfe696e7445acb8Jessica Hummelimport android.support.v4.content.LocalBroadcastManager;
5214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport android.text.TextUtils;
5314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
545f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevotimport com.android.managedprovisioning.CrossProfileIntentFiltersHelper;
5514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelimport com.android.managedprovisioning.task.DeleteNonRequiredAppsTask;
5614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
5714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel/**
5814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * Service that runs the managed provisioning.
5914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel *
6014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * <p>This service is started from and sends updates to the {@link ManagedProvisioningActivity},
6114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel * which contains the provisioning UI.
6214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel */
6314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummelpublic class ManagedProvisioningService extends Service {
6414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
6514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    // Intent actions for communication with DeviceOwnerProvisioningService.
6614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    public static final String ACTION_PROVISIONING_SUCCESS =
6714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            "com.android.managedprovisioning.provisioning_success";
6814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    public static final String ACTION_PROVISIONING_ERROR =
6914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            "com.android.managedprovisioning.error";
7014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    public static final String EXTRA_LOG_MESSAGE_KEY = "ProvisioingErrorLogMessage";
7114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
7214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private String mMdmPackageName;
7314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private ComponentName mActiveAdminComponentName;
7414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
75f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse    // PersistableBundle extra received in starting intent.
76f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse    // Should be passed through to device management application when provisioning is complete.
77f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse    private PersistableBundle mAdminExtrasBundle;
78f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse
7914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private IPackageManager mIpm;
8014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private UserInfo mManagedProfileUserInfo;
8114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private UserManager mUserManager;
8214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
8314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private int mStartIdProvisioning;
843da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel    private AsyncTask<Intent, Object, Void> runnerTask;
853da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel
863da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel    private class RunnerTask extends AsyncTask<Intent, Object, Void> {
873da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        @Override
883da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        protected Void doInBackground(Intent ... intents) {
893da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel            initialize(intents[0]);
903da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel            startManagedProfileProvisioning();
913da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel            return null;
923da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        }
933da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel    }
9414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
9514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    @Override
9614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    public void onCreate() {
9714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        super.onCreate();
9814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
9914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        ProvisionLogger.logd("Managed provisioning service ONCREATE");
10014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
10114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
10214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
1033da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel
1043da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        runnerTask = new RunnerTask();
10514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
10614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
10714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    @Override
10814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    public int onStartCommand(final Intent intent, int flags, int startId) {
1093da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel
11014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        ProvisionLogger.logd("Starting managed provisioning service");
1113da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        try {
1123da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel            runnerTask.execute(intent);
1133da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        } catch (IllegalStateException ex) {
1143da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel            ProvisionLogger.logd("ManagedProvisioningService: Provisioning already in progress, "
1153da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel                    + "second provisioning intent not being processed");
1163da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        }
11714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        return START_NOT_STICKY;
1189480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy    }
11914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
12014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void initialize(Intent intent) {
121ff364bd8dafb6bb72a8acc3672edd884625771b5Jessica Hummel        mMdmPackageName = intent.getStringExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME);
12214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
123f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        // Cast is guaranteed by check in Activity.
124f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        mAdminExtrasBundle  = (PersistableBundle) intent.getParcelableExtra(
125f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE);
126f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse
1272e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel        mActiveAdminComponentName = getAdminReceiverComponent(mMdmPackageName);
12814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
12914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
1302e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel    /**
1312e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     * Find the Device admin receiver component from the manifest.
1322e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     */
1332e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel    private ComponentName getAdminReceiverComponent(String packageName) {
1342e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel        ComponentName adminReceiverComponent = null;
1352e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel
1362e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel        try {
1372e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel            PackageInfo pi = getPackageManager().getPackageInfo(packageName,
1382e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel                    PackageManager.GET_RECEIVERS);
1392e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel            for (ActivityInfo ai : pi.receivers) {
1402e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel                if (!TextUtils.isEmpty(ai.permission) &&
14115b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                        ai.permission.equals(BIND_DEVICE_ADMIN)) {
1422e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel                    adminReceiverComponent = new ComponentName(packageName, ai.name);
1432e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel
1442e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel                }
1452e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel            }
1462e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel        } catch (NameNotFoundException e) {
1472e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel            error("Error: The provided mobile device management package does not define a device"
1482e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel                    + "admin receiver component in its manifest.");
14914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        }
1502e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel        return adminReceiverComponent;
15114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
15214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
15314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    /**
15414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * This is the core method of this class. It goes through every provisioning step.
15514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     */
15614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void startManagedProfileProvisioning() {
15714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
15814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        ProvisionLogger.logd("Starting managed profile provisioning");
15914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
16014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        // Work through the provisioning steps in their corresponding order
161ff364bd8dafb6bb72a8acc3672edd884625771b5Jessica Hummel        createProfile(getString(R.string.default_managed_profile_name));
1629480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy        if (mManagedProfileUserInfo != null) {
1639480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy            new DeleteNonRequiredAppsTask(this,
1649480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                    mMdmPackageName, mManagedProfileUserInfo.id,
1659480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                    R.array.required_apps_managed_profile,
1669480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                    R.array.vendor_required_apps_managed_profile,
1679480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                    true /* We are creating a new profile */,
1689480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                    true /* Disable INSTALL_SHORTCUT listeners */,
1699480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                    new DeleteNonRequiredAppsTask.Callback() {
1709480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy
1719480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                        @Override
1729480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                        public void onSuccess() {
1739480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                            setUpProfileAndFinish();
1749480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                        }
1759480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy
1769480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                        @Override
1779480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                        public void onError() {
1789480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                            error("Delete non required apps task failed.");
1799480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                        }
1809480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy                    }).run();
1819480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy        }
18214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
18314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
18414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    /**
18514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * Called when the new profile is ready for provisioning (the profile is created and all the
18614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * apps not needed have been deleted).
18714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     */
18814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void setUpProfileAndFinish() {
18914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            installMdmOnManagedProfile();
19014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            setMdmAsActiveAdmin();
19114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            setMdmAsManagedProfileOwner();
19214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            startManagedProfile();
1935f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot            CrossProfileIntentFiltersHelper.setFilters(
1945f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot                    getPackageManager(), getUserId(), mManagedProfileUserInfo.id);
19514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            onProvisioningSuccess(mActiveAdminComponentName);
19614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
19714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
19814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void createProfile(String profileName) {
19914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
20014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        ProvisionLogger.logd("Creating managed profile with name " + profileName);
20114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
20214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        mManagedProfileUserInfo = mUserManager.createProfileForUser(profileName,
20314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_DISABLED,
20414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                Process.myUserHandle().getIdentifier());
20514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
20614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        if (mManagedProfileUserInfo == null) {
20714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            if (UserManager.getMaxSupportedUsers() == mUserManager.getUserCount()) {
20814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                error("Profile creation failed, maximum number of users reached.");
20914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            } else {
21014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                error("Couldn't create profile. Reason unknown.");
21114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            }
21214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        }
21314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
21414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
21514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    /**
21614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * Initializes the user that underlies the managed profile.
21714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * This is required so that the provisioning complete broadcast can be sent across to the
21814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * profile and apps can run on it.
21914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     */
22014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void startManagedProfile()  {
22114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        ProvisionLogger.logd("Starting user in background");
22214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        IActivityManager iActivityManager = ActivityManagerNative.getDefault();
22314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        try {
22414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            boolean success = iActivityManager.startUserInBackground(mManagedProfileUserInfo.id);
22514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            if (!success) {
22614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel               error("Could not start user in background");
22714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            }
22814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        } catch (RemoteException neverThrown) {
22914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            // Never thrown, as we are making local calls.
23014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            ProvisionLogger.loge("This should not happen.", neverThrown);
23114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        }
23214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
23314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
23414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void installMdmOnManagedProfile() {
23514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
23614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        ProvisionLogger.logd("Installing mobile device management app " + mMdmPackageName +
23714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel              " on managed profile");
23814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
23914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        try {
24014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            int status = mIpm.installExistingPackageAsUser(
24114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                mMdmPackageName, mManagedProfileUserInfo.id);
24214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            switch (status) {
24314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel              case PackageManager.INSTALL_SUCCEEDED:
24414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                  return;
24514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel              case PackageManager.INSTALL_FAILED_USER_RESTRICTED:
24614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                  // Should not happen because we're not installing a restricted user
24714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                  error("Could not install mobile device management app on managed "
24814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                          + "profile because the user is restricted");
24914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel              case PackageManager.INSTALL_FAILED_INVALID_URI:
25014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                  // Should not happen because we already checked
25114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                  error("Could not install mobile device management app on managed "
25214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                          + "profile because the package could not be found");
25314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel              default:
25414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                  error("Could not install mobile device management app on managed "
25514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                          + "profile. Unknown status: " + status);
25614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            }
25714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        } catch (RemoteException neverThrown) {
25814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            // Never thrown, as we are making local calls.
25914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            ProvisionLogger.loge("This should not happen.", neverThrown);
26014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        }
26114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
26214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
26314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void setMdmAsManagedProfileOwner() {
26414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
26514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        ProvisionLogger.logd("Setting package " + mMdmPackageName + " as managed profile owner.");
26614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
26714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        DevicePolicyManager dpm =
26814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
269ff364bd8dafb6bb72a8acc3672edd884625771b5Jessica Hummel        if (!dpm.setProfileOwner(mActiveAdminComponentName, mMdmPackageName,
270ff364bd8dafb6bb72a8acc3672edd884625771b5Jessica Hummel                mManagedProfileUserInfo.id)) {
27114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            ProvisionLogger.logw("Could not set profile owner.");
27214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            error("Could not set profile owner.");
27314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        }
27414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
27514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
27614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void setMdmAsActiveAdmin() {
27714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
27814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        ProvisionLogger.logd("Setting package " + mMdmPackageName + " as active admin.");
27914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
28014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        DevicePolicyManager dpm =
28114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
28214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        dpm.setActiveAdmin(mActiveAdminComponentName, true /* refreshing*/,
28314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                mManagedProfileUserInfo.id);
28414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
28514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
28615b7de6bdebf32729320f510165769b67b04cadeJessica Hummel    /**
28715b7de6bdebf32729320f510165769b67b04cadeJessica Hummel     * Notify the mdm that provisioning has completed. When the mdm has received the intent, stop
28815b7de6bdebf32729320f510165769b67b04cadeJessica Hummel     * the service and notify the {@link ManagedProvisioningActivity} so that it can finish itself.
28915b7de6bdebf32729320f510165769b67b04cadeJessica Hummel     *
29015b7de6bdebf32729320f510165769b67b04cadeJessica Hummel     * @param deviceAdminComponent The component of the mdm that will be notified.
29115b7de6bdebf32729320f510165769b67b04cadeJessica Hummel     */
29215b7de6bdebf32729320f510165769b67b04cadeJessica Hummel    private void onProvisioningSuccess(ComponentName deviceAdminComponent) {
29315b7de6bdebf32729320f510165769b67b04cadeJessica Hummel        Settings.Secure.putIntForUser(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE,
29415b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                1 /* true- > setup complete */, mManagedProfileUserInfo.id);
29515b7de6bdebf32729320f510165769b67b04cadeJessica Hummel
29614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
29714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        UserHandle userHandle = userManager.getUserForSerialNumber(
29814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel                mManagedProfileUserInfo.serialNumber);
29914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
30014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        Intent completeIntent = new Intent(ACTION_PROFILE_PROVISIONING_COMPLETE);
30114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        completeIntent.setComponent(mActiveAdminComponentName);
30214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        completeIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES |
30314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            Intent.FLAG_RECEIVER_FOREGROUND);
304f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        if (mAdminExtrasBundle != null) {
305f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse            completeIntent.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, mAdminExtrasBundle);
306f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        }
30714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
30815b7de6bdebf32729320f510165769b67b04cadeJessica Hummel        // Use an ordered broadcast, so that we only finish when the mdm has received it.
30915b7de6bdebf32729320f510165769b67b04cadeJessica Hummel        // Avoids a lag in the transition between provisioning and the mdm.
31015b7de6bdebf32729320f510165769b67b04cadeJessica Hummel        BroadcastReceiver mdmReceivedSuccessReceiver = new BroadcastReceiver() {
31115b7de6bdebf32729320f510165769b67b04cadeJessica Hummel            @Override
31215b7de6bdebf32729320f510165769b67b04cadeJessica Hummel            public void onReceive(Context context, Intent intent) {
31315b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                ProvisionLogger.logd("ACTION_PROFILE_PROVISIONING_COMPLETE broadcast received by"
31415b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                        + " mdm");
31515b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                Intent successIntent = new Intent(ACTION_PROVISIONING_SUCCESS);
31615b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                LocalBroadcastManager.getInstance(ManagedProvisioningService.this)
31715b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                        .sendBroadcast(successIntent);
31815b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                stopSelf();
31915b7de6bdebf32729320f510165769b67b04cadeJessica Hummel            }
3201350a21bf52e2e5fae569ffb0e3d1daa9d3252bbKenny Guy
32115b7de6bdebf32729320f510165769b67b04cadeJessica Hummel        };
32215b7de6bdebf32729320f510165769b67b04cadeJessica Hummel        sendOrderedBroadcastAsUser(completeIntent, userHandle, null,
32315b7de6bdebf32729320f510165769b67b04cadeJessica Hummel                mdmReceivedSuccessReceiver, null, Activity.RESULT_OK, null, null);
32414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
32515b7de6bdebf32729320f510165769b67b04cadeJessica Hummel        ProvisionLogger.logd("Provisioning complete broadcast has been sent to user "
32615b7de6bdebf32729320f510165769b67b04cadeJessica Hummel            + userHandle.getIdentifier());
32714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
32814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
3292e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel    private void error(String logMessage) {
33014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        Intent intent = new Intent(ACTION_PROVISIONING_ERROR);
3312e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel        intent.putExtra(EXTRA_LOG_MESSAGE_KEY, logMessage);
3329480d6efd4a67573f16755b559e6aa7c7cb9546fKenny Guy        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
33314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        cleanup();
3343da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        stopSelf();
33514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
33614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
33714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    /**
33814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     * Performs cleanup of the device on failure.
33914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel     */
34014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    private void cleanup() {
34114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        // The only cleanup we need to do is remove the profile we created.
34214eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        if (mManagedProfileUserInfo != null) {
34314eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            ProvisionLogger.logd("Removing managed profile");
34414eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel            mUserManager.removeUser(mManagedProfileUserInfo.id);
34514eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        }
34614eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
34714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel
34814eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    @Override
34914eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    public IBinder onBind(Intent intent) {
35014eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel        return null;
35114eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel    }
3523da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel
3533da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel    @Override
3543da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel    public void onDestroy() {
3553da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel        ProvisionLogger.logd("ManagedProvisioningService  ONDESTROY");
3563da1e3290575cd7d8d0a92fc8442952b9ba49c81Jessica Hummel    }
35714eeef9ff6b961f4a746f2953dde1529ad27bc6aJessica Hummel}
358