1d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn/* 2d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Copyright (C) 2010 The Android Open Source Project 3d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * 4d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * you may not use this file except in compliance with the License. 6d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * You may obtain a copy of the License at 7d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * 8d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * 10d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Unless required by applicable law or agreed to in writing, software 11d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * See the License for the specific language governing permissions and 14d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * limitations under the License. 15d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn */ 16d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 17d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornpackage com.android.server; 18d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 1921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport com.android.internal.content.PackageMonitor; 20424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackbornimport com.android.internal.os.storage.ExternalStorageFormatter; 212269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.FastXmlSerializer; 221afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackbornimport com.android.internal.util.JournaledFile; 232269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.XmlUtils; 24df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport com.android.internal.widget.LockPatternUtils; 25d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 26d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlPullParser; 27d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlPullParserException; 28d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport org.xmlpull.v1.XmlSerializer; 29d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 308ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.app.Activity; 31a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport android.app.AlarmManager; 32a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport android.app.PendingIntent; 3387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DeviceAdminInfo; 3487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DeviceAdminReceiver; 3587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DevicePolicyManager; 3687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.IDevicePolicyManager; 378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.content.BroadcastReceiver; 38d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.ComponentName; 3969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayorimport android.content.ContentResolver; 40d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Context; 41d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.Intent; 42a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport android.content.IntentFilter; 43d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.content.pm.PackageManager; 4421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException; 451f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadlerimport android.content.pm.ResolveInfo; 46d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.os.Binder; 47ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komaloimport android.os.Environment; 48a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport android.os.Handler; 49df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.IBinder; 50df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.IPowerManager; 51424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackbornimport android.os.PowerManager; 52df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.RecoverySystem; 538ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackbornimport android.os.RemoteCallback; 54df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.RemoteException; 55df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackbornimport android.os.ServiceManager; 56254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackbornimport android.os.SystemClock; 570fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadlerimport android.os.SystemProperties; 5869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayorimport android.provider.Settings; 5987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.util.PrintWriterPrinter; 6087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.util.Printer; 611f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadlerimport android.util.Slog; 62d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport android.util.Xml; 63254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackbornimport android.view.WindowManagerPolicy; 64d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 65d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.File; 6687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport java.io.FileDescriptor; 67d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.FileInputStream; 68cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackbornimport java.io.FileNotFoundException; 69d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.FileOutputStream; 70d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.io.IOException; 7187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport java.io.PrintWriter; 72a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport java.text.DateFormat; 73d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackbornimport java.util.ArrayList; 74a4e28d181942018ba8759989799a28fa88764ce3Jim Millerimport java.util.Date; 75d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackbornimport java.util.HashMap; 76d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornimport java.util.List; 7769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayorimport java.util.Set; 78d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 79d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn/** 80d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Implementation of the device policy APIs. 81d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn */ 82d68478467e3f837511196c80891d7245d0e163dfDianne Hackbornpublic class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 836b85768058b065cc682757a366abc828c9ca727aJim Miller private static final String TAG = "DevicePolicyManagerService"; 84a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 856b85768058b065cc682757a366abc828c9ca727aJim Miller private static final int REQUEST_EXPIRE_PASSWORD = 5571; 863255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 87a4e28d181942018ba8759989799a28fa88764ce3Jim Miller private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * 86400 * 1000; // 5 days, in ms 88a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 89a4e28d181942018ba8759989799a28fa88764ce3Jim Miller protected static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION 90a4e28d181942018ba8759989799a28fa88764ce3Jim Miller = "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION"; 91a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 92a4e28d181942018ba8759989799a28fa88764ce3Jim Miller private static final long MS_PER_DAY = 86400 * 1000; 93a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 9421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn final Context mContext; 9521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn final MyPackageMonitor mMonitor; 96424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn final PowerManager.WakeLock mWakeLock; 97d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 98df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn IPowerManager mIPowerManager; 993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1009327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 101d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn int mActivePasswordLength = 0; 102a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int mActivePasswordUpperCase = 0; 103a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int mActivePasswordLowerCase = 0; 104a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int mActivePasswordLetters = 0; 105a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int mActivePasswordNumeric = 0; 106a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int mActivePasswordSymbols = 0; 107c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev int mActivePasswordNonLetter = 0; 108d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn int mFailedPasswordAttempts = 0; 1093255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 11087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn int mPasswordOwner = -1; 111a4e28d181942018ba8759989799a28fa88764ce3Jim Miller Handler mHandler = new Handler(); 1123255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 113d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn final HashMap<ComponentName, ActiveAdmin> mAdminMap 114d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn = new HashMap<ComponentName, ActiveAdmin>(); 115d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn final ArrayList<ActiveAdmin> mAdminList 116d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn = new ArrayList<ActiveAdmin>(); 1173255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 118a4e28d181942018ba8759989799a28fa88764ce3Jim Miller BroadcastReceiver mReceiver = new BroadcastReceiver() { 119a4e28d181942018ba8759989799a28fa88764ce3Jim Miller @Override 120a4e28d181942018ba8759989799a28fa88764ce3Jim Miller public void onReceive(Context context, Intent intent) { 121a4e28d181942018ba8759989799a28fa88764ce3Jim Miller String action = intent.getAction(); 122a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (Intent.ACTION_BOOT_COMPLETED.equals(action) 123a4e28d181942018ba8759989799a28fa88764ce3Jim Miller || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) { 124a4e28d181942018ba8759989799a28fa88764ce3Jim Miller Slog.v(TAG, "Sending password expiration notifications for action " + action); 125a4e28d181942018ba8759989799a28fa88764ce3Jim Miller mHandler.post(new Runnable() { 126a4e28d181942018ba8759989799a28fa88764ce3Jim Miller public void run() { 127a4e28d181942018ba8759989799a28fa88764ce3Jim Miller handlePasswordExpirationNotification(); 128a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 129a4e28d181942018ba8759989799a28fa88764ce3Jim Miller }); 130a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 131a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 132a4e28d181942018ba8759989799a28fa88764ce3Jim Miller }; 133a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 134d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn static class ActiveAdmin { 1358ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn final DeviceAdminInfo info; 1363255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1379327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 138d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 139d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_MINIMUM_PASSWORD_LENGTH = 0; 140d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn int minimumPasswordLength = DEF_MINIMUM_PASSWORD_LENGTH; 141d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 142d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_PASSWORD_HISTORY_LENGTH = 0; 143d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn int passwordHistoryLength = DEF_PASSWORD_HISTORY_LENGTH; 144d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 145d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_MINIMUM_PASSWORD_UPPER_CASE = 0; 146d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn int minimumPasswordUpperCase = DEF_MINIMUM_PASSWORD_UPPER_CASE; 147d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 148d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_MINIMUM_PASSWORD_LOWER_CASE = 0; 149d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn int minimumPasswordLowerCase = DEF_MINIMUM_PASSWORD_LOWER_CASE; 150d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 151d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_MINIMUM_PASSWORD_LETTERS = 1; 1522a108403803bd30bee1c019060c208fb8c52c10cDianne Hackborn int minimumPasswordLetters = DEF_MINIMUM_PASSWORD_LETTERS; 153d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 154d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_MINIMUM_PASSWORD_NUMERIC = 1; 155d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn int minimumPasswordNumeric = DEF_MINIMUM_PASSWORD_NUMERIC; 156d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 157d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_MINIMUM_PASSWORD_SYMBOLS = 1; 158d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn int minimumPasswordSymbols = DEF_MINIMUM_PASSWORD_SYMBOLS; 159d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 160d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_MINIMUM_PASSWORD_NON_LETTER = 0; 161d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn int minimumPasswordNonLetter = DEF_MINIMUM_PASSWORD_NON_LETTER; 162d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 163d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0; 164d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK; 165d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 166d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0; 167d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE; 168d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 169d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final long DEF_PASSWORD_EXPIRATION_TIMEOUT = 0; 170d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn long passwordExpirationTimeout = DEF_PASSWORD_EXPIRATION_TIMEOUT; 171d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 172d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn static final long DEF_PASSWORD_EXPIRATION_DATE = 0; 173d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE; 174d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 17522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler boolean encryptionRequested = false; 1762447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo boolean disableCamera = false; 1773255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 17869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // TODO: review implementation decisions with frameworks team 17969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor boolean specifiesGlobalProxy = false; 18069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor String globalProxySpec = null; 18169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor String globalProxyExclusionList = null; 18269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 183d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn ActiveAdmin(DeviceAdminInfo _info) { 184d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn info = _info; 185d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1863255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 187d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn int getUid() { return info.getActivityInfo().applicationInfo.uid; } 1883255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1898ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn void writeToXml(XmlSerializer out) 1908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn throws IllegalArgumentException, IllegalStateException, IOException { 19121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn out.startTag(null, "policies"); 19221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn info.writePoliciesToXml(out); 19321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn out.endTag(null, "policies"); 1949327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 1959327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn out.startTag(null, "password-quality"); 1969327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn out.attribute(null, "value", Integer.toString(passwordQuality)); 1979327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn out.endTag(null, "password-quality"); 198d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) { 1998ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.startTag(null, "min-password-length"); 2008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.attribute(null, "value", Integer.toString(minimumPasswordLength)); 2013255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev out.endTag(null, "min-password-length"); 2023255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 203d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) { 2043255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev out.startTag(null, "password-history-length"); 2053255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev out.attribute(null, "value", Integer.toString(passwordHistoryLength)); 2063255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev out.endTag(null, "password-history-length"); 2078ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 208d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) { 209a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.startTag(null, "min-password-uppercase"); 210a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase)); 211a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.endTag(null, "min-password-uppercase"); 212a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 213d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) { 214a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.startTag(null, "min-password-lowercase"); 215a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase)); 216a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.endTag(null, "min-password-lowercase"); 217a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 218d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) { 219a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.startTag(null, "min-password-letters"); 220a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "value", Integer.toString(minimumPasswordLetters)); 221a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.endTag(null, "min-password-letters"); 222a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 223d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) { 224a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.startTag(null, "min-password-numeric"); 225a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "value", Integer.toString(minimumPasswordNumeric)); 226a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.endTag(null, "min-password-numeric"); 227a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 228d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) { 229a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.startTag(null, "min-password-symbols"); 230a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "value", Integer.toString(minimumPasswordSymbols)); 231a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.endTag(null, "min-password-symbols"); 232a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 233d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) { 234c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev out.startTag(null, "min-password-nonletter"); 235c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter)); 236c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev out.endTag(null, "min-password-nonletter"); 237c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 2388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 239d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) { 2408ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.startTag(null, "max-time-to-unlock"); 2418ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.attribute(null, "value", Long.toString(maximumTimeToUnlock)); 2428ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.endTag(null, "max-time-to-unlock"); 2438ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 244d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) { 2458ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.startTag(null, "max-failed-password-wipe"); 2468ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe)); 2478ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.endTag(null, "max-failed-password-wipe"); 2488ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 24969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (specifiesGlobalProxy) { 25069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.startTag(null, "specifies-global-proxy"); 25169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.attribute(null, "value", Boolean.toString(specifiesGlobalProxy)); 25269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.endTag(null, "specifies_global_proxy"); 25369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (globalProxySpec != null) { 25469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.startTag(null, "global-proxy-spec"); 25569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.attribute(null, "value", globalProxySpec); 25669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.endTag(null, "global-proxy-spec"); 25769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 25869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (globalProxyExclusionList != null) { 25969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.startTag(null, "global-proxy-exclusion-list"); 26069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.attribute(null, "value", globalProxyExclusionList); 26169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor out.endTag(null, "global-proxy-exclusion-list"); 26269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 26369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 264d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) { 265a4e28d181942018ba8759989799a28fa88764ce3Jim Miller out.startTag(null, "password-expiration-timeout"); 266a4e28d181942018ba8759989799a28fa88764ce3Jim Miller out.attribute(null, "value", Long.toString(passwordExpirationTimeout)); 267a4e28d181942018ba8759989799a28fa88764ce3Jim Miller out.endTag(null, "password-expiration-timeout"); 268a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 269d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) { 270a4e28d181942018ba8759989799a28fa88764ce3Jim Miller out.startTag(null, "password-expiration-date"); 271a4e28d181942018ba8759989799a28fa88764ce3Jim Miller out.attribute(null, "value", Long.toString(passwordExpirationDate)); 272a4e28d181942018ba8759989799a28fa88764ce3Jim Miller out.endTag(null, "password-expiration-date"); 273a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 27422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler if (encryptionRequested) { 27522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler out.startTag(null, "encryption-requested"); 27622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler out.attribute(null, "value", Boolean.toString(encryptionRequested)); 27722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler out.endTag(null, "encryption-requested"); 27822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 2792447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo if (disableCamera) { 2802447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo out.startTag(null, "disable-camera"); 2812447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo out.attribute(null, "value", Boolean.toString(disableCamera)); 2822447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo out.endTag(null, "disable-camera"); 2832447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 2848ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 2853255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 2868ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn void readFromXml(XmlPullParser parser) 2878ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn throws XmlPullParserException, IOException { 2888ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn int outerDepth = parser.getDepth(); 2898ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn int type; 2908ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 2918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn continue; 2948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 2958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn String tag = parser.getName(); 29621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if ("policies".equals(tag)) { 29721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn info.readPoliciesFromXml(parser); 29821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else if ("password-quality".equals(tag)) { 2999327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn passwordQuality = Integer.parseInt( 3008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn parser.getAttributeValue(null, "value")); 3018ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } else if ("min-password-length".equals(tag)) { 3028ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn minimumPasswordLength = Integer.parseInt( 3038ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn parser.getAttributeValue(null, "value")); 3043255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } else if ("password-history-length".equals(tag)) { 3053255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev passwordHistoryLength = Integer.parseInt( 3063255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev parser.getAttributeValue(null, "value")); 307a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } else if ("min-password-uppercase".equals(tag)) { 308a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev minimumPasswordUpperCase = Integer.parseInt( 309a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "value")); 310a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } else if ("min-password-lowercase".equals(tag)) { 311a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev minimumPasswordLowerCase = Integer.parseInt( 312a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "value")); 313a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } else if ("min-password-letters".equals(tag)) { 314a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev minimumPasswordLetters = Integer.parseInt( 315a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "value")); 316a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } else if ("min-password-numeric".equals(tag)) { 317a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev minimumPasswordNumeric = Integer.parseInt( 318a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "value")); 319a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } else if ("min-password-symbols".equals(tag)) { 320a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev minimumPasswordSymbols = Integer.parseInt( 321a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "value")); 322c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } else if ("min-password-nonletter".equals(tag)) { 323c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev minimumPasswordNonLetter = Integer.parseInt( 324c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev parser.getAttributeValue(null, "value")); 3258ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } else if ("max-time-to-unlock".equals(tag)) { 3268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn maximumTimeToUnlock = Long.parseLong( 3278ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn parser.getAttributeValue(null, "value")); 3288ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } else if ("max-failed-password-wipe".equals(tag)) { 3298ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn maximumFailedPasswordsForWipe = Integer.parseInt( 3308ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn parser.getAttributeValue(null, "value")); 33169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } else if ("specifies-global-proxy".equals(tag)) { 33222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler specifiesGlobalProxy = Boolean.parseBoolean( 33369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor parser.getAttributeValue(null, "value")); 33469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } else if ("global-proxy-spec".equals(tag)) { 33569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor globalProxySpec = 33669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor parser.getAttributeValue(null, "value"); 33769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } else if ("global-proxy-exclusion-list".equals(tag)) { 33869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor globalProxyExclusionList = 33969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor parser.getAttributeValue(null, "value"); 340a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } else if ("password-expiration-timeout".equals(tag)) { 341a4e28d181942018ba8759989799a28fa88764ce3Jim Miller passwordExpirationTimeout = Long.parseLong( 342a4e28d181942018ba8759989799a28fa88764ce3Jim Miller parser.getAttributeValue(null, "value")); 343a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } else if ("password-expiration-date".equals(tag)) { 344a4e28d181942018ba8759989799a28fa88764ce3Jim Miller passwordExpirationDate = Long.parseLong( 345a4e28d181942018ba8759989799a28fa88764ce3Jim Miller parser.getAttributeValue(null, "value")); 34622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } else if ("encryption-requested".equals(tag)) { 34722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler encryptionRequested = Boolean.parseBoolean( 34822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler parser.getAttributeValue(null, "value")); 3492447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } else if ("disable-camera".equals(tag)) { 3502447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo disableCamera = Boolean.parseBoolean( 3512447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo parser.getAttributeValue(null, "value")); 35221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else { 35385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Unknown admin tag: " + tag); 35421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 35521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn XmlUtils.skipCurrentTag(parser); 35621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 35721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 3583255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 35987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn void dump(String prefix, PrintWriter pw) { 36087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(prefix); pw.print("uid="); pw.println(getUid()); 36187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(prefix); pw.println("policies:"); 36287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn ArrayList<DeviceAdminInfo.PolicyInfo> pols = info.getUsedPolicies(); 36387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (pols != null) { 36487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn for (int i=0; i<pols.size(); i++) { 36587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(prefix); pw.print(" "); pw.println(pols.get(i).tag); 36687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 36787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 36885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn pw.print(prefix); pw.print("passwordQuality=0x"); 3693255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev pw.println(Integer.toHexString(passwordQuality)); 3703255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev pw.print(prefix); pw.print("minimumPasswordLength="); 37187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.println(minimumPasswordLength); 3723255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev pw.print(prefix); pw.print("passwordHistoryLength="); 3733255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev pw.println(passwordHistoryLength); 374a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(prefix); pw.print("minimumPasswordUpperCase="); 375a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.println(minimumPasswordUpperCase); 376a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(prefix); pw.print("minimumPasswordLowerCase="); 377a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.println(minimumPasswordLowerCase); 378a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(prefix); pw.print("minimumPasswordLetters="); 379a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.println(minimumPasswordLetters); 380a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(prefix); pw.print("minimumPasswordNumeric="); 381a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.println(minimumPasswordNumeric); 382a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(prefix); pw.print("minimumPasswordSymbols="); 383a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.println(minimumPasswordSymbols); 384c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev pw.print(prefix); pw.print("minimumPasswordNonLetter="); 385c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev pw.println(minimumPasswordNonLetter); 38687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(prefix); pw.print("maximumTimeToUnlock="); 38787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.println(maximumTimeToUnlock); 38887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(prefix); pw.print("maximumFailedPasswordsForWipe="); 38987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.println(maximumFailedPasswordsForWipe); 39069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor pw.print(prefix); pw.print("specifiesGlobalProxy="); 39169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor pw.println(specifiesGlobalProxy); 392a4e28d181942018ba8759989799a28fa88764ce3Jim Miller pw.print(prefix); pw.print("passwordExpirationTimeout="); 393a4e28d181942018ba8759989799a28fa88764ce3Jim Miller pw.println(passwordExpirationTimeout); 394a4e28d181942018ba8759989799a28fa88764ce3Jim Miller pw.print(prefix); pw.print("passwordExpirationDate="); 395a4e28d181942018ba8759989799a28fa88764ce3Jim Miller pw.println(passwordExpirationDate); 39669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (globalProxySpec != null) { 39769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor pw.print(prefix); pw.print("globalProxySpec="); 39869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor pw.println(globalProxySpec); 39969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 40069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (globalProxyExclusionList != null) { 40169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor pw.print(prefix); pw.print("globalProxyEclusionList="); 40269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor pw.println(globalProxyExclusionList); 40369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 40422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler pw.print(prefix); pw.print("encryptionRequested="); 40522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler pw.println(encryptionRequested); 4062447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo pw.print(prefix); pw.print("disableCamera="); 4072447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo pw.println(disableCamera); 40887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 40921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 4103255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 41121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn class MyPackageMonitor extends PackageMonitor { 4121f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler @Override 41321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public void onSomePackagesChanged() { 41421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn synchronized (DevicePolicyManagerService.this) { 41587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn boolean removed = false; 41621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (int i=mAdminList.size()-1; i>=0; i--) { 41721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ActiveAdmin aa = mAdminList.get(i); 4183255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev int change = isPackageDisappearing(aa.info.getPackageName()); 41921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (change == PACKAGE_PERMANENT_CHANGE 42021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || change == PACKAGE_TEMPORARY_CHANGE) { 42185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Admin unexpectedly uninstalled: " 42221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn + aa.info.getComponent()); 42387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn removed = true; 42421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mAdminList.remove(i); 42521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else if (isPackageModified(aa.info.getPackageName())) { 42621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn try { 42721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mContext.getPackageManager().getReceiverInfo( 42821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn aa.info.getComponent(), 0); 42921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } catch (NameNotFoundException e) { 43085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Admin package change removed component: " 43121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn + aa.info.getComponent()); 43287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn removed = true; 43321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mAdminList.remove(i); 43421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 43521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 4368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 43787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (removed) { 43887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn validatePasswordOwnerLocked(); 4392447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo syncDeviceCapabilitiesLocked(); 440d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn saveSettingsLocked(); 44187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 4428ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 4438ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 444d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 4453255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 446d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn /** 447d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn * Instantiates the service. 448d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn */ 449d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public DevicePolicyManagerService(Context context) { 450d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mContext = context; 45121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mMonitor = new MyPackageMonitor(); 45221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mMonitor.register(context, true); 453424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)) 454424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM"); 455a4e28d181942018ba8759989799a28fa88764ce3Jim Miller IntentFilter filter = new IntentFilter(); 456a4e28d181942018ba8759989799a28fa88764ce3Jim Miller filter.addAction(Intent.ACTION_BOOT_COMPLETED); 457a4e28d181942018ba8759989799a28fa88764ce3Jim Miller filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION); 458a4e28d181942018ba8759989799a28fa88764ce3Jim Miller context.registerReceiver(mReceiver, filter); 459a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 460a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 461043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler /** 462043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration 463043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler * reminders. Clears alarm if no expirations are configured. 464043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler */ 465a4e28d181942018ba8759989799a28fa88764ce3Jim Miller protected void setExpirationAlarmCheckLocked(Context context) { 466a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final long expiration = getPasswordExpirationLocked(null); 467a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final long now = System.currentTimeMillis(); 468a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final long timeToExpire = expiration - now; 469a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final long alarmTime; 470043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler if (expiration == 0) { 471043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler // No expirations are currently configured: Cancel alarm. 472043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler alarmTime = 0; 473043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler } else if (timeToExpire <= 0) { 474043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler // The password has already expired: Repeat every 24 hours. 475a4e28d181942018ba8759989799a28fa88764ce3Jim Miller alarmTime = now + MS_PER_DAY; 476043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler } else { 477043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler // Selecting the next alarm time: Roll forward to the next 24 hour multiple before 478043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler // the expiration time. 479043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler long alarmInterval = timeToExpire % MS_PER_DAY; 480043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler if (alarmInterval == 0) { 481043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler alarmInterval = MS_PER_DAY; 482043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler } 483043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler alarmTime = now + alarmInterval; 484a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 485a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 4861f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler long token = Binder.clearCallingIdentity(); 4871f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler try { 4881f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 4891f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler PendingIntent pi = PendingIntent.getBroadcast(context, REQUEST_EXPIRE_PASSWORD, 4901f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION), 4911f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); 4921f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler am.cancel(pi); 493043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler if (alarmTime != 0) { 494043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler am.set(AlarmManager.RTC, alarmTime, pi); 495043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler } 4961f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler } finally { 4971f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler Binder.restoreCallingIdentity(token); 4981f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler } 499d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 500d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 501df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn private IPowerManager getIPowerManager() { 502df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn if (mIPowerManager == null) { 503df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn IBinder b = ServiceManager.getService(Context.POWER_SERVICE); 504df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn mIPowerManager = IPowerManager.Stub.asInterface(b); 505df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 506df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn return mIPowerManager; 507df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 5083255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 5098ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who) { 510d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ActiveAdmin admin = mAdminMap.get(who); 5118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if (admin != null 5128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn && who.getPackageName().equals(admin.info.getActivityInfo().packageName) 5138ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn && who.getClassName().equals(admin.info.getActivityInfo().name)) { 5148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn return admin; 5158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 5168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn return null; 5178ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 5183255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 519254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) 5208aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn throws SecurityException { 521254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn final int callingUid = Binder.getCallingUid(); 522254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (who != null) { 523254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn ActiveAdmin admin = mAdminMap.get(who); 524254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (admin == null) { 525254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn throw new SecurityException("No active admin " + who); 526254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 527254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (admin.getUid() != callingUid) { 528254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn throw new SecurityException("Admin " + who + " is not owned by uid " 529254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn + Binder.getCallingUid()); 530254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 531254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (!admin.info.usesPolicy(reqPolicy)) { 532254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn throw new SecurityException("Admin " + admin.info.getComponent() 533254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn + " did not specify uses-policy for: " 534254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn + admin.info.getTagForPolicy(reqPolicy)); 535d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 536d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return admin; 537254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } else { 538254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn final int N = mAdminList.size(); 539254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn for (int i=0; i<N; i++) { 540254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn ActiveAdmin admin = mAdminList.get(i); 541254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) { 542254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn return admin; 543254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 544254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 545254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn throw new SecurityException("No active admin owned by uid " 546254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn + Binder.getCallingUid() + " for policy #" + reqPolicy); 547d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 5488ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 5493255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 5508aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn void sendAdminCommandLocked(ActiveAdmin admin, String action) { 551d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn sendAdminCommandLocked(admin, action, null); 552d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn } 553d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn 554d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn void sendAdminCommandLocked(ActiveAdmin admin, String action, BroadcastReceiver result) { 555d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn Intent intent = new Intent(action); 5568aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn intent.setComponent(admin.info.getComponent()); 557a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) { 558a4e28d181942018ba8759989799a28fa88764ce3Jim Miller intent.putExtra("expiration", admin.passwordExpirationDate); 559a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 560d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (result != null) { 561d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn mContext.sendOrderedBroadcast(intent, null, result, mHandler, 562d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn Activity.RESULT_OK, null, null); 563d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn } else { 564d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn mContext.sendBroadcast(intent); 565d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn } 566d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 5673255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 5688aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn void sendAdminCommandLocked(String action, int reqPolicy) { 569d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn final int N = mAdminList.size(); 570d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (N > 0) { 571d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn for (int i=0; i<N; i++) { 572d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ActiveAdmin admin = mAdminList.get(i); 573d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (admin.info.usesPolicy(reqPolicy)) { 574d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn sendAdminCommandLocked(admin, action); 575d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 5768aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn } 5774141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn } 5784141d035c7d41f39f023d7a051568dff87c7cd32Dianne Hackborn } 5793255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 580d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn void removeActiveAdminLocked(final ComponentName adminReceiver) { 581d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver); 582d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (admin != null) { 583d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn sendAdminCommandLocked(admin, 584d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED, 585d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn new BroadcastReceiver() { 586d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn @Override 587d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn public void onReceive(Context context, Intent intent) { 588d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn synchronized (this) { 589d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn boolean doProxyCleanup = admin.info.usesPolicy( 590d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY); 591d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn mAdminList.remove(admin); 592d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn mAdminMap.remove(adminReceiver); 593d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn validatePasswordOwnerLocked(); 5942447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo syncDeviceCapabilitiesLocked(); 595d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn if (doProxyCleanup) { 596d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn resetGlobalProxy(); 597d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn } 598d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn saveSettingsLocked(); 599d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn } 600d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn } 601d998acb3491fe750ce157b6171d5b0a18f4b3883Dianne Hackborn }); 602d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 603d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 6043255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 605d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public DeviceAdminInfo findAdmin(ComponentName adminName) { 606d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn Intent resolveIntent = new Intent(); 607d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn resolveIntent.setComponent(adminName); 608d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers( 609d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn resolveIntent, PackageManager.GET_META_DATA); 610d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (infos == null || infos.size() <= 0) { 611d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn throw new IllegalArgumentException("Unknown admin: " + adminName); 612d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 6133255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 614d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 615d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn return new DeviceAdminInfo(mContext, infos.get(0)); 616d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (XmlPullParserException e) { 61785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Bad device admin requested: " + adminName, e); 618d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn return null; 619d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (IOException e) { 62085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Bad device admin requested: " + adminName, e); 621d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn return null; 622d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 623d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 6243255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 625d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn private static JournaledFile makeJournaledFile() { 626d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn final String base = "/data/system/device_policies.xml"; 627d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn return new JournaledFile(new File(base), new File(base + ".tmp")); 628d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 629d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 630d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn private void saveSettingsLocked() { 631d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn JournaledFile journal = makeJournaledFile(); 632d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn FileOutputStream stream = null; 633d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 634d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn stream = new FileOutputStream(journal.chooseForWrite(), false); 635d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn XmlSerializer out = new FastXmlSerializer(); 636d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn out.setOutput(stream, "utf-8"); 637d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn out.startDocument(null, true); 638d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 639d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn out.startTag(null, "policies"); 6403255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 641d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn final int N = mAdminList.size(); 642d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn for (int i=0; i<N; i++) { 643d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ActiveAdmin ap = mAdminList.get(i); 644d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (ap != null) { 645d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn out.startTag(null, "admin"); 646d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn out.attribute(null, "name", ap.info.getComponent().flattenToString()); 647d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ap.writeToXml(out); 648d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn out.endTag(null, "admin"); 649d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 650d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 6513255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 65287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (mPasswordOwner >= 0) { 65387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn out.startTag(null, "password-owner"); 65487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn out.attribute(null, "value", Integer.toString(mPasswordOwner)); 65587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn out.endTag(null, "password-owner"); 65687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 6573255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 6588ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if (mFailedPasswordAttempts != 0) { 6598ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.startTag(null, "failed-password-attempts"); 6608ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.attribute(null, "value", Integer.toString(mFailedPasswordAttempts)); 6618ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn out.endTag(null, "failed-password-attempts"); 6628ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 6633255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 664a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (mActivePasswordQuality != 0 || mActivePasswordLength != 0 665a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev || mActivePasswordUpperCase != 0 || mActivePasswordLowerCase != 0 666a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev || mActivePasswordLetters != 0 || mActivePasswordNumeric != 0 667c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev || mActivePasswordSymbols != 0 || mActivePasswordNonLetter != 0) { 66885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn out.startTag(null, "active-password"); 66985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn out.attribute(null, "quality", Integer.toString(mActivePasswordQuality)); 67085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn out.attribute(null, "length", Integer.toString(mActivePasswordLength)); 671a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "uppercase", Integer.toString(mActivePasswordUpperCase)); 672a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "lowercase", Integer.toString(mActivePasswordLowerCase)); 673a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "letters", Integer.toString(mActivePasswordLetters)); 674a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "numeric", Integer 675a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev .toString(mActivePasswordNumeric)); 676a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev out.attribute(null, "symbols", Integer.toString(mActivePasswordSymbols)); 677c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev out.attribute(null, "nonletter", Integer.toString(mActivePasswordNonLetter)); 67885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn out.endTag(null, "active-password"); 67985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn } 6803255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 68185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn out.endTag(null, "policies"); 68285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn 683d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn out.endDocument(); 684d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn stream.close(); 685d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn journal.commit(); 686284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller sendChangedNotification(); 687d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (IOException e) { 688d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 689d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (stream != null) { 690d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn stream.close(); 691d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 692d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (IOException ex) { 693d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn // Ignore 694d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 695d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn journal.rollback(); 696d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 697d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 698d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 699284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller private void sendChangedNotification() { 700284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 701284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 702284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller mContext.sendBroadcast(intent); 703284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller } 704284b62e1b8c3419bfd02c6fea5ba0a68146c06f8Jim Miller 705d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn private void loadSettingsLocked() { 706d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn JournaledFile journal = makeJournaledFile(); 707d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn FileInputStream stream = null; 708d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn File file = journal.chooseForRead(); 709d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 710d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn stream = new FileInputStream(file); 711d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn XmlPullParser parser = Xml.newPullParser(); 712d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn parser.setInput(stream, null); 713d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 7148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn int type; 7158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 7168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn && type != XmlPullParser.START_TAG) { 717d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 718d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn String tag = parser.getName(); 7198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if (!"policies".equals(tag)) { 7208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn throw new XmlPullParserException( 7218ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn "Settings do not start with policies tag: found " + tag); 7228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 7238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn type = parser.next(); 7248ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn int outerDepth = parser.getDepth(); 7258ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 7268ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 7278ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 7288ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn continue; 7298ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 7308ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn tag = parser.getName(); 7318ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if ("admin".equals(tag)) { 732e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn String name = parser.getAttributeValue(null, "name"); 733e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn try { 734e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn DeviceAdminInfo dai = findAdmin( 735e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn ComponentName.unflattenFromString(name)); 736e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn if (dai != null) { 737e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn ActiveAdmin ap = new ActiveAdmin(dai); 738e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn ap.readFromXml(parser); 739e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn mAdminMap.put(ap.info.getComponent(), ap); 740e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn mAdminList.add(ap); 741e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn } 742e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn } catch (RuntimeException e) { 74385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Failed loading admin " + name, e); 744d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 7458ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } else if ("failed-password-attempts".equals(tag)) { 7468ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn mFailedPasswordAttempts = Integer.parseInt( 7478ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn parser.getAttributeValue(null, "value")); 74821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn XmlUtils.skipCurrentTag(parser); 74987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } else if ("password-owner".equals(tag)) { 75087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn mPasswordOwner = Integer.parseInt( 75187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn parser.getAttributeValue(null, "value")); 75287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn XmlUtils.skipCurrentTag(parser); 75385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn } else if ("active-password".equals(tag)) { 75485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn mActivePasswordQuality = Integer.parseInt( 75585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn parser.getAttributeValue(null, "quality")); 75685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn mActivePasswordLength = Integer.parseInt( 75785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn parser.getAttributeValue(null, "length")); 758a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordUpperCase = Integer.parseInt( 759a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "uppercase")); 760a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordLowerCase = Integer.parseInt( 761a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "lowercase")); 762a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordLetters = Integer.parseInt( 763a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "letters")); 764a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordNumeric = Integer.parseInt( 765a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "numeric")); 766a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordSymbols = Integer.parseInt( 767a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev parser.getAttributeValue(null, "symbols")); 768c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev mActivePasswordNonLetter = Integer.parseInt( 769c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev parser.getAttributeValue(null, "nonletter")); 77085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn XmlUtils.skipCurrentTag(parser); 77121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else { 77285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Unknown tag: " + tag); 77321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn XmlUtils.skipCurrentTag(parser); 7748ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 775d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 776d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (NullPointerException e) { 77785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "failed parsing " + file + " " + e); 778d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (NumberFormatException e) { 77985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "failed parsing " + file + " " + e); 780d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (XmlPullParserException e) { 78185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "failed parsing " + file + " " + e); 782cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn } catch (FileNotFoundException e) { 783cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn // Don't be noisy, this is normal if we haven't defined any policies. 784d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (IOException e) { 78585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "failed parsing " + file + " " + e); 786d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (IndexOutOfBoundsException e) { 78785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "failed parsing " + file + " " + e); 788d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 789d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 790d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (stream != null) { 791d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn stream.close(); 792d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 793d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } catch (IOException e) { 794d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn // Ignore 795d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 796d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 79785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn // Validate that what we stored for the password quality matches 79885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn // sufficiently what is currently set. Note that this is only 79985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn // a sanity check in case the two get out of sync; this should 80085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn // never normally happen. 80185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn LockPatternUtils utils = new LockPatternUtils(mContext); 80285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn if (utils.getActivePasswordQuality() < mActivePasswordQuality) { 80385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Active password quality 0x" 80485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn + Integer.toHexString(mActivePasswordQuality) 80585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn + " does not match actual quality 0x" 80685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn + Integer.toHexString(utils.getActivePasswordQuality())); 80785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 80885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn mActivePasswordLength = 0; 809a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordUpperCase = 0; 810a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordLowerCase = 0; 811a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordLetters = 0; 812a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordNumeric = 0; 813a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordSymbols = 0; 814c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev mActivePasswordNonLetter = 0; 81585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn } 8163255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 81787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn validatePasswordOwnerLocked(); 8182447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo syncDeviceCapabilitiesLocked(); 8193255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 820254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn long timeMs = getMaximumTimeToLock(null); 821df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn if (timeMs <= 0) { 822df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn timeMs = Integer.MAX_VALUE; 823df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 824df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn try { 825df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn getIPowerManager().setMaximumScreenOffTimeount((int)timeMs); 826df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } catch (RemoteException e) { 82785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Failure talking with power manager", e); 828df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 829d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 830d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn 83185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn static void validateQualityConstant(int quality) { 83285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn switch (quality) { 83385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: 83485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 83585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 83685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 83785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 838a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 83985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn return; 84085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn } 84185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn throw new IllegalArgumentException("Invalid quality constant: 0x" 84285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn + Integer.toHexString(quality)); 84385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn } 8443255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 84587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn void validatePasswordOwnerLocked() { 84687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (mPasswordOwner >= 0) { 84787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn boolean haveOwner = false; 84887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn for (int i=mAdminList.size()-1; i>=0; i--) { 84987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (mAdminList.get(i).getUid() == mPasswordOwner) { 85087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn haveOwner = true; 85187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn break; 85287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 85387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 85487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (!haveOwner) { 85585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Previous password owner " + mPasswordOwner 85687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn + " no longer active; disabling"); 85787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn mPasswordOwner = -1; 85887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 85987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 86087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 8613255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 8622447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo /** 8632447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo * Pushes down policy information to the system for any policies related to general device 8642447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo * capabilities that need to be enforced by lower level services (e.g. Camera services). 8652447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo */ 8662447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo void syncDeviceCapabilitiesLocked() { 8672447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo // Ensure the status of the camera is synced down to the system. Interested native services 8682447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo // should monitor this value and act accordingly. 8692447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo boolean systemState = SystemProperties.getBoolean(SYSTEM_PROP_DISABLE_CAMERA, false); 8702447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo boolean cameraDisabled = getCameraDisabled(null); 8712447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo if (cameraDisabled != systemState) { 8722447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo long token = Binder.clearCallingIdentity(); 8732447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo try { 8742447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo String value = cameraDisabled ? "1" : "0"; 8752447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo Slog.v(TAG, "Change in camera state [" 8762447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo + SYSTEM_PROP_DISABLE_CAMERA + "] = " + value); 8772447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value); 8782447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } finally { 8792447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo Binder.restoreCallingIdentity(token); 8802447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 8812447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 8822447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 8832447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo 884d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public void systemReady() { 885d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 886d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn loadSettingsLocked(); 887d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 888d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 8893255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 890a4e28d181942018ba8759989799a28fa88764ce3Jim Miller private void handlePasswordExpirationNotification() { 891a4e28d181942018ba8759989799a28fa88764ce3Jim Miller synchronized (this) { 892a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final long now = System.currentTimeMillis(); 893a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final int N = mAdminList.size(); 894a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (N <= 0) { 895a4e28d181942018ba8759989799a28fa88764ce3Jim Miller return; 896a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 897a4e28d181942018ba8759989799a28fa88764ce3Jim Miller for (int i=0; i < N; i++) { 898a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ActiveAdmin admin = mAdminList.get(i); 899a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD) 900a4e28d181942018ba8759989799a28fa88764ce3Jim Miller && admin.passwordExpirationTimeout > 0L 901a4e28d181942018ba8759989799a28fa88764ce3Jim Miller && admin.passwordExpirationDate > 0L 902043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS) { 903a4e28d181942018ba8759989799a28fa88764ce3Jim Miller sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING); 904a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 905a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 906a4e28d181942018ba8759989799a28fa88764ce3Jim Miller setExpirationAlarmCheckLocked(mContext); 907a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 908a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 909a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 910c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler /** 911c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler * @param adminReceiver The admin to add 912c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler * @param refreshing true = update an active admin, no error 913c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler */ 914c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing) { 915d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mContext.enforceCallingOrSelfPermission( 916d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn android.Manifest.permission.BIND_DEVICE_ADMIN, null); 9173255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 918d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn DeviceAdminInfo info = findAdmin(adminReceiver); 919d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (info == null) { 920d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn throw new IllegalArgumentException("Bad admin: " + adminReceiver); 921d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 922d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 923d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn long ident = Binder.clearCallingIdentity(); 924d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 925c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler if (!refreshing && getActiveAdminUncheckedLocked(adminReceiver) != null) { 926d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn throw new IllegalArgumentException("Admin is already added"); 927d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 928c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler ActiveAdmin newAdmin = new ActiveAdmin(info); 929c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler mAdminMap.put(adminReceiver, newAdmin); 930c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler int replaceIndex = -1; 931c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler if (refreshing) { 932c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler final int N = mAdminList.size(); 933c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler for (int i=0; i < N; i++) { 934c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler ActiveAdmin oldAdmin = mAdminList.get(i); 935c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler if (oldAdmin.info.getComponent().equals(adminReceiver)) { 936c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler replaceIndex = i; 937c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler break; 938c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler } 939c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler } 940c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler } 941c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler if (replaceIndex == -1) { 942c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler mAdminList.add(newAdmin); 943c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler } else { 944c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler mAdminList.set(replaceIndex, newAdmin); 945c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler } 946d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn saveSettingsLocked(); 947c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED); 948d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } finally { 949d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn Binder.restoreCallingIdentity(ident); 950d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 951d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 952d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 9533255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 954d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn public boolean isAdminActive(ComponentName adminReceiver) { 955d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn synchronized (this) { 956d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return getActiveAdminUncheckedLocked(adminReceiver) != null; 957d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 958d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 9593255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 960c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler public boolean hasGrantedPolicy(ComponentName adminReceiver, int policyId) { 961c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler synchronized (this) { 962c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver); 963c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler if (administrator == null) { 964c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler throw new SecurityException("No active admin " + adminReceiver); 965c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler } 966c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler return administrator.info.usesPolicy(policyId); 967c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler } 968c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler } 969c25f70a440ef9468085b8d98c8416c7e8b116753Andy Stadler 970d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn public List<ComponentName> getActiveAdmins() { 971d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 972d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn final int N = mAdminList.size(); 973d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (N <= 0) { 974d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return null; 975d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 976d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ArrayList<ComponentName> res = new ArrayList<ComponentName>(N); 977d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn for (int i=0; i<N; i++) { 978d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn res.add(mAdminList.get(i).info.getComponent()); 979d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 980d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return res; 981d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 982d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 9833255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 98421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public boolean packageHasActiveAdmins(String packageName) { 98521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn synchronized (this) { 98621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn final int N = mAdminList.size(); 98721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (int i=0; i<N; i++) { 98821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (mAdminList.get(i).info.getPackageName().equals(packageName)) { 98921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 99021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 99121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 99221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return false; 99321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 99421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 9953255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 996d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public void removeActiveAdmin(ComponentName adminReceiver) { 997d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 998d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver); 999d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (admin == null) { 1000d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return; 1001d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1002d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (admin.getUid() != Binder.getCallingUid()) { 1003d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mContext.enforceCallingOrSelfPermission( 1004d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn android.Manifest.permission.BIND_DEVICE_ADMIN, null); 1005d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1006d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn long ident = Binder.clearCallingIdentity(); 1007d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 1008d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn removeActiveAdminLocked(adminReceiver); 1009d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } finally { 1010d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn Binder.restoreCallingIdentity(ident); 1011d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1012d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1013d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 10143255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 101585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn public void setPasswordQuality(ComponentName who, int quality) { 101685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn validateQualityConstant(quality); 10173255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1018d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1019d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (who == null) { 1020d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn throw new NullPointerException("ComponentName is null"); 1021d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 10228aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn ActiveAdmin ap = getActiveAdminForCallerLocked(who, 10238aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 102485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn if (ap.passwordQuality != quality) { 102585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn ap.passwordQuality = quality; 1026d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn saveSettingsLocked(); 1027d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1028d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1029d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 10303255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 10319327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn public int getPasswordQuality(ComponentName who) { 1032d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 10339327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 10343255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1035254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (who != null) { 1036254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 10379327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn return admin != null ? admin.passwordQuality : mode; 1038254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 10393255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1040254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn final int N = mAdminList.size(); 1041d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn for (int i=0; i<N; i++) { 1042d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ActiveAdmin admin = mAdminList.get(i); 10439327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn if (mode < admin.passwordQuality) { 10449327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn mode = admin.passwordQuality; 1045d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1046d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1047d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return mode; 1048d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1049d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 10503255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1051254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn public void setPasswordMinimumLength(ComponentName who, int length) { 1052d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1053d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (who == null) { 1054d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn throw new NullPointerException("ComponentName is null"); 1055d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 10568aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn ActiveAdmin ap = getActiveAdminForCallerLocked(who, 10578aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1058d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (ap.minimumPasswordLength != length) { 1059d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn ap.minimumPasswordLength = length; 1060d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn saveSettingsLocked(); 1061d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1062d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1063d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 10643255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1065254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn public int getPasswordMinimumLength(ComponentName who) { 1066d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1067d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn int length = 0; 10683255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1069254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (who != null) { 1070254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1071254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn return admin != null ? admin.minimumPasswordLength : length; 1072254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 10733255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1074254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn final int N = mAdminList.size(); 1075d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn for (int i=0; i<N; i++) { 1076d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ActiveAdmin admin = mAdminList.get(i); 1077d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (length < admin.minimumPasswordLength) { 1078d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn length = admin.minimumPasswordLength; 1079d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1080d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1081d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return length; 1082d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1083d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 10843255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 10853255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev public void setPasswordHistoryLength(ComponentName who, int length) { 10863255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev synchronized (this) { 10873255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev if (who == null) { 10883255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev throw new NullPointerException("ComponentName is null"); 10893255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 10903255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev ActiveAdmin ap = getActiveAdminForCallerLocked(who, 10913255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 10923255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev if (ap.passwordHistoryLength != length) { 10933255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev ap.passwordHistoryLength = length; 10943255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev saveSettingsLocked(); 10953255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 10963255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 10973255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 10983255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 10993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev public int getPasswordHistoryLength(ComponentName who) { 11003255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev synchronized (this) { 11013255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev int length = 0; 11023255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 11033255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev if (who != null) { 11043255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 11053255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev return admin != null ? admin.passwordHistoryLength : length; 11063255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 11073255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 11083255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev final int N = mAdminList.size(); 11093255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev for (int i = 0; i < N; i++) { 11103255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev ActiveAdmin admin = mAdminList.get(i); 11113255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev if (length < admin.passwordHistoryLength) { 11123255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev length = admin.passwordHistoryLength; 11133255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 11143255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 11153255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev return length; 11163255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 11173255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 11183255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1119a4e28d181942018ba8759989799a28fa88764ce3Jim Miller public void setPasswordExpirationTimeout(ComponentName who, long timeout) { 1120a4e28d181942018ba8759989799a28fa88764ce3Jim Miller synchronized (this) { 1121a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (who == null) { 1122a4e28d181942018ba8759989799a28fa88764ce3Jim Miller throw new NullPointerException("ComponentName is null"); 1123a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 11241f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler if (timeout < 0) { 11251f35d487ba1a5208e66bc960f35f6e1d874fbd1eAndy Stadler throw new IllegalArgumentException("Timeout must be >= 0 ms"); 1126a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1127a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1128a4e28d181942018ba8759989799a28fa88764ce3Jim Miller DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD); 1129a4e28d181942018ba8759989799a28fa88764ce3Jim Miller // Calling this API automatically bumps the expiration date 1130a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L; 1131a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ap.passwordExpirationDate = expiration; 1132a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ap.passwordExpirationTimeout = timeout; 1133a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (timeout > 0L) { 1134a4e28d181942018ba8759989799a28fa88764ce3Jim Miller Slog.w(TAG, "setPasswordExpiration(): password will expire on " 1135a4e28d181942018ba8759989799a28fa88764ce3Jim Miller + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT) 1136a4e28d181942018ba8759989799a28fa88764ce3Jim Miller .format(new Date(expiration))); 1137a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1138a4e28d181942018ba8759989799a28fa88764ce3Jim Miller saveSettingsLocked(); 1139a4e28d181942018ba8759989799a28fa88764ce3Jim Miller setExpirationAlarmCheckLocked(mContext); // in case this is the first one 1140a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1141a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1142a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 1143043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler /** 1144043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler * Return a single admin's expiration cycle time, or the min of all cycle times. 1145043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler * Returns 0 if not configured. 1146043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler */ 1147a4e28d181942018ba8759989799a28fa88764ce3Jim Miller public long getPasswordExpirationTimeout(ComponentName who) { 1148a4e28d181942018ba8759989799a28fa88764ce3Jim Miller synchronized (this) { 1149a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (who != null) { 1150a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1151043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler return admin != null ? admin.passwordExpirationTimeout : 0L; 1152a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1153a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 1154043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler long timeout = 0L; 1155a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final int N = mAdminList.size(); 1156a4e28d181942018ba8759989799a28fa88764ce3Jim Miller for (int i = 0; i < N; i++) { 1157a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ActiveAdmin admin = mAdminList.get(i); 1158a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (timeout == 0L || (admin.passwordExpirationTimeout != 0L 1159a4e28d181942018ba8759989799a28fa88764ce3Jim Miller && timeout > admin.passwordExpirationTimeout)) { 1160a4e28d181942018ba8759989799a28fa88764ce3Jim Miller timeout = admin.passwordExpirationTimeout; 1161a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1162a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1163a4e28d181942018ba8759989799a28fa88764ce3Jim Miller return timeout; 1164a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1165a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1166a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 1167043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler /** 1168043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler * Return a single admin's expiration date/time, or the min (soonest) for all admins. 1169043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler * Returns 0 if not configured. 1170043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler */ 1171a4e28d181942018ba8759989799a28fa88764ce3Jim Miller private long getPasswordExpirationLocked(ComponentName who) { 1172a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (who != null) { 1173a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1174043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler return admin != null ? admin.passwordExpirationDate : 0L; 1175a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1176a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 1177043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler long timeout = 0L; 1178a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final int N = mAdminList.size(); 1179a4e28d181942018ba8759989799a28fa88764ce3Jim Miller for (int i = 0; i < N; i++) { 1180a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ActiveAdmin admin = mAdminList.get(i); 1181a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (timeout == 0L || (admin.passwordExpirationDate != 0 1182a4e28d181942018ba8759989799a28fa88764ce3Jim Miller && timeout > admin.passwordExpirationDate)) { 1183a4e28d181942018ba8759989799a28fa88764ce3Jim Miller timeout = admin.passwordExpirationDate; 1184a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1185a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1186a4e28d181942018ba8759989799a28fa88764ce3Jim Miller return timeout; 1187a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1188a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 1189a4e28d181942018ba8759989799a28fa88764ce3Jim Miller public long getPasswordExpiration(ComponentName who) { 1190a4e28d181942018ba8759989799a28fa88764ce3Jim Miller synchronized (this) { 1191a4e28d181942018ba8759989799a28fa88764ce3Jim Miller return getPasswordExpirationLocked(who); 1192a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1193a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1194a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 1195a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public void setPasswordMinimumUpperCase(ComponentName who, int length) { 1196a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1197a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who == null) { 1198a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev throw new NullPointerException("ComponentName is null"); 1199a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1200a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1201a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1202a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (ap.minimumPasswordUpperCase != length) { 1203a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ap.minimumPasswordUpperCase = length; 1204a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev saveSettingsLocked(); 1205a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1206a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1207a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1208a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1209a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public int getPasswordMinimumUpperCase(ComponentName who) { 1210a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1211a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int length = 0; 1212a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1213a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who != null) { 1214a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1215a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return admin != null ? admin.minimumPasswordUpperCase : length; 1216a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1217a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1218a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev final int N = mAdminList.size(); 1219a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev for (int i=0; i<N; i++) { 1220a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = mAdminList.get(i); 1221a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (length < admin.minimumPasswordUpperCase) { 1222a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev length = admin.minimumPasswordUpperCase; 1223a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1224a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1225a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return length; 1226a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1227a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1228a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1229a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public void setPasswordMinimumLowerCase(ComponentName who, int length) { 1230a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1231a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who == null) { 1232a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev throw new NullPointerException("ComponentName is null"); 1233a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1234a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1235a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1236a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (ap.minimumPasswordLowerCase != length) { 1237a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ap.minimumPasswordLowerCase = length; 1238a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev saveSettingsLocked(); 1239a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1240a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1241a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1242a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1243a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public int getPasswordMinimumLowerCase(ComponentName who) { 1244a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1245a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int length = 0; 1246a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1247a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who != null) { 1248a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1249a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return admin != null ? admin.minimumPasswordLowerCase : length; 1250a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1251a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1252a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev final int N = mAdminList.size(); 1253a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev for (int i=0; i<N; i++) { 1254a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = mAdminList.get(i); 1255a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (length < admin.minimumPasswordLowerCase) { 1256a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev length = admin.minimumPasswordLowerCase; 1257a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1258a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1259a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return length; 1260a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1261a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1262a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1263a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public void setPasswordMinimumLetters(ComponentName who, int length) { 1264a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1265a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who == null) { 1266a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev throw new NullPointerException("ComponentName is null"); 1267a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1268a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1269a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1270a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (ap.minimumPasswordLetters != length) { 1271a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ap.minimumPasswordLetters = length; 1272a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev saveSettingsLocked(); 1273a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1274a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1275a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1276a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1277a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public int getPasswordMinimumLetters(ComponentName who) { 1278a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1279a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int length = 0; 1280a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1281a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who != null) { 1282a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1283a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return admin != null ? admin.minimumPasswordLetters : length; 1284a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1285a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1286a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev final int N = mAdminList.size(); 1287a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev for (int i=0; i<N; i++) { 1288a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = mAdminList.get(i); 1289a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (length < admin.minimumPasswordLetters) { 1290a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev length = admin.minimumPasswordLetters; 1291a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1292a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1293a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return length; 1294a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1295a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1296a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1297a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public void setPasswordMinimumNumeric(ComponentName who, int length) { 1298a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1299a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who == null) { 1300a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev throw new NullPointerException("ComponentName is null"); 1301a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1302a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1303a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1304a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (ap.minimumPasswordNumeric != length) { 1305a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ap.minimumPasswordNumeric = length; 1306a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev saveSettingsLocked(); 1307a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1308a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1309a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1310a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1311a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public int getPasswordMinimumNumeric(ComponentName who) { 1312a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1313a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int length = 0; 1314a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1315a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who != null) { 1316a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1317a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return admin != null ? admin.minimumPasswordNumeric : length; 1318a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1319a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1320a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev final int N = mAdminList.size(); 1321a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev for (int i = 0; i < N; i++) { 1322a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = mAdminList.get(i); 1323a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (length < admin.minimumPasswordNumeric) { 1324a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev length = admin.minimumPasswordNumeric; 1325a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1326a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1327a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return length; 1328a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1329a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1330a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1331a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public void setPasswordMinimumSymbols(ComponentName who, int length) { 1332a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1333a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who == null) { 1334a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev throw new NullPointerException("ComponentName is null"); 1335a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1336a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1337a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1338a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (ap.minimumPasswordSymbols != length) { 1339a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ap.minimumPasswordSymbols = length; 1340a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev saveSettingsLocked(); 1341a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1342a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1343a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1344a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1345a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public int getPasswordMinimumSymbols(ComponentName who) { 1346a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev synchronized (this) { 1347a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int length = 0; 1348a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1349a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (who != null) { 1350a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1351a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return admin != null ? admin.minimumPasswordSymbols : length; 1352a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1353a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1354a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev final int N = mAdminList.size(); 1355a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev for (int i=0; i<N; i++) { 1356a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev ActiveAdmin admin = mAdminList.get(i); 1357a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (length < admin.minimumPasswordSymbols) { 1358a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev length = admin.minimumPasswordSymbols; 1359a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1360a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1361a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return length; 1362a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1363a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1364a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 1365c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev public void setPasswordMinimumNonLetter(ComponentName who, int length) { 1366c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev synchronized (this) { 1367c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev if (who == null) { 1368c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev throw new NullPointerException("ComponentName is null"); 1369c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1370c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1371c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1372c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev if (ap.minimumPasswordNonLetter != length) { 1373c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev ap.minimumPasswordNonLetter = length; 1374c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev saveSettingsLocked(); 1375c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1376c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1377c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1378c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev 1379c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev public int getPasswordMinimumNonLetter(ComponentName who) { 1380c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev synchronized (this) { 1381c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev int length = 0; 1382c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev 1383c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev if (who != null) { 1384c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1385c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev return admin != null ? admin.minimumPasswordNonLetter : length; 1386c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1387c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev 1388c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev final int N = mAdminList.size(); 1389c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev for (int i=0; i<N; i++) { 1390c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev ActiveAdmin admin = mAdminList.get(i); 1391c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev if (length < admin.minimumPasswordNonLetter) { 1392c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev length = admin.minimumPasswordNonLetter; 1393c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1394c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1395c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev return length; 1396c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1397c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1398c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev 1399df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn public boolean isActivePasswordSufficient() { 1400d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1401d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn // This API can only be called by an active device admin, 1402d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn // so try to retrieve it to check that the caller is one. 14038aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn getActiveAdminForCallerLocked(null, 14048aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1405a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (mActivePasswordQuality < getPasswordQuality(null) 1406a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev || mActivePasswordLength < getPasswordMinimumLength(null)) { 1407a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return false; 1408a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1409a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if(mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 1410a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return true; 1411a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1412a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null) 1413a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev && mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null) 1414a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev && mActivePasswordLetters >= getPasswordMinimumLetters(null) 1415a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev && mActivePasswordNumeric >= getPasswordMinimumNumeric(null) 1416c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev && mActivePasswordSymbols >= getPasswordMinimumSymbols(null) 1417c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev && mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null); 1418d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1419d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 14203255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1421d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public int getCurrentFailedPasswordAttempts() { 1422d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1423d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn // This API can only be called by an active device admin, 1424d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn // so try to retrieve it to check that the caller is one. 14258aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn getActiveAdminForCallerLocked(null, 14268aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 1427d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn return mFailedPasswordAttempts; 1428d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1429d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 14303255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 14318ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn public void setMaximumFailedPasswordsForWipe(ComponentName who, int num) { 14328ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn synchronized (this) { 14338ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn // This API can only be called by an active device admin, 14348ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn // so try to retrieve it to check that the caller is one. 14358ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn getActiveAdminForCallerLocked(who, 14368ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn DeviceAdminInfo.USES_POLICY_WIPE_DATA); 14378ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn ActiveAdmin ap = getActiveAdminForCallerLocked(who, 14388ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 14398ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if (ap.maximumFailedPasswordsForWipe != num) { 14408ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn ap.maximumFailedPasswordsForWipe = num; 14418ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn saveSettingsLocked(); 14428ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 14438ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 14448ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 14453255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1446254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn public int getMaximumFailedPasswordsForWipe(ComponentName who) { 14478ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn synchronized (this) { 1448d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn int count = 0; 14493255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1450254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (who != null) { 1451254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1452254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn return admin != null ? admin.maximumFailedPasswordsForWipe : count; 1453254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 14543255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1455254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn final int N = mAdminList.size(); 1456d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn for (int i=0; i<N; i++) { 1457d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ActiveAdmin admin = mAdminList.get(i); 1458d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (count == 0) { 1459d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn count = admin.maximumFailedPasswordsForWipe; 1460d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } else if (admin.maximumFailedPasswordsForWipe != 0 1461d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn && count > admin.maximumFailedPasswordsForWipe) { 1462d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn count = admin.maximumFailedPasswordsForWipe; 1463d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1464d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1465d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return count; 14668ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 14678ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 14683255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 146987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn public boolean resetPassword(String password, int flags) { 14709327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn int quality; 1471df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn synchronized (this) { 1472df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn // This API can only be called by an active device admin, 1473df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn // so try to retrieve it to check that the caller is one. 14748aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn getActiveAdminForCallerLocked(null, 14758aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_RESET_PASSWORD); 14769327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn quality = getPasswordQuality(null); 14779327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 147885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn int realQuality = LockPatternUtils.computePasswordQuality(password); 1479a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (realQuality < quality 1480a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 148185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "resetPassword: password quality 0x" 148285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn + Integer.toHexString(quality) 148385f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn + " does not meet required quality 0x" 148485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn + Integer.toHexString(quality)); 14859327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn return false; 14869327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn } 1487a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev quality = Math.max(realQuality, quality); 14889327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn } 14899327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn int length = getPasswordMinimumLength(null); 14909327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn if (password.length() < length) { 149185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "resetPassword: password length " + password.length() 149285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn + " does not meet required length " + length); 1493df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn return false; 1494df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 1495a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 1496a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int letters = 0; 1497a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int uppercase = 0; 1498a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int lowercase = 0; 1499a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int numbers = 0; 1500a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int symbols = 0; 1501c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev int nonletter = 0; 1502a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev for (int i = 0; i < password.length(); i++) { 1503a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev char c = password.charAt(i); 1504a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (c >= 'A' && c <= 'Z') { 1505a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev letters++; 1506a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev uppercase++; 1507a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } else if (c >= 'a' && c <= 'z') { 1508a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev letters++; 1509a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev lowercase++; 1510a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } else if (c >= '0' && c <= '9') { 1511a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev numbers++; 1512c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev nonletter++; 1513a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } else { 1514a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev symbols++; 1515c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev nonletter++; 1516a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1517a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1518a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int neededLetters = getPasswordMinimumLetters(null); 1519a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if(letters < neededLetters) { 1520a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev Slog.w(TAG, "resetPassword: number of letters " + letters 1521a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev + " does not meet required number of letters " + neededLetters); 1522a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return false; 1523a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1524a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int neededNumbers = getPasswordMinimumNumeric(null); 1525a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (numbers < neededNumbers) { 1526a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev Slog 1527a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev .w(TAG, "resetPassword: number of numerical digits " + numbers 1528a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev + " does not meet required number of numerical digits " 1529a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev + neededNumbers); 1530a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return false; 1531a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1532a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int neededLowerCase = getPasswordMinimumLowerCase(null); 1533a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (lowercase < neededLowerCase) { 1534a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase 1535a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev + " does not meet required number of lowercase letters " 1536a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev + neededLowerCase); 1537a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return false; 1538a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1539a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int neededUpperCase = getPasswordMinimumUpperCase(null); 1540a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (uppercase < neededUpperCase) { 1541a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase 1542a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev + " does not meet required number of uppercase letters " 1543a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev + neededUpperCase); 1544a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return false; 1545a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1546a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev int neededSymbols = getPasswordMinimumSymbols(null); 1547a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev if (symbols < neededSymbols) { 1548a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev Slog.w(TAG, "resetPassword: number of special symbols " + symbols 1549a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev + " does not meet required number of special symbols " + neededSymbols); 1550a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev return false; 1551a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1552c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev int neededNonLetter = getPasswordMinimumNonLetter(null); 1553c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev if (nonletter < neededNonLetter) { 1554c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev Slog.w(TAG, "resetPassword: number of non-letter characters " + nonletter 1555c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev + " does not meet required number of non-letter characters " 1556c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev + neededNonLetter); 1557c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev return false; 1558c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 1559a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 1560df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 15613255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 156287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn int callingUid = Binder.getCallingUid(); 156387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (mPasswordOwner >= 0 && mPasswordOwner != callingUid) { 156485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "resetPassword: already set by another uid and not entered by user"); 156587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn return false; 156687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 15673255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1568df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn // Don't do this with the lock held, because it is going to call 1569df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn // back in to the service. 1570df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn long ident = Binder.clearCallingIdentity(); 1571df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn try { 1572df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn LockPatternUtils utils = new LockPatternUtils(mContext); 15739327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn utils.saveLockPassword(password, quality); 157485f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn synchronized (this) { 157585f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn int newOwner = (flags&DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) 157685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn != 0 ? callingUid : -1; 157785f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn if (mPasswordOwner != newOwner) { 157885f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn mPasswordOwner = newOwner; 157985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn saveSettingsLocked(); 158085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn } 158187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 1582df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } finally { 1583df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn Binder.restoreCallingIdentity(ident); 1584df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 15853255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1586df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn return true; 1587df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 15883255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1589d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public void setMaximumTimeToLock(ComponentName who, long timeMs) { 1590d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1591d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (who == null) { 1592d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn throw new NullPointerException("ComponentName is null"); 1593d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 15948aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1595315ada7fbb9e967c22e87b4921bec720ceb2c73cDianne Hackborn DeviceAdminInfo.USES_POLICY_FORCE_LOCK); 1596d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn if (ap.maximumTimeToUnlock != timeMs) { 1597d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn ap.maximumTimeToUnlock = timeMs; 15983255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1599df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn long ident = Binder.clearCallingIdentity(); 1600df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn try { 1601df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn saveSettingsLocked(); 16023255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1603254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn timeMs = getMaximumTimeToLock(null); 1604df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn if (timeMs <= 0) { 1605df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn timeMs = Integer.MAX_VALUE; 1606df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 16073255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1608df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn try { 1609df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn getIPowerManager().setMaximumScreenOffTimeount((int)timeMs); 1610df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } catch (RemoteException e) { 161185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn Slog.w(TAG, "Failure talking with power manager", e); 1612df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 1613df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } finally { 1614df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn Binder.restoreCallingIdentity(ident); 1615df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 1616d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1617d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1618d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 16193255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1620254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn public long getMaximumTimeToLock(ComponentName who) { 1621d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1622d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn long time = 0; 16233255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1624254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn if (who != null) { 1625254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1626254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn return admin != null ? admin.maximumTimeToUnlock : time; 1627254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 16283255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1629254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn final int N = mAdminList.size(); 1630d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn for (int i=0; i<N; i++) { 1631d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn ActiveAdmin admin = mAdminList.get(i); 1632d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn if (time == 0) { 1633d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn time = admin.maximumTimeToUnlock; 1634d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } else if (admin.maximumTimeToUnlock != 0 1635d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn && time > admin.maximumTimeToUnlock) { 1636d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn time = admin.maximumTimeToUnlock; 1637d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1638d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn } 1639d47c6ed4a9f2b5bd31f6c806b74701428efe458bDianne Hackborn return time; 1640d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1641d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 16423255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1643df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn public void lockNow() { 1644df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn synchronized (this) { 1645df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn // This API can only be called by an active device admin, 1646df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn // so try to retrieve it to check that the caller is one. 16478aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn getActiveAdminForCallerLocked(null, 16488aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_FORCE_LOCK); 1649254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn long ident = Binder.clearCallingIdentity(); 1650254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn try { 1651254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn mIPowerManager.goToSleepWithReason(SystemClock.uptimeMillis(), 1652254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN); 1653254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } catch (RemoteException e) { 1654254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } finally { 1655254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn Binder.restoreCallingIdentity(ident); 1656254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn } 1657df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 1658df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 16593255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1660ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo private boolean isExtStorageEncrypted() { 1661ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo String state = SystemProperties.get("vold.decrypt"); 1662ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo return !"".equals(state); 1663ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo } 1664ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo 16658ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn void wipeDataLocked(int flags) { 1666ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo // If the SD card is encrypted and non-removable, we have to force a wipe. 1667ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted(); 1668ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0; 1669ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo 1670ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated. 1671ed48c8b4f50e060add50ad72a8d7af2fa547885bBen Komalo if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) { 1672424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET); 1673424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME); 1674424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn mWakeLock.acquire(10000); 1675424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn mContext.startService(intent); 1676424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn } else { 1677424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn try { 1678424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn RecoverySystem.rebootWipeUserData(mContext); 1679424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn } catch (IOException e) { 1680424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn Slog.w(TAG, "Failed requesting data wipe", e); 1681424991704b5fb7a64f6cf0fcc3f4b1aabbf2a2e0Dianne Hackborn } 16828ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 16838ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 16843255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1685d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public void wipeData(int flags) { 1686d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1687d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn // This API can only be called by an active device admin, 1688d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn // so try to retrieve it to check that the caller is one. 16898aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn getActiveAdminForCallerLocked(null, 16908aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_WIPE_DATA); 16918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn long ident = Binder.clearCallingIdentity(); 16928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn try { 16938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn wipeDataLocked(flags); 16948ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } finally { 16958ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn Binder.restoreCallingIdentity(ident); 16968ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 1697df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 16988ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 16993255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 17008ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn public void getRemoveWarning(ComponentName comp, final RemoteCallback result) { 17018ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn mContext.enforceCallingOrSelfPermission( 17028ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn android.Manifest.permission.BIND_DEVICE_ADMIN, null); 17033255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 17048ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn synchronized (this) { 17058ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn ActiveAdmin admin = getActiveAdminUncheckedLocked(comp); 17068ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if (admin == null) { 17078ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn try { 17088ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn result.sendResult(null); 17098ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } catch (RemoteException e) { 17108ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 17118ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn return; 17128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 1713ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED); 17148ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn intent.setComponent(admin.info.getComponent()); 17158ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { 17168ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn @Override 17178ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn public void onReceive(Context context, Intent intent) { 17188ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn try { 17198ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn result.sendResult(getResultExtras(false)); 17208ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } catch (RemoteException e) { 17218ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 17228ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 17238ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn }, null, Activity.RESULT_OK, null, null); 1724d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1725d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 17263255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1727a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev public void setActivePasswordState(int quality, int length, int letters, int uppercase, 1728c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev int lowercase, int numbers, int symbols, int nonletter) { 1729d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mContext.enforceCallingOrSelfPermission( 1730d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn android.Manifest.permission.BIND_DEVICE_ADMIN, null); 17313255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 173285f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn validateQualityConstant(quality); 17333255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1734d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 17359327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn if (mActivePasswordQuality != quality || mActivePasswordLength != length 1736a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev || mFailedPasswordAttempts != 0 || mActivePasswordLetters != letters 1737a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev || mActivePasswordUpperCase != uppercase 1738a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev || mActivePasswordLowerCase != lowercase || mActivePasswordNumeric != numbers 1739c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev || mActivePasswordSymbols != symbols || mActivePasswordNonLetter != nonletter) { 1740d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn long ident = Binder.clearCallingIdentity(); 1741d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 17429327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn mActivePasswordQuality = quality; 1743d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mActivePasswordLength = length; 1744a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordLetters = letters; 1745a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordLowerCase = lowercase; 1746a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordUpperCase = uppercase; 1747a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordNumeric = numbers; 1748a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev mActivePasswordSymbols = symbols; 1749c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev mActivePasswordNonLetter = nonletter; 175085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn mFailedPasswordAttempts = 0; 175185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn saveSettingsLocked(); 1752a4e28d181942018ba8759989799a28fa88764ce3Jim Miller updatePasswordExpirationsLocked(); 1753043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler setExpirationAlarmCheckLocked(mContext); 1754ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED, 17558aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1756d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } finally { 1757d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn Binder.restoreCallingIdentity(ident); 1758d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1759d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1760d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1761d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 17623255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1763043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler /** 1764043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler * Called any time the device password is updated. Resets all password expiration clocks. 1765043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler */ 1766a4e28d181942018ba8759989799a28fa88764ce3Jim Miller private void updatePasswordExpirationsLocked() { 1767a4e28d181942018ba8759989799a28fa88764ce3Jim Miller final int N = mAdminList.size(); 1768a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (N > 0) { 1769a4e28d181942018ba8759989799a28fa88764ce3Jim Miller for (int i=0; i<N; i++) { 1770a4e28d181942018ba8759989799a28fa88764ce3Jim Miller ActiveAdmin admin = mAdminList.get(i); 1771a4e28d181942018ba8759989799a28fa88764ce3Jim Miller if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) { 1772043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler long timeout = admin.passwordExpirationTimeout; 1773043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L; 1774043116a572c2bcb9dad4c264b38e252861fa54b4Andy Stadler admin.passwordExpirationDate = expiration; 1775a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1776a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1777a4e28d181942018ba8759989799a28fa88764ce3Jim Miller saveSettingsLocked(); 1778a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1779a4e28d181942018ba8759989799a28fa88764ce3Jim Miller } 1780a4e28d181942018ba8759989799a28fa88764ce3Jim Miller 1781d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public void reportFailedPasswordAttempt() { 1782d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mContext.enforceCallingOrSelfPermission( 1783d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn android.Manifest.permission.BIND_DEVICE_ADMIN, null); 17843255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1785d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 1786d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn long ident = Binder.clearCallingIdentity(); 1787d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 1788d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mFailedPasswordAttempts++; 17898ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn saveSettingsLocked(); 1790254cb446faa7cb13699d8150eb4cc4f44cb61a2dDianne Hackborn int max = getMaximumFailedPasswordsForWipe(null); 17918ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn if (max > 0 && mFailedPasswordAttempts >= max) { 17928ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn wipeDataLocked(0); 17938ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn } 1794ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED, 17958aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 1796d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } finally { 1797d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn Binder.restoreCallingIdentity(ident); 1798d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1799d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1800d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 18013255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1802d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn public void reportSuccessfulPasswordAttempt() { 1803d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mContext.enforceCallingOrSelfPermission( 1804d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn android.Manifest.permission.BIND_DEVICE_ADMIN, null); 18053255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 1806d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn synchronized (this) { 180787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (mFailedPasswordAttempts != 0 || mPasswordOwner >= 0) { 1808d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn long ident = Binder.clearCallingIdentity(); 1809d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn try { 1810d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn mFailedPasswordAttempts = 0; 181187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn mPasswordOwner = -1; 18128ea138cbf12b140d43fd81f4f12fe1a9234f1f25Dianne Hackborn saveSettingsLocked(); 1813ef6b22fc04a8d5ab26e13efac8069c097e0da7c9Dianne Hackborn sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED, 18148aa2e8939c61d788cbc192098465e79f584e173aDianne Hackborn DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 1815d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } finally { 1816d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn Binder.restoreCallingIdentity(ident); 1817d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1818d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1819d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 1820d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn } 18213255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 182269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor public ComponentName setGlobalProxy(ComponentName who, String proxySpec, 182369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor String exclusionList) { 182469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor synchronized(this) { 182569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (who == null) { 182669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor throw new NullPointerException("ComponentName is null"); 182769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 182869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 182969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor ActiveAdmin admin = getActiveAdminForCallerLocked(who, 183069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY); 183169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 183269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Scan through active admins and find if anyone has already 183369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // set the global proxy. 183469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor Set<ComponentName> compSet = mAdminMap.keySet(); 183569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor for (ComponentName component : compSet) { 183669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor ActiveAdmin ap = mAdminMap.get(component); 183769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if ((ap.specifiesGlobalProxy) && (!component.equals(who))) { 183869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Another admin already sets the global proxy 183969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Return it to the caller. 184069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor return component; 184169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 184269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 184369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (proxySpec == null) { 184469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor admin.specifiesGlobalProxy = false; 184569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor admin.globalProxySpec = null; 184669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor admin.globalProxyExclusionList = null; 184769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } else { 184869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 184969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor admin.specifiesGlobalProxy = true; 185069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor admin.globalProxySpec = proxySpec; 185169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor admin.globalProxyExclusionList = exclusionList; 185269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 185369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 185469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Reset the global proxy accordingly 185569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Do this using system permissions, as apps cannot write to secure settings 185669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor long origId = Binder.clearCallingIdentity(); 185769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor resetGlobalProxy(); 185869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor Binder.restoreCallingIdentity(origId); 185969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor return null; 186069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 186169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 186269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 186369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor public ComponentName getGlobalProxyAdmin() { 186469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor synchronized(this) { 186569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Scan through active admins and find if anyone has already 186669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // set the global proxy. 186769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor final int N = mAdminList.size(); 186869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor for (int i = 0; i < N; i++) { 186969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor ActiveAdmin ap = mAdminList.get(i); 187069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (ap.specifiesGlobalProxy) { 187169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Device admin sets the global proxy 187269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Return it to the caller. 187369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor return ap.info.getComponent(); 187469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 187569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 187669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 187769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // No device admin sets the global proxy. 187869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor return null; 187969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 188069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 188169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor private void resetGlobalProxy() { 188269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor final int N = mAdminList.size(); 188369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor for (int i = 0; i < N; i++) { 188469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor ActiveAdmin ap = mAdminList.get(i); 188569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (ap.specifiesGlobalProxy) { 188669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor saveGlobalProxy(ap.globalProxySpec, ap.globalProxyExclusionList); 188769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor return; 188869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 188969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 189069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // No device admins defining global proxies - reset global proxy settings to none 189169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor saveGlobalProxy(null, null); 189269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 189369238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 189469238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor private void saveGlobalProxy(String proxySpec, String exclusionList) { 189569238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (exclusionList == null) { 189669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor exclusionList = ""; 189769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 189869238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor if (proxySpec == null) { 189969238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor proxySpec = ""; 190069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 190169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor // Remove white spaces 190269238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor proxySpec = proxySpec.trim(); 1903434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt String data[] = proxySpec.split(":"); 1904434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt int proxyPort = 8080; 1905434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt if (data.length > 1) { 1906434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt try { 1907434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt proxyPort = Integer.parseInt(data[1]); 1908434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt } catch (NumberFormatException e) {} 1909434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt } 191069238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor exclusionList = exclusionList.trim(); 191169238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor ContentResolver res = mContext.getContentResolver(); 1912434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt Settings.Secure.putString(res, Settings.Secure.GLOBAL_HTTP_PROXY_HOST, data[0]); 1913434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt Settings.Secure.putInt(res, Settings.Secure.GLOBAL_HTTP_PROXY_PORT, proxyPort); 1914434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt Settings.Secure.putString(res, Settings.Secure.GLOBAL_HTTP_PROXY_EXCLUSION_LIST, 1915434203a277cd2f237a71508a3d5a7d1602126cd5Robert Greenwalt exclusionList); 191669238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor } 191769238c6a37ae43c748ad9cd7613f2209149ee7daOscar Montemayor 19187b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler /** 191922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * Set the storage encryption request for a single admin. Returns the new total request 192022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * status (for all admins). 19217b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler */ 19227b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler public int setStorageEncryption(ComponentName who, boolean encrypt) { 19237b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler synchronized (this) { 19247b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler // Check for permissions 19257b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler if (who == null) { 19267b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler throw new NullPointerException("ComponentName is null"); 19277b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler } 19287b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler ActiveAdmin ap = getActiveAdminForCallerLocked(who, 19297b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler DeviceAdminInfo.USES_ENCRYPTED_STORAGE); 19307b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler 193122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // Quick exit: If the filesystem does not support encryption, we can exit early. 193222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler if (!isEncryptionSupported()) { 193322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 193422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 193522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler 193622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // (1) Record the value for the admin so it's sticky 193722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler if (ap.encryptionRequested != encrypt) { 193822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler ap.encryptionRequested = encrypt; 193922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler saveSettingsLocked(); 194022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 194122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler 194222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // (2) Compute "max" for all admins 194322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler boolean newRequested = false; 194422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler final int N = mAdminList.size(); 194522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler for (int i = 0; i < N; i++) { 194622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler newRequested |= mAdminList.get(i).encryptionRequested; 194722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 194822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler 194922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // Notify OS of new request 195022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler setEncryptionRequested(newRequested); 195122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler 195222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // Return the new global request status 195322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler return newRequested 195422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE 195522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler : DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE; 19567b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler } 19577b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler } 19587b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler 19597b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler /** 196022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * Get the current storage encryption request status for a given admin, or aggregate of all 196122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * active admins. 19627b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler */ 196322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler public boolean getStorageEncryption(ComponentName who) { 19647b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler synchronized (this) { 19657b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler // Check for permissions if a particular caller is specified 19667b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler if (who != null) { 196722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // When checking for a single caller, status is based on caller's request 1968c994d693b684bcba1a690310b5b2be306074cc02Andy Stadler ActiveAdmin ap = getActiveAdminUncheckedLocked(who); 1969c994d693b684bcba1a690310b5b2be306074cc02Andy Stadler return ap != null ? ap.encryptionRequested : false; 19707b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler } 19717b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler 197222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // If no particular caller is specified, return the aggregate set of requests. 197322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // This is short circuited by returning true on the first hit. 197422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler final int N = mAdminList.size(); 197522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler for (int i = 0; i < N; i++) { 197622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler if (mAdminList.get(i).encryptionRequested) { 197722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler return true; 197822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 197922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 198022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler return false; 19817b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler } 19827b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler } 19837b0f8f08ac7b3ed5cf462b92283713b033d6a64aAndy Stadler 198422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler /** 198522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * Get the current encryption status of the device. 198622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler */ 198722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler public int getStorageEncryptionStatus() { 198822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler return getEncryptionStatus(); 198922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 199022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler 199122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler /** 199222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * Hook to low-levels: This should report if the filesystem supports encrypted storage. 199322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler */ 199422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler private boolean isEncryptionSupported() { 199522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // Note, this can be implemented as 199622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 199722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // But is provided as a separate internal method if there's a faster way to do a 199822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler // simple check for supported-or-not. 199922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 200022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 200122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler 200222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler /** 200322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * Hook to low-levels: Reporting the current status of encryption. 200422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED} or 200522dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE} or 200622dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}. 200722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler */ 200822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler private int getEncryptionStatus() { 20090fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler String status = SystemProperties.get("ro.crypto.state", "unsupported"); 20100fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler if ("encrypted".equalsIgnoreCase(status)) { 20110fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE; 20120fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler } else if ("unencrypted".equalsIgnoreCase(status)) { 20130fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE; 20140fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler } else { 20150fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 20160fe45dea927dc87c19d6afd4502658b36177aa07Andy Stadler } 201722dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 201822dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler 201922dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler /** 202022dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler * Hook to low-levels: If needed, record the new admin setting for encryption. 202122dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler */ 202222dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler private void setEncryptionRequested(boolean encrypt) { 202322dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler } 202422dbfda976aab9ae897eed0625e2e64ead32bbc4Andy Stadler 20252447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo /** 20262447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo * The system property used to share the state of the camera. The native camera service 20272447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo * is expected to read this property and act accordingly. 20282447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo */ 20292447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo public static final String SYSTEM_PROP_DISABLE_CAMERA = "sys.secpolicy.camera.disabled"; 20302447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo 20312447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo /** 20322447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo * Disables all device cameras according to the specified admin. 20332447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo */ 20342447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo public void setCameraDisabled(ComponentName who, boolean disabled) { 20352447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo synchronized (this) { 20362447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo if (who == null) { 20372447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo throw new NullPointerException("ComponentName is null"); 20382447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20392447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo ActiveAdmin ap = getActiveAdminForCallerLocked(who, 20402447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA); 20412447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo if (ap.disableCamera != disabled) { 20422447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo ap.disableCamera = disabled; 20432447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo saveSettingsLocked(); 20442447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20452447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo syncDeviceCapabilitiesLocked(); 20462447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20472447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20482447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo 20492447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo /** 20502447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo * Gets whether or not all device cameras are disabled for a given admin, or disabled for any 20512447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo * active admins. 20522447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo */ 20532447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo public boolean getCameraDisabled(ComponentName who) { 20542447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo synchronized (this) { 20552447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo if (who != null) { 20562447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 20572447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo return (admin != null) ? admin.disableCamera : false; 20582447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20592447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo 20602447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo // Determine whether or not the device camera is disabled for any active admins. 20612447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo final int N = mAdminList.size(); 20622447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo for (int i = 0; i < N; i++) { 20632447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo ActiveAdmin admin = mAdminList.get(i); 20642447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo if (admin.disableCamera) { 20652447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo return true; 20662447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20672447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20682447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo return false; 20692447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20702447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo } 20712447edd85baac3225a12b868ef40f76cfdc6ec11Ben Komalo 207287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn @Override 207387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 207487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 207587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn != PackageManager.PERMISSION_GRANTED) { 207687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn 207787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid=" 207887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn + Binder.getCallingPid() 207987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn + ", uid=" + Binder.getCallingUid()); 208087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn return; 208187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 20823255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 208387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn final Printer p = new PrintWriterPrinter(pw); 20843255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 208587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn synchronized (this) { 208687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn p.println("Current Device Policy Manager state:"); 20873255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 208887bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn p.println(" Enabled Device Admins:"); 208987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn final int N = mAdminList.size(); 209087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn for (int i=0; i<N; i++) { 209187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn ActiveAdmin ap = mAdminList.get(i); 209287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn if (ap != null) { 209387bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(" "); pw.print(ap.info.getComponent().flattenToShortString()); 209487bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.println(":"); 209587bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn ap.dump(" ", pw); 209687bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 209787bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 20983255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 209987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.println(" "); 210085f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn pw.print(" mActivePasswordQuality=0x"); 210185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn pw.println(Integer.toHexString(mActivePasswordQuality)); 210287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(" mActivePasswordLength="); pw.println(mActivePasswordLength); 2103a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(" mActivePasswordUpperCase="); pw.println(mActivePasswordUpperCase); 2104a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(" mActivePasswordLowerCase="); pw.println(mActivePasswordLowerCase); 2105a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(" mActivePasswordLetters="); pw.println(mActivePasswordLetters); 2106a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(" mActivePasswordNumeric="); pw.println(mActivePasswordNumeric); 2107a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev pw.print(" mActivePasswordSymbols="); pw.println(mActivePasswordSymbols); 2108c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev pw.print(" mActivePasswordNonLetter="); pw.println(mActivePasswordNonLetter); 210987bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(" mFailedPasswordAttempts="); pw.println(mFailedPasswordAttempts); 211087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn pw.print(" mPasswordOwner="); pw.println(mPasswordOwner); 211187bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 211287bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackborn } 2113d68478467e3f837511196c80891d7245d0e163dfDianne Hackborn} 2114