From 8cdb6fcd9b6a53978cb2b2ad9ab668ae19392266 Mon Sep 17 00:00:00 2001 From: Jessica Hummel Date: Mon, 3 Mar 2014 14:14:51 +0000 Subject: [PATCH] Extend DeviceAdminReceiver to receive provisioning complete broadcast. The managed profile provisioning app completes provisioning (creating the profile, installing the mdm on the secondary user, setting the mdm as the profile owner, removing unneeded apps from secondary user, removing mdm from the primary user). Then it sends a notification that the provisioning has completed across to the new profile. If the mdm, which is now installed on the profile wants to be notified that provisioning has completed it needs to implement this callback method. Change-Id: I75f2d6d19709fd39aa867f1254e0c37a0c936222 --- api/current.txt | 2 + .../app/admin/DeviceAdminReceiver.java | 75 +++++++++++++------ 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/api/current.txt b/api/current.txt index f1aa8bf9e2a6f..e59ee8336841f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -4728,6 +4728,7 @@ package android.app.admin { method public void onPasswordExpiring(android.content.Context, android.content.Intent); method public void onPasswordFailed(android.content.Context, android.content.Intent); method public void onPasswordSucceeded(android.content.Context, android.content.Intent); + method public void onProfileProvisioningComplete(android.content.Context, android.content.Intent); method public void onReceive(android.content.Context, android.content.Intent); field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED"; field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED"; @@ -4736,6 +4737,7 @@ package android.app.admin { field public static final java.lang.String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING"; field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED"; field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED"; + field public static final java.lang.String ACTION_PROVISIONING_COMPLETE = "android.managedprovisioning.ACTION_PROVISIONING_COMPLETE"; field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin"; field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING"; } diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index 30b65de9a690e..00e7da4fc6eea 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -29,25 +29,25 @@ import android.os.Bundle; * Base class for implementing a device administration component. This * class provides a convenience for interpreting the raw intent actions * that are sent by the system. - * + * *

The callback methods, like the base * {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()} * method, happen on the main thread of the process. Thus long running * operations must be done on another thread. Note that because a receiver * is done once returning from its receive function, such long-running operations * should probably be done in a {@link Service}. - * + * *

When publishing your DeviceAdmin subclass as a receiver, it must * handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission. A typical * manifest entry would look like:

- * + * * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration} - * + * *

The meta-data referenced here provides addition information specific * to the device administrator, as parsed by the {@link DeviceAdminInfo} class. * A typical file would be:

- * + * * {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data} * *
@@ -86,7 +86,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED"; - + /** * A CharSequence that can be shown to the user informing them of the * impact of disabling your admin. @@ -94,7 +94,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED */ public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING"; - + /** * Action sent to a device administrator when the user has disabled * it. Upon return, the application no longer has access to the @@ -107,7 +107,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED"; - + /** * Action sent to a device administrator when the user has changed the * password of their device. You can at this point check the characteristics @@ -115,7 +115,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * DevicePolicyManager.isActivePasswordSufficient()}. * You will generally * handle this in {@link DeviceAdminReceiver#onPasswordChanged}. - * + * *

The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive * this broadcast. @@ -123,7 +123,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PASSWORD_CHANGED = "android.app.action.ACTION_PASSWORD_CHANGED"; - + /** * Action sent to a device administrator when the user has failed at * attempted to enter the password. You can at this point check the @@ -131,7 +131,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts * DevicePolicyManager.getCurrentFailedPasswordAttempts()}. You will generally * handle this in {@link DeviceAdminReceiver#onPasswordFailed}. - * + * *

The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive * this broadcast. @@ -139,11 +139,11 @@ public class DeviceAdminReceiver extends BroadcastReceiver { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED"; - + /** * Action sent to a device administrator when the user has successfully * entered their password, after failing one or more times. - * + * *

The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive * this broadcast. @@ -164,16 +164,24 @@ public class DeviceAdminReceiver extends BroadcastReceiver { public static final String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING"; + + /** + * Action broadcasted when provisioning of a managed profile has completed. + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_PROFILE_PROVISIONING_COMPLETE + = "android.managedprovisioning.ACTION_PROVISIONING_COMPLETE"; + /** * Name under which a DevicePolicy component publishes information * about itself. This meta-data must reference an XML resource containing * a device-admin tag. XXX TO DO: describe syntax. */ public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin"; - + private DevicePolicyManager mManager; private ComponentName mWho; - + /** * Retrieve the DevicePolicyManager interface for this administrator to work * with the system. @@ -186,7 +194,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { Context.DEVICE_POLICY_SERVICE); return mManager; } - + /** * Retrieve the ComponentName describing who this device administrator is, for * use in {@link DevicePolicyManager} APIs that require the administrator to @@ -199,7 +207,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { mWho = new ComponentName(context, getClass()); return mWho; } - + /** * Called after the administrator is first enabled, as a result of * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}. At this point you @@ -209,7 +217,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onEnabled(Context context, Intent intent) { } - + /** * Called when the user has asked to disable the administrator, as a result of * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you @@ -224,7 +232,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { public CharSequence onDisableRequested(Context context, Intent intent) { return null; } - + /** * Called prior to the administrator being disabled, as a result of * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}. Upon return, you @@ -235,7 +243,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onDisabled(Context context, Intent intent) { } - + /** * Called after the user has changed their password, as a result of * receiving {@link #ACTION_PASSWORD_CHANGED}. At this point you @@ -247,7 +255,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onPasswordChanged(Context context, Intent intent) { } - + /** * Called after the user has failed at entering their current password, as a result of * receiving {@link #ACTION_PASSWORD_FAILED}. At this point you @@ -258,7 +266,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onPasswordFailed(Context context, Intent intent) { } - + /** * Called after the user has succeeded at entering their current password, * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}. This will @@ -291,6 +299,26 @@ public class DeviceAdminReceiver extends BroadcastReceiver { public void onPasswordExpiring(Context context, Intent intent) { } + /** + * Called on the new profile when managed profile provisioning has completed. + * Managed profile provisioning is the process of setting up the device so that it has a + * separate profile which is managed by the mobile device management(mdm) application that + * triggered the provisioning. + * + *

As part of provisioning a new profile is created, the mdm is moved to the new profile and + * set as the owner of the profile so that it has full control over it. + * This intent is only received by the mdm package that is set as profile owner during + * provisioning. + * + *

Provisioning can be triggered via an intent with the action + * android.managedprovisioning.ACTION_PROVISION_MANAGED_PROFILE. + * + * @param context The running context as per {@link #onReceive}. + * @param intent The received intent as per {@link #onReceive}. + */ + public void onProfileProvisioningComplete(Context context, Intent intent) { + } + /** * Intercept standard device administrator broadcasts. Implementations * should not override this method; it is better to implement the @@ -299,6 +327,7 @@ public class DeviceAdminReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); + if (ACTION_PASSWORD_CHANGED.equals(action)) { onPasswordChanged(context, intent); } else if (ACTION_PASSWORD_FAILED.equals(action)) { @@ -317,6 +346,8 @@ public class DeviceAdminReceiver extends BroadcastReceiver { onDisabled(context, intent); } else if (ACTION_PASSWORD_EXPIRING.equals(action)) { onPasswordExpiring(context, intent); + } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) { + onProfileProvisioningComplete(context, intent); } } }