19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19682d16758010e311910133fb40868133c05b3fe6Rubin Xuimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; 20682d16758010e311910133fb40868133c05b3fe6Rubin Xuimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; 21682d16758010e311910133fb40868133c05b3fe6Rubin Xuimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; 22682d16758010e311910133fb40868133c05b3fe6Rubin Xuimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED; 23682d16758010e311910133fb40868133c05b3fe6Rubin Xuimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; 24682d16758010e311910133fb40868133c05b3fe6Rubin Xuimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; 25682d16758010e311910133fb40868133c05b3fe6Rubin Xuimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; 26682d16758010e311910133fb40868133c05b3fe6Rubin Xuimport static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 27682d16758010e311910133fb40868133c05b3fe6Rubin Xu 28b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roosimport android.annotation.IntDef; 29e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggiimport android.annotation.Nullable; 3087bba1ee14279bb14a28d42e27c4ef66d9967bf8Dianne Hackbornimport android.app.admin.DevicePolicyManager; 315f9e6f37b276fac7be6db982c9cb7fbd93150c4aAndrew Scullimport android.app.admin.PasswordMetrics; 32b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roosimport android.app.trust.IStrongAuthTracker; 3382142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roosimport android.app.trust.TrustManager; 3482142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roosimport android.content.ComponentName; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 3631f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Millerimport android.content.Context; 37a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarriimport android.content.pm.UserInfo; 383a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrenceimport android.os.AsyncTask; 39b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roosimport android.os.Handler; 40f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parksimport android.os.IBinder; 41aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xiaimport android.os.Looper; 42b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roosimport android.os.Message; 4369ac9887459a65a0eebc6f9c450a5b6c2313d713Jim Millerimport android.os.RemoteException; 4469ac9887459a65a0eebc6f9c450a5b6c2313d713Jim Millerimport android.os.ServiceManager; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 46f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 47a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarriimport android.os.UserManager; 482250d56a0b47b93016018340c8f4040325aa5611Sudheer Shankaimport android.os.storage.IStorageManager; 498e39736f91a08961cf59c87075e61d9026833b50Paul Lawrenceimport android.os.storage.StorageManager; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 53b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roosimport android.util.SparseIntArray; 54a3e5582fac1cc259022c06d027e73c767dc1c117Kevin Chynimport android.util.SparseLongArray; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 560cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xuimport com.android.internal.annotations.VisibleForTesting; 57fcd49f993ede363d0b17900565dfe37066362480Rubin Xuimport com.android.server.LocalServices; 581254f2f42f7173ef51d0034975ab5cb7d44f8209Michael Jurkaimport com.google.android.collect.Lists; 599dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 601de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xuimport libcore.util.HexEncoding; 611de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu 62b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roosimport java.lang.annotation.Retention; 63b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roosimport java.lang.annotation.RetentionPolicy; 6478108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamathimport java.nio.charset.StandardCharsets; 65929a1c219248b62778807cac8ea256c7ac0fda6aBrian Carlstromimport java.security.MessageDigest; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.security.NoSuchAlgorithmException; 6711b019d07f4de0b25e2f863a7bcaad112d847d56Jim Millerimport java.security.SecureRandom; 6882142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roosimport java.util.ArrayList; 69f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xuimport java.util.Arrays; 7082142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roosimport java.util.Collection; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 72f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xuimport java.util.StringJoiner; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 745cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom * Utilities for the lock pattern and its settings. 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class LockPatternUtils { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "LockPatternUtils"; 79a0ee004abf1e8988ece2d19ff5a3bef333763c9bBrian Colonna private static final boolean DEBUG = false; 808370e472cdf22d30e5485c8cdd884767ea482571Adrian Roos private static final boolean FRP_CREDENTIAL_ENABLED = true; 8169aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 831de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * The key to identify when the lock pattern enabled flag is being accessed for legacy reasons. 844614596a395b6c86fff3f35a07edda2e848d743cBryce Lee */ 854614596a395b6c86fff3f35a07edda2e848d743cBryce Lee public static final String LEGACY_LOCK_PATTERN_ENABLED = "legacy_lock_pattern_enabled"; 864614596a395b6c86fff3f35a07edda2e848d743cBryce Lee 874614596a395b6c86fff3f35a07edda2e848d743cBryce Lee /** 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The number of incorrect attempts before which we fall back on an alternative 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method of verifying the user, and resetting their lock pattern. 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int FAILED_ATTEMPTS_BEFORE_RESET = 20; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The interval of the countdown for showing progress of the lockout. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final long FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS = 1000L; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 984f36995777a4136e8e63ea51cef2ff61df48790dJim Miller 994f36995777a4136e8e63ea51cef2ff61df48790dJim Miller /** 1004f36995777a4136e8e63ea51cef2ff61df48790dJim Miller * This dictates when we start telling the user that continued failed attempts will wipe 1014f36995777a4136e8e63ea51cef2ff61df48790dJim Miller * their device. 1024f36995777a4136e8e63ea51cef2ff61df48790dJim Miller */ 1034f36995777a4136e8e63ea51cef2ff61df48790dJim Miller public static final int FAILED_ATTEMPTS_BEFORE_WIPE_GRACE = 5; 1044f36995777a4136e8e63ea51cef2ff61df48790dJim Miller 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The minimum number of dots in a valid pattern. 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MIN_LOCK_PATTERN_SIZE = 4; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 111f80e66ce9a57c4d3abf97e582c89292623b3904dAdrian Roos * The minimum size of a valid password. 112f80e66ce9a57c4d3abf97e582c89292623b3904dAdrian Roos */ 113f80e66ce9a57c4d3abf97e582c89292623b3904dAdrian Roos public static final int MIN_LOCK_PASSWORD_SIZE = 4; 114f80e66ce9a57c4d3abf97e582c89292623b3904dAdrian Roos 115f80e66ce9a57c4d3abf97e582c89292623b3904dAdrian Roos /** 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The minimum number of dots the user must include in a wrong pattern 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attempt for it to be counted against the counts that affect 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #FAILED_ATTEMPTS_BEFORE_TIMEOUT} and {@link #FAILED_ATTEMPTS_BEFORE_RESET} 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1204f36995777a4136e8e63ea51cef2ff61df48790dJim Miller public static final int MIN_PATTERN_REGISTER_FAIL = MIN_LOCK_PATTERN_SIZE; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1221de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu public static final int CREDENTIAL_TYPE_NONE = -1; 1231de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu 1241de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu public static final int CREDENTIAL_TYPE_PATTERN = 1; 1251de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu 1261de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu public static final int CREDENTIAL_TYPE_PASSWORD = 2; 1271de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu 1287374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos /** 1297374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos * Special user id for triggering the FRP verification flow. 1307374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos */ 1317374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos public static final int USER_FRP = UserHandle.USER_NULL + 1; 1327374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos 1339dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos @Deprecated 1347a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently"; 1357a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen"; 13669aa4a953f040277c19c23208bb830f52796c8c6Jim Miller public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type"; 137230635efe7ffb09d6dc56bfd9193aa1d89c8a898Adrian Roos @Deprecated 138230635efe7ffb09d6dc56bfd9193aa1d89c8a898Adrian Roos public final static String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate"; 1397a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt"; 1407a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled"; 1417a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public final static String LOCKSCREEN_OPTIONS = "lockscreen.options"; 142230635efe7ffb09d6dc56bfd9193aa1d89c8a898Adrian Roos @Deprecated 1436edf2637e96139735df83907c221cce16d4d7eaaJim Miller public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK 1446edf2637e96139735df83907c221cce16d4d7eaaJim Miller = "lockscreen.biometric_weak_fallback"; 145230635efe7ffb09d6dc56bfd9193aa1d89c8a898Adrian Roos @Deprecated 1467a07219a1fc8cb94ea2694025e26f70d652ad2a1Danielle Millett public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY 1477a07219a1fc8cb94ea2694025e26f70d652ad2a1Danielle Millett = "lockscreen.biometricweakeverchosen"; 148a4edd151c5266a2c794c95444fed67d19740cee3Jim Miller public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS 149a4edd151c5266a2c794c95444fed67d19740cee3Jim Miller = "lockscreen.power_button_instantly_locks"; 150230635efe7ffb09d6dc56bfd9193aa1d89c8a898Adrian Roos @Deprecated 151f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller public final static String LOCKSCREEN_WIDGETS_ENABLED = "lockscreen.widgets_enabled"; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1537a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey public final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory"; 154863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev 155187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller private static final String LOCK_SCREEN_OWNER_INFO = Settings.Secure.LOCK_SCREEN_OWNER_INFO; 156187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller private static final String LOCK_SCREEN_OWNER_INFO_ENABLED = 157187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED; 158187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller 1596644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu private static final String LOCK_SCREEN_DEVICE_OWNER_INFO = "lockscreen.device_owner_info"; 1606644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu 16182142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents"; 162c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged"; 16382142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos 164d398244513c62c9ea14a0f1c6ffef832e803c16fRicky Wai public static final String PROFILE_KEY_NAME_ENCRYPT = "profile_key_name_encrypt_"; 165d398244513c62c9ea14a0f1c6ffef832e803c16fRicky Wai public static final String PROFILE_KEY_NAME_DECRYPT = "profile_key_name_decrypt_"; 1663bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu public static final String SYNTHETIC_PASSWORD_KEY_PREFIX = "synthetic_password_"; 1673bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 1683bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu public static final String SYNTHETIC_PASSWORD_HANDLE_KEY = "sp-handle"; 1693bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp"; 170f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu private static final String HISTORY_DELIMITER = ","; 171d398244513c62c9ea14a0f1c6ffef832e803c16fRicky Wai 172df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn private final Context mContext; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ContentResolver mContentResolver; 17431f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller private DevicePolicyManager mDevicePolicyManager; 17552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private ILockSettings mLockSettingsService; 176a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri private UserManager mUserManager; 1777a3bf7c46e54cf226f86e3eeedb100a159f08d00Adrian Roos private final Handler mHandler; 178a3e5582fac1cc259022c06d027e73c767dc1c117Kevin Chyn private final SparseLongArray mLockoutDeadlines = new SparseLongArray(); 179ee82f8fa2d47fc1dbfc29582ae348b3c45ff8fe0Jim Miller 180c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos /** 181c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos * Use {@link TrustManager#isTrustUsuallyManaged(int)}. 182c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos * 183c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos * This returns the lazily-peristed value and should only be used by TrustManagerService. 184c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos */ 185c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos public boolean isTrustUsuallyManaged(int userId) { 186c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos if (!(mLockSettingsService instanceof ILockSettings.Stub)) { 187c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos throw new IllegalStateException("May only be called by TrustManagerService. " 188c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos + "Use TrustManager.isTrustUsuallyManaged()"); 189c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos } 190c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos try { 191c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos return getLockSettings().getBoolean(IS_TRUST_USUALLY_MANAGED, false, userId); 192c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos } catch (RemoteException e) { 193c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos return false; 194c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos } 195c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos } 196c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos 197c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos public void setTrustUsuallyManaged(boolean managed, int userId) { 198c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos try { 199c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos getLockSettings().setBoolean(IS_TRUST_USUALLY_MANAGED, managed, userId); 200c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos } catch (RemoteException e) { 201c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos // System dead. 202c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos } 203c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos } 2042397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales 2054ab7e595a5deef72448da950f2f973bc0c90fe18Adrian Roos public void userPresent(int userId) { 2064ab7e595a5deef72448da950f2f973bc0c90fe18Adrian Roos try { 2074ab7e595a5deef72448da950f2f973bc0c90fe18Adrian Roos getLockSettings().userPresent(userId); 2084ab7e595a5deef72448da950f2f973bc0c90fe18Adrian Roos } catch (RemoteException e) { 2094ab7e595a5deef72448da950f2f973bc0c90fe18Adrian Roos throw e.rethrowFromSystemServer(); 2104ab7e595a5deef72448da950f2f973bc0c90fe18Adrian Roos } 2114ab7e595a5deef72448da950f2f973bc0c90fe18Adrian Roos } 2124ab7e595a5deef72448da950f2f973bc0c90fe18Adrian Roos 2132397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales public static final class RequestThrottledException extends Exception { 2142397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales private int mTimeoutMs; 2152397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales public RequestThrottledException(int timeoutMs) { 2162397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales mTimeoutMs = timeoutMs; 2172397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales } 2182397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales 2192397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales /** 2202397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales * @return The amount of time in ms before another request may 2212397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales * be executed 2222397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales */ 2232397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales public int getTimeoutMs() { 2242397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales return mTimeoutMs; 2252397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales } 2262397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales 2272397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales } 2282397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales 229cd70988401be5919e8d1889727bb01c91d56627cJim Miller public DevicePolicyManager getDevicePolicyManager() { 2305b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller if (mDevicePolicyManager == null) { 2315b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller mDevicePolicyManager = 2325b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller (DevicePolicyManager)mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 2335b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller if (mDevicePolicyManager == null) { 2345b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller Log.e(TAG, "Can't get DevicePolicyManagerService: is it running?", 2355b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller new IllegalStateException("Stack trace:")); 2365b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller } 2375b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller } 2385b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller return mDevicePolicyManager; 2395b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller } 24052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 241a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri private UserManager getUserManager() { 242a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri if (mUserManager == null) { 243a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri mUserManager = UserManager.get(mContext); 244a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri } 245a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri return mUserManager; 246a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri } 247a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri 24882142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos private TrustManager getTrustManager() { 24982142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos TrustManager trust = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE); 25082142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos if (trust == null) { 25182142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos Log.e(TAG, "Can't get TrustManagerService: is it running?", 25282142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos new IllegalStateException("Stack trace:")); 25382142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 25482142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos return trust; 25582142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 25682142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos 25731f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller public LockPatternUtils(Context context) { 258df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn mContext = context; 25931f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller mContentResolver = context.getContentResolver(); 2607a3bf7c46e54cf226f86e3eeedb100a159f08d00Adrian Roos 2617a3bf7c46e54cf226f86e3eeedb100a159f08d00Adrian Roos Looper looper = Looper.myLooper(); 2627a3bf7c46e54cf226f86e3eeedb100a159f08d00Adrian Roos mHandler = looper != null ? new Handler(looper) : null; 26352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 26490881005182936e443cb6cd9fb7eff21f83206f5Brad Fitzpatrick 2650cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu @VisibleForTesting 2660cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu public ILockSettings getLockSettings() { 26752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (mLockSettingsService == null) { 268450ce9fc8a1522819aec151433e6f509dfe60690Adrian Roos ILockSettings service = ILockSettings.Stub.asInterface( 269450ce9fc8a1522819aec151433e6f509dfe60690Adrian Roos ServiceManager.getService("lock_settings")); 270138b83347b8da29166ee2eb09fa8126686bda3c7Adrian Roos mLockSettingsService = service; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return mLockSettingsService; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2758150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public int getRequestedMinimumPasswordLength(int userId) { 2768150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getDevicePolicyManager().getPasswordMinimumLength(null, userId); 27731f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller } 27831f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller 27931f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller /** 28031f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller * Gets the device policy password mode. If the mode is non-specific, returns 28131f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller * MODE_PATTERN which allows the user to choose anything. 28231f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller */ 2838150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public int getRequestedPasswordQuality(int userId) { 2848150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getDevicePolicyManager().getPasswordQuality(null, userId); 2859dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos } 2869dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 2879dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos private int getRequestedPasswordHistoryLength(int userId) { 2889dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return getDevicePolicyManager().getPasswordHistoryLength(null, userId); 2893255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 2903255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev 2918150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public int getRequestedPasswordMinimumLetters(int userId) { 2928150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getDevicePolicyManager().getPasswordMinimumLetters(null, userId); 293a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 294a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 2958150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public int getRequestedPasswordMinimumUpperCase(int userId) { 2968150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getDevicePolicyManager().getPasswordMinimumUpperCase(null, userId); 297a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 298a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 2998150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public int getRequestedPasswordMinimumLowerCase(int userId) { 3008150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getDevicePolicyManager().getPasswordMinimumLowerCase(null, userId); 301a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 302a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 3038150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public int getRequestedPasswordMinimumNumeric(int userId) { 3048150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getDevicePolicyManager().getPasswordMinimumNumeric(null, userId); 305a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 306a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 3078150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public int getRequestedPasswordMinimumSymbols(int userId) { 3088150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getDevicePolicyManager().getPasswordMinimumSymbols(null, userId); 309a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev } 310a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev 3118150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public int getRequestedPasswordMinimumNonLetter(int userId) { 3128150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getDevicePolicyManager().getPasswordMinimumNonLetter(null, userId); 313c857740f242169f2ca7fd42f0d1268661b399ad6Konstantin Lopyrev } 314599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani 3158150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public void reportFailedPasswordAttempt(int userId) { 3162adc263ce97ae6c8291653490868879841d31a63Adrian Roos if (userId == USER_FRP && frpCredentialEnabled(mContext)) { 3177374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos return; 3187374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos } 3194f994eb2ddbe68b0eada89dcaae34c079df55c7eAdrian Roos getDevicePolicyManager().reportFailedPasswordAttempt(userId); 3204f994eb2ddbe68b0eada89dcaae34c079df55c7eAdrian Roos getTrustManager().reportUnlockAttempt(false /* authenticated */, userId); 32131f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller } 32231f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller 3238150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public void reportSuccessfulPasswordAttempt(int userId) { 3242adc263ce97ae6c8291653490868879841d31a63Adrian Roos if (userId == USER_FRP && frpCredentialEnabled(mContext)) { 3257374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos return; 3267374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos } 3278150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId); 3288150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos getTrustManager().reportUnlockAttempt(true /* authenticated */, userId); 32931f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller } 33031f90b62e8c83270094f5b0b4c75a0e06d72cd75Jim Miller 331327323d2b337077433fe02438a79cc98e91799e3Zachary Iqbal public void reportPasswordLockout(int timeoutMs, int userId) { 3322adc263ce97ae6c8291653490868879841d31a63Adrian Roos if (userId == USER_FRP && frpCredentialEnabled(mContext)) { 3337374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos return; 3347374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos } 335327323d2b337077433fe02438a79cc98e91799e3Zachary Iqbal getTrustManager().reportUnlockLockout(timeoutMs, userId); 336327323d2b337077433fe02438a79cc98e91799e3Zachary Iqbal } 337327323d2b337077433fe02438a79cc98e91799e3Zachary Iqbal 33851e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri public int getCurrentFailedPasswordAttempts(int userId) { 3392adc263ce97ae6c8291653490868879841d31a63Adrian Roos if (userId == USER_FRP && frpCredentialEnabled(mContext)) { 3407374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos return 0; 3417374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos } 34251e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri return getDevicePolicyManager().getCurrentFailedPasswordAttempts(userId); 34351e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri } 34451e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri 34551e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri public int getMaximumFailedPasswordsForWipe(int userId) { 3462adc263ce97ae6c8291653490868879841d31a63Adrian Roos if (userId == USER_FRP && frpCredentialEnabled(mContext)) { 3477374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos return 0; 3487374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos } 34951e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri return getDevicePolicyManager().getMaximumFailedPasswordsForWipe( 35051e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri null /* componentName */, userId); 35151e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri } 35251e41ad887a2e30a1366f0a3b4750f0204912b8eClara Bayarri 3531de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu private byte[] verifyCredential(String credential, int type, long challenge, int userId) 3542397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales throws RequestThrottledException { 355d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales try { 3561de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu VerifyCredentialResponse response = getLockSettings().verifyCredential(credential, 3571de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu type, challenge, userId); 3582397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { 3592397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales return response.getPayload(); 3602397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { 3612397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales throw new RequestThrottledException(response.getTimeout()); 3622397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales } else { 3632397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales return null; 3642397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales } 365d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales } catch (RemoteException re) { 366d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales return null; 367d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales } 368d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales } 369d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales 3701de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu private boolean checkCredential(String credential, int type, int userId, 3711de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu @Nullable CheckCredentialProgressCallback progressCallback) 3721de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu throws RequestThrottledException { 3731de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu try { 3741de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu VerifyCredentialResponse response = getLockSettings().checkCredential(credential, type, 3751de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu userId, wrapCallback(progressCallback)); 3761de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu 3771de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { 3781de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu return true; 3791de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { 3801de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu throw new RequestThrottledException(response.getTimeout()); 3811de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu } else { 3821de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu return false; 3831de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu } 3841de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu } catch (RemoteException re) { 3851de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu return false; 3861de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu } 3871de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu } 3881de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu 3891de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu /** 3901de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * Check to see if a pattern matches the saved pattern. 3911de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * If pattern matches, return an opaque attestation that the challenge 3921de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * was verified. 3931de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * 3941de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * @param pattern The pattern to check. 3951de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * @param challenge The challenge to verify against the pattern 3961de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * @return the attestation that the challenge was verified, or null. 3971de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu */ 3981de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu public byte[] verifyPattern(List<LockPatternView.Cell> pattern, long challenge, int userId) 3991de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu throws RequestThrottledException { 4001de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu throwIfCalledOnMainThread(); 4011de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu return verifyCredential(patternToString(pattern), CREDENTIAL_TYPE_PATTERN, challenge, 4021de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu userId); 4031de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu } 4041de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu 405d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales /** 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check to see if a pattern matches the saved pattern. If no pattern exists, 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * always returns true. 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pattern The pattern to check. 40969aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * @return Whether the pattern matches the stored one. 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4112397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales public boolean checkPattern(List<LockPatternView.Cell> pattern, int userId) 4122397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales throws RequestThrottledException { 413e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi return checkPattern(pattern, userId, null /* progressCallback */); 414e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi } 415e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi 416e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi /** 417e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * Check to see if a pattern matches the saved pattern. If no pattern exists, 418e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * always returns true. 419e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * @param pattern The pattern to check. 420e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * @return Whether the pattern matches the stored one. 421e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi */ 422e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi public boolean checkPattern(List<LockPatternView.Cell> pattern, int userId, 423e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi @Nullable CheckCredentialProgressCallback progressCallback) 424e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi throws RequestThrottledException { 425aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia throwIfCalledOnMainThread(); 4261de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu return checkCredential(patternToString(pattern), CREDENTIAL_TYPE_PATTERN, userId, 4271de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu progressCallback); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 431d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales * Check to see if a password matches the saved password. 432d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales * If password matches, return an opaque attestation that the challenge 433d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales * was verified. 434d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales * 435d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales * @param password The password to check. 436d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales * @param challenge The challenge to verify against the password 437d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales * @return the attestation that the challenge was verified, or null. 438d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales */ 4392397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales public byte[] verifyPassword(String password, long challenge, int userId) 4402397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales throws RequestThrottledException { 441aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia throwIfCalledOnMainThread(); 4421de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu return verifyCredential(password, CREDENTIAL_TYPE_PASSWORD, challenge, userId); 44353940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai } 44453940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai 44553940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai 44653940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai /** 44753940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai * Check to see if a password matches the saved password. 44853940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai * If password matches, return an opaque attestation that the challenge 44953940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai * was verified. 45053940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai * 45153940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai * @param password The password to check. 45253940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai * @param challenge The challenge to verify against the password 45353940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai * @return the attestation that the challenge was verified, or null. 45453940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai */ 45553940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai public byte[] verifyTiedProfileChallenge(String password, boolean isPattern, long challenge, 45653940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai int userId) throws RequestThrottledException { 45753940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai throwIfCalledOnMainThread(); 45853940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai try { 45953940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai VerifyCredentialResponse response = 4601de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu getLockSettings().verifyTiedProfileChallenge(password, 4611de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu isPattern ? CREDENTIAL_TYPE_PATTERN : CREDENTIAL_TYPE_PASSWORD, challenge, 46253940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai userId); 46353940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai 46453940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { 46553940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai return response.getPayload(); 46653940d4c7f45a26d8b571982a1f8f4b8094aa5e0Ricky Wai } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { 4672397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales throw new RequestThrottledException(response.getTimeout()); 4682397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales } else { 4692397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales return null; 4702397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales } 471d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales } catch (RemoteException re) { 472d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales return null; 473d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales } 474d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales } 475d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales 476d9fc85ac27742adbe89e54fd35f3cb2469e94b91Andres Morales /** 47769aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * Check to see if a password matches the saved password. If no password exists, 47869aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * always returns true. 47969aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * @param password The password to check. 48069aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * @return Whether the password matches the stored one. 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4822397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales public boolean checkPassword(String password, int userId) throws RequestThrottledException { 483e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi return checkPassword(password, userId, null /* progressCallback */); 484e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi } 485e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi 486e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi /** 487e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * Check to see if a password matches the saved password. If no password exists, 488e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * always returns true. 489e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * @param password The password to check. 490e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * @return Whether the password matches the stored one. 491e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi */ 492e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi public boolean checkPassword(String password, int userId, 493e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi @Nullable CheckCredentialProgressCallback progressCallback) 494e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi throws RequestThrottledException { 495aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia throwIfCalledOnMainThread(); 4961de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu return checkCredential(password, CREDENTIAL_TYPE_PASSWORD, userId, progressCallback); 49769aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 49869aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 49969aa4a953f040277c19c23208bb830f52796c8c6Jim Miller /** 500945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence * Check to see if vold already has the password. 501945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence * Note that this also clears vold's copy of the password. 502945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence * @return Whether the vold password matches or not. 503945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence */ 5048150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public boolean checkVoldPassword(int userId) { 505945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence try { 506945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return getLockSettings().checkVoldPassword(userId); 507945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } catch (RemoteException re) { 508945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return false; 509945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 510945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 511945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence 512945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence /** 513f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu * Returns the password history hash factor, needed to check new password against password 514f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu * history with {@link #checkPasswordHistory(String, byte[], int)} 515f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu */ 516f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu public byte[] getPasswordHistoryHashFactor(String currentPassword, int userId) { 517f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu try { 518f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return getLockSettings().getHashFactor(currentPassword, userId); 519f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } catch (RemoteException e) { 520f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu Log.e(TAG, "failed to get hash factor", e); 521f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return null; 522f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 523f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 524f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu 525f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu /** 526863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev * Check to see if a password matches any of the passwords stored in the 527863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev * password history. 528863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev * 529f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu * @param passwordToCheck The password to check. 530f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu * @param hashFactor Hash factor of the current user returned from 531f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu * {@link ILockSettings#getHashFactor} 532863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev * @return Whether the password matches any in the history. 533863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev */ 534f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu public boolean checkPasswordHistory(String passwordToCheck, byte[] hashFactor, int userId) { 535f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu if (TextUtils.isEmpty(passwordToCheck)) { 536f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu Log.e(TAG, "checkPasswordHistory: empty password"); 537f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return false; 538f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 539dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos String passwordHistory = getString(PASSWORD_HISTORY_KEY, userId); 540f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu if (TextUtils.isEmpty(passwordHistory)) { 5413255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev return false; 5423255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 5438150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos int passwordHistoryLength = getRequestedPasswordHistoryLength(userId); 5443255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev if(passwordHistoryLength == 0) { 5453255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev return false; 5463255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 547f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu String legacyHash = legacyPasswordToHash(passwordToCheck, userId); 548f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu String passwordHash = passwordToHistoryHash(passwordToCheck, hashFactor, userId); 549f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu String[] history = passwordHistory.split(HISTORY_DELIMITER); 550f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu // Password History may be too long... 551f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu for (int i = 0; i < Math.min(passwordHistoryLength, history.length); i++) { 552f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu if (history[i].equals(legacyHash) || history[i].equals(passwordHash)) { 553f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return true; 554f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 5553255823de062e981f7bfc7994919207988697e45Konstantin Lopyrev } 556f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return false; 557863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev } 558863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev 559863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev /** 56069aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * Check to see if the user has stored a lock pattern. 56169aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * @return Whether a saved pattern exists. 56269aa4a953f040277c19c23208bb830f52796c8c6Jim Miller */ 5639dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos private boolean savedPatternExists(int userId) { 56452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 56550bfeec868157106e8b60abf8964cb24462af182Adrian Roos return getLockSettings().havePattern(userId); 56652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (RemoteException re) { 56752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return false; 56852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 56969aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 57069aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 57169aa4a953f040277c19c23208bb830f52796c8c6Jim Miller /** 57269aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * Check to see if the user has stored a lock pattern. 57369aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * @return Whether a saved pattern exists. 57469aa4a953f040277c19c23208bb830f52796c8c6Jim Miller */ 5759dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos private boolean savedPasswordExists(int userId) { 57652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 57750bfeec868157106e8b60abf8964cb24462af182Adrian Roos return getLockSettings().havePassword(userId); 57852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (RemoteException re) { 57952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return false; 58052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 58169aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 58269aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 58369aa4a953f040277c19c23208bb830f52796c8c6Jim Miller /** 584ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * Return true if the user has ever chosen a pattern. This is true even if the pattern is 585ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * currently cleared. 586ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * 587ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project * @return True if the user has ever chosen a pattern. 588ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project */ 5898150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public boolean isPatternEverChosen(int userId) { 5908150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getBoolean(PATTERN_EVER_CHOSEN_KEY, false, userId); 591dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos } 592dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos 593dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos /** 594e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney * Records that the user has chosen a pattern at some time, even if the pattern is 595e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney * currently cleared. 596e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney */ 597e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney public void reportPatternWasChosen(int userId) { 598e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId); 599e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney } 600e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney 601e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney /** 602dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos * Used by device policy manager to validate the current password 603dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos * information it has. 604dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos */ 605dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos public int getActivePasswordQuality(int userId) { 6069dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos int quality = getKeyguardStoredPasswordQuality(userId); 6079dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 6089dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos if (isLockPasswordEnabled(quality, userId)) { 6099dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos // Quality is a password and a password exists. Return the quality. 6109dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return quality; 6119dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos } 6129dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 6139dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos if (isLockPatternEnabled(quality, userId)) { 6149dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos // Quality is a pattern and a pattern exists. Return the quality. 6159dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return quality; 61685f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn } 617c8fb532d456b009e61d38e919277e00939cf894aDanielle Millett 618682d16758010e311910133fb40868133c05b3fe6Rubin Xu return PASSWORD_QUALITY_UNSPECIFIED; 61985f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn } 620cd70988401be5919e8d1889727bb01c91d56627cJim Miller 62185f2c9ce5a0e074df2429a5d66e1754e368a0430Dianne Hackborn /** 6224613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai * Use it to reset keystore without wiping work profile 6234613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai */ 6244613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai public void resetKeyStore(int userId) { 6254613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai try { 6264613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai getLockSettings().resetKeyStore(userId); 6274613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai } catch (RemoteException e) { 6284613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai // It should not happen 6294613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai Log.e(TAG, "Couldn't reset keystore " + e); 6304613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai } 6314613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai } 6324613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai 6334613fe41ac9e817e76d7087de45bf01f4a6584d6Ricky Wai /** 634df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn * Clear any lock pattern or password. 635df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn */ 636a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu public void clearLock(String savedCredential, int userHandle) { 637682d16758010e311910133fb40868133c05b3fe6Rubin Xu final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); 638682d16758010e311910133fb40868133c05b3fe6Rubin Xu setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle); 6399dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 640a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu try{ 641a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, savedCredential, 642682d16758010e311910133fb40868133c05b3fe6Rubin Xu PASSWORD_QUALITY_UNSPECIFIED, userHandle); 643682d16758010e311910133fb40868133c05b3fe6Rubin Xu } catch (Exception e) { 644682d16758010e311910133fb40868133c05b3fe6Rubin Xu Log.e(TAG, "Failed to clear lock", e); 645682d16758010e311910133fb40868133c05b3fe6Rubin Xu setKeyguardStoredPasswordQuality(currentQuality, userHandle); 646682d16758010e311910133fb40868133c05b3fe6Rubin Xu return; 6479dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos } 6489dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 64986c69ddefd503e93887d7728b5ce072522747527Xiaohui Chen if (userHandle == UserHandle.USER_SYSTEM) { 6509dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos // Set the encryption password to default. 6519dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null); 652d39113ea00b650f5778ed3d5dea6664c5d06f5b4Robin Lee setCredentialRequiredToDecrypt(false); 6539dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos } 6549dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 655f8f56bce428bb2b89d1d572ccd2d604761dbbce8Adrian Roos onAfterChangingPassword(userHandle); 656df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn } 6575b0fb3a7e8070ed366a85acc1904d2f34030445dJim Miller 658df83afaf299666e99c519aa86e7e082b7c116e95Dianne Hackborn /** 65951ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz * Disable showing lock screen at all for a given user. 66051ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz * This is only meaningful if pattern, pin or password are not set. 6612a98a4cbaaf3300036434dd1d44b891ea8a8c932Jim Miller * 66251ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz * @param disable Disables lock screen when true 66351ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz * @param userId User ID of the user this has effect on 66451ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz */ 66551ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz public void setLockScreenDisabled(boolean disable, int userId) { 66651ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz setBoolean(DISABLE_LOCKSCREEN_KEY, disable, userId); 66751ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz } 66851ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz 66951ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz /** 67051ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz * Determine if LockScreen is disabled for the current user. This is used to decide whether 67151ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz * LockScreen is shown after reboot or after screen timeout / short press on power. 67251ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz * 67351ed794e2f4489c57e1e854fa872aef352d6c28aBenjamin Franz * @return true if lock screen is disabled 6742a98a4cbaaf3300036434dd1d44b891ea8a8c932Jim Miller */ 6758150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public boolean isLockScreenDisabled(int userId) { 6762eff745087f71ec9f5909bec272cda1132462609Evan Rosky if (isSecure(userId)) { 6772eff745087f71ec9f5909bec272cda1132462609Evan Rosky return false; 6782eff745087f71ec9f5909bec272cda1132462609Evan Rosky } 6792eff745087f71ec9f5909bec272cda1132462609Evan Rosky boolean disabledByDefault = mContext.getResources().getBoolean( 6802eff745087f71ec9f5909bec272cda1132462609Evan Rosky com.android.internal.R.bool.config_disableLockscreenByDefault); 6812eff745087f71ec9f5909bec272cda1132462609Evan Rosky boolean isSystemUser = UserManager.isSplitSystemUser() && userId == UserHandle.USER_SYSTEM; 6825856be889f5e631eea822e13e560fd386c3907b8Christine Franks UserInfo userInfo = getUserManager().getUserInfo(userId); 6835856be889f5e631eea822e13e560fd386c3907b8Christine Franks boolean isDemoUser = UserManager.isDeviceInDemoMode(mContext) && userInfo != null 6845856be889f5e631eea822e13e560fd386c3907b8Christine Franks && userInfo.isDemo(); 6852eff745087f71ec9f5909bec272cda1132462609Evan Rosky return getBoolean(DISABLE_LOCKSCREEN_KEY, false, userId) 6865856be889f5e631eea822e13e560fd386c3907b8Christine Franks || (disabledByDefault && !isSystemUser) 6875856be889f5e631eea822e13e560fd386c3907b8Christine Franks || isDemoUser; 6882a98a4cbaaf3300036434dd1d44b891ea8a8c932Jim Miller } 6892a98a4cbaaf3300036434dd1d44b891ea8a8c932Jim Miller 6902a98a4cbaaf3300036434dd1d44b891ea8a8c932Jim Miller /** 6916edf2637e96139735df83907c221cce16d4d7eaaJim Miller * Save a lock pattern. 6926edf2637e96139735df83907c221cce16d4d7eaaJim Miller * @param pattern The new pattern to save. 6938150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos * @param userId the user whose pattern is to be saved. 6942364a222fcba233d66d0a9cde691d1d6e82227dbDanielle Millett */ 6958fa5665f0e757cec0063fb4cf1354f1596f93a91Andres Morales public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) { 6968fa5665f0e757cec0063fb4cf1354f1596f93a91Andres Morales this.saveLockPattern(pattern, null, userId); 6978fa5665f0e757cec0063fb4cf1354f1596f93a91Andres Morales } 6982364a222fcba233d66d0a9cde691d1d6e82227dbDanielle Millett /** 6992364a222fcba233d66d0a9cde691d1d6e82227dbDanielle Millett * Save a lock pattern. 7002364a222fcba233d66d0a9cde691d1d6e82227dbDanielle Millett * @param pattern The new pattern to save. 7018fa5665f0e757cec0063fb4cf1354f1596f93a91Andres Morales * @param savedPattern The previously saved pattern, converted to String format 702f8f56bce428bb2b89d1d572ccd2d604761dbbce8Adrian Roos * @param userId the user whose pattern is to be saved. 703f8f56bce428bb2b89d1d572ccd2d604761dbbce8Adrian Roos */ 7048fa5665f0e757cec0063fb4cf1354f1596f93a91Andres Morales public void saveLockPattern(List<LockPatternView.Cell> pattern, String savedPattern, int userId) { 705682d16758010e311910133fb40868133c05b3fe6Rubin Xu if (pattern == null || pattern.size() < MIN_LOCK_PATTERN_SIZE) { 706682d16758010e311910133fb40868133c05b3fe6Rubin Xu throw new IllegalArgumentException("pattern must not be null and at least " 707682d16758010e311910133fb40868133c05b3fe6Rubin Xu + MIN_LOCK_PATTERN_SIZE + " dots long."); 708682d16758010e311910133fb40868133c05b3fe6Rubin Xu } 7099dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 710682d16758010e311910133fb40868133c05b3fe6Rubin Xu final String stringPattern = patternToString(pattern); 711682d16758010e311910133fb40868133c05b3fe6Rubin Xu final int currentQuality = getKeyguardStoredPasswordQuality(userId); 712682d16758010e311910133fb40868133c05b3fe6Rubin Xu setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId); 713682d16758010e311910133fb40868133c05b3fe6Rubin Xu try { 714682d16758010e311910133fb40868133c05b3fe6Rubin Xu getLockSettings().setLockCredential(stringPattern, CREDENTIAL_TYPE_PATTERN, 715682d16758010e311910133fb40868133c05b3fe6Rubin Xu savedPattern, PASSWORD_QUALITY_SOMETHING, userId); 716682d16758010e311910133fb40868133c05b3fe6Rubin Xu } catch (Exception e) { 717682d16758010e311910133fb40868133c05b3fe6Rubin Xu Log.e(TAG, "Couldn't save lock pattern", e); 718682d16758010e311910133fb40868133c05b3fe6Rubin Xu setKeyguardStoredPasswordQuality(currentQuality, userId); 719682d16758010e311910133fb40868133c05b3fe6Rubin Xu return; 720682d16758010e311910133fb40868133c05b3fe6Rubin Xu } 721682d16758010e311910133fb40868133c05b3fe6Rubin Xu // Update the device encryption password. 722682d16758010e311910133fb40868133c05b3fe6Rubin Xu if (userId == UserHandle.USER_SYSTEM 723682d16758010e311910133fb40868133c05b3fe6Rubin Xu && LockPatternUtils.isDeviceEncryptionEnabled()) { 724682d16758010e311910133fb40868133c05b3fe6Rubin Xu if (!shouldEncryptWithCredentials(true)) { 725682d16758010e311910133fb40868133c05b3fe6Rubin Xu clearEncryptionPassword(); 726682d16758010e311910133fb40868133c05b3fe6Rubin Xu } else { 727682d16758010e311910133fb40868133c05b3fe6Rubin Xu updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern); 7289dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos } 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 730682d16758010e311910133fb40868133c05b3fe6Rubin Xu 731682d16758010e311910133fb40868133c05b3fe6Rubin Xu reportPatternWasChosen(userId); 732682d16758010e311910133fb40868133c05b3fe6Rubin Xu onAfterChangingPassword(userId); 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7359dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos private void updateCryptoUserInfo(int userId) { 73686c69ddefd503e93887d7728b5ce072522747527Xiaohui Chen if (userId != UserHandle.USER_SYSTEM) { 737e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence return; 738e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence } 739e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence 7409dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos final String ownerInfo = isOwnerInfoEnabled(userId) ? getOwnerInfo(userId) : ""; 741e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence 742e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence IBinder service = ServiceManager.getService("mount"); 743e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence if (service == null) { 744e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence Log.e(TAG, "Could not find the mount service to update the user info"); 745e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence return; 746e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence } 747e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence 7482250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka IStorageManager storageManager = IStorageManager.Stub.asInterface(service); 749e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence try { 750e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence Log.d(TAG, "Setting owner info"); 7512250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka storageManager.setField(StorageManager.OWNER_INFO_KEY, ownerInfo); 752e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence } catch (RemoteException e) { 753e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence Log.e(TAG, "Error changing user info", e); 754e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence } 755e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence } 756e51dcf98a4ddb1340cffba88059ad89f0b90909aPaul Lawrence 757187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller public void setOwnerInfo(String info, int userId) { 758187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller setString(LOCK_SCREEN_OWNER_INFO, info, userId); 7599dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos updateCryptoUserInfo(userId); 760187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller } 761187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller 7628150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public void setOwnerInfoEnabled(boolean enabled, int userId) { 7639dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId); 7649dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos updateCryptoUserInfo(userId); 765187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller } 766187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller 767187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller public String getOwnerInfo(int userId) { 768dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos return getString(LOCK_SCREEN_OWNER_INFO, userId); 769187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller } 770187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller 7718150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public boolean isOwnerInfoEnabled(int userId) { 7729dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return getBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, false, userId); 773187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller } 774187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7766644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu * Sets the device owner information. If the information is {@code null} or empty then the 7776644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu * device owner info is cleared. 7786644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu * 7796644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu * @param info Device owner information which will be displayed instead of the user 7806644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu * owner info. 7816644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu */ 7826644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu public void setDeviceOwnerInfo(String info) { 7836644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu if (info != null && info.isEmpty()) { 7846644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu info = null; 7856644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu } 7866644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu 7876644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu setString(LOCK_SCREEN_DEVICE_OWNER_INFO, info, UserHandle.USER_SYSTEM); 7886644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu } 7896644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu 7906644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu public String getDeviceOwnerInfo() { 7916644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu return getString(LOCK_SCREEN_DEVICE_OWNER_INFO, UserHandle.USER_SYSTEM); 7926644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu } 7936644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu 7946644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu public boolean isDeviceOwnerInfoEnabled() { 7956644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu return getDeviceOwnerInfo() != null; 7966644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu } 7976644cd9630be363a25af5e1327f41e16ca868556Andrei Stingaceanu 798f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks /** Update the encryption password if it is enabled **/ 7993a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence private void updateEncryptionPassword(final int type, final String password) { 800cd410ba4e816b657020cafb23e69206734726b42Amith Yamasani if (!isDeviceEncryptionEnabled()) { 801f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks return; 802f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks } 8033a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence final IBinder service = ServiceManager.getService("mount"); 804f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks if (service == null) { 805f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks Log.e(TAG, "Could not find the mount service to update the encryption password"); 806f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks return; 807f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks } 808f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks 8093a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence new AsyncTask<Void, Void, Void>() { 8103a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence @Override 8113a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence protected Void doInBackground(Void... dummy) { 8122250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka IStorageManager storageManager = IStorageManager.Stub.asInterface(service); 8133a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence try { 8142250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka storageManager.changeEncryptionPassword(type, password); 8153a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence } catch (RemoteException e) { 8163a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence Log.e(TAG, "Error changing encryption password", e); 8173a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence } 8183a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence return null; 8193a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence } 8203a5a0be61ec7ea08884c80817c226f7cfe531a67Paul Lawrence }.execute(); 821f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks } 822f7b3cd4efd40b7631f36ea014407a850f7dc637eJason parks 8239327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn /** 824cd70988401be5919e8d1889727bb01c91d56627cJim Miller * Save a lock password. Does not ensure that the password is as good 8259327f4f671de3cbb795612bf4f314ceff88de865Dianne Hackborn * as the requested mode, but will adjust the mode to be as good as the 8268150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos * password. 82769aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * @param password The password to save 8288fa5665f0e757cec0063fb4cf1354f1596f93a91Andres Morales * @param savedPassword The previously saved lock password, or null if none 8297374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} 830599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani * @param userHandle The userId of the user to change the password for 831599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani */ 8327374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos public void saveLockPassword(String password, String savedPassword, int requestedQuality, 8338fa5665f0e757cec0063fb4cf1354f1596f93a91Andres Morales int userHandle) { 834682d16758010e311910133fb40868133c05b3fe6Rubin Xu if (password == null || password.length() < MIN_LOCK_PASSWORD_SIZE) { 835682d16758010e311910133fb40868133c05b3fe6Rubin Xu throw new IllegalArgumentException("password must not be null and at least " 836682d16758010e311910133fb40868133c05b3fe6Rubin Xu + "of length " + MIN_LOCK_PASSWORD_SIZE); 837682d16758010e311910133fb40868133c05b3fe6Rubin Xu } 8389dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 839682d16758010e311910133fb40868133c05b3fe6Rubin Xu final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); 840682d16758010e311910133fb40868133c05b3fe6Rubin Xu setKeyguardStoredPasswordQuality( 841682d16758010e311910133fb40868133c05b3fe6Rubin Xu computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality), 842682d16758010e311910133fb40868133c05b3fe6Rubin Xu userHandle); 843682d16758010e311910133fb40868133c05b3fe6Rubin Xu try { 844682d16758010e311910133fb40868133c05b3fe6Rubin Xu getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, 845682d16758010e311910133fb40868133c05b3fe6Rubin Xu savedPassword, requestedQuality, userHandle); 846682d16758010e311910133fb40868133c05b3fe6Rubin Xu } catch (Exception e) { 847682d16758010e311910133fb40868133c05b3fe6Rubin Xu Log.e(TAG, "Unable to save lock password", e); 848682d16758010e311910133fb40868133c05b3fe6Rubin Xu setKeyguardStoredPasswordQuality(currentQuality, userHandle); 849682d16758010e311910133fb40868133c05b3fe6Rubin Xu return; 85069aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 851682d16758010e311910133fb40868133c05b3fe6Rubin Xu 852682d16758010e311910133fb40868133c05b3fe6Rubin Xu updateEncryptionPasswordIfNeeded(password, 853682d16758010e311910133fb40868133c05b3fe6Rubin Xu PasswordMetrics.computeForPassword(password).quality, userHandle); 854682d16758010e311910133fb40868133c05b3fe6Rubin Xu updatePasswordHistory(password, userHandle); 855f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu onAfterChangingPassword(userHandle); 85669aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 85769aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 858f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu /** 859f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * Update device encryption password if calling user is USER_SYSTEM and device supports 860f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * encryption. 861f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu */ 862f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu private void updateEncryptionPasswordIfNeeded(String password, int quality, int userHandle) { 863a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu // Update the device encryption password. 864a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu if (userHandle == UserHandle.USER_SYSTEM 865a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu && LockPatternUtils.isDeviceEncryptionEnabled()) { 866a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu if (!shouldEncryptWithCredentials(true)) { 867a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu clearEncryptionPassword(); 868a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu } else { 869682d16758010e311910133fb40868133c05b3fe6Rubin Xu boolean numeric = quality == PASSWORD_QUALITY_NUMERIC; 870682d16758010e311910133fb40868133c05b3fe6Rubin Xu boolean numericComplex = quality == PASSWORD_QUALITY_NUMERIC_COMPLEX; 871a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu int type = numeric || numericComplex ? StorageManager.CRYPT_TYPE_PIN 872a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu : StorageManager.CRYPT_TYPE_PASSWORD; 873a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu updateEncryptionPassword(type, password); 874a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu } 875a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu } 876a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu } 877a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu 878f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu /** 879f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu * Store the hash of the *current* password in the password history list, if device policy 880f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu * enforces password history requirement. 881f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu */ 882a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu private void updatePasswordHistory(String password, int userHandle) { 883f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu if (TextUtils.isEmpty(password)) { 884f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu Log.e(TAG, "checkPasswordHistory: empty password"); 885f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return; 886f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 887a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu // Add the password to the password history. We assume all 888a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu // password hashes have the same length for simplicity of implementation. 889a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle); 890a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu if (passwordHistory == null) { 891a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu passwordHistory = ""; 892a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu } 893a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu int passwordHistoryLength = getRequestedPasswordHistoryLength(userHandle); 894a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu if (passwordHistoryLength == 0) { 895a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu passwordHistory = ""; 896a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu } else { 897f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu final byte[] hashFactor = getPasswordHistoryHashFactor(password, userHandle); 898f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu String hash = passwordToHistoryHash(password, hashFactor, userHandle); 899f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu if (hash == null) { 900f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu Log.e(TAG, "Compute new style password hash failed, fallback to legacy style"); 901f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu hash = legacyPasswordToHash(password, userHandle); 902f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 903f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu if (TextUtils.isEmpty(passwordHistory)) { 904f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu passwordHistory = hash; 905f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } else { 906f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu String[] history = passwordHistory.split(HISTORY_DELIMITER); 907f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu StringJoiner joiner = new StringJoiner(HISTORY_DELIMITER); 908f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu joiner.add(hash); 909f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu for (int i = 0; i < passwordHistoryLength - 1 && i < history.length; i++) { 910f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu joiner.add(history[i]); 911f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 912f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu passwordHistory = joiner.toString(); 913f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 914a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu } 915a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle); 916a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu } 917a55b168b5d5a0584b2411793f870a7849c5014f1Rubin Xu 918cd70988401be5919e8d1889727bb01c91d56627cJim Miller /** 9196848dc8e3b54fb27047836d8026c4c9971754607Jim Miller * Determine if the device supports encryption, even if it's set to default. This 9206848dc8e3b54fb27047836d8026c4c9971754607Jim Miller * differs from isDeviceEncrypted() in that it returns true even if the device is 9216848dc8e3b54fb27047836d8026c4c9971754607Jim Miller * encrypted with the default password. 9226848dc8e3b54fb27047836d8026c4c9971754607Jim Miller * @return true if device encryption is enabled 9236848dc8e3b54fb27047836d8026c4c9971754607Jim Miller */ 9246848dc8e3b54fb27047836d8026c4c9971754607Jim Miller public static boolean isDeviceEncryptionEnabled() { 92520be5d62471d520eed3a52d90c11944464a71c07Paul Lawrence return StorageManager.isEncrypted(); 9266848dc8e3b54fb27047836d8026c4c9971754607Jim Miller } 9276848dc8e3b54fb27047836d8026c4c9971754607Jim Miller 9286848dc8e3b54fb27047836d8026c4c9971754607Jim Miller /** 9295c21c7037192128b2cbcc42c596e290c001f4090Paul Lawrence * Determine if the device is file encrypted 9305c21c7037192128b2cbcc42c596e290c001f4090Paul Lawrence * @return true if device is file encrypted 9315c21c7037192128b2cbcc42c596e290c001f4090Paul Lawrence */ 9325c21c7037192128b2cbcc42c596e290c001f4090Paul Lawrence public static boolean isFileEncryptionEnabled() { 93320be5d62471d520eed3a52d90c11944464a71c07Paul Lawrence return StorageManager.isFileEncryptedNativeOrEmulated(); 9345c21c7037192128b2cbcc42c596e290c001f4090Paul Lawrence } 9355c21c7037192128b2cbcc42c596e290c001f4090Paul Lawrence 9365c21c7037192128b2cbcc42c596e290c001f4090Paul Lawrence /** 93716e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav * Clears the encryption password. 93816e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav */ 93916e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav public void clearEncryptionPassword() { 94016e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null); 94116e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav } 94216e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav 94316e4a1aade2b73edfdaa42aa86a3893fd039fc62Svetoslav /** 9441572ee379e1d070c7ad1c37a626ed25db5341a3eAdrian Roos * Retrieves the quality mode for {@param userHandle}. 9451572ee379e1d070c7ad1c37a626ed25db5341a3eAdrian Roos * {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} 9461572ee379e1d070c7ad1c37a626ed25db5341a3eAdrian Roos * 9471572ee379e1d070c7ad1c37a626ed25db5341a3eAdrian Roos * @return stored password quality 9481572ee379e1d070c7ad1c37a626ed25db5341a3eAdrian Roos */ 9491572ee379e1d070c7ad1c37a626ed25db5341a3eAdrian Roos public int getKeyguardStoredPasswordQuality(int userHandle) { 950682d16758010e311910133fb40868133c05b3fe6Rubin Xu return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle); 951682d16758010e311910133fb40868133c05b3fe6Rubin Xu } 952682d16758010e311910133fb40868133c05b3fe6Rubin Xu 953682d16758010e311910133fb40868133c05b3fe6Rubin Xu private void setKeyguardStoredPasswordQuality(int quality, int userHandle) { 954682d16758010e311910133fb40868133c05b3fe6Rubin Xu setLong(PASSWORD_TYPE_KEY, quality, userHandle); 9556edf2637e96139735df83907c221cce16d4d7eaaJim Miller } 9566edf2637e96139735df83907c221cce16d4d7eaaJim Miller 95758396984ef49080d5550919130fc0d869ccf840bDanielle Millett /** 9587cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * Returns the password quality of the given credential, promoting it to a higher level 9597cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * if DevicePolicyManager has a stronger quality requirement. This value will be written 9607cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * to PASSWORD_TYPE_KEY. 9617cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu */ 9627cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu private int computePasswordQuality(int type, String credential, int requestedQuality) { 9637cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu final int quality; 9647cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu if (type == CREDENTIAL_TYPE_PASSWORD) { 9657cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu int computedQuality = PasswordMetrics.computeForPassword(credential).quality; 9667cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu quality = Math.max(requestedQuality, computedQuality); 9677cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu } else if (type == CREDENTIAL_TYPE_PATTERN) { 968682d16758010e311910133fb40868133c05b3fe6Rubin Xu quality = PASSWORD_QUALITY_SOMETHING; 9697cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu } else /* if (type == CREDENTIAL_TYPE_NONE) */ { 970682d16758010e311910133fb40868133c05b3fe6Rubin Xu quality = PASSWORD_QUALITY_UNSPECIFIED; 9717cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu } 9727cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu return quality; 9737cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu } 9747cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu 9757cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu /** 976a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri * Enables/disables the Separate Profile Challenge for this {@param userHandle}. This is a no-op 977a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri * for user handles that do not belong to a managed profile. 978dc283a897680ffd33c4d15535ebe778ba5b42c43Ricky Wai * 979dc283a897680ffd33c4d15535ebe778ba5b42c43Ricky Wai * @param userHandle Managed profile user id 980dc283a897680ffd33c4d15535ebe778ba5b42c43Ricky Wai * @param enabled True if separate challenge is enabled 981dc283a897680ffd33c4d15535ebe778ba5b42c43Ricky Wai * @param managedUserPassword Managed profile previous password. Null when {@param enabled} is 982dc283a897680ffd33c4d15535ebe778ba5b42c43Ricky Wai * true 983a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri */ 984dc283a897680ffd33c4d15535ebe778ba5b42c43Ricky Wai public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled, 985dc283a897680ffd33c4d15535ebe778ba5b42c43Ricky Wai String managedUserPassword) { 986b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov if (!isManagedProfile(userHandle)) { 987b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov return; 988b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov } 989b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov try { 990b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov getLockSettings().setSeparateProfileChallengeEnabled(userHandle, enabled, 991b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov managedUserPassword); 992b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov onAfterChangingPassword(userHandle); 993b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov } catch (RemoteException e) { 994b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov Log.e(TAG, "Couldn't update work profile challenge enabled"); 995a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri } 996a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri } 997a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri 998a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri /** 999b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov * Returns true if {@param userHandle} is a managed profile with separate challenge. 1000a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri */ 1001a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri public boolean isSeparateProfileChallengeEnabled(int userHandle) { 1002b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov return isManagedProfile(userHandle) && hasSeparateChallenge(userHandle); 1003b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov } 1004b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov 1005b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov /** 1006b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov * Returns true if {@param userHandle} is a managed profile with unified challenge. 1007b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov */ 1008b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov public boolean isManagedProfileWithUnifiedChallenge(int userHandle) { 1009b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov return isManagedProfile(userHandle) && !hasSeparateChallenge(userHandle); 1010a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri } 1011a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri 1012a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri /** 1013a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri * Retrieves whether the current DPM allows use of the Profile Challenge. 1014a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri */ 1015a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri public boolean isSeparateProfileChallengeAllowed(int userHandle) { 1016b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov return isManagedProfile(userHandle) 1017b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov && getDevicePolicyManager().isSeparateProfileChallengeAllowed(userHandle); 1018a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri } 1019a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri 1020a1771110d67fa7361f92d92f2e91019882ce3305Clara Bayarri /** 1021d7693917a7c7348cb12692116d2693314c29e809Clara Bayarri * Retrieves whether the current profile and device locks can be unified. 1022c4f87e9ceb4d5ce78c1663912bc166e0d41554aaPavel Grafov * @param userHandle profile user handle. 1023d7693917a7c7348cb12692116d2693314c29e809Clara Bayarri */ 1024d7693917a7c7348cb12692116d2693314c29e809Clara Bayarri public boolean isSeparateProfileChallengeAllowedToUnify(int userHandle) { 1025c4f87e9ceb4d5ce78c1663912bc166e0d41554aaPavel Grafov return getDevicePolicyManager().isProfileActivePasswordSufficientForParent(userHandle) 1026c4f87e9ceb4d5ce78c1663912bc166e0d41554aaPavel Grafov && !getUserManager().hasUserRestriction( 1027c4f87e9ceb4d5ce78c1663912bc166e0d41554aaPavel Grafov UserManager.DISALLOW_UNIFIED_PASSWORD, UserHandle.of(userHandle)); 1028d7693917a7c7348cb12692116d2693314c29e809Clara Bayarri } 1029d7693917a7c7348cb12692116d2693314c29e809Clara Bayarri 1030b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov private boolean hasSeparateChallenge(int userHandle) { 1031b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov try { 1032b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov return getLockSettings().getSeparateProfileChallengeEnabled(userHandle); 1033b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov } catch (RemoteException e) { 1034b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov Log.e(TAG, "Couldn't get separate profile challenge enabled"); 1035b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov // Default value is false 1036b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov return false; 1037b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov } 1038b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov } 1039b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov 1040b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov private boolean isManagedProfile(int userHandle) { 1041b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov final UserInfo info = getUserManager().getUserInfo(userHandle); 1042b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov return info != null && info.isManagedProfile(); 1043b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov } 1044b31912544661f0ea3d05e07a8250530660101c0bPavel Grafov 1045d7693917a7c7348cb12692116d2693314c29e809Clara Bayarri /** 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deserialize a pattern. 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param string The pattern serialized with {@link #patternToString} 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The pattern. 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static List<LockPatternView.Cell> stringToPattern(String string) { 10519dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos if (string == null) { 10529dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return null; 10539dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos } 10549dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<LockPatternView.Cell> result = Lists.newArrayList(); 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final byte[] bytes = string.getBytes(); 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < bytes.length; i++) { 1059e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales byte b = (byte) (bytes[i] - '1'); 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result.add(LockPatternView.Cell.of(b / 3, b % 3)); 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Serialize a pattern. 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pattern The pattern. 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The pattern in string form. 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static String patternToString(List<LockPatternView.Cell> pattern) { 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pattern == null) { 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ""; 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int patternSize = pattern.size(); 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] res = new byte[patternSize]; 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < patternSize; i++) { 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LockPatternView.Cell cell = pattern.get(i); 1079e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales res[i] = (byte) (cell.getRow() * 3 + cell.getColumn() + '1'); 1080e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales } 1081e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales return new String(res); 1082e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales } 1083e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales 1084e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales public static String patternStringToBaseZero(String pattern) { 1085e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales if (pattern == null) { 1086e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales return ""; 1087e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales } 1088e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales final int patternSize = pattern.length(); 1089e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales 1090e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales byte[] res = new byte[patternSize]; 1091e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales final byte[] bytes = pattern.getBytes(); 1092e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales for (int i = 0; i < patternSize; i++) { 1093e40bad8cf9397becdf05776c775c8286d3de46faAndres Morales res[i] = (byte) (bytes[i] - '1'); 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new String(res); 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 109769aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Generate an SHA-1 hash for the pattern. Not the most secure, but it is 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at least a second level of protection. First level is that the file 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is in a location only readable by the system process. 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pattern the gesture pattern. 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the hash of the pattern in a byte array. 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1105de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller public static byte[] patternToHash(List<LockPatternView.Cell> pattern) { 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pattern == null) { 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 110969aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int patternSize = pattern.size(); 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] res = new byte[patternSize]; 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < patternSize; i++) { 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LockPatternView.Cell cell = pattern.get(i); 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res[i] = (byte) (cell.getRow() * 3 + cell.getColumn()); 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MessageDigest md = MessageDigest.getInstance("SHA-1"); 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] hash = md.digest(res); 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return hash; 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NoSuchAlgorithmException nsa) { 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1125987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard private String getSalt(int userId) { 1126987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard long salt = getLong(LOCK_PASSWORD_SALT_KEY, 0, userId); 112711b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller if (salt == 0) { 112811b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller try { 112911b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller salt = SecureRandom.getInstance("SHA1PRNG").nextLong(); 1130987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard setLong(LOCK_PASSWORD_SALT_KEY, salt, userId); 1131987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard Log.v(TAG, "Initialized lock password salt for user: " + userId); 113211b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller } catch (NoSuchAlgorithmException e) { 113311b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller // Throw an exception rather than storing a password we'll never be able to recover 113411b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller throw new IllegalStateException("Couldn't get SecureRandom number", e); 113511b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller } 113611b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller } 113711b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller return Long.toHexString(salt); 113811b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller } 113911b019d07f4de0b25e2f863a7bcaad112d847d56Jim Miller 1140f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu /** 114169aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * Generate a hash for the given password. To avoid brute force attacks, we use a salted hash. 114269aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * Not the most secure, but it is at least a second level of protection. First level is that 114369aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * the file is in a location only readable by the system process. 114478108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath * 114569aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * @param password the gesture pattern. 114678108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath * 114769aa4a953f040277c19c23208bb830f52796c8c6Jim Miller * @return the hash of the pattern in a byte array. 114869aa4a953f040277c19c23208bb830f52796c8c6Jim Miller */ 1149f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu public String legacyPasswordToHash(String password, int userId) { 115069aa4a953f040277c19c23208bb830f52796c8c6Jim Miller if (password == null) { 115169aa4a953f040277c19c23208bb830f52796c8c6Jim Miller return null; 115269aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 115378108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath 115469aa4a953f040277c19c23208bb830f52796c8c6Jim Miller try { 1155987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard byte[] saltedPassword = (password + getSalt(userId)).getBytes(); 115678108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath byte[] sha1 = MessageDigest.getInstance("SHA-1").digest(saltedPassword); 115778108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath byte[] md5 = MessageDigest.getInstance("MD5").digest(saltedPassword); 115869aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 115978108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath byte[] combined = new byte[sha1.length + md5.length]; 116078108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath System.arraycopy(sha1, 0, combined, 0, sha1.length); 116178108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath System.arraycopy(md5, 0, combined, sha1.length, md5.length); 116278108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath 116378108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath final char[] hexEncoded = HexEncoding.encode(combined); 1164f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return new String(hexEncoded); 1165f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } catch (NoSuchAlgorithmException e) { 1166f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu throw new AssertionError("Missing digest algorithm: ", e); 1167f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 1168f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 1169f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu 1170f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu /** 1171f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu * Hash the password for password history check purpose. 1172f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu */ 1173f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu private String passwordToHistoryHash(String passwordToHash, byte[] hashFactor, int userId) { 1174f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu if (TextUtils.isEmpty(passwordToHash) || hashFactor == null) { 1175f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return null; 1176f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu } 1177f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu try { 1178f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); 1179f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu sha256.update(hashFactor); 1180f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu sha256.update((passwordToHash + getSalt(userId)).getBytes()); 1181f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu return new String(HexEncoding.encode(sha256.digest())); 118278108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath } catch (NoSuchAlgorithmException e) { 118378108a3e52c20ad0a481a8419c2d2c9722b53400Narayan Kamath throw new AssertionError("Missing digest algorithm: ", e); 118469aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 118569aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 118669aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 118769aa4a953f040277c19c23208bb830f52796c8c6Jim Miller /** 11889dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos * @param userId the user for which to report the value 11899dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos * @return Whether the lock screen is secured. 11909dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos */ 11919dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos public boolean isSecure(int userId) { 11929dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos int mode = getKeyguardStoredPasswordQuality(userId); 11939dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId); 1194dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos } 1195dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos 1196dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos public boolean isLockPasswordEnabled(int userId) { 11979dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId); 11989dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos } 11999dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos 12009dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos private boolean isLockPasswordEnabled(int mode, int userId) { 1201682d16758010e311910133fb40868133c05b3fe6Rubin Xu final boolean passwordEnabled = mode == PASSWORD_QUALITY_ALPHABETIC 1202682d16758010e311910133fb40868133c05b3fe6Rubin Xu || mode == PASSWORD_QUALITY_NUMERIC 1203682d16758010e311910133fb40868133c05b3fe6Rubin Xu || mode == PASSWORD_QUALITY_NUMERIC_COMPLEX 1204682d16758010e311910133fb40868133c05b3fe6Rubin Xu || mode == PASSWORD_QUALITY_ALPHANUMERIC 1205682d16758010e311910133fb40868133c05b3fe6Rubin Xu || mode == PASSWORD_QUALITY_COMPLEX 1206682d16758010e311910133fb40868133c05b3fe6Rubin Xu || mode == PASSWORD_QUALITY_MANAGED; 12079dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return passwordEnabled && savedPasswordExists(userId); 120869aa4a953f040277c19c23208bb830f52796c8c6Jim Miller } 120969aa4a953f040277c19c23208bb830f52796c8c6Jim Miller 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1211230635efe7ffb09d6dc56bfd9193aa1d89c8a898Adrian Roos * @return Whether the lock pattern is enabled 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 121350bfeec868157106e8b60abf8964cb24462af182Adrian Roos public boolean isLockPatternEnabled(int userId) { 12149dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId); 1215925a7d8f062c2ef275ccb7579889d6f83d0d378eDanielle Millett } 1216925a7d8f062c2ef275ccb7579889d6f83d0d378eDanielle Millett 12174614596a395b6c86fff3f35a07edda2e848d743cBryce Lee @Deprecated 12184614596a395b6c86fff3f35a07edda2e848d743cBryce Lee public boolean isLegacyLockPatternEnabled(int userId) { 12194614596a395b6c86fff3f35a07edda2e848d743cBryce Lee // Note: this value should default to {@code true} to avoid any reset that might result. 12204614596a395b6c86fff3f35a07edda2e848d743cBryce Lee // We must use a special key to read this value, since it will by default return the value 12214614596a395b6c86fff3f35a07edda2e848d743cBryce Lee // based on the new logic. 12224614596a395b6c86fff3f35a07edda2e848d743cBryce Lee return getBoolean(LEGACY_LOCK_PATTERN_ENABLED, true, userId); 12234614596a395b6c86fff3f35a07edda2e848d743cBryce Lee } 12244614596a395b6c86fff3f35a07edda2e848d743cBryce Lee 12254614596a395b6c86fff3f35a07edda2e848d743cBryce Lee @Deprecated 12264614596a395b6c86fff3f35a07edda2e848d743cBryce Lee public void setLegacyLockPatternEnabled(int userId) { 12274614596a395b6c86fff3f35a07edda2e848d743cBryce Lee setBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, true, userId); 12284614596a395b6c86fff3f35a07edda2e848d743cBryce Lee } 12294614596a395b6c86fff3f35a07edda2e848d743cBryce Lee 12309dd16ebcf2a25c189a39b72847d3db2b1189cb4dAdrian Roos private boolean isLockPatternEnabled(int mode, int userId) { 1231682d16758010e311910133fb40868133c05b3fe6Rubin Xu return mode == PASSWORD_QUALITY_SOMETHING && savedPatternExists(userId); 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether the visible pattern is enabled. 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12378150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public boolean isVisiblePatternEnabled(int userId) { 12388150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, userId); 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set whether the visible pattern is enabled. 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12448150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public void setVisiblePatternEnabled(boolean enabled, int userId) { 1245dce0122ea2d27474890d5e18ba4b7e4d06303e53Adrian Roos setBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, enabled, userId); 1246878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence 1247878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence // Update for crypto if owner 124886c69ddefd503e93887d7728b5ce072522747527Xiaohui Chen if (userId != UserHandle.USER_SYSTEM) { 1249878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence return; 1250878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence } 1251878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence 1252878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence IBinder service = ServiceManager.getService("mount"); 1253878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence if (service == null) { 1254878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence Log.e(TAG, "Could not find the mount service to update the user info"); 1255878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence return; 1256878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence } 1257878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence 12582250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka IStorageManager storageManager = IStorageManager.Stub.asInterface(service); 1259878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence try { 12602250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka storageManager.setField(StorageManager.PATTERN_VISIBLE_KEY, enabled ? "1" : "0"); 1261878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence } catch (RemoteException e) { 1262878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence Log.e(TAG, "Error changing pattern visible state", e); 1263878ba0a266246f29e8145612a2a58e5e997b018cPaul Lawrence } 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1266e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney public boolean isVisiblePatternEverChosen(int userId) { 1267e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney return getString(Settings.Secure.LOCK_PATTERN_VISIBLE, userId) != null; 1268e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney } 1269e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1271d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence * Set whether the visible password is enabled for cryptkeeper screen. 1272d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence */ 1273d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence public void setVisiblePasswordEnabled(boolean enabled, int userId) { 1274d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence // Update for crypto if owner 127586c69ddefd503e93887d7728b5ce072522747527Xiaohui Chen if (userId != UserHandle.USER_SYSTEM) { 1276d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence return; 1277d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence } 1278d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence 1279d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence IBinder service = ServiceManager.getService("mount"); 1280d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence if (service == null) { 1281d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence Log.e(TAG, "Could not find the mount service to update the user info"); 1282d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence return; 1283d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence } 1284d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence 12852250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka IStorageManager storageManager = IStorageManager.Stub.asInterface(service); 1286d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence try { 12872250d56a0b47b93016018340c8f4040325aa5611Sudheer Shanka storageManager.setField(StorageManager.PASSWORD_VISIBLE_KEY, enabled ? "1" : "0"); 1288d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence } catch (RemoteException e) { 1289d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence Log.e(TAG, "Error changing password visible state", e); 1290d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence } 1291d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence } 1292d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence 1293d8fdb338918e63bbab2e65bdb2f4d12320a1b24aPaul Lawrence /** 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether tactile feedback for the pattern is enabled. 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isTactileFeedbackEnabled() { 12975ed9d680409c83fbfd7b617d7f257305d3c34b62Jeff Sharkey return Settings.System.getIntForUser(mContentResolver, 12985ed9d680409c83fbfd7b617d7f257305d3c34b62Jeff Sharkey Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0; 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set and store the lockout deadline, meaning the user can't attempt his/her unlock 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pattern until the deadline has passed. 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the chosen deadline. 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13062397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales public long setLockoutAttemptDeadline(int userId, int timeoutMs) { 13072397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales final long deadline = SystemClock.elapsedRealtime() + timeoutMs; 1308b7d81d9a20000e3db2b4d2612090c6217f489385Adrian Roos if (userId == USER_FRP) { 1309b7d81d9a20000e3db2b4d2612090c6217f489385Adrian Roos // For secure password storage (that is required for FRP), the underlying storage also 1310b7d81d9a20000e3db2b4d2612090c6217f489385Adrian Roos // enforces the deadline. Since we cannot store settings for the FRP user, don't. 1311b7d81d9a20000e3db2b4d2612090c6217f489385Adrian Roos return deadline; 1312b7d81d9a20000e3db2b4d2612090c6217f489385Adrian Roos } 1313a3e5582fac1cc259022c06d027e73c767dc1c117Kevin Chyn mLockoutDeadlines.put(userId, deadline); 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return deadline; 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The elapsed time in millis in the future when the user is allowed to 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attempt to enter his/her lock pattern, or 0 if the user is welcome to 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enter a pattern. 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13228150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public long getLockoutAttemptDeadline(int userId) { 1323a3e5582fac1cc259022c06d027e73c767dc1c117Kevin Chyn final long deadline = mLockoutDeadlines.get(userId, 0L); 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long now = SystemClock.elapsedRealtime(); 1325e3e6d56b94b2c196659e15deffed9dc9028fa974Jorim Jaggi if (deadline < now && deadline != 0) { 1326a4e23375663ac3a2b6115da71e6711282f03492dAndres Morales // timeout expired 1327a3e5582fac1cc259022c06d027e73c767dc1c117Kevin Chyn mLockoutDeadlines.put(userId, 0); 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0L; 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return deadline; 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1333f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller private boolean getBoolean(String secureSettingKey, boolean defaultValue, int userId) { 133452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 1335f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller return getLockSettings().getBoolean(secureSettingKey, defaultValue, userId); 133652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (RemoteException re) { 133752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return defaultValue; 133852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1341f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller private void setBoolean(String secureSettingKey, boolean enabled, int userId) { 134252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 1343f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller getLockSettings().setBoolean(secureSettingKey, enabled, userId); 134452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (RemoteException re) { 134552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // What can we do? 134652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Log.e(TAG, "Couldn't write boolean " + secureSettingKey + re); 134752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1350987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard private long getLong(String secureSettingKey, long defaultValue, int userHandle) { 1351987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard try { 1352987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard return getLockSettings().getLong(secureSettingKey, defaultValue, userHandle); 1353987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard } catch (RemoteException re) { 1354987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard return defaultValue; 1355987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard } 1356987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard } 1357987672d2621fa5278dbf48cbef46c50d3fafe4c1Geoffrey Borggaard 1358599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani private void setLong(String secureSettingKey, long value, int userHandle) { 135952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 13600cf13701d69c79ccd4011472e5c58bf9b4a24726Kenny Guy getLockSettings().setLong(secureSettingKey, value, userHandle); 136152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (RemoteException re) { 136252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // What can we do? 136352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Log.e(TAG, "Couldn't write long " + secureSettingKey + re); 136452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1367599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani private String getString(String secureSettingKey, int userHandle) { 136852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 1369599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani return getLockSettings().getString(secureSettingKey, null, userHandle); 137052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (RemoteException re) { 137152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return null; 137252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 1373863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev } 1374863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev 1375599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani private void setString(String secureSettingKey, String value, int userHandle) { 137652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 1377599dd7ce9adf8ca067cefb0b191a5ac20ec35a79Amith Yamasani getLockSettings().setString(secureSettingKey, value, userHandle); 137852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (RemoteException re) { 137952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // What can we do? 138052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Log.e(TAG, "Couldn't write string " + secureSettingKey + re); 138152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 1382863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev } 1383863f22d0451d52cbcccc252ad29858ef1578e709Konstantin Lopyrev 13848150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public void setPowerButtonInstantlyLocks(boolean enabled, int userId) { 13858150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId); 138682142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 138782142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos 13888150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos public boolean getPowerButtonInstantlyLocks(int userId) { 13898150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId); 139082142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 139182142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos 1392e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney public boolean isPowerButtonInstantlyLocksEverChosen(int userId) { 1393e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney return getString(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, userId) != null; 1394e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney } 1395e483b56ea8454886a892a6840d3f71ce9fd5becfBryan Mawhinney 139682142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents, int userId) { 139782142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos StringBuilder sb = new StringBuilder(); 139882142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos for (ComponentName cn : activeTrustAgents) { 139982142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos if (sb.length() > 0) { 140082142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos sb.append(','); 140182142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 140282142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos sb.append(cn.flattenToShortString()); 140382142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 140482142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos setString(ENABLED_TRUST_AGENTS, sb.toString(), userId); 14058150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos getTrustManager().reportEnabledTrustAgentsChanged(userId); 140682142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 140782142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos 140882142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos public List<ComponentName> getEnabledTrustAgents(int userId) { 140982142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos String serialized = getString(ENABLED_TRUST_AGENTS, userId); 141082142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos if (TextUtils.isEmpty(serialized)) { 141182142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos return null; 141282142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 141382142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos String[] split = serialized.split(","); 141482142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos ArrayList<ComponentName> activeTrustAgents = new ArrayList<ComponentName>(split.length); 141582142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos for (String s : split) { 141682142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos if (!TextUtils.isEmpty(s)) { 141782142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos activeTrustAgents.add(ComponentName.unflattenFromString(s)); 141882142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 141982142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 142082142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos return activeTrustAgents; 142182142c21dd333307682d5f4bb09de3ab3ccfa06cAdrian Roos } 14222c12cfa1d53b586ae8a8d6aca64a4de771dc85b0Adrian Roos 14232c12cfa1d53b586ae8a8d6aca64a4de771dc85b0Adrian Roos /** 1424b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Disable trust until credentials have been entered for user {@param userId}. 1425b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * 1426b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. 1427b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * 1428b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL} 14292c12cfa1d53b586ae8a8d6aca64a4de771dc85b0Adrian Roos */ 14302c12cfa1d53b586ae8a8d6aca64a4de771dc85b0Adrian Roos public void requireCredentialEntry(int userId) { 143116093fe3f0d824731a53a264a132504deb08421aJorim Jaggi requireStrongAuth(StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, userId); 1432b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1433b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1434b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1435b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Requests strong authentication for user {@param userId}. 1436b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * 1437b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission. 1438b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * 1439b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * @param strongAuthReason a combination of {@link StrongAuthTracker.StrongAuthFlags} indicating 1440b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * the reason for and the strength of the requested authentication. 1441b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL} 1442b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1443b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public void requireStrongAuth(@StrongAuthTracker.StrongAuthFlags int strongAuthReason, 1444b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos int userId) { 1445b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos try { 1446b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos getLockSettings().requireStrongAuth(strongAuthReason, userId); 1447b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } catch (RemoteException e) { 1448b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos Log.e(TAG, "Error while requesting strong auth: " + e); 1449b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 14502c12cfa1d53b586ae8a8d6aca64a4de771dc85b0Adrian Roos } 14514b9e324b6f59f49a8ca4bc4cd8b38a5ea005a6b2Adrian Roos 1452f8f56bce428bb2b89d1d572ccd2d604761dbbce8Adrian Roos private void onAfterChangingPassword(int userHandle) { 1453f8f56bce428bb2b89d1d572ccd2d604761dbbce8Adrian Roos getTrustManager().reportEnabledTrustAgentsChanged(userHandle); 14544b9e324b6f59f49a8ca4bc4cd8b38a5ea005a6b2Adrian Roos } 1455dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller 1456dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller public boolean isCredentialRequiredToDecrypt(boolean defaultValue) { 1457dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller final int value = Settings.Global.getInt(mContentResolver, 1458dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, -1); 1459dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller return value == -1 ? defaultValue : (value != 0); 1460dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller } 1461dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller 1462dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller public void setCredentialRequiredToDecrypt(boolean required) { 1463d39113ea00b650f5778ed3d5dea6664c5d06f5b4Robin Lee if (!(getUserManager().isSystemUser() || getUserManager().isPrimaryUser())) { 1464d39113ea00b650f5778ed3d5dea6664c5d06f5b4Robin Lee throw new IllegalStateException( 1465d39113ea00b650f5778ed3d5dea6664c5d06f5b4Robin Lee "Only the system or primary user may call setCredentialRequiredForDecrypt()"); 1466dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller } 1467688af6c5743d4ef5d08537b02b23fdde24a3c348Paul Lawrence 1468688af6c5743d4ef5d08537b02b23fdde24a3c348Paul Lawrence if (isDeviceEncryptionEnabled()){ 1469688af6c5743d4ef5d08537b02b23fdde24a3c348Paul Lawrence Settings.Global.putInt(mContext.getContentResolver(), 1470688af6c5743d4ef5d08537b02b23fdde24a3c348Paul Lawrence Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, required ? 1 : 0); 1471688af6c5743d4ef5d08537b02b23fdde24a3c348Paul Lawrence } 1472dd5de719c5a0d39030f94d931c0ab1bed1f147f8Jim Miller } 14734eb6a36922f5e98fe181c0326cc5721f0e7589caAndrei Kapishnikov 14744eb6a36922f5e98fe181c0326cc5721f0e7589caAndrei Kapishnikov private boolean isDoNotAskCredentialsOnBootSet() { 14754929a5d3b434a6915d64e449b234b40b8eff9993Rubin Xu return getDevicePolicyManager().getDoNotAskCredentialsOnBoot(); 14764eb6a36922f5e98fe181c0326cc5721f0e7589caAndrei Kapishnikov } 14774eb6a36922f5e98fe181c0326cc5721f0e7589caAndrei Kapishnikov 14784eb6a36922f5e98fe181c0326cc5721f0e7589caAndrei Kapishnikov private boolean shouldEncryptWithCredentials(boolean defaultValue) { 14794eb6a36922f5e98fe181c0326cc5721f0e7589caAndrei Kapishnikov return isCredentialRequiredToDecrypt(defaultValue) && !isDoNotAskCredentialsOnBootSet(); 14804eb6a36922f5e98fe181c0326cc5721f0e7589caAndrei Kapishnikov } 1481aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia 1482aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia private void throwIfCalledOnMainThread() { 1483aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia if (Looper.getMainLooper().isCurrentThread()) { 1484aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia throw new IllegalStateException("should not be called from the main thread."); 1485aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia } 1486aa26294de3ad97859637f65f6e70eb773541a767Xiyuan Xia } 1487b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1488b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public void registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker) { 1489b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos try { 1490b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos getLockSettings().registerStrongAuthTracker(strongAuthTracker.mStub); 1491b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } catch (RemoteException e) { 1492b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos throw new RuntimeException("Could not register StrongAuthTracker"); 1493b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1494b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1495b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1496b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public void unregisterStrongAuthTracker(final StrongAuthTracker strongAuthTracker) { 1497b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos try { 1498b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos getLockSettings().unregisterStrongAuthTracker(strongAuthTracker.mStub); 1499b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } catch (RemoteException e) { 1500b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos Log.e(TAG, "Could not unregister StrongAuthTracker", e); 1501b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1502b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1503b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1504b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1505a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang * @see StrongAuthTracker#getStrongAuthForUser 1506a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang */ 1507a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang public int getStrongAuthForUser(int userId) { 1508a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang try { 1509a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang return getLockSettings().getStrongAuthForUser(userId); 1510a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang } catch (RemoteException e) { 1511a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang Log.e(TAG, "Could not get StrongAuth", e); 1512a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang return StrongAuthTracker.getDefaultFlags(mContext); 1513a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang } 1514a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang } 1515a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang 1516a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang /** 1517a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang * @see StrongAuthTracker#isTrustAllowedForUser 1518a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang */ 1519a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang public boolean isTrustAllowedForUser(int userId) { 1520a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang return getStrongAuthForUser(userId) == StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; 1521a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang } 1522a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang 1523a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang /** 1524a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang * @see StrongAuthTracker#isFingerprintAllowedForUser 1525a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang */ 1526a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang public boolean isFingerprintAllowedForUser(int userId) { 1527a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang return (getStrongAuthForUser(userId) & ~StrongAuthTracker.ALLOWING_FINGERPRINT) == 0; 1528a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang } 1529a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang 1530ea8c5ef2b8bc00575073ddbce42e7986a59af627Chad Brubaker public boolean isUserInLockdown(int userId) { 1531ea8c5ef2b8bc00575073ddbce42e7986a59af627Chad Brubaker return getStrongAuthForUser(userId) 1532ea8c5ef2b8bc00575073ddbce42e7986a59af627Chad Brubaker == StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; 1533ea8c5ef2b8bc00575073ddbce42e7986a59af627Chad Brubaker } 1534ea8c5ef2b8bc00575073ddbce42e7986a59af627Chad Brubaker 1535e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi private ICheckCredentialProgressCallback wrapCallback( 1536e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi final CheckCredentialProgressCallback callback) { 1537e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi if (callback == null) { 1538e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi return null; 1539e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi } else { 15407a3bf7c46e54cf226f86e3eeedb100a159f08d00Adrian Roos if (mHandler == null) { 15417a3bf7c46e54cf226f86e3eeedb100a159f08d00Adrian Roos throw new IllegalStateException("Must construct LockPatternUtils on a looper thread" 15427a3bf7c46e54cf226f86e3eeedb100a159f08d00Adrian Roos + " to use progress callbacks."); 15437a3bf7c46e54cf226f86e3eeedb100a159f08d00Adrian Roos } 1544e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi return new ICheckCredentialProgressCallback.Stub() { 1545e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi 1546e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi @Override 1547e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi public void onCredentialVerified() throws RemoteException { 1548e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi mHandler.post(callback::onEarlyMatched); 1549e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi } 1550e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi }; 1551e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi } 1552e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi } 1553e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi 1554fcd49f993ede363d0b17900565dfe37066362480Rubin Xu private LockSettingsInternal getLockSettingsInternal() { 1555fcd49f993ede363d0b17900565dfe37066362480Rubin Xu LockSettingsInternal service = LocalServices.getService(LockSettingsInternal.class); 1556fcd49f993ede363d0b17900565dfe37066362480Rubin Xu if (service == null) { 1557fcd49f993ede363d0b17900565dfe37066362480Rubin Xu throw new SecurityException("Only available to system server itself"); 1558fcd49f993ede363d0b17900565dfe37066362480Rubin Xu } 1559fcd49f993ede363d0b17900565dfe37066362480Rubin Xu return service; 1560fcd49f993ede363d0b17900565dfe37066362480Rubin Xu } 1561e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi /** 1562f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * Create an escrow token for the current user, which can later be used to unlock FBE 1563f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * or change user password. 1564f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * 1565f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * After adding, if the user currently has lockscreen password, he will need to perform a 1566f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * confirm credential operation in order to activate the token for future use. If the user 1567f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * has no secure lockscreen, then the token is activated immediately. 1568f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * 1569fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * <p>This method is only available to code running in the system server process itself. 1570fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * 1571f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * @return a unique 64-bit token handle which is needed to refer to this token later. 1572f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu */ 1573f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu public long addEscrowToken(byte[] token, int userId) { 1574fcd49f993ede363d0b17900565dfe37066362480Rubin Xu return getLockSettingsInternal().addEscrowToken(token, userId); 1575f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu } 1576f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu 1577f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu /** 1578f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * Remove an escrow token. 1579fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * 1580fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * <p>This method is only available to code running in the system server process itself. 1581fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * 1582f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * @return true if the given handle refers to a valid token previously returned from 1583f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * {@link #addEscrowToken}, whether it's active or not. return false otherwise. 1584f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu */ 1585f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu public boolean removeEscrowToken(long handle, int userId) { 1586fcd49f993ede363d0b17900565dfe37066362480Rubin Xu return getLockSettingsInternal().removeEscrowToken(handle, userId); 1587f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu } 1588f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu 1589f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu /** 1590f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * Check if the given escrow token is active or not. Only active token can be used to call 1591f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu * {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken} 1592fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * 1593fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * <p>This method is only available to code running in the system server process itself. 1594f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu */ 1595f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu public boolean isEscrowTokenActive(long handle, int userId) { 1596fcd49f993ede363d0b17900565dfe37066362480Rubin Xu return getLockSettingsInternal().isEscrowTokenActive(handle, userId); 1597f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu } 1598f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu 15997cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu /** 16007cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * Change a user's lock credential with a pre-configured escrow token. 16017cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * 1602fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * <p>This method is only available to code running in the system server process itself. 1603fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * 16047cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * @param credential The new credential to be set 16057cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * @param type Credential type: password / pattern / none. 16067cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * @param requestedQuality the requested password quality by DevicePolicyManager. 16077cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * See {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} 16087cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * @param tokenHandle Handle of the escrow token 16097cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * @param token Escrow token 16107cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * @param userId The user who's lock credential to be changed 16117cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu * @return {@code true} if the operation is successful. 16127cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu */ 16137cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu public boolean setLockCredentialWithToken(String credential, int type, int requestedQuality, 16147cf4509c31f3dc1c32f89c26867a50c4ed0d5618Rubin Xu long tokenHandle, byte[] token, int userId) { 1615fcd49f993ede363d0b17900565dfe37066362480Rubin Xu LockSettingsInternal localService = getLockSettingsInternal(); 1616fcd49f993ede363d0b17900565dfe37066362480Rubin Xu if (type != CREDENTIAL_TYPE_NONE) { 1617fcd49f993ede363d0b17900565dfe37066362480Rubin Xu if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) { 1618fcd49f993ede363d0b17900565dfe37066362480Rubin Xu throw new IllegalArgumentException("password must not be null and at least " 1619fcd49f993ede363d0b17900565dfe37066362480Rubin Xu + "of length " + MIN_LOCK_PASSWORD_SIZE); 1620fcd49f993ede363d0b17900565dfe37066362480Rubin Xu } 1621fcd49f993ede363d0b17900565dfe37066362480Rubin Xu final int quality = computePasswordQuality(type, credential, requestedQuality); 1622fcd49f993ede363d0b17900565dfe37066362480Rubin Xu if (!localService.setLockCredentialWithToken(credential, type, tokenHandle, 1623fcd49f993ede363d0b17900565dfe37066362480Rubin Xu token, quality, userId)) { 1624fcd49f993ede363d0b17900565dfe37066362480Rubin Xu return false; 1625fcd49f993ede363d0b17900565dfe37066362480Rubin Xu } 1626682d16758010e311910133fb40868133c05b3fe6Rubin Xu setKeyguardStoredPasswordQuality(quality, userId); 1627f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu 1628fcd49f993ede363d0b17900565dfe37066362480Rubin Xu updateEncryptionPasswordIfNeeded(credential, quality, userId); 1629fcd49f993ede363d0b17900565dfe37066362480Rubin Xu updatePasswordHistory(credential, userId); 1630f01e90789eb27bc538df13374b6e67991c0ea829Rubin Xu onAfterChangingPassword(userId); 1631fcd49f993ede363d0b17900565dfe37066362480Rubin Xu } else { 1632fcd49f993ede363d0b17900565dfe37066362480Rubin Xu if (!TextUtils.isEmpty(credential)) { 1633fcd49f993ede363d0b17900565dfe37066362480Rubin Xu throw new IllegalArgumentException("password must be emtpy for NONE type"); 1634fcd49f993ede363d0b17900565dfe37066362480Rubin Xu } 1635fcd49f993ede363d0b17900565dfe37066362480Rubin Xu if (!localService.setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE, 1636682d16758010e311910133fb40868133c05b3fe6Rubin Xu tokenHandle, token, PASSWORD_QUALITY_UNSPECIFIED, userId)) { 1637fcd49f993ede363d0b17900565dfe37066362480Rubin Xu return false; 1638fcd49f993ede363d0b17900565dfe37066362480Rubin Xu } 1639682d16758010e311910133fb40868133c05b3fe6Rubin Xu setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userId); 1640f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu 1641fcd49f993ede363d0b17900565dfe37066362480Rubin Xu if (userId == UserHandle.USER_SYSTEM) { 1642fcd49f993ede363d0b17900565dfe37066362480Rubin Xu // Set the encryption password to default. 1643fcd49f993ede363d0b17900565dfe37066362480Rubin Xu updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null); 1644fcd49f993ede363d0b17900565dfe37066362480Rubin Xu setCredentialRequiredToDecrypt(false); 1645f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu } 1646f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu } 1647fcd49f993ede363d0b17900565dfe37066362480Rubin Xu onAfterChangingPassword(userId); 1648fcd49f993ede363d0b17900565dfe37066362480Rubin Xu return true; 1649f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu } 1650f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu 1651fcd49f993ede363d0b17900565dfe37066362480Rubin Xu /** 1652fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * Unlock the specified user by an pre-activated escrow token. This should have the same effect 1653fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * on device encryption as the user entering his lockscreen credentials for the first time after 1654fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * boot, this includes unlocking the user's credential-encrypted storage as well as the keystore 1655fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * 1656fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * <p>This method is only available to code running in the system server process itself. 1657fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * 1658fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * @return {@code true} if the supplied token is valid and unlock succeeds, 1659fcd49f993ede363d0b17900565dfe37066362480Rubin Xu * {@code false} otherwise. 1660fcd49f993ede363d0b17900565dfe37066362480Rubin Xu */ 1661fcd49f993ede363d0b17900565dfe37066362480Rubin Xu public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) { 1662fcd49f993ede363d0b17900565dfe37066362480Rubin Xu return getLockSettingsInternal().unlockUserWithToken(tokenHandle, token, userId); 1663f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu } 1664f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu 1665f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu 1666f095f8366bac52ac1eeb2b3eb1a403294ceeb541Rubin Xu /** 1667e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * Callback to be notified about progress when checking credentials. 1668e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi */ 1669e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi public interface CheckCredentialProgressCallback { 1670e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi 1671e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi /** 1672e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * Called as soon as possible when we know that the credentials match but the user hasn't 1673e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi * been fully unlocked. 1674e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi */ 1675e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi void onEarlyMatched(); 1676e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi } 1677e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi 1678a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang /** 1679b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Tracks the global strong authentication state. 1680b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1681b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public static class StrongAuthTracker { 1682b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1683b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos @IntDef(flag = true, 1684b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos value = { STRONG_AUTH_NOT_REQUIRED, 1685b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos STRONG_AUTH_REQUIRED_AFTER_BOOT, 1686b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW, 16879d6fc9246ba0b726872a6a8dabe6c334292c3a10Adrian Roos SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, 1688c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, 16894f28f0de37b00216dbe0f66513735a0ab7dd570dChad Brubaker STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, 16904f28f0de37b00216dbe0f66513735a0ab7dd570dChad Brubaker STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN}) 1691b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos @Retention(RetentionPolicy.SOURCE) 1692b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public @interface StrongAuthFlags {} 1693b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1694b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1695b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Strong authentication is not required. 1696b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1697b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public static final int STRONG_AUTH_NOT_REQUIRED = 0x0; 1698b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1699b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1700b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Strong authentication is required because the user has not authenticated since boot. 1701b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1702b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public static final int STRONG_AUTH_REQUIRED_AFTER_BOOT = 0x1; 1703b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1704b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 170516093fe3f0d824731a53a264a132504deb08421aJorim Jaggi * Strong authentication is required because a device admin has requested it. 1706b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1707b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public static final int STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW = 0x2; 1708b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1709b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 171016093fe3f0d824731a53a264a132504deb08421aJorim Jaggi * Some authentication is required because the user has temporarily disabled trust. 1711b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 171216093fe3f0d824731a53a264a132504deb08421aJorim Jaggi public static final int SOME_AUTH_REQUIRED_AFTER_USER_REQUEST = 0x4; 1713b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1714873010dfeea11e0f9982c66ad9bdc990d055b129Adrian Roos /** 1715873010dfeea11e0f9982c66ad9bdc990d055b129Adrian Roos * Strong authentication is required because the user has been locked out after too many 1716873010dfeea11e0f9982c66ad9bdc990d055b129Adrian Roos * attempts. 1717873010dfeea11e0f9982c66ad9bdc990d055b129Adrian Roos */ 1718873010dfeea11e0f9982c66ad9bdc990d055b129Adrian Roos public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8; 1719873010dfeea11e0f9982c66ad9bdc990d055b129Adrian Roos 1720af4ab3e2d3665c72889bf2337c744eca6c7d5e86Adrian Roos /** 1721c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski * Strong authentication is required because it hasn't been used for a time required by 1722c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski * a device admin. 1723c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski */ 1724c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski public static final int STRONG_AUTH_REQUIRED_AFTER_TIMEOUT = 0x10; 1725c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski 1726c52f867875ed7f671bf897f11e359e8104ce8795Michal Karpinski /** 17274f28f0de37b00216dbe0f66513735a0ab7dd570dChad Brubaker * Strong authentication is required because the user has triggered lockdown. 17284f28f0de37b00216dbe0f66513735a0ab7dd570dChad Brubaker */ 17294f28f0de37b00216dbe0f66513735a0ab7dd570dChad Brubaker public static final int STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN = 0x20; 17304f28f0de37b00216dbe0f66513735a0ab7dd570dChad Brubaker 17314f28f0de37b00216dbe0f66513735a0ab7dd570dChad Brubaker /** 17329d6fc9246ba0b726872a6a8dabe6c334292c3a10Adrian Roos * Strong auth flags that do not prevent fingerprint from being accepted as auth. 17339d6fc9246ba0b726872a6a8dabe6c334292c3a10Adrian Roos * 17349d6fc9246ba0b726872a6a8dabe6c334292c3a10Adrian Roos * If any other flags are set, fingerprint is disabled. 1735af4ab3e2d3665c72889bf2337c744eca6c7d5e86Adrian Roos */ 1736af4ab3e2d3665c72889bf2337c744eca6c7d5e86Adrian Roos private static final int ALLOWING_FINGERPRINT = STRONG_AUTH_NOT_REQUIRED 17379d6fc9246ba0b726872a6a8dabe6c334292c3a10Adrian Roos | SOME_AUTH_REQUIRED_AFTER_USER_REQUEST; 1738b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1739af4ab3e2d3665c72889bf2337c744eca6c7d5e86Adrian Roos private final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray(); 1740b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos private final H mHandler; 1741a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer private final int mDefaultStrongAuthFlags; 1742b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1743a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer public StrongAuthTracker(Context context) { 1744a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer this(context, Looper.myLooper()); 1745b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1746b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1747b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1748b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * @param looper the looper on whose thread calls to {@link #onStrongAuthRequiredChanged} 1749b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * will be scheduled. 1750a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer * @param context the current {@link Context} 1751b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1752a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer public StrongAuthTracker(Context context, Looper looper) { 1753b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos mHandler = new H(looper); 1754a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer mDefaultStrongAuthFlags = getDefaultFlags(context); 1755a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer } 1756a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer 1757a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer public static @StrongAuthFlags int getDefaultFlags(Context context) { 1758a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer boolean strongAuthRequired = context.getResources().getBoolean( 1759a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer com.android.internal.R.bool.config_strongAuthRequiredOnBoot); 1760a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer return strongAuthRequired ? STRONG_AUTH_REQUIRED_AFTER_BOOT : STRONG_AUTH_NOT_REQUIRED; 1761b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1762b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1763b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1764b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Returns {@link #STRONG_AUTH_NOT_REQUIRED} if strong authentication is not required, 1765b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * otherwise returns a combination of {@link StrongAuthFlags} indicating why strong 1766b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * authentication is required. 1767b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * 1768b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * @param userId the user for whom the state is queried. 1769b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1770b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public @StrongAuthFlags int getStrongAuthForUser(int userId) { 1771a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer return mStrongAuthRequiredForUser.get(userId, mDefaultStrongAuthFlags); 1772b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1773b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1774b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1775b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * @return true if unlocking with trust alone is allowed for {@param userId} by the current 1776b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * strong authentication requirements. 1777b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1778b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public boolean isTrustAllowedForUser(int userId) { 1779b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos return getStrongAuthForUser(userId) == STRONG_AUTH_NOT_REQUIRED; 1780b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1781b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1782b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1783b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * @return true if unlocking with fingerprint alone is allowed for {@param userId} by the 1784b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * current strong authentication requirements. 1785b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1786b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public boolean isFingerprintAllowedForUser(int userId) { 1787af4ab3e2d3665c72889bf2337c744eca6c7d5e86Adrian Roos return (getStrongAuthForUser(userId) & ~ALLOWING_FINGERPRINT) == 0; 1788b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1789b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1790b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos /** 1791b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos * Called when the strong authentication requirements for {@param userId} changed. 1792b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos */ 1793b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public void onStrongAuthRequiredChanged(int userId) { 1794b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1795b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1796a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang protected void handleStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags, 1797b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos int userId) { 1798b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos int oldValue = getStrongAuthForUser(userId); 1799b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos if (strongAuthFlags != oldValue) { 1800a7aa4d6f0b91e050c083c19459b0c8b265c92617Rakesh Iyer if (strongAuthFlags == mDefaultStrongAuthFlags) { 1801b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos mStrongAuthRequiredForUser.delete(userId); 1802b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } else { 1803b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos mStrongAuthRequiredForUser.put(userId, strongAuthFlags); 1804b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1805b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos onStrongAuthRequiredChanged(userId); 1806b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1807b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1808b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1809b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1810a0940d33dcbac0245ad5467d9c302f8eaee615dcVictor Chang protected final IStrongAuthTracker.Stub mStub = new IStrongAuthTracker.Stub() { 1811b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos @Override 1812b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public void onStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags, 1813b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos int userId) { 1814b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos mHandler.obtainMessage(H.MSG_ON_STRONG_AUTH_REQUIRED_CHANGED, 1815b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos strongAuthFlags, userId).sendToTarget(); 1816b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1817b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos }; 1818b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1819b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos private class H extends Handler { 1820b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos static final int MSG_ON_STRONG_AUTH_REQUIRED_CHANGED = 1; 1821b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1822b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public H(Looper looper) { 1823b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos super(looper); 1824b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1825b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos 1826b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos @Override 1827b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos public void handleMessage(Message msg) { 1828b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos switch (msg.what) { 1829b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos case MSG_ON_STRONG_AUTH_REQUIRED_CHANGED: 1830b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos handleStrongAuthRequiredChanged(msg.arg1, msg.arg2); 1831b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos break; 1832b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 1833b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 18343bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 18353bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 18363bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 18373bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu public void enableSyntheticPassword() { 18383bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1L, UserHandle.USER_SYSTEM); 18393bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu } 18403bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu 18417a0cc0a7fbfaae2843dd333ab8e62731bc04e2b2Paul Crowley public void disableSyntheticPassword() { 18427a0cc0a7fbfaae2843dd333ab8e62731bc04e2b2Paul Crowley setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0L, UserHandle.USER_SYSTEM); 18437a0cc0a7fbfaae2843dd333ab8e62731bc04e2b2Paul Crowley } 18447a0cc0a7fbfaae2843dd333ab8e62731bc04e2b2Paul Crowley 18453bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu public boolean isSyntheticPasswordEnabled() { 18463bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM) != 0; 1847b5e4722891e7bbf2fffcd995af02838667a3ababAdrian Roos } 18487374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos 18492adc263ce97ae6c8291653490868879841d31a63Adrian Roos public static boolean userOwnsFrpCredential(Context context, UserInfo info) { 18502adc263ce97ae6c8291653490868879841d31a63Adrian Roos return info != null && info.isPrimary() && info.isAdmin() && frpCredentialEnabled(context); 18517374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos } 18527374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos 18532adc263ce97ae6c8291653490868879841d31a63Adrian Roos public static boolean frpCredentialEnabled(Context context) { 18542adc263ce97ae6c8291653490868879841d31a63Adrian Roos return FRP_CREDENTIAL_ENABLED && context.getResources().getBoolean( 18552adc263ce97ae6c8291653490868879841d31a63Adrian Roos com.android.internal.R.bool.config_enableCredentialFactoryResetProtection); 18567374d3a4bca6bfbf7da1ef5dbf0db9f35f0c8315Adrian Roos } 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1858