blob: 1c4a740f3441e11f582588e2c9509a211c1d3b3b [file] [log] [blame]
/*
* 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);
}
}