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