1 /*
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 
17 package android.app.admin;
18 
19 import android.accounts.AccountManager;
20 import android.annotation.BroadcastBehavior;
21 import android.annotation.IntDef;
22 import android.annotation.SdkConstant;
23 import android.annotation.SdkConstant.SdkConstantType;
24 import android.annotation.SystemApi;
25 import android.app.Service;
26 import android.content.BroadcastReceiver;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.net.Uri;
31 import android.os.Bundle;
32 import android.os.Process;
33 import android.os.UserHandle;
34 import android.security.KeyChain;
35 
36 import java.lang.annotation.Retention;
37 import java.lang.annotation.RetentionPolicy;
38 
39 /**
40  * Base class for implementing a device administration component.  This
41  * class provides a convenience for interpreting the raw intent actions
42  * that are sent by the system.
43  *
44  * <p>The callback methods, like the base
45  * {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()}
46  * method, happen on the main thread of the process.  Thus long running
47  * operations must be done on another thread.  Note that because a receiver
48  * is done once returning from its receive function, such long-running operations
49  * should probably be done in a {@link Service}.
50  *
51  * <p>When publishing your DeviceAdmin subclass as a receiver, it must
52  * handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the
53  * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission.  A typical
54  * manifest entry would look like:</p>
55  *
56  * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration}
57  *
58  * <p>The meta-data referenced here provides addition information specific
59  * to the device administrator, as parsed by the {@link DeviceAdminInfo} class.
60  * A typical file would be:</p>
61  *
62  * {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data}
63  *
64  * <div class="special reference">
65  * <h3>Developer Guides</h3>
66  * <p>For more information about device administration, read the
67  * <a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a>
68  * developer guide.</p>
69  * </div>
70  */
71 public class DeviceAdminReceiver extends BroadcastReceiver {
72     private static String TAG = "DevicePolicy";
73     private static boolean localLOGV = false;
74 
75     /**
76      * This is the primary action that a device administrator must implement to be
77      * allowed to manage a device.  This will be set to the receiver
78      * when the user enables it for administration.  You will generally
79      * handle this in {@link DeviceAdminReceiver#onEnabled(Context, Intent)}.  To be
80      * supported, the receiver must also require the
81      * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission so
82      * that other applications can not abuse it.
83      */
84     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
85     @BroadcastBehavior(explicitOnly = true)
86     public static final String ACTION_DEVICE_ADMIN_ENABLED
87             = "android.app.action.DEVICE_ADMIN_ENABLED";
88 
89     /**
90      * Action sent to a device administrator when the user has requested to
91      * disable it, but before this has actually been done.  This gives you
92      * a chance to supply a message to the user about the impact of
93      * disabling your admin, by setting the extra field
94      * {@link #EXTRA_DISABLE_WARNING} in the result Intent.  If not set,
95      * no warning will be displayed.  If set, the given text will be shown
96      * to the user before they disable your admin.
97      */
98     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
99     @BroadcastBehavior(explicitOnly = true)
100     public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
101             = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
102 
103     /**
104      * A CharSequence that can be shown to the user informing them of the
105      * impact of disabling your admin.
106      *
107      * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
108      */
109     public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
110 
111     /**
112      * Action sent to a device administrator when the user has disabled
113      * it.  Upon return, the application no longer has access to the
114      * protected device policy manager APIs.  You will generally
115      * handle this in {@link DeviceAdminReceiver#onDisabled(Context, Intent)}.  Note
116      * that this action will be
117      * sent the receiver regardless of whether it is explicitly listed in
118      * its intent filter.
119      */
120     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
121     @BroadcastBehavior(explicitOnly = true)
122     public static final String ACTION_DEVICE_ADMIN_DISABLED
123             = "android.app.action.DEVICE_ADMIN_DISABLED";
124 
125     /**
126      * Action sent to a device administrator when the user has changed the password of their device
127      * or profile challenge.  You can at this point check the characteristics
128      * of the new password with {@link DevicePolicyManager#isActivePasswordSufficient()
129      * DevicePolicyManager.isActivePasswordSufficient()}.
130      * You will generally
131      * handle this in {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent, UserHandle)}.
132      *
133      * <p>The calling device admin must have requested
134      * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive
135      * this broadcast.
136      */
137     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
138     @BroadcastBehavior(explicitOnly = true)
139     public static final String ACTION_PASSWORD_CHANGED
140             = "android.app.action.ACTION_PASSWORD_CHANGED";
141 
142     /**
143      * Action sent to a device administrator when the user has entered an incorrect device
144      * or profile challenge password.  You can at this point check the
145      * number of failed password attempts there have been with
146      * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts
147      * DevicePolicyManager.getCurrentFailedPasswordAttempts()}.  You will generally
148      * handle this in {@link DeviceAdminReceiver#onPasswordFailed(Context, Intent, UserHandle)}.
149      *
150      * <p>The calling device admin must have requested
151      * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
152      * this broadcast.
153      */
154     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
155     @BroadcastBehavior(explicitOnly = true)
156     public static final String ACTION_PASSWORD_FAILED
157             = "android.app.action.ACTION_PASSWORD_FAILED";
158 
159     /**
160      * Action sent to a device administrator when the user has successfully entered their device
161      * or profile challenge password, after failing one or more times.  You will generally
162      * handle this in {@link DeviceAdminReceiver#onPasswordSucceeded(Context, Intent, UserHandle)}.
163      *
164      * <p>The calling device admin must have requested
165      * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
166      * this broadcast.
167      */
168     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
169     @BroadcastBehavior(explicitOnly = true)
170     public static final String ACTION_PASSWORD_SUCCEEDED
171             = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
172 
173     /**
174      * Action periodically sent to a device administrator when the device or profile challenge
175      * password is expiring.  You will generally
176      * handle this in {@link DeviceAdminReceiver#onPasswordExpiring(Context, Intent, UserHandle)}.
177      *
178      * <p>The calling device admin must have requested
179      * {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to receive
180      * this broadcast.
181      */
182     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
183     @BroadcastBehavior(explicitOnly = true)
184     public static final String ACTION_PASSWORD_EXPIRING
185             = "android.app.action.ACTION_PASSWORD_EXPIRING";
186 
187     /**
188      * Action sent to a device administrator to notify that the device is entering
189      * lock task mode.  The extra {@link #EXTRA_LOCK_TASK_PACKAGE}
190      * will describe the package using lock task mode.
191      *
192      * <p>The calling device admin must be the device owner or profile
193      * owner to receive this broadcast.
194      *
195      * @see DevicePolicyManager#isLockTaskPermitted(String)
196      */
197     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
198     @BroadcastBehavior(explicitOnly = true)
199     public static final String ACTION_LOCK_TASK_ENTERING
200             = "android.app.action.LOCK_TASK_ENTERING";
201 
202     /**
203      * Action sent to a device administrator to notify that the device is exiting
204      * lock task mode.
205      *
206      * <p>The calling device admin must be the device owner or profile
207      * owner to receive this broadcast.
208      *
209      * @see DevicePolicyManager#isLockTaskPermitted(String)
210      */
211     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
212     @BroadcastBehavior(explicitOnly = true)
213     public static final String ACTION_LOCK_TASK_EXITING
214             = "android.app.action.LOCK_TASK_EXITING";
215 
216     /**
217      * A string containing the name of the package entering lock task mode.
218      *
219      * @see #ACTION_LOCK_TASK_ENTERING
220      */
221     public static final String EXTRA_LOCK_TASK_PACKAGE =
222             "android.app.extra.LOCK_TASK_PACKAGE";
223 
224     /**
225      * Broadcast Action: This broadcast is sent to indicate that provisioning of a managed profile
226      * or managed device has completed successfully.
227      *
228      * <p>The broadcast is limited to the profile that will be managed by the application that
229      * requested provisioning. In the device owner case the profile is the primary user.
230      * The broadcast will also be limited to the {@link DeviceAdminReceiver} component
231      * specified in the original intent or NFC bump that started the provisioning process
232      * (see {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE
233      * DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE}).
234      *
235      * <p>A device admin application which listens to this intent can find out if the device was
236      * provisioned for the device owner or profile owner case by calling respectively
237      * {@link android.app.admin.DevicePolicyManager#isDeviceOwnerApp} and
238      * {@link android.app.admin.DevicePolicyManager#isProfileOwnerApp}. You will generally handle
239      * this in {@link DeviceAdminReceiver#onProfileProvisioningComplete}.
240      *
241      * <p>Input: Nothing.</p>
242      * <p>Output: Nothing</p>
243      */
244     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
245     @BroadcastBehavior(explicitOnly = true)
246     public static final String ACTION_PROFILE_PROVISIONING_COMPLETE =
247             "android.app.action.PROFILE_PROVISIONING_COMPLETE";
248 
249     /**
250      * Action sent to a device administrator to notify that the device user
251      * has declined sharing a bugreport.
252      *
253      * <p>The calling device admin must be the device owner to receive this broadcast.
254      * @see DevicePolicyManager#requestBugreport
255      * @hide
256      */
257     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
258     @BroadcastBehavior(explicitOnly = true)
259     public static final String ACTION_BUGREPORT_SHARING_DECLINED =
260             "android.app.action.BUGREPORT_SHARING_DECLINED";
261 
262     /**
263      * Action sent to a device administrator to notify that the collection of a bugreport
264      * has failed.
265      *
266      * <p>The calling device admin must be the device owner to receive this broadcast.
267      * @see DevicePolicyManager#requestBugreport
268      * @hide
269      */
270     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
271     @BroadcastBehavior(explicitOnly = true)
272     public static final String ACTION_BUGREPORT_FAILED = "android.app.action.BUGREPORT_FAILED";
273 
274     /**
275      * Action sent to a device administrator to share the bugreport.
276      *
277      * <p>The calling device admin must be the device owner to receive this broadcast.
278      * @see DevicePolicyManager#requestBugreport
279      * @hide
280      */
281     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
282     @BroadcastBehavior(explicitOnly = true)
283     public static final String ACTION_BUGREPORT_SHARE =
284             "android.app.action.BUGREPORT_SHARE";
285 
286     /**
287      * Broadcast action: notify that a new batch of security logs is ready to be collected.
288      * @hide
289      */
290     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
291     @BroadcastBehavior(explicitOnly = true)
292     public static final String ACTION_SECURITY_LOGS_AVAILABLE
293             = "android.app.action.SECURITY_LOGS_AVAILABLE";
294 
295     /**
296      * Broadcast action: notify that a new batch of network logs is ready to be collected.
297      * @see DeviceAdminReceiver#onNetworkLogsAvailable
298      * @hide
299      */
300     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
301     @BroadcastBehavior(explicitOnly = true)
302     public static final String ACTION_NETWORK_LOGS_AVAILABLE
303             = "android.app.action.NETWORK_LOGS_AVAILABLE";
304 
305     /**
306      * A {@code long} containing a token of the current batch of network logs, that has to be used
307      * to retrieve the batch of logs by the device owner.
308      *
309      * @see #ACTION_NETWORK_LOGS_AVAILABLE
310      * @see DevicePolicyManager#retrieveNetworkLogs
311      * @hide
312      */
313     public static final String EXTRA_NETWORK_LOGS_TOKEN =
314             "android.app.extra.EXTRA_NETWORK_LOGS_TOKEN";
315 
316     /**
317      * An {@code int} count representing a total count of network logs inside the current batch of
318      * network logs.
319      *
320      * @see #ACTION_NETWORK_LOGS_AVAILABLE
321      * @hide
322      */
323     public static final String EXTRA_NETWORK_LOGS_COUNT =
324             "android.app.extra.EXTRA_NETWORK_LOGS_COUNT";
325 
326     /**
327      * Broadcast action: notify the device owner that a user or profile has been added.
328      * Carries an extra {@link Intent#EXTRA_USER} that has the {@link UserHandle} of
329      * the new user.
330      * @hide
331      */
332     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
333     @BroadcastBehavior(explicitOnly = true)
334     public static final String ACTION_USER_ADDED = "android.app.action.USER_ADDED";
335 
336     /**
337      * Broadcast action: notify the device owner that a user or profile has been removed.
338      * Carries an extra {@link Intent#EXTRA_USER} that has the {@link UserHandle} of
339      * the new user.
340      * @hide
341      */
342     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
343     @BroadcastBehavior(explicitOnly = true)
344     public static final String ACTION_USER_REMOVED = "android.app.action.USER_REMOVED";
345 
346     /**
347      * A string containing the SHA-256 hash of the bugreport file.
348      *
349      * @see #ACTION_BUGREPORT_SHARE
350      * @hide
351      */
352     public static final String EXTRA_BUGREPORT_HASH = "android.app.extra.BUGREPORT_HASH";
353 
354     /**
355      * An {@code int} failure code representing the reason of the bugreport failure. One of
356      * {@link #BUGREPORT_FAILURE_FAILED_COMPLETING}
357      * or {@link #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE}
358      *
359      * @see #ACTION_BUGREPORT_FAILED
360      * @hide
361      */
362     public static final String EXTRA_BUGREPORT_FAILURE_REASON =
363             "android.app.extra.BUGREPORT_FAILURE_REASON";
364 
365     /**
366      * An interface representing reason of bugreport failure.
367      *
368      * @see #EXTRA_BUGREPORT_FAILURE_REASON
369      * @hide
370      */
371     @Retention(RetentionPolicy.SOURCE)
372     @IntDef({
373         BUGREPORT_FAILURE_FAILED_COMPLETING,
374         BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE
375     })
376     public @interface BugreportFailureCode {}
377 
378     /**
379      * Bugreport completion process failed.
380      *
381      * <p>If this error code is received, the requesting of bugreport can be retried.
382      * @see DevicePolicyManager#requestBugreport
383      */
384     public static final int BUGREPORT_FAILURE_FAILED_COMPLETING = 0;
385 
386     /**
387      * Bugreport has been created, but is no longer available for collection.
388      *
389      * <p>This error likely occurs because the user of the device hasn't consented to share
390      * the bugreport for a long period after its creation.
391      *
392      * <p>If this error code is received, the requesting of bugreport can be retried.
393      * @see DevicePolicyManager#requestBugreport
394      */
395     public static final int BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE = 1;
396 
397     /** @hide */
398     public static final String ACTION_CHOOSE_PRIVATE_KEY_ALIAS =
399             "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS";
400 
401     /** @hide */
402     public static final String EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID =
403             "android.app.extra.CHOOSE_PRIVATE_KEY_SENDER_UID";
404 
405     /** @hide */
406     public static final String EXTRA_CHOOSE_PRIVATE_KEY_URI =
407             "android.app.extra.CHOOSE_PRIVATE_KEY_URI";
408 
409     /** @hide */
410     public static final String EXTRA_CHOOSE_PRIVATE_KEY_ALIAS =
411             "android.app.extra.CHOOSE_PRIVATE_KEY_ALIAS";
412 
413     /** @hide */
414     public static final String EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE =
415             "android.app.extra.CHOOSE_PRIVATE_KEY_RESPONSE";
416 
417     /**
418      * Broadcast action: notify device owner that there is a pending system update.
419      * @hide
420      */
421     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
422     @BroadcastBehavior(explicitOnly = true)
423     public static final String ACTION_NOTIFY_PENDING_SYSTEM_UPDATE =
424             "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE";
425 
426     /**
427      * A long type extra for {@link #onSystemUpdatePending} recording the system time as given by
428      * {@link System#currentTimeMillis()} when the current pending system update is first available.
429      * @hide
430      */
431     public static final String EXTRA_SYSTEM_UPDATE_RECEIVED_TIME =
432             "android.app.extra.SYSTEM_UPDATE_RECEIVED_TIME";
433 
434     /**
435      * Name under which a DevicePolicy component publishes information
436      * about itself.  This meta-data must reference an XML resource containing
437      * a device-admin tag.
438      */
439     //  TO DO: describe syntax.
440     public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
441 
442     private DevicePolicyManager mManager;
443     private ComponentName mWho;
444 
445     /**
446      * Retrieve the DevicePolicyManager interface for this administrator to work
447      * with the system.
448      */
getManager(Context context)449     public DevicePolicyManager getManager(Context context) {
450         if (mManager != null) {
451             return mManager;
452         }
453         mManager = (DevicePolicyManager)context.getSystemService(
454                 Context.DEVICE_POLICY_SERVICE);
455         return mManager;
456     }
457 
458     /**
459      * Retrieve the ComponentName describing who this device administrator is, for
460      * use in {@link DevicePolicyManager} APIs that require the administrator to
461      * identify itself.
462      */
getWho(Context context)463     public ComponentName getWho(Context context) {
464         if (mWho != null) {
465             return mWho;
466         }
467         mWho = new ComponentName(context, getClass());
468         return mWho;
469     }
470 
471     /**
472      * Called after the administrator is first enabled, as a result of
473      * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}.  At this point you
474      * can use {@link DevicePolicyManager} to set your desired policies.
475      *
476      * <p> If the admin is activated by a device owner, then the intent
477      * may contain private extras that are relevant to user setup.
478      * {@see DevicePolicyManager#createAndManageUser(ComponentName, String, ComponentName,
479      *      PersistableBundle, int)}
480      *
481      * @param context The running context as per {@link #onReceive}.
482      * @param intent The received intent as per {@link #onReceive}.
483      */
onEnabled(Context context, Intent intent)484     public void onEnabled(Context context, Intent intent) {
485     }
486 
487     /**
488      * Called when the user has asked to disable the administrator, as a result of
489      * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
490      * a chance to present a warning message to them.  The message is returned
491      * as the result; if null is returned (the default implementation), no
492      * message will be displayed.
493      * @param context The running context as per {@link #onReceive}.
494      * @param intent The received intent as per {@link #onReceive}.
495      * @return Return the warning message to display to the user before
496      * being disabled; if null is returned, no message is displayed.
497      */
onDisableRequested(Context context, Intent intent)498     public CharSequence onDisableRequested(Context context, Intent intent) {
499         return null;
500     }
501 
502     /**
503      * Called prior to the administrator being disabled, as a result of
504      * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}.  Upon return, you
505      * can no longer use the protected parts of the {@link DevicePolicyManager}
506      * API.
507      * @param context The running context as per {@link #onReceive}.
508      * @param intent The received intent as per {@link #onReceive}.
509      */
onDisabled(Context context, Intent intent)510     public void onDisabled(Context context, Intent intent) {
511     }
512 
513     /**
514      * Called after the user has changed their device or profile challenge password, as a result of
515      * receiving {@link #ACTION_PASSWORD_CHANGED}.  At this point you
516      * can use {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
517      * to retrieve the active password characteristics.
518      * @param context The running context as per {@link #onReceive}.
519      * @param intent The received intent as per {@link #onReceive}.
520      *
521      * @deprecated From {@link android.os.Build.VERSION_CODES#O}, use
522      *             {@link #onPasswordChanged(Context, Intent, UserHandle)} instead.
523      */
524     @Deprecated
onPasswordChanged(Context context, Intent intent)525     public void onPasswordChanged(Context context, Intent intent) {
526     }
527 
528     /**
529      * Called after the user has changed their device or profile challenge password, as a result of
530      * receiving {@link #ACTION_PASSWORD_CHANGED}.  At this point you
531      * can use {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
532      * to retrieve the active password characteristics.
533      * @param context The running context as per {@link #onReceive}.
534      * @param intent The received intent as per {@link #onReceive}.
535      * @param user The user or profile for whom the password changed. To see whether this
536      *        user is the current profile or a parent user, check for equality with
537      *        {@link Process#myUserHandle}.
538      */
onPasswordChanged(Context context, Intent intent, UserHandle user)539     public void onPasswordChanged(Context context, Intent intent, UserHandle user) {
540         onPasswordChanged(context, intent);
541     }
542 
543     /**
544      * Called after the user has failed at entering their device or profile challenge password,
545      * as a result of receiving {@link #ACTION_PASSWORD_FAILED}.  At this point you can use
546      * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()} to retrieve the number of
547      * failed password attempts.
548      * @param context The running context as per {@link #onReceive}.
549      * @param intent The received intent as per {@link #onReceive}.
550      *
551      * @deprecated From {@link android.os.Build.VERSION_CODES#O}, use
552      *             {@link #onPasswordFailed(Context, Intent, UserHandle)} instead.
553      */
554     @Deprecated
onPasswordFailed(Context context, Intent intent)555     public void onPasswordFailed(Context context, Intent intent) {
556     }
557 
558     /**
559      * Called after the user has failed at entering their device or profile challenge password,
560      * as a result of receiving {@link #ACTION_PASSWORD_FAILED}.  At this point you can use
561      * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()} to retrieve the number of
562      * failed password attempts.
563      * @param context The running context as per {@link #onReceive}.
564      * @param intent The received intent as per {@link #onReceive}.
565      * @param user The user or profile for whom the password check failed. To see whether this
566      *        user is the current profile or a parent user, check for equality with
567      *        {@link Process#myUserHandle}.
568      */
onPasswordFailed(Context context, Intent intent, UserHandle user)569     public void onPasswordFailed(Context context, Intent intent, UserHandle user) {
570         onPasswordFailed(context, intent);
571     }
572 
573     /**
574      * Called after the user has succeeded at entering their device or profile challenge password,
575      * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}.  This will
576      * only be received the first time they succeed after having previously
577      * failed.
578      * @param context The running context as per {@link #onReceive}.
579      * @param intent The received intent as per {@link #onReceive}.
580      *
581      * @deprecated From {@link android.os.Build.VERSION_CODES#O}, use
582      *             {@link #onPasswordSucceeded(Context, Intent, UserHandle)} instead.
583      */
584     @Deprecated
onPasswordSucceeded(Context context, Intent intent)585     public void onPasswordSucceeded(Context context, Intent intent) {
586     }
587 
588     /**
589      * Called after the user has succeeded at entering their device or profile challenge password,
590      * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}.  This will
591      * only be received the first time they succeed after having previously
592      * failed.
593      * @param context The running context as per {@link #onReceive}.
594      * @param intent The received intent as per {@link #onReceive}.
595      * @param user The user of profile for whom the password check succeeded.  To see whether this
596      *        user is the current profile or a parent user, check for equality with
597      *        {@link Process#myUserHandle}.
598      */
onPasswordSucceeded(Context context, Intent intent, UserHandle user)599     public void onPasswordSucceeded(Context context, Intent intent, UserHandle user) {
600         onPasswordSucceeded(context, intent);
601     }
602 
603     /**
604      * Called periodically when the device or profile challenge password is about to expire
605      * or has expired.  It will typically be called at these times: on device boot, once per day
606      * before the password expires, and at the time when the password expires.
607      *
608      * <p>If the password is not updated by the user, this method will continue to be called
609      * once per day until the password is changed or the device admin disables password expiration.
610      *
611      * <p>The admin will typically post a notification requesting the user to change their password
612      * in response to this call. The actual password expiration time can be obtained by calling
613      * {@link DevicePolicyManager#getPasswordExpiration(ComponentName) }
614      *
615      * <p>The admin should be sure to take down any notifications it posted in response to this call
616      * when it receives {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent) }.
617      *
618      * @param context The running context as per {@link #onReceive}.
619      * @param intent The received intent as per {@link #onReceive}.
620      *
621      * @deprecated From {@link android.os.Build.VERSION_CODES#O}, use
622      *             {@link #onPasswordExpiring(Context, Intent, UserHandle)} instead.
623      */
624     @Deprecated
onPasswordExpiring(Context context, Intent intent)625     public void onPasswordExpiring(Context context, Intent intent) {
626     }
627 
628     /**
629      * Called periodically when the device or profile challenge password is about to expire
630      * or has expired.  It will typically be called at these times: on device boot, once per day
631      * before the password expires, and at the time when the password expires.
632      *
633      * <p>If the password is not updated by the user, this method will continue to be called
634      * once per day until the password is changed or the device admin disables password expiration.
635      *
636      * <p>The admin will typically post a notification requesting the user to change their password
637      * in response to this call. The actual password expiration time can be obtained by calling
638      * {@link DevicePolicyManager#getPasswordExpiration(ComponentName) }
639      *
640      * <p>The admin should be sure to take down any notifications it posted in response to this call
641      * when it receives {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent, UserHandle) }.
642      *
643      * @param context The running context as per {@link #onReceive}.
644      * @param intent The received intent as per {@link #onReceive}.
645      * @param user The user or profile for whom the password is expiring. To see whether this
646      *        user is the current profile or a parent user, check for equality with
647      *        {@link Process#myUserHandle}.
648      */
onPasswordExpiring(Context context, Intent intent, UserHandle user)649     public void onPasswordExpiring(Context context, Intent intent, UserHandle user) {
650         onPasswordExpiring(context, intent);
651     }
652 
653     /**
654      * Called when provisioning of a managed profile or managed device has completed successfully.
655      *
656      * <p> As a prerequisite for the execution of this callback the {@link DeviceAdminReceiver} has
657      * to declare an intent filter for {@link #ACTION_PROFILE_PROVISIONING_COMPLETE}.
658      * Its component must also be specified in the {@link DevicePolicyManager#EXTRA_DEVICE_ADMIN}
659      * of the {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} intent that started the
660      * managed provisioning.
661      *
662      * <p>When provisioning of a managed profile is complete, the managed profile is hidden until
663      * the profile owner calls {DevicePolicyManager#setProfileEnabled(ComponentName admin)}.
664      * Typically a profile owner will enable the profile when it has finished any additional setup
665      * such as adding an account by using the {@link AccountManager} and calling apis to bring the
666      * profile into the desired state.
667      *
668      * <p> Note that provisioning completes without waiting for any server interactions, so the
669      * profile owner needs to wait for data to be available if required (e.g. android device ids or
670      * other data that is set as a result of server interactions).
671      *
672      * @param context The running context as per {@link #onReceive}.
673      * @param intent The received intent as per {@link #onReceive}.
674      */
onProfileProvisioningComplete(Context context, Intent intent)675     public void onProfileProvisioningComplete(Context context, Intent intent) {
676     }
677 
678     /**
679      * Called during provisioning of a managed device to allow the device initializer to perform
680      * user setup steps.
681      *
682      * @param context The running context as per {@link #onReceive}.
683      * @param intent The received intent as per {@link #onReceive}.
684      * @deprecated Do not use
685      */
686     @Deprecated
687     @SystemApi
onReadyForUserInitialization(Context context, Intent intent)688     public void onReadyForUserInitialization(Context context, Intent intent) {
689     }
690 
691     /**
692      * Called when a device is entering lock task mode.
693      *
694      * @param context The running context as per {@link #onReceive}.
695      * @param intent The received intent as per {@link #onReceive}.
696      * @param pkg If entering, the authorized package using lock task mode, otherwise null.
697      */
onLockTaskModeEntering(Context context, Intent intent, String pkg)698     public void onLockTaskModeEntering(Context context, Intent intent, String pkg) {
699     }
700 
701     /**
702      * Called when a device is exiting lock task mode.
703      *
704      * @param context The running context as per {@link #onReceive}.
705      * @param intent The received intent as per {@link #onReceive}.
706      */
onLockTaskModeExiting(Context context, Intent intent)707     public void onLockTaskModeExiting(Context context, Intent intent) {
708     }
709 
710     /**
711      * Allows this receiver to select the alias for a private key and certificate pair for
712      * authentication. If this method returns null, the default {@link android.app.Activity} will be
713      * shown that lets the user pick a private key and certificate pair.
714      *
715      * @param context The running context as per {@link #onReceive}.
716      * @param intent The received intent as per {@link #onReceive}.
717      * @param uid The uid asking for the private key and certificate pair.
718      * @param uri The URI to authenticate, may be null.
719      * @param alias The alias preselected by the client, or null.
720      * @return The private key alias to return and grant access to.
721      * @see KeyChain#choosePrivateKeyAlias
722      */
onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri, String alias)723     public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
724             String alias) {
725         return null;
726     }
727 
728     /**
729      * Called when the information about a pending system update is available.
730      *
731      * <p>Allows the receiver to be notified when information about a pending system update is
732      * available from the system update service. The same pending system update can trigger multiple
733      * calls to this method, so it is necessary to examine the incoming parameters for details about
734      * the update.
735      *
736      * <p>This callback is only applicable to device owners and profile owners.
737      *
738      * <p>To get further information about a pending system update (for example, whether or not the
739      * update is a security patch), the device owner or profile owner can call
740      * {@link DevicePolicyManager#getPendingSystemUpdate}.
741      *
742      * @param context The running context as per {@link #onReceive}.
743      * @param intent The received intent as per {@link #onReceive}.
744      * @param receivedTime The time as given by {@link System#currentTimeMillis()} indicating when
745      *        the current pending update was first available. -1 if no pending update is available.
746      * @see DevicePolicyManager#getPendingSystemUpdate
747      */
onSystemUpdatePending(Context context, Intent intent, long receivedTime)748     public void onSystemUpdatePending(Context context, Intent intent, long receivedTime) {
749     }
750 
751     /**
752      * Called when sharing a bugreport has been cancelled by the user of the device.
753      *
754      * <p>This callback is only applicable to device owners.
755      *
756      * @param context The running context as per {@link #onReceive}.
757      * @param intent The received intent as per {@link #onReceive}.
758      * @see DevicePolicyManager#requestBugreport
759      */
onBugreportSharingDeclined(Context context, Intent intent)760     public void onBugreportSharingDeclined(Context context, Intent intent) {
761     }
762 
763     /**
764      * Called when the bugreport has been shared with the device administrator app.
765      *
766      * <p>This callback is only applicable to device owners.
767      *
768      * @param context The running context as per {@link #onReceive}.
769      * @param intent The received intent as per {@link #onReceive}. Contains the URI of
770      * the bugreport file (with MIME type "application/vnd.android.bugreport"), that can be accessed
771      * by calling {@link Intent#getData()}
772      * @param bugreportHash SHA-256 hash of the bugreport file.
773      * @see DevicePolicyManager#requestBugreport
774      */
onBugreportShared(Context context, Intent intent, String bugreportHash)775     public void onBugreportShared(Context context, Intent intent, String bugreportHash) {
776     }
777 
778     /**
779      * Called when the bugreport collection flow has failed.
780      *
781      * <p>This callback is only applicable to device owners.
782      *
783      * @param context The running context as per {@link #onReceive}.
784      * @param intent The received intent as per {@link #onReceive}.
785      * @param failureCode int containing failure code. One of
786      * {@link #BUGREPORT_FAILURE_FAILED_COMPLETING}
787      * or {@link #BUGREPORT_FAILURE_FILE_NO_LONGER_AVAILABLE}
788      * @see DevicePolicyManager#requestBugreport
789      */
onBugreportFailed(Context context, Intent intent, @BugreportFailureCode int failureCode)790     public void onBugreportFailed(Context context, Intent intent,
791             @BugreportFailureCode int failureCode) {
792     }
793 
794     /**
795      * Called when a new batch of security logs can be retrieved.
796      *
797      * <p>If a secondary user or profile is created, this callback won't be received until all users
798      * become affiliated again (even if security logging is enabled).
799      * See {@link DevicePolicyManager#setAffiliationIds}
800      *
801      * <p>This callback will be re-triggered if the logs are not retrieved.
802      *
803      * <p>This callback is only applicable to device owners.
804      *
805      * @param context The running context as per {@link #onReceive}.
806      * @param intent The received intent as per {@link #onReceive}.
807      * @see DevicePolicyManager#retrieveSecurityLogs(ComponentName)
808      */
onSecurityLogsAvailable(Context context, Intent intent)809     public void onSecurityLogsAvailable(Context context, Intent intent) {
810     }
811 
812     /**
813      * Called each time a new batch of network logs can be retrieved. This callback method will only
814      * ever be called when network logging is enabled. The logs can only be retrieved while network
815      * logging is enabled.
816      *
817      * <p>If a secondary user or profile is created, this callback won't be received until all users
818      * become affiliated again (even if network logging is enabled). It will also no longer be
819      * possible to retrieve the network logs batch with the most recent {@code batchToken} provided
820      * by this callback. See {@link DevicePolicyManager#setAffiliationIds}.
821      *
822      * <p>This callback is only applicable to device owners.
823      *
824      * @param context The running context as per {@link #onReceive}.
825      * @param intent The received intent as per {@link #onReceive}.
826      * @param batchToken The token representing the current batch of network logs.
827      * @param networkLogsCount The total count of events in the current batch of network logs.
828      * @see DevicePolicyManager#retrieveNetworkLogs
829      */
onNetworkLogsAvailable(Context context, Intent intent, long batchToken, int networkLogsCount)830     public void onNetworkLogsAvailable(Context context, Intent intent, long batchToken,
831             int networkLogsCount) {
832     }
833 
834      /**
835       * Called when a user or profile is created.
836       *
837       * <p>This callback is only applicable to device owners.
838       *
839       * @param context The running context as per {@link #onReceive}.
840       * @param intent The received intent as per {@link #onReceive}.
841       * @param newUser The {@link UserHandle} of the user that has just been added.
842       */
onUserAdded(Context context, Intent intent, UserHandle newUser)843      public void onUserAdded(Context context, Intent intent, UserHandle newUser) {
844      }
845 
846      /**
847       * Called when a user or profile is removed.
848       *
849       * <p>This callback is only applicable to device owners.
850       *
851       * @param context The running context as per {@link #onReceive}.
852       * @param intent The received intent as per {@link #onReceive}.
853       * @param removedUser The {@link UserHandle} of the user that has just been removed.
854       */
onUserRemoved(Context context, Intent intent, UserHandle removedUser)855      public void onUserRemoved(Context context, Intent intent, UserHandle removedUser) {
856      }
857 
858     /**
859      * Intercept standard device administrator broadcasts.  Implementations
860      * should not override this method; it is better to implement the
861      * convenience callbacks for each action.
862      */
863     @Override
onReceive(Context context, Intent intent)864     public void onReceive(Context context, Intent intent) {
865         String action = intent.getAction();
866 
867         if (ACTION_PASSWORD_CHANGED.equals(action)) {
868             onPasswordChanged(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
869         } else if (ACTION_PASSWORD_FAILED.equals(action)) {
870             onPasswordFailed(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
871         } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
872             onPasswordSucceeded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
873         } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
874             onEnabled(context, intent);
875         } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
876             CharSequence res = onDisableRequested(context, intent);
877             if (res != null) {
878                 Bundle extras = getResultExtras(true);
879                 extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
880             }
881         } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
882             onDisabled(context, intent);
883         } else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
884             onPasswordExpiring(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
885         } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
886             onProfileProvisioningComplete(context, intent);
887         } else if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) {
888             int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1);
889             Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI);
890             String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS);
891             String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias);
892             setResultData(chosenAlias);
893         } else if (ACTION_LOCK_TASK_ENTERING.equals(action)) {
894             String pkg = intent.getStringExtra(EXTRA_LOCK_TASK_PACKAGE);
895             onLockTaskModeEntering(context, intent, pkg);
896         } else if (ACTION_LOCK_TASK_EXITING.equals(action)) {
897             onLockTaskModeExiting(context, intent);
898         } else if (ACTION_NOTIFY_PENDING_SYSTEM_UPDATE.equals(action)) {
899             long receivedTime = intent.getLongExtra(EXTRA_SYSTEM_UPDATE_RECEIVED_TIME, -1);
900             onSystemUpdatePending(context, intent, receivedTime);
901         } else if (ACTION_BUGREPORT_SHARING_DECLINED.equals(action)) {
902             onBugreportSharingDeclined(context, intent);
903         } else if (ACTION_BUGREPORT_SHARE.equals(action)) {
904             String bugreportFileHash = intent.getStringExtra(EXTRA_BUGREPORT_HASH);
905             onBugreportShared(context, intent, bugreportFileHash);
906         } else if (ACTION_BUGREPORT_FAILED.equals(action)) {
907             int failureCode = intent.getIntExtra(EXTRA_BUGREPORT_FAILURE_REASON,
908                     BUGREPORT_FAILURE_FAILED_COMPLETING);
909             onBugreportFailed(context, intent, failureCode);
910         } else if (ACTION_SECURITY_LOGS_AVAILABLE.equals(action)) {
911             onSecurityLogsAvailable(context, intent);
912         } else if (ACTION_NETWORK_LOGS_AVAILABLE.equals(action)) {
913             long batchToken = intent.getLongExtra(EXTRA_NETWORK_LOGS_TOKEN, -1);
914             int networkLogsCount = intent.getIntExtra(EXTRA_NETWORK_LOGS_COUNT, 0);
915             onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount);
916         } else if (ACTION_USER_ADDED.equals(action)) {
917             onUserAdded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
918         } else if (ACTION_USER_REMOVED.equals(action)) {
919             onUserRemoved(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
920         }
921     }
922 }
923