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
19424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackbornimport com.android.internal.os.storage.ExternalStorageFormatter;
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;
30599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasaniimport android.app.ActivityManagerNative;
31a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport android.app.AlarmManager;
32599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasaniimport android.app.AppGlobals;
33a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport android.app.PendingIntent;
3487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DeviceAdminInfo;
3587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DeviceAdminReceiver;
3687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DevicePolicyManager;
3787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.IDevicePolicyManager;
388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.content.BroadcastReceiver;
39d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.ComponentName;
4069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayorimport android.content.ContentResolver;
41d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Context;
42d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Intent;
43a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport android.content.IntentFilter;
44599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasaniimport android.content.pm.IPackageManager;
45d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.pm.PackageManager;
4621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException;
471f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadlerimport android.content.pm.ResolveInfo;
48d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.os.Binder;
49f752202bee88e31ce765483ba2efa6999ae9c9adAdam Cohenimport android.os.Bundle;
50ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komaloimport android.os.Environment;
51a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport android.os.Handler;
52df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.IBinder;
53df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.IPowerManager;
54424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackbornimport android.os.PowerManager;
55599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasaniimport android.os.Process;
56df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.RecoverySystem;
578ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.os.RemoteCallback;
58df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.RemoteException;
59df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.ServiceManager;
60254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackbornimport android.os.SystemClock;
610fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadlerimport android.os.SystemProperties;
625ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
63599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasaniimport android.os.UserManager;
6469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayorimport android.provider.Settings;
6587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.util.PrintWriterPrinter;
6687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.util.Printer;
671f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadlerimport android.util.Slog;
68599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasaniimport android.util.SparseArray;
69d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.util.Xml;
7093c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Millerimport android.view.IWindowManager;
71254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackbornimport android.view.WindowManagerPolicy;
72d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
73d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.File;
7487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport java.io.FileDescriptor;
75d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.FileInputStream;
76cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackbornimport java.io.FileNotFoundException;
77d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.FileOutputStream;
78d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.IOException;
7987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport java.io.PrintWriter;
80a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport java.text.DateFormat;
81d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackbornimport java.util.ArrayList;
82a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport java.util.Date;
83d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackbornimport java.util.HashMap;
84d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.util.List;
8569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayorimport java.util.Set;
86d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
87d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn/**
88d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Implementation of the device policy APIs.
89d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn */
90d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornpublic class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
91599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private static final String DEVICE_POLICIES_XML = "device_policies.xml";
92599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
936b85768058b065cc682757a366abc828c9ca727aJim Miller    private static final String TAG = "DevicePolicyManagerService";
94a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
956b85768058b065cc682757a366abc828c9ca727aJim Miller    private static final int REQUEST_EXPIRE_PASSWORD = 5571;
963255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
97599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private static final long MS_PER_DAY = 86400 * 1000;
98599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
99599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms
100a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
101a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    protected static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION
102a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            = "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION";
103a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
104599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private static final boolean DBG = false;
105a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
10621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    final Context mContext;
107424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn    final PowerManager.WakeLock mWakeLock;
108d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
109df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    IPowerManager mIPowerManager;
11093c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller    IWindowManager mIWindowManager;
1113255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
112599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public static class DevicePolicyData {
113599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
114599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mActivePasswordLength = 0;
115599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mActivePasswordUpperCase = 0;
116599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mActivePasswordLowerCase = 0;
117599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mActivePasswordLetters = 0;
118599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mActivePasswordNumeric = 0;
119599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mActivePasswordSymbols = 0;
120599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mActivePasswordNonLetter = 0;
121599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mFailedPasswordAttempts = 0;
122599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
123599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mUserHandle;;
124599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        int mPasswordOwner = -1;
125599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        long mLastMaximumTimeToLock = -1;
126599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
127599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final HashMap<ComponentName, ActiveAdmin> mAdminMap
128599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                = new HashMap<ComponentName, ActiveAdmin>();
129599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final ArrayList<ActiveAdmin> mAdminList
130599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                = new ArrayList<ActiveAdmin>();
131599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
132599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        public DevicePolicyData(int userHandle) {
133599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            mUserHandle = userHandle;
134599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        }
135599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    }
1363255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
137599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    final SparseArray<DevicePolicyData> mUserData = new SparseArray<DevicePolicyData>();
1382fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn
139599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    Handler mHandler = new Handler();
1403255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
141a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    BroadcastReceiver mReceiver = new BroadcastReceiver() {
142a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        @Override
143a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        public void onReceive(Context context, Intent intent) {
144599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final String action = intent.getAction();
145599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
146599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    getSendingUserId());
147a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            if (Intent.ACTION_BOOT_COMPLETED.equals(action)
148a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) {
149599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                Slog.v(TAG, "Sending password expiration notifications for action " + action
150599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        + " for user " + userHandle);
151a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                mHandler.post(new Runnable() {
152a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    public void run() {
153599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        handlePasswordExpirationNotification(getUserData(userHandle));
154a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    }
155a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                });
156599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
157599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                removeUserData(userHandle);
158599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            } else if (Intent.ACTION_USER_STARTED.equals(action)
159599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || Intent.ACTION_PACKAGE_CHANGED.equals(action)
160599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || Intent.ACTION_PACKAGE_REMOVED.equals(action)
161599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
162599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
163599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (Intent.ACTION_USER_STARTED.equals(action)) {
164599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    // Reset the policy data
165599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    synchronized (DevicePolicyManagerService.this) {
166599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        mUserData.remove(userHandle);
167599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    }
168599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                }
169599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
170599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                handlePackagesChanged(userHandle);
171a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
172a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
173a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    };
174a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
175d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    static class ActiveAdmin {
1768ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        final DeviceAdminInfo info;
1773255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1789327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn        int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
179d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
180d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_MINIMUM_PASSWORD_LENGTH = 0;
181d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        int minimumPasswordLength = DEF_MINIMUM_PASSWORD_LENGTH;
182d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
183d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_PASSWORD_HISTORY_LENGTH = 0;
184d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        int passwordHistoryLength = DEF_PASSWORD_HISTORY_LENGTH;
185d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
186d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_MINIMUM_PASSWORD_UPPER_CASE = 0;
187d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        int minimumPasswordUpperCase = DEF_MINIMUM_PASSWORD_UPPER_CASE;
188d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
189d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_MINIMUM_PASSWORD_LOWER_CASE = 0;
190d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        int minimumPasswordLowerCase = DEF_MINIMUM_PASSWORD_LOWER_CASE;
191d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
192d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_MINIMUM_PASSWORD_LETTERS = 1;
1932a108403803bd30bee1c019060c208fb8c52c10cDianne Hackborn        int minimumPasswordLetters = DEF_MINIMUM_PASSWORD_LETTERS;
194d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
195d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_MINIMUM_PASSWORD_NUMERIC = 1;
196d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        int minimumPasswordNumeric = DEF_MINIMUM_PASSWORD_NUMERIC;
197d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
198d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_MINIMUM_PASSWORD_SYMBOLS = 1;
199d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        int minimumPasswordSymbols = DEF_MINIMUM_PASSWORD_SYMBOLS;
200d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
201d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_MINIMUM_PASSWORD_NON_LETTER = 0;
202d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        int minimumPasswordNonLetter = DEF_MINIMUM_PASSWORD_NON_LETTER;
203d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
204d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
205d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
206d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
207d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0;
208d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE;
209d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
210d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final long DEF_PASSWORD_EXPIRATION_TIMEOUT = 0;
211d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        long passwordExpirationTimeout = DEF_PASSWORD_EXPIRATION_TIMEOUT;
212d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
213d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        static final long DEF_PASSWORD_EXPIRATION_DATE = 0;
214d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
215d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
21648b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller        static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none
21748b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller        int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED;
218b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller
21922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler        boolean encryptionRequested = false;
2202447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        boolean disableCamera = false;
2213255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
22269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        // TODO: review implementation decisions with frameworks team
22369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        boolean specifiesGlobalProxy = false;
22469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        String globalProxySpec = null;
22569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        String globalProxyExclusionList = null;
22669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
227d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        ActiveAdmin(DeviceAdminInfo _info) {
228d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            info = _info;
229d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
2303255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
231d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        int getUid() { return info.getActivityInfo().applicationInfo.uid; }
2323255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
233599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        public UserHandle getUserHandle() {
234599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            return new UserHandle(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid));
235599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        }
236599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
2378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        void writeToXml(XmlSerializer out)
2388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throws IllegalArgumentException, IllegalStateException, IOException {
23921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            out.startTag(null, "policies");
24021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            info.writePoliciesToXml(out);
24121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            out.endTag(null, "policies");
2429327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
2439327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.startTag(null, "password-quality");
2449327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.attribute(null, "value", Integer.toString(passwordQuality));
2459327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                out.endTag(null, "password-quality");
246d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) {
2478ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    out.startTag(null, "min-password-length");
2488ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    out.attribute(null, "value", Integer.toString(minimumPasswordLength));
2493255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    out.endTag(null, "min-password-length");
2503255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                }
251d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) {
2523255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    out.startTag(null, "password-history-length");
2533255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(passwordHistoryLength));
2543255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    out.endTag(null, "password-history-length");
2558ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
256d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) {
257a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-uppercase");
258a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase));
259a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-uppercase");
260a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
261d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) {
262a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-lowercase");
263a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase));
264a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-lowercase");
265a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
266d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) {
267a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-letters");
268a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordLetters));
269a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-letters");
270a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
271d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) {
272a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-numeric");
273a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordNumeric));
274a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-numeric");
275a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
276d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) {
277a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.startTag(null, "min-password-symbols");
278a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordSymbols));
279a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    out.endTag(null, "min-password-symbols");
280a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
281d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) {
282c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    out.startTag(null, "min-password-nonletter");
283c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter));
284c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    out.endTag(null, "min-password-nonletter");
285c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                }
2868ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
287d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn            if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) {
2888ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "max-time-to-unlock");
2898ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.attribute(null, "value", Long.toString(maximumTimeToUnlock));
2908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "max-time-to-unlock");
2918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
292d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn            if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
2938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "max-failed-password-wipe");
2948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe));
2958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "max-failed-password-wipe");
2968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
29769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            if (specifiesGlobalProxy) {
29869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                out.startTag(null, "specifies-global-proxy");
29969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                out.attribute(null, "value", Boolean.toString(specifiesGlobalProxy));
30069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                out.endTag(null, "specifies_global_proxy");
30169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                if (globalProxySpec != null) {
30269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    out.startTag(null, "global-proxy-spec");
30369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    out.attribute(null, "value", globalProxySpec);
30469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    out.endTag(null, "global-proxy-spec");
30569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                }
30669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                if (globalProxyExclusionList != null) {
30769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    out.startTag(null, "global-proxy-exclusion-list");
30869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    out.attribute(null, "value", globalProxyExclusionList);
30969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    out.endTag(null, "global-proxy-exclusion-list");
31069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                }
31169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            }
312d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn            if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) {
313a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                out.startTag(null, "password-expiration-timeout");
314a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                out.attribute(null, "value", Long.toString(passwordExpirationTimeout));
315a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                out.endTag(null, "password-expiration-timeout");
316a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
317d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn            if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) {
318a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                out.startTag(null, "password-expiration-date");
319a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                out.attribute(null, "value", Long.toString(passwordExpirationDate));
320a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                out.endTag(null, "password-expiration-date");
321a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
32222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            if (encryptionRequested) {
32322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                out.startTag(null, "encryption-requested");
32422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                out.attribute(null, "value", Boolean.toString(encryptionRequested));
32522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                out.endTag(null, "encryption-requested");
32622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            }
3272447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            if (disableCamera) {
3282447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                out.startTag(null, "disable-camera");
3292447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                out.attribute(null, "value", Boolean.toString(disableCamera));
3302447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                out.endTag(null, "disable-camera");
3312447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            }
33248b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller            if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
33348b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                out.startTag(null, "disable-keyguard-features");
33448b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                out.attribute(null, "value", Integer.toString(disabledKeyguardFeatures));
33548b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                out.endTag(null, "disable-keyguard-features");
336b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            }
3378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
3383255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
3398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        void readFromXml(XmlPullParser parser)
3408ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throws XmlPullParserException, IOException {
3418ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int outerDepth = parser.getDepth();
3428ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int type;
3438ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
3448ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                   && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3458ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3468ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    continue;
3478ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
3488ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                String tag = parser.getName();
34921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if ("policies".equals(tag)) {
35021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    info.readPoliciesFromXml(parser);
35121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                } else if ("password-quality".equals(tag)) {
3529327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    passwordQuality = Integer.parseInt(
3538ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
3548ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("min-password-length".equals(tag)) {
3558ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    minimumPasswordLength = Integer.parseInt(
3568ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
3573255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                } else if ("password-history-length".equals(tag)) {
3583255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    passwordHistoryLength = Integer.parseInt(
3593255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
360a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-uppercase".equals(tag)) {
361a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordUpperCase = Integer.parseInt(
362a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
363a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-lowercase".equals(tag)) {
364a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordLowerCase = Integer.parseInt(
365a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
366a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-letters".equals(tag)) {
367a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordLetters = Integer.parseInt(
368a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
369a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-numeric".equals(tag)) {
370a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordNumeric = Integer.parseInt(
371a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
372a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                } else if ("min-password-symbols".equals(tag)) {
373a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    minimumPasswordSymbols = Integer.parseInt(
374a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
375c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                } else if ("min-password-nonletter".equals(tag)) {
376c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    minimumPasswordNonLetter = Integer.parseInt(
377c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                            parser.getAttributeValue(null, "value"));
3788ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("max-time-to-unlock".equals(tag)) {
3798ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    maximumTimeToUnlock = Long.parseLong(
3808ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
3818ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("max-failed-password-wipe".equals(tag)) {
3828ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    maximumFailedPasswordsForWipe = Integer.parseInt(
3838ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
38469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                } else if ("specifies-global-proxy".equals(tag)) {
38522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                    specifiesGlobalProxy = Boolean.parseBoolean(
38669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                            parser.getAttributeValue(null, "value"));
38769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                } else if ("global-proxy-spec".equals(tag)) {
38869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    globalProxySpec =
38969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                        parser.getAttributeValue(null, "value");
39069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                } else if ("global-proxy-exclusion-list".equals(tag)) {
39169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    globalProxyExclusionList =
39269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                        parser.getAttributeValue(null, "value");
393a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                } else if ("password-expiration-timeout".equals(tag)) {
394a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    passwordExpirationTimeout = Long.parseLong(
395a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                            parser.getAttributeValue(null, "value"));
396a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                } else if ("password-expiration-date".equals(tag)) {
397a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    passwordExpirationDate = Long.parseLong(
398a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                            parser.getAttributeValue(null, "value"));
39922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                } else if ("encryption-requested".equals(tag)) {
40022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                    encryptionRequested = Boolean.parseBoolean(
40122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                            parser.getAttributeValue(null, "value"));
4022447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                } else if ("disable-camera".equals(tag)) {
4032447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                    disableCamera = Boolean.parseBoolean(
4042447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                            parser.getAttributeValue(null, "value"));
4057077b3c9bb7367bae3e073aa213de51baf3321a9Amith Yamasani                } else if ("disable-keyguard-features".equals(tag)) {
4067077b3c9bb7367bae3e073aa213de51baf3321a9Amith Yamasani                    disabledKeyguardFeatures = Integer.parseInt(
4077077b3c9bb7367bae3e073aa213de51baf3321a9Amith Yamasani                            parser.getAttributeValue(null, "value"));
40821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                } else {
40985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    Slog.w(TAG, "Unknown admin tag: " + tag);
41021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
41121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                XmlUtils.skipCurrentTag(parser);
41221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
41321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
4143255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
41587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        void dump(String prefix, PrintWriter pw) {
41687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print(prefix); pw.print("uid="); pw.println(getUid());
41787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print(prefix); pw.println("policies:");
41887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            ArrayList<DeviceAdminInfo.PolicyInfo> pols = info.getUsedPolicies();
41987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            if (pols != null) {
42087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                for (int i=0; i<pols.size(); i++) {
42187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.print(prefix); pw.print("  "); pw.println(pols.get(i).tag);
42287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                }
42387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
42485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            pw.print(prefix); pw.print("passwordQuality=0x");
4253255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    pw.println(Integer.toHexString(passwordQuality));
4263255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordLength=");
42787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.println(minimumPasswordLength);
4283255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            pw.print(prefix); pw.print("passwordHistoryLength=");
4293255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    pw.println(passwordHistoryLength);
430a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordUpperCase=");
431a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordUpperCase);
432a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordLowerCase=");
433a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordLowerCase);
434a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordLetters=");
435a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordLetters);
436a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordNumeric=");
437a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordNumeric);
438a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordSymbols=");
439a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    pw.println(minimumPasswordSymbols);
440c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            pw.print(prefix); pw.print("minimumPasswordNonLetter=");
441c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    pw.println(minimumPasswordNonLetter);
44287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print(prefix); pw.print("maximumTimeToUnlock=");
44387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.println(maximumTimeToUnlock);
44487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.print(prefix); pw.print("maximumFailedPasswordsForWipe=");
44587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    pw.println(maximumFailedPasswordsForWipe);
44669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            pw.print(prefix); pw.print("specifiesGlobalProxy=");
44769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    pw.println(specifiesGlobalProxy);
448a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            pw.print(prefix); pw.print("passwordExpirationTimeout=");
449a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    pw.println(passwordExpirationTimeout);
450a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            pw.print(prefix); pw.print("passwordExpirationDate=");
451a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    pw.println(passwordExpirationDate);
45269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            if (globalProxySpec != null) {
45369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                pw.print(prefix); pw.print("globalProxySpec=");
45469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                        pw.println(globalProxySpec);
45569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            }
45669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            if (globalProxyExclusionList != null) {
45769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                pw.print(prefix); pw.print("globalProxyEclusionList=");
45869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                        pw.println(globalProxyExclusionList);
45969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            }
46022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            pw.print(prefix); pw.print("encryptionRequested=");
46122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                    pw.println(encryptionRequested);
4622447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            pw.print(prefix); pw.print("disableCamera=");
4632447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                    pw.println(disableCamera);
4647077b3c9bb7367bae3e073aa213de51baf3321a9Amith Yamasani            pw.print(prefix); pw.print("disabledKeyguardFeatures=");
4657077b3c9bb7367bae3e073aa213de51baf3321a9Amith Yamasani                    pw.println(disabledKeyguardFeatures);
46687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
46721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
4683255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
469599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void handlePackagesChanged(int userHandle) {
470599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        boolean removed = false;
471599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        Slog.d(TAG, "Handling package changes for user " + userHandle);
472599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        DevicePolicyData policy = getUserData(userHandle);
473599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        IPackageManager pm = AppGlobals.getPackageManager();
474599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        for (int i = policy.mAdminList.size() - 1; i >= 0; i--) {
475599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            ActiveAdmin aa = policy.mAdminList.get(i);
476599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            try {
477599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (pm.getPackageInfo(aa.info.getPackageName(), 0, userHandle) == null
478599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        || pm.getReceiverInfo(aa.info.getComponent(), 0, userHandle) == null) {
479599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    removed = true;
480599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mAdminList.remove(i);
48187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                }
482599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            } catch (RemoteException re) {
483599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                // Shouldn't happen
4848ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
4858ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
486599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (removed) {
487599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            validatePasswordOwnerLocked(policy);
488599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            syncDeviceCapabilitiesLocked(policy);
489599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            saveSettingsLocked(policy.mUserHandle);
490599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        }
491d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
4923255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
493d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    /**
494d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     * Instantiates the service.
495d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn     */
496d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public DevicePolicyManagerService(Context context) {
497d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext = context;
498424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn        mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE))
499424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn                .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
500a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        IntentFilter filter = new IntentFilter();
501a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
502a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION);
503599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        filter.addAction(Intent.ACTION_USER_REMOVED);
504599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        filter.addAction(Intent.ACTION_USER_STARTED);
505599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
506599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        filter = new IntentFilter();
507599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
508599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
509599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
510599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        filter.addDataScheme("package");
511599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
512599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    }
513599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
514599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    /**
515599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani     * Creates and loads the policy data from xml.
516599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani     * @param userHandle the user for whom to load the policy data
517599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani     * @return
518599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani     */
519599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    DevicePolicyData getUserData(int userHandle) {
520599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        synchronized (this) {
521599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = mUserData.get(userHandle);
522599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (policy == null) {
523599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                policy = new DevicePolicyData(userHandle);
524599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                mUserData.append(userHandle, policy);
525599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                loadSettingsLocked(policy, userHandle);
526599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            }
527599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            return policy;
528599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        }
529599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    }
530599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
531599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    void removeUserData(int userHandle) {
532599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        synchronized (this) {
533599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (userHandle == UserHandle.USER_OWNER) {
534599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                Slog.w(TAG, "Tried to remove device policy file for user 0! Ignoring.");
535599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                return;
536599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            }
537599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = mUserData.get(userHandle);
538599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (policy != null) {
539599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                mUserData.remove(userHandle);
540599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            }
541599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            File policyFile = new File(Environment.getUserSystemDirectory(userHandle),
542599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    DEVICE_POLICIES_XML);
543599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policyFile.delete();
544599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            Slog.i(TAG, "Removed device policy file " + policyFile.getAbsolutePath());
545599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        }
546a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
547a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
548043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler    /**
549043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration
550043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     * reminders.  Clears alarm if no expirations are configured.
551043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     */
552599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    protected void setExpirationAlarmCheckLocked(Context context, DevicePolicyData policy) {
553599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final long expiration = getPasswordExpirationLocked(null, policy.mUserHandle);
554a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        final long now = System.currentTimeMillis();
555a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        final long timeToExpire = expiration - now;
556a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        final long alarmTime;
557043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler        if (expiration == 0) {
558043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            // No expirations are currently configured:  Cancel alarm.
559043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            alarmTime = 0;
560043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler        } else if (timeToExpire <= 0) {
561043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            // The password has already expired:  Repeat every 24 hours.
562a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            alarmTime = now + MS_PER_DAY;
563043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler        } else {
564043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            // Selecting the next alarm time:  Roll forward to the next 24 hour multiple before
565043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            // the expiration time.
566043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            long alarmInterval = timeToExpire % MS_PER_DAY;
567043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            if (alarmInterval == 0) {
568043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler                alarmInterval = MS_PER_DAY;
569043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            }
570043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            alarmTime = now + alarmInterval;
571a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
572a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
5731f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler        long token = Binder.clearCallingIdentity();
5741f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler        try {
5751f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler            AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
576599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD,
5771f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler                    new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION),
578599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT,
579599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    new UserHandle(policy.mUserHandle));
5801f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler            am.cancel(pi);
581043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            if (alarmTime != 0) {
582043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler                am.set(AlarmManager.RTC, alarmTime, pi);
583043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            }
5841f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler        } finally {
5851f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler            Binder.restoreCallingIdentity(token);
5861f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler        }
587d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
588d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
589df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    private IPowerManager getIPowerManager() {
590df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        if (mIPowerManager == null) {
591df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            IBinder b = ServiceManager.getService(Context.POWER_SERVICE);
592df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            mIPowerManager = IPowerManager.Stub.asInterface(b);
593df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
594df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        return mIPowerManager;
595df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
5963255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
59793c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller    private IWindowManager getWindowManager() {
59893c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller        if (mIWindowManager == null) {
59993c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller            IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
60093c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller            mIWindowManager = IWindowManager.Stub.asInterface(b);
60193c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller        }
60293c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller        return mIWindowManager;
60393c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller    }
60493c518e4f8abd98f87cda1712b30a5a86cfa60ddJim Miller
605599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) {
606599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who);
6078ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        if (admin != null
6088ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                && who.getPackageName().equals(admin.info.getActivityInfo().packageName)
6098ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                && who.getClassName().equals(admin.info.getActivityInfo().name)) {
6108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            return admin;
6118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
6128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        return null;
6138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
6143255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
615254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn    ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy)
6168aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            throws SecurityException {
617254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        final int callingUid = Binder.getCallingUid();
618599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final int userHandle = UserHandle.getUserId(callingUid);
619599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final DevicePolicyData policy = getUserData(userHandle);
620254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        if (who != null) {
621599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            ActiveAdmin admin = policy.mAdminMap.get(who);
622254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (admin == null) {
623254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("No active admin " + who);
624254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
625254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (admin.getUid() != callingUid) {
626254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("Admin " + who + " is not owned by uid "
627254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + Binder.getCallingUid());
628254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
629254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (!admin.info.usesPolicy(reqPolicy)) {
630254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                throw new SecurityException("Admin " + admin.info.getComponent()
631254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + " did not specify uses-policy for: "
632254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                        + admin.info.getTagForPolicy(reqPolicy));
633d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
634d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return admin;
635254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn        } else {
636599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
637254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            for (int i=0; i<N; i++) {
638599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
639254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) {
640254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    return admin;
641254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                }
642254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
643254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            throw new SecurityException("No active admin owned by uid "
644254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                    + Binder.getCallingUid() + " for policy #" + reqPolicy);
645d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
6468ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
6473255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
6488aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn    void sendAdminCommandLocked(ActiveAdmin admin, String action) {
649d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        sendAdminCommandLocked(admin, action, null);
650d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn    }
651d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn
652d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn    void sendAdminCommandLocked(ActiveAdmin admin, String action, BroadcastReceiver result) {
653d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        Intent intent = new Intent(action);
6548aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn        intent.setComponent(admin.info.getComponent());
655a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) {
656a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            intent.putExtra("expiration", admin.passwordExpirationDate);
657a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
658d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        if (result != null) {
659599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            mContext.sendOrderedBroadcastAsUser(intent, admin.getUserHandle(),
6605ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn                    null, result, mHandler, Activity.RESULT_OK, null, null);
661d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        } else {
6625ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn            mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
663d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn        }
664d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
6653255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
666599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    void sendAdminCommandLocked(String action, int reqPolicy, int userHandle) {
667599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final DevicePolicyData policy = getUserData(userHandle);
668599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final int count = policy.mAdminList.size();
669599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (count > 0) {
670599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            for (int i = 0; i < count; i++) {
671599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
672d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (admin.info.usesPolicy(reqPolicy)) {
673d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    sendAdminCommandLocked(admin, action);
674d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
6758aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            }
6764141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn        }
6774141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn    }
6783255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
679599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    void removeActiveAdminLocked(final ComponentName adminReceiver, int userHandle) {
680599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
681d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        if (admin != null) {
682d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            sendAdminCommandLocked(admin,
683d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                    DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED,
684d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                    new BroadcastReceiver() {
685d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                        @Override
686d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                        public void onReceive(Context context, Intent intent) {
6872fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn                            synchronized (DevicePolicyManagerService.this) {
688599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                int userHandle = admin.getUserHandle().getIdentifier();
689599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                DevicePolicyData policy = getUserData(userHandle);
690d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                                boolean doProxyCleanup = admin.info.usesPolicy(
691d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                                        DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
692599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                policy.mAdminList.remove(admin);
693599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                policy.mAdminMap.remove(adminReceiver);
694599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                validatePasswordOwnerLocked(policy);
695599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                syncDeviceCapabilitiesLocked(policy);
696d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                                if (doProxyCleanup) {
697599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                    resetGlobalProxyLocked(getUserData(userHandle));
698d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                                }
699599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                saveSettingsLocked(userHandle);
700599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                updateMaximumTimeToLockLocked(policy);
701d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                            }
702d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn                        }
703d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn            });
704d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
705d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
7063255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
707599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle) {
708599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
709d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        Intent resolveIntent = new Intent();
710d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        resolveIntent.setComponent(adminName);
711d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers(
712599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                resolveIntent, PackageManager.GET_META_DATA, userHandle);
713d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (infos == null || infos.size() <= 0) {
714d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            throw new IllegalArgumentException("Unknown admin: " + adminName);
715d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
7163255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
717d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
718d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return new DeviceAdminInfo(mContext, infos.get(0));
719d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (XmlPullParserException e) {
720599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e);
721d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return null;
722d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
723599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e);
724d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            return null;
725d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
726d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
7273255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
728599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private static JournaledFile makeJournaledFile(int userHandle) {
729599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final String base = userHandle == 0
730599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ? "/data/system/" + DEVICE_POLICIES_XML
731599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                : new File(Environment.getUserSystemDirectory(userHandle), DEVICE_POLICIES_XML)
732599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        .getAbsolutePath();
733d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        return new JournaledFile(new File(base), new File(base + ".tmp"));
734d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
735d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
736599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void saveSettingsLocked(int userHandle) {
737599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        DevicePolicyData policy = getUserData(userHandle);
738599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        JournaledFile journal = makeJournaledFile(userHandle);
739d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        FileOutputStream stream = null;
740d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
741d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream = new FileOutputStream(journal.chooseForWrite(), false);
742d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            XmlSerializer out = new FastXmlSerializer();
743d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.setOutput(stream, "utf-8");
744d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.startDocument(null, true);
745d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
746d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.startTag(null, "policies");
7473255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
748599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
749d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for (int i=0; i<N; i++) {
750599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin ap = policy.mAdminList.get(i);
751d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (ap != null) {
752d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.startTag(null, "admin");
753d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.attribute(null, "name", ap.info.getComponent().flattenToString());
754d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    ap.writeToXml(out);
755d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    out.endTag(null, "admin");
756d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
757d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
7583255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
759599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (policy.mPasswordOwner >= 0) {
76087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                out.startTag(null, "password-owner");
761599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "value", Integer.toString(policy.mPasswordOwner));
76287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                out.endTag(null, "password-owner");
76387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
7643255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
765599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (policy.mFailedPasswordAttempts != 0) {
7668ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.startTag(null, "failed-password-attempts");
767599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "value", Integer.toString(policy.mFailedPasswordAttempts));
7688ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                out.endTag(null, "failed-password-attempts");
7698ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
7703255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
771599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (policy.mActivePasswordQuality != 0 || policy.mActivePasswordLength != 0
772599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || policy.mActivePasswordUpperCase != 0 || policy.mActivePasswordLowerCase != 0
773599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || policy.mActivePasswordLetters != 0 || policy.mActivePasswordNumeric != 0
774599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || policy.mActivePasswordSymbols != 0 || policy.mActivePasswordNonLetter != 0) {
77585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                out.startTag(null, "active-password");
776599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "quality", Integer.toString(policy.mActivePasswordQuality));
777599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "length", Integer.toString(policy.mActivePasswordLength));
778599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "uppercase", Integer.toString(policy.mActivePasswordUpperCase));
779599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "lowercase", Integer.toString(policy.mActivePasswordLowerCase));
780599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "letters", Integer.toString(policy.mActivePasswordLetters));
781a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                out.attribute(null, "numeric", Integer
782599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        .toString(policy.mActivePasswordNumeric));
783599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "symbols", Integer.toString(policy.mActivePasswordSymbols));
784599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                out.attribute(null, "nonletter", Integer.toString(policy.mActivePasswordNonLetter));
78585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                out.endTag(null, "active-password");
78685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            }
7873255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
78885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            out.endTag(null, "policies");
78985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn
790d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            out.endDocument();
791d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream.close();
792d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            journal.commit();
793599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            sendChangedNotification(userHandle);
794d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
795d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
796d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                if (stream != null) {
797d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    stream.close();
798d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
799d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } catch (IOException ex) {
800d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                // Ignore
801d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
802d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            journal.rollback();
803d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
804d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
805d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
806599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void sendChangedNotification(int userHandle) {
807284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller        Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
808284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller        intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
809b7a685978f3ea8a1514166c6986c1f1bacedab4aAmith Yamasani        long ident = Binder.clearCallingIdentity();
810b7a685978f3ea8a1514166c6986c1f1bacedab4aAmith Yamasani        try {
811599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle));
812b7a685978f3ea8a1514166c6986c1f1bacedab4aAmith Yamasani        } finally {
813b7a685978f3ea8a1514166c6986c1f1bacedab4aAmith Yamasani            Binder.restoreCallingIdentity(ident);
814b7a685978f3ea8a1514166c6986c1f1bacedab4aAmith Yamasani        }
815284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller    }
816284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller
817599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void loadSettingsLocked(DevicePolicyData policy, int userHandle) {
818599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        JournaledFile journal = makeJournaledFile(userHandle);
819d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        FileInputStream stream = null;
820d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        File file = journal.chooseForRead();
821d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
822d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            stream = new FileInputStream(file);
823d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            XmlPullParser parser = Xml.newPullParser();
824d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            parser.setInput(stream, null);
825d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
8268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int type;
8278ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
8288ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    && type != XmlPullParser.START_TAG) {
829d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
830d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            String tag = parser.getName();
8318ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (!"policies".equals(tag)) {
8328ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                throw new XmlPullParserException(
8338ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                        "Settings do not start with policies tag: found " + tag);
8348ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
8358ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            type = parser.next();
8368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            int outerDepth = parser.getDepth();
8378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
8388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                   && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
8398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
8408ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    continue;
8418ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
8428ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                tag = parser.getName();
8438ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                if ("admin".equals(tag)) {
844e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    String name = parser.getAttributeValue(null, "name");
845e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    try {
846e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        DeviceAdminInfo dai = findAdmin(
847599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                ComponentName.unflattenFromString(name), userHandle);
848599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        if (DBG && (UserHandle.getUserId(dai.getActivityInfo().applicationInfo.uid)
849599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                != userHandle)) {
850599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                            Slog.w(TAG, "findAdmin returned an incorrect uid "
851599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                    + dai.getActivityInfo().applicationInfo.uid + " for user "
852599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                    + userHandle);
853599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        }
854e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        if (dai != null) {
855e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            ActiveAdmin ap = new ActiveAdmin(dai);
856e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                            ap.readFromXml(parser);
857599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                            policy.mAdminMap.put(ap.info.getComponent(), ap);
858599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                            policy.mAdminList.add(ap);
859e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                        }
860e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                    } catch (RuntimeException e) {
86185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                        Slog.w(TAG, "Failed loading admin " + name, e);
862d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    }
8638ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } else if ("failed-password-attempts".equals(tag)) {
864599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mFailedPasswordAttempts = Integer.parseInt(
8658ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                            parser.getAttributeValue(null, "value"));
86621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    XmlUtils.skipCurrentTag(parser);
86787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                } else if ("password-owner".equals(tag)) {
868599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mPasswordOwner = Integer.parseInt(
86987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                            parser.getAttributeValue(null, "value"));
87087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    XmlUtils.skipCurrentTag(parser);
87185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                } else if ("active-password".equals(tag)) {
872599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mActivePasswordQuality = Integer.parseInt(
87385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            parser.getAttributeValue(null, "quality"));
874599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mActivePasswordLength = Integer.parseInt(
87585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            parser.getAttributeValue(null, "length"));
876599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mActivePasswordUpperCase = Integer.parseInt(
877a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "uppercase"));
878599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mActivePasswordLowerCase = Integer.parseInt(
879a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "lowercase"));
880599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mActivePasswordLetters = Integer.parseInt(
881a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "letters"));
882599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mActivePasswordNumeric = Integer.parseInt(
883a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "numeric"));
884599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mActivePasswordSymbols = Integer.parseInt(
885a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            parser.getAttributeValue(null, "symbols"));
886599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mActivePasswordNonLetter = Integer.parseInt(
887c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                            parser.getAttributeValue(null, "nonletter"));
88885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    XmlUtils.skipCurrentTag(parser);
88921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                } else {
89085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    Slog.w(TAG, "Unknown tag: " + tag);
89121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    XmlUtils.skipCurrentTag(parser);
8928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
893d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
894d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (NullPointerException e) {
89585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
896d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (NumberFormatException e) {
89785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
898d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (XmlPullParserException e) {
89985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
900cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn        } catch (FileNotFoundException e) {
901cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn            // Don't be noisy, this is normal if we haven't defined any policies.
902d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
90385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
904d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IndexOutOfBoundsException e) {
90585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "failed parsing " + file + " " + e);
906d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
907d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        try {
908d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (stream != null) {
909d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                stream.close();
910d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
911d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        } catch (IOException e) {
912d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // Ignore
913d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
914d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
91585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        // Validate that what we stored for the password quality matches
91685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        // sufficiently what is currently set.  Note that this is only
91785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        // a sanity check in case the two get out of sync; this should
91885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        // never normally happen.
91985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        LockPatternUtils utils = new LockPatternUtils(mContext);
920599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (utils.getActivePasswordQuality() < policy.mActivePasswordQuality) {
92185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "Active password quality 0x"
922599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    + Integer.toHexString(policy.mActivePasswordQuality)
92385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    + " does not match actual quality 0x"
92485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    + Integer.toHexString(utils.getActivePasswordQuality()));
925599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
926599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mActivePasswordLength = 0;
927599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mActivePasswordUpperCase = 0;
928599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mActivePasswordLowerCase = 0;
929599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mActivePasswordLetters = 0;
930599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mActivePasswordNumeric = 0;
931599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mActivePasswordSymbols = 0;
932599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mActivePasswordNonLetter = 0;
93385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        }
9343255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
935599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        validatePasswordOwnerLocked(policy);
936599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        syncDeviceCapabilitiesLocked(policy);
937599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        updateMaximumTimeToLockLocked(policy);
938d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
939d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn
94085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn    static void validateQualityConstant(int quality) {
94185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        switch (quality) {
94285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
943de7a2f30548ac64d67e9ce8ac08090eb5458449dDanielle Millett            case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
94485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
94585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
94685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
94785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
948a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
94985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                return;
95085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        }
95185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        throw new IllegalArgumentException("Invalid quality constant: 0x"
95285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                + Integer.toHexString(quality));
95385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn    }
9543255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
955599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    void validatePasswordOwnerLocked(DevicePolicyData policy) {
956599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (policy.mPasswordOwner >= 0) {
95787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            boolean haveOwner = false;
958599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            for (int i = policy.mAdminList.size() - 1; i >= 0; i--) {
959599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (policy.mAdminList.get(i).getUid() == policy.mPasswordOwner) {
96087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    haveOwner = true;
96187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    break;
96287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                }
96387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
96487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            if (!haveOwner) {
965599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                Slog.w(TAG, "Previous password owner " + policy.mPasswordOwner
96687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                        + " no longer active; disabling");
967599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                policy.mPasswordOwner = -1;
96887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
96987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
97087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    }
9713255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
9722447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo    /**
9732447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     * Pushes down policy information to the system for any policies related to general device
9742447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     * capabilities that need to be enforced by lower level services (e.g. Camera services).
9752447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     */
976599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    void syncDeviceCapabilitiesLocked(DevicePolicyData policy) {
9772447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        // Ensure the status of the camera is synced down to the system. Interested native services
9782447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        // should monitor this value and act accordingly.
9792447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        boolean systemState = SystemProperties.getBoolean(SYSTEM_PROP_DISABLE_CAMERA, false);
980599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        boolean cameraDisabled = getCameraDisabled(null, policy.mUserHandle);
9812447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        if (cameraDisabled != systemState) {
9822447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            long token = Binder.clearCallingIdentity();
9832447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            try {
9842447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                String value = cameraDisabled ? "1" : "0";
9852447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                Slog.v(TAG, "Change in camera state ["
9862447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                        + SYSTEM_PROP_DISABLE_CAMERA + "] = " + value);
9872447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value);
9882447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            } finally {
9892447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                Binder.restoreCallingIdentity(token);
9902447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            }
9912447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        }
9922447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo    }
9932447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo
994d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    public void systemReady() {
995d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
996599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER);
997d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
998d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
9993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1000599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void handlePasswordExpirationNotification(DevicePolicyData policy) {
1001a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        synchronized (this) {
1002a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            final long now = System.currentTimeMillis();
1003599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1004a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            if (N <= 0) {
1005a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                return;
1006a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
1007a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            for (int i=0; i < N; i++) {
1008599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1009a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)
1010a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                        && admin.passwordExpirationTimeout > 0L
1011a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                        && admin.passwordExpirationDate > 0L
1012043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler                        && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS) {
1013a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING);
1014a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                }
1015a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
1016599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            setExpirationAlarmCheckLocked(mContext, policy);
1017a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
1018a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
1019a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1020c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler    /**
1021c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler     * @param adminReceiver The admin to add
1022c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler     * @param refreshing true = update an active admin, no error
1023c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler     */
1024599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle) {
1025d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
1026d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
1027599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
10283255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1029599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        DevicePolicyData policy = getUserData(userHandle);
1030599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        DeviceAdminInfo info = findAdmin(adminReceiver, userHandle);
1031d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        if (info == null) {
1032d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            throw new IllegalArgumentException("Bad admin: " + adminReceiver);
1033d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1034d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1035d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
1036d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
1037599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (!refreshing && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) {
1038d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    throw new IllegalArgumentException("Admin is already added");
1039d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
1040c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                ActiveAdmin newAdmin = new ActiveAdmin(info);
1041599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                policy.mAdminMap.put(adminReceiver, newAdmin);
1042c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                int replaceIndex = -1;
1043c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                if (refreshing) {
1044599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    final int N = policy.mAdminList.size();
1045c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                    for (int i=0; i < N; i++) {
1046599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        ActiveAdmin oldAdmin = policy.mAdminList.get(i);
1047c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                        if (oldAdmin.info.getComponent().equals(adminReceiver)) {
1048c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                            replaceIndex = i;
1049c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                            break;
1050c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                        }
1051c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                    }
1052c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                }
1053c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                if (replaceIndex == -1) {
1054599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mAdminList.add(newAdmin);
1055c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                } else {
1056599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mAdminList.set(replaceIndex, newAdmin);
1057c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                }
1058599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1059c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED);
1060d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
1061d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
1062d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1063d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1064d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
10653255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1066599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public boolean isAdminActive(ComponentName adminReceiver, int userHandle) {
1067599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1068d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        synchronized (this) {
1069599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null;
1070d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn        }
1071d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn    }
10723255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1073599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public boolean hasGrantedPolicy(ComponentName adminReceiver, int policyId, int userHandle) {
1074599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1075c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler        synchronized (this) {
1076599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
1077c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler            if (administrator == null) {
1078c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler                throw new SecurityException("No active admin " + adminReceiver);
1079c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler            }
1080c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler            return administrator.info.usesPolicy(policyId);
1081c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler        }
1082c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler    }
1083c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler
1084599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public List<ComponentName> getActiveAdmins(int userHandle) {
1085599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1086d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1087599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1088599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1089d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (N <= 0) {
1090d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                return null;
1091d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1092d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            ArrayList<ComponentName> res = new ArrayList<ComponentName>(N);
1093d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for (int i=0; i<N; i++) {
1094599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                res.add(policy.mAdminList.get(i).info.getComponent());
1095d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1096d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return res;
1097d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1098d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
10993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1100599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public boolean packageHasActiveAdmins(String packageName, int userHandle) {
1101599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
110221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        synchronized (this) {
1103599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1104599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
110521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            for (int i=0; i<N; i++) {
1106599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (policy.mAdminList.get(i).info.getPackageName().equals(packageName)) {
110721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    return true;
110821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
110921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
111021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            return false;
111121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
111221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
11133255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1114599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
1115599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1116d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1117599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
1118d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (admin == null) {
1119d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                return;
1120d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1121d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            if (admin.getUid() != Binder.getCallingUid()) {
1122d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                mContext.enforceCallingOrSelfPermission(
1123d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                        android.Manifest.permission.BIND_DEVICE_ADMIN, null);
1124d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1125d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
1126d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
1127599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                removeActiveAdminLocked(adminReceiver, userHandle);
1128d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
1129d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
1130d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1131d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1132d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
11333255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1134599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordQuality(ComponentName who, int quality, int userHandle) {
113585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        validateQualityConstant(quality);
1136599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
11373255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1138d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1139d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
1140d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
1141d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
11428aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
11438aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
114485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            if (ap.passwordQuality != quality) {
114585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                ap.passwordQuality = quality;
1146599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1147d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1148d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1149d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
11503255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1151599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordQuality(ComponentName who, int userHandle) {
1152599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1153d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
11549327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
1155599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
11563255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1157254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
1158599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
11599327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                return admin != null ? admin.passwordQuality : mode;
1160254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
11613255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1162599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1163d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
1164599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
11659327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                if (mode < admin.passwordQuality) {
11669327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    mode = admin.passwordQuality;
1167d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
1168d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1169d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return mode;
1170d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1171d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
11723255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1173599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordMinimumLength(ComponentName who, int length, int userHandle) {
1174599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1175d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1176d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
1177d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
1178d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
11798aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
11808aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1181d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (ap.minimumPasswordLength != length) {
1182d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                ap.minimumPasswordLength = length;
1183599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1184d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1185d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1186d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
11873255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1188599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordMinimumLength(ComponentName who, int userHandle) {
1189599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1190d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1191599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1192d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            int length = 0;
11933255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1194254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
1195599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1196254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.minimumPasswordLength : length;
1197254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
11983255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1199599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1200d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
1201599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1202d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (length < admin.minimumPasswordLength) {
1203d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    length = admin.minimumPasswordLength;
1204d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
1205d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1206d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return length;
1207d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1208d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
12093255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1210599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordHistoryLength(ComponentName who, int length, int userHandle) {
1211599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
12123255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        synchronized (this) {
12133255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            if (who == null) {
12143255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
12153255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            }
12163255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
12173255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
12183255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            if (ap.passwordHistoryLength != length) {
12193255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                ap.passwordHistoryLength = length;
1220599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
12213255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            }
12223255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        }
12233255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev    }
12243255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1225599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordHistoryLength(ComponentName who, int userHandle) {
1226599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
12273255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        synchronized (this) {
1228599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
12293255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            int length = 0;
12303255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
12313255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            if (who != null) {
1232599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
12333255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                return admin != null ? admin.passwordHistoryLength : length;
12343255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            }
12353255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1236599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
12373255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            for (int i = 0; i < N; i++) {
1238599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
12393255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                if (length < admin.passwordHistoryLength) {
12403255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                    length = admin.passwordHistoryLength;
12413255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev                }
12423255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            }
12433255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev            return length;
12443255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev        }
12453255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev    }
12463255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1247599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordExpirationTimeout(ComponentName who, long timeout, int userHandle) {
1248599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1249a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        synchronized (this) {
1250a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            if (who == null) {
1251a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                throw new NullPointerException("ComponentName is null");
1252a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
12531f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler            if (timeout < 0) {
12541f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler                throw new IllegalArgumentException("Timeout must be >= 0 ms");
1255a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
1256a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1257a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD);
1258a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            // Calling this API automatically bumps the expiration date
1259a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
1260a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            ap.passwordExpirationDate = expiration;
1261a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            ap.passwordExpirationTimeout = timeout;
1262a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            if (timeout > 0L) {
1263a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                Slog.w(TAG, "setPasswordExpiration(): password will expire on "
1264a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                        + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT)
1265a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                        .format(new Date(expiration)));
1266a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
1267599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            saveSettingsLocked(userHandle);
1268599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            // in case this is the first one
1269599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            setExpirationAlarmCheckLocked(mContext, getUserData(userHandle));
1270a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
1271a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
1272a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1273043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler    /**
1274043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     * Return a single admin's expiration cycle time, or the min of all cycle times.
1275043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     * Returns 0 if not configured.
1276043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     */
1277599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public long getPasswordExpirationTimeout(ComponentName who, int userHandle) {
1278599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1279a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        synchronized (this) {
1280a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            if (who != null) {
1281599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1282043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler                return admin != null ? admin.passwordExpirationTimeout : 0L;
1283a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
1284a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1285043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            long timeout = 0L;
1286599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1287599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1288a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            for (int i = 0; i < N; i++) {
1289599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1290a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                if (timeout == 0L || (admin.passwordExpirationTimeout != 0L
1291a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                        && timeout > admin.passwordExpirationTimeout)) {
1292a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    timeout = admin.passwordExpirationTimeout;
1293a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                }
1294a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
1295a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            return timeout;
1296a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
1297a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
1298a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1299043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler    /**
1300043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     * Return a single admin's expiration date/time, or the min (soonest) for all admins.
1301043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     * Returns 0 if not configured.
1302043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     */
1303599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private long getPasswordExpirationLocked(ComponentName who, int userHandle) {
1304a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        if (who != null) {
1305599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1306043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler            return admin != null ? admin.passwordExpirationDate : 0L;
1307a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
1308a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1309043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler        long timeout = 0L;
1310599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        DevicePolicyData policy = getUserData(userHandle);
1311599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final int N = policy.mAdminList.size();
1312a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        for (int i = 0; i < N; i++) {
1313599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            ActiveAdmin admin = policy.mAdminList.get(i);
1314a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            if (timeout == 0L || (admin.passwordExpirationDate != 0
1315a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                    && timeout > admin.passwordExpirationDate)) {
1316a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                timeout = admin.passwordExpirationDate;
1317a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
1318a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
1319a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        return timeout;
1320a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
1321a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1322599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public long getPasswordExpiration(ComponentName who, int userHandle) {
1323599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1324a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        synchronized (this) {
1325599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            return getPasswordExpirationLocked(who, userHandle);
1326a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
1327a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
1328a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1329599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordMinimumUpperCase(ComponentName who, int length, int userHandle) {
1330599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1331a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1332a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
1333a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
1334a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1335a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1336a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1337a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordUpperCase != length) {
1338a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordUpperCase = length;
1339599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1340a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1341a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1342a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1343a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1344599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordMinimumUpperCase(ComponentName who, int userHandle) {
1345599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1346a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1347a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
1348a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1349a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
1350599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1351a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordUpperCase : length;
1352a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1353a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1354599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1355599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1356a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for (int i=0; i<N; i++) {
1357599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1358a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordUpperCase) {
1359a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordUpperCase;
1360a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1361a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1362a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
1363a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1364a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1365a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1366599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordMinimumLowerCase(ComponentName who, int length, int userHandle) {
1367599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1368a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1369a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
1370a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
1371a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1372a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1373a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1374a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordLowerCase != length) {
1375a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordLowerCase = length;
1376599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1377a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1378a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1379a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1380a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1381599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordMinimumLowerCase(ComponentName who, int userHandle) {
1382599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1383a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1384a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
1385a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1386a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
1387599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1388a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordLowerCase : length;
1389a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1390a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1391599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1392599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1393a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for (int i=0; i<N; i++) {
1394599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1395a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordLowerCase) {
1396a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordLowerCase;
1397a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1398a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1399a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
1400a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1401a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1402a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1403599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordMinimumLetters(ComponentName who, int length, int userHandle) {
1404599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1405a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1406a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
1407a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
1408a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1409a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1410a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1411a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordLetters != length) {
1412a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordLetters = length;
1413599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1414a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1415a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1416a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1417a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1418599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordMinimumLetters(ComponentName who, int userHandle) {
1419599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1420a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1421a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
1422a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1423a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
1424599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1425a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordLetters : length;
1426a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1427a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1428599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1429599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1430a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for (int i=0; i<N; i++) {
1431599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1432a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordLetters) {
1433a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordLetters;
1434a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1435a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1436a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
1437a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1438a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1439a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1440599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordMinimumNumeric(ComponentName who, int length, int userHandle) {
1441599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1442a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1443a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
1444a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
1445a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1446a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1447a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1448a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordNumeric != length) {
1449a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordNumeric = length;
1450599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1451a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1452a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1453a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1454a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1455599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordMinimumNumeric(ComponentName who, int userHandle) {
1456599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1457a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1458a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
1459a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1460a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
1461599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1462a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordNumeric : length;
1463a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1464a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1465599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1466599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1467a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for (int i = 0; i < N; i++) {
1468599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1469a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordNumeric) {
1470a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordNumeric;
1471a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1472a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1473a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
1474a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1475a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1476a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1477599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordMinimumSymbols(ComponentName who, int length, int userHandle) {
1478599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1479a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1480a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who == null) {
1481a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
1482a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1483a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1484a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1485a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (ap.minimumPasswordSymbols != length) {
1486a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                ap.minimumPasswordSymbols = length;
1487599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1488a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1489a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1490a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1491a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1492599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordMinimumSymbols(ComponentName who, int userHandle) {
1493599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1494a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        synchronized (this) {
1495a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            int length = 0;
1496a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1497a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (who != null) {
1498599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1499a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return admin != null ? admin.minimumPasswordSymbols : length;
1500a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1501a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1502599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1503599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1504a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            for  (int i=0; i<N; i++) {
1505599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1506a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (length < admin.minimumPasswordSymbols) {
1507a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    length = admin.minimumPasswordSymbols;
1508a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1509a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1510a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            return length;
1511a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev        }
1512a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    }
1513a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev
1514599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setPasswordMinimumNonLetter(ComponentName who, int length, int userHandle) {
1515599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1516c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        synchronized (this) {
1517c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            if (who == null) {
1518c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                throw new NullPointerException("ComponentName is null");
1519c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            }
1520c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1521c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1522c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            if (ap.minimumPasswordNonLetter != length) {
1523c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                ap.minimumPasswordNonLetter = length;
1524599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1525c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            }
1526c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        }
1527c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev    }
1528c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev
1529599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getPasswordMinimumNonLetter(ComponentName who, int userHandle) {
1530599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1531c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        synchronized (this) {
1532c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            int length = 0;
1533c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev
1534c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            if (who != null) {
1535599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1536c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                return admin != null ? admin.minimumPasswordNonLetter : length;
1537c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            }
1538c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev
1539599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1540599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1541c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            for (int i=0; i<N; i++) {
1542599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1543c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                if (length < admin.minimumPasswordNonLetter) {
1544c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    length = admin.minimumPasswordNonLetter;
1545c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                }
1546c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            }
1547c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev            return length;
1548c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev        }
1549c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev    }
1550c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev
1551599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public boolean isActivePasswordSufficient(int userHandle) {
1552599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1553d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1554599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1555d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
1556d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
15578aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
15588aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1559599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (policy.mActivePasswordQuality < getPasswordQuality(null, userHandle)
1560599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) {
1561a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return false;
1562a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1563599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (policy.mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
1564a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                return true;
1565a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1566599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null, userHandle)
1567599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle)
1568599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle)
1569599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle)
1570599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle)
1571599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle);
1572d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1573d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
15743255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1575599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getCurrentFailedPasswordAttempts(int userHandle) {
1576599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1577d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1578d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
1579d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
15808aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
15818aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
1582599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            return getUserData(userHandle).mFailedPasswordAttempts;
1583d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1584d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
15853255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1586599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, int userHandle) {
1587599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
15888ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
15898ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            // This API can only be called by an active device admin,
15908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            // so try to retrieve it to check that the caller is one.
15918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            getActiveAdminForCallerLocked(who,
15928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
15938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
15948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
15958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (ap.maximumFailedPasswordsForWipe != num) {
15968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                ap.maximumFailedPasswordsForWipe = num;
1597599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
15988ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
15998ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
16008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
16013255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1602599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) {
1603599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
16048ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
1605599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1606d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            int count = 0;
16073255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1608254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
1609599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1610254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.maximumFailedPasswordsForWipe : count;
1611254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
16123255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1613599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1614d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
1615599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1616d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (count == 0) {
1617d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    count = admin.maximumFailedPasswordsForWipe;
1618d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                } else if (admin.maximumFailedPasswordsForWipe != 0
1619d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                        && count > admin.maximumFailedPasswordsForWipe) {
1620d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    count = admin.maximumFailedPasswordsForWipe;
1621d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
1622d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1623d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return count;
16248ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
16258ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
16263255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1627599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public boolean resetPassword(String password, int flags, int userHandle) {
1628599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
16299327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn        int quality;
1630df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        synchronized (this) {
1631df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // This API can only be called by an active device admin,
1632df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // so try to retrieve it to check that the caller is one.
16338aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
16348aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_RESET_PASSWORD);
1635599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            quality = getPasswordQuality(null, userHandle);
16369327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
163785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                int realQuality = LockPatternUtils.computePasswordQuality(password);
1638a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (realQuality < quality
1639a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
164085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                    Slog.w(TAG, "resetPassword: password quality 0x"
164185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            + Integer.toHexString(quality)
164285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            + " does not meet required quality 0x"
164385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                            + Integer.toHexString(quality));
16449327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                    return false;
16459327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn                }
1646a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                quality = Math.max(realQuality, quality);
16479327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            }
1648599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            int length = getPasswordMinimumLength(null, userHandle);
16499327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn            if (password.length() < length) {
165085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                Slog.w(TAG, "resetPassword: password length " + password.length()
165185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                        + " does not meet required length " + length);
1652df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn                return false;
1653df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            }
1654a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
1655a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int letters = 0;
1656a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int uppercase = 0;
1657a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int lowercase = 0;
1658a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int numbers = 0;
1659a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                int symbols = 0;
1660c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                int nonletter = 0;
1661a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                for (int i = 0; i < password.length(); i++) {
1662a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    char c = password.charAt(i);
1663a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    if (c >= 'A' && c <= 'Z') {
1664a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        letters++;
1665a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        uppercase++;
1666a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    } else if (c >= 'a' && c <= 'z') {
1667a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        letters++;
1668a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        lowercase++;
1669a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    } else if (c >= '0' && c <= '9') {
1670a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        numbers++;
1671c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                        nonletter++;
1672a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    } else {
1673a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                        symbols++;
1674c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                        nonletter++;
1675a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    }
1676a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1677599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                int neededLetters = getPasswordMinimumLetters(null, userHandle);
1678a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if(letters < neededLetters) {
1679a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of letters " + letters
1680a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + " does not meet required number of letters " + neededLetters);
1681a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1682a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1683599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                int neededNumbers = getPasswordMinimumNumeric(null, userHandle);
1684a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (numbers < neededNumbers) {
1685a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog
1686a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            .w(TAG, "resetPassword: number of numerical digits " + numbers
1687a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                                    + " does not meet required number of numerical digits "
1688a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                                    + neededNumbers);
1689a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1690a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1691599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                int neededLowerCase = getPasswordMinimumLowerCase(null, userHandle);
1692a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (lowercase < neededLowerCase) {
1693a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase
1694a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + " does not meet required number of lowercase letters "
1695a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + neededLowerCase);
1696a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1697a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1698599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                int neededUpperCase = getPasswordMinimumUpperCase(null, userHandle);
1699a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (uppercase < neededUpperCase) {
1700a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase
1701a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + " does not meet required number of uppercase letters "
1702a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + neededUpperCase);
1703a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1704a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1705599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                int neededSymbols = getPasswordMinimumSymbols(null, userHandle);
1706a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                if (symbols < neededSymbols) {
1707a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of special symbols " + symbols
1708a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                            + " does not meet required number of special symbols " + neededSymbols);
1709a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                    return false;
1710a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                }
1711599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                int neededNonLetter = getPasswordMinimumNonLetter(null, userHandle);
1712c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                if (nonletter < neededNonLetter) {
1713c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    Slog.w(TAG, "resetPassword: number of non-letter characters " + nonletter
1714c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                            + " does not meet required number of non-letter characters "
1715c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                            + neededNonLetter);
1716c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                    return false;
1717c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev                }
1718a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev            }
1719df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
17203255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
172187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        int callingUid = Binder.getCallingUid();
1722599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        DevicePolicyData policy = getUserData(userHandle);
1723599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (policy.mPasswordOwner >= 0 && policy.mPasswordOwner != callingUid) {
172485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            Slog.w(TAG, "resetPassword: already set by another uid and not entered by user");
172587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            return false;
172687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
17273255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1728df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        // Don't do this with the lock held, because it is going to call
1729df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        // back in to the service.
1730df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        long ident = Binder.clearCallingIdentity();
1731df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        try {
1732df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            LockPatternUtils utils = new LockPatternUtils(mContext);
1733599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            utils.saveLockPassword(password, quality, false, userHandle);
173485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn            synchronized (this) {
173585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                int newOwner = (flags&DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY)
173685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                        != 0 ? callingUid : -1;
1737599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (policy.mPasswordOwner != newOwner) {
1738599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mPasswordOwner = newOwner;
1739599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    saveSettingsLocked(userHandle);
174085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn                }
174187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            }
1742df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        } finally {
1743df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            Binder.restoreCallingIdentity(ident);
1744df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
17453255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1746df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        return true;
1747df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
17483255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1749599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setMaximumTimeToLock(ComponentName who, long timeMs, int userHandle) {
1750599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1751d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1752d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (who == null) {
1753d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                throw new NullPointerException("ComponentName is null");
1754d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
17558aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1756315ada7fbb9e967c22e87b4921bec720ceb2c73cDianne Hackborn                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
1757d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            if (ap.maximumTimeToUnlock != timeMs) {
1758d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                ap.maximumTimeToUnlock = timeMs;
1759599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1760599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                updateMaximumTimeToLockLocked(getUserData(userHandle));
17612fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn            }
17622fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn        }
17632fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn    }
17643255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1765599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    void updateMaximumTimeToLockLocked(DevicePolicyData policy) {
1766599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        long timeMs = getMaximumTimeToLock(null, policy.mUserHandle);
1767599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (policy.mLastMaximumTimeToLock == timeMs) {
17682fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn            return;
17692fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn        }
17703255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
17712fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn        long ident = Binder.clearCallingIdentity();
17722fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn        try {
17732fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn            if (timeMs <= 0) {
17742fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn                timeMs = Integer.MAX_VALUE;
17752fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn            } else {
17762fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn                // Make sure KEEP_SCREEN_ON is disabled, since that
17772fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn                // would allow bypassing of the maximum time to lock.
177862df6eb5081fbb66d9245626e8c91497431040e4Christopher Tate                Settings.Global.putInt(mContext.getContentResolver(),
177962df6eb5081fbb66d9245626e8c91497431040e4Christopher Tate                        Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
17802fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn            }
17813255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1782599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            policy.mLastMaximumTimeToLock = timeMs;
17832fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn
17842fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn            try {
17859630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
17862fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn            } catch (RemoteException e) {
17872fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn                Slog.w(TAG, "Failure talking with power manager", e);
1788d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
17892fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn        } finally {
17902fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn            Binder.restoreCallingIdentity(ident);
1791d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1792d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
17933255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1794599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public long getMaximumTimeToLock(ComponentName who, int userHandle) {
1795599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1796d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1797d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            long time = 0;
17983255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1799254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            if (who != null) {
1800599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1801254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn                return admin != null ? admin.maximumTimeToUnlock : time;
1802254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn            }
18033255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1804599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1805599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
1806d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            for  (int i=0; i<N; i++) {
1807599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1808d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                if (time == 0) {
1809d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    time = admin.maximumTimeToUnlock;
1810d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                } else if (admin.maximumTimeToUnlock != 0
1811d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                        && time > admin.maximumTimeToUnlock) {
1812d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                    time = admin.maximumTimeToUnlock;
1813d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn                }
1814d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            }
1815d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn            return time;
1816d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1817d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
18183255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1819df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    public void lockNow() {
1820df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        synchronized (this) {
1821df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // This API can only be called by an active device admin,
1822df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn            // so try to retrieve it to check that the caller is one.
18238aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
18248aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
1825599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            lockNowUnchecked();
1826599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        }
1827599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    }
1828599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
1829599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void lockNowUnchecked() {
1830599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        long ident = Binder.clearCallingIdentity();
1831599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        try {
1832599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            // Power off the display
1833599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            getIPowerManager().goToSleep(SystemClock.uptimeMillis(),
1834599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN);
1835599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            // Ensure the device is locked
1836f752202bee88e31ce765483ba2efa6999ae9c9adAdam Cohen            getWindowManager().lockNow(null);
1837599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        } catch (RemoteException e) {
1838599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        } finally {
1839599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            Binder.restoreCallingIdentity(ident);
1840df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
1841df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn    }
18423255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1843ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo    private boolean isExtStorageEncrypted() {
1844ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo        String state = SystemProperties.get("vold.decrypt");
1845ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo        return !"".equals(state);
1846ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo    }
1847ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo
18488ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    void wipeDataLocked(int flags) {
1849ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo        // If the SD card is encrypted and non-removable, we have to force a wipe.
1850ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo        boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
1851ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo        boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0;
1852ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo
1853ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo        // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
1854ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo        if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
1855424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn            Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
1856f535cb04f08575d29118fab0342b1e6274091734Masanori Ogino            intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
1857424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn            intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
1858424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn            mWakeLock.acquire(10000);
1859424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn            mContext.startService(intent);
1860424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn        } else {
1861424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn            try {
1862424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn                RecoverySystem.rebootWipeUserData(mContext);
1863424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn            } catch (IOException e) {
1864424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn                Slog.w(TAG, "Failed requesting data wipe", e);
1865424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn            }
18668ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        }
18678ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
18683255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1869599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void wipeData(int flags, final int userHandle) {
1870599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1871d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1872d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // This API can only be called by an active device admin,
1873d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            // so try to retrieve it to check that the caller is one.
18748aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn            getActiveAdminForCallerLocked(null,
18758aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
18768ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            long ident = Binder.clearCallingIdentity();
18778ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            try {
1878599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (userHandle == UserHandle.USER_OWNER) {
1879599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    wipeDataLocked(flags);
1880599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                } else {
1881599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    lockNowUnchecked();
1882599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    mHandler.post(new Runnable() {
1883599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        public void run() {
1884599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                            try {
1885599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                ActivityManagerNative.getDefault().switchUser(0);
1886599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
1887599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                        .removeUser(userHandle);
1888599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                            } catch (RemoteException re) {
1889599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                // Shouldn't happen
1890599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                            }
1891599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        }
1892599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    });
1893599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                }
18948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            } finally {
18958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                Binder.restoreCallingIdentity(ident);
18968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1897df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn        }
18988ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn    }
18993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1900599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void getRemoveWarning(ComponentName comp, final RemoteCallback result, int userHandle) {
1901599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
19028ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        mContext.enforceCallingOrSelfPermission(
19038ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
19043255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
19058ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn        synchronized (this) {
1906599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            ActiveAdmin admin = getActiveAdminUncheckedLocked(comp, userHandle);
19078ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            if (admin == null) {
19088ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                try {
19098ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    result.sendResult(null);
19108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                } catch (RemoteException e) {
19118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
19128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                return;
19138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }
1914ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn            Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED);
19158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            intent.setComponent(admin.info.getComponent());
1916599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            mContext.sendOrderedBroadcastAsUser(intent, new UserHandle(userHandle),
19175ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn                    null, new BroadcastReceiver() {
19188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                @Override
19198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                public void onReceive(Context context, Intent intent) {
19208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    try {
19218ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                        result.sendResult(getResultExtras(false));
19228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    } catch (RemoteException e) {
19238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    }
19248ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
19258ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn            }, null, Activity.RESULT_OK, null, null);
1926d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1927d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
19283255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1929a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev    public void setActivePasswordState(int quality, int length, int letters, int uppercase,
1930599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            int lowercase, int numbers, int symbols, int nonletter, int userHandle) {
1931599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1932d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
1933d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
1934599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        DevicePolicyData p = getUserData(userHandle);
19353255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
193685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn        validateQualityConstant(quality);
19373255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1938d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1939599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (p.mActivePasswordQuality != quality || p.mActivePasswordLength != length
1940599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || p.mFailedPasswordAttempts != 0 || p.mActivePasswordLetters != letters
1941599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || p.mActivePasswordUpperCase != uppercase
1942599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || p.mActivePasswordLowerCase != lowercase || p.mActivePasswordNumeric != numbers
1943599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || p.mActivePasswordSymbols != symbols || p.mActivePasswordNonLetter != nonletter) {
1944d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                long ident = Binder.clearCallingIdentity();
1945d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                try {
1946599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mActivePasswordQuality = quality;
1947599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mActivePasswordLength = length;
1948599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mActivePasswordLetters = letters;
1949599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mActivePasswordLowerCase = lowercase;
1950599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mActivePasswordUpperCase = uppercase;
1951599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mActivePasswordNumeric = numbers;
1952599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mActivePasswordSymbols = symbols;
1953599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mActivePasswordNonLetter = nonletter;
1954599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    p.mFailedPasswordAttempts = 0;
1955599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    saveSettingsLocked(userHandle);
1956599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    updatePasswordExpirationsLocked(userHandle);
1957599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    setExpirationAlarmCheckLocked(mContext, p);
1958ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn                    sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
1959599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                            DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
1960d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                } finally {
1961d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    Binder.restoreCallingIdentity(ident);
1962d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
1963d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
1964d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
1965d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
19663255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1967043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler    /**
1968043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     * Called any time the device password is updated.  Resets all password expiration clocks.
1969043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler     */
1970599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void updatePasswordExpirationsLocked(int userHandle) {
1971599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        DevicePolicyData policy = getUserData(userHandle);
1972599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final int N = policy.mAdminList.size();
1973a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        if (N > 0) {
1974a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            for (int i=0; i<N; i++) {
1975599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
1976a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) {
1977043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler                    long timeout = admin.passwordExpirationTimeout;
1978043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler                    long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
1979043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler                    admin.passwordExpirationDate = expiration;
1980a4e28d181942018ba8759989799a28fa88764ce3Jim Miller                }
1981a4e28d181942018ba8759989799a28fa88764ce3Jim Miller            }
1982599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            saveSettingsLocked(userHandle);
1983a4e28d181942018ba8759989799a28fa88764ce3Jim Miller        }
1984a4e28d181942018ba8759989799a28fa88764ce3Jim Miller    }
1985a4e28d181942018ba8759989799a28fa88764ce3Jim Miller
1986599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void reportFailedPasswordAttempt(int userHandle) {
1987599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
1988d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
1989d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
19903255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
1991d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
1992599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
1993d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            long ident = Binder.clearCallingIdentity();
1994d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            try {
1995599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                policy.mFailedPasswordAttempts++;
1996599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
1997599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                int max = getMaximumFailedPasswordsForWipe(null, userHandle);
1998599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (max > 0 && policy.mFailedPasswordAttempts >= max) {
19998ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                    wipeDataLocked(0);
20008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn                }
2001ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn                sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED,
2002599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
2003d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            } finally {
2004d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                Binder.restoreCallingIdentity(ident);
2005d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
2006d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
2007d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
20083255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
2009599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void reportSuccessfulPasswordAttempt(int userHandle) {
2010599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
2011d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        mContext.enforceCallingOrSelfPermission(
2012d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
20133255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
2014d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        synchronized (this) {
2015599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
2016599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (policy.mFailedPasswordAttempts != 0 || policy.mPasswordOwner >= 0) {
2017d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                long ident = Binder.clearCallingIdentity();
2018d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                try {
2019599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mFailedPasswordAttempts = 0;
2020599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    policy.mPasswordOwner = -1;
2021599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    saveSettingsLocked(userHandle);
2022ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn                    sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED,
2023599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                            DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
2024d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                } finally {
2025d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                    Binder.restoreCallingIdentity(ident);
2026d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn                }
2027d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn            }
2028d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn        }
2029d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn    }
20303255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
203169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor    public ComponentName setGlobalProxy(ComponentName who, String proxySpec,
2032599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            String exclusionList, int userHandle) {
2033599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
203469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        synchronized(this) {
203569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            if (who == null) {
203669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                throw new NullPointerException("ComponentName is null");
203769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            }
203869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
2039599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            // Only check if owner has set global proxy. We don't allow other users to set it.
2040599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
204169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            ActiveAdmin admin = getActiveAdminForCallerLocked(who,
204269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
204369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
204469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            // Scan through active admins and find if anyone has already
204569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            // set the global proxy.
2046599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            Set<ComponentName> compSet = policy.mAdminMap.keySet();
204769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            for  (ComponentName component : compSet) {
2048599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin ap = policy.mAdminMap.get(component);
204969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                if ((ap.specifiesGlobalProxy) && (!component.equals(who))) {
205069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    // Another admin already sets the global proxy
205169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    // Return it to the caller.
205269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    return component;
205369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                }
205469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            }
2055599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
2056599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            // If the user is not the owner, don't set the global proxy. Fail silently.
2057599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
2058599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                Slog.w(TAG, "Only the owner is allowed to set the global proxy. User "
2059599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        + userHandle + " is not permitted.");
2060599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                return null;
2061599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            }
206269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            if (proxySpec == null) {
206369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                admin.specifiesGlobalProxy = false;
206469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                admin.globalProxySpec = null;
206569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                admin.globalProxyExclusionList = null;
206669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            } else {
206769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
206869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                admin.specifiesGlobalProxy = true;
206969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                admin.globalProxySpec = proxySpec;
207069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                admin.globalProxyExclusionList = exclusionList;
207169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            }
207269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
207369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            // Reset the global proxy accordingly
207469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            // Do this using system permissions, as apps cannot write to secure settings
207569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            long origId = Binder.clearCallingIdentity();
2076599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            resetGlobalProxyLocked(policy);
207769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            Binder.restoreCallingIdentity(origId);
207869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            return null;
207969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        }
208069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor    }
208169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
2082599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public ComponentName getGlobalProxyAdmin(int userHandle) {
2083599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
208469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        synchronized(this) {
2085599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
208669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            // Scan through active admins and find if anyone has already
208769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            // set the global proxy.
2088599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
208969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            for (int i = 0; i < N; i++) {
2090599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin ap = policy.mAdminList.get(i);
209169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                if (ap.specifiesGlobalProxy) {
209269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    // Device admin sets the global proxy
209369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    // Return it to the caller.
209469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                    return ap.info.getComponent();
209569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                }
209669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            }
209769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        }
209869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        // No device admin sets the global proxy.
209969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        return null;
210069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor    }
210169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
2102599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void resetGlobalProxyLocked(DevicePolicyData policy) {
2103599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final int N = policy.mAdminList.size();
210469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        for (int i = 0; i < N; i++) {
2105599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            ActiveAdmin ap = policy.mAdminList.get(i);
210669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            if (ap.specifiesGlobalProxy) {
21072fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn                saveGlobalProxyLocked(ap.globalProxySpec, ap.globalProxyExclusionList);
210869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor                return;
210969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            }
211069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        }
211169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        // No device admins defining global proxies - reset global proxy settings to none
21122fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn        saveGlobalProxyLocked(null, null);
211369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor    }
211469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
21152fe8fb276c28372edb60f5bb10e172c19ef2671bDianne Hackborn    private void saveGlobalProxyLocked(String proxySpec, String exclusionList) {
211669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        if (exclusionList == null) {
211769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            exclusionList = "";
211869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        }
211969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        if (proxySpec == null) {
212069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor            proxySpec = "";
212169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        }
212269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        // Remove white spaces
212369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        proxySpec = proxySpec.trim();
2124434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        String data[] = proxySpec.split(":");
2125434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        int proxyPort = 8080;
2126434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        if (data.length > 1) {
2127434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            try {
2128434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                proxyPort = Integer.parseInt(data[1]);
2129434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt            } catch (NumberFormatException e) {}
2130434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt        }
213169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        exclusionList = exclusionList.trim();
213269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor        ContentResolver res = mContext.getContentResolver();
2133625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]);
2134625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, proxyPort);
2135625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey        Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
2136434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt                exclusionList);
213769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor    }
213869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor
21397b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler    /**
214022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * Set the storage encryption request for a single admin.  Returns the new total request
214122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * status (for all admins).
21427b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler     */
2143599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int setStorageEncryption(ComponentName who, boolean encrypt, int userHandle) {
2144599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
21457b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler        synchronized (this) {
21467b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler            // Check for permissions
21477b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler            if (who == null) {
21487b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler                throw new NullPointerException("ComponentName is null");
21497b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler            }
2150599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            // Only owner can set storage encryption
2151599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            if (userHandle != UserHandle.USER_OWNER
2152599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    || UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
2153599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                Slog.w(TAG, "Only owner is allowed to set storage encryption. User "
2154599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        + UserHandle.getCallingUserId() + " is not permitted.");
2155599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                return 0;
2156599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            }
2157599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
21587b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
21597b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler                    DeviceAdminInfo.USES_ENCRYPTED_STORAGE);
21607b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler
216122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            // Quick exit:  If the filesystem does not support encryption, we can exit early.
216222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            if (!isEncryptionSupported()) {
216322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
216422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            }
216522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler
216622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            // (1) Record the value for the admin so it's sticky
216722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            if (ap.encryptionRequested != encrypt) {
216822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                ap.encryptionRequested = encrypt;
2169599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
217022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            }
217122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler
2172599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
217322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            // (2) Compute "max" for all admins
217422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            boolean newRequested = false;
2175599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
217622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            for (int i = 0; i < N; i++) {
2177599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                newRequested |= policy.mAdminList.get(i).encryptionRequested;
217822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            }
217922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler
218022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            // Notify OS of new request
218122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            setEncryptionRequested(newRequested);
218222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler
218322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            // Return the new global request status
218422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            return newRequested
218522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                    ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE
218622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                    : DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
21877b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler        }
21887b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler    }
21897b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler
21907b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler    /**
219122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * Get the current storage encryption request status for a given admin, or aggregate of all
219222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * active admins.
21937b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler     */
2194599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public boolean getStorageEncryption(ComponentName who, int userHandle) {
2195599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
21967b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler        synchronized (this) {
21977b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler            // Check for permissions if a particular caller is specified
21987b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler            if (who != null) {
219922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                // When checking for a single caller, status is based on caller's request
2200599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin ap = getActiveAdminUncheckedLocked(who, userHandle);
2201c994d693b684bcba1a690310b5b2be306074cc02Andy Stadler                return ap != null ? ap.encryptionRequested : false;
22027b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler            }
22037b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler
220422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            // If no particular caller is specified, return the aggregate set of requests.
220522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            // This is short circuited by returning true on the first hit.
2206599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
2207599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
220822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            for (int i = 0; i < N; i++) {
2209599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                if (policy.mAdminList.get(i).encryptionRequested) {
221022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                    return true;
221122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler                }
221222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            }
221322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler            return false;
22147b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler        }
22157b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler    }
22167b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler
221722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    /**
221822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * Get the current encryption status of the device.
221922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     */
2220599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public int getStorageEncryptionStatus(int userHandle) {
2221599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
222222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler        return getEncryptionStatus();
222322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    }
222422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler
222522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    /**
222622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * Hook to low-levels:  This should report if the filesystem supports encrypted storage.
222722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     */
222822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    private boolean isEncryptionSupported() {
222922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler        // Note, this can be implemented as
223022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler        //   return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
223122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler        // But is provided as a separate internal method if there's a faster way to do a
223222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler        // simple check for supported-or-not.
223322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler        return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
223422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    }
223522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler
223622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    /**
223722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * Hook to low-levels:  Reporting the current status of encryption.
223822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED} or
223922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE} or
224022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}.
224122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     */
224222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    private int getEncryptionStatus() {
22430fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler        String status = SystemProperties.get("ro.crypto.state", "unsupported");
22440fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler        if ("encrypted".equalsIgnoreCase(status)) {
22450fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler            return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
22460fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler        } else if ("unencrypted".equalsIgnoreCase(status)) {
22470fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler            return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
22480fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler        } else {
22490fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler            return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
22500fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler        }
225122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    }
225222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler
225322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    /**
225422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     * Hook to low-levels:  If needed, record the new admin setting for encryption.
225522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler     */
225622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    private void setEncryptionRequested(boolean encrypt) {
225722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler    }
225822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler
22592447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo    /**
22602447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     * The system property used to share the state of the camera. The native camera service
22612447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     * is expected to read this property and act accordingly.
22622447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     */
22632447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo    public static final String SYSTEM_PROP_DISABLE_CAMERA = "sys.secpolicy.camera.disabled";
22642447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo
22652447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo    /**
22662447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     * Disables all device cameras according to the specified admin.
22672447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     */
2268599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public void setCameraDisabled(ComponentName who, boolean disabled, int userHandle) {
2269599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
22702447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        synchronized (this) {
22712447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            if (who == null) {
22722447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                throw new NullPointerException("ComponentName is null");
22732447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            }
22742447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
22752447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                    DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA);
22762447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            if (ap.disableCamera != disabled) {
22772447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                ap.disableCamera = disabled;
2278599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
22792447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            }
2280599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            syncDeviceCapabilitiesLocked(getUserData(userHandle));
22812447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        }
22822447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo    }
22832447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo
22842447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo    /**
22852447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     * Gets whether or not all device cameras are disabled for a given admin, or disabled for any
22862447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     * active admins.
22872447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo     */
2288599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    public boolean getCameraDisabled(ComponentName who, int userHandle) {
22892447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        synchronized (this) {
22902447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            if (who != null) {
2291599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
22922447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                return (admin != null) ? admin.disableCamera : false;
22932447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            }
22942447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo
2295599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
22962447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            // Determine whether or not the device camera is disabled for any active admins.
2297599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
22982447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            for (int i = 0; i < N; i++) {
2299599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
23002447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                if (admin.disableCamera) {
23012447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                    return true;
23022447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo                }
23032447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            }
23042447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo            return false;
23052447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo        }
23062447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo    }
23072447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo
2308b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller    /**
230948b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller     * Selectively disable keyguard features.
2310b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller     */
231148b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller    public void setKeyguardDisabledFeatures(ComponentName who, int which, int userHandle) {
2312599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
2313b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        synchronized (this) {
2314b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            if (who == null) {
2315b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller                throw new NullPointerException("ComponentName is null");
2316b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            }
2317b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
231848b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                    DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
231948b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller            if (ap.disabledKeyguardFeatures != which) {
232048b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                ap.disabledKeyguardFeatures = which;
2321599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                saveSettingsLocked(userHandle);
2322b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            }
2323599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            syncDeviceCapabilitiesLocked(getUserData(userHandle));
2324b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        }
2325b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller    }
2326b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller
2327b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller    /**
232848b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller     * Gets the disabled state for features in keyguard for the given admin,
2329b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller     * or the aggregate of all active admins if who is null.
2330b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller     */
233148b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller    public int getKeyguardDisabledFeatures(ComponentName who, int userHandle) {
2332599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        enforceCrossUserPermission(userHandle);
2333b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        synchronized (this) {
2334b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            if (who != null) {
2335599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
233648b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                return (admin != null) ? admin.disabledKeyguardFeatures : 0;
2337b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            }
2338b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller
233948b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller            // Determine which keyguard features are disabled for any active admins.
2340599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            DevicePolicyData policy = getUserData(userHandle);
2341599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            final int N = policy.mAdminList.size();
2342b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            int which = 0;
2343b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            for (int i = 0; i < N; i++) {
2344599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                ActiveAdmin admin = policy.mAdminList.get(i);
234548b9b0d068844af9eb37c215484831c4d6b831b0Jim Miller                which |= admin.disabledKeyguardFeatures;
2346b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            }
2347b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller            return which;
2348b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller        }
2349b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller    }
2350b8ec470617590fa2025db869e8e80dcce8eaec23Jim Miller
2351599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    private void enforceCrossUserPermission(int userHandle) {
2352599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (userHandle < 0) {
2353599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            throw new IllegalArgumentException("Invalid userId " + userHandle);
2354599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        }
2355599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        final int callingUid = Binder.getCallingUid();
2356599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (userHandle == UserHandle.getUserId(callingUid)) return;
2357599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2358599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            mContext.enforceCallingOrSelfPermission(
2359599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have"
2360599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    + " INTERACT_ACROSS_USERS_FULL permission");
2361599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani        }
2362599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani    }
2363599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani
236487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    @Override
236587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
236687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
236787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                != PackageManager.PERMISSION_GRANTED) {
236887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn
236987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid="
237087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    + Binder.getCallingPid()
237187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                    + ", uid=" + Binder.getCallingUid());
237287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            return;
237387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
23743255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
237587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        final Printer p = new PrintWriterPrinter(pw);
23763255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
237787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        synchronized (this) {
237887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn            p.println("Current Device Policy Manager state:");
23793255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
2380599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            int userCount = mUserData.size();
2381599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            for (int u = 0; u < userCount; u++) {
2382599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                DevicePolicyData policy = getUserData(mUserData.keyAt(u));
2383599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                p.println("  Enabled Device Admins (User " + policy.mUserHandle + "):");
2384599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                final int N = policy.mAdminList.size();
2385599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                for (int i=0; i<N; i++) {
2386599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    ActiveAdmin ap = policy.mAdminList.get(i);
2387599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    if (ap != null) {
2388599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        pw.print("  "); pw.print(ap.info.getComponent().flattenToShortString());
2389599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                                pw.println(":");
2390599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                        ap.dump("    ", pw);
2391599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                    }
239287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn                }
23933255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev
2394599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                pw.println(" ");
2395599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani                pw.print("  mPasswordOwner="); pw.println(policy.mPasswordOwner);
2396599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani            }
239787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn        }
239887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn    }
2399d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn}
2400