2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package android.app.admin;
19 import android.annotation.SdkConstant;
20 import android.annotation.SdkConstant.SdkConstantType;
21 import android.app.Service;
22 import android.content.BroadcastReceiver;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.os.Bundle;
29 * Base class for implementing a device administration component. This
30 * class provides a convenience for interpreting the raw intent actions
31 * that are sent by the system.
33 * <p>The callback methods, like the base
34 * {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()}
35 * method, happen on the main thread of the process. Thus long running
36 * operations must be done on another thread. Note that because a receiver
37 * is done once returning from its receive function, such long-running operations
38 * should probably be done in a {@link Service}.
40 * <p>When publishing your DeviceAdmin subclass as a receiver, it must
41 * handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the
42 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission. A typical
43 * manifest entry would look like:</p>
45 * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration}
47 * <p>The meta-data referenced here provides addition information specific
48 * to the device administrator, as parsed by the {@link DeviceAdminInfo} class.
49 * A typical file would be:</p>
51 * {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data}
53 public class DeviceAdminReceiver extends BroadcastReceiver {
54 private static String TAG = "DevicePolicy";
55 private static boolean DEBUG = false;
56 private static boolean localLOGV = DEBUG || android.util.Config.LOGV;
59 * This is the primary action that a device administrator must implement to be
60 * allowed to manage a device. This will be set to the receiver
61 * when the user enables it for administration. You will generally
62 * handle this in {@link DeviceAdminReceiver#onEnabled(Context, Intent)}. To be
63 * supported, the receiver must also require the
64 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission so
65 * that other applications can not abuse it.
67 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
68 public static final String ACTION_DEVICE_ADMIN_ENABLED
69 = "android.app.action.DEVICE_ADMIN_ENABLED";
72 * Action sent to a device administrator when the user has requested to
73 * disable it, but before this has actually been done. This gives you
74 * a chance to supply a message to the user about the impact of
75 * disabling your admin, by setting the extra field
76 * {@link #EXTRA_DISABLE_WARNING} in the result Intent. If not set,
77 * no warning will be displayed. If set, the given text will be shown
78 * to the user before they disable your admin.
80 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
81 public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
82 = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
85 * A CharSequence that can be shown to the user informing them of the
86 * impact of disabling your admin.
88 * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
90 public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
93 * Action sent to a device administrator when the user has disabled
94 * it. Upon return, the application no longer has access to the
95 * protected device policy manager APIs. You will generally
96 * handle this in {@link DeviceAdminReceiver#onDisabled(Context, Intent)}. Note
97 * that this action will be
98 * sent the receiver regardless of whether it is explicitly listed in
101 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
102 public static final String ACTION_DEVICE_ADMIN_DISABLED
103 = "android.app.action.DEVICE_ADMIN_DISABLED";
106 * Action sent to a device administrator when the user has changed the
107 * password of their device. You can at this point check the characteristics
108 * of the new password with {@link DevicePolicyManager#isActivePasswordSufficient()
109 * DevicePolicyManager.isActivePasswordSufficient()}.
111 * handle this in {@link DeviceAdminReceiver#onPasswordChanged}.
113 * <p>The calling device admin must have requested
114 * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive
117 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
118 public static final String ACTION_PASSWORD_CHANGED
119 = "android.app.action.ACTION_PASSWORD_CHANGED";
122 * Action sent to a device administrator when the user has failed at
123 * attempted to enter the password. You can at this point check the
124 * number of failed password attempts there have been with
125 * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts
126 * DevicePolicyManager.getCurrentFailedPasswordAttempts()}. You will generally
127 * handle this in {@link DeviceAdminReceiver#onPasswordFailed}.
129 * <p>The calling device admin must have requested
130 * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
133 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
134 public static final String ACTION_PASSWORD_FAILED
135 = "android.app.action.ACTION_PASSWORD_FAILED";
138 * Action sent to a device administrator when the user has successfully
139 * entered their password, after failing one or more times.
141 * <p>The calling device admin must have requested
142 * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
145 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
146 public static final String ACTION_PASSWORD_SUCCEEDED
147 = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
150 * Name under which an DevicePolicy component publishes information
151 * about itself. This meta-data must reference an XML resource containing
152 * a device-admin tag. XXX TO DO: describe syntax.
154 public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
156 private DevicePolicyManager mManager;
157 private ComponentName mWho;
160 * Retrieve the DevicePolicyManager interface for this administrator to work
163 public DevicePolicyManager getManager(Context context) {
164 if (mManager != null) {
167 mManager = (DevicePolicyManager)context.getSystemService(
168 Context.DEVICE_POLICY_SERVICE);
173 * Retrieve the ComponentName describing who this device administrator is, for
174 * use in {@link DevicePolicyManager} APIs that require the administrator to
177 public ComponentName getWho(Context context) {
181 mWho = new ComponentName(context, getClass());
186 * Called after the administrator is first enabled, as a result of
187 * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}. At this point you
188 * can use {@link DevicePolicyManager} to set your desired policies.
189 * @param context The running context as per {@link #onReceive}.
190 * @param intent The received intent as per {@link #onReceive}.
192 public void onEnabled(Context context, Intent intent) {
196 * Called when the user has asked to disable the administrator, as a result of
197 * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
198 * a chance to present a warning message to them. The message is returned
199 * as the result; if null is returned (the default implementation), no
200 * message will be displayed.
201 * @param context The running context as per {@link #onReceive}.
202 * @param intent The received intent as per {@link #onReceive}.
203 * @return Return the warning message to display to the user before
204 * being disabled; if null is returned, no message is displayed.
206 public CharSequence onDisableRequested(Context context, Intent intent) {
211 * Called prior to the administrator being disabled, as a result of
212 * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}. Upon return, you
213 * can no longer use the protected parts of the {@link DevicePolicyManager}
215 * @param context The running context as per {@link #onReceive}.
216 * @param intent The received intent as per {@link #onReceive}.
218 public void onDisabled(Context context, Intent intent) {
222 * Called after the user has changed their password, as a result of
223 * receiving {@link #ACTION_PASSWORD_CHANGED}. At this point you
224 * can use {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()
225 * DevicePolicyManager.getCurrentFailedPasswordAttempts()}
226 * to retrieve the active password characteristics.
227 * @param context The running context as per {@link #onReceive}.
228 * @param intent The received intent as per {@link #onReceive}.
230 public void onPasswordChanged(Context context, Intent intent) {
234 * Called after the user has failed at entering their current password, as a result of
235 * receiving {@link #ACTION_PASSWORD_FAILED}. At this point you
236 * can use {@link DevicePolicyManager} to retrieve the number of failed
238 * @param context The running context as per {@link #onReceive}.
239 * @param intent The received intent as per {@link #onReceive}.
241 public void onPasswordFailed(Context context, Intent intent) {
245 * Called after the user has succeeded at entering their current password,
246 * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}. This will
247 * only be received the first time they succeed after having previously
249 * @param context The running context as per {@link #onReceive}.
250 * @param intent The received intent as per {@link #onReceive}.
252 public void onPasswordSucceeded(Context context, Intent intent) {
256 * Intercept standard device administrator broadcasts. Implementations
257 * should not override this method; it is better to implement the
258 * convenience callbacks for each action.
261 public void onReceive(Context context, Intent intent) {
262 String action = intent.getAction();
263 if (ACTION_PASSWORD_CHANGED.equals(action)) {
264 onPasswordChanged(context, intent);
265 } else if (ACTION_PASSWORD_FAILED.equals(action)) {
266 onPasswordFailed(context, intent);
267 } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
268 onPasswordSucceeded(context, intent);
269 } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
270 onEnabled(context, intent);
271 } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
272 CharSequence res = onDisableRequested(context, intent);
274 Bundle extras = getResultExtras(true);
275 extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
277 } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
278 onDisabled(context, intent);