blob: a35aea77dea431d1c543aa6832824ed93a152b71 [file] [log] [blame]
Robin Lee3ab2b572014-05-06 18:39:07 +01001/*
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 */
16package com.android.managedprovisioning;
17
Alexandra Gherghina7cca9272014-11-26 20:57:13 +000018import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
Sander Alewijnsef88f7092014-08-20 16:26:09 +010019import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
Nicolas Prevot0b447252015-03-09 14:59:02 +000020import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME;
Nicolas Prevot668d65f2015-03-10 17:58:15 +000021import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
Robin Lee3ab2b572014-05-06 18:39:07 +010022
23import android.app.Notification;
24import android.app.NotificationManager;
25import android.app.PendingIntent;
Robin Lee3ab2b572014-05-06 18:39:07 +010026import android.content.BroadcastReceiver;
27import android.content.ComponentName;
28import android.content.Context;
29import android.content.Intent;
Robin Lee3ab2b572014-05-06 18:39:07 +010030import android.os.Bundle;
31
32/**
Rubin Xu292e9a32015-03-20 17:02:38 +000033 * Class that handles the resuming process that takes place after a reboot during the provisioning
34 * process. The reboot could be an unexpected reboot or a reboot during the encryption process.
Robin Lee3ab2b572014-05-06 18:39:07 +010035 */
36public class BootReminder extends BroadcastReceiver {
37 private static final int NOTIFY_ID = 1;
38
Sander Alewijnse28bffd62014-06-05 10:54:26 +010039 /*
40 * Profile owner parameters that are stored in the IntentStore for resuming provisioning.
41 */
42 private static final String PROFILE_OWNER_PREFERENCES_NAME =
43 "profile-owner-provisioning-resume";
44
Nicolas Prevot668d65f2015-03-10 17:58:15 +000045 private static final String[] PROFILE_OWNER_STRING_EXTRAS = {
46 // Key for the device admin package name
47 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
48 };
49
Nicolas Prevot0b447252015-03-09 14:59:02 +000050 private static final String[] PROFILE_OWNER_COMPONENT_NAME_EXTRAS = {
51 // Key for the device admin component name
52 EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME
Sander Alewijnse28bffd62014-06-05 10:54:26 +010053 };
54
Sander Alewijnsef88f7092014-08-20 16:26:09 +010055 private static final String[] PROFILE_OWNER_PERSISTABLE_BUNDLE_EXTRAS = {
56 // Key for the admin extras bundle
57 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
58 };
59
Alexandra Gherghina7cca9272014-11-26 20:57:13 +000060 private static final String[] PROFILE_OWNER_ACCOUNT_EXTRAS = {
61 // Key for the account extras
62 EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE
63 };
64
Sander Alewijnse28bffd62014-06-05 10:54:26 +010065 private static final ComponentName PROFILE_OWNER_INTENT_TARGET =
Sander Alewijnse606780d2014-10-29 10:51:39 +000066 ProfileOwnerPreProvisioningActivity.ALIAS_NO_CHECK_CALLER;
Sander Alewijnse28bffd62014-06-05 10:54:26 +010067
68 /*
Rubin Xu292e9a32015-03-20 17:02:38 +000069 * Device owner parameters that are stored in the IntentStore for resuming provisioning after
70 * encryption.
Sander Alewijnse28bffd62014-06-05 10:54:26 +010071 */
Rubin Xu292e9a32015-03-20 17:02:38 +000072 private static final String DEVICE_OWNER_ENCRYPTION_PREFERENCES_NAME =
73 "device-owner-encryption-resume";
74
75 // Device owner parameter stored for resuming provisioning after unexpected device reboot during
76 // finalizing stage.
77 private static final String DEVICE_OWNER_FINALIZING_PREFERENCES_NAME =
78 "device-owner-finalizing-resume";
Sander Alewijnse28bffd62014-06-05 10:54:26 +010079
Sander Alewijnse28bffd62014-06-05 10:54:26 +010080 private static final ComponentName DEVICE_OWNER_INTENT_TARGET =
81 new ComponentName("com.android.managedprovisioning",
82 "com.android.managedprovisioning.DeviceOwnerProvisioningActivity");
Robin Lee3ab2b572014-05-06 18:39:07 +010083
Rubin Xu292e9a32015-03-20 17:02:38 +000084 private static final ComponentName HOME_RECEIVER_INTENT_TARGET =
85 new ComponentName("com.android.managedprovisioning",
86 "com.android.managedprovisioning.HomeReceiverActivity");
87
Robin Lee3ab2b572014-05-06 18:39:07 +010088 @Override
89 public void onReceive(Context context, Intent intent) {
90 if (android.content.Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Robin Lee3ab2b572014-05-06 18:39:07 +010091
Sander Alewijnse28bffd62014-06-05 10:54:26 +010092 // Resume profile owner provisioning if applicable.
93 IntentStore profileOwnerIntentStore = getProfileOwnerIntentStore(context);
94 final Intent resumeProfileOwnerPrvIntent = profileOwnerIntentStore.load();
Robin Lee4af4ed02014-08-04 12:29:31 +010095 if (resumeProfileOwnerPrvIntent != null) {
Robin Lee7691d192014-08-29 21:29:38 +010096 if (EncryptDeviceActivity.isDeviceEncrypted()) {
97 // Show reminder notification and then forget about it for next boot
98 profileOwnerIntentStore.clear();
99 setNotification(context, resumeProfileOwnerPrvIntent);
100 }
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100101 }
102
Rubin Xu292e9a32015-03-20 17:02:38 +0000103 // Resume device owner provisioning after encryption if applicable.
104 IntentStore deviceOwnerIntentStore = getDeviceOwnerEncryptionResumptionIntentStore(context);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100105 Intent resumeDeviceOwnerPrvIntent = deviceOwnerIntentStore.load();
106 if (resumeDeviceOwnerPrvIntent != null) {
107 deviceOwnerIntentStore.clear();
108 resumeDeviceOwnerPrvIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
109 context.startActivity(resumeDeviceOwnerPrvIntent);
Robin Lee3ab2b572014-05-06 18:39:07 +0100110 }
111 }
112 }
113
114 /**
115 * Schedule a provisioning reminder notification for the next reboot.
116 *
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100117 * {@code extras} should be a Bundle containing the
118 * {@link EncryptDeviceActivity.EXTRA_RESUME_TARGET}.
Jessica Hummel2e9cec62014-06-20 11:50:01 +0100119 * This field has only two supported values {@link EncryptDeviceActivity.TARGET_PROFILE_OWNER}
120 * and {@link EncryptDeviceActivity.TARGET_DEVICE_OWNER}
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100121 *
Jessica Hummel2e9cec62014-06-20 11:50:01 +0100122 * <p> In case of TARGET_PROFILE_OWNER {@code extras} should further contain a value for at
Nicolas Prevot0b447252015-03-09 14:59:02 +0000123 * least the key: {@link EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}, a {@link String}
124 * which, when unflattened to a componentName, specifies the component to set as profile owner.
Robin Lee3ab2b572014-05-06 18:39:07 +0100125 *
Sander Alewijnse56f71572014-06-23 16:21:33 +0100126 * <p>
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100127 * See {@link MessageParser} for the TARGET_DEVICE_OWNER case.
Sander Alewijnse56f71572014-06-23 16:21:33 +0100128 * </ul>
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100129 *
Jessica Hummel2e9cec62014-06-20 11:50:01 +0100130 * <p> These fields will be persisted and restored to the provisioner after rebooting. Any other
131 * key/value pairs will be ignored.
Robin Lee3ab2b572014-05-06 18:39:07 +0100132 */
133 public static void setProvisioningReminder(Context context, Bundle extras) {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100134 IntentStore intentStore;
135 String resumeTarget = extras.getString(EncryptDeviceActivity.EXTRA_RESUME_TARGET, null);
136 if (resumeTarget == null) {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100137 return;
138 }
139 if (resumeTarget.equals(EncryptDeviceActivity.TARGET_PROFILE_OWNER)) {
140 intentStore = getProfileOwnerIntentStore(context);
141 } else if (resumeTarget.equals(EncryptDeviceActivity.TARGET_DEVICE_OWNER)) {
Rubin Xu292e9a32015-03-20 17:02:38 +0000142 intentStore = getDeviceOwnerEncryptionResumptionIntentStore(context);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100143 } else {
144 ProvisionLogger.loge("Unknown resume target for bootreminder.");
145 return;
146 }
147 intentStore.save(extras);
Robin Lee3ab2b572014-05-06 18:39:07 +0100148 }
149
Robin Lee563ea172014-06-20 18:55:31 +0100150 /**
151 * Cancel all active provisioning reminders.
152 */
153 public static void cancelProvisioningReminder(Context context) {
154 getProfileOwnerIntentStore(context).clear();
Rubin Xu292e9a32015-03-20 17:02:38 +0000155 getDeviceOwnerEncryptionResumptionIntentStore(context).clear();
Robin Lee563ea172014-06-20 18:55:31 +0100156 setNotification(context, null);
157 }
158
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100159 private static IntentStore getProfileOwnerIntentStore(Context context) {
Sander Alewijnsef88f7092014-08-20 16:26:09 +0100160 return new IntentStore(context,PROFILE_OWNER_INTENT_TARGET, PROFILE_OWNER_PREFERENCES_NAME)
Nicolas Prevot0b447252015-03-09 14:59:02 +0000161 .setComponentNameKeys(PROFILE_OWNER_COMPONENT_NAME_EXTRAS)
Nicolas Prevot668d65f2015-03-10 17:58:15 +0000162 .setStringKeys(PROFILE_OWNER_STRING_EXTRAS)
Alexandra Gherghina7cca9272014-11-26 20:57:13 +0000163 .setPersistableBundleKeys(PROFILE_OWNER_PERSISTABLE_BUNDLE_EXTRAS)
164 .setAccountKeys(PROFILE_OWNER_ACCOUNT_EXTRAS);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100165 }
Robin Lee3ab2b572014-05-06 18:39:07 +0100166
Rubin Xu292e9a32015-03-20 17:02:38 +0000167 private static IntentStore getDeviceOwnerIntentStore(Context context,
168 ComponentName intentTarget, String storeName) {
169 return new IntentStore(context, intentTarget, storeName)
Nicolas Prevot0b447252015-03-09 14:59:02 +0000170 .setComponentNameKeys(MessageParser.DEVICE_OWNER_COMPONENT_NAME_EXTRAS)
Sander Alewijnsef88f7092014-08-20 16:26:09 +0100171 .setStringKeys(MessageParser.DEVICE_OWNER_STRING_EXTRAS)
172 .setLongKeys(MessageParser.DEVICE_OWNER_LONG_EXTRAS)
173 .setIntKeys(MessageParser.DEVICE_OWNER_INT_EXTRAS)
174 .setBooleanKeys(MessageParser.DEVICE_OWNER_BOOLEAN_EXTRAS)
175 .setPersistableBundleKeys(MessageParser.DEVICE_OWNER_PERSISTABLE_BUNDLE_EXTRAS);
Robin Lee3ab2b572014-05-06 18:39:07 +0100176 }
177
Rubin Xu292e9a32015-03-20 17:02:38 +0000178 private static IntentStore getDeviceOwnerEncryptionResumptionIntentStore(Context context) {
179 return getDeviceOwnerIntentStore(context, DEVICE_OWNER_INTENT_TARGET,
180 DEVICE_OWNER_ENCRYPTION_PREFERENCES_NAME);
181 }
182
183 protected static IntentStore getDeviceOwnerFinalizingIntentStore(Context context) {
184 return getDeviceOwnerIntentStore(context, HOME_RECEIVER_INTENT_TARGET,
185 DEVICE_OWNER_FINALIZING_PREFERENCES_NAME);
186 }
187
Robin Lee3ab2b572014-05-06 18:39:07 +0100188 /** Create and show the provisioning reminder notification. */
189 private static void setNotification(Context context, Intent intent) {
190 final NotificationManager notificationManager = (NotificationManager)
191 context.getSystemService(Context.NOTIFICATION_SERVICE);
Robin Lee563ea172014-06-20 18:55:31 +0100192 if (intent == null) {
193 notificationManager.cancel(NOTIFY_ID);
194 return;
195 }
Robin Lee3ab2b572014-05-06 18:39:07 +0100196 final PendingIntent resumePendingIntent = PendingIntent.getActivity(
197 context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
198 final Notification.Builder notify = new Notification.Builder(context)
199 .setContentIntent(resumePendingIntent)
200 .setContentTitle(context.getString(R.string.continue_provisioning_notify_title))
201 .setContentText(context.getString(R.string.continue_provisioning_notify_text))
Alexandra Gherghinadd5bb0b2014-09-18 16:19:15 +0100202 .setSmallIcon(com.android.internal.R.drawable.ic_corp_statusbar_icon)
Robin Lee4af4ed02014-08-04 12:29:31 +0100203 .setVisibility(Notification.VISIBILITY_PUBLIC)
Selim Cinekee3ce602014-08-27 16:59:20 +0200204 .setColor(context.getResources().getColor(
205 com.android.internal.R.color.system_notification_accent_color))
Robin Lee3ab2b572014-05-06 18:39:07 +0100206 .setAutoCancel(true);
Robin Lee3ab2b572014-05-06 18:39:07 +0100207 notificationManager.notify(NOTIFY_ID, notify.build());
208 }
209}