blob: cfc7241f00fc5fd7a0c4478fbc3e842f9bf4dea1 [file] [log] [blame]
/*
* 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_DEFAULT_MANAGED_PROFILE_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCAL_TIME;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_LOCALE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_HIDDEN;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_HOST;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_PORT;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PROXY_BYPASS;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PAC_URL;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION;
import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM;
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 provisioining 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 ComponentName PROFILE_OWNER_INTENT_TARGET =
new ComponentName("com.android.managedprovisioning",
"com.android.managedprovisioning.ManagedProvisioningActivity");
/*
* 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 String[] DEVICE_OWNER_STRING_EXTRAS = {
EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
EXTRA_PROVISIONING_TIME_ZONE,
EXTRA_PROVISIONING_LOCALE,
EXTRA_PROVISIONING_WIFI_SSID,
EXTRA_PROVISIONING_WIFI_SECURITY_TYPE,
EXTRA_PROVISIONING_WIFI_PASSWORD,
EXTRA_PROVISIONING_WIFI_PROXY_HOST,
EXTRA_PROVISIONING_WIFI_PROXY_BYPASS,
EXTRA_PROVISIONING_WIFI_PAC_URL,
EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION,
EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
};
private static final String[] DEVICE_OWNER_LONG_EXTRAS = {
EXTRA_PROVISIONING_LOCAL_TIME
};
private static final String[] DEVICE_OWNER_INT_EXTRAS = {
EXTRA_PROVISIONING_WIFI_PROXY_PORT
};
private static final String[] DEVICE_OWNER_BOOLEAN_EXTRAS = {
EXTRA_PROVISIONING_WIFI_HIDDEN
};
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 ) {
// Show reminder notification and then forget about it for next boot
setNotification(context, resumeProfileOwnerPrvIntent);
profileOwnerIntentStore.clear();
}
// 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>
* In case of TARGET_DEVICE_OWNER {@code extras} should further contain values for at least
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} and may contain
* {@link #EXTRA_PROVISIONING_TIME_ZONE}, {@link #EXTRA_PROVISIONING_LOCAL_TIME}, and
* {@link #EXTRA_PROVISIONING_LOCALE}.
* A download location may be specified using
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION} accompanied by the
* checksum of the target file {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM}.
* Furthermore a wifi network may be specified using {@link #EXTRA_PROVISIONING_WIFI_SSID}, and
* if applicable {@link #EXTRA_PROVISIONING_WIFI_HIDDEN},
* {@link #EXTRA_PROVISIONING_WIFI_PASSWORD}, {@link #EXTRA_PROVISIONING_WIFI_PROXY_HOST},
* {@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT}, {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE},
* {@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}, {@link #EXTRA_PROVISIONING_WIFI_PAC_URL}.
* </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_STRING_EXTRAS,
new String[0],
new String[0],
new String[0],
PROFILE_OWNER_INTENT_TARGET,
PROFILE_OWNER_PREFERENCES_NAME);
}
private static IntentStore getDeviceOwnerIntentStore(Context context) {
return new IntentStore(context,
DEVICE_OWNER_STRING_EXTRAS,
DEVICE_OWNER_LONG_EXTRAS,
DEVICE_OWNER_INT_EXTRAS,
DEVICE_OWNER_BOOLEAN_EXTRAS,
DEVICE_OWNER_INTENT_TARGET,
DEVICE_OWNER_PREFERENCES_NAME);
}
/** 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(android.R.drawable.ic_dialog_alert)
.setAutoCancel(true);
notificationManager.notify(NOTIFY_ID, notify.build());
}
}