DevicePolicyManagerService.java revision e83cefcef07f9ac025642c1ffec76b4c7ab39cf2
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
17d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornpackage com.android.server;
18d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
19d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport com.android.common.FastXmlSerializer;
20df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport com.android.internal.widget.LockPatternUtils;
21d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
22d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlPullParser;
23d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlPullParserException;
24d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlSerializer;
25d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.app.Activity;
27d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.app.DeviceAdmin;
28d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.app.DeviceAdminInfo;
29d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.app.DevicePolicyManager;
30d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.app.IDevicePolicyManager;
318ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.content.BroadcastReceiver;
32d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.ComponentName;
33d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Context;
34d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Intent;
35d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.pm.PackageManager;
36d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.pm.ResolveInfo;
37d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.os.Binder;
38df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.IBinder;
39df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.IPowerManager;
40df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.RecoverySystem;
418ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.os.RemoteCallback;
42df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.RemoteException;
43df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.ServiceManager;
44254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackbornimport android.os.SystemClock;
45d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.util.Log;
46d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.util.Xml;
47254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackbornimport android.view.WindowManagerPolicy;
48d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
49d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.File;
50d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.FileInputStream;
51d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.FileOutputStream;
52d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.IOException;
53d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackbornimport java.util.ArrayList;
54d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackbornimport java.util.HashMap;
55d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.util.List;
56d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
57d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn/**
58d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Implementation of the device policy APIs.
59d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn */
60d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornpublic class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
61d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private static final String TAG = "DevicePolicyManagerService";
62d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
63d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private final Context mContext;
64d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
65df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    IPowerManager mIPowerManager;
66df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn
679327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn    int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
68d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    int mActivePasswordLength = 0;
69d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    int mFailedPasswordAttempts = 0;
70d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
71d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    final HashMap<ComponentName, ActiveAdmin> mAdminMap
72d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            = new HashMap<ComponentName, ActiveAdmin>();
73d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    final ArrayList<ActiveAdmin> mAdminList
74d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            = new ArrayList<ActiveAdmin>();
75d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
76d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    static class ActiveAdmin {
778ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        final DeviceAdminInfo info;
788ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
799327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn        int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
808ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        int minimumPasswordLength = 0;
818ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        long maximumTimeToUnlock = 0;
828ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        int maximumFailedPasswordsForWipe = 0;
838ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
84d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        ActiveAdmin(DeviceAdminInfo _info) {
85d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            info = _info;
86d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
87d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
88d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        int getUid() { return info.getActivityInfo().applicationInfo.uid; }
89d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        void writeToXml(XmlSerializer out)
918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throws IllegalArgumentException, IllegalStateException, IOException {
929327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
939327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.startTag(null, "password-quality");
949327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.attribute(null, "value", Integer.toString(passwordQuality));
959327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.endTag(null, "password-quality");
968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (minimumPasswordLength > 0) {
978ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    out.startTag(null, "min-password-length");
988ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    out.attribute(null, "value", Integer.toString(minimumPasswordLength));
998ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    out.endTag(null, "mn-password-length");
1008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
1018ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1029327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (maximumTimeToUnlock != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
1038ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "max-time-to-unlock");
1048ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.attribute(null, "value", Long.toString(maximumTimeToUnlock));
1058ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "max-time-to-unlock");
1068ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1078ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (maximumFailedPasswordsForWipe != 0) {
1088ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "max-failed-password-wipe");
1098ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe));
1108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "max-failed-password-wipe");
1118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
1138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
1148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        void readFromXml(XmlPullParser parser)
1158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throws XmlPullParserException, IOException {
1168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int outerDepth = parser.getDepth();
1178ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int type;
1188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                   && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1218ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    continue;
1228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
1238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                String tag = parser.getName();
1249327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                if ("password-quality".equals(tag)) {
1259327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    passwordQuality = Integer.parseInt(
1268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
1278ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("min-password-length".equals(tag)) {
1288ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    minimumPasswordLength = Integer.parseInt(
1298ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
1308ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("max-time-to-unlock".equals(tag)) {
1318ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    maximumTimeToUnlock = Long.parseLong(
1328ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
1338ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("max-failed-password-wipe".equals(tag)) {
1348ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    maximumFailedPasswordsForWipe = Integer.parseInt(
1358ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
1368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
1378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
139d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
140d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
141d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
142d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Instantiates the service.
143d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
144d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public DevicePolicyManagerService(Context context) {
145d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext = context;
146d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
147d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
148df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    private IPowerManager getIPowerManager() {
149df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        if (mIPowerManager == null) {
150df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            IBinder b = ServiceManager.getService(Context.POWER_SERVICE);
151df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            mIPowerManager = IPowerManager.Stub.asInterface(b);
152df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
153df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        return mIPowerManager;
154df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
155df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn
1568ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who) {
157d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        ActiveAdmin admin = mAdminMap.get(who);
1588ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        if (admin != null
1598ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                && who.getPackageName().equals(admin.info.getActivityInfo().packageName)
1608ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                && who.getClassName().equals(admin.info.getActivityInfo().name)) {
1618ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            return admin;
1628ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
1638ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        return null;
1648ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
1658ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
166254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy)
1678aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            throws SecurityException {
168254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        final int callingUid = Binder.getCallingUid();
169254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        if (who != null) {
170254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            ActiveAdmin admin = mAdminMap.get(who);
171254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (admin == null) {
172254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("No active admin " + who);
173254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
174254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (admin.getUid() != callingUid) {
175254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("Admin " + who + " is not owned by uid "
176254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + Binder.getCallingUid());
177254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
178254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (!admin.info.usesPolicy(reqPolicy)) {
179254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("Admin " + admin.info.getComponent()
180254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + " did not specify uses-policy for: "
181254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + admin.info.getTagForPolicy(reqPolicy));
182d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
183d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return admin;
184254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        } else {
185254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
186254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            for (int i=0; i<N; i++) {
187254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
188254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) {
189254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    return admin;
190254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                }
191254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
192254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            throw new SecurityException("No active admin owned by uid "
193254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    + Binder.getCallingUid() + " for policy #" + reqPolicy);
194d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
1968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
1978aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn    void sendAdminCommandLocked(ActiveAdmin admin, String action) {
198d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        Intent intent = new Intent(action);
1998aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn        intent.setComponent(admin.info.getComponent());
200d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.sendBroadcast(intent);
201d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
202d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
2038aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn    void sendAdminCommandLocked(String action, int reqPolicy) {
204d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        final int N = mAdminList.size();
205d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        if (N > 0) {
206d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for (int i=0; i<N; i++) {
207d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
208d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (admin.info.usesPolicy(reqPolicy)) {
209d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    sendAdminCommandLocked(admin, action);
210d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
2118aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            }
2124141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn        }
2134141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn    }
2144141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn
215d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    void removeActiveAdminLocked(ComponentName adminReceiver) {
216d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver);
217d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        if (admin != null) {
218d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            sendAdminCommandLocked(admin,
219d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    DeviceAdmin.ACTION_DEVICE_ADMIN_DISABLED);
220d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // XXX need to wait for it to complete.
221d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            mAdminList.remove(admin);
222d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            mAdminMap.remove(adminReceiver);
223d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
224d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
225d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
226d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public DeviceAdminInfo findAdmin(ComponentName adminName) {
227d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        Intent resolveIntent = new Intent();
228d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        resolveIntent.setComponent(adminName);
229d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers(
230d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                resolveIntent, PackageManager.GET_META_DATA);
231d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (infos == null || infos.size() <= 0) {
232d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            throw new IllegalArgumentException("Unknown admin: " + adminName);
233d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
234d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
235d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
236d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return new DeviceAdminInfo(mContext, infos.get(0));
237d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (XmlPullParserException e) {
238d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            Log.w(TAG, "Bad device admin requested: " + adminName, e);
239d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return null;
240d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
241d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            Log.w(TAG, "Bad device admin requested: " + adminName, e);
242d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return null;
243d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
244d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
245d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
246d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private static JournaledFile makeJournaledFile() {
247d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        final String base = "/data/system/device_policies.xml";
248d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        return new JournaledFile(new File(base), new File(base + ".tmp"));
249d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
250d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
251d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private void saveSettingsLocked() {
252d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        JournaledFile journal = makeJournaledFile();
253d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        FileOutputStream stream = null;
254d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
255d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream = new FileOutputStream(journal.chooseForWrite(), false);
256d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            XmlSerializer out = new FastXmlSerializer();
257d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.setOutput(stream, "utf-8");
258d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.startDocument(null, true);
259d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
260d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.startTag(null, "policies");
261d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
262d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            final int N = mAdminList.size();
263d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for (int i=0; i<N; i++) {
264d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin ap = mAdminList.get(i);
265d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (ap != null) {
266d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.startTag(null, "admin");
267d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.attribute(null, "name", ap.info.getComponent().flattenToString());
268d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    ap.writeToXml(out);
269d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.endTag(null, "admin");
270d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
271d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
272d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn
273d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.endTag(null, "policies");
274d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
2758ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (mFailedPasswordAttempts != 0) {
2768ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "failed-password-attempts");
2778ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.attribute(null, "value", Integer.toString(mFailedPasswordAttempts));
2788ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "failed-password-attempts");
2798ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
2808ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
281d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.endDocument();
282d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream.close();
283d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            journal.commit();
284d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
285d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
286d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                if (stream != null) {
287d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    stream.close();
288d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
289d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } catch (IOException ex) {
290d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                // Ignore
291d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
292d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            journal.rollback();
293d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
294d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
295d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
296d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private void loadSettingsLocked() {
297d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        JournaledFile journal = makeJournaledFile();
298d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        FileInputStream stream = null;
299d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        File file = journal.chooseForRead();
300d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
301d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream = new FileInputStream(file);
302d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            XmlPullParser parser = Xml.newPullParser();
303d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            parser.setInput(stream, null);
304d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
3058ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int type;
3068ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
3078ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    && type != XmlPullParser.START_TAG) {
308d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
309d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            String tag = parser.getName();
3108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (!"policies".equals(tag)) {
3118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throw new XmlPullParserException(
3128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                        "Settings do not start with policies tag: found " + tag);
3138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
3148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            type = parser.next();
3158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int outerDepth = parser.getDepth();
3168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
3178ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                   && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    continue;
3208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
3218ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                tag = parser.getName();
3228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if ("admin".equals(tag)) {
323e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    String name = parser.getAttributeValue(null, "name");
324e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    try {
325e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        DeviceAdminInfo dai = findAdmin(
326e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                                ComponentName.unflattenFromString(name));
327e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        if (dai != null) {
328e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            ActiveAdmin ap = new ActiveAdmin(dai);
329e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            ap.readFromXml(parser);
330e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            mAdminMap.put(ap.info.getComponent(), ap);
331e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            mAdminList.add(ap);
332e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        }
333e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    } catch (RuntimeException e) {
334e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        Log.w(TAG, "Failed loading admin " + name, e);
335d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    }
3368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("failed-password-attempts".equals(tag)) {
3378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    mFailedPasswordAttempts = Integer.parseInt(
3388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
3398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
340d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
341d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (NullPointerException e) {
342d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            Log.w(TAG, "failed parsing " + file + " " + e);
343d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (NumberFormatException e) {
344d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            Log.w(TAG, "failed parsing " + file + " " + e);
345d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (XmlPullParserException e) {
346d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            Log.w(TAG, "failed parsing " + file + " " + e);
347d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
348d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            Log.w(TAG, "failed parsing " + file + " " + e);
349d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IndexOutOfBoundsException e) {
350d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            Log.w(TAG, "failed parsing " + file + " " + e);
351d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
352d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
353d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (stream != null) {
354d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                stream.close();
355d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
356d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
357d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // Ignore
358d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
359d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
360254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        long timeMs = getMaximumTimeToLock(null);
361df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        if (timeMs <= 0) {
362df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            timeMs = Integer.MAX_VALUE;
363df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
364df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        try {
365df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
366df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        } catch (RemoteException e) {
367df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            Log.w(TAG, "Failure talking with power manager", e);
368df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
369d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
370d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
371d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void systemReady() {
372d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
373d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            loadSettingsLocked();
374d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
375d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
376d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
377d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void setActiveAdmin(ComponentName adminReceiver) {
378d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
379d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
380d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
381d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        DeviceAdminInfo info = findAdmin(adminReceiver);
382d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (info == null) {
383d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            throw new IllegalArgumentException("Bad admin: " + adminReceiver);
384d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
385d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
386d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
387d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
388d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (getActiveAdminUncheckedLocked(adminReceiver) != null) {
389d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    throw new IllegalArgumentException("Admin is already added");
390d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
391d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = new ActiveAdmin(info);
392d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                mAdminMap.put(adminReceiver, admin);
393d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                mAdminList.add(admin);
394d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                saveSettingsLocked();
395d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                sendAdminCommandLocked(admin,
396d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                        DeviceAdmin.ACTION_DEVICE_ADMIN_ENABLED);
397d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
398d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
399d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
400d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
401d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
402d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
403d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    public boolean isAdminActive(ComponentName adminReceiver) {
404d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        synchronized (this) {
405d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return getActiveAdminUncheckedLocked(adminReceiver) != null;
406d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        }
407d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    }
408d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn
409d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    public List<ComponentName> getActiveAdmins() {
410d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
411d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            final int N = mAdminList.size();
412d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (N <= 0) {
413d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                return null;
414d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
415d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            ArrayList<ComponentName> res = new ArrayList<ComponentName>(N);
416d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for (int i=0; i<N; i++) {
417d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                res.add(mAdminList.get(i).info.getComponent());
418d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
419d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return res;
420d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
421d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
422d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
423d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void removeActiveAdmin(ComponentName adminReceiver) {
424d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
425d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver);
426d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (admin == null) {
427d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                return;
428d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
429d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (admin.getUid() != Binder.getCallingUid()) {
430d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                mContext.enforceCallingOrSelfPermission(
431d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                        android.Manifest.permission.BIND_DEVICE_ADMIN, null);
432d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
433d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
434d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
435d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                removeActiveAdminLocked(adminReceiver);
436d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
437d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
438d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
439d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
440d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
441d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
4429327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn    public void setPasswordQuality(ComponentName who, int mode) {
443d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
444d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
445d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
446d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
4478aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
4488aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
4499327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (ap.passwordQuality != mode) {
4509327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                ap.passwordQuality = mode;
451d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                saveSettingsLocked();
452d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
453d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
454d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
455d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
4569327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn    public int getPasswordQuality(ComponentName who) {
457d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
4589327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
459254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
460254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
461254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
4629327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                return admin != null ? admin.passwordQuality : mode;
463254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
464254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
465254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
466d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
467d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
4689327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                if (mode < admin.passwordQuality) {
4699327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    mode = admin.passwordQuality;
470d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
471d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
472d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return mode;
473d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
474d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
475d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
476254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    public void setPasswordMinimumLength(ComponentName who, int length) {
477d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
478d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
479d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
480d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
4818aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
4828aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
483d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (ap.minimumPasswordLength != length) {
484d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                ap.minimumPasswordLength = length;
485d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                saveSettingsLocked();
486d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
487d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
488d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
489d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
490254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    public int getPasswordMinimumLength(ComponentName who) {
491d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
492d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            int length = 0;
493254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
494254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
495254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
496254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.minimumPasswordLength : length;
497254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
498254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
499254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
500d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
501d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
502d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (length < admin.minimumPasswordLength) {
503d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    length = admin.minimumPasswordLength;
504d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
505d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
506d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return length;
507d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
508d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
509d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
510df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    public boolean isActivePasswordSufficient() {
511d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
512d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
513d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
5148aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
5158aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
5169327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            return mActivePasswordQuality >= getPasswordQuality(null)
517254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    && mActivePasswordLength >= getPasswordMinimumLength(null);
518d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
519d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
520d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
521d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public int getCurrentFailedPasswordAttempts() {
522d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
523d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
524d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
5258aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
5268aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
527d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return mFailedPasswordAttempts;
528d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
529d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
530d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
5318ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    public void setMaximumFailedPasswordsForWipe(ComponentName who, int num) {
5328ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
5338ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            // This API can only be called by an active device admin,
5348ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            // so try to retrieve it to check that the caller is one.
5358ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            getActiveAdminForCallerLocked(who,
5368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
5378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
5388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
5398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (ap.maximumFailedPasswordsForWipe != num) {
5408ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                ap.maximumFailedPasswordsForWipe = num;
5418ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                saveSettingsLocked();
5428ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
5438ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
5448ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
5458ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
546254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    public int getMaximumFailedPasswordsForWipe(ComponentName who) {
5478ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
548d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            int count = 0;
549254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
550254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
551254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
552254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.maximumFailedPasswordsForWipe : count;
553254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
554254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
555254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
556d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
557d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
558d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (count == 0) {
559d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    count = admin.maximumFailedPasswordsForWipe;
560d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                } else if (admin.maximumFailedPasswordsForWipe != 0
561d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                        && count > admin.maximumFailedPasswordsForWipe) {
562d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    count = admin.maximumFailedPasswordsForWipe;
563d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
564d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
565d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return count;
5668ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
5678ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
5688ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
569df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    public boolean resetPassword(String password) {
5709327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn        int quality;
571df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        synchronized (this) {
572df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // This API can only be called by an active device admin,
573df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // so try to retrieve it to check that the caller is one.
5748aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
5758aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_RESET_PASSWORD);
5769327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            quality = getPasswordQuality(null);
5779327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
5789327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                int adjQuality = LockPatternUtils.adjustPasswordMode(password, quality);
5799327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                if (adjQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
5809327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    Log.w(TAG, "resetPassword: password does not meet quality " + quality);
5819327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    return false;
5829327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                }
5839327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                quality = adjQuality;
5849327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            }
5859327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            int length = getPasswordMinimumLength(null);
5869327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (password.length() < length) {
5879327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                Log.w(TAG, "resetPassword: password does not meet length " + length);
588df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                return false;
589df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            }
590df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
591df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn
592df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        // Don't do this with the lock held, because it is going to call
593df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        // back in to the service.
594df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        long ident = Binder.clearCallingIdentity();
595df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        try {
596df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            LockPatternUtils utils = new LockPatternUtils(mContext);
5979327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            utils.saveLockPassword(password, quality);
598df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        } finally {
599df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            Binder.restoreCallingIdentity(ident);
600df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
601df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn
602df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        return true;
603df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
604df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn
605d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void setMaximumTimeToLock(ComponentName who, long timeMs) {
606d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
607d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
608d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
609d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
6108aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
6118aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_UNLOCK);
612d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (ap.maximumTimeToUnlock != timeMs) {
613d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                ap.maximumTimeToUnlock = timeMs;
614df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn
615df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                long ident = Binder.clearCallingIdentity();
616df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                try {
617df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    saveSettingsLocked();
618254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
619254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    timeMs = getMaximumTimeToLock(null);
620df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    if (timeMs <= 0) {
621df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                        timeMs = Integer.MAX_VALUE;
622df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    }
623254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
624df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    try {
625df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                        getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
626df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    } catch (RemoteException e) {
627df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                        Log.w(TAG, "Failure talking with power manager", e);
628df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    }
629df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                } finally {
630df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    Binder.restoreCallingIdentity(ident);
631df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                }
632d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
633d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
634d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
635d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
636254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    public long getMaximumTimeToLock(ComponentName who) {
637d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
638d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            long time = 0;
639254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
640254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
641254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
642254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.maximumTimeToUnlock : time;
643254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
644254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn
645254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
646d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
647d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
648d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (time == 0) {
649d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    time = admin.maximumTimeToUnlock;
650d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                } else if (admin.maximumTimeToUnlock != 0
651d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                        && time > admin.maximumTimeToUnlock) {
652d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    time = admin.maximumTimeToUnlock;
653d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
654d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
655d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return time;
656d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
657d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
658d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
659df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    public void lockNow() {
660df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        synchronized (this) {
661df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // This API can only be called by an active device admin,
662df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // so try to retrieve it to check that the caller is one.
6638aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
6648aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
665254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            long ident = Binder.clearCallingIdentity();
666254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            try {
667254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                mIPowerManager.goToSleepWithReason(SystemClock.uptimeMillis(),
668254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN);
669254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            } catch (RemoteException e) {
670254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            } finally {
671254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                Binder.restoreCallingIdentity(ident);
672254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
673df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
674df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
675df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn
6768ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    void wipeDataLocked(int flags) {
6778ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        try {
6788ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            RecoverySystem.rebootWipeUserData(mContext);
6798ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        } catch (IOException e) {
6808ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            Log.w(TAG, "Failed requesting data wipe", e);
6818ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
6828ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
6838ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
684d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void wipeData(int flags) {
685d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
686d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
687d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
6888aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
6898aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
6908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            long ident = Binder.clearCallingIdentity();
6918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            try {
6928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                wipeDataLocked(flags);
6938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            } finally {
6948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                Binder.restoreCallingIdentity(ident);
6958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
696df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
6978ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
6988ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
6998ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    public void getRemoveWarning(ComponentName comp, final RemoteCallback result) {
7008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        mContext.enforceCallingOrSelfPermission(
7018ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
7028ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn
7038ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
7048ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            ActiveAdmin admin = getActiveAdminUncheckedLocked(comp);
7058ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (admin == null) {
7068ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                try {
7078ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    result.sendResult(null);
7088ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } catch (RemoteException e) {
7098ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
7108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                return;
7118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
7128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            Intent intent = new Intent(DeviceAdmin.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED);
7138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            intent.setComponent(admin.info.getComponent());
7148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
7158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                @Override
7168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                public void onReceive(Context context, Intent intent) {
7178ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    try {
7188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                        result.sendResult(getResultExtras(false));
7198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    } catch (RemoteException e) {
7208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    }
7218ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
7228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }, null, Activity.RESULT_OK, null, null);
723d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
724d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
725d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
7269327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn    public void setActivePasswordState(int quality, int length) {
727d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
728d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
729d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
730d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
7319327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (mActivePasswordQuality != quality || mActivePasswordLength != length
732d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    || mFailedPasswordAttempts != 0) {
733d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                long ident = Binder.clearCallingIdentity();
734d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                try {
7359327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    mActivePasswordQuality = quality;
736d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    mActivePasswordLength = length;
7378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    if (mFailedPasswordAttempts != 0) {
7388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                        mFailedPasswordAttempts = 0;
7398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                        saveSettingsLocked();
7408ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    }
7418aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    sendAdminCommandLocked(DeviceAdmin.ACTION_PASSWORD_CHANGED,
7428aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                            DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
743d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                } finally {
744d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    Binder.restoreCallingIdentity(ident);
745d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
746d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
747d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
748d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
749d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
750d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void reportFailedPasswordAttempt() {
751d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
752d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
753d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
754d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
755d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
756d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
757d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                mFailedPasswordAttempts++;
7588ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                saveSettingsLocked();
759254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                int max = getMaximumFailedPasswordsForWipe(null);
7608ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (max > 0 && mFailedPasswordAttempts >= max) {
7618ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    wipeDataLocked(0);
7628ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
7638aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                sendAdminCommandLocked(DeviceAdmin.ACTION_PASSWORD_FAILED,
7648aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                        DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
765d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
766d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
767d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
768d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
769d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
770d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
771d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void reportSuccessfulPasswordAttempt() {
772d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
773d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
774d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
775d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
776d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (mFailedPasswordAttempts != 0) {
777d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                long ident = Binder.clearCallingIdentity();
778d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                try {
779d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    mFailedPasswordAttempts = 0;
7808ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    saveSettingsLocked();
7818aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    sendAdminCommandLocked(DeviceAdmin.ACTION_PASSWORD_SUCCEEDED,
7828aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                            DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
783d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                } finally {
784d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    Binder.restoreCallingIdentity(ident);
785d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
786d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
787d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
788d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
789d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn}
790