13ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee/*
23ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * Copyright 2014, The Android Open Source Project
33ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee *
43ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * Licensed under the Apache License, Version 2.0 (the "License");
53ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * you may not use this file except in compliance with the License.
63ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * You may obtain a copy of the License at
73ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee *
83ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee *     http://www.apache.org/licenses/LICENSE-2.0
93ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee *
103ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * Unless required by applicable law or agreed to in writing, software
113ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * distributed under the License is distributed on an "AS IS" BASIS,
123ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * See the License for the specific language governing permissions and
143ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee * limitations under the License.
153ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee */
163ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leepackage com.android.managedprovisioning;
173ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
18f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnseimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
193ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
203ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
213ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport android.app.Notification;
223ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport android.app.NotificationManager;
233ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport android.app.PendingIntent;
243ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport android.content.BroadcastReceiver;
253ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport android.content.ComponentName;
263ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport android.content.Context;
273ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport android.content.Intent;
283ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leeimport android.os.Bundle;
293ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
303ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee/**
3156f7157c220d657d48406caf8e0d61904dfd7789Sander Alewijnse * Class that handles the resuming process that takes place after a reboot for encryption
325c9955338d2c1100374f9bee647828854c0d26c7Jessica Hummel * during the provisioning process.
333ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee */
343ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Leepublic class BootReminder extends BroadcastReceiver {
353ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    private static final int NOTIFY_ID = 1;
363ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
3728bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    /*
3828bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse     * Profile owner parameters that are stored in the IntentStore for resuming provisioning.
3928bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse     */
4028bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    private static final String PROFILE_OWNER_PREFERENCES_NAME =
4128bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            "profile-owner-provisioning-resume";
4228bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse
4328bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    private static final String[] PROFILE_OWNER_STRING_EXTRAS = {
4428bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        // Key for the device admin package name
4528bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
4628bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    };
4728bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse
48f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse    private static final String[] PROFILE_OWNER_PERSISTABLE_BUNDLE_EXTRAS = {
49f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        // Key for the admin extras bundle
50f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
51f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse    };
52f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse
5328bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    private static final ComponentName PROFILE_OWNER_INTENT_TARGET =
544af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            ManagedProvisioningActivity.ALIAS_NO_CHECK_CALLER;
5528bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse
5628bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    /*
5728bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse     * Device owner parameters that are stored in the IntentStore for resuming provisioning.
5828bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse     */
5928bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    private static final String DEVICE_OWNER_PREFERENCES_NAME =
6028bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            "device-owner-provisioning-resume";
6128bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse
6228bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    private static final ComponentName DEVICE_OWNER_INTENT_TARGET =
6328bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            new ComponentName("com.android.managedprovisioning",
6428bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse                    "com.android.managedprovisioning.DeviceOwnerProvisioningActivity");
653ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
663ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    @Override
673ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    public void onReceive(Context context, Intent intent) {
683ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee        if (android.content.Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
693ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
7028bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            // Resume profile owner provisioning if applicable.
7128bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            IntentStore profileOwnerIntentStore = getProfileOwnerIntentStore(context);
7228bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            final Intent resumeProfileOwnerPrvIntent = profileOwnerIntentStore.load();
734af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee            if (resumeProfileOwnerPrvIntent != null) {
747691d1932821a16fe3b0dc08b6bdfc9be968f9dcRobin Lee                if (EncryptDeviceActivity.isDeviceEncrypted()) {
757691d1932821a16fe3b0dc08b6bdfc9be968f9dcRobin Lee                    // Show reminder notification and then forget about it for next boot
767691d1932821a16fe3b0dc08b6bdfc9be968f9dcRobin Lee                    profileOwnerIntentStore.clear();
777691d1932821a16fe3b0dc08b6bdfc9be968f9dcRobin Lee                    setNotification(context, resumeProfileOwnerPrvIntent);
787691d1932821a16fe3b0dc08b6bdfc9be968f9dcRobin Lee                }
7928bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            }
8028bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse
8128bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            // Resume device owner provisioning if applicable.
8228bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            IntentStore deviceOwnerIntentStore = getDeviceOwnerIntentStore(context);
8328bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            Intent resumeDeviceOwnerPrvIntent = deviceOwnerIntentStore.load();
8428bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            if (resumeDeviceOwnerPrvIntent != null) {
8528bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse                deviceOwnerIntentStore.clear();
8628bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse                resumeDeviceOwnerPrvIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8728bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse                context.startActivity(resumeDeviceOwnerPrvIntent);
883ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee            }
893ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee        }
903ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    }
913ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
923ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    /**
933ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee     * Schedule a provisioning reminder notification for the next reboot.
943ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee     *
9528bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse     * {@code extras} should be a Bundle containing the
9628bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse     * {@link EncryptDeviceActivity.EXTRA_RESUME_TARGET}.
972e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     * This field has only two supported values {@link EncryptDeviceActivity.TARGET_PROFILE_OWNER}
982e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     * and {@link EncryptDeviceActivity.TARGET_DEVICE_OWNER}
9928bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse     *
1002e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     * <p> In case of TARGET_PROFILE_OWNER {@code extras} should further contain a value for at
1012e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     * least the key: {@link EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, a {@link String} which
1022e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     * specifies the package to set as profile owner.
10328bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse     *
10456f7157c220d657d48406caf8e0d61904dfd7789Sander Alewijnse     * <p>
105d8dcb1f2cf3f537a6199671179470828f74236adSander Alewijnse     * See {@link MessageParser} for the TARGET_DEVICE_OWNER case.
10656f7157c220d657d48406caf8e0d61904dfd7789Sander Alewijnse     * </ul>
1073ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee     *
1082e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     * <p> These fields will be persisted and restored to the provisioner after rebooting. Any other
1092e9cec64bd2a99b7e93d8408173e79b5d6fc3801Jessica Hummel     * key/value pairs will be ignored.
1103ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee     */
1113ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    public static void setProvisioningReminder(Context context, Bundle extras) {
11228bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        IntentStore intentStore;
11328bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        String resumeTarget = extras.getString(EncryptDeviceActivity.EXTRA_RESUME_TARGET, null);
11428bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        if (resumeTarget == null) {
11528bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            return;
1163ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee        }
11728bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        if (resumeTarget.equals(EncryptDeviceActivity.TARGET_PROFILE_OWNER)) {
11828bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            intentStore = getProfileOwnerIntentStore(context);
11928bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        } else if (resumeTarget.equals(EncryptDeviceActivity.TARGET_DEVICE_OWNER)) {
12028bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            intentStore = getDeviceOwnerIntentStore(context);
12128bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        } else {
12228bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            ProvisionLogger.loge("Unknown resume target for bootreminder.");
12328bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse            return;
1243ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee        }
12528bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse        intentStore.save(extras);
12628bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    }
1273ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
128563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee    /**
129563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee     * Cancel all active provisioning reminders.
130563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee     */
131563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee    public static void cancelProvisioningReminder(Context context) {
132563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee        getProfileOwnerIntentStore(context).clear();
133563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee        getDeviceOwnerIntentStore(context).clear();
134563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee        setNotification(context, null);
135563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee    }
136563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee
13728bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    private static IntentStore getProfileOwnerIntentStore(Context context) {
138f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        return new IntentStore(context,PROFILE_OWNER_INTENT_TARGET, PROFILE_OWNER_PREFERENCES_NAME)
139f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                .setStringKeys(PROFILE_OWNER_STRING_EXTRAS)
140f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                .setPersistableBundleKeys(PROFILE_OWNER_PERSISTABLE_BUNDLE_EXTRAS);
14128bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    }
1423ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
14328bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse    private static IntentStore getDeviceOwnerIntentStore(Context context) {
144f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse        return new IntentStore(context, DEVICE_OWNER_INTENT_TARGET, DEVICE_OWNER_PREFERENCES_NAME)
145f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                .setStringKeys(MessageParser.DEVICE_OWNER_STRING_EXTRAS)
146f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                .setLongKeys(MessageParser.DEVICE_OWNER_LONG_EXTRAS)
147f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                .setIntKeys(MessageParser.DEVICE_OWNER_INT_EXTRAS)
148f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                .setBooleanKeys(MessageParser.DEVICE_OWNER_BOOLEAN_EXTRAS)
149f88f709f4a03da9451ea63a60fdb09f0ce972dd3Sander Alewijnse                .setPersistableBundleKeys(MessageParser.DEVICE_OWNER_PERSISTABLE_BUNDLE_EXTRAS);
1503ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    }
1513ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee
1523ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    /** Create and show the provisioning reminder notification. */
1533ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    private static void setNotification(Context context, Intent intent) {
1543ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee        final NotificationManager notificationManager = (NotificationManager)
1553ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee                context.getSystemService(Context.NOTIFICATION_SERVICE);
156563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee        if (intent == null) {
157563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee            notificationManager.cancel(NOTIFY_ID);
158563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee            return;
159563ea1782a60e9428501a600aa2e926741bb1c55Robin Lee        }
1603ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee        final PendingIntent resumePendingIntent = PendingIntent.getActivity(
1613ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee                context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
1623ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee        final Notification.Builder notify = new Notification.Builder(context)
1633ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee                .setContentIntent(resumePendingIntent)
1643ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee                .setContentTitle(context.getString(R.string.continue_provisioning_notify_title))
1653ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee                .setContentText(context.getString(R.string.continue_provisioning_notify_text))
166dd5bb0bffb41d5ad265833ce2ac3d286b760c482Alexandra Gherghina                .setSmallIcon(com.android.internal.R.drawable.ic_corp_statusbar_icon)
1674af4ed0f1d4e01c1b9763b9d7c76192d7ca16654Robin Lee                .setVisibility(Notification.VISIBILITY_PUBLIC)
168ee3ce60d0aa51b9f5347d7c00ed53cfea67d66c2Selim Cinek                .setColor(context.getResources().getColor(
169ee3ce60d0aa51b9f5347d7c00ed53cfea67d66c2Selim Cinek                        com.android.internal.R.color.system_notification_accent_color))
1703ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee                .setAutoCancel(true);
1713ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee        notificationManager.notify(NOTIFY_ID, notify.build());
1723ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee    }
1733ab2b570bd2e18bbdd742ade979de5d368aa0a0eRobin Lee}
174