• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.managedprovisioning;
18 
19 import static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE;
20 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
21 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
22 
23 import android.accounts.Account;
24 import android.app.Activity;
25 import android.app.admin.DevicePolicyManager;
26 import android.content.BroadcastReceiver;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.pm.PackageManager;
31 import android.os.AsyncTask;
32 import android.os.Bundle;
33 import android.os.UserHandle;
34 
35 import com.android.managedprovisioning.Utils.IllegalProvisioningArgumentException;
36 
37 /*
38  * This class is used to make sure that we start the mdm after we shut the Setup wizard down.
39  * The shut down of the Setup wizard is initiated in the DeviceOwnerProvisioningActivity or
40  * ProfileOwnerProvisioningActivity by setting Global.DEVICE_PROVISIONED. This will cause the
41  * Setup wizard to shut down and send a HOME intent. Instead of opening the home screen we want
42  * to open the mdm, so the HOME intent is caught by this activity instead which will send the
43  * ACTION_PROFILE_PROVISIONING_COMPLETE to the mdm, which will then open up.
44  */
45 
46 public class HomeReceiverActivity extends Activity {
47 
48     private ProvisioningParams mParams;
49 
50     @Override
onCreate(Bundle savedInstanceState)51     public void onCreate(Bundle savedInstanceState) {
52         super.onCreate(savedInstanceState);
53         try {
54             finalizeProvisioning();
55         } finally {
56             // Disable the HomeReceiverActivity. Make sure this is always called to prevent an
57             // infinite loop of HomeReceiverActivity capturing HOME intent in case something fails.
58             disableComponent(new ComponentName(this, HomeReceiverActivity.class));
59         }
60         finish();
61     }
62 
finalizeProvisioning()63     private void finalizeProvisioning() {
64         mParams = loadProvisioningParamsFromStore(
65                 BootReminder.getProfileOwnerFinalizingIntentStore(this));
66         if (mParams != null) {
67             // Finalizing provisioning: send complete intent to mdm.
68             finalizeProfileOwnerProvisioning();
69             return;
70         }
71         mParams = loadProvisioningParamsFromStore(
72                 BootReminder.getDeviceOwnerFinalizingIntentStore(this));
73         if (mParams != null) {
74             finalizeDeviceOwnerProvisioning();
75         }
76     }
77 
finalizeProfileOwnerProvisioning()78     private void finalizeProfileOwnerProvisioning() {
79         Intent provisioningCompleteIntent = getProvisioningCompleteIntent();
80         if (provisioningCompleteIntent == null) {
81             return;
82         }
83 
84         final UserHandle managedUserHandle = Utils.getManagedProfile(this);
85         if (managedUserHandle == null) {
86             ProvisionLogger.loge("Failed to retrieve the userHandle of the managed profile.");
87             return;
88         }
89         BroadcastReceiver mdmReceivedSuccessReceiver = new MdmReceivedSuccessReceiver(
90                 mParams.accountToMigrate, mParams.deviceAdminPackageName);
91 
92         sendOrderedBroadcastAsUser(provisioningCompleteIntent, managedUserHandle, null,
93                 mdmReceivedSuccessReceiver, null, Activity.RESULT_OK, null, null);
94     }
95 
finalizeDeviceOwnerProvisioning()96     private void finalizeDeviceOwnerProvisioning() {
97         Intent provisioningCompleteIntent = getProvisioningCompleteIntent();
98         if (provisioningCompleteIntent == null) {
99             return;
100         }
101 
102         // Disable the Device Initializer component, if it exists, in case it did not do so itself.
103         if(mParams.deviceInitializerComponentName != null) {
104             DevicePolicyManager devicePolicyManager =
105                     (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
106             devicePolicyManager.removeActiveAdmin(mParams.deviceInitializerComponentName);
107             disableComponent(mParams.deviceInitializerComponentName);
108         }
109 
110         sendBroadcast(provisioningCompleteIntent);
111     }
112 
getProvisioningCompleteIntent()113     private Intent getProvisioningCompleteIntent() {
114         Intent intent = new Intent(ACTION_PROFILE_PROVISIONING_COMPLETE);
115         try {
116             intent.setComponent(mParams.inferDeviceAdminComponentName(this));
117         } catch (Utils.IllegalProvisioningArgumentException e) {
118             ProvisionLogger.loge("Failed to infer the device admin component name", e);
119             return null;
120         }
121         intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND);
122         if (mParams.adminExtrasBundle != null) {
123             intent.putExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE, mParams.adminExtrasBundle);
124         }
125         return intent;
126     }
127 
loadProvisioningParamsFromStore(IntentStore store)128     private ProvisioningParams loadProvisioningParamsFromStore(IntentStore store) {
129         Intent intent = store.load();
130         if (intent == null) {
131             ProvisionLogger.loge("Fail to retrieve ProvisioningParams from intent store.");
132             return null;
133         }
134         store.clear();
135         ProvisioningParams params = null;
136         try {
137             params = (new MessageParser()).parseNonNfcIntent(intent, true /* trusted */);
138         } catch (IllegalProvisioningArgumentException e) {
139             ProvisionLogger.loge("Failed to parse provisioning intent", e);
140         }
141         return params;
142     }
143 
disableComponent(ComponentName component)144     private void disableComponent(ComponentName component) {
145         PackageManager pm = getPackageManager();
146         pm.setComponentEnabledSetting(component,
147                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
148                 PackageManager.DONT_KILL_APP);
149     }
150 }
151