/* * Copyright 2014, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.managedprovisioning; import static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE; import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE; import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; import android.accounts.Account; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.AsyncTask; import android.os.Bundle; import android.os.UserHandle; import com.android.managedprovisioning.Utils.IllegalProvisioningArgumentException; /* * This class is used to make sure that we start the mdm after we shut the Setup wizard down. * The shut down of the Setup wizard is initiated in the DeviceOwnerProvisioningActivity or * ProfileOwnerProvisioningActivity by setting Global.DEVICE_PROVISIONED. This will cause the * Setup wizard to shut down and send a HOME intent. Instead of opening the home screen we want * to open the mdm, so the HOME intent is caught by this activity instead which will send the * ACTION_PROFILE_PROVISIONING_COMPLETE to the mdm, which will then open up. */ public class HomeReceiverActivity extends Activity { private ProvisioningParams mParams; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { finalizeProvisioning(); } finally { // Disable the HomeReceiverActivity. Make sure this is always called to prevent an // infinite loop of HomeReceiverActivity capturing HOME intent in case something fails. disableComponent(new ComponentName(this, HomeReceiverActivity.class)); } finish(); } private void finalizeProvisioning() { mParams = loadProvisioningParamsFromStore( BootReminder.getProfileOwnerFinalizingIntentStore(this)); if (mParams != null) { // Finalizing provisioning: send complete intent to mdm. finalizeProfileOwnerProvisioning(); return; } mParams = loadProvisioningParamsFromStore( BootReminder.getDeviceOwnerFinalizingIntentStore(this)); if (mParams != null) { finalizeDeviceOwnerProvisioning(); } } private void finalizeProfileOwnerProvisioning() { Intent provisioningCompleteIntent = getProvisioningCompleteIntent(); if (provisioningCompleteIntent == null) { return; } final UserHandle managedUserHandle = Utils.getManagedProfile(this); if (managedUserHandle == null) { ProvisionLogger.loge("Failed to retrieve the userHandle of the managed profile."); return; } BroadcastReceiver mdmReceivedSuccessReceiver = new MdmReceivedSuccessReceiver( mParams.accountToMigrate, mParams.deviceAdminPackageName); sendOrderedBroadcastAsUser(provisioningCompleteIntent, managedUserHandle, null, mdmReceivedSuccessReceiver, null, Activity.RESULT_OK, null, null); } private void finalizeDeviceOwnerProvisioning() { Intent provisioningCompleteIntent = getProvisioningCompleteIntent(); if (provisioningCompleteIntent == null) { return; } // Disable the Device Initializer component, if it exists, in case it did not do so itself. if(mParams.deviceInitializerComponentName != null) { DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); devicePolicyManager.removeActiveAdmin(mParams.deviceInitializerComponentName); disableComponent(mParams.deviceInitializerComponentName); } sendBroadcast(provisioningCompleteIntent); } private Intent getProvisioningCompleteIntent() { Intent intent = new Intent(ACTION_PROFILE_PROVISIONING_COMPLETE); try { intent.setComponent(mParams.inferDeviceAdminComponentName(this)); } catch (Utils.IllegalProvisioningArgumentException e) { ProvisionLogger.loge("Failed to infer the device admin component name", e); return null; } intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND); if (mParams.adminExtrasBundle != null) { intent.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, mParams.adminExtrasBundle); } return intent; } private ProvisioningParams loadProvisioningParamsFromStore(IntentStore store) { Intent intent = store.load(); if (intent == null) { ProvisionLogger.loge("Fail to retrieve ProvisioningParams from intent store."); return null; } store.clear(); ProvisioningParams params = null; try { params = (new MessageParser()).parseNonNfcIntent(intent, true /* trusted */); } catch (IllegalProvisioningArgumentException e) { ProvisionLogger.loge("Failed to parse provisioning intent", e); } return params; } private void disableComponent(ComponentName component) { PackageManager pm = getPackageManager(); pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } }