DeviceAdminReceiver.java revision 8cdb6fcd9b6a53978cb2b2ad9ab668ae19392266
1d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn/*
2d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Copyright (C) 2010 The Android Open Source Project
3d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn *
4d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * you may not use this file except in compliance with the License.
6d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * You may obtain a copy of the License at
7d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn *
8d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn *
10d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Unless required by applicable law or agreed to in writing, software
11d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * See the License for the specific language governing permissions and
14d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * limitations under the License.
15d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn */
16d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
1787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornpackage android.app.admin;
18d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
19d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.annotation.SdkConstant;
20d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.annotation.SdkConstant.SdkConstantType;
2187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.Service;
22d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.BroadcastReceiver;
23d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.ComponentName;
24d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Context;
25d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Intent;
268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.os.Bundle;
27d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
28d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn/**
29d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Base class for implementing a device administration component.  This
30d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * class provides a convenience for interpreting the raw intent actions
31d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * that are sent by the system.
328cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel *
33ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn * <p>The callback methods, like the base
34ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn * {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()}
35ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn * method, happen on the main thread of the process.  Thus long running
36ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn * operations must be done on another thread.  Note that because a receiver
37ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn * is done once returning from its receive function, such long-running operations
38ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn * should probably be done in a {@link Service}.
398cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel *
40d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * <p>When publishing your DeviceAdmin subclass as a receiver, it must
41d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the
42d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission.  A typical
43d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * manifest entry would look like:</p>
448cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel *
45ab8a8ed2eb068b696f6b5519c55a03546a5927efDianne Hackborn * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration}
468cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel *
47d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * <p>The meta-data referenced here provides addition information specific
48d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * to the device administrator, as parsed by the {@link DeviceAdminInfo} class.
49d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * A typical file would be:</p>
508cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel *
5188209d15dd5fcb883403525a6455857566e3aee7Andrew Stadler * {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data}
523aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez *
533aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference">
543aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3>
553aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about device administration, read the
563aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/admin/device-admin.html">Device Administration</a>
573aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * developer guide.</p>
583aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div>
59d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn */
60ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackbornpublic class DeviceAdminReceiver extends BroadcastReceiver {
61d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private static String TAG = "DevicePolicy";
6243a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato    private static boolean localLOGV = false;
63d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
64d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
65d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * This is the primary action that a device administrator must implement to be
66d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * allowed to manage a device.  This will be set to the receiver
67d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * when the user enables it for administration.  You will generally
68ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn     * handle this in {@link DeviceAdminReceiver#onEnabled(Context, Intent)}.  To be
69d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * supported, the receiver must also require the
70d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission so
71d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * that other applications can not abuse it.
72d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
73d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
74d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public static final String ACTION_DEVICE_ADMIN_ENABLED
75d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            = "android.app.action.DEVICE_ADMIN_ENABLED";
76d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
77d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
788ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * Action sent to a device administrator when the user has requested to
798ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * disable it, but before this has actually been done.  This gives you
808ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * a chance to supply a message to the user about the impact of
818ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * disabling your admin, by setting the extra field
828ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * {@link #EXTRA_DISABLE_WARNING} in the result Intent.  If not set,
838ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * no warning will be displayed.  If set, the given text will be shown
848ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * to the user before they disable your admin.
858ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     */
868ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
878ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
888ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
898cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    /**
918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * A CharSequence that can be shown to the user informing them of the
928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * impact of disabling your admin.
938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     *
948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     */
968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
978cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
988ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    /**
99d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Action sent to a device administrator when the user has disabled
100d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * it.  Upon return, the application no longer has access to the
101d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * protected device policy manager APIs.  You will generally
102ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn     * handle this in {@link DeviceAdminReceiver#onDisabled(Context, Intent)}.  Note
103d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * that this action will be
104d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * sent the receiver regardless of whether it is explicitly listed in
105d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * its intent filter.
106d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
107d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
108d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public static final String ACTION_DEVICE_ADMIN_DISABLED
109d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            = "android.app.action.DEVICE_ADMIN_DISABLED";
1108cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
111d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
112d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Action sent to a device administrator when the user has changed the
113d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * password of their device.  You can at this point check the characteristics
114254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn     * of the new password with {@link DevicePolicyManager#isActivePasswordSufficient()
115254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn     * DevicePolicyManager.isActivePasswordSufficient()}.
116254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn     * You will generally
117ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn     * handle this in {@link DeviceAdminReceiver#onPasswordChanged}.
1188cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     *
1198aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * <p>The calling device admin must have requested
1208aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive
1218aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * this broadcast.
122d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
123d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
124d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public static final String ACTION_PASSWORD_CHANGED
125d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            = "android.app.action.ACTION_PASSWORD_CHANGED";
1268cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
127d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
128d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Action sent to a device administrator when the user has failed at
129d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * attempted to enter the password.  You can at this point check the
130d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * number of failed password attempts there have been with
131254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn     * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts
132d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * DevicePolicyManager.getCurrentFailedPasswordAttempts()}.  You will generally
133ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn     * handle this in {@link DeviceAdminReceiver#onPasswordFailed}.
1348cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     *
1358aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * <p>The calling device admin must have requested
1368aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
1378aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * this broadcast.
138d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
139d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
140d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public static final String ACTION_PASSWORD_FAILED
141d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            = "android.app.action.ACTION_PASSWORD_FAILED";
1428cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
143d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
144d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Action sent to a device administrator when the user has successfully
145d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * entered their password, after failing one or more times.
1468cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     *
1478aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * <p>The calling device admin must have requested
1488aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
1498aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     * this broadcast.
150d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
151d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
152d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public static final String ACTION_PASSWORD_SUCCEEDED
153d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
154a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
155a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    /**
156a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * Action periodically sent to a device administrator when the device password
1576b85768058b065cc682757a366abc828c9ca727aJim Miller     * is expiring.
158a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
159a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * <p>The calling device admin must have requested
160a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to receive
161a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * this broadcast.
162a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     */
163a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
164a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    public static final String ACTION_PASSWORD_EXPIRING
165a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            = "android.app.action.ACTION_PASSWORD_EXPIRING";
166a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1678cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
1688cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel    /**
1698cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * Action broadcasted when provisioning of a managed profile has completed.
1708cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     */
1718cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1728cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel    public static final String ACTION_PROFILE_PROVISIONING_COMPLETE
1738cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel            = "android.managedprovisioning.ACTION_PROVISIONING_COMPLETE";
1748cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
175d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
176f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa     * Name under which a DevicePolicy component publishes information
177d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * about itself.  This meta-data must reference an XML resource containing
178d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * a device-admin tag.  XXX TO DO: describe syntax.
179d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
180d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
1818cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
182d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private DevicePolicyManager mManager;
183d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private ComponentName mWho;
1848cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
185d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
186d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Retrieve the DevicePolicyManager interface for this administrator to work
187d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * with the system.
188d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
189d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public DevicePolicyManager getManager(Context context) {
190d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (mManager != null) {
191d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return mManager;
192d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
193d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mManager = (DevicePolicyManager)context.getSystemService(
194d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Context.DEVICE_POLICY_SERVICE);
195d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        return mManager;
196d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
1978cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
198d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
199d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Retrieve the ComponentName describing who this device administrator is, for
200d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * use in {@link DevicePolicyManager} APIs that require the administrator to
201d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * identify itself.
202d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
203d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public ComponentName getWho(Context context) {
204d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (mWho != null) {
205d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return mWho;
206d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
207d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mWho = new ComponentName(context, getClass());
208d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        return mWho;
209d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
2108cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
211d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
212d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called after the administrator is first enabled, as a result of
213d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}.  At this point you
214d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * can use {@link DevicePolicyManager} to set your desired policies.
215d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
216d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
217d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
218d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onEnabled(Context context, Intent intent) {
219d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
2208cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
221d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
2228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * Called when the user has asked to disable the administrator, as a result of
2238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
2248ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * a chance to present a warning message to them.  The message is returned
2258ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * as the result; if null is returned (the default implementation), no
2268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * message will be displayed.
2278ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * @param context The running context as per {@link #onReceive}.
2288ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
2298ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * @return Return the warning message to display to the user before
2308ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * being disabled; if null is returned, no message is displayed.
2318ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     */
2328ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    public CharSequence onDisableRequested(Context context, Intent intent) {
2338ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        return null;
2348ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
2358cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
2368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    /**
237d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called prior to the administrator being disabled, as a result of
238d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}.  Upon return, you
239d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * can no longer use the protected parts of the {@link DevicePolicyManager}
240d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * API.
241d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
242d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
243d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
244d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onDisabled(Context context, Intent intent) {
245d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
2468cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
247d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
248d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called after the user has changed their password, as a result of
249d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * receiving {@link #ACTION_PASSWORD_CHANGED}.  At this point you
250d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * can use {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()
251d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * DevicePolicyManager.getCurrentFailedPasswordAttempts()}
252d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * to retrieve the active password characteristics.
253d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
254d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
255d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
256d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onPasswordChanged(Context context, Intent intent) {
257d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
2588cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
259d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
260d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called after the user has failed at entering their current password, as a result of
261d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * receiving {@link #ACTION_PASSWORD_FAILED}.  At this point you
262d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * can use {@link DevicePolicyManager} to retrieve the number of failed
263d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * password attempts.
264d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
265d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
266d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
267d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onPasswordFailed(Context context, Intent intent) {
268d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
2698cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
270d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
271d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called after the user has succeeded at entering their current password,
272d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}.  This will
273d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * only be received the first time they succeed after having previously
274d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * failed.
275d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
276d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
277d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
278d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onPasswordSucceeded(Context context, Intent intent) {
279d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
280a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
281a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    /**
282a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * Called periodically when the password is about to expire or has expired.  It will typically
2836b85768058b065cc682757a366abc828c9ca727aJim Miller     * be called at these times: on device boot, once per day before the password expires,
2846b85768058b065cc682757a366abc828c9ca727aJim Miller     * and at the time when the password expires.
285a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
286a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * <p>If the password is not updated by the user, this method will continue to be called
287a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * once per day until the password is changed or the device admin disables password expiration.
288a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
289a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * <p>The admin will typically post a notification requesting the user to change their password
290a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * in response to this call. The actual password expiration time can be obtained by calling
291a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * {@link DevicePolicyManager#getPasswordExpiration(ComponentName) }
292a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
293a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * <p>The admin should be sure to take down any notifications it posted in response to this call
294a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * when it receives {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent) }.
295a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
296a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * @param context The running context as per {@link #onReceive}.
297a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * @param intent The received intent as per {@link #onReceive}.
298a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     */
299a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    public void onPasswordExpiring(Context context, Intent intent) {
300a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
301a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
302d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
3038cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * Called on the new profile when managed profile provisioning has completed.
3048cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * Managed profile provisioning is the process of setting up the device so that it has a
3058cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * separate profile which is managed by the mobile device management(mdm) application that
3068cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * triggered the provisioning.
3078cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     *
3088cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * <p>As part of provisioning a new profile is created, the mdm is moved to the new profile and
3098cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * set as the owner of the profile so that it has full control over it.
3108cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * This intent is only received by the mdm package that is set as profile owner during
3118cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * provisioning.
3128cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     *
3138cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * <p>Provisioning can be triggered via an intent with the action
3148cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * android.managedprovisioning.ACTION_PROVISION_MANAGED_PROFILE.
3158cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     *
3168cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * @param context The running context as per {@link #onReceive}.
3178cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     * @param intent The received intent as per {@link #onReceive}.
3188cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel     */
3198cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel    public void onProfileProvisioningComplete(Context context, Intent intent) {
3208cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel    }
3218cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
3228cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel    /**
323d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Intercept standard device administrator broadcasts.  Implementations
324d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * should not override this method; it is better to implement the
325d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * convenience callbacks for each action.
326d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
327d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    @Override
328d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onReceive(Context context, Intent intent) {
329d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        String action = intent.getAction();
3308cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel
331d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (ACTION_PASSWORD_CHANGED.equals(action)) {
332d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onPasswordChanged(context, intent);
333d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } else if (ACTION_PASSWORD_FAILED.equals(action)) {
334d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onPasswordFailed(context, intent);
335d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
336d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onPasswordSucceeded(context, intent);
337d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
338d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onEnabled(context, intent);
3398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
3408ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            CharSequence res = onDisableRequested(context, intent);
3418ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (res != null) {
3428ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                Bundle extras = getResultExtras(true);
3438ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
3448ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
345d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
346d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onDisabled(context, intent);
347a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        } else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
348a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            onPasswordExpiring(context, intent);
3498cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel        } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
3508cdb6fcd9b6a53978cb2b2ad9ab668ae19392266Jessica Hummel            onProfileProvisioningComplete(context, intent);
351d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
352d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
353d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn}
354