/*
 * 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.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;

import android.os.Bundle;

/**
 * Class that handles the resuming process that takes place after a reboot for encryption
 * during the provisioning process.
 */
public class BootReminder extends BroadcastReceiver {
    private static final int NOTIFY_ID = 1;

    /*
     * Profile owner parameters that are stored in the IntentStore for resuming provisioning.
     */
    private static final String PROFILE_OWNER_PREFERENCES_NAME =
            "profile-owner-provisioning-resume";

    private static final String[] PROFILE_OWNER_STRING_EXTRAS = {
        // Key for the default name of the managed profile
        EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME,
        // Key for the device admin package name
        EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
    };

    private static final String[] PROFILE_OWNER_PERSISTABLE_BUNDLE_EXTRAS = {
        // Key for the admin extras bundle
        EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
    };

    private static final ComponentName PROFILE_OWNER_INTENT_TARGET =
            ManagedProvisioningActivity.ALIAS_NO_CHECK_CALLER;

    /*
     * Device owner parameters that are stored in the IntentStore for resuming provisioning.
     */
    private static final String DEVICE_OWNER_PREFERENCES_NAME =
            "device-owner-provisioning-resume";

    private static final ComponentName DEVICE_OWNER_INTENT_TARGET =
            new ComponentName("com.android.managedprovisioning",
                    "com.android.managedprovisioning.DeviceOwnerProvisioningActivity");

    @Override
    public void onReceive(Context context, Intent intent) {
        if (android.content.Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {

            // Resume profile owner provisioning if applicable.
            IntentStore profileOwnerIntentStore = getProfileOwnerIntentStore(context);
            final Intent resumeProfileOwnerPrvIntent = profileOwnerIntentStore.load();
            if (resumeProfileOwnerPrvIntent != null) {
                if (EncryptDeviceActivity.isDeviceEncrypted()) {
                    // Show reminder notification and then forget about it for next boot
                    profileOwnerIntentStore.clear();
                    setNotification(context, resumeProfileOwnerPrvIntent);
                }
            }

            // Resume device owner provisioning if applicable.
            IntentStore deviceOwnerIntentStore = getDeviceOwnerIntentStore(context);
            Intent resumeDeviceOwnerPrvIntent = deviceOwnerIntentStore.load();
            if (resumeDeviceOwnerPrvIntent != null) {
                deviceOwnerIntentStore.clear();
                resumeDeviceOwnerPrvIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(resumeDeviceOwnerPrvIntent);
            }
        }
    }

    /**
     * Schedule a provisioning reminder notification for the next reboot.
     *
     * {@code extras} should be a Bundle containing the
     * {@link EncryptDeviceActivity.EXTRA_RESUME_TARGET}.
     * This field has only two supported values {@link EncryptDeviceActivity.TARGET_PROFILE_OWNER}
     * and {@link EncryptDeviceActivity.TARGET_DEVICE_OWNER}
     *
     * <p> In case of TARGET_PROFILE_OWNER {@code extras} should further contain a value for at
     * least the key: {@link EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}, a {@link String} which
     * specifies the package to set as profile owner.
     *
     * <p>
     * See {@link MessageParser} for the TARGET_DEVICE_OWNER case.
     * </ul>
     *
     * <p> These fields will be persisted and restored to the provisioner after rebooting. Any other
     * key/value pairs will be ignored.
     */
    public static void setProvisioningReminder(Context context, Bundle extras) {
        IntentStore intentStore;
        String resumeTarget = extras.getString(EncryptDeviceActivity.EXTRA_RESUME_TARGET, null);
        if (resumeTarget == null) {
            return;
        }
        if (resumeTarget.equals(EncryptDeviceActivity.TARGET_PROFILE_OWNER)) {
            intentStore = getProfileOwnerIntentStore(context);
        } else if (resumeTarget.equals(EncryptDeviceActivity.TARGET_DEVICE_OWNER)) {
            intentStore = getDeviceOwnerIntentStore(context);
        } else {
            ProvisionLogger.loge("Unknown resume target for bootreminder.");
            return;
        }
        intentStore.save(extras);
    }

    /**
     * Cancel all active provisioning reminders.
     */
    public static void cancelProvisioningReminder(Context context) {
        getProfileOwnerIntentStore(context).clear();
        getDeviceOwnerIntentStore(context).clear();
        setNotification(context, null);
    }

    private static IntentStore getProfileOwnerIntentStore(Context context) {
        return new IntentStore(context,PROFILE_OWNER_INTENT_TARGET, PROFILE_OWNER_PREFERENCES_NAME)
                .setStringKeys(PROFILE_OWNER_STRING_EXTRAS)
                .setPersistableBundleKeys(PROFILE_OWNER_PERSISTABLE_BUNDLE_EXTRAS);
    }

    private static IntentStore getDeviceOwnerIntentStore(Context context) {
        return new IntentStore(context, DEVICE_OWNER_INTENT_TARGET, DEVICE_OWNER_PREFERENCES_NAME)
                .setStringKeys(MessageParser.DEVICE_OWNER_STRING_EXTRAS)
                .setLongKeys(MessageParser.DEVICE_OWNER_LONG_EXTRAS)
                .setIntKeys(MessageParser.DEVICE_OWNER_INT_EXTRAS)
                .setBooleanKeys(MessageParser.DEVICE_OWNER_BOOLEAN_EXTRAS)
                .setPersistableBundleKeys(MessageParser.DEVICE_OWNER_PERSISTABLE_BUNDLE_EXTRAS);
    }

    /** Create and show the provisioning reminder notification. */
    private static void setNotification(Context context, Intent intent) {
        final NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (intent == null) {
            notificationManager.cancel(NOTIFY_ID);
            return;
        }
        final PendingIntent resumePendingIntent = PendingIntent.getActivity(
                context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        final Notification.Builder notify = new Notification.Builder(context)
                .setContentIntent(resumePendingIntent)
                .setContentTitle(context.getString(R.string.continue_provisioning_notify_title))
                .setContentText(context.getString(R.string.continue_provisioning_notify_text))
                .setSmallIcon(com.android.internal.R.drawable.ic_corp_icon)
                .setVisibility(Notification.VISIBILITY_PUBLIC)
                .setColor(context.getResources().getColor(
                        com.android.internal.R.color.system_notification_accent_color))
                .setAutoCancel(true);
        notificationManager.notify(NOTIFY_ID, notify.build());
    }
}
