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.
32d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn *
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}.
39ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn *
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>
44d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn *
45ab8a8ed2eb068b696f6b5519c55a03546a5927efDianne Hackborn * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration}
46d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn *
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>
50d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn *
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";
898ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
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";
978ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
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";
110d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
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}.
1188aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     *
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";
126d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
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}.
1348aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     *
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";
142d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
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.
1468aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn     *
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
167d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
168f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa     * Name under which a DevicePolicy component publishes information
169d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * about itself.  This meta-data must reference an XML resource containing
170d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * a device-admin tag.  XXX TO DO: describe syntax.
171d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
172d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
173d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
174d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private DevicePolicyManager mManager;
175d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private ComponentName mWho;
176d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
177d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
178d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Retrieve the DevicePolicyManager interface for this administrator to work
179d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * with the system.
180d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
181d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public DevicePolicyManager getManager(Context context) {
182d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (mManager != null) {
183d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return mManager;
184d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
185d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mManager = (DevicePolicyManager)context.getSystemService(
186d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Context.DEVICE_POLICY_SERVICE);
187d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        return mManager;
188d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
189d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
190d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
191d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Retrieve the ComponentName describing who this device administrator is, for
192d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * use in {@link DevicePolicyManager} APIs that require the administrator to
193d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * identify itself.
194d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
195d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public ComponentName getWho(Context context) {
196d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (mWho != null) {
197d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return mWho;
198d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
199d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mWho = new ComponentName(context, getClass());
200d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        return mWho;
201d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
202d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
203d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
204d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called after the administrator is first enabled, as a result of
205d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}.  At this point you
206d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * can use {@link DevicePolicyManager} to set your desired policies.
207d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
208d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
209d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
210d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onEnabled(Context context, Intent intent) {
211d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
212d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
213d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
2148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * Called when the user has asked to disable the administrator, as a result of
2158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
2168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * a chance to present a warning message to them.  The message is returned
2178ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * as the result; if null is returned (the default implementation), no
2188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * message will be displayed.
2198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * @param context The running context as per {@link #onReceive}.
2208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
2218ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * @return Return the warning message to display to the user before
2228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     * being disabled; if null is returned, no message is displayed.
2238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn     */
2248ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    public CharSequence onDisableRequested(Context context, Intent intent) {
2258ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        return null;
2268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
2278ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
2288ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    /**
229d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called prior to the administrator being disabled, as a result of
230d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}.  Upon return, you
231d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * can no longer use the protected parts of the {@link DevicePolicyManager}
232d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * API.
233d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
234d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
235d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
236d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onDisabled(Context context, Intent intent) {
237d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
238d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
239d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
240d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called after the user has changed their password, as a result of
241d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * receiving {@link #ACTION_PASSWORD_CHANGED}.  At this point you
242d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * can use {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()
243d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * DevicePolicyManager.getCurrentFailedPasswordAttempts()}
244d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * to retrieve the active password characteristics.
245d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
246d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
247d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
248d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onPasswordChanged(Context context, Intent intent) {
249d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
250d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
251d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
252d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called after the user has failed at entering their current password, as a result of
253d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * receiving {@link #ACTION_PASSWORD_FAILED}.  At this point you
254d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * can use {@link DevicePolicyManager} to retrieve the number of failed
255d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * password attempts.
256d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
257d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
258d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
259d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onPasswordFailed(Context context, Intent intent) {
260d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
261d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
262d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
263d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Called after the user has succeeded at entering their current password,
264d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}.  This will
265d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * only be received the first time they succeed after having previously
266d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * failed.
267d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param context The running context as per {@link #onReceive}.
268d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * @param intent The received intent as per {@link #onReceive}.
269d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
270d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onPasswordSucceeded(Context context, Intent intent) {
271d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
272a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
273a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    /**
274a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * Called periodically when the password is about to expire or has expired.  It will typically
2756b85768058b065cc682757a366abc828c9ca727aJim Miller     * be called at these times: on device boot, once per day before the password expires,
2766b85768058b065cc682757a366abc828c9ca727aJim Miller     * and at the time when the password expires.
277a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
278a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * <p>If the password is not updated by the user, this method will continue to be called
279a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * once per day until the password is changed or the device admin disables password expiration.
280a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
281a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * <p>The admin will typically post a notification requesting the user to change their password
282a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * in response to this call. The actual password expiration time can be obtained by calling
283a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * {@link DevicePolicyManager#getPasswordExpiration(ComponentName) }
284a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
285a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * <p>The admin should be sure to take down any notifications it posted in response to this call
286a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * when it receives {@link DeviceAdminReceiver#onPasswordChanged(Context, Intent) }.
287a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     *
288a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * @param context The running context as per {@link #onReceive}.
289a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     * @param intent The received intent as per {@link #onReceive}.
290a4e28d181942018ba8759989799a28fa88764ce3Jim Miller     */
291a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    public void onPasswordExpiring(Context context, Intent intent) {
292a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
293a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
294d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
295d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Intercept standard device administrator broadcasts.  Implementations
296d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * should not override this method; it is better to implement the
297d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * convenience callbacks for each action.
298d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
299d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    @Override
300d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void onReceive(Context context, Intent intent) {
301d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        String action = intent.getAction();
302d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (ACTION_PASSWORD_CHANGED.equals(action)) {
303d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onPasswordChanged(context, intent);
304d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } else if (ACTION_PASSWORD_FAILED.equals(action)) {
305d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onPasswordFailed(context, intent);
306d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
307d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onPasswordSucceeded(context, intent);
308d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
309d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onEnabled(context, intent);
3108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
3118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            CharSequence res = onDisableRequested(context, intent);
3128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (res != null) {
3138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                Bundle extras = getResultExtras(true);
3148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
3158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
316d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
317d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            onDisabled(context, intent);
318a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        } else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
319a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            onPasswordExpiring(context, intent);
320d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
321d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
322d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn}
323