1ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway/* 2ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * Copyright 2014, The Android Open Source Project 3ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * 4ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * Licensed under the Apache License, Version 2.0 (the "License"); 5ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * you may not use this file except in compliance with the License. 6ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * You may obtain a copy of the License at 7ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * 8ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * http://www.apache.org/licenses/LICENSE-2.0 9ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * 10ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * Unless required by applicable law or agreed to in writing, software 11ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * distributed under the License is distributed on an "AS IS" BASIS, 12ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * See the License for the specific language governing permissions and 14ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * limitations under the License. 15ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway */ 16ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 17ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwaypackage com.android.managedprovisioning; 18ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 19d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE; 20d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 21d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; 22d1784bd4d917bb36125e6faf125a2425c343838bSteven Ng 23ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwayimport android.app.Activity; 24ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwayimport android.app.admin.DevicePolicyManager; 25ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwayimport android.content.BroadcastReceiver; 26ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwayimport android.content.Context; 27ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwayimport android.content.Intent; 28ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwayimport android.os.Bundle; 29ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwayimport android.os.UserHandle; 30ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 3172023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franzimport com.android.managedprovisioning.common.IllegalProvisioningArgumentException; 3272023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franzimport com.android.managedprovisioning.common.Utils; 33d1784bd4d917bb36125e6faf125a2425c343838bSteven Ngimport com.android.managedprovisioning.model.ProvisioningParams; 347079df5a3fb155947004843ee8ec25b36127e3edSteven Ngimport com.android.managedprovisioning.parser.MessageParser; 35ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 36ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway/* 37ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * This class is used to make sure that we start the MDM after we shut the setup wizard down. 38ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * The shut down of the setup wizard is initiated in the DeviceOwnerProvisioningActivity or 39ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * ProfileOwnerProvisioningActivity by calling 40ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * {@link DevicePolicyManager.setUserProvisioningState()}. This will cause the 41ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * Setup wizard to shut down and send a ACTION_PROVISIONING_FINALIZATION intent. This intent is 42ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * caught by this receiver instead which will send the 43ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * ACTION_PROFILE_PROVISIONING_COMPLETE broadcast to the MDM, which can then present it's own 44ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway * activities. 45ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway */ 46ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadwaypublic class FinalizationActivity extends Activity { 47ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 48ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway private ProvisioningParams mParams; 49ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 50ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway private static final String INTENT_STORE_NAME = "finalization-receiver"; 51ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 5272023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franz private final Utils mUtils = new Utils(); 5372023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franz 54ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway @Override 55ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway public void onCreate(Bundle savedInstanceState) { 56ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway super.onCreate(savedInstanceState); 57ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 58e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class); 59e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz int currentState = dpm.getUserProvisioningState(); 60ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 61e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz switch (currentState) { 62e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz case DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE: 63e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz case DevicePolicyManager.STATE_USER_SETUP_COMPLETE: 64e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz case DevicePolicyManager.STATE_USER_PROFILE_COMPLETE: 65e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz finalizeProvisioning(dpm); 66e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz break; 67e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz case DevicePolicyManager.STATE_USER_UNMANAGED: 68e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz case DevicePolicyManager.STATE_USER_SETUP_FINALIZED: 69e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz // Nothing to do in these cases. 70e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz ProvisionLogger.logw("Received ACTION_PROVISIONING_FINALIZATION intent, but " 71e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz + "nothing to do in state: " + currentState); 72e04659786591df44c6fd359de5408fd8f7d6254bBenjamin Franz break; 73ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 74ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 75ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway finish(); 76ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 77ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 78ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway public static void storeProvisioningParams(Context context, ProvisioningParams params) { 79ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway Intent intent = new MessageParser().getIntentFromProvisioningParams(params); 80ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway getIntentStore(context).save(intent); 81ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 82ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 83ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway private void finalizeProvisioning(DevicePolicyManager dpm) { 84ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway mParams = loadProvisioningParamsAndClearIntentStore(); 85ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway Intent provisioningCompleteIntent = getProvisioningCompleteIntent(dpm); 86ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway if (provisioningCompleteIntent == null) { 87ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway return; 88ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 89ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 90ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // It maybe the case that mParams is null at this point - we expect this to be the case if 91ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // ManagedProvisioning wasn't invoked to perform setup. We'll simply trigger the normal 92ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // broadcast so that the installed DPC knows that user-setup completed. Concrete use-case 93ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // is a user being setup through DevicePolicyManager.createAndInitializeUser() by the 94ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // device-owner, which sets profile-owner and then launches the user. Setup-wizard on the 95ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // user runs, and at the end of it's activity flow will trigger the finalization intent, 96ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // which then allows us to notify the DPC that profile setup is complete. 97ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway if (mParams != null && 98ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway mParams.provisioningAction.equals(ACTION_PROVISION_MANAGED_PROFILE)) { 99ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // For the managed profile owner case, we need to send the provisioning complete 100ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // intent to the mdm. Once it has been received, we'll send 101ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // ACTION_MANAGED_PROFILE_PROVISIONED in the parent. 102ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway finalizeManagedProfileOwnerProvisioning(provisioningCompleteIntent); 103ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } else { 104ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // For managed user and device owner, we just need to send the provisioning complete 105ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // intent to the mdm. 106ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway sendBroadcast(provisioningCompleteIntent); 107ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 108ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 10972023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franz mUtils.markUserProvisioningStateFinalized(this, mParams); 110ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 111ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 112ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway private void finalizeManagedProfileOwnerProvisioning(Intent provisioningCompleteIntent) { 11372023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franz UserHandle managedUserHandle = mUtils.getManagedProfile(this); 114ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway if (managedUserHandle == null) { 115ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway ProvisionLogger.loge("Failed to retrieve the userHandle of the managed profile."); 116ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway return; 117ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 118ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway BroadcastReceiver mdmReceivedSuccessReceiver = new MdmReceivedSuccessReceiver( 11925a4d3d99c94d562cb11eef8bef81ddf4d602ec2Steven Ng mParams.accountToMigrate, mParams.deviceAdminComponentName.getPackageName()); 120ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 121ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway sendOrderedBroadcastAsUser(provisioningCompleteIntent, managedUserHandle, null, 122ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway mdmReceivedSuccessReceiver, null, Activity.RESULT_OK, null, null); 123ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 124ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 125ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway private Intent getProvisioningCompleteIntent(DevicePolicyManager dpm) { 126ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway Intent intent = new Intent(ACTION_PROFILE_PROVISIONING_COMPLETE); 127ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway try { 128ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // mParams maybe null for cases where DevicePolicyManager has directly set DO or PO and 129ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // ManagedProvisioning wasn't involved. In that case, we may still want to use the same 130ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // mechanism after setup-wizard to invoke the MDM, hence why we fallback to inspecting 131ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway // device and profile-owner. 132ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway if (mParams != null) { 133ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway intent.setComponent(mParams.inferDeviceAdminComponentName(this)); 134ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } else if (dpm.getDeviceOwner() != null) { 13572023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franz intent.setComponent(mUtils.findDeviceAdmin(dpm.getDeviceOwner(), 136ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway null /* mdmComponentName */, this)); 137ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } else if (dpm.getProfileOwner() != null) { 13872023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franz intent.setComponent(mUtils.findDeviceAdmin(dpm.getProfileOwner().getPackageName(), 139ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway null /* mdmComponentName */, this)); 140ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } else { 141ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway return null; 142ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 14372023ca7b7a818fa33e0303baf6f5baef05b5f1bBenjamin Franz } catch (IllegalProvisioningArgumentException e) { 144ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway ProvisionLogger.loge("Failed to infer the device admin component name", e); 145ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway return null; 146ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 147ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND); 148ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway if (mParams != null && mParams.adminExtrasBundle != null) { 149ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway intent.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, mParams.adminExtrasBundle); 150ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 151ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway return intent; 152ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 153ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 154ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway private ProvisioningParams loadProvisioningParamsAndClearIntentStore() { 155ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway IntentStore intentStore = getIntentStore(this); 156ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway Intent intent = intentStore.load(); 157ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway if (intent == null) { 158ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway ProvisionLogger.loge("Fail to retrieve ProvisioningParams from intent store."); 159ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway return null; 160ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 161ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway intentStore.clear(); 162ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 163ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway try { 1647079df5a3fb155947004843ee8ec25b36127e3edSteven Ng return new MessageParser().parse(intent, this); 165ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } catch (IllegalProvisioningArgumentException e) { 166ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway ProvisionLogger.loge("Failed to parse provisioning intent", e); 167ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 168ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway return null; 169ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 170ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway 171ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway private static IntentStore getIntentStore(Context context) { 172ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway return new IntentStore(context, INTENT_STORE_NAME); 173ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway } 174ba113214d1820f32e5132cd83a06fa1eaedd2866Alan Treadway} 175