blob: cfd5ca88f3a5e71205094bb8d8329760eeba9121 [file] [log] [blame]
Dianne Hackbornd6847842010-01-12 18:14:19 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080017package android.app.admin;
Dianne Hackbornd6847842010-01-12 18:14:19 -080018
Jessica Hummel9da60392014-05-21 12:32:57 +010019import android.accounts.AccountManager;
Michal Karpinski3fc437e2015-12-15 10:09:00 +000020import android.annotation.IntDef;
Dianne Hackbornd6847842010-01-12 18:14:19 -080021import android.annotation.SdkConstant;
22import android.annotation.SdkConstant.SdkConstantType;
Julia Reynolds94e7bf62015-06-10 14:44:56 -040023import android.annotation.SystemApi;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080024import android.app.Service;
Dianne Hackbornd6847842010-01-12 18:14:19 -080025import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.Context;
28import android.content.Intent;
Robin Lee39087b12015-05-05 15:57:17 +010029import android.net.Uri;
Dianne Hackborn8ea138c2010-01-26 18:01:04 -080030import android.os.Bundle;
Robin Lee3798ed52015-02-03 17:55:31 +000031import android.security.KeyChain;
Dianne Hackbornd6847842010-01-12 18:14:19 -080032
Michal Karpinski3fc437e2015-12-15 10:09:00 +000033import java.lang.annotation.Retention;
34import java.lang.annotation.RetentionPolicy;
35
Dianne Hackbornd6847842010-01-12 18:14:19 -080036/**
37 * Base class for implementing a device administration component. This
38 * class provides a convenience for interpreting the raw intent actions
39 * that are sent by the system.
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +000040 *
Dianne Hackbornef6b22f2010-02-16 20:38:49 -080041 * <p>The callback methods, like the base
42 * {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()}
43 * method, happen on the main thread of the process. Thus long running
44 * operations must be done on another thread. Note that because a receiver
45 * is done once returning from its receive function, such long-running operations
46 * should probably be done in a {@link Service}.
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +000047 *
Dianne Hackbornd6847842010-01-12 18:14:19 -080048 * <p>When publishing your DeviceAdmin subclass as a receiver, it must
49 * handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the
50 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission. A typical
51 * manifest entry would look like:</p>
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +000052 *
Dianne Hackbornab8a8ed2010-01-29 19:03:06 -080053 * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration}
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +000054 *
Dianne Hackbornd6847842010-01-12 18:14:19 -080055 * <p>The meta-data referenced here provides addition information specific
56 * to the device administrator, as parsed by the {@link DeviceAdminInfo} class.
57 * A typical file would be:</p>
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +000058 *
Andrew Stadler88209d12010-02-08 22:59:36 -080059 * {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data}
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080060 *
61 * <div class="special reference">
62 * <h3>Developer Guides</h3>
63 * <p>For more information about device administration, read the
64 * <a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a>
65 * developer guide.</p>
66 * </div>
Dianne Hackbornd6847842010-01-12 18:14:19 -080067 */
Dianne Hackbornef6b22f2010-02-16 20:38:49 -080068public class DeviceAdminReceiver extends BroadcastReceiver {
Dianne Hackbornd6847842010-01-12 18:14:19 -080069 private static String TAG = "DevicePolicy";
Joe Onorato43a17652011-04-06 19:22:23 -070070 private static boolean localLOGV = false;
Dianne Hackbornd6847842010-01-12 18:14:19 -080071
72 /**
73 * This is the primary action that a device administrator must implement to be
74 * allowed to manage a device. This will be set to the receiver
75 * when the user enables it for administration. You will generally
Dianne Hackbornef6b22f2010-02-16 20:38:49 -080076 * handle this in {@link DeviceAdminReceiver#onEnabled(Context, Intent)}. To be
Dianne Hackbornd6847842010-01-12 18:14:19 -080077 * supported, the receiver must also require the
78 * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission so
79 * that other applications can not abuse it.
80 */
81 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
82 public static final String ACTION_DEVICE_ADMIN_ENABLED
83 = "android.app.action.DEVICE_ADMIN_ENABLED";
84
85 /**
Dianne Hackborn8ea138c2010-01-26 18:01:04 -080086 * Action sent to a device administrator when the user has requested to
87 * disable it, but before this has actually been done. This gives you
88 * a chance to supply a message to the user about the impact of
89 * disabling your admin, by setting the extra field
90 * {@link #EXTRA_DISABLE_WARNING} in the result Intent. If not set,
91 * no warning will be displayed. If set, the given text will be shown
92 * to the user before they disable your admin.
93 */
94 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
95 public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
96 = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +000097
Dianne Hackborn8ea138c2010-01-26 18:01:04 -080098 /**
99 * A CharSequence that can be shown to the user informing them of the
100 * impact of disabling your admin.
101 *
102 * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
103 */
104 public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000105
Dianne Hackborn8ea138c2010-01-26 18:01:04 -0800106 /**
Dianne Hackbornd6847842010-01-12 18:14:19 -0800107 * Action sent to a device administrator when the user has disabled
108 * it. Upon return, the application no longer has access to the
109 * protected device policy manager APIs. You will generally
Dianne Hackbornef6b22f2010-02-16 20:38:49 -0800110 * handle this in {@link DeviceAdminReceiver#onDisabled(Context, Intent)}. Note
Dianne Hackbornd6847842010-01-12 18:14:19 -0800111 * that this action will be
112 * sent the receiver regardless of whether it is explicitly listed in
113 * its intent filter.
114 */
115 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
116 public static final String ACTION_DEVICE_ADMIN_DISABLED
117 = "android.app.action.DEVICE_ADMIN_DISABLED";
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000118
Dianne Hackbornd6847842010-01-12 18:14:19 -0800119 /**
120 * Action sent to a device administrator when the user has changed the
121 * password of their device. You can at this point check the characteristics
Dianne Hackborn254cb442010-01-27 19:23:59 -0800122 * of the new password with {@link DevicePolicyManager#isActivePasswordSufficient()
123 * DevicePolicyManager.isActivePasswordSufficient()}.
124 * You will generally
Dianne Hackbornef6b22f2010-02-16 20:38:49 -0800125 * handle this in {@link DeviceAdminReceiver#onPasswordChanged}.
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000126 *
Dianne Hackborn8aa2e892010-01-22 11:31:30 -0800127 * <p>The calling device admin must have requested
128 * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive
129 * this broadcast.
Dianne Hackbornd6847842010-01-12 18:14:19 -0800130 */
131 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
132 public static final String ACTION_PASSWORD_CHANGED
133 = "android.app.action.ACTION_PASSWORD_CHANGED";
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000134
Dianne Hackbornd6847842010-01-12 18:14:19 -0800135 /**
136 * Action sent to a device administrator when the user has failed at
137 * attempted to enter the password. You can at this point check the
138 * number of failed password attempts there have been with
Dianne Hackborn254cb442010-01-27 19:23:59 -0800139 * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts
Dianne Hackbornd6847842010-01-12 18:14:19 -0800140 * DevicePolicyManager.getCurrentFailedPasswordAttempts()}. You will generally
Dianne Hackbornef6b22f2010-02-16 20:38:49 -0800141 * handle this in {@link DeviceAdminReceiver#onPasswordFailed}.
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000142 *
Dianne Hackborn8aa2e892010-01-22 11:31:30 -0800143 * <p>The calling device admin must have requested
144 * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
145 * this broadcast.
Dianne Hackbornd6847842010-01-12 18:14:19 -0800146 */
147 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
148 public static final String ACTION_PASSWORD_FAILED
149 = "android.app.action.ACTION_PASSWORD_FAILED";
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000150
Dianne Hackbornd6847842010-01-12 18:14:19 -0800151 /**
152 * Action sent to a device administrator when the user has successfully
153 * entered their password, after failing one or more times.
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000154 *
Dianne Hackborn8aa2e892010-01-22 11:31:30 -0800155 * <p>The calling device admin must have requested
156 * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
157 * this broadcast.
Dianne Hackbornd6847842010-01-12 18:14:19 -0800158 */
159 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
160 public static final String ACTION_PASSWORD_SUCCEEDED
161 = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
Jim Millera4e28d12010-11-08 16:15:47 -0800162
163 /**
164 * Action periodically sent to a device administrator when the device password
Jim Miller6b857682011-02-16 16:27:41 -0800165 * is expiring.
Jim Millera4e28d12010-11-08 16:15:47 -0800166 *
167 * <p>The calling device admin must have requested
168 * {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to receive
169 * this broadcast.
170 */
171 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
172 public static final String ACTION_PASSWORD_EXPIRING
173 = "android.app.action.ACTION_PASSWORD_EXPIRING";
174
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000175 /**
Jason Monk35c62a42014-06-17 10:24:47 -0400176 * Action sent to a device administrator to notify that the device is entering
Benjamin Franz43261142015-02-11 15:59:44 +0000177 * lock task mode. The extra {@link #EXTRA_LOCK_TASK_PACKAGE}
178 * will describe the package using lock task mode.
Jason Monk35c62a42014-06-17 10:24:47 -0400179 *
Jason Monk35c62a42014-06-17 10:24:47 -0400180 * <p>The calling device admin must be the device owner or profile
181 * owner to receive this broadcast.
Benjamin Franzc70d0e72015-02-12 16:12:58 +0000182 *
183 * @see DevicePolicyManager#isLockTaskPermitted(String)
Jason Monk35c62a42014-06-17 10:24:47 -0400184 */
185 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Jason Monk48aacba2014-08-13 16:29:08 -0400186 public static final String ACTION_LOCK_TASK_ENTERING
Jason Monk5503a552014-09-04 14:14:37 -0400187 = "android.app.action.LOCK_TASK_ENTERING";
Jason Monk35c62a42014-06-17 10:24:47 -0400188
189 /**
Jason Monk48aacba2014-08-13 16:29:08 -0400190 * Action sent to a device administrator to notify that the device is exiting
Benjamin Franz43261142015-02-11 15:59:44 +0000191 * lock task mode.
Jason Monk35c62a42014-06-17 10:24:47 -0400192 *
Jason Monk48aacba2014-08-13 16:29:08 -0400193 * <p>The calling device admin must be the device owner or profile
194 * owner to receive this broadcast.
Benjamin Franzc70d0e72015-02-12 16:12:58 +0000195 *
196 * @see DevicePolicyManager#isLockTaskPermitted(String)
Jason Monk35c62a42014-06-17 10:24:47 -0400197 */
Jason Monk48aacba2014-08-13 16:29:08 -0400198 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
199 public static final String ACTION_LOCK_TASK_EXITING
Jason Monk5503a552014-09-04 14:14:37 -0400200 = "android.app.action.LOCK_TASK_EXITING";
Jason Monk35c62a42014-06-17 10:24:47 -0400201
202 /**
Benjamin Franzc70d0e72015-02-12 16:12:58 +0000203 * A string containing the name of the package entering lock task mode.
Jason Monk35c62a42014-06-17 10:24:47 -0400204 *
Benjamin Franzc70d0e72015-02-12 16:12:58 +0000205 * @see #ACTION_LOCK_TASK_ENTERING
Jason Monk35c62a42014-06-17 10:24:47 -0400206 */
207 public static final String EXTRA_LOCK_TASK_PACKAGE =
208 "android.app.extra.LOCK_TASK_PACKAGE";
209
210 /**
Jessica Hummel9da60392014-05-21 12:32:57 +0100211 * Broadcast Action: This broadcast is sent to indicate that provisioning of a managed profile
212 * or managed device has completed successfully.
Jessica Hummelf72078b2014-03-06 16:13:12 +0000213 *
Jessica Hummel9da60392014-05-21 12:32:57 +0100214 * <p>The broadcast is limited to the profile that will be managed by the application that
215 * requested provisioning. In the device owner case the profile is the primary user.
216 * The broadcast will also be limited to the {@link DeviceAdminReceiver} component
217 * specified in the original intent or NFC bump that started the provisioning process
Andrew Solovay27f53372015-03-02 16:37:59 -0800218 * (see {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE
219 * DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE}).
Nicolas Prevot07ac20b2014-05-27 15:37:45 +0100220 *
Sander Alewijnse1cc4ecc2014-06-23 19:56:52 +0100221 * <p>A device admin application which listens to this intent can find out if the device was
222 * provisioned for the device owner or profile owner case by calling respectively
223 * {@link android.app.admin.DevicePolicyManager#isDeviceOwnerApp} and
Julia Reynolds20118f12015-02-11 12:34:08 -0500224 * {@link android.app.admin.DevicePolicyManager#isProfileOwnerApp}. You will generally handle
225 * this in {@link DeviceAdminReceiver#onProfileProvisioningComplete}.
Sander Alewijnse1cc4ecc2014-06-23 19:56:52 +0100226 *
Jessica Hummelf72078b2014-03-06 16:13:12 +0000227 * <p>Input: Nothing.</p>
228 * <p>Output: Nothing</p>
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000229 */
230 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Jessica Hummelf72078b2014-03-06 16:13:12 +0000231 public static final String ACTION_PROFILE_PROVISIONING_COMPLETE =
Jessica Hummel56692162014-09-10 15:12:11 +0100232 "android.app.action.PROFILE_PROVISIONING_COMPLETE";
233
Michal Karpinski3fc437e2015-12-15 10:09:00 +0000234 /**
235 * Action sent to a device administrator to notify that the device user
236 * has declined sharing a bugreport.
237 *
238 * <p>The calling device admin must be the device owner to receive this broadcast.
239 * @see DevicePolicyManager#requestBugreport
240 * @hide
241 */
242 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
243 public static final String ACTION_BUGREPORT_SHARING_DECLINED =
244 "android.app.action.BUGREPORT_SHARING_DECLINED";
245
246 /**
247 * Action sent to a device administrator to notify that the collection of a bugreport
248 * has failed.
249 *
250 * <p>The calling device admin must be the device owner to receive this broadcast.
251 * @see DevicePolicyManager#requestBugreport
252 * @hide
253 */
254 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
255 public static final String ACTION_BUGREPORT_FAILED = "android.app.action.BUGREPORT_FAILED";
256
257 /**
258 * Action sent to a device administrator to share the bugreport.
259 *
260 * <p>The calling device admin must be the device owner to receive this broadcast.
261 * @see DevicePolicyManager#requestBugreport
262 * @hide
263 */
264 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
265 public static final String ACTION_BUGREPORT_SHARE =
266 "android.app.action.BUGREPORT_SHARE";
267
268 /**
269 * A string containing the SHA-256 hash of the bugreport file.
270 *
271 * @see #ACTION_BUGREPORT_SHARE
272 * @hide
273 */
274 public static final String EXTRA_BUGREPORT_HASH = "android.app.extra.BUGREPORT_HASH";
275
276 /**
277 * An {@code int} failure code representing the reason of the bugreport failure.
278 *
279 * @see #ACTION_BUGREPORT_FAILED
280 * @see #BUGREPORT_FAILURE_FAILED_COMPLETING, #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
281 * @hide
282 */
283 public static final String EXTRA_BUGREPORT_FAILURE_REASON =
284 "android.app.extra.BUGREPORT_FAILURE_REASON";
285
286 @Retention(RetentionPolicy.SOURCE)
287 @IntDef({
288 BUGREPORT_FAILURE_FAILED_COMPLETING,
289 BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
290 })
291 /**
292 * An interface representing reason of bugreport failure.
293 *
294 * @see #EXTRA_BUGREPORT_FAILURE_REASON
295 * @hide
296 */
297 public @interface BugreportFailureCode {}
298 /** Bugreport completion process failed. */
299 public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0;
300 /** Bugreport is no longer available for collection. */
301 public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1;
302
Robin Lee3798ed52015-02-03 17:55:31 +0000303 /** @hide */
304 public static final String ACTION_CHOOSE_PRIVATE_KEY_ALIAS = "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS";
305
306 /** @hide */
307 public static final String EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID = "android.app.extra.CHOOSE_PRIVATE_KEY_SENDER_UID";
308
309 /** @hide */
Robin Lee39087b12015-05-05 15:57:17 +0100310 public static final String EXTRA_CHOOSE_PRIVATE_KEY_URI = "android.app.extra.CHOOSE_PRIVATE_KEY_URI";
Robin Lee3798ed52015-02-03 17:55:31 +0000311
312 /** @hide */
313 public static final String EXTRA_CHOOSE_PRIVATE_KEY_ALIAS = "android.app.extra.CHOOSE_PRIVATE_KEY_ALIAS";
314
315 /** @hide */
316 public static final String EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE = "android.app.extra.CHOOSE_PRIVATE_KEY_RESPONSE";
317
Julia Reynolds20118f12015-02-11 12:34:08 -0500318 /**
Rubin Xudc105cc2015-04-14 23:38:01 +0100319 * Broadcast action: notify device owner that there is a pending system update.
320 * @hide
321 */
322 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
323 public static final String ACTION_NOTIFY_PENDING_SYSTEM_UPDATE = "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE";
324
325 /**
326 * A long type extra for {@link #onSystemUpdatePending} recording the system time as given by
327 * {@link System#currentTimeMillis()} when the current pending system update is first available.
328 * @hide
329 */
330 public static final String EXTRA_SYSTEM_UPDATE_RECEIVED_TIME = "android.app.extra.SYSTEM_UPDATE_RECEIVED_TIME";
331
332 /**
Ken Wakasaf76a50c2012-03-09 19:56:35 +0900333 * Name under which a DevicePolicy component publishes information
Dianne Hackbornd6847842010-01-12 18:14:19 -0800334 * about itself. This meta-data must reference an XML resource containing
Andrew Solovay27f53372015-03-02 16:37:59 -0800335 * a device-admin tag.
Dianne Hackbornd6847842010-01-12 18:14:19 -0800336 */
Andrew Solovay27f53372015-03-02 16:37:59 -0800337 // TO DO: describe syntax.
Dianne Hackbornd6847842010-01-12 18:14:19 -0800338 public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000339
Dianne Hackbornd6847842010-01-12 18:14:19 -0800340 private DevicePolicyManager mManager;
341 private ComponentName mWho;
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000342
Dianne Hackbornd6847842010-01-12 18:14:19 -0800343 /**
344 * Retrieve the DevicePolicyManager interface for this administrator to work
345 * with the system.
346 */
347 public DevicePolicyManager getManager(Context context) {
348 if (mManager != null) {
349 return mManager;
350 }
351 mManager = (DevicePolicyManager)context.getSystemService(
352 Context.DEVICE_POLICY_SERVICE);
353 return mManager;
354 }
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000355
Dianne Hackbornd6847842010-01-12 18:14:19 -0800356 /**
357 * Retrieve the ComponentName describing who this device administrator is, for
358 * use in {@link DevicePolicyManager} APIs that require the administrator to
359 * identify itself.
360 */
361 public ComponentName getWho(Context context) {
362 if (mWho != null) {
363 return mWho;
364 }
365 mWho = new ComponentName(context, getClass());
366 return mWho;
367 }
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000368
Dianne Hackbornd6847842010-01-12 18:14:19 -0800369 /**
370 * Called after the administrator is first enabled, as a result of
371 * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}. At this point you
372 * can use {@link DevicePolicyManager} to set your desired policies.
Jason Monk03978a42014-06-10 15:05:30 -0400373 *
374 * <p> If the admin is activated by a device owner, then the intent
375 * may contain private extras that are relevant to user setup.
376 * {@see DevicePolicyManager#createAndInitializeUser(ComponentName, String, String,
377 * ComponentName, Intent)}
378 *
Dianne Hackbornd6847842010-01-12 18:14:19 -0800379 * @param context The running context as per {@link #onReceive}.
380 * @param intent The received intent as per {@link #onReceive}.
381 */
382 public void onEnabled(Context context, Intent intent) {
383 }
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000384
Dianne Hackbornd6847842010-01-12 18:14:19 -0800385 /**
Dianne Hackborn8ea138c2010-01-26 18:01:04 -0800386 * Called when the user has asked to disable the administrator, as a result of
387 * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
388 * a chance to present a warning message to them. The message is returned
389 * as the result; if null is returned (the default implementation), no
390 * message will be displayed.
391 * @param context The running context as per {@link #onReceive}.
392 * @param intent The received intent as per {@link #onReceive}.
393 * @return Return the warning message to display to the user before
394 * being disabled; if null is returned, no message is displayed.
395 */
396 public CharSequence onDisableRequested(Context context, Intent intent) {
397 return null;
398 }
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000399
Dianne Hackborn8ea138c2010-01-26 18:01:04 -0800400 /**
Dianne Hackbornd6847842010-01-12 18:14:19 -0800401 * Called prior to the administrator being disabled, as a result of
402 * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}. Upon return, you
403 * can no longer use the protected parts of the {@link DevicePolicyManager}
404 * API.
405 * @param context The running context as per {@link #onReceive}.
406 * @param intent The received intent as per {@link #onReceive}.
407 */
408 public void onDisabled(Context context, Intent intent) {
409 }
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000410
Dianne Hackbornd6847842010-01-12 18:14:19 -0800411 /**
412 * Called after the user has changed their password, as a result of
413 * receiving {@link #ACTION_PASSWORD_CHANGED}. At this point you
Robin Lee9983aca2016-01-20 17:15:08 +0000414 * can use {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
Dianne Hackbornd6847842010-01-12 18:14:19 -0800415 * to retrieve the active password characteristics.
416 * @param context The running context as per {@link #onReceive}.
417 * @param intent The received intent as per {@link #onReceive}.
418 */
419 public void onPasswordChanged(Context context, Intent intent) {
420 }
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000421
Dianne Hackbornd6847842010-01-12 18:14:19 -0800422 /**
423 * Called after the user has failed at entering their current password, as a result of
424 * receiving {@link #ACTION_PASSWORD_FAILED}. At this point you
425 * can use {@link DevicePolicyManager} to retrieve the number of failed
426 * password attempts.
427 * @param context The running context as per {@link #onReceive}.
428 * @param intent The received intent as per {@link #onReceive}.
429 */
430 public void onPasswordFailed(Context context, Intent intent) {
431 }
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000432
Dianne Hackbornd6847842010-01-12 18:14:19 -0800433 /**
434 * Called after the user has succeeded at entering their current password,
435 * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}. This will
436 * only be received the first time they succeed after having previously
437 * failed.
438 * @param context The running context as per {@link #onReceive}.
439 * @param intent The received intent as per {@link #onReceive}.
440 */
441 public void onPasswordSucceeded(Context context, Intent intent) {
442 }
Jim Millera4e28d12010-11-08 16:15:47 -0800443
444 /**
445 * Called periodically when the password is about to expire or has expired. It will typically
Jim Miller6b857682011-02-16 16:27:41 -0800446 * be called at these times: on device boot, once per day before the password expires,
447 * and at the time when the password expires.
Jim Millera4e28d12010-11-08 16:15:47 -0800448 *
449 * <p>If the password is not updated by the user, this method will continue to be called
450 * once per day until the password is changed or the device admin disables password expiration.
451 *
452 * <p>The admin will typically post a notification requesting the user to change their password
453 * in response to this call. The actual password expiration time can be obtained by calling
454 * {@link DevicePolicyManager#getPasswordExpiration(ComponentName) }
455 *
456 * <p>The admin should be sure to take down any notifications it posted in response to this call
457 * when it receives {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent) }.
458 *
459 * @param context The running context as per {@link #onReceive}.
460 * @param intent The received intent as per {@link #onReceive}.
461 */
462 public void onPasswordExpiring(Context context, Intent intent) {
463 }
464
Dianne Hackbornd6847842010-01-12 18:14:19 -0800465 /**
Jessica Hummel9da60392014-05-21 12:32:57 +0100466 * Called when provisioning of a managed profile or managed device has completed successfully.
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000467 *
Julia Reynolds20118f12015-02-11 12:34:08 -0500468 * <p> As a prerequisite for the execution of this callback the {@link DeviceAdminReceiver} has
Jessica Hummel9da60392014-05-21 12:32:57 +0100469 * to declare an intent filter for {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}.
470 * Its component must also be specified in the {@link DevicePolicyManager#EXTRA_DEVICE_ADMIN}
471 * of the {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} intent that started the
472 * managed provisioning.
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000473 *
Julia Reynolds20118f12015-02-11 12:34:08 -0500474 * <p>When provisioning of a managed profile is complete, the managed profile is hidden until
475 * the profile owner calls {DevicePolicyManager#setProfileEnabled(ComponentName admin)}.
476 * Typically a profile owner will enable the profile when it has finished any additional setup
477 * such as adding an account by using the {@link AccountManager} and calling apis to bring the
478 * profile into the desired state.
Jessica Hummel9da60392014-05-21 12:32:57 +0100479 *
480 * <p> Note that provisioning completes without waiting for any server interactions, so the
Julia Reynolds20118f12015-02-11 12:34:08 -0500481 * profile owner needs to wait for data to be available if required (e.g. android device ids or
Jessica Hummel9da60392014-05-21 12:32:57 +0100482 * other data that is set as a result of server interactions).
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000483 *
484 * @param context The running context as per {@link #onReceive}.
485 * @param intent The received intent as per {@link #onReceive}.
486 */
487 public void onProfileProvisioningComplete(Context context, Intent intent) {
488 }
489
490 /**
Julia Reynolds20118f12015-02-11 12:34:08 -0500491 * Called during provisioning of a managed device to allow the device initializer to perform
Craig Lafayettee7ee54e2015-09-21 13:48:53 -0400492 * user setup steps.
Julia Reynolds20118f12015-02-11 12:34:08 -0500493 *
494 * @param context The running context as per {@link #onReceive}.
495 * @param intent The received intent as per {@link #onReceive}.
Craig Lafayettee7ee54e2015-09-21 13:48:53 -0400496 * @deprecated Do not use
Julia Reynolds20118f12015-02-11 12:34:08 -0500497 */
Craig Lafayettee7ee54e2015-09-21 13:48:53 -0400498 @Deprecated
Julia Reynolds94e7bf62015-06-10 14:44:56 -0400499 @SystemApi
Julia Reynolds20118f12015-02-11 12:34:08 -0500500 public void onReadyForUserInitialization(Context context, Intent intent) {
501 }
502
503 /**
Benjamin Franz43261142015-02-11 15:59:44 +0000504 * Called when a device is entering lock task mode.
Jason Monk35c62a42014-06-17 10:24:47 -0400505 *
506 * @param context The running context as per {@link #onReceive}.
507 * @param intent The received intent as per {@link #onReceive}.
Jason Monk35c62a42014-06-17 10:24:47 -0400508 * @param pkg If entering, the authorized package using lock task mode, otherwise null.
509 */
Jason Monk48aacba2014-08-13 16:29:08 -0400510 public void onLockTaskModeEntering(Context context, Intent intent, String pkg) {
511 }
512
513 /**
Benjamin Franz43261142015-02-11 15:59:44 +0000514 * Called when a device is exiting lock task mode.
Jason Monk48aacba2014-08-13 16:29:08 -0400515 *
516 * @param context The running context as per {@link #onReceive}.
517 * @param intent The received intent as per {@link #onReceive}.
518 */
519 public void onLockTaskModeExiting(Context context, Intent intent) {
Jason Monk35c62a42014-06-17 10:24:47 -0400520 }
521
522 /**
Robin Lee3798ed52015-02-03 17:55:31 +0000523 * Allows this receiver to select the alias for a private key and certificate pair for
524 * authentication. If this method returns null, the default {@link android.app.Activity} will be
525 * shown that lets the user pick a private key and certificate pair.
526 *
527 * @param context The running context as per {@link #onReceive}.
528 * @param intent The received intent as per {@link #onReceive}.
529 * @param uid The uid asking for the private key and certificate pair.
Robin Lee39087b12015-05-05 15:57:17 +0100530 * @param uri The URI to authenticate, may be null.
Robin Lee3798ed52015-02-03 17:55:31 +0000531 * @param alias The alias preselected by the client, or null.
532 * @return The private key alias to return and grant access to.
533 * @see KeyChain#choosePrivateKeyAlias
534 */
Robin Lee39087b12015-05-05 15:57:17 +0100535 public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
536 String alias) {
Robin Lee3798ed52015-02-03 17:55:31 +0000537 return null;
538 }
539
540 /**
Rubin Xudc105cc2015-04-14 23:38:01 +0100541 * Allows the receiver to be notified when information about a pending system update is
542 * available from the system update service. The same pending system update can trigger multiple
543 * calls to this method, so it is necessary to examine the incoming parameters for details about
544 * the update.
545 * <p>
546 * This callback is only applicable to device owners.
547 *
548 * @param context The running context as per {@link #onReceive}.
549 * @param intent The received intent as per {@link #onReceive}.
550 * @param receivedTime The time as given by {@link System#currentTimeMillis()} indicating when
551 * the current pending update was first available. -1 if no pending update is available.
552 */
553 public void onSystemUpdatePending(Context context, Intent intent, long receivedTime) {
554 }
555
556 /**
Michal Karpinski3fc437e2015-12-15 10:09:00 +0000557 * Called when sharing a bugreport has been cancelled by the user of the device.
558 *
559 * <p>This callback is only applicable to device owners.
560 *
561 * @param context The running context as per {@link #onReceive}.
562 * @param intent The received intent as per {@link #onReceive}.
563 * @see DevicePolicyManager#requestBugreport
564 */
565 public void onBugreportSharingDeclined(Context context, Intent intent) {
566 }
567
568 /**
569 * Called when the bugreport has been shared with the device administrator app.
570 *
571 * <p>This callback is only applicable to device owners.
572 *
573 * @param context The running context as per {@link #onReceive}.
574 * @param intent The received intent as per {@link #onReceive}. Contains the URI of
575 * the bugreport file (with MIME type "application/vnd.android.bugreport"), that can be accessed
576 * by calling {@link Intent#getData()}
577 * @param bugreportHash SHA-256 hash of the bugreport file.
578 * @see DevicePolicyManager#requestBugreport
579 */
580 public void onBugreportShared(Context context, Intent intent, String bugreportHash) {
581 }
582
583 /**
584 * Called when the bugreport collection flow has failed.
585 *
586 * <p>This callback is only applicable to device owners.
587 *
588 * @param context The running context as per {@link #onReceive}.
589 * @param intent The received intent as per {@link #onReceive}.
590 * @param failureCode int containing failure code. One of
591 * #BUGREPORT_FAILURE_FAILED_COMPLETING or #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
592 * @see DevicePolicyManager#requestBugreport
593 */
594 public void onBugreportFailed(Context context, Intent intent,
595 @BugreportFailureCode int failureCode) {
596 }
597
598 /**
Dianne Hackbornd6847842010-01-12 18:14:19 -0800599 * Intercept standard device administrator broadcasts. Implementations
600 * should not override this method; it is better to implement the
601 * convenience callbacks for each action.
602 */
603 @Override
604 public void onReceive(Context context, Intent intent) {
605 String action = intent.getAction();
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000606
Dianne Hackbornd6847842010-01-12 18:14:19 -0800607 if (ACTION_PASSWORD_CHANGED.equals(action)) {
608 onPasswordChanged(context, intent);
609 } else if (ACTION_PASSWORD_FAILED.equals(action)) {
610 onPasswordFailed(context, intent);
611 } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
612 onPasswordSucceeded(context, intent);
613 } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
614 onEnabled(context, intent);
Dianne Hackborn8ea138c2010-01-26 18:01:04 -0800615 } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
616 CharSequence res = onDisableRequested(context, intent);
617 if (res != null) {
618 Bundle extras = getResultExtras(true);
619 extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
620 }
Dianne Hackbornd6847842010-01-12 18:14:19 -0800621 } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
622 onDisabled(context, intent);
Jim Millera4e28d12010-11-08 16:15:47 -0800623 } else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
624 onPasswordExpiring(context, intent);
Jessica Hummel8cdb6fc2014-03-03 14:14:51 +0000625 } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
626 onProfileProvisioningComplete(context, intent);
Robin Lee3798ed52015-02-03 17:55:31 +0000627 } else if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) {
Robin Leeabf35702015-02-17 14:12:48 +0000628 int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1);
Robin Lee39087b12015-05-05 15:57:17 +0100629 Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI);
Robin Lee3798ed52015-02-03 17:55:31 +0000630 String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS);
Robin Lee39087b12015-05-05 15:57:17 +0100631 String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias);
Robin Lee3798ed52015-02-03 17:55:31 +0000632 setResultData(chosenAlias);
Jason Monk48aacba2014-08-13 16:29:08 -0400633 } else if (ACTION_LOCK_TASK_ENTERING.equals(action)) {
Jason Monk35c62a42014-06-17 10:24:47 -0400634 String pkg = intent.getStringExtra(EXTRA_LOCK_TASK_PACKAGE);
Jason Monk48aacba2014-08-13 16:29:08 -0400635 onLockTaskModeEntering(context, intent, pkg);
636 } else if (ACTION_LOCK_TASK_EXITING.equals(action)) {
637 onLockTaskModeExiting(context, intent);
Rubin Xudc105cc2015-04-14 23:38:01 +0100638 } else if (ACTION_NOTIFY_PENDING_SYSTEM_UPDATE.equals(action)) {
639 long receivedTime = intent.getLongExtra(EXTRA_SYSTEM_UPDATE_RECEIVED_TIME, -1);
640 onSystemUpdatePending(context, intent, receivedTime);
Michal Karpinski3fc437e2015-12-15 10:09:00 +0000641 } else if (ACTION_BUGREPORT_SHARING_DECLINED.equals(action)) {
642 onBugreportSharingDeclined(context, intent);
643 } else if (ACTION_BUGREPORT_SHARE.equals(action)) {
644 String bugreportFileHash = intent.getStringExtra(EXTRA_BUGREPORT_HASH);
645 onBugreportShared(context, intent, bugreportFileHash);
646 } else if (ACTION_BUGREPORT_FAILED.equals(action)) {
647 int failureCode = intent.getIntExtra(EXTRA_BUGREPORT_FAILURE_REASON,
648 BUGREPORT_FAILURE_FAILED_COMPLETING);
649 onBugreportFailed(context, intent, failureCode);
Dianne Hackbornd6847842010-01-12 18:14:19 -0800650 }
651 }
652}