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