• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.widget;
18 
19 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
20 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
21 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
22 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
23 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
24 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
25 import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
26 
27 import static com.android.internal.widget.flags.Flags.hideLastCharWithPhysicalInput;
28 
29 import android.annotation.IntDef;
30 import android.annotation.NonNull;
31 import android.annotation.Nullable;
32 import android.annotation.UserIdInt;
33 import android.app.PropertyInvalidatedCache;
34 import android.app.RemoteLockscreenValidationResult;
35 import android.app.RemoteLockscreenValidationSession;
36 import android.app.admin.DevicePolicyManager;
37 import android.app.admin.PasswordMetrics;
38 import android.app.trust.IStrongAuthTracker;
39 import android.app.trust.TrustManager;
40 import android.compat.annotation.UnsupportedAppUsage;
41 import android.content.ComponentName;
42 import android.content.ContentResolver;
43 import android.content.Context;
44 import android.content.pm.UserInfo;
45 import android.hardware.input.InputManagerGlobal;
46 import android.os.Build;
47 import android.os.Handler;
48 import android.os.Looper;
49 import android.os.Message;
50 import android.os.RemoteException;
51 import android.os.ServiceManager;
52 import android.os.SystemClock;
53 import android.os.SystemProperties;
54 import android.os.UserHandle;
55 import android.os.UserManager;
56 import android.os.storage.StorageManager;
57 import android.provider.Settings;
58 import android.text.TextUtils;
59 import android.util.Log;
60 import android.util.SparseBooleanArray;
61 import android.util.SparseIntArray;
62 import android.util.SparseLongArray;
63 import android.view.InputDevice;
64 
65 import com.android.internal.annotations.VisibleForTesting;
66 import com.android.internal.util.ArrayUtils;
67 import com.android.server.LocalServices;
68 
69 import com.google.android.collect.Lists;
70 
71 import java.lang.annotation.Retention;
72 import java.lang.annotation.RetentionPolicy;
73 import java.nio.charset.StandardCharsets;
74 import java.security.NoSuchAlgorithmException;
75 import java.security.SecureRandom;
76 import java.util.ArrayList;
77 import java.util.Arrays;
78 import java.util.Collection;
79 import java.util.List;
80 
81 /**
82  * Utilities for the lock pattern and its settings.
83  */
84 public class LockPatternUtils {
85     private static final String TAG = "LockPatternUtils";
86     private static final boolean FRP_CREDENTIAL_ENABLED = true;
87 
88     /**
89      * The interval of the countdown for showing progress of the lockout.
90      */
91     public static final long FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS = 1000L;
92 
93     /**
94      * This dictates when we start telling the user that continued failed attempts will wipe
95      * their device.
96      */
97     public static final int FAILED_ATTEMPTS_BEFORE_WIPE_GRACE = 5;
98 
99     /**
100      * The minimum number of dots in a valid pattern.
101      */
102     public static final int MIN_LOCK_PATTERN_SIZE = 4;
103 
104     /**
105      * The minimum size of a valid password or PIN.
106      */
107     public static final int MIN_LOCK_PASSWORD_SIZE = 4;
108 
109     /**
110      * The minimum number of dots the user must include in a wrong pattern attempt for it to be
111      * counted.
112      */
113     public static final int MIN_PATTERN_REGISTER_FAIL = MIN_LOCK_PATTERN_SIZE;
114 
115     // NOTE: When modifying this, make sure credential sufficiency validation logic is intact.
116     public static final int CREDENTIAL_TYPE_NONE = -1;
117     public static final int CREDENTIAL_TYPE_PATTERN = 1;
118     // This is the legacy value persisted on disk. Never return it to clients, but internally
119     // we still need it to handle upgrade cases.
120     public static final int CREDENTIAL_TYPE_PASSWORD_OR_PIN = 2;
121     public static final int CREDENTIAL_TYPE_PIN = 3;
122     public static final int CREDENTIAL_TYPE_PASSWORD = 4;
123 
124     // This is the value of pin length whenever pin length is not available
125     public static final int PIN_LENGTH_UNAVAILABLE = -1;
126 
127     // This is the minimum pin length at which auto confirmation is supported
128     public static final int MIN_AUTO_PIN_REQUIREMENT_LENGTH = 6;
129 
130     /**
131      * Header used for the encryption and decryption of the device credential for
132      * remote device lockscreen validation.
133      */
134     public static final byte[] ENCRYPTED_REMOTE_CREDENTIALS_HEADER =
135             "encrypted_remote_credentials".getBytes(StandardCharsets.UTF_8);
136 
137     @Retention(RetentionPolicy.SOURCE)
138     @IntDef(prefix = {"CREDENTIAL_TYPE_"}, value = {
139             CREDENTIAL_TYPE_NONE,
140             CREDENTIAL_TYPE_PATTERN,
141             CREDENTIAL_TYPE_PASSWORD,
142             CREDENTIAL_TYPE_PIN,
143             // CREDENTIAL_TYPE_PASSWORD_OR_PIN is missing on purpose.
144     })
145     public @interface CredentialType {}
146 
credentialTypeToString(int credentialType)147     public static String credentialTypeToString(int credentialType) {
148         switch (credentialType) {
149             case CREDENTIAL_TYPE_NONE:
150                 return "NONE";
151             case CREDENTIAL_TYPE_PATTERN:
152                 return "PATTERN";
153             case CREDENTIAL_TYPE_PIN:
154                 return "PIN";
155             case CREDENTIAL_TYPE_PASSWORD:
156                 return "PASSWORD";
157             default:
158                 return "UNKNOWN_" + credentialType;
159         }
160     }
161 
162     /**
163      * Flag provided to {@link #verifyCredential(LockscreenCredential, int, int)} . If set, the
164      * method will return a handle to the Gatekeeper Password in the
165      * {@link VerifyCredentialResponse}.
166      */
167     public static final int VERIFY_FLAG_REQUEST_GK_PW_HANDLE = 1 << 0;
168 
169     /**
170      * Flag provided to {@link #verifyCredential(LockscreenCredential, int, int)} . If set, the
171      * method writes the password data to the repair mode file after the credential is verified
172      * successfully.
173      */
174     public static final int VERIFY_FLAG_WRITE_REPAIR_MODE_PW = 1 << 1;
175 
176     @Retention(RetentionPolicy.SOURCE)
177     @IntDef(flag = true, value = {
178             VERIFY_FLAG_REQUEST_GK_PW_HANDLE,
179             VERIFY_FLAG_WRITE_REPAIR_MODE_PW
180     })
181     public @interface VerifyFlag {}
182 
183     /**
184      * Special user id for triggering the FRP verification flow.
185      */
186     public static final int USER_FRP = UserHandle.USER_NULL + 1;
187 
188     /**
189      * Special user id for triggering the exiting repair mode verification flow.
190      */
191     public static final int USER_REPAIR_MODE = UserHandle.USER_NULL + 2;
192 
193     public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
194     @Deprecated
195     public final static String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
196     public final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
197     public final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
198     public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
199             = "lockscreen.power_button_instantly_locks";
200     @Deprecated
201     public final static String LOCKSCREEN_WIDGETS_ENABLED = "lockscreen.widgets_enabled";
202 
203     public final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
204 
205     private static final String LOCK_SCREEN_OWNER_INFO = Settings.Secure.LOCK_SCREEN_OWNER_INFO;
206     private static final String LOCK_SCREEN_OWNER_INFO_ENABLED =
207             Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
208 
209     private static final String LOCK_PIN_ENHANCED_PRIVACY = "pin_enhanced_privacy";
210 
211     private static final String LOCK_SCREEN_DEVICE_OWNER_INFO = "lockscreen.device_owner_info";
212 
213     private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents";
214     private static final String KNOWN_TRUST_AGENTS = "lockscreen.knowntrustagents";
215     private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged";
216 
217     public static final String AUTO_PIN_CONFIRM = "lockscreen.auto_pin_confirm";
218 
219     public static final String CURRENT_LSKF_BASED_PROTECTOR_ID_KEY = "sp-handle";
220     public static final String PASSWORD_HISTORY_DELIMITER = ",";
221 
222     private static final String GSI_RUNNING_PROP = "ro.gsid.image_running";
223 
224     /**
225      * drives the pin auto confirmation feature availability in code logic.
226      */
227     public static final String FLAG_ENABLE_AUTO_PIN_CONFIRMATION =
228             "AutoPinConfirmation__enable_auto_pin_confirmation";
229 
230     @UnsupportedAppUsage
231     private final Context mContext;
232     @UnsupportedAppUsage
233     private final ContentResolver mContentResolver;
234     private DevicePolicyManager mDevicePolicyManager;
235     private ILockSettings mLockSettingsService;
236     private UserManager mUserManager;
237     private final Handler mHandler;
238     private final SparseLongArray mLockoutDeadlines = new SparseLongArray();
239     private Boolean mHasSecureLockScreen;
240 
241     /**
242      * Use {@link TrustManager#isTrustUsuallyManaged(int)}.
243      *
244      * This returns the lazily-peristed value and should only be used by TrustManagerService.
245      */
isTrustUsuallyManaged(int userId)246     public boolean isTrustUsuallyManaged(int userId) {
247         if (!(mLockSettingsService instanceof ILockSettings.Stub)) {
248             throw new IllegalStateException("May only be called by TrustManagerService. "
249                     + "Use TrustManager.isTrustUsuallyManaged()");
250         }
251         try {
252             return getLockSettings().getBoolean(IS_TRUST_USUALLY_MANAGED, false, userId);
253         } catch (RemoteException e) {
254             return false;
255         }
256     }
257 
setTrustUsuallyManaged(boolean managed, int userId)258     public void setTrustUsuallyManaged(boolean managed, int userId) {
259         try {
260             getLockSettings().setBoolean(IS_TRUST_USUALLY_MANAGED, managed, userId);
261         } catch (RemoteException e) {
262             // System dead.
263         }
264     }
265 
userPresent(int userId)266     public void userPresent(int userId) {
267         try {
268             getLockSettings().userPresent(userId);
269         } catch (RemoteException e) {
270             throw e.rethrowFromSystemServer();
271         }
272     }
273 
274     public static final class RequestThrottledException extends Exception {
275         private int mTimeoutMs;
276         @UnsupportedAppUsage
RequestThrottledException(int timeoutMs)277         public RequestThrottledException(int timeoutMs) {
278             mTimeoutMs = timeoutMs;
279         }
280 
281         /**
282          * @return The amount of time in ms before another request may
283          * be executed
284          */
285         @UnsupportedAppUsage
getTimeoutMs()286         public int getTimeoutMs() {
287             return mTimeoutMs;
288         }
289 
290     }
291 
292     /**
293      * This exists temporarily due to trunk-stable policies.
294      * Please use ArrayUtils directly if you can.
295      */
newNonMovableByteArray(int length)296     public static byte[] newNonMovableByteArray(int length) {
297         if (!android.security.Flags.secureArrayZeroization()) {
298             return new byte[length];
299         }
300         return ArrayUtils.newNonMovableByteArray(length);
301     }
302 
303     /**
304      * This exists temporarily due to trunk-stable policies.
305      * Please use ArrayUtils directly if you can.
306      */
newNonMovableCharArray(int length)307     public static char[] newNonMovableCharArray(int length) {
308         if (!android.security.Flags.secureArrayZeroization()) {
309             return new char[length];
310         }
311         return ArrayUtils.newNonMovableCharArray(length);
312     }
313 
314     /**
315      * This exists temporarily due to trunk-stable policies.
316      * Please use ArrayUtils directly if you can.
317      */
zeroize(byte[] array)318     public static void zeroize(byte[] array) {
319         if (!android.security.Flags.secureArrayZeroization()) {
320             if (array != null) {
321                 Arrays.fill(array, (byte) 0);
322             }
323             return;
324         }
325         ArrayUtils.zeroize(array);
326     }
327 
328     /**
329      * This exists temporarily due to trunk-stable policies.
330      * Please use ArrayUtils directly if you can.
331      */
zeroize(char[] array)332     public static void zeroize(char[] array) {
333         if (!android.security.Flags.secureArrayZeroization()) {
334             if (array != null) {
335                 Arrays.fill(array, (char) 0);
336             }
337             return;
338         }
339         ArrayUtils.zeroize(array);
340     }
341 
342     @UnsupportedAppUsage
getDevicePolicyManager()343     public DevicePolicyManager getDevicePolicyManager() {
344         if (mDevicePolicyManager == null) {
345             mDevicePolicyManager =
346                 (DevicePolicyManager)mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
347             if (mDevicePolicyManager == null) {
348                 Log.e(TAG, "Can't get DevicePolicyManagerService: is it running?",
349                         new IllegalStateException("Stack trace:"));
350             }
351         }
352         return mDevicePolicyManager;
353     }
354 
getUserManager()355     private UserManager getUserManager() {
356         if (mUserManager == null) {
357             mUserManager = UserManager.get(mContext);
358         }
359         return mUserManager;
360     }
361 
getTrustManager()362     private TrustManager getTrustManager() {
363         TrustManager trust = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
364         if (trust == null) {
365             Log.e(TAG, "Can't get TrustManagerService: is it running?",
366                     new IllegalStateException("Stack trace:"));
367         }
368         return trust;
369     }
370 
371     @UnsupportedAppUsage
LockPatternUtils(Context context)372     public LockPatternUtils(Context context) {
373         this(context, null);
374     }
375 
376     @VisibleForTesting
LockPatternUtils(Context context, ILockSettings lockSettings)377     public LockPatternUtils(Context context, ILockSettings lockSettings) {
378         mContext = context;
379         mContentResolver = context.getContentResolver();
380 
381         Looper looper = Looper.myLooper();
382         mHandler = looper != null ? new Handler(looper) : null;
383         mLockSettingsService = lockSettings;
384     }
385 
386     @UnsupportedAppUsage
387     @VisibleForTesting
getLockSettings()388     public ILockSettings getLockSettings() {
389         if (mLockSettingsService == null) {
390             ILockSettings service = ILockSettings.Stub.asInterface(
391                     ServiceManager.getService("lock_settings"));
392             mLockSettingsService = service;
393         }
394         return mLockSettingsService;
395     }
396 
getRequestedMinimumPasswordLength(int userId)397     public int getRequestedMinimumPasswordLength(int userId) {
398         return getDevicePolicyManager().getPasswordMinimumLength(null, userId);
399     }
400 
getMaximumPasswordLength(int quality)401     public int getMaximumPasswordLength(int quality) {
402         return getDevicePolicyManager().getPasswordMaximumLength(quality);
403     }
404 
405     /**
406      * Returns aggregated (legacy) password quality requirement on the target user from all admins.
407      */
getRequestedPasswordMetrics(int userId)408     public PasswordMetrics getRequestedPasswordMetrics(int userId) {
409         return getRequestedPasswordMetrics(userId, false);
410     }
411 
412     /**
413      * Returns aggregated (legacy) password quality requirement on the target user from all admins,
414      * optioanlly disregarding policies set on the managed profile as if the  profile had separate
415      * work challenge.
416      */
getRequestedPasswordMetrics(int userId, boolean deviceWideOnly)417     public PasswordMetrics getRequestedPasswordMetrics(int userId, boolean deviceWideOnly) {
418         return getDevicePolicyManager().getPasswordMinimumMetrics(userId, deviceWideOnly);
419     }
420 
getRequestedPasswordHistoryLength(int userId)421     private int getRequestedPasswordHistoryLength(int userId) {
422         return getDevicePolicyManager().getPasswordHistoryLength(null, userId);
423     }
424 
425     /**
426      * Returns the effective complexity for the user.
427      * @param userId  The user to return the complexity for.
428      * @return complexity level for the user.
429      */
getRequestedPasswordComplexity(int userId)430     public @DevicePolicyManager.PasswordComplexity int getRequestedPasswordComplexity(int userId) {
431         return getRequestedPasswordComplexity(userId, false);
432     }
433 
434     /**
435      * Returns the effective complexity for the user, optioanlly disregarding complexity set on the
436      * managed profile as if the  profile had separate work challenge.
437 
438      * @param userId  The user to return the complexity for.
439      * @param deviceWideOnly  whether to ignore complexity set on the managed profile.
440      * @return complexity level for the user.
441      */
getRequestedPasswordComplexity(int userId, boolean deviceWideOnly)442     public @DevicePolicyManager.PasswordComplexity int getRequestedPasswordComplexity(int userId,
443             boolean deviceWideOnly) {
444         return getDevicePolicyManager().getAggregatedPasswordComplexityForUser(userId,
445                 deviceWideOnly);
446     }
447 
448     @UnsupportedAppUsage
reportFailedPasswordAttempt(int userId)449     public void reportFailedPasswordAttempt(int userId) {
450         if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
451             return;
452         }
453         getDevicePolicyManager().reportFailedPasswordAttempt(userId);
454         if (!shouldTrustManagerListenForPrimaryAuth()) {
455             getTrustManager().reportUnlockAttempt(/* authenticated= */ false, userId);
456         }
457     }
458 
459     @UnsupportedAppUsage
reportSuccessfulPasswordAttempt(int userId)460     public void reportSuccessfulPasswordAttempt(int userId) {
461         if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
462             return;
463         }
464         getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
465         if (!shouldTrustManagerListenForPrimaryAuth()) {
466             getTrustManager().reportUnlockAttempt(/* authenticated= */ true, userId);
467         }
468     }
469 
reportPasswordLockout(int timeoutMs, int userId)470     public void reportPasswordLockout(int timeoutMs, int userId) {
471         if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
472             return;
473         }
474         getTrustManager().reportUnlockLockout(timeoutMs, userId);
475     }
476 
getCurrentFailedPasswordAttempts(int userId)477     public int getCurrentFailedPasswordAttempts(int userId) {
478         if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
479             return 0;
480         }
481         return getDevicePolicyManager().getCurrentFailedPasswordAttempts(userId);
482     }
483 
getMaximumFailedPasswordsForWipe(int userId)484     public int getMaximumFailedPasswordsForWipe(int userId) {
485         if (isSpecialUserId(mContext, userId, /* checkDeviceSupported= */ true)) {
486             return 0;
487         }
488         return getDevicePolicyManager().getMaximumFailedPasswordsForWipe(
489                 null /* componentName */, userId);
490     }
491 
492     /**
493      * Save the current password data to the repair mode file.
494      *
495      * @return true if success or false otherwise.
496      */
writeRepairModeCredential(int userId)497     public boolean writeRepairModeCredential(int userId) {
498         throwIfCalledOnMainThread();
499         try {
500             return getLockSettings().writeRepairModeCredential(userId);
501         } catch (RemoteException re) {
502             Log.e(TAG, "Failed to write repair mode credential", re);
503             return false;
504         }
505     }
506 
507     /**
508      * Check to see if a credential matches the saved one.
509      * If credential matches, return an opaque attestation that the challenge was verified.
510      *
511      * @param credential The credential to check.
512      * @param userId The user whose credential is being verified
513      * @param flags See {@link VerifyFlag}
514      * @throws IllegalStateException if called on the main thread.
515      */
516     @NonNull
verifyCredential(@onNull LockscreenCredential credential, int userId, @VerifyFlag int flags)517     public VerifyCredentialResponse verifyCredential(@NonNull LockscreenCredential credential,
518             int userId, @VerifyFlag int flags) {
519         throwIfCalledOnMainThread();
520         try {
521             final VerifyCredentialResponse response = getLockSettings().verifyCredential(
522                     credential, userId, flags);
523             if (response == null) {
524                 return VerifyCredentialResponse.ERROR;
525             } else {
526                 return response;
527             }
528         } catch (RemoteException re) {
529             Log.e(TAG, "failed to verify credential", re);
530             return VerifyCredentialResponse.ERROR;
531         }
532     }
533 
534     /**
535      * With the Gatekeeper Password Handle returned via {@link #verifyCredential(
536      * LockscreenCredential, int, int)}, request Gatekeeper to create a HardwareAuthToken wrapping
537      * the given challenge.
538      */
539     @NonNull
verifyGatekeeperPasswordHandle(long gatekeeperPasswordHandle, long challenge, int userId)540     public VerifyCredentialResponse verifyGatekeeperPasswordHandle(long gatekeeperPasswordHandle,
541             long challenge, int userId) {
542         try {
543             final VerifyCredentialResponse response = getLockSettings()
544                     .verifyGatekeeperPasswordHandle(gatekeeperPasswordHandle, challenge, userId);
545             if (response == null) {
546                 return VerifyCredentialResponse.ERROR;
547             }
548             return response;
549         } catch (RemoteException e) {
550             Log.e(TAG, "failed to verify gatekeeper password", e);
551             return VerifyCredentialResponse.ERROR;
552         }
553     }
554 
removeGatekeeperPasswordHandle(long gatekeeperPasswordHandle)555     public void removeGatekeeperPasswordHandle(long gatekeeperPasswordHandle) {
556         try {
557             getLockSettings().removeGatekeeperPasswordHandle(gatekeeperPasswordHandle);
558         } catch (RemoteException e) {
559             Log.e(TAG, "failed to remove gatekeeper password handle", e);
560         }
561     }
562 
563     /**
564      * Check to see if a credential matches the saved one.
565      *
566      * @param credential The credential to check.
567      * @param userId The user whose credential is being checked
568      * @param progressCallback callback to deliver early signal that the credential matches
569      * @return {@code true} if credential matches, {@code false} otherwise
570      * @throws RequestThrottledException if credential verification is being throttled due to
571      *         to many incorrect attempts.
572      * @throws IllegalStateException if called on the main thread.
573      */
checkCredential(@onNull LockscreenCredential credential, int userId, @Nullable CheckCredentialProgressCallback progressCallback)574     public boolean checkCredential(@NonNull LockscreenCredential credential, int userId,
575             @Nullable CheckCredentialProgressCallback progressCallback)
576             throws RequestThrottledException {
577         throwIfCalledOnMainThread();
578         try {
579             VerifyCredentialResponse response = getLockSettings().checkCredential(
580                     credential, userId, wrapCallback(progressCallback));
581             if (response == null) {
582                 return false;
583             } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
584                 return true;
585             } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
586                 throw new RequestThrottledException(response.getTimeout());
587             } else {
588                 return false;
589             }
590         } catch (RemoteException re) {
591             Log.e(TAG, "failed to check credential", re);
592             return false;
593         }
594     }
595 
596     /**
597      * Check if the credential of a managed profile with unified challenge matches. In this context,
598      * The credential should be the parent user's lockscreen password. If credential matches,
599      * return an opaque attestation associated with the managed profile that the challenge was
600      * verified.
601      *
602      * @param credential The parent user's credential to check.
603      * @return the attestation that the challenge was verified, or null
604      * @param userId The managed profile user id
605      * @param flags See {@link VerifyFlag}
606      * @throws IllegalStateException if called on the main thread.
607      */
608     @NonNull
verifyTiedProfileChallenge( @onNull LockscreenCredential credential, int userId, @VerifyFlag int flags)609     public VerifyCredentialResponse verifyTiedProfileChallenge(
610             @NonNull LockscreenCredential credential, int userId, @VerifyFlag int flags) {
611         throwIfCalledOnMainThread();
612         try {
613             final VerifyCredentialResponse response = getLockSettings()
614                     .verifyTiedProfileChallenge(credential, userId, flags);
615             if (response == null) {
616                 return VerifyCredentialResponse.ERROR;
617             } else {
618                 return response;
619             }
620         } catch (RemoteException re) {
621             Log.e(TAG, "failed to verify tied profile credential", re);
622             return VerifyCredentialResponse.ERROR;
623         }
624     }
625 
626     /**
627      * Returns the password history hash factor, needed to check new password against password
628      * history with {@link #checkPasswordHistory(byte[], byte[], int)}
629      */
getPasswordHistoryHashFactor(@onNull LockscreenCredential currentPassword, int userId)630     public byte[] getPasswordHistoryHashFactor(@NonNull LockscreenCredential currentPassword,
631             int userId) {
632         try {
633             return getLockSettings().getHashFactor(currentPassword, userId);
634         } catch (RemoteException e) {
635             Log.e(TAG, "failed to get hash factor", e);
636             return null;
637         }
638     }
639 
640     /**
641      * Check to see if a password matches any of the passwords stored in the
642      * password history.
643      *
644      * @param passwordToCheck The password to check.
645      * @param hashFactor Hash factor of the current user returned from
646      *        {@link ILockSettings#getHashFactor}
647      * @return Whether the password matches any in the history.
648      */
checkPasswordHistory(byte[] passwordToCheck, byte[] hashFactor, int userId)649     public boolean checkPasswordHistory(byte[] passwordToCheck, byte[] hashFactor, int userId) {
650         if (passwordToCheck == null || passwordToCheck.length == 0) {
651             Log.e(TAG, "checkPasswordHistory: empty password");
652             return false;
653         }
654         String passwordHistory = getString(PASSWORD_HISTORY_KEY, userId);
655         if (TextUtils.isEmpty(passwordHistory)) {
656             return false;
657         }
658         int passwordHistoryLength = getRequestedPasswordHistoryLength(userId);
659         if(passwordHistoryLength == 0) {
660             return false;
661         }
662         byte[] salt = getSalt(userId).getBytes();
663         String legacyHash = LockscreenCredential.legacyPasswordToHash(passwordToCheck, salt);
664         String passwordHash = LockscreenCredential.passwordToHistoryHash(
665                 passwordToCheck, salt, hashFactor);
666         String[] history = passwordHistory.split(PASSWORD_HISTORY_DELIMITER);
667         // Password History may be too long...
668         for (int i = 0; i < Math.min(passwordHistoryLength, history.length); i++) {
669             if (history[i].equals(legacyHash) || history[i].equals(passwordHash)) {
670                 return true;
671             }
672         }
673         return false;
674     }
675 
676     /**
677      * Returns the length of the PIN set by a particular user.
678      * @param userId user id of the user whose pin length we have to return
679      * @return
680      *       A. the length of the pin set by user if it is currently available
681      *       B. PIN_LENGTH_UNAVAILABLE if it is not available or if an exception occurs
682      */
getPinLength(int userId)683     public int getPinLength(int userId) {
684         try {
685             return getLockSettings().getPinLength(userId);
686         } catch (RemoteException e) {
687             Log.e(TAG, "Could not fetch PIN length " + e);
688             return PIN_LENGTH_UNAVAILABLE;
689         }
690     }
691 
692     /**
693      * This method saves the pin length value to disk based on the user's auto pin
694      * confirmation flag setting. If the auto pin confirmation flag is disabled, or if the
695      * user does not have a PIN setup, or if length of PIN is less than minimum storable PIN length
696      * value, the pin length value is set to PIN_LENGTH_UNAVAILABLE. Otherwise, if the
697      * flag is enabled, the pin length value is set to the actual length of the user's PIN.
698      * @param userId user id of the user whose pin length we want to save
699      * @return true/false depending on whether PIN length has been saved or not
700      */
refreshStoredPinLength(int userId)701     public boolean refreshStoredPinLength(int userId) {
702         try {
703             return getLockSettings().refreshStoredPinLength(userId);
704         } catch (RemoteException e) {
705             Log.e(TAG, "Could not store PIN length on disk " + e);
706             return false;
707         }
708     }
709 
710     /**
711      * Used by device policy manager to validate the current password
712      * information it has.
713      * @Deprecated use {@link #getKeyguardStoredPasswordQuality}
714      */
715     @UnsupportedAppUsage
getActivePasswordQuality(int userId)716     public int getActivePasswordQuality(int userId) {
717         return getKeyguardStoredPasswordQuality(userId);
718     }
719 
720     /**
721      * Use it to reset keystore without wiping work profile
722      */
resetKeyStore(int userId)723     public void resetKeyStore(int userId) {
724         try {
725             getLockSettings().resetKeyStore(userId);
726         } catch (RemoteException e) {
727             // It should not happen
728             Log.e(TAG, "Couldn't reset keystore " + e);
729         }
730     }
731 
732     /**
733      * Disable showing lock screen at all for a given user.
734      * This is only meaningful if pattern, pin or password are not set.
735      *
736      * @param disable Disables lock screen when true
737      * @param userId User ID of the user this has effect on
738      */
setLockScreenDisabled(boolean disable, int userId)739     public void setLockScreenDisabled(boolean disable, int userId) {
740         setBoolean(DISABLE_LOCKSCREEN_KEY, disable, userId);
741     }
742 
743     /**
744      * Determine if LockScreen is disabled for the current user. This is used to decide whether
745      * LockScreen is shown after reboot or after screen timeout / short press on power.
746      *
747      * @return true if lock screen is disabled
748      */
749     @UnsupportedAppUsage
isLockScreenDisabled(int userId)750     public boolean isLockScreenDisabled(int userId) {
751         if (isSecure(userId)) {
752             return false;
753         }
754         boolean disabledByDefault = mContext.getResources().getBoolean(
755                 com.android.internal.R.bool.config_disableLockscreenByDefault);
756         UserInfo userInfo = getUserManager().getUserInfo(userId);
757         boolean isDemoUser = UserManager.isDeviceInDemoMode(mContext) && userInfo != null
758                 && userInfo.isDemo();
759         return getBoolean(DISABLE_LOCKSCREEN_KEY, false, userId)
760                 || disabledByDefault
761                 || isDemoUser;
762     }
763 
764     /**
765      * Sets the pin auto confirm capability to enabled or disabled
766      * @param enabled enables pin auto confirm capability when true
767      * @param userId user ID of the user this has effect on
768      */
setAutoPinConfirm(boolean enabled, int userId)769     public void setAutoPinConfirm(boolean enabled, int userId) {
770         setBoolean(AUTO_PIN_CONFIRM, enabled, userId);
771     }
772 
773     /**
774      * Determines if the auto pin confirmation feature is enabled or not for current user
775      * If setting is not available, the default behaviour is disabled
776      * @param userId user ID of the user this has effect on
777      *
778      * @return true, if the entered pin should be auto confirmed
779      */
isAutoPinConfirmEnabled(int userId)780     public boolean isAutoPinConfirmEnabled(int userId) {
781         return getBoolean(AUTO_PIN_CONFIRM, /* defaultValue= */ false, userId);
782     }
783 
784     /**
785      * Whether the auto pin feature is available or not.
786      * @return true. This method is always returning true due to feature flags not working
787      * properly (b/282246482). Ideally, this should check if deviceConfig flag is set to true
788      * and then return the appropriate value.
789      */
isAutoPinConfirmFeatureAvailable()790     public static boolean isAutoPinConfirmFeatureAvailable() {
791         return true;
792     }
793 
794     /** Returns if the given quality maps to an alphabetic password */
isQualityAlphabeticPassword(int quality)795     public static boolean isQualityAlphabeticPassword(int quality) {
796         return quality >= PASSWORD_QUALITY_ALPHABETIC;
797     }
798 
799     /** Returns if the given quality maps to an numeric pin */
isQualityNumericPin(int quality)800     public static boolean isQualityNumericPin(int quality) {
801         return quality == PASSWORD_QUALITY_NUMERIC || quality == PASSWORD_QUALITY_NUMERIC_COMPLEX;
802     }
803 
804     /** Returns the canonical password quality corresponding to the given credential type. */
credentialTypeToPasswordQuality(int credentialType)805     public static int credentialTypeToPasswordQuality(int credentialType) {
806         switch (credentialType) {
807             case CREDENTIAL_TYPE_NONE:
808                 return PASSWORD_QUALITY_UNSPECIFIED;
809             case CREDENTIAL_TYPE_PATTERN:
810                 return PASSWORD_QUALITY_SOMETHING;
811             case CREDENTIAL_TYPE_PIN:
812                 return PASSWORD_QUALITY_NUMERIC;
813             case CREDENTIAL_TYPE_PASSWORD:
814                 return PASSWORD_QUALITY_ALPHABETIC;
815             default:
816                 throw new IllegalStateException("Unknown type: " + credentialType);
817         }
818     }
819 
820     /** Returns the credential type corresponding to the given PIN or password quality. */
pinOrPasswordQualityToCredentialType(int quality)821     public static int pinOrPasswordQualityToCredentialType(int quality) {
822         if (isQualityAlphabeticPassword(quality)) {
823             return CREDENTIAL_TYPE_PASSWORD;
824         }
825         if (isQualityNumericPin(quality)) {
826             return CREDENTIAL_TYPE_PIN;
827         }
828         throw new IllegalArgumentException("Quality is neither Pin nor password: " + quality);
829     }
830 
831     /**
832      * Save a new lockscreen credential.
833      *
834      * <p> This method will fail (returning {@code false}) if the previously saved credential
835      * provided is incorrect, or if the lockscreen verification is still being throttled.
836      *
837      * @param newCredential The new credential to save
838      * @param savedCredential The current credential
839      * @param userHandle the user whose lockscreen credential is to be changed
840      *
841      * @return whether this method saved the new password successfully or not. This flow will fail
842      * and return false if the given credential is wrong.
843      * @throws RuntimeException if password change encountered an unrecoverable error.
844      * @throws UnsupportedOperationException secure lockscreen is not supported on this device.
845      */
setLockCredential(@onNull LockscreenCredential newCredential, @NonNull LockscreenCredential savedCredential, int userHandle)846     public boolean setLockCredential(@NonNull LockscreenCredential newCredential,
847             @NonNull LockscreenCredential savedCredential, int userHandle) {
848         if (!hasSecureLockScreen() && newCredential.getType() != CREDENTIAL_TYPE_NONE) {
849             throw new UnsupportedOperationException(
850                     "This operation requires the lock screen feature.");
851         }
852 
853         try {
854             if (!getLockSettings().setLockCredential(newCredential, savedCredential, userHandle)) {
855                 return false;
856             }
857         } catch (RemoteException e) {
858             throw new RuntimeException("Unable to save lock password", e);
859         }
860         return true;
861     }
862 
863     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setOwnerInfo(String info, int userId)864     public void setOwnerInfo(String info, int userId) {
865         setString(LOCK_SCREEN_OWNER_INFO, info, userId);
866     }
867 
868     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setOwnerInfoEnabled(boolean enabled, int userId)869     public void setOwnerInfoEnabled(boolean enabled, int userId) {
870         setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId);
871     }
872 
873     @UnsupportedAppUsage
getOwnerInfo(int userId)874     public String getOwnerInfo(int userId) {
875         return getString(LOCK_SCREEN_OWNER_INFO, userId);
876     }
877 
isOwnerInfoEnabled(int userId)878     public boolean isOwnerInfoEnabled(int userId) {
879         return getBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, false, userId);
880     }
881 
882     /**
883      * Sets the device owner information. If the information is {@code null} or empty then the
884      * device owner info is cleared.
885      *
886      * @param info Device owner information which will be displayed instead of the user
887      * owner info.
888      */
setDeviceOwnerInfo(String info)889     public void setDeviceOwnerInfo(String info) {
890         if (info != null && info.isEmpty()) {
891             info = null;
892         }
893 
894         setString(LOCK_SCREEN_DEVICE_OWNER_INFO, info, UserHandle.USER_SYSTEM);
895     }
896 
getDeviceOwnerInfo()897     public String getDeviceOwnerInfo() {
898         return getString(LOCK_SCREEN_DEVICE_OWNER_INFO, UserHandle.USER_SYSTEM);
899     }
900 
isDeviceOwnerInfoEnabled()901     public boolean isDeviceOwnerInfoEnabled() {
902         return getDeviceOwnerInfo() != null;
903     }
904 
905     /**
906      * Determine if the device supports encryption, even if it's set to default. This
907      * differs from isDeviceEncrypted() in that it returns true even if the device is
908      * encrypted with the default password.
909      * @return true if device encryption is enabled
910      */
911     @UnsupportedAppUsage
isDeviceEncryptionEnabled()912     public static boolean isDeviceEncryptionEnabled() {
913         return StorageManager.isEncrypted();
914     }
915 
916     /**
917      * Determine if the device is file encrypted
918      * @return true if device is file encrypted
919      */
isFileEncryptionEnabled()920     public static boolean isFileEncryptionEnabled() {
921         return StorageManager.isFileEncrypted();
922     }
923 
924     /**
925      * Retrieves the quality mode for {@code userHandle}.
926      * @see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)
927      *
928      * @return stored password quality
929      * @deprecated use {@link #getCredentialTypeForUser(int)} instead
930      */
931     @UnsupportedAppUsage
932     @Deprecated
getKeyguardStoredPasswordQuality(int userHandle)933     public int getKeyguardStoredPasswordQuality(int userHandle) {
934         return credentialTypeToPasswordQuality(getCredentialTypeForUser(userHandle));
935     }
936 
937     /**
938      * Enables/disables the Separate Profile Challenge for this {@code userHandle}. This is a no-op
939      * for user handles that do not belong to a profile that shares credential with parent.
940      * (managed profile and clone profile share lock credential with parent).
941      *
942      * @param userHandle Managed profile user id
943      * @param enabled True if separate challenge is enabled
944      * @param profilePassword Managed/Clone profile previous password. Null when {@code enabled} is
945      *            true
946      */
setSeparateProfileChallengeEnabled(int userHandle, boolean enabled, LockscreenCredential profilePassword)947     public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled,
948             LockscreenCredential profilePassword) {
949         if (!isCredentialShareableWithParent(userHandle)) {
950             return;
951         }
952         try {
953             getLockSettings().setSeparateProfileChallengeEnabled(userHandle, enabled,
954                     profilePassword);
955             reportEnabledTrustAgentsChanged(userHandle);
956         } catch (RemoteException e) {
957             Log.e(TAG, "Couldn't update work profile challenge enabled");
958         }
959     }
960 
961     /**
962      * Returns true if {@code userHandle} is a profile with separate challenge.
963      * <p>
964      * Returns false if {@code userHandle} is a profile with unified challenge, a profile whose
965      * credential is not shareable with its parent, or a non-profile user.
966      */
isSeparateProfileChallengeEnabled(int userHandle)967     public boolean isSeparateProfileChallengeEnabled(int userHandle) {
968         return isCredentialShareableWithParent(userHandle) && hasSeparateChallenge(userHandle);
969     }
970 
971     /**
972      * Returns true if {@code userHandle} is a profile with unified challenge.
973      * <p>
974      * Returns false if {@code userHandle} is a profile with separate challenge, a profile whose
975      * credential is not shareable with its parent, or a non-profile user.
976      */
isProfileWithUnifiedChallenge(int userHandle)977     public boolean isProfileWithUnifiedChallenge(int userHandle) {
978         return isCredentialShareableWithParent(userHandle) && !hasSeparateChallenge(userHandle);
979     }
980 
981     /**
982      * Returns true if {@code userHandle} is a managed profile with unified challenge.
983      */
isManagedProfileWithUnifiedChallenge(int userHandle)984     public boolean isManagedProfileWithUnifiedChallenge(int userHandle) {
985         return isManagedProfile(userHandle) && !hasSeparateChallenge(userHandle);
986     }
987 
hasSeparateChallenge(int userHandle)988     private boolean hasSeparateChallenge(int userHandle) {
989         try {
990             return getLockSettings().getSeparateProfileChallengeEnabled(userHandle);
991         } catch (RemoteException e) {
992             Log.e(TAG, "Couldn't get separate profile challenge enabled");
993             // Default value is false
994             return false;
995         }
996     }
997 
isManagedProfile(int userHandle)998     private boolean isManagedProfile(int userHandle) {
999         final UserInfo info = getUserManager().getUserInfo(userHandle);
1000         return info != null && info.isManagedProfile();
1001     }
1002 
isCredentialShareableWithParent(int userHandle)1003     private boolean isCredentialShareableWithParent(int userHandle) {
1004         try {
1005             return getUserManager().getUserProperties(UserHandle.of(userHandle))
1006                     .isCredentialShareableWithParent();
1007         } catch (IllegalArgumentException e) {
1008             return false;
1009         }
1010     }
1011 
1012     /**
1013      * Deserialize a pattern.
1014      * @param  bytes The pattern serialized with {@link #patternToByteArray}
1015      * @return The pattern.
1016      */
byteArrayToPattern(byte[] bytes)1017     public static List<LockPatternView.Cell> byteArrayToPattern(byte[] bytes) {
1018         if (bytes == null) {
1019             return null;
1020         }
1021 
1022         List<LockPatternView.Cell> result = Lists.newArrayList();
1023 
1024         for (int i = 0; i < bytes.length; i++) {
1025             byte b = (byte) (bytes[i] - '1');
1026             result.add(LockPatternView.Cell.of(b / 3, b % 3));
1027         }
1028         return result;
1029     }
1030 
1031     /**
1032      * Serialize a pattern.
1033      * @param pattern The pattern.
1034      * @return The pattern in byte array form.
1035      */
patternToByteArray(List<LockPatternView.Cell> pattern)1036     public static byte[] patternToByteArray(List<LockPatternView.Cell> pattern) {
1037         if (pattern == null) {
1038             return new byte[0];
1039         }
1040         final int patternSize = pattern.size();
1041 
1042         byte[] res = newNonMovableByteArray(patternSize);
1043         for (int i = 0; i < patternSize; i++) {
1044             LockPatternView.Cell cell = pattern.get(i);
1045             res[i] = (byte) (cell.getRow() * 3 + cell.getColumn() + '1');
1046         }
1047         return res;
1048     }
1049 
getSalt(int userId)1050     private String getSalt(int userId) {
1051         long salt = getLong(LOCK_PASSWORD_SALT_KEY, 0, userId);
1052         if (salt == 0) {
1053             try {
1054                 salt = SecureRandom.getInstance("SHA1PRNG").nextLong();
1055                 setLong(LOCK_PASSWORD_SALT_KEY, salt, userId);
1056                 Log.v(TAG, "Initialized lock password salt for user: " + userId);
1057             } catch (NoSuchAlgorithmException e) {
1058                 // Throw an exception rather than storing a password we'll never be able to recover
1059                 throw new IllegalStateException("Couldn't get SecureRandom number", e);
1060             }
1061         }
1062         return Long.toHexString(salt);
1063     }
1064 
1065     /**
1066      * Retrieve the credential type of a user.
1067      */
1068     private final PropertyInvalidatedCache.QueryHandler<Integer, Integer> mCredentialTypeQuery =
1069             new PropertyInvalidatedCache.QueryHandler<>() {
1070                 @Override
1071                 public Integer apply(Integer userHandle) {
1072                     try {
1073                         return getLockSettings().getCredentialType(userHandle);
1074                     } catch (RemoteException re) {
1075                         Log.e(TAG, "failed to get credential type", re);
1076                         return CREDENTIAL_TYPE_NONE;
1077                     }
1078                 }
1079                 @Override
1080                 public boolean shouldBypassCache(Integer userHandle) {
1081                     return isSpecialUserId(userHandle);
1082                 }
1083             };
1084 
1085     /**
1086      * The API that is cached.
1087      */
1088     private final static String CREDENTIAL_TYPE_API = "getCredentialType";
1089 
1090     /**
1091      * Cache the credential type of a user.
1092      */
1093     private final PropertyInvalidatedCache<Integer, Integer> mCredentialTypeCache =
1094             new PropertyInvalidatedCache<>(4, PropertyInvalidatedCache.MODULE_SYSTEM,
1095                     CREDENTIAL_TYPE_API, CREDENTIAL_TYPE_API, mCredentialTypeQuery);
1096 
1097     /**
1098      * Invalidate the credential type cache
1099      * @hide
1100      */
invalidateCredentialTypeCache()1101     public final static void invalidateCredentialTypeCache() {
1102         PropertyInvalidatedCache.invalidateCache(PropertyInvalidatedCache.MODULE_SYSTEM,
1103                 CREDENTIAL_TYPE_API);
1104     }
1105 
1106     /**
1107      * Returns the credential type of the user, can be one of {@link #CREDENTIAL_TYPE_NONE},
1108      * {@link #CREDENTIAL_TYPE_PATTERN}, {@link #CREDENTIAL_TYPE_PIN} and
1109      * {@link #CREDENTIAL_TYPE_PASSWORD}
1110      */
getCredentialTypeForUser(int userHandle)1111     public @CredentialType int getCredentialTypeForUser(int userHandle) {
1112         return mCredentialTypeCache.query(userHandle);
1113     }
1114 
1115     /**
1116      * @param userId the user for which to report the value
1117      * @return Whether the lock screen is secured.
1118      */
1119     @UnsupportedAppUsage
isSecure(int userId)1120     public boolean isSecure(int userId) {
1121         int type = getCredentialTypeForUser(userId);
1122         return type != CREDENTIAL_TYPE_NONE;
1123     }
1124 
1125     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
isLockPasswordEnabled(int userId)1126     public boolean isLockPasswordEnabled(int userId) {
1127         int type = getCredentialTypeForUser(userId);
1128         return type == CREDENTIAL_TYPE_PASSWORD || type == CREDENTIAL_TYPE_PIN;
1129     }
1130 
1131     /**
1132      * @return Whether the lock pattern is enabled
1133      */
1134     @UnsupportedAppUsage
isLockPatternEnabled(int userId)1135     public boolean isLockPatternEnabled(int userId) {
1136         int type = getCredentialTypeForUser(userId);
1137         return type == CREDENTIAL_TYPE_PATTERN;
1138     }
1139 
hasActivePointerDeviceAttached()1140     private boolean hasActivePointerDeviceAttached() {
1141         return !getEnabledNonTouchInputDevices(InputDevice.SOURCE_CLASS_POINTER).isEmpty();
1142     }
1143 
1144     /**
1145      * @return Whether the visible pattern is enabled.
1146      */
1147     @UnsupportedAppUsage
isVisiblePatternEnabled(int userId)1148     public boolean isVisiblePatternEnabled(int userId) {
1149         boolean defaultValue = true;
1150         if (hideLastCharWithPhysicalInput()) {
1151             defaultValue = !hasActivePointerDeviceAttached();
1152         }
1153         return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, defaultValue, userId);
1154     }
1155 
1156     /**
1157      * Set whether the visible pattern is enabled.
1158      */
setVisiblePatternEnabled(boolean enabled, int userId)1159     public void setVisiblePatternEnabled(boolean enabled, int userId) {
1160         setBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, enabled, userId);
1161     }
1162 
isVisiblePatternEverChosen(int userId)1163     public boolean isVisiblePatternEverChosen(int userId) {
1164         return getString(Settings.Secure.LOCK_PATTERN_VISIBLE, userId) != null;
1165     }
1166 
getEnabledNonTouchInputDevices(int source)1167     private List<InputDevice> getEnabledNonTouchInputDevices(int source) {
1168         final InputManagerGlobal inputManager = InputManagerGlobal.getInstance();
1169         final int[] inputIds = inputManager.getInputDeviceIds();
1170         List<InputDevice> matchingDevices = new ArrayList<InputDevice>();
1171         for (final int deviceId : inputIds) {
1172             final InputDevice inputDevice = inputManager.getInputDevice(deviceId);
1173             if (!inputDevice.isEnabled()) continue;
1174             if (inputDevice.supportsSource(InputDevice.SOURCE_TOUCHSCREEN)) continue;
1175             if (inputDevice.isVirtual()) continue;
1176             if (!inputDevice.supportsSource(source)) continue;
1177             matchingDevices.add(inputDevice);
1178         }
1179         return matchingDevices;
1180     }
1181 
hasPhysicalKeyboardActive()1182     private boolean hasPhysicalKeyboardActive() {
1183         final List<InputDevice> keyboards =
1184                 getEnabledNonTouchInputDevices(InputDevice.SOURCE_KEYBOARD);
1185         for (final InputDevice keyboard : keyboards) {
1186             if (keyboard.isFullKeyboard()) return true;
1187         }
1188         return false;
1189     }
1190 
1191     /**
1192      * @return Whether enhanced pin privacy is enabled.
1193      */
isPinEnhancedPrivacyEnabled(int userId)1194     public boolean isPinEnhancedPrivacyEnabled(int userId) {
1195         boolean defaultValue = false;
1196         if (hideLastCharWithPhysicalInput()) {
1197             defaultValue = hasPhysicalKeyboardActive();
1198         }
1199         return getBoolean(LOCK_PIN_ENHANCED_PRIVACY, defaultValue, userId);
1200     }
1201 
1202     /**
1203      * Set whether enhanced pin privacy is enabled.
1204      */
setPinEnhancedPrivacyEnabled(boolean enabled, int userId)1205     public void setPinEnhancedPrivacyEnabled(boolean enabled, int userId) {
1206         setBoolean(LOCK_PIN_ENHANCED_PRIVACY, enabled, userId);
1207     }
1208 
1209     /**
1210      * @return Whether enhanced pin privacy was ever chosen.
1211      */
isPinEnhancedPrivacyEverChosen(int userId)1212     public boolean isPinEnhancedPrivacyEverChosen(int userId) {
1213         return getString(LOCK_PIN_ENHANCED_PRIVACY, userId) != null;
1214     }
1215 
1216     /**
1217      * Set and store the lockout deadline, meaning the user can't attempt their unlock
1218      * pattern until the deadline has passed.
1219      * @return the chosen deadline.
1220      */
1221     @UnsupportedAppUsage
setLockoutAttemptDeadline(int userId, int timeoutMs)1222     public long setLockoutAttemptDeadline(int userId, int timeoutMs) {
1223         final long deadline = SystemClock.elapsedRealtime() + timeoutMs;
1224         if (userId == USER_FRP) {
1225             // For secure password storage (that is required for FRP), the underlying storage also
1226             // enforces the deadline. Since we cannot store settings for the FRP user, don't.
1227             return deadline;
1228         }
1229         mLockoutDeadlines.put(userId, deadline);
1230         return deadline;
1231     }
1232 
1233     /**
1234      * @return The elapsed time in millis in the future when the user is allowed to
1235      *   attempt to enter their lock pattern, or 0 if the user is welcome to
1236      *   enter a pattern.
1237      */
getLockoutAttemptDeadline(int userId)1238     public long getLockoutAttemptDeadline(int userId) {
1239         final long deadline = mLockoutDeadlines.get(userId, 0L);
1240         final long now = SystemClock.elapsedRealtime();
1241         if (deadline < now && deadline != 0) {
1242             // timeout expired
1243             mLockoutDeadlines.put(userId, 0);
1244             return 0L;
1245         }
1246         return deadline;
1247     }
1248 
getBoolean(String secureSettingKey, boolean defaultValue, int userId)1249     private boolean getBoolean(String secureSettingKey, boolean defaultValue, int userId) {
1250         try {
1251             return getLockSettings().getBoolean(secureSettingKey, defaultValue, userId);
1252         } catch (RemoteException re) {
1253             return defaultValue;
1254         }
1255     }
1256 
setBoolean(String secureSettingKey, boolean enabled, int userId)1257     private void setBoolean(String secureSettingKey, boolean enabled, int userId) {
1258         try {
1259             getLockSettings().setBoolean(secureSettingKey, enabled, userId);
1260         } catch (RemoteException re) {
1261             // What can we do?
1262             Log.e(TAG, "Couldn't write boolean " + secureSettingKey + re);
1263         }
1264     }
1265 
getLong(String secureSettingKey, long defaultValue, int userHandle)1266     private long getLong(String secureSettingKey, long defaultValue, int userHandle) {
1267         try {
1268             return getLockSettings().getLong(secureSettingKey, defaultValue, userHandle);
1269         } catch (RemoteException re) {
1270             return defaultValue;
1271         }
1272     }
1273 
1274     @UnsupportedAppUsage
setLong(String secureSettingKey, long value, int userHandle)1275     private void setLong(String secureSettingKey, long value, int userHandle) {
1276         try {
1277             getLockSettings().setLong(secureSettingKey, value, userHandle);
1278         } catch (RemoteException re) {
1279             // What can we do?
1280             Log.e(TAG, "Couldn't write long " + secureSettingKey + re);
1281         }
1282     }
1283 
1284     @UnsupportedAppUsage
getString(String secureSettingKey, int userHandle)1285     private String getString(String secureSettingKey, int userHandle) {
1286         try {
1287             return getLockSettings().getString(secureSettingKey, null, userHandle);
1288         } catch (RemoteException re) {
1289             return null;
1290         }
1291     }
1292 
1293     @UnsupportedAppUsage
setString(String secureSettingKey, String value, int userHandle)1294     private void setString(String secureSettingKey, String value, int userHandle) {
1295         try {
1296             getLockSettings().setString(secureSettingKey, value, userHandle);
1297         } catch (RemoteException re) {
1298             // What can we do?
1299             Log.e(TAG, "Couldn't write string " + secureSettingKey + re);
1300         }
1301     }
1302 
setPowerButtonInstantlyLocks(boolean enabled, int userId)1303     public void setPowerButtonInstantlyLocks(boolean enabled, int userId) {
1304         setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId);
1305     }
1306 
1307     @UnsupportedAppUsage
getPowerButtonInstantlyLocks(int userId)1308     public boolean getPowerButtonInstantlyLocks(int userId) {
1309         return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId);
1310     }
1311 
isPowerButtonInstantlyLocksEverChosen(int userId)1312     public boolean isPowerButtonInstantlyLocksEverChosen(int userId) {
1313         return getString(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, userId) != null;
1314     }
1315 
1316     /** Updates the list of enabled trust agent in LockSettings storage for the given user. */
setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents, int userId)1317     public void setEnabledTrustAgents(Collection<ComponentName> activeTrustAgents, int userId) {
1318         setString(ENABLED_TRUST_AGENTS, serializeTrustAgents(activeTrustAgents), userId);
1319         getTrustManager().reportEnabledTrustAgentsChanged(userId);
1320     }
1321 
1322     /** Returns the list of enabled trust agent in LockSettings storage for the given user. */
getEnabledTrustAgents(int userId)1323     public List<ComponentName> getEnabledTrustAgents(int userId) {
1324         return deserializeTrustAgents(getString(ENABLED_TRUST_AGENTS, userId));
1325     }
1326 
1327     /** Updates the list of known trust agent in LockSettings storage for the given user. */
setKnownTrustAgents(Collection<ComponentName> knownTrustAgents, int userId)1328     public void setKnownTrustAgents(Collection<ComponentName> knownTrustAgents, int userId) {
1329         setString(KNOWN_TRUST_AGENTS, serializeTrustAgents(knownTrustAgents), userId);
1330     }
1331 
1332     /** Returns the list of known trust agent in LockSettings storage for the given user. */
getKnownTrustAgents(int userId)1333     public List<ComponentName> getKnownTrustAgents(int userId) {
1334         return deserializeTrustAgents(getString(KNOWN_TRUST_AGENTS, userId));
1335     }
1336 
serializeTrustAgents(Collection<ComponentName> trustAgents)1337     private String serializeTrustAgents(Collection<ComponentName> trustAgents) {
1338         StringBuilder sb = new StringBuilder();
1339         for (ComponentName cn : trustAgents) {
1340             if (sb.length() > 0) {
1341                 sb.append(',');
1342             }
1343             sb.append(cn.flattenToShortString());
1344         }
1345         return sb.toString();
1346     }
1347 
deserializeTrustAgents(String serializedTrustAgents)1348     private List<ComponentName> deserializeTrustAgents(String serializedTrustAgents) {
1349         if (TextUtils.isEmpty(serializedTrustAgents)) {
1350             return new ArrayList<>();
1351         }
1352         String[] split = serializedTrustAgents.split(",");
1353         ArrayList<ComponentName> trustAgents = new ArrayList<>(split.length);
1354         for (String s : split) {
1355             if (!TextUtils.isEmpty(s)) {
1356                 trustAgents.add(ComponentName.unflattenFromString(s));
1357             }
1358         }
1359         return trustAgents;
1360     }
1361 
1362     /**
1363      * Disable trust until credentials have been entered for user {@code userId}.
1364      *
1365      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
1366      *
1367      * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
1368      */
requireCredentialEntry(int userId)1369     public void requireCredentialEntry(int userId) {
1370         requireStrongAuth(StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, userId);
1371     }
1372 
1373     /**
1374      * Requests strong authentication for user {@code userId}.
1375      *
1376      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
1377      *
1378      * @param strongAuthReason a combination of {@link StrongAuthTracker.StrongAuthFlags} indicating
1379      *                         the reason for and the strength of the requested authentication.
1380      * @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
1381      */
requireStrongAuth(@trongAuthTracker.StrongAuthFlags int strongAuthReason, int userId)1382     public void requireStrongAuth(@StrongAuthTracker.StrongAuthFlags int strongAuthReason,
1383             int userId) {
1384         try {
1385             getLockSettings().requireStrongAuth(strongAuthReason, userId);
1386         } catch (RemoteException e) {
1387             Log.e(TAG, "Error while requesting strong auth: " + e);
1388         }
1389     }
1390 
reportEnabledTrustAgentsChanged(int userHandle)1391     private void reportEnabledTrustAgentsChanged(int userHandle) {
1392         getTrustManager().reportEnabledTrustAgentsChanged(userHandle);
1393     }
1394 
throwIfCalledOnMainThread()1395     private void throwIfCalledOnMainThread() {
1396         if (Looper.getMainLooper().isCurrentThread()) {
1397             throw new IllegalStateException("should not be called from the main thread.");
1398         }
1399     }
1400 
registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker)1401     public void registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
1402         try {
1403             getLockSettings().registerStrongAuthTracker(strongAuthTracker.getStub());
1404         } catch (RemoteException e) {
1405             e.rethrowFromSystemServer();
1406         }
1407     }
1408 
unregisterStrongAuthTracker(final StrongAuthTracker strongAuthTracker)1409     public void unregisterStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
1410         try {
1411             getLockSettings().unregisterStrongAuthTracker(strongAuthTracker.getStub());
1412         } catch (RemoteException e) {
1413             Log.e(TAG, "Could not unregister StrongAuthTracker", e);
1414         }
1415     }
1416 
1417     /** Register the given WeakEscrowTokenRemovedListener. */
registerWeakEscrowTokenRemovedListener( @onNull final IWeakEscrowTokenRemovedListener listener)1418     public boolean registerWeakEscrowTokenRemovedListener(
1419             @NonNull final IWeakEscrowTokenRemovedListener listener) {
1420         try {
1421             return getLockSettings().registerWeakEscrowTokenRemovedListener(listener);
1422         } catch (RemoteException e) {
1423             Log.e(TAG, "Could not register WeakEscrowTokenRemovedListener.");
1424             throw e.rethrowFromSystemServer();
1425         }
1426     }
1427 
1428     /** Unregister the given WeakEscrowTokenRemovedListener. */
unregisterWeakEscrowTokenRemovedListener( @onNull final IWeakEscrowTokenRemovedListener listener)1429     public boolean unregisterWeakEscrowTokenRemovedListener(
1430             @NonNull final IWeakEscrowTokenRemovedListener listener) {
1431         try {
1432             return getLockSettings().unregisterWeakEscrowTokenRemovedListener(listener);
1433         } catch (RemoteException e) {
1434             Log.e(TAG, "Could not register WeakEscrowTokenRemovedListener.");
1435             throw e.rethrowFromSystemServer();
1436         }
1437     }
1438 
reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId)1439     public void reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId) {
1440         try {
1441             getLockSettings().reportSuccessfulBiometricUnlock(isStrongBiometric, userId);
1442         } catch (RemoteException e) {
1443             Log.e(TAG, "Could not report successful biometric unlock", e);
1444         }
1445     }
1446 
scheduleNonStrongBiometricIdleTimeout(int userId)1447     public void scheduleNonStrongBiometricIdleTimeout(int userId) {
1448         try {
1449             getLockSettings().scheduleNonStrongBiometricIdleTimeout(userId);
1450         } catch (RemoteException e) {
1451             Log.e(TAG, "Could not schedule non-strong biometric idle timeout", e);
1452         }
1453     }
1454 
1455     /**
1456      * @see StrongAuthTracker#getStrongAuthForUser
1457      */
getStrongAuthForUser(int userId)1458     public int getStrongAuthForUser(int userId) {
1459         try {
1460             return getLockSettings().getStrongAuthForUser(userId);
1461         } catch (RemoteException e) {
1462             Log.e(TAG, "Could not get StrongAuth", e);
1463             return StrongAuthTracker.getDefaultFlags(mContext);
1464         }
1465     }
1466 
1467     /**
1468      * Whether the user is not allowed to set any credentials via PASSWORD_QUALITY_MANAGED.
1469      */
isCredentialsDisabledForUser(int userId)1470     public boolean isCredentialsDisabledForUser(int userId) {
1471         return getDevicePolicyManager().getPasswordQuality(/* admin= */ null, userId)
1472                 == PASSWORD_QUALITY_MANAGED;
1473     }
1474 
1475     /**
1476      * @see StrongAuthTracker#isTrustAllowedForUser
1477      */
isTrustAllowedForUser(int userId)1478     public boolean isTrustAllowedForUser(int userId) {
1479         return getStrongAuthForUser(userId) == StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
1480     }
1481 
1482     /**
1483      * @see StrongAuthTracker#isBiometricAllowedForUser(int)
1484      */
isBiometricAllowedForUser(int userId)1485     public boolean isBiometricAllowedForUser(int userId) {
1486         return (getStrongAuthForUser(userId) & ~StrongAuthTracker.ALLOWING_BIOMETRIC) == 0;
1487     }
1488 
isUserInLockdown(int userId)1489     public boolean isUserInLockdown(int userId) {
1490         return (getStrongAuthForUser(userId)
1491                 & StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0;
1492     }
1493 
1494     private static class WrappedCallback extends ICheckCredentialProgressCallback.Stub {
1495 
1496         private Handler mHandler;
1497         private CheckCredentialProgressCallback mCallback;
1498 
WrappedCallback(Handler handler, CheckCredentialProgressCallback callback)1499         WrappedCallback(Handler handler, CheckCredentialProgressCallback callback) {
1500             mHandler = handler;
1501             mCallback = callback;
1502         }
1503 
1504         @Override
onCredentialVerified()1505         public void onCredentialVerified() throws RemoteException {
1506             if (mHandler == null) {
1507                 Log.e(TAG, "Handler is null during callback");
1508             }
1509             // Kill reference immediately to allow early GC at client side independent of
1510             // when system_server decides to lose its reference to the
1511             // ICheckCredentialProgressCallback binder object.
1512             mHandler.post(() -> {
1513                 mCallback.onEarlyMatched();
1514                 mCallback = null;
1515             });
1516             mHandler = null;
1517         }
1518     }
1519 
wrapCallback( final CheckCredentialProgressCallback callback)1520     private ICheckCredentialProgressCallback wrapCallback(
1521             final CheckCredentialProgressCallback callback) {
1522         if (callback == null) {
1523             return null;
1524         } else {
1525             if (mHandler == null) {
1526                 throw new IllegalStateException("Must construct LockPatternUtils on a looper thread"
1527                         + " to use progress callbacks.");
1528             }
1529             return new WrappedCallback(mHandler, callback);
1530         }
1531     }
1532 
getLockSettingsInternal()1533     private LockSettingsInternal getLockSettingsInternal() {
1534         LockSettingsInternal service = LocalServices.getService(LockSettingsInternal.class);
1535         if (service == null) {
1536             throw new SecurityException("Only available to system server itself");
1537         }
1538         return service;
1539     }
1540     /**
1541      * Create an escrow token for the current user, which can later be used to unlock FBE
1542      * or change user password.
1543      *
1544      * After adding, if the user currently has lockscreen password, they will need to perform a
1545      * confirm credential operation in order to activate the token for future use. If the user
1546      * has no secure lockscreen, then the token is activated immediately.
1547      *
1548      * <p>This method is only available to code running in the system server process itself.
1549      *
1550      * @return a unique 64-bit token handle which is needed to refer to this token later.
1551      */
addEscrowToken(byte[] token, int userId, @Nullable EscrowTokenStateChangeCallback callback)1552     public long addEscrowToken(byte[] token, int userId,
1553             @Nullable EscrowTokenStateChangeCallback callback) {
1554         return getLockSettingsInternal().addEscrowToken(token, userId, callback);
1555     }
1556 
1557     /**
1558      * Create a weak escrow token for the current user, which can later be used to unlock FBE
1559      * or change user password.
1560      *
1561      * After adding, if the user currently has lockscreen password, they will need to perform a
1562      * confirm credential operation in order to activate the token for future use. If the user
1563      * has no secure lockscreen, then the token is activated immediately.
1564      *
1565      * If the user changes or removes lockscreen password, activated weak escrow tokens will be
1566      * removed.
1567      *
1568      * @return a unique 64-bit token handle which is needed to refer to this token later.
1569      */
addWeakEscrowToken(byte[] token, int userId, @NonNull IWeakEscrowTokenActivatedListener callback)1570     public long addWeakEscrowToken(byte[] token, int userId,
1571             @NonNull IWeakEscrowTokenActivatedListener callback) {
1572         try {
1573             return getLockSettings().addWeakEscrowToken(token, userId, callback);
1574         } catch (RemoteException e) {
1575             Log.e(TAG, "Could not add weak token.");
1576             throw e.rethrowFromSystemServer();
1577         }
1578     }
1579 
1580     /**
1581      * Callback interface to notify when an added escrow token has been activated.
1582      */
1583     public interface EscrowTokenStateChangeCallback {
1584         /**
1585          * The method to be called when the token is activated.
1586          * @param handle 64 bit handle corresponding to the escrow token
1587          * @param userId user for whom the escrow token has been added
1588          */
onEscrowTokenActivated(long handle, int userId)1589         void onEscrowTokenActivated(long handle, int userId);
1590     }
1591 
1592     /**
1593      * Remove an escrow token.
1594      *
1595      * <p>This method is only available to code running in the system server process itself.
1596      *
1597      * @return true if the given handle refers to a valid token previously returned from
1598      * {@link #addEscrowToken}, whether it's active or not. return false otherwise.
1599      */
removeEscrowToken(long handle, int userId)1600     public boolean removeEscrowToken(long handle, int userId) {
1601         return getLockSettingsInternal().removeEscrowToken(handle, userId);
1602     }
1603 
1604     /**
1605      * Remove a weak escrow token.
1606      *
1607      * @return true if the given handle refers to a valid weak token previously returned from
1608      * {@link #addWeakEscrowToken}, whether it's active or not. return false otherwise.
1609      */
removeWeakEscrowToken(long handle, int userId)1610     public boolean removeWeakEscrowToken(long handle, int userId) {
1611         try {
1612             return getLockSettings().removeWeakEscrowToken(handle, userId);
1613         } catch (RemoteException e) {
1614             Log.e(TAG, "Could not remove the weak token.");
1615             throw e.rethrowFromSystemServer();
1616         }
1617     }
1618 
1619     /**
1620      * Check if the given escrow token is active or not. Only active token can be used to call
1621      * {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken}
1622      *
1623      * <p>This method is only available to code running in the system server process itself.
1624      */
isEscrowTokenActive(long handle, int userId)1625     public boolean isEscrowTokenActive(long handle, int userId) {
1626         return getLockSettingsInternal().isEscrowTokenActive(handle, userId);
1627     }
1628 
1629     /**
1630      * Check if the given weak escrow token is active or not. Only active token can be used to call
1631      * {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken}
1632      */
isWeakEscrowTokenActive(long handle, int userId)1633     public boolean isWeakEscrowTokenActive(long handle, int userId) {
1634         try {
1635             return getLockSettings().isWeakEscrowTokenActive(handle, userId);
1636         } catch (RemoteException e) {
1637             Log.e(TAG, "Could not check the weak token.");
1638             throw e.rethrowFromSystemServer();
1639         }
1640     }
1641 
1642     /** Check if the given weak escrow token is valid. */
isWeakEscrowTokenValid(long handle, byte[] token, int userId)1643     public boolean isWeakEscrowTokenValid(long handle, byte[] token, int userId) {
1644         try {
1645             return getLockSettings().isWeakEscrowTokenValid(handle, token, userId);
1646         } catch (RemoteException e) {
1647             Log.e(TAG, "Could not validate the weak token.");
1648             throw e.rethrowFromSystemServer();
1649         }
1650     }
1651 
1652     /**
1653      * Change a user's lock credential with a pre-configured escrow token.
1654      *
1655      * <p>This method is only available to code running in the system server process itself.
1656      *
1657      * @param credential The new credential to be set
1658      * @param tokenHandle Handle of the escrow token
1659      * @param token Escrow token
1660      * @param userHandle The user who's lock credential to be changed
1661      * @return {@code true} if the operation is successful.
1662      */
setLockCredentialWithToken(@onNull LockscreenCredential credential, long tokenHandle, byte[] token, int userHandle)1663     public boolean setLockCredentialWithToken(@NonNull LockscreenCredential credential,
1664             long tokenHandle, byte[] token, int userHandle) {
1665         if (!hasSecureLockScreen() && credential.getType() != CREDENTIAL_TYPE_NONE) {
1666             throw new UnsupportedOperationException(
1667                     "This operation requires the lock screen feature.");
1668         }
1669         LockSettingsInternal localService = getLockSettingsInternal();
1670 
1671         return localService.setLockCredentialWithToken(credential, tokenHandle, token, userHandle);
1672     }
1673 
1674     /**
1675      * Unlock the specified user by an pre-activated escrow token. This should have the same effect
1676      * on device encryption as the user entering their lockscreen credentials for the first time after
1677      * boot, this includes unlocking the user's credential-encrypted storage as well as the keystore
1678      *
1679      * <p>This method is only available to code running in the system server process itself.
1680      *
1681      * @return {@code true} if the supplied token is valid and unlock succeeds,
1682      *         {@code false} otherwise.
1683      */
unlockUserWithToken(long tokenHandle, byte[] token, int userId)1684     public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) {
1685         return getLockSettingsInternal().unlockUserWithToken(tokenHandle, token, userId);
1686     }
1687 
1688 
1689     /**
1690      * Callback to be notified about progress when checking credentials.
1691      */
1692     public interface CheckCredentialProgressCallback {
1693 
1694         /**
1695          * Called as soon as possible when we know that the credentials match but the user hasn't
1696          * been fully unlocked.
1697          */
onEarlyMatched()1698         void onEarlyMatched();
1699     }
1700 
1701     /**
1702      * Tracks the global strong authentication state.
1703      */
1704     public static class StrongAuthTracker {
1705 
1706         @IntDef(flag = true,
1707                 value = { STRONG_AUTH_NOT_REQUIRED,
1708                         STRONG_AUTH_REQUIRED_AFTER_BOOT,
1709                         STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
1710                         SOME_AUTH_REQUIRED_AFTER_USER_REQUEST,
1711                         STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
1712                         STRONG_AUTH_REQUIRED_AFTER_TIMEOUT,
1713                         STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN,
1714                         STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT,
1715                         SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED,
1716                         SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST})
1717         @Retention(RetentionPolicy.SOURCE)
1718         public @interface StrongAuthFlags {}
1719 
1720         /**
1721          * Strong authentication is not required.
1722          */
1723         public static final int STRONG_AUTH_NOT_REQUIRED = 0x0;
1724 
1725         /**
1726          * Strong authentication is required because the user has not authenticated since boot.
1727          */
1728         public static final int STRONG_AUTH_REQUIRED_AFTER_BOOT = 0x1;
1729 
1730         /**
1731          * Strong authentication is required because a device admin has requested it.
1732          */
1733         public static final int STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW = 0x2;
1734 
1735         /**
1736          * Some authentication is required because the user has temporarily disabled trust.
1737          */
1738         public static final int SOME_AUTH_REQUIRED_AFTER_USER_REQUEST = 0x4;
1739 
1740         /**
1741          * Strong authentication is required because the user has been locked out after too many
1742          * attempts using primary auth methods (i.e. PIN/pattern/password) from the lock screen,
1743          * Android Settings, and BiometricPrompt where user authentication is required.
1744          */
1745         public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8;
1746 
1747         /**
1748          * Strong authentication is required because it hasn't been used for a time required by
1749          * a device admin.
1750          */
1751         public static final int STRONG_AUTH_REQUIRED_AFTER_TIMEOUT = 0x10;
1752 
1753         /**
1754          * Strong authentication is required because the user has triggered lockdown.
1755          */
1756         public static final int STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN = 0x20;
1757 
1758         /**
1759          * Strong authentication is required to prepare for unattended upgrade.
1760          */
1761         public static final int STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE = 0x40;
1762 
1763         /**
1764          * Strong authentication is required because it hasn't been used for a time after a
1765          * non-strong biometric (i.e. weak or convenience biometric) is used to unlock device.
1766          */
1767         public static final int STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT = 0x80;
1768 
1769         /**
1770          * Some authentication is required because the trustagent either timed out or was disabled
1771          * manually.
1772          */
1773         public static final int SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED = 0x100;
1774 
1775         /**
1776          * Some authentication is required because adaptive auth has requested to lock device due to
1777          * repeated failed primary auth (i.e. PIN/pattern/password) or biometric auth attempts which
1778          * can come from Android Settings or BiometricPrompt where user authentication is required,
1779          * in addition to from the lock screen. When a risk is determined, adaptive auth will
1780          * proactively prompt the lock screen and will require users to re-enter the device with
1781          * either primary auth or biometric auth (if not prohibited by other flags).
1782          */
1783         public static final int SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST = 0x200;
1784 
1785         /**
1786          * Strong auth flags that do not prevent biometric methods from being accepted as auth.
1787          * If any other flags are set, biometric authentication is disabled.
1788          */
1789         private static final int ALLOWING_BIOMETRIC = STRONG_AUTH_NOT_REQUIRED
1790                 | SOME_AUTH_REQUIRED_AFTER_USER_REQUEST
1791                 | SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED
1792                 | SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST;
1793 
1794         private final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
1795         private final H mHandler;
1796         private final int mDefaultStrongAuthFlags;
1797 
1798         private final SparseBooleanArray mIsNonStrongBiometricAllowedForUser =
1799                 new SparseBooleanArray();
1800         private final boolean mDefaultIsNonStrongBiometricAllowed = true;
1801 
StrongAuthTracker(Context context)1802         public StrongAuthTracker(Context context) {
1803             this(context, Looper.myLooper());
1804         }
1805 
1806         /**
1807          * @param looper the looper on whose thread calls to {@link #onStrongAuthRequiredChanged}
1808          *               will be scheduled.
1809          * @param context the current {@link Context}
1810          */
StrongAuthTracker(Context context, Looper looper)1811         public StrongAuthTracker(Context context, Looper looper) {
1812             mHandler = new H(looper);
1813             mDefaultStrongAuthFlags = getDefaultFlags(context);
1814         }
1815 
getDefaultFlags(Context context)1816         public static @StrongAuthFlags int getDefaultFlags(Context context) {
1817             boolean strongAuthRequired = context.getResources().getBoolean(
1818                     com.android.internal.R.bool.config_strongAuthRequiredOnBoot);
1819             return strongAuthRequired ? STRONG_AUTH_REQUIRED_AFTER_BOOT : STRONG_AUTH_NOT_REQUIRED;
1820         }
1821 
1822         /**
1823          * Returns {@link #STRONG_AUTH_NOT_REQUIRED} if strong authentication is not required,
1824          * otherwise returns a combination of {@link StrongAuthFlags} indicating why strong
1825          * authentication is required.
1826          *
1827          * @param userId the user for whom the state is queried.
1828          */
getStrongAuthForUser(int userId)1829         public @StrongAuthFlags int getStrongAuthForUser(int userId) {
1830             return mStrongAuthRequiredForUser.get(userId, mDefaultStrongAuthFlags);
1831         }
1832 
1833         /**
1834          * @return true if unlocking with trust alone is allowed for {@code userId} by the current
1835          * strong authentication requirements.
1836          */
isTrustAllowedForUser(int userId)1837         public boolean isTrustAllowedForUser(int userId) {
1838             return getStrongAuthForUser(userId) == STRONG_AUTH_NOT_REQUIRED;
1839         }
1840 
1841         /**
1842          * @return true if unlocking with a biometric method alone is allowed for {@code userId}
1843          * by the current strong authentication requirements.
1844          */
isBiometricAllowedForUser(boolean isStrongBiometric, int userId)1845         public boolean isBiometricAllowedForUser(boolean isStrongBiometric, int userId) {
1846             boolean allowed = ((getStrongAuthForUser(userId) & ~ALLOWING_BIOMETRIC) == 0);
1847             if (!isStrongBiometric) {
1848                 allowed &= isNonStrongBiometricAllowedAfterIdleTimeout(userId);
1849             }
1850             return allowed;
1851         }
1852 
1853         /**
1854          * @return true if unlocking with a non-strong (i.e. weak or convenience) biometric method
1855          * alone is allowed for {@code userId}, otherwise returns false.
1856          */
isNonStrongBiometricAllowedAfterIdleTimeout(int userId)1857         public boolean isNonStrongBiometricAllowedAfterIdleTimeout(int userId) {
1858             return mIsNonStrongBiometricAllowedForUser.get(userId,
1859                     mDefaultIsNonStrongBiometricAllowed);
1860         }
1861 
1862         /**
1863          * Called when the strong authentication requirements for {@code userId} changed.
1864          */
onStrongAuthRequiredChanged(int userId)1865         public void onStrongAuthRequiredChanged(int userId) {
1866         }
1867 
1868         /**
1869          * Called when whether non-strong biometric is allowed for {@code userId} changed.
1870          */
onIsNonStrongBiometricAllowedChanged(int userId)1871         public void onIsNonStrongBiometricAllowedChanged(int userId) {
1872         }
1873 
handleStrongAuthRequiredChanged(@trongAuthFlags int strongAuthFlags, int userId)1874         protected void handleStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
1875                 int userId) {
1876             int oldValue = getStrongAuthForUser(userId);
1877             if (strongAuthFlags != oldValue) {
1878                 if (strongAuthFlags == mDefaultStrongAuthFlags) {
1879                     mStrongAuthRequiredForUser.delete(userId);
1880                 } else {
1881                     mStrongAuthRequiredForUser.put(userId, strongAuthFlags);
1882                 }
1883                 onStrongAuthRequiredChanged(userId);
1884             }
1885         }
1886 
handleIsNonStrongBiometricAllowedChanged(boolean allowed, int userId)1887         protected void handleIsNonStrongBiometricAllowedChanged(boolean allowed,
1888                 int userId) {
1889             boolean oldValue = isNonStrongBiometricAllowedAfterIdleTimeout(userId);
1890             if (allowed != oldValue) {
1891                 if (allowed == mDefaultIsNonStrongBiometricAllowed) {
1892                     mIsNonStrongBiometricAllowedForUser.delete(userId);
1893                 } else {
1894                     mIsNonStrongBiometricAllowedForUser.put(userId, allowed);
1895                 }
1896                 onIsNonStrongBiometricAllowedChanged(userId);
1897             }
1898         }
1899 
1900         private final IStrongAuthTracker.Stub mStub = new IStrongAuthTracker.Stub() {
1901             @Override
1902             public void onStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
1903                     int userId) {
1904                 mHandler.obtainMessage(H.MSG_ON_STRONG_AUTH_REQUIRED_CHANGED,
1905                         strongAuthFlags, userId).sendToTarget();
1906             }
1907 
1908             @Override
1909             public void onIsNonStrongBiometricAllowedChanged(boolean allowed, int userId) {
1910                 mHandler.obtainMessage(H.MSG_ON_IS_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED,
1911                         allowed ? 1 : 0, userId).sendToTarget();
1912             }
1913         };
1914 
getStub()1915         public IStrongAuthTracker.Stub getStub() {
1916             return mStub;
1917         }
1918 
1919         private class H extends Handler {
1920             static final int MSG_ON_STRONG_AUTH_REQUIRED_CHANGED = 1;
1921             static final int MSG_ON_IS_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED = 2;
1922 
H(Looper looper)1923             public H(Looper looper) {
1924                 super(looper);
1925             }
1926 
1927             @Override
handleMessage(Message msg)1928             public void handleMessage(Message msg) {
1929                 switch (msg.what) {
1930                     case MSG_ON_STRONG_AUTH_REQUIRED_CHANGED:
1931                         handleStrongAuthRequiredChanged(msg.arg1, msg.arg2);
1932                         break;
1933                     case MSG_ON_IS_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED:
1934                         handleIsNonStrongBiometricAllowedChanged(msg.arg1 == 1 /* allowed */,
1935                                 msg.arg2);
1936                         break;
1937                 }
1938             }
1939         }
1940     }
1941 
1942     /**
1943      * Returns whether the given user has pending escrow tokens
1944      */
hasPendingEscrowToken(int userId)1945     public boolean hasPendingEscrowToken(int userId) {
1946         try {
1947             return getLockSettings().hasPendingEscrowToken(userId);
1948         } catch (RemoteException e) {
1949             e.rethrowFromSystemServer();
1950         }
1951         return false;
1952     }
1953 
1954     /**
1955      * Return true if the device supports the lock screen feature, false otherwise.
1956      */
hasSecureLockScreen()1957     public boolean hasSecureLockScreen() {
1958         if (mHasSecureLockScreen == null) {
1959             try {
1960                 mHasSecureLockScreen = Boolean.valueOf(getLockSettings().hasSecureLockScreen());
1961             } catch (RemoteException e) {
1962                 e.rethrowFromSystemServer();
1963             }
1964         }
1965         return mHasSecureLockScreen.booleanValue();
1966     }
1967 
userOwnsFrpCredential(Context context, UserInfo info)1968     public static boolean userOwnsFrpCredential(Context context, UserInfo info) {
1969         return info != null && info.isMain() && info.isAdmin() && frpCredentialEnabled(context);
1970     }
1971 
frpCredentialEnabled(Context context)1972     public static boolean frpCredentialEnabled(Context context) {
1973         return FRP_CREDENTIAL_ENABLED && context.getResources().getBoolean(
1974                 com.android.internal.R.bool.config_enableCredentialFactoryResetProtection);
1975     }
1976 
1977     /**
1978      * Return {@code true} if repair mode is supported by the device.
1979      */
isRepairModeSupported(Context context)1980     public static boolean isRepairModeSupported(Context context) {
1981         return context.getResources().getBoolean(
1982                 com.android.internal.R.bool.config_repairModeSupported);
1983     }
1984 
1985     /**
1986      * Return {@code true} if repair mode is active on the device.
1987      */
isRepairModeActive(Context context)1988     public static boolean isRepairModeActive(Context context) {
1989         return Settings.Global.getInt(context.getContentResolver(),
1990                 Settings.Global.REPAIR_MODE_ACTIVE, /* def= */ 0) > 0;
1991     }
1992 
1993     /**
1994      * Return {@code true} if repair mode is supported by the device and the user has been granted
1995      * admin privileges.
1996      */
canUserEnterRepairMode(Context context, UserInfo info)1997     public static boolean canUserEnterRepairMode(Context context, UserInfo info) {
1998         return info != null && info.isAdmin() && isRepairModeSupported(context);
1999     }
2000 
2001     /**
2002      * Return {@code true} if GSI is running on the device.
2003      */
isGsiRunning()2004     public static boolean isGsiRunning() {
2005         return SystemProperties.getInt(GSI_RUNNING_PROP, 0) > 0;
2006     }
2007 
2008     /**
2009      * Return {@code true} if the given user id is a special user such as {@link #USER_FRP}.
2010      */
isSpecialUserId(int userId)2011     public static boolean isSpecialUserId(int userId) {
2012         return isSpecialUserId(/* context= */ null, userId, /* checkDeviceSupported= */ false);
2013     }
2014 
2015     /**
2016      * Return {@code true} if the given user id is a special user for the verification flow.
2017      *
2018      * @param checkDeviceSupported {@code true} to check the specified user is supported
2019      *                             by the device.
2020      */
isSpecialUserId(@ullable Context context, int userId, boolean checkDeviceSupported)2021     private static boolean isSpecialUserId(@Nullable Context context, int userId,
2022             boolean checkDeviceSupported) {
2023         switch (userId) {
2024             case USER_FRP:
2025                 if (checkDeviceSupported) return frpCredentialEnabled(context);
2026                 return true;
2027 
2028             case USER_REPAIR_MODE:
2029                 if (checkDeviceSupported) return isRepairModeSupported(context);
2030                 return true;
2031         }
2032         return false;
2033     }
2034 
2035     /**
2036      * Attempt to rederive the unified work challenge for the specified profile user and unlock the
2037      * user. If successful, this would allow the user to leave quiet mode automatically without
2038      * additional user authentication.
2039      *
2040      * This is made possible by the framework storing an encrypted copy of the unified challenge
2041      * auth-bound to the primary user's lockscreen. As long as the primery user has unlocked
2042      * recently (7 days), the framework will be able to decrypt it and plug the secret into the
2043      * unlock flow.
2044      *
2045      * @return {@code true} if automatic unlocking is successful, {@code false} otherwise.
2046      */
tryUnlockWithCachedUnifiedChallenge(int userId)2047     public boolean tryUnlockWithCachedUnifiedChallenge(int userId) {
2048         try {
2049             return getLockSettings().tryUnlockWithCachedUnifiedChallenge(userId);
2050         } catch (RemoteException re) {
2051             return false;
2052         }
2053     }
2054 
2055     /** Remove cached unified profile challenge, for testing and CTS usage. */
removeCachedUnifiedChallenge(int userId)2056     public void removeCachedUnifiedChallenge(int userId) {
2057         try {
2058             getLockSettings().removeCachedUnifiedChallenge(userId);
2059         } catch (RemoteException re) {
2060             re.rethrowFromSystemServer();
2061         }
2062     }
2063 
2064     /**
2065      * If the user is not secured, ie doesn't have an LSKF, then decrypt the user's synthetic
2066      * password and use it to unlock various cryptographic keys associated with the user.  This
2067      * primarily includes unlocking the user's credential-encrypted (CE) storage.  It also includes
2068      * unlocking the user's Keystore super keys, and deriving or decrypting the vendor auth secret
2069      * and sending it to the AuthSecret HAL in order to unlock Secure Element firmware updates.
2070      * <p>
2071      * These tasks would normally be done when the LSKF is verified.  This method is where these
2072      * tasks are done when the user doesn't have an LSKF.  It's called when the user is started.
2073      * <p>
2074      * Except on permission denied, this method doesn't throw an exception on failure.  However, the
2075      * last thing that it does is unlock CE storage, and whether CE storage has been successfully
2076      * unlocked can be determined by {@link StorageManager#isCeStorageUnlocked()}.
2077      * <p>
2078      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
2079      *
2080      * @param userId the ID of the user whose keys to unlock
2081      */
unlockUserKeyIfUnsecured(@serIdInt int userId)2082     public void unlockUserKeyIfUnsecured(@UserIdInt int userId) {
2083         try {
2084             getLockSettings().unlockUserKeyIfUnsecured(userId);
2085         } catch (RemoteException re) {
2086             re.rethrowFromSystemServer();
2087         }
2088     }
2089 
createNewUser(@serIdInt int userId, int userSerialNumber)2090     public void createNewUser(@UserIdInt int userId, int userSerialNumber) {
2091         getLockSettingsInternal().createNewUser(userId, userSerialNumber);
2092     }
2093 
removeUser(@serIdInt int userId)2094     public void removeUser(@UserIdInt int userId) {
2095         getLockSettingsInternal().removeUser(userId);
2096     }
2097 
2098    /**
2099      * Starts a session to verify lockscreen credentials provided by a remote device.
2100      */
2101     @NonNull
startRemoteLockscreenValidation()2102     public RemoteLockscreenValidationSession startRemoteLockscreenValidation() {
2103         try {
2104             return getLockSettings().startRemoteLockscreenValidation();
2105         } catch (RemoteException e) {
2106             throw e.rethrowFromSystemServer();
2107         }
2108     }
2109 
2110    /**
2111      * Verifies credentials guess from a remote device.
2112      */
2113     @NonNull
validateRemoteLockscreen( @onNull byte[] encryptedCredential)2114     public RemoteLockscreenValidationResult validateRemoteLockscreen(
2115             @NonNull byte[] encryptedCredential) {
2116         try {
2117             return getLockSettings().validateRemoteLockscreen(encryptedCredential);
2118         } catch (RemoteException e) {
2119             throw e.rethrowFromSystemServer();
2120         }
2121     }
2122 }
2123