blob: 85c651107d2a70e089f99c70e5891cd59e35c915 [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;
Robin Lee3ab2b572014-05-06 18:39:07 +010020import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
21
22import android.app.Notification;
23import android.app.NotificationManager;
24import android.app.PendingIntent;
Robin Lee3ab2b572014-05-06 18:39:07 +010025import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.Context;
28import android.content.Intent;
Robin Lee3ab2b572014-05-06 18:39:07 +010029import android.os.Bundle;
30
31/**
Sander Alewijnse56f71572014-06-23 16:21:33 +010032 * Class that handles the resuming process that takes place after a reboot for encryption
Jessica Hummel5c995532014-08-26 16:29:22 +010033 * during the provisioning process.
Robin Lee3ab2b572014-05-06 18:39:07 +010034 */
35public class BootReminder extends BroadcastReceiver {
36 private static final int NOTIFY_ID = 1;
37
Sander Alewijnse28bffd62014-06-05 10:54:26 +010038 /*
39 * Profile owner parameters that are stored in the IntentStore for resuming provisioning.
40 */
41 private static final String PROFILE_OWNER_PREFERENCES_NAME =
42 "profile-owner-provisioning-resume";
43
44 private static final String[] PROFILE_OWNER_STRING_EXTRAS = {
Sander Alewijnse28bffd62014-06-05 10:54:26 +010045 // Key for the device admin package name
46 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
47 };
48
Sander Alewijnsef88f7092014-08-20 16:26:09 +010049 private static final String[] PROFILE_OWNER_PERSISTABLE_BUNDLE_EXTRAS = {
50 // Key for the admin extras bundle
51 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
52 };
53
Alexandra Gherghina7cca9272014-11-26 20:57:13 +000054 private static final String[] PROFILE_OWNER_ACCOUNT_EXTRAS = {
55 // Key for the account extras
56 EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE
57 };
58
Sander Alewijnse28bffd62014-06-05 10:54:26 +010059 private static final ComponentName PROFILE_OWNER_INTENT_TARGET =
Sander Alewijnse606780d2014-10-29 10:51:39 +000060 ProfileOwnerPreProvisioningActivity.ALIAS_NO_CHECK_CALLER;
Sander Alewijnse28bffd62014-06-05 10:54:26 +010061
62 /*
63 * Device owner parameters that are stored in the IntentStore for resuming provisioning.
64 */
65 private static final String DEVICE_OWNER_PREFERENCES_NAME =
66 "device-owner-provisioning-resume";
67
Sander Alewijnse28bffd62014-06-05 10:54:26 +010068 private static final ComponentName DEVICE_OWNER_INTENT_TARGET =
69 new ComponentName("com.android.managedprovisioning",
70 "com.android.managedprovisioning.DeviceOwnerProvisioningActivity");
Robin Lee3ab2b572014-05-06 18:39:07 +010071
72 @Override
73 public void onReceive(Context context, Intent intent) {
74 if (android.content.Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Robin Lee3ab2b572014-05-06 18:39:07 +010075
Sander Alewijnse28bffd62014-06-05 10:54:26 +010076 // Resume profile owner provisioning if applicable.
77 IntentStore profileOwnerIntentStore = getProfileOwnerIntentStore(context);
78 final Intent resumeProfileOwnerPrvIntent = profileOwnerIntentStore.load();
Robin Lee4af4ed02014-08-04 12:29:31 +010079 if (resumeProfileOwnerPrvIntent != null) {
Robin Lee7691d192014-08-29 21:29:38 +010080 if (EncryptDeviceActivity.isDeviceEncrypted()) {
81 // Show reminder notification and then forget about it for next boot
82 profileOwnerIntentStore.clear();
83 setNotification(context, resumeProfileOwnerPrvIntent);
84 }
Sander Alewijnse28bffd62014-06-05 10:54:26 +010085 }
86
87 // Resume device owner provisioning if applicable.
88 IntentStore deviceOwnerIntentStore = getDeviceOwnerIntentStore(context);
89 Intent resumeDeviceOwnerPrvIntent = deviceOwnerIntentStore.load();
90 if (resumeDeviceOwnerPrvIntent != null) {
91 deviceOwnerIntentStore.clear();
92 resumeDeviceOwnerPrvIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
93 context.startActivity(resumeDeviceOwnerPrvIntent);
Robin Lee3ab2b572014-05-06 18:39:07 +010094 }
95 }
96 }
97
98 /**
99 * Schedule a provisioning reminder notification for the next reboot.
100 *
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100101 * {@code extras} should be a Bundle containing the
102 * {@link EncryptDeviceActivity.EXTRA_RESUME_TARGET}.
Jessica Hummel2e9cec62014-06-20 11:50:01 +0100103 * This field has only two supported values {@link EncryptDeviceActivity.TARGET_PROFILE_OWNER}
104 * and {@link EncryptDeviceActivity.TARGET_DEVICE_OWNER}
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100105 *
Jessica Hummel2e9cec62014-06-20 11:50:01 +0100106 * <p> In case of TARGET_PROFILE_OWNER {@code extras} should further contain a value for at
107 * least the key: {@link EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, a {@link String} which
108 * specifies the package to set as profile owner.
Robin Lee3ab2b572014-05-06 18:39:07 +0100109 *
Sander Alewijnse56f71572014-06-23 16:21:33 +0100110 * <p>
Sander Alewijnsed8dcb1f2014-07-24 15:24:50 +0100111 * See {@link MessageParser} for the TARGET_DEVICE_OWNER case.
Sander Alewijnse56f71572014-06-23 16:21:33 +0100112 * </ul>
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100113 *
Jessica Hummel2e9cec62014-06-20 11:50:01 +0100114 * <p> These fields will be persisted and restored to the provisioner after rebooting. Any other
115 * key/value pairs will be ignored.
Robin Lee3ab2b572014-05-06 18:39:07 +0100116 */
117 public static void setProvisioningReminder(Context context, Bundle extras) {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100118 IntentStore intentStore;
119 String resumeTarget = extras.getString(EncryptDeviceActivity.EXTRA_RESUME_TARGET, null);
120 if (resumeTarget == null) {
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100121 return;
122 }
123 if (resumeTarget.equals(EncryptDeviceActivity.TARGET_PROFILE_OWNER)) {
124 intentStore = getProfileOwnerIntentStore(context);
125 } else if (resumeTarget.equals(EncryptDeviceActivity.TARGET_DEVICE_OWNER)) {
126 intentStore = getDeviceOwnerIntentStore(context);
127 } else {
128 ProvisionLogger.loge("Unknown resume target for bootreminder.");
129 return;
130 }
131 intentStore.save(extras);
Robin Lee3ab2b572014-05-06 18:39:07 +0100132 }
133
Robin Lee563ea172014-06-20 18:55:31 +0100134 /**
135 * Cancel all active provisioning reminders.
136 */
137 public static void cancelProvisioningReminder(Context context) {
138 getProfileOwnerIntentStore(context).clear();
139 getDeviceOwnerIntentStore(context).clear();
140 setNotification(context, null);
141 }
142
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100143 private static IntentStore getProfileOwnerIntentStore(Context context) {
Sander Alewijnsef88f7092014-08-20 16:26:09 +0100144 return new IntentStore(context,PROFILE_OWNER_INTENT_TARGET, PROFILE_OWNER_PREFERENCES_NAME)
145 .setStringKeys(PROFILE_OWNER_STRING_EXTRAS)
Alexandra Gherghina7cca9272014-11-26 20:57:13 +0000146 .setPersistableBundleKeys(PROFILE_OWNER_PERSISTABLE_BUNDLE_EXTRAS)
147 .setAccountKeys(PROFILE_OWNER_ACCOUNT_EXTRAS);
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100148 }
Robin Lee3ab2b572014-05-06 18:39:07 +0100149
Sander Alewijnse28bffd62014-06-05 10:54:26 +0100150 private static IntentStore getDeviceOwnerIntentStore(Context context) {
Sander Alewijnsef88f7092014-08-20 16:26:09 +0100151 return new IntentStore(context, DEVICE_OWNER_INTENT_TARGET, DEVICE_OWNER_PREFERENCES_NAME)
152 .setStringKeys(MessageParser.DEVICE_OWNER_STRING_EXTRAS)
153 .setLongKeys(MessageParser.DEVICE_OWNER_LONG_EXTRAS)
154 .setIntKeys(MessageParser.DEVICE_OWNER_INT_EXTRAS)
155 .setBooleanKeys(MessageParser.DEVICE_OWNER_BOOLEAN_EXTRAS)
156 .setPersistableBundleKeys(MessageParser.DEVICE_OWNER_PERSISTABLE_BUNDLE_EXTRAS);
Robin Lee3ab2b572014-05-06 18:39:07 +0100157 }
158
159 /** Create and show the provisioning reminder notification. */
160 private static void setNotification(Context context, Intent intent) {
161 final NotificationManager notificationManager = (NotificationManager)
162 context.getSystemService(Context.NOTIFICATION_SERVICE);
Robin Lee563ea172014-06-20 18:55:31 +0100163 if (intent == null) {
164 notificationManager.cancel(NOTIFY_ID);
165 return;
166 }
Robin Lee3ab2b572014-05-06 18:39:07 +0100167 final PendingIntent resumePendingIntent = PendingIntent.getActivity(
168 context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
169 final Notification.Builder notify = new Notification.Builder(context)
170 .setContentIntent(resumePendingIntent)
171 .setContentTitle(context.getString(R.string.continue_provisioning_notify_title))
172 .setContentText(context.getString(R.string.continue_provisioning_notify_text))
Alexandra Gherghinadd5bb0b2014-09-18 16:19:15 +0100173 .setSmallIcon(com.android.internal.R.drawable.ic_corp_statusbar_icon)
Robin Lee4af4ed02014-08-04 12:29:31 +0100174 .setVisibility(Notification.VISIBILITY_PUBLIC)
Selim Cinekee3ce602014-08-27 16:59:20 +0200175 .setColor(context.getResources().getColor(
176 com.android.internal.R.color.system_notification_accent_color))
Robin Lee3ab2b572014-05-06 18:39:07 +0100177 .setAutoCancel(true);
Robin Lee3ab2b572014-05-06 18:39:07 +0100178 notificationManager.notify(NOTIFY_ID, notify.build());
179 }
180}