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