DevicePolicyManagerService.java revision c857740f242169f2ca7fd42f0d1268661b399ad6
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
1921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport com.android.internal.content.PackageMonitor;
202269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.FastXmlSerializer;
211afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackbornimport com.android.internal.util.JournaledFile;
222269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.XmlUtils;
23df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport com.android.internal.widget.LockPatternUtils;
24d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
25d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlPullParser;
26d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlPullParserException;
27d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlSerializer;
28d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
298ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.app.Activity;
3087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DeviceAdminInfo;
3187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DeviceAdminReceiver;
3287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DevicePolicyManager;
3387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.IDevicePolicyManager;
348ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.content.BroadcastReceiver;
35d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.ComponentName;
36d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Context;
37d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Intent;
38d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.pm.PackageManager;
39d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.pm.ResolveInfo;
4021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException;
41d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.os.Binder;
42df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.IBinder;
43df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.IPowerManager;
44df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.RecoverySystem;
458ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.os.RemoteCallback;
46df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.RemoteException;
47df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.ServiceManager;
48254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackbornimport android.os.SystemClock;
4985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackbornimport android.util.Slog;
5087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.util.PrintWriterPrinter;
5187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.util.Printer;
52d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.util.Xml;
53254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackbornimport android.view.WindowManagerPolicy;
54d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
55d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.File;
5687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport java.io.FileDescriptor;
57d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.FileInputStream;
58d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.FileOutputStream;
59d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.IOException;
6087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport java.io.PrintWriter;
61d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackbornimport java.util.ArrayList;
62d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackbornimport java.util.HashMap;
63d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.util.List;
64d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
65d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn/**
66d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Implementation of the device policy APIs.
67d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn */
68d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornpublic class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
6921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    static final String TAG = "DevicePolicyManagerService";
703255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
7121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    final Context mContext;
7221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    final MyPackageMonitor mMonitor;
73d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
74df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    IPowerManager mIPowerManager;
753255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
769327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn    int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
77d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    int mActivePasswordLength = 0;
78a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    int mActivePasswordUpperCase = 0;
79a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    int mActivePasswordLowerCase = 0;
80a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    int mActivePasswordLetters = 0;
81a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    int mActivePasswordNumeric = 0;
82a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    int mActivePasswordSymbols = 0;
83c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev    int mActivePasswordNonLetter = 0;
84d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    int mFailedPasswordAttempts = 0;
853255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
8687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    int mPasswordOwner = -1;
873255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
88d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    final HashMap<ComponentName, ActiveAdmin> mAdminMap
89d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            = new HashMap<ComponentName, ActiveAdmin>();
90d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    final ArrayList<ActiveAdmin> mAdminList
91d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            = new ArrayList<ActiveAdmin>();
923255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
93d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    static class ActiveAdmin {
948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        final DeviceAdminInfo info;
953255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
969327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn        int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
978ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        int minimumPasswordLength = 0;
983255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        int passwordHistoryLength = 0;
99a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        int minimumPasswordUpperCase = 0;
100a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        int minimumPasswordLowerCase = 0;
101a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        int minimumPasswordLetters = 1;
102a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        int minimumPasswordNumeric = 1;
103a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        int minimumPasswordSymbols = 1;
104c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        int minimumPasswordNonLetter = 0;
1058ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        long maximumTimeToUnlock = 0;
1068ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        int maximumFailedPasswordsForWipe = 0;
1073255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
108d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        ActiveAdmin(DeviceAdminInfo _info) {
109d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            info = _info;
110d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1113255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
112d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        int getUid() { return info.getActivityInfo().applicationInfo.uid; }
1133255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        void writeToXml(XmlSerializer out)
1158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throws IllegalArgumentException, IllegalStateException, IOException {
11621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            out.startTag(null, "policies");
11721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            info.writePoliciesToXml(out);
11821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            out.endTag(null, "policies");
1199327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
1209327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.startTag(null, "password-quality");
1219327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.attribute(null, "value", Integer.toString(passwordQuality));
1229327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.endTag(null, "password-quality");
1238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (minimumPasswordLength > 0) {
1248ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    out.startTag(null, "min-password-length");
1258ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    out.attribute(null, "value", Integer.toString(minimumPasswordLength));
1263255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    out.endTag(null, "min-password-length");
1273255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                }
1283255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                if(passwordHistoryLength > 0) {
1293255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    out.startTag(null, "password-history-length");
1303255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(passwordHistoryLength));
1313255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    out.endTag(null, "password-history-length");
1328ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
133a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (minimumPasswordUpperCase > 0) {
134a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-uppercase");
135a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase));
136a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-uppercase");
137a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
138a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (minimumPasswordLowerCase > 0) {
139a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-lowercase");
140a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase));
141a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-lowercase");
142a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
143a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (minimumPasswordLetters > 0) {
144a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-letters");
145a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordLetters));
146a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-letters");
147a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
148a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (minimumPasswordNumeric > 0) {
149a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-numeric");
150a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordNumeric));
151a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-numeric");
152a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
153a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (minimumPasswordSymbols > 0) {
154a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-symbols");
155a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordSymbols));
156a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-symbols");
157a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
158c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                if (minimumPasswordNonLetter > 0) {
159c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    out.startTag(null, "min-password-nonletter");
160c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter));
161c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    out.endTag(null, "min-password-nonletter");
162c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                }
1638ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1649327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (maximumTimeToUnlock != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
1658ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "max-time-to-unlock");
1668ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.attribute(null, "value", Long.toString(maximumTimeToUnlock));
1678ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "max-time-to-unlock");
1688ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1698ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (maximumFailedPasswordsForWipe != 0) {
1708ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "max-failed-password-wipe");
1718ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe));
1728ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "max-failed-password-wipe");
1738ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1748ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
1753255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1768ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        void readFromXml(XmlPullParser parser)
1778ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throws XmlPullParserException, IOException {
1788ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int outerDepth = parser.getDepth();
1798ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int type;
1808ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1818ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                   && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1828ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1838ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    continue;
1848ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
1858ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                String tag = parser.getName();
18621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if ("policies".equals(tag)) {
18721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    info.readPoliciesFromXml(parser);
18821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                } else if ("password-quality".equals(tag)) {
1899327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    passwordQuality = Integer.parseInt(
1908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
1918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("min-password-length".equals(tag)) {
1928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    minimumPasswordLength = Integer.parseInt(
1938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
1943255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                } else if ("password-history-length".equals(tag)) {
1953255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    passwordHistoryLength = Integer.parseInt(
1963255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
197a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-uppercase".equals(tag)) {
198a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordUpperCase = Integer.parseInt(
199a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
200a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-lowercase".equals(tag)) {
201a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordLowerCase = Integer.parseInt(
202a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
203a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-letters".equals(tag)) {
204a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordLetters = Integer.parseInt(
205a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
206a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-numeric".equals(tag)) {
207a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordNumeric = Integer.parseInt(
208a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
209a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-symbols".equals(tag)) {
210a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordSymbols = Integer.parseInt(
211a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
212c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                } else if ("min-password-nonletter".equals(tag)) {
213c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    minimumPasswordNonLetter = Integer.parseInt(
214c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
2158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("max-time-to-unlock".equals(tag)) {
2168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    maximumTimeToUnlock = Long.parseLong(
2178ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
2188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("max-failed-password-wipe".equals(tag)) {
2198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    maximumFailedPasswordsForWipe = Integer.parseInt(
2208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
22121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                } else {
22285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    Slog.w(TAG, "Unknown admin tag: " + tag);
22321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
22421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                XmlUtils.skipCurrentTag(parser);
22521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
22621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
2273255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
22887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        void dump(String prefix, PrintWriter pw) {
22987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print(prefix); pw.print("uid="); pw.println(getUid());
23087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print(prefix); pw.println("policies:");
23187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            ArrayList<DeviceAdminInfo.PolicyInfo> pols = info.getUsedPolicies();
23287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            if (pols != null) {
23387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                for (int i=0; i<pols.size(); i++) {
23487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.print(prefix); pw.print("  "); pw.println(pols.get(i).tag);
23587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                }
23687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
23785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            pw.print(prefix); pw.print("passwordQuality=0x");
2383255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    pw.println(Integer.toHexString(passwordQuality));
2393255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordLength=");
24087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.println(minimumPasswordLength);
2413255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            pw.print(prefix); pw.print("passwordHistoryLength=");
2423255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    pw.println(passwordHistoryLength);
243a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordUpperCase=");
244a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordUpperCase);
245a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordLowerCase=");
246a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordLowerCase);
247a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordLetters=");
248a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordLetters);
249a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordNumeric=");
250a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordNumeric);
251a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordSymbols=");
252a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordSymbols);
253c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordNonLetter=");
254c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    pw.println(minimumPasswordNonLetter);
25587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print(prefix); pw.print("maximumTimeToUnlock=");
25687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.println(maximumTimeToUnlock);
25787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print(prefix); pw.print("maximumFailedPasswordsForWipe=");
25887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.println(maximumFailedPasswordsForWipe);
25987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
26021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
2613255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
26221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    class MyPackageMonitor extends PackageMonitor {
26321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public void onSomePackagesChanged() {
26421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            synchronized (DevicePolicyManagerService.this) {
26587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                boolean removed = false;
26621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                for (int i=mAdminList.size()-1; i>=0; i--) {
26721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    ActiveAdmin aa = mAdminList.get(i);
2683255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    int change = isPackageDisappearing(aa.info.getPackageName());
26921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    if (change == PACKAGE_PERMANENT_CHANGE
27021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            || change == PACKAGE_TEMPORARY_CHANGE) {
27185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                        Slog.w(TAG, "Admin unexpectedly uninstalled: "
27221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                + aa.info.getComponent());
27387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                        removed = true;
27421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        mAdminList.remove(i);
27521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    } else if (isPackageModified(aa.info.getPackageName())) {
27621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        try {
27721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            mContext.getPackageManager().getReceiverInfo(
27821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    aa.info.getComponent(), 0);
27921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        } catch (NameNotFoundException e) {
28085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            Slog.w(TAG, "Admin package change removed component: "
28121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    + aa.info.getComponent());
28287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                            removed = true;
28321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            mAdminList.remove(i);
28421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        }
28521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    }
2868ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
28787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                if (removed) {
28887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    validatePasswordOwnerLocked();
28987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                }
2908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
2918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
292d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
2933255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
294d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
295d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Instantiates the service.
296d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
297d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public DevicePolicyManagerService(Context context) {
298d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext = context;
29921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        mMonitor = new MyPackageMonitor();
30021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        mMonitor.register(context, true);
301d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
302d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
303df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    private IPowerManager getIPowerManager() {
304df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        if (mIPowerManager == null) {
305df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            IBinder b = ServiceManager.getService(Context.POWER_SERVICE);
306df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            mIPowerManager = IPowerManager.Stub.asInterface(b);
307df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
308df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        return mIPowerManager;
309df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
3103255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
3118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who) {
312d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        ActiveAdmin admin = mAdminMap.get(who);
3138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        if (admin != null
3148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                && who.getPackageName().equals(admin.info.getActivityInfo().packageName)
3158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                && who.getClassName().equals(admin.info.getActivityInfo().name)) {
3168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            return admin;
3178ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
3188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        return null;
3198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
3203255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
321254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy)
3228aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            throws SecurityException {
323254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        final int callingUid = Binder.getCallingUid();
324254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        if (who != null) {
325254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            ActiveAdmin admin = mAdminMap.get(who);
326254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (admin == null) {
327254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("No active admin " + who);
328254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
329254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (admin.getUid() != callingUid) {
330254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("Admin " + who + " is not owned by uid "
331254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + Binder.getCallingUid());
332254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
333254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (!admin.info.usesPolicy(reqPolicy)) {
334254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("Admin " + admin.info.getComponent()
335254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + " did not specify uses-policy for: "
336254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + admin.info.getTagForPolicy(reqPolicy));
337d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
338d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return admin;
339254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        } else {
340254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
341254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            for (int i=0; i<N; i++) {
342254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
343254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) {
344254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    return admin;
345254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                }
346254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
347254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            throw new SecurityException("No active admin owned by uid "
348254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    + Binder.getCallingUid() + " for policy #" + reqPolicy);
349d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
3508ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
3513255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
3528aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn    void sendAdminCommandLocked(ActiveAdmin admin, String action) {
353d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        Intent intent = new Intent(action);
3548aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn        intent.setComponent(admin.info.getComponent());
355d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.sendBroadcast(intent);
356d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
3573255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
3588aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn    void sendAdminCommandLocked(String action, int reqPolicy) {
359d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        final int N = mAdminList.size();
360d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        if (N > 0) {
361d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for (int i=0; i<N; i++) {
362d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
363d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (admin.info.usesPolicy(reqPolicy)) {
364d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    sendAdminCommandLocked(admin, action);
365d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
3668aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            }
3674141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn        }
3684141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn    }
3693255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
370d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    void removeActiveAdminLocked(ComponentName adminReceiver) {
371d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver);
372d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        if (admin != null) {
373d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            sendAdminCommandLocked(admin,
374ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn                    DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED);
375d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // XXX need to wait for it to complete.
376d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            mAdminList.remove(admin);
377d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            mAdminMap.remove(adminReceiver);
37887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            validatePasswordOwnerLocked();
379d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
380d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
3813255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
382d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public DeviceAdminInfo findAdmin(ComponentName adminName) {
383d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        Intent resolveIntent = new Intent();
384d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        resolveIntent.setComponent(adminName);
385d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers(
386d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                resolveIntent, PackageManager.GET_META_DATA);
387d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (infos == null || infos.size() <= 0) {
388d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            throw new IllegalArgumentException("Unknown admin: " + adminName);
389d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
3903255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
391d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
392d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return new DeviceAdminInfo(mContext, infos.get(0));
393d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (XmlPullParserException e) {
39485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "Bad device admin requested: " + adminName, e);
395d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return null;
396d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
39785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "Bad device admin requested: " + adminName, e);
398d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return null;
399d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
400d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
4013255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
402d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private static JournaledFile makeJournaledFile() {
403d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        final String base = "/data/system/device_policies.xml";
404d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        return new JournaledFile(new File(base), new File(base + ".tmp"));
405d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
406d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
407d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private void saveSettingsLocked() {
408d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        JournaledFile journal = makeJournaledFile();
409d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        FileOutputStream stream = null;
410d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
411d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream = new FileOutputStream(journal.chooseForWrite(), false);
412d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            XmlSerializer out = new FastXmlSerializer();
413d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.setOutput(stream, "utf-8");
414d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.startDocument(null, true);
415d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
416d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.startTag(null, "policies");
4173255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
418d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            final int N = mAdminList.size();
419d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for (int i=0; i<N; i++) {
420d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin ap = mAdminList.get(i);
421d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (ap != null) {
422d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.startTag(null, "admin");
423d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.attribute(null, "name", ap.info.getComponent().flattenToString());
424d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    ap.writeToXml(out);
425d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.endTag(null, "admin");
426d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
427d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
4283255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
42987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            if (mPasswordOwner >= 0) {
43087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                out.startTag(null, "password-owner");
43187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                out.attribute(null, "value", Integer.toString(mPasswordOwner));
43287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                out.endTag(null, "password-owner");
43387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
4343255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
4358ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (mFailedPasswordAttempts != 0) {
4368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "failed-password-attempts");
4378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.attribute(null, "value", Integer.toString(mFailedPasswordAttempts));
4388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "failed-password-attempts");
4398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
4403255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
441a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (mActivePasswordQuality != 0 || mActivePasswordLength != 0
442a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    || mActivePasswordUpperCase != 0 || mActivePasswordLowerCase != 0
443a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    || mActivePasswordLetters != 0 || mActivePasswordNumeric != 0
444c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    || mActivePasswordSymbols != 0 || mActivePasswordNonLetter != 0) {
44585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                out.startTag(null, "active-password");
44685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                out.attribute(null, "quality", Integer.toString(mActivePasswordQuality));
44785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                out.attribute(null, "length", Integer.toString(mActivePasswordLength));
448a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                out.attribute(null, "uppercase", Integer.toString(mActivePasswordUpperCase));
449a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                out.attribute(null, "lowercase", Integer.toString(mActivePasswordLowerCase));
450a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                out.attribute(null, "letters", Integer.toString(mActivePasswordLetters));
451a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                out.attribute(null, "numeric", Integer
452a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        .toString(mActivePasswordNumeric));
453a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                out.attribute(null, "symbols", Integer.toString(mActivePasswordSymbols));
454c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                out.attribute(null, "nonletter", Integer.toString(mActivePasswordNonLetter));
45585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                out.endTag(null, "active-password");
45685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            }
4573255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
45885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            out.endTag(null, "policies");
45985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn
460d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.endDocument();
461d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream.close();
462d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            journal.commit();
463284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller            sendChangedNotification();
464d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
465d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
466d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                if (stream != null) {
467d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    stream.close();
468d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
469d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } catch (IOException ex) {
470d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                // Ignore
471d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
472d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            journal.rollback();
473d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
474d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
475d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
476284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller    private void sendChangedNotification() {
477284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller        Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
478284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller        intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
479284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller        mContext.sendBroadcast(intent);
480284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller    }
481284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller
482d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    private void loadSettingsLocked() {
483d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        JournaledFile journal = makeJournaledFile();
484d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        FileInputStream stream = null;
485d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        File file = journal.chooseForRead();
486d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
487d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream = new FileInputStream(file);
488d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            XmlPullParser parser = Xml.newPullParser();
489d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            parser.setInput(stream, null);
490d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
4918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int type;
4928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
4938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    && type != XmlPullParser.START_TAG) {
494d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
495d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            String tag = parser.getName();
4968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (!"policies".equals(tag)) {
4978ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throw new XmlPullParserException(
4988ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                        "Settings do not start with policies tag: found " + tag);
4998ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
5008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            type = parser.next();
5018ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int outerDepth = parser.getDepth();
5028ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
5038ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                   && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5048ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5058ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    continue;
5068ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
5078ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                tag = parser.getName();
5088ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if ("admin".equals(tag)) {
509e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    String name = parser.getAttributeValue(null, "name");
510e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    try {
511e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        DeviceAdminInfo dai = findAdmin(
512e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                                ComponentName.unflattenFromString(name));
513e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        if (dai != null) {
514e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            ActiveAdmin ap = new ActiveAdmin(dai);
515e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            ap.readFromXml(parser);
516e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            mAdminMap.put(ap.info.getComponent(), ap);
517e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            mAdminList.add(ap);
518e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        }
519e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    } catch (RuntimeException e) {
52085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                        Slog.w(TAG, "Failed loading admin " + name, e);
521d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    }
5228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("failed-password-attempts".equals(tag)) {
5238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    mFailedPasswordAttempts = Integer.parseInt(
5248ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
52521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    XmlUtils.skipCurrentTag(parser);
52687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                } else if ("password-owner".equals(tag)) {
52787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    mPasswordOwner = Integer.parseInt(
52887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                            parser.getAttributeValue(null, "value"));
52987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    XmlUtils.skipCurrentTag(parser);
53085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                } else if ("active-password".equals(tag)) {
53185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    mActivePasswordQuality = Integer.parseInt(
53285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            parser.getAttributeValue(null, "quality"));
53385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    mActivePasswordLength = Integer.parseInt(
53485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            parser.getAttributeValue(null, "length"));
535a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordUpperCase = Integer.parseInt(
536a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "uppercase"));
537a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordLowerCase = Integer.parseInt(
538a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "lowercase"));
539a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordLetters = Integer.parseInt(
540a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "letters"));
541a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordNumeric = Integer.parseInt(
542a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "numeric"));
543a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordSymbols = Integer.parseInt(
544a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "symbols"));
545c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    mActivePasswordNonLetter = Integer.parseInt(
546c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                            parser.getAttributeValue(null, "nonletter"));
54785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    XmlUtils.skipCurrentTag(parser);
54821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                } else {
54985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    Slog.w(TAG, "Unknown tag: " + tag);
55021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    XmlUtils.skipCurrentTag(parser);
5518ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
552d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
553d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (NullPointerException e) {
55485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
555d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (NumberFormatException e) {
55685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
557d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (XmlPullParserException e) {
55885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
559d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
56085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
561d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IndexOutOfBoundsException e) {
56285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
563d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
564d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
565d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (stream != null) {
566d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                stream.close();
567d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
568d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
569d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // Ignore
570d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
571d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
57285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        // Validate that what we stored for the password quality matches
57385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        // sufficiently what is currently set.  Note that this is only
57485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        // a sanity check in case the two get out of sync; this should
57585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        // never normally happen.
57685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        LockPatternUtils utils = new LockPatternUtils(mContext);
57785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        if (utils.getActivePasswordQuality() < mActivePasswordQuality) {
57885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "Active password quality 0x"
57985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    + Integer.toHexString(mActivePasswordQuality)
58085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    + " does not match actual quality 0x"
58185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    + Integer.toHexString(utils.getActivePasswordQuality()));
58285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
58385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            mActivePasswordLength = 0;
584a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            mActivePasswordUpperCase = 0;
585a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            mActivePasswordLowerCase = 0;
586a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            mActivePasswordLetters = 0;
587a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            mActivePasswordNumeric = 0;
588a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            mActivePasswordSymbols = 0;
589c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            mActivePasswordNonLetter = 0;
59085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        }
5913255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
59287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        validatePasswordOwnerLocked();
5933255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
594254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        long timeMs = getMaximumTimeToLock(null);
595df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        if (timeMs <= 0) {
596df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            timeMs = Integer.MAX_VALUE;
597df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
598df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        try {
599df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
600df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        } catch (RemoteException e) {
60185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "Failure talking with power manager", e);
602df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
603d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
604d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
60585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn    static void validateQualityConstant(int quality) {
60685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        switch (quality) {
60785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
60885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
60985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
61085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
61185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
612a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
61385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                return;
61485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        }
61585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        throw new IllegalArgumentException("Invalid quality constant: 0x"
61685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                + Integer.toHexString(quality));
61785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn    }
6183255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
61987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    void validatePasswordOwnerLocked() {
62087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        if (mPasswordOwner >= 0) {
62187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            boolean haveOwner = false;
62287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            for (int i=mAdminList.size()-1; i>=0; i--) {
62387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                if (mAdminList.get(i).getUid() == mPasswordOwner) {
62487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    haveOwner = true;
62587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    break;
62687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                }
62787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
62887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            if (!haveOwner) {
62985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                Slog.w(TAG, "Previous password owner " + mPasswordOwner
63087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                        + " no longer active; disabling");
63187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                mPasswordOwner = -1;
63287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
63387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
63487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    }
6353255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
636d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void systemReady() {
637d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
638d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            loadSettingsLocked();
639d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
640d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
6413255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
642d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void setActiveAdmin(ComponentName adminReceiver) {
643d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
644d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
6453255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
646d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        DeviceAdminInfo info = findAdmin(adminReceiver);
647d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (info == null) {
648d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            throw new IllegalArgumentException("Bad admin: " + adminReceiver);
649d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
650d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
651d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
652d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
653d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (getActiveAdminUncheckedLocked(adminReceiver) != null) {
654d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    throw new IllegalArgumentException("Admin is already added");
655d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
656d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = new ActiveAdmin(info);
657d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                mAdminMap.put(adminReceiver, admin);
658d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                mAdminList.add(admin);
659d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                saveSettingsLocked();
660d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                sendAdminCommandLocked(admin,
661ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn                        DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED);
662d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
663d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
664d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
665d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
666d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
6673255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
668d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    public boolean isAdminActive(ComponentName adminReceiver) {
669d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        synchronized (this) {
670d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return getActiveAdminUncheckedLocked(adminReceiver) != null;
671d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        }
672d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    }
6733255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
674d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    public List<ComponentName> getActiveAdmins() {
675d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
676d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            final int N = mAdminList.size();
677d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (N <= 0) {
678d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                return null;
679d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
680d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            ArrayList<ComponentName> res = new ArrayList<ComponentName>(N);
681d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for (int i=0; i<N; i++) {
682d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                res.add(mAdminList.get(i).info.getComponent());
683d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
684d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return res;
685d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
686d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
6873255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
68821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    public boolean packageHasActiveAdmins(String packageName) {
68921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        synchronized (this) {
69021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            final int N = mAdminList.size();
69121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            for (int i=0; i<N; i++) {
69221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if (mAdminList.get(i).info.getPackageName().equals(packageName)) {
69321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    return true;
69421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
69521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
69621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            return false;
69721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
69821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
6993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
700d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void removeActiveAdmin(ComponentName adminReceiver) {
701d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
702d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver);
703d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (admin == null) {
704d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                return;
705d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
706d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (admin.getUid() != Binder.getCallingUid()) {
707d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                mContext.enforceCallingOrSelfPermission(
708d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                        android.Manifest.permission.BIND_DEVICE_ADMIN, null);
709d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
710d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
711d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
712d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                removeActiveAdminLocked(adminReceiver);
713d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
714d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
715d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
716d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
717d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
7183255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
71985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn    public void setPasswordQuality(ComponentName who, int quality) {
72085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        validateQualityConstant(quality);
7213255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
722d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
723d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
724d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
725d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
7268aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
7278aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
72885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            if (ap.passwordQuality != quality) {
72985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                ap.passwordQuality = quality;
730d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                saveSettingsLocked();
731d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
732d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
733d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
7343255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
7359327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn    public int getPasswordQuality(ComponentName who) {
736d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
7379327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
7383255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
739254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
740254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
7419327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                return admin != null ? admin.passwordQuality : mode;
742254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
7433255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
744254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
745d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
746d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
7479327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                if (mode < admin.passwordQuality) {
7489327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    mode = admin.passwordQuality;
749d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
750d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
751d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return mode;
752d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
753d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
7543255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
755254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    public void setPasswordMinimumLength(ComponentName who, int length) {
756d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
757d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
758d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
759d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
7608aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
7618aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
762d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (ap.minimumPasswordLength != length) {
763d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                ap.minimumPasswordLength = length;
764d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                saveSettingsLocked();
765d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
766d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
767d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
7683255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
769254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    public int getPasswordMinimumLength(ComponentName who) {
770d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
771d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            int length = 0;
7723255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
773254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
774254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
775254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.minimumPasswordLength : length;
776254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
7773255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
778254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
779d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
780d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
781d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (length < admin.minimumPasswordLength) {
782d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    length = admin.minimumPasswordLength;
783d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
784d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
785d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return length;
786d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
787d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
7883255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
7893255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev    public void setPasswordHistoryLength(ComponentName who, int length) {
7903255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        synchronized (this) {
7913255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            if (who == null) {
7923255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
7933255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            }
7943255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
7953255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
7963255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            if (ap.passwordHistoryLength != length) {
7973255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                ap.passwordHistoryLength = length;
7983255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                saveSettingsLocked();
7993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            }
8003255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        }
8013255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev    }
8023255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
8033255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev    public int getPasswordHistoryLength(ComponentName who) {
8043255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        synchronized (this) {
8053255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            int length = 0;
8063255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
8073255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            if (who != null) {
8083255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
8093255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                return admin != null ? admin.passwordHistoryLength : length;
8103255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            }
8113255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
8123255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            final int N = mAdminList.size();
8133255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            for (int i = 0; i < N; i++) {
8143255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                ActiveAdmin admin = mAdminList.get(i);
8153255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                if (length < admin.passwordHistoryLength) {
8163255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    length = admin.passwordHistoryLength;
8173255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                }
8183255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            }
8193255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            return length;
8203255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        }
8213255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev    }
8223255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
823a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public void setPasswordMinimumUpperCase(ComponentName who, int length) {
824a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
825a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
826a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
827a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
828a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
829a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
830a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordUpperCase != length) {
831a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordUpperCase = length;
832a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                saveSettingsLocked();
833a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
834a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
835a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
836a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
837a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public int getPasswordMinimumUpperCase(ComponentName who) {
838a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
839a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
840a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
841a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
842a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
843a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordUpperCase : length;
844a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
845a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
846a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            final int N = mAdminList.size();
847a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for (int i=0; i<N; i++) {
848a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = mAdminList.get(i);
849a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordUpperCase) {
850a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordUpperCase;
851a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
852a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
853a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
854a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
855a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
856a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
857a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public void setPasswordMinimumLowerCase(ComponentName who, int length) {
858a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
859a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
860a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
861a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
862a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
863a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
864a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordLowerCase != length) {
865a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordLowerCase = length;
866a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                saveSettingsLocked();
867a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
868a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
869a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
870a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
871a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public int getPasswordMinimumLowerCase(ComponentName who) {
872a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
873a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
874a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
875a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
876a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
877a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordLowerCase : length;
878a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
879a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
880a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            final int N = mAdminList.size();
881a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for (int i=0; i<N; i++) {
882a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = mAdminList.get(i);
883a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordLowerCase) {
884a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordLowerCase;
885a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
886a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
887a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
888a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
889a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
890a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
891a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public void setPasswordMinimumLetters(ComponentName who, int length) {
892a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
893a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
894a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
895a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
896a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
897a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
898a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordLetters != length) {
899a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordLetters = length;
900a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                saveSettingsLocked();
901a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
902a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
903a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
904a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
905a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public int getPasswordMinimumLetters(ComponentName who) {
906a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
907a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
908a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
909a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
910a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
911a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordLetters : length;
912a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
913a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
914a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            final int N = mAdminList.size();
915a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for (int i=0; i<N; i++) {
916a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = mAdminList.get(i);
917a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordLetters) {
918a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordLetters;
919a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
920a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
921a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
922a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
923a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
924a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
925a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public void setPasswordMinimumNumeric(ComponentName who, int length) {
926a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
927a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
928a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
929a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
930a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
931a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
932a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordNumeric != length) {
933a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordNumeric = length;
934a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                saveSettingsLocked();
935a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
936a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
937a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
938a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
939a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public int getPasswordMinimumNumeric(ComponentName who) {
940a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
941a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
942a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
943a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
944a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
945a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordNumeric : length;
946a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
947a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
948a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            final int N = mAdminList.size();
949a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for (int i = 0; i < N; i++) {
950a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = mAdminList.get(i);
951a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordNumeric) {
952a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordNumeric;
953a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
954a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
955a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
956a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
957a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
958a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
959a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public void setPasswordMinimumSymbols(ComponentName who, int length) {
960a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
961a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
962a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
963a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
964a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
965a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
966a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordSymbols != length) {
967a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordSymbols = length;
968a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                saveSettingsLocked();
969a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
970a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
971a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
972a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
973a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public int getPasswordMinimumSymbols(ComponentName who) {
974a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
975a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
976a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
977a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
978a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
979a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordSymbols : length;
980a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
981a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
982a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            final int N = mAdminList.size();
983a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for  (int i=0; i<N; i++) {
984a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ActiveAdmin admin = mAdminList.get(i);
985a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordSymbols) {
986a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordSymbols;
987a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
988a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
989a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
990a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
991a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
992a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
993c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev    public void setPasswordMinimumNonLetter(ComponentName who, int length) {
994c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        synchronized (this) {
995c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            if (who == null) {
996c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
997c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            }
998c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
999c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1000c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            if (ap.minimumPasswordNonLetter != length) {
1001c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                ap.minimumPasswordNonLetter = length;
1002c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                saveSettingsLocked();
1003c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            }
1004c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        }
1005c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev    }
1006c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev
1007c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev    public int getPasswordMinimumNonLetter(ComponentName who) {
1008c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        synchronized (this) {
1009c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            int length = 0;
1010c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev
1011c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            if (who != null) {
1012c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
1013c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                return admin != null ? admin.minimumPasswordNonLetter : length;
1014c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            }
1015c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev
1016c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            final int N = mAdminList.size();
1017c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            for (int i=0; i<N; i++) {
1018c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                ActiveAdmin admin = mAdminList.get(i);
1019c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                if (length < admin.minimumPasswordNonLetter) {
1020c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    length = admin.minimumPasswordNonLetter;
1021c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                }
1022c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            }
1023c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            return length;
1024c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        }
1025c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev    }
1026c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev
1027df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    public boolean isActivePasswordSufficient() {
1028d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1029d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
1030d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
10318aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
10328aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1033a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (mActivePasswordQuality < getPasswordQuality(null)
1034a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    || mActivePasswordLength < getPasswordMinimumLength(null)) {
1035a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return false;
1036a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1037a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if(mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
1038a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return true;
1039a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1040a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null)
1041a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    && mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null)
1042a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    && mActivePasswordLetters >= getPasswordMinimumLetters(null)
1043a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    && mActivePasswordNumeric >= getPasswordMinimumNumeric(null)
1044c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    && mActivePasswordSymbols >= getPasswordMinimumSymbols(null)
1045c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    && mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null);
1046d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1047d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
10483255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1049d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public int getCurrentFailedPasswordAttempts() {
1050d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1051d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
1052d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
10538aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
10548aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
1055d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return mFailedPasswordAttempts;
1056d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1057d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
10583255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
10598ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    public void setMaximumFailedPasswordsForWipe(ComponentName who, int num) {
10608ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
10618ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            // This API can only be called by an active device admin,
10628ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            // so try to retrieve it to check that the caller is one.
10638ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            getActiveAdminForCallerLocked(who,
10648ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
10658ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
10668ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
10678ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (ap.maximumFailedPasswordsForWipe != num) {
10688ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                ap.maximumFailedPasswordsForWipe = num;
10698ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                saveSettingsLocked();
10708ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
10718ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
10728ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
10733255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1074254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    public int getMaximumFailedPasswordsForWipe(ComponentName who) {
10758ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
1076d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            int count = 0;
10773255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1078254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
1079254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
1080254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.maximumFailedPasswordsForWipe : count;
1081254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
10823255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1083254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
1084d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
1085d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
1086d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (count == 0) {
1087d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    count = admin.maximumFailedPasswordsForWipe;
1088d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                } else if (admin.maximumFailedPasswordsForWipe != 0
1089d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                        && count > admin.maximumFailedPasswordsForWipe) {
1090d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    count = admin.maximumFailedPasswordsForWipe;
1091d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
1092d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1093d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return count;
10948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
10958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
10963255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
109787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    public boolean resetPassword(String password, int flags) {
10989327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn        int quality;
1099df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        synchronized (this) {
1100df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // This API can only be called by an active device admin,
1101df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // so try to retrieve it to check that the caller is one.
11028aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
11038aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_RESET_PASSWORD);
11049327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            quality = getPasswordQuality(null);
11059327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
110685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                int realQuality = LockPatternUtils.computePasswordQuality(password);
1107a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (realQuality < quality
1108a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
110985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    Slog.w(TAG, "resetPassword: password quality 0x"
111085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            + Integer.toHexString(quality)
111185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            + " does not meet required quality 0x"
111285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            + Integer.toHexString(quality));
11139327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    return false;
11149327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                }
1115a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                quality = Math.max(realQuality, quality);
11169327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            }
11179327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            int length = getPasswordMinimumLength(null);
11189327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (password.length() < length) {
111985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                Slog.w(TAG, "resetPassword: password length " + password.length()
112085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                        + " does not meet required length " + length);
1121df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                return false;
1122df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            }
1123a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
1124a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int letters = 0;
1125a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int uppercase = 0;
1126a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int lowercase = 0;
1127a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int numbers = 0;
1128a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int symbols = 0;
1129c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                int nonletter = 0;
1130a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                for (int i = 0; i < password.length(); i++) {
1131a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    char c = password.charAt(i);
1132a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    if (c >= 'A' && c <= 'Z') {
1133a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        letters++;
1134a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        uppercase++;
1135a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    } else if (c >= 'a' && c <= 'z') {
1136a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        letters++;
1137a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        lowercase++;
1138a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    } else if (c >= '0' && c <= '9') {
1139a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        numbers++;
1140c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                        nonletter++;
1141a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    } else {
1142a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        symbols++;
1143c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                        nonletter++;
1144a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    }
1145a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1146a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int neededLetters = getPasswordMinimumLetters(null);
1147a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if(letters < neededLetters) {
1148a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of letters " + letters
1149a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + " does not meet required number of letters " + neededLetters);
1150a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1151a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1152a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int neededNumbers = getPasswordMinimumNumeric(null);
1153a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (numbers < neededNumbers) {
1154a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog
1155a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            .w(TAG, "resetPassword: number of numerical digits " + numbers
1156a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                                    + " does not meet required number of numerical digits "
1157a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                                    + neededNumbers);
1158a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1159a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1160a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int neededLowerCase = getPasswordMinimumLowerCase(null);
1161a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (lowercase < neededLowerCase) {
1162a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase
1163a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + " does not meet required number of lowercase letters "
1164a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + neededLowerCase);
1165a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1166a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1167a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int neededUpperCase = getPasswordMinimumUpperCase(null);
1168a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (uppercase < neededUpperCase) {
1169a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase
1170a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + " does not meet required number of uppercase letters "
1171a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + neededUpperCase);
1172a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1173a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1174a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int neededSymbols = getPasswordMinimumSymbols(null);
1175a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (symbols < neededSymbols) {
1176a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of special symbols " + symbols
1177a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + " does not meet required number of special symbols " + neededSymbols);
1178a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1179a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1180c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                int neededNonLetter = getPasswordMinimumNonLetter(null);
1181c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                if (nonletter < neededNonLetter) {
1182c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of non-letter characters " + nonletter
1183c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                            + " does not meet required number of non-letter characters "
1184c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                            + neededNonLetter);
1185c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    return false;
1186c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                }
1187a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1188a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1189a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            LockPatternUtils utils = new LockPatternUtils(mContext);
1190a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if(utils.checkPasswordHistory(password)) {
1191a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                Slog.w(TAG, "resetPassword: password is the same as one of the last "
1192a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        + getPasswordHistoryLength(null) + " passwords");
1193a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return false;
1194a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1195df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
11963255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
119787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        int callingUid = Binder.getCallingUid();
119887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        if (mPasswordOwner >= 0 && mPasswordOwner != callingUid) {
119985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "resetPassword: already set by another uid and not entered by user");
120087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            return false;
120187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
12023255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1203df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        // Don't do this with the lock held, because it is going to call
1204df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        // back in to the service.
1205df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        long ident = Binder.clearCallingIdentity();
1206df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        try {
1207df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            LockPatternUtils utils = new LockPatternUtils(mContext);
12089327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            utils.saveLockPassword(password, quality);
120985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            synchronized (this) {
121085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                int newOwner = (flags&DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY)
121185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                        != 0 ? callingUid : -1;
121285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                if (mPasswordOwner != newOwner) {
121385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    mPasswordOwner = newOwner;
121485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    saveSettingsLocked();
121585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                }
121687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
1217df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        } finally {
1218df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            Binder.restoreCallingIdentity(ident);
1219df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
12203255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1221df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        return true;
1222df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
12233255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1224d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void setMaximumTimeToLock(ComponentName who, long timeMs) {
1225d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1226d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
1227d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
1228d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
12298aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1230315ada7fbb9e967c22e87b4921bec720ceb2c73cDianne Hackborn                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
1231d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (ap.maximumTimeToUnlock != timeMs) {
1232d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                ap.maximumTimeToUnlock = timeMs;
12333255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1234df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                long ident = Binder.clearCallingIdentity();
1235df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                try {
1236df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    saveSettingsLocked();
12373255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1238254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    timeMs = getMaximumTimeToLock(null);
1239df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    if (timeMs <= 0) {
1240df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                        timeMs = Integer.MAX_VALUE;
1241df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    }
12423255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1243df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    try {
1244df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                        getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
1245df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    } catch (RemoteException e) {
124685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                        Slog.w(TAG, "Failure talking with power manager", e);
1247df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    }
1248df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                } finally {
1249df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                    Binder.restoreCallingIdentity(ident);
1250df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                }
1251d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1252d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1253d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
12543255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1255254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    public long getMaximumTimeToLock(ComponentName who) {
1256d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1257d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            long time = 0;
12583255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1259254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
1260254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
1261254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.maximumTimeToUnlock : time;
1262254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
12633255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1264254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            final int N = mAdminList.size();
1265d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
1266d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                ActiveAdmin admin = mAdminList.get(i);
1267d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (time == 0) {
1268d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    time = admin.maximumTimeToUnlock;
1269d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                } else if (admin.maximumTimeToUnlock != 0
1270d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                        && time > admin.maximumTimeToUnlock) {
1271d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    time = admin.maximumTimeToUnlock;
1272d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
1273d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1274d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return time;
1275d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1276d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
12773255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1278df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    public void lockNow() {
1279df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        synchronized (this) {
1280df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // This API can only be called by an active device admin,
1281df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // so try to retrieve it to check that the caller is one.
12828aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
12838aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
1284254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            long ident = Binder.clearCallingIdentity();
1285254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            try {
1286254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                mIPowerManager.goToSleepWithReason(SystemClock.uptimeMillis(),
1287254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN);
1288254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            } catch (RemoteException e) {
1289254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            } finally {
1290254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                Binder.restoreCallingIdentity(ident);
1291254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
1292df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
1293df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
12943255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
12958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    void wipeDataLocked(int flags) {
12968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        try {
12978ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            RecoverySystem.rebootWipeUserData(mContext);
12988ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        } catch (IOException e) {
129985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "Failed requesting data wipe", e);
13008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
13018ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
13023255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1303d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void wipeData(int flags) {
1304d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1305d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
1306d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
13078aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
13088aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
13098ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            long ident = Binder.clearCallingIdentity();
13108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            try {
13118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                wipeDataLocked(flags);
13128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            } finally {
13138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                Binder.restoreCallingIdentity(ident);
13148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1315df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
13168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
13173255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
13188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    public void getRemoveWarning(ComponentName comp, final RemoteCallback result) {
13198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        mContext.enforceCallingOrSelfPermission(
13208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
13213255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
13228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
13238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            ActiveAdmin admin = getActiveAdminUncheckedLocked(comp);
13248ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (admin == null) {
13258ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                try {
13268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    result.sendResult(null);
13278ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } catch (RemoteException e) {
13288ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
13298ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                return;
13308ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1331ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn            Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED);
13328ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            intent.setComponent(admin.info.getComponent());
13338ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
13348ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                @Override
13358ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                public void onReceive(Context context, Intent intent) {
13368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    try {
13378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                        result.sendResult(getResultExtras(false));
13388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    } catch (RemoteException e) {
13398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    }
13408ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
13418ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }, null, Activity.RESULT_OK, null, null);
1342d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1343d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
13443255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1345a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public void setActivePasswordState(int quality, int length, int letters, int uppercase,
1346c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            int lowercase, int numbers, int symbols, int nonletter) {
1347d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
1348d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
13493255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
135085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        validateQualityConstant(quality);
13513255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1352d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
13539327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (mActivePasswordQuality != quality || mActivePasswordLength != length
1354a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    || mFailedPasswordAttempts != 0 || mActivePasswordLetters != letters
1355a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    || mActivePasswordUpperCase != uppercase
1356a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    || mActivePasswordLowerCase != lowercase || mActivePasswordNumeric != numbers
1357c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    || mActivePasswordSymbols != symbols || mActivePasswordNonLetter != nonletter) {
1358d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                long ident = Binder.clearCallingIdentity();
1359d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                try {
13609327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    mActivePasswordQuality = quality;
1361d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    mActivePasswordLength = length;
1362a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordLetters = letters;
1363a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordLowerCase = lowercase;
1364a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordUpperCase = uppercase;
1365a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordNumeric = numbers;
1366a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    mActivePasswordSymbols = symbols;
1367c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    mActivePasswordNonLetter = nonletter;
136885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    mFailedPasswordAttempts = 0;
136985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    saveSettingsLocked();
1370ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn                    sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
13718aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                            DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1372d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                } finally {
1373d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    Binder.restoreCallingIdentity(ident);
1374d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
1375d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1376d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1377d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
13783255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1379d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void reportFailedPasswordAttempt() {
1380d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
1381d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
13823255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1383d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1384d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
1385d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
1386d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                mFailedPasswordAttempts++;
13878ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                saveSettingsLocked();
1388254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                int max = getMaximumFailedPasswordsForWipe(null);
13898ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (max > 0 && mFailedPasswordAttempts >= max) {
13908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    wipeDataLocked(0);
13918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
1392ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn                sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED,
13938aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                        DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
1394d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
1395d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
1396d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1397d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1398d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
13993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1400d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void reportSuccessfulPasswordAttempt() {
1401d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
1402d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
14033255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1404d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
140587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            if (mFailedPasswordAttempts != 0 || mPasswordOwner >= 0) {
1406d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                long ident = Binder.clearCallingIdentity();
1407d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                try {
1408d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    mFailedPasswordAttempts = 0;
140987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    mPasswordOwner = -1;
14108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    saveSettingsLocked();
1411ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn                    sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED,
14128aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                            DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
1413d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                } finally {
1414d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    Binder.restoreCallingIdentity(ident);
1415d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
1416d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1417d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1418d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
14193255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
142087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    @Override
142187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
142287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
142387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                != PackageManager.PERMISSION_GRANTED) {
142487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn
142587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid="
142687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    + Binder.getCallingPid()
142787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    + ", uid=" + Binder.getCallingUid());
142887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            return;
142987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
14303255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
143187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        final Printer p = new PrintWriterPrinter(pw);
14323255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
143387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        synchronized (this) {
143487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            p.println("Current Device Policy Manager state:");
14353255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
143687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            p.println("  Enabled Device Admins:");
143787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            final int N = mAdminList.size();
143887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            for (int i=0; i<N; i++) {
143987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                ActiveAdmin ap = mAdminList.get(i);
144087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                if (ap != null) {
144187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.print("  "); pw.print(ap.info.getComponent().flattenToShortString());
144287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                            pw.println(":");
144387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    ap.dump("    ", pw);
144487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                }
144587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
14463255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
144787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.println(" ");
144885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            pw.print("  mActivePasswordQuality=0x");
144985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    pw.println(Integer.toHexString(mActivePasswordQuality));
145087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print("  mActivePasswordLength="); pw.println(mActivePasswordLength);
1451a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print("  mActivePasswordUpperCase="); pw.println(mActivePasswordUpperCase);
1452a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print("  mActivePasswordLowerCase="); pw.println(mActivePasswordLowerCase);
1453a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print("  mActivePasswordLetters="); pw.println(mActivePasswordLetters);
1454a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print("  mActivePasswordNumeric="); pw.println(mActivePasswordNumeric);
1455a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print("  mActivePasswordSymbols="); pw.println(mActivePasswordSymbols);
1456c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            pw.print("  mActivePasswordNonLetter="); pw.println(mActivePasswordNonLetter);
145787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print("  mFailedPasswordAttempts="); pw.println(mFailedPasswordAttempts);
145887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print("  mPasswordOwner="); pw.println(mPasswordOwner);
145987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
146087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    }
1461d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn}
1462