Merge "For non-udfps, detectFP if primaryAuth required" into tm-qpr-dev
This commit is contained in:
@@ -26,7 +26,6 @@ data class KeyguardFingerprintListenModel(
|
|||||||
val credentialAttempted: Boolean,
|
val credentialAttempted: Boolean,
|
||||||
val deviceInteractive: Boolean,
|
val deviceInteractive: Boolean,
|
||||||
val dreaming: Boolean,
|
val dreaming: Boolean,
|
||||||
val encryptedOrLockdown: Boolean,
|
|
||||||
val fingerprintDisabled: Boolean,
|
val fingerprintDisabled: Boolean,
|
||||||
val fingerprintLockedOut: Boolean,
|
val fingerprintLockedOut: Boolean,
|
||||||
val goingToSleep: Boolean,
|
val goingToSleep: Boolean,
|
||||||
@@ -37,6 +36,7 @@ data class KeyguardFingerprintListenModel(
|
|||||||
val primaryUser: Boolean,
|
val primaryUser: Boolean,
|
||||||
val shouldListenSfpsState: Boolean,
|
val shouldListenSfpsState: Boolean,
|
||||||
val shouldListenForFingerprintAssistant: Boolean,
|
val shouldListenForFingerprintAssistant: Boolean,
|
||||||
|
val strongerAuthRequired: Boolean,
|
||||||
val switchingUser: Boolean,
|
val switchingUser: Boolean,
|
||||||
val udfps: Boolean,
|
val udfps: Boolean,
|
||||||
val userDoesNotHaveTrust: Boolean
|
val userDoesNotHaveTrust: Boolean
|
||||||
|
|||||||
@@ -363,16 +363,18 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
|||||||
final boolean sfpsEnabled = getResources().getBoolean(
|
final boolean sfpsEnabled = getResources().getBoolean(
|
||||||
R.bool.config_show_sidefps_hint_on_bouncer);
|
R.bool.config_show_sidefps_hint_on_bouncer);
|
||||||
final boolean fpsDetectionRunning = mUpdateMonitor.isFingerprintDetectionRunning();
|
final boolean fpsDetectionRunning = mUpdateMonitor.isFingerprintDetectionRunning();
|
||||||
final boolean needsStrongAuth = mUpdateMonitor.userNeedsStrongAuth();
|
final boolean isUnlockingWithFpAllowed =
|
||||||
|
mUpdateMonitor.isUnlockingWithFingerprintAllowed();
|
||||||
|
|
||||||
boolean toShow = mBouncerVisible && sfpsEnabled && fpsDetectionRunning && !needsStrongAuth;
|
boolean toShow = mBouncerVisible && sfpsEnabled && fpsDetectionRunning
|
||||||
|
&& isUnlockingWithFpAllowed;
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "sideFpsToShow=" + toShow + ", "
|
Log.d(TAG, "sideFpsToShow=" + toShow + ", "
|
||||||
+ "mBouncerVisible=" + mBouncerVisible + ", "
|
+ "mBouncerVisible=" + mBouncerVisible + ", "
|
||||||
+ "configEnabled=" + sfpsEnabled + ", "
|
+ "configEnabled=" + sfpsEnabled + ", "
|
||||||
+ "fpsDetectionRunning=" + fpsDetectionRunning + ", "
|
+ "fpsDetectionRunning=" + fpsDetectionRunning + ", "
|
||||||
+ "needsStrongAuth=" + needsStrongAuth);
|
+ "isUnlockingWithFpAllowed=" + isUnlockingWithFpAllowed);
|
||||||
}
|
}
|
||||||
if (toShow) {
|
if (toShow) {
|
||||||
mSideFpsController.get().show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
|
mSideFpsController.get().show(SideFpsUiRequestSource.PRIMARY_BOUNCER);
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_P
|
|||||||
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_TIMED;
|
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_TIMED;
|
||||||
import static android.hardware.biometrics.BiometricConstants.LockoutMode;
|
import static android.hardware.biometrics.BiometricConstants.LockoutMode;
|
||||||
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
|
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
|
||||||
|
import static android.hardware.biometrics.BiometricSourceType.FACE;
|
||||||
|
import static android.hardware.biometrics.BiometricSourceType.FINGERPRINT;
|
||||||
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
|
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
|
||||||
|
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||||
@@ -229,7 +231,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
* Biometric authentication: Cancelling and waiting for the relevant biometric service to
|
* Biometric authentication: Cancelling and waiting for the relevant biometric service to
|
||||||
* send us the confirmation that cancellation has happened.
|
* send us the confirmation that cancellation has happened.
|
||||||
*/
|
*/
|
||||||
private static final int BIOMETRIC_STATE_CANCELLING = 2;
|
@VisibleForTesting
|
||||||
|
protected static final int BIOMETRIC_STATE_CANCELLING = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Biometric state: During cancelling we got another request to start listening, so when we
|
||||||
|
* receive the cancellation done signal, we should start listening again.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
protected static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action indicating keyguard *can* start biometric authentiation.
|
* Action indicating keyguard *can* start biometric authentiation.
|
||||||
@@ -244,12 +254,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
*/
|
*/
|
||||||
private static final int BIOMETRIC_ACTION_UPDATE = 2;
|
private static final int BIOMETRIC_ACTION_UPDATE = 2;
|
||||||
|
|
||||||
/**
|
|
||||||
* Biometric state: During cancelling we got another request to start listening, so when we
|
|
||||||
* receive the cancellation done signal, we should start listening again.
|
|
||||||
*/
|
|
||||||
private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
|
public static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
|
||||||
public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
|
public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
|
||||||
@@ -372,7 +376,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|
|
||||||
private KeyguardBypassController mKeyguardBypassController;
|
private KeyguardBypassController mKeyguardBypassController;
|
||||||
private List<SubscriptionInfo> mSubscriptionInfo;
|
private List<SubscriptionInfo> mSubscriptionInfo;
|
||||||
private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
|
@VisibleForTesting
|
||||||
|
protected int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
|
||||||
private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
|
private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
|
||||||
private boolean mIsDreaming;
|
private boolean mIsDreaming;
|
||||||
private boolean mLogoutEnabled;
|
private boolean mLogoutEnabled;
|
||||||
@@ -806,7 +811,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
new BiometricAuthenticated(true, isStrongBiometric));
|
new BiometricAuthenticated(true, isStrongBiometric));
|
||||||
// Update/refresh trust state only if user can skip bouncer
|
// Update/refresh trust state only if user can skip bouncer
|
||||||
if (getUserCanSkipBouncer(userId)) {
|
if (getUserCanSkipBouncer(userId)) {
|
||||||
mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
|
mTrustManager.unlockedByBiometricForUser(userId, FINGERPRINT);
|
||||||
}
|
}
|
||||||
// Don't send cancel if authentication succeeds
|
// Don't send cancel if authentication succeeds
|
||||||
mFingerprintCancelSignal = null;
|
mFingerprintCancelSignal = null;
|
||||||
@@ -816,7 +821,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT,
|
cb.onBiometricAuthenticated(userId, FINGERPRINT,
|
||||||
isStrongBiometric);
|
isStrongBiometric);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -849,7 +854,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
|
cb.onBiometricAuthFailed(FINGERPRINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isUdfpsSupported()) {
|
if (isUdfpsSupported()) {
|
||||||
@@ -874,7 +879,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT, acquireInfo);
|
cb.onBiometricAcquired(FINGERPRINT, acquireInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -908,7 +913,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FINGERPRINT);
|
cb.onBiometricHelp(msgId, helpString, FINGERPRINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -960,7 +965,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
|
if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
|
||||||
lockedOutStateChanged = !mFingerprintLockedOutPermanent;
|
lockedOutStateChanged = !mFingerprintLockedOutPermanent;
|
||||||
mFingerprintLockedOutPermanent = true;
|
mFingerprintLockedOutPermanent = true;
|
||||||
mLogger.d("Fingerprint locked out - requiring strong auth");
|
mLogger.d("Fingerprint permanently locked out - requiring stronger auth");
|
||||||
mLockPatternUtils.requireStrongAuth(
|
mLockPatternUtils.requireStrongAuth(
|
||||||
STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, getCurrentUser());
|
STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, getCurrentUser());
|
||||||
}
|
}
|
||||||
@@ -969,6 +974,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|| msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
|
|| msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
|
||||||
lockedOutStateChanged |= !mFingerprintLockedOut;
|
lockedOutStateChanged |= !mFingerprintLockedOut;
|
||||||
mFingerprintLockedOut = true;
|
mFingerprintLockedOut = true;
|
||||||
|
mLogger.d("Fingerprint temporarily locked out - requiring stronger auth");
|
||||||
if (isUdfpsEnrolled()) {
|
if (isUdfpsEnrolled()) {
|
||||||
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
|
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
|
||||||
}
|
}
|
||||||
@@ -979,12 +985,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
|
cb.onBiometricError(msgId, errString, FINGERPRINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lockedOutStateChanged) {
|
if (lockedOutStateChanged) {
|
||||||
notifyLockedOutStateChanged(BiometricSourceType.FINGERPRINT);
|
notifyLockedOutStateChanged(FINGERPRINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1012,7 +1018,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
notifyLockedOutStateChanged(BiometricSourceType.FINGERPRINT);
|
notifyLockedOutStateChanged(FINGERPRINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1035,7 +1041,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
|
cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
|
||||||
BiometricSourceType.FINGERPRINT);
|
FINGERPRINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1048,7 +1054,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
new BiometricAuthenticated(true, isStrongBiometric));
|
new BiometricAuthenticated(true, isStrongBiometric));
|
||||||
// Update/refresh trust state only if user can skip bouncer
|
// Update/refresh trust state only if user can skip bouncer
|
||||||
if (getUserCanSkipBouncer(userId)) {
|
if (getUserCanSkipBouncer(userId)) {
|
||||||
mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FACE);
|
mTrustManager.unlockedByBiometricForUser(userId, FACE);
|
||||||
}
|
}
|
||||||
// Don't send cancel if authentication succeeds
|
// Don't send cancel if authentication succeeds
|
||||||
mFaceCancelSignal = null;
|
mFaceCancelSignal = null;
|
||||||
@@ -1059,7 +1065,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricAuthenticated(userId,
|
cb.onBiometricAuthenticated(userId,
|
||||||
BiometricSourceType.FACE,
|
FACE,
|
||||||
isStrongBiometric);
|
isStrongBiometric);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1081,7 +1087,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricAuthFailed(BiometricSourceType.FACE);
|
cb.onBiometricAuthFailed(FACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleFaceHelp(BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
|
handleFaceHelp(BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
|
||||||
@@ -1094,7 +1100,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricAcquired(BiometricSourceType.FACE, acquireInfo);
|
cb.onBiometricAcquired(FACE, acquireInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1129,7 +1135,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FACE);
|
cb.onBiometricHelp(msgId, helpString, FACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1197,12 +1203,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricError(msgId, errString,
|
cb.onBiometricError(msgId, errString,
|
||||||
BiometricSourceType.FACE);
|
FACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lockedOutStateChanged) {
|
if (lockedOutStateChanged) {
|
||||||
notifyLockedOutStateChanged(BiometricSourceType.FACE);
|
notifyLockedOutStateChanged(FACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,7 +1222,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET), getBiometricLockoutDelay());
|
FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET), getBiometricLockoutDelay());
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
notifyLockedOutStateChanged(BiometricSourceType.FACE);
|
notifyLockedOutStateChanged(FACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1239,7 +1245,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
|
cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
|
||||||
BiometricSourceType.FACE);
|
FACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1380,7 +1386,39 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
|
public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
|
||||||
return mStrongAuthTracker.isUnlockingWithBiometricAllowed(isStrongBiometric);
|
// StrongAuthTracker#isUnlockingWithBiometricAllowed includes
|
||||||
|
// STRONG_AUTH_REQUIRED_AFTER_LOCKOUT which is the same as mFingerprintLockedOutPermanent;
|
||||||
|
// however the strong auth tracker does not include the temporary lockout
|
||||||
|
// mFingerprintLockedOut.
|
||||||
|
return mStrongAuthTracker.isUnlockingWithBiometricAllowed(isStrongBiometric)
|
||||||
|
&& !mFingerprintLockedOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUnlockingWithFaceAllowed() {
|
||||||
|
return mStrongAuthTracker.isUnlockingWithBiometricAllowed(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether fingerprint is allowed ot be used for unlocking based on the strongAuthTracker
|
||||||
|
* and temporary lockout state (tracked by FingerprintManager via error codes).
|
||||||
|
*/
|
||||||
|
public boolean isUnlockingWithFingerprintAllowed() {
|
||||||
|
return isUnlockingWithBiometricAllowed(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the given biometric is allowed based on strongAuth & lockout states.
|
||||||
|
*/
|
||||||
|
public boolean isUnlockingWithBiometricAllowed(
|
||||||
|
@NonNull BiometricSourceType biometricSourceType) {
|
||||||
|
switch (biometricSourceType) {
|
||||||
|
case FINGERPRINT:
|
||||||
|
return isUnlockingWithFingerprintAllowed();
|
||||||
|
case FACE:
|
||||||
|
return isUnlockingWithFaceAllowed();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUserInLockdown(int userId) {
|
public boolean isUserInLockdown(int userId) {
|
||||||
@@ -1402,11 +1440,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
return isEncrypted || isLockDown;
|
return isEncrypted || isLockDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean userNeedsStrongAuth() {
|
|
||||||
return mStrongAuthTracker.getStrongAuthForUser(getCurrentUser())
|
|
||||||
!= LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean containsFlag(int haystack, int needle) {
|
private boolean containsFlag(int haystack, int needle) {
|
||||||
return (haystack & needle) != 0;
|
return (haystack & needle) != 0;
|
||||||
}
|
}
|
||||||
@@ -1576,12 +1609,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final FingerprintManager.FingerprintDetectionCallback mFingerprintDetectionCallback
|
|
||||||
= (sensorId, userId, isStrongBiometric) -> {
|
|
||||||
// Trigger the fingerprint success path so the bouncer can be shown
|
|
||||||
handleFingerprintAuthenticated(userId, isStrongBiometric);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Propagates a pointer down event to keyguard.
|
* Propagates a pointer down event to keyguard.
|
||||||
*/
|
*/
|
||||||
@@ -2651,27 +2678,25 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
&& (!mKeyguardGoingAway || !mDeviceInteractive)
|
&& (!mKeyguardGoingAway || !mDeviceInteractive)
|
||||||
&& mIsPrimaryUser
|
&& mIsPrimaryUser
|
||||||
&& biometricEnabledForUser;
|
&& biometricEnabledForUser;
|
||||||
|
final boolean strongerAuthRequired = !isUnlockingWithFingerprintAllowed();
|
||||||
final boolean shouldListenBouncerState = !(mFingerprintLockedOut
|
final boolean isSideFps = isSfpsSupported() && isSfpsEnrolled();
|
||||||
&& mPrimaryBouncerIsOrWillBeShowing && mCredentialAttempted);
|
final boolean shouldListenBouncerState =
|
||||||
|
!strongerAuthRequired || !mPrimaryBouncerIsOrWillBeShowing;
|
||||||
final boolean isEncryptedOrLockdownForUser = isEncryptedOrLockdown(user);
|
|
||||||
|
|
||||||
final boolean shouldListenUdfpsState = !isUdfps
|
final boolean shouldListenUdfpsState = !isUdfps
|
||||||
|| (!userCanSkipBouncer
|
|| (!userCanSkipBouncer
|
||||||
&& !isEncryptedOrLockdownForUser
|
&& !strongerAuthRequired
|
||||||
&& userDoesNotHaveTrust);
|
&& userDoesNotHaveTrust);
|
||||||
|
|
||||||
boolean shouldListenSideFpsState = true;
|
boolean shouldListenSideFpsState = true;
|
||||||
if (isSfpsSupported() && isSfpsEnrolled()) {
|
if (isSideFps) {
|
||||||
shouldListenSideFpsState =
|
shouldListenSideFpsState =
|
||||||
mSfpsRequireScreenOnToAuthPrefEnabled ? isDeviceInteractive() : true;
|
mSfpsRequireScreenOnToAuthPrefEnabled ? isDeviceInteractive() : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
|
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
|
||||||
&& shouldListenBouncerState && shouldListenUdfpsState && !isFingerprintLockedOut()
|
&& shouldListenBouncerState && shouldListenUdfpsState
|
||||||
&& shouldListenSideFpsState;
|
&& shouldListenSideFpsState;
|
||||||
|
|
||||||
maybeLogListenerModelData(
|
maybeLogListenerModelData(
|
||||||
new KeyguardFingerprintListenModel(
|
new KeyguardFingerprintListenModel(
|
||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
@@ -2683,7 +2708,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
mCredentialAttempted,
|
mCredentialAttempted,
|
||||||
mDeviceInteractive,
|
mDeviceInteractive,
|
||||||
mIsDreaming,
|
mIsDreaming,
|
||||||
isEncryptedOrLockdownForUser,
|
|
||||||
fingerprintDisabledForUser,
|
fingerprintDisabledForUser,
|
||||||
mFingerprintLockedOut,
|
mFingerprintLockedOut,
|
||||||
mGoingToSleep,
|
mGoingToSleep,
|
||||||
@@ -2694,6 +2718,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
mIsPrimaryUser,
|
mIsPrimaryUser,
|
||||||
shouldListenSideFpsState,
|
shouldListenSideFpsState,
|
||||||
shouldListenForFingerprintAssistant,
|
shouldListenForFingerprintAssistant,
|
||||||
|
strongerAuthRequired,
|
||||||
mSwitchingUser,
|
mSwitchingUser,
|
||||||
isUdfps,
|
isUdfps,
|
||||||
userDoesNotHaveTrust));
|
userDoesNotHaveTrust));
|
||||||
@@ -2721,10 +2746,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
final boolean isEncryptedOrTimedOut =
|
final boolean isEncryptedOrTimedOut =
|
||||||
containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
|
containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
|
||||||
|| containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
|
|| containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
|
||||||
|
final boolean fpLockedOut = isFingerprintLockedOut();
|
||||||
// TODO: always disallow when fp is already locked out?
|
|
||||||
final boolean fpLockedOut = mFingerprintLockedOut || mFingerprintLockedOutPermanent;
|
|
||||||
|
|
||||||
final boolean canBypass = mKeyguardBypassController != null
|
final boolean canBypass = mKeyguardBypassController != null
|
||||||
&& mKeyguardBypassController.canBypass();
|
&& mKeyguardBypassController.canBypass();
|
||||||
// There's no reason to ask the HAL for authentication when the user can dismiss the
|
// There's no reason to ask the HAL for authentication when the user can dismiss the
|
||||||
@@ -2846,15 +2868,22 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
// Waiting for restart via handleFingerprintError().
|
// Waiting for restart via handleFingerprintError().
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mLogger.v("startListeningForFingerprint()");
|
|
||||||
|
|
||||||
if (unlockPossible) {
|
if (unlockPossible) {
|
||||||
mFingerprintCancelSignal = new CancellationSignal();
|
mFingerprintCancelSignal = new CancellationSignal();
|
||||||
|
|
||||||
if (isEncryptedOrLockdown(userId)) {
|
if (!isUnlockingWithFingerprintAllowed()) {
|
||||||
mFpm.detectFingerprint(mFingerprintCancelSignal, mFingerprintDetectionCallback,
|
mLogger.v("startListeningForFingerprint - detect");
|
||||||
|
mFpm.detectFingerprint(
|
||||||
|
mFingerprintCancelSignal,
|
||||||
|
(sensorId, user, isStrongBiometric) -> {
|
||||||
|
mLogger.d("fingerprint detected");
|
||||||
|
// Trigger the fingerprint success path so the bouncer can be shown
|
||||||
|
handleFingerprintAuthenticated(user, isStrongBiometric);
|
||||||
|
},
|
||||||
userId);
|
userId);
|
||||||
} else {
|
} else {
|
||||||
|
mLogger.v("startListeningForFingerprint - authenticate");
|
||||||
mFpm.authenticate(null /* crypto */, mFingerprintCancelSignal,
|
mFpm.authenticate(null /* crypto */, mFingerprintCancelSignal,
|
||||||
mFingerprintAuthenticationCallback, null /* handler */,
|
mFingerprintAuthenticationCallback, null /* handler */,
|
||||||
FingerprintManager.SENSOR_ID_ANY, userId, 0 /* flags */);
|
FingerprintManager.SENSOR_ID_ANY, userId, 0 /* flags */);
|
||||||
@@ -3071,11 +3100,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Immediately stop previous biometric listening states.
|
||||||
|
// Resetting lockout states updates the biometric listening states.
|
||||||
if (mFaceManager != null && !mFaceSensorProperties.isEmpty()) {
|
if (mFaceManager != null && !mFaceSensorProperties.isEmpty()) {
|
||||||
|
stopListeningForFace(FACE_AUTH_UPDATED_USER_SWITCHING);
|
||||||
handleFaceLockoutReset(mFaceManager.getLockoutModeForUser(
|
handleFaceLockoutReset(mFaceManager.getLockoutModeForUser(
|
||||||
mFaceSensorProperties.get(0).sensorId, userId));
|
mFaceSensorProperties.get(0).sensorId, userId));
|
||||||
}
|
}
|
||||||
if (mFpm != null && !mFingerprintSensorProperties.isEmpty()) {
|
if (mFpm != null && !mFingerprintSensorProperties.isEmpty()) {
|
||||||
|
stopListeningForFingerprint();
|
||||||
handleFingerprintLockoutReset(mFpm.getLockoutModeForUser(
|
handleFingerprintLockoutReset(mFpm.getLockoutModeForUser(
|
||||||
mFingerprintSensorProperties.get(0).sensorId, userId));
|
mFingerprintSensorProperties.get(0).sensorId, userId));
|
||||||
}
|
}
|
||||||
@@ -3482,7 +3515,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
@AnyThread
|
@AnyThread
|
||||||
public void setSwitchingUser(boolean switching) {
|
public void setSwitchingUser(boolean switching) {
|
||||||
mSwitchingUser = switching;
|
mSwitchingUser = switching;
|
||||||
// Since this comes in on a binder thread, we need to post if first
|
// Since this comes in on a binder thread, we need to post it first
|
||||||
mHandler.post(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
|
mHandler.post(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
|
||||||
FACE_AUTH_UPDATED_USER_SWITCHING));
|
FACE_AUTH_UPDATED_USER_SWITCHING));
|
||||||
}
|
}
|
||||||
@@ -3574,8 +3607,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
mUserFingerprintAuthenticated.clear();
|
mUserFingerprintAuthenticated.clear();
|
||||||
mUserFaceAuthenticated.clear();
|
mUserFaceAuthenticated.clear();
|
||||||
mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT, unlockedUser);
|
mTrustManager.clearAllBiometricRecognized(FINGERPRINT, unlockedUser);
|
||||||
mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE, unlockedUser);
|
mTrustManager.clearAllBiometricRecognized(FACE, unlockedUser);
|
||||||
mLogger.d("clearBiometricRecognized");
|
mLogger.d("clearBiometricRecognized");
|
||||||
|
|
||||||
for (int i = 0; i < mCallbacks.size(); i++) {
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ class AuthRippleController @Inject constructor(
|
|||||||
notificationShadeWindowController.setForcePluginOpen(false, this)
|
notificationShadeWindowController.setForcePluginOpen(false, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showUnlockRipple(biometricSourceType: BiometricSourceType?) {
|
fun showUnlockRipple(biometricSourceType: BiometricSourceType) {
|
||||||
if (!keyguardStateController.isShowing ||
|
if (!keyguardStateController.isShowing ||
|
||||||
keyguardUpdateMonitor.userNeedsStrongAuth()) {
|
!keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(biometricSourceType)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +246,7 @@ class AuthRippleController @Inject constructor(
|
|||||||
object : KeyguardUpdateMonitorCallback() {
|
object : KeyguardUpdateMonitorCallback() {
|
||||||
override fun onBiometricAuthenticated(
|
override fun onBiometricAuthenticated(
|
||||||
userId: Int,
|
userId: Int,
|
||||||
biometricSourceType: BiometricSourceType?,
|
biometricSourceType: BiometricSourceType,
|
||||||
isStrongBiometric: Boolean
|
isStrongBiometric: Boolean
|
||||||
) {
|
) {
|
||||||
if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
|
if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
|
||||||
@@ -255,14 +255,14 @@ class AuthRippleController @Inject constructor(
|
|||||||
showUnlockRipple(biometricSourceType)
|
showUnlockRipple(biometricSourceType)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType?) {
|
override fun onBiometricAuthFailed(biometricSourceType: BiometricSourceType) {
|
||||||
if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
|
if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
|
||||||
mView.retractDwellRipple()
|
mView.retractDwellRipple()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBiometricAcquired(
|
override fun onBiometricAcquired(
|
||||||
biometricSourceType: BiometricSourceType?,
|
biometricSourceType: BiometricSourceType,
|
||||||
acquireInfo: Int
|
acquireInfo: Int
|
||||||
) {
|
) {
|
||||||
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
|
if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.systemui.keyguard.domain.interactor
|
package com.android.systemui.keyguard.domain.interactor
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
|
import android.hardware.biometrics.BiometricSourceType
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Trace
|
import android.os.Trace
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
@@ -71,7 +72,7 @@ constructor(
|
|||||||
KeyguardUpdateMonitor.getCurrentUser()
|
KeyguardUpdateMonitor.getCurrentUser()
|
||||||
) &&
|
) &&
|
||||||
!needsFullscreenBouncer() &&
|
!needsFullscreenBouncer() &&
|
||||||
!keyguardUpdateMonitor.userNeedsStrongAuth() &&
|
keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE) &&
|
||||||
!keyguardBypassController.bypassEnabled
|
!keyguardBypassController.bypassEnabled
|
||||||
|
|
||||||
/** Runnable to show the primary bouncer. */
|
/** Runnable to show the primary bouncer. */
|
||||||
|
|||||||
@@ -240,8 +240,8 @@ public class KeyguardBouncer {
|
|||||||
&& !mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
|
&& !mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
|
||||||
KeyguardUpdateMonitor.getCurrentUser())
|
KeyguardUpdateMonitor.getCurrentUser())
|
||||||
&& !needsFullscreenBouncer()
|
&& !needsFullscreenBouncer()
|
||||||
&& !mKeyguardUpdateMonitor.isFaceLockedOut()
|
&& mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
&& !mKeyguardUpdateMonitor.userNeedsStrongAuth()
|
BiometricSourceType.FACE)
|
||||||
&& !mKeyguardBypassController.getBypassEnabled()) {
|
&& !mKeyguardBypassController.getBypassEnabled()) {
|
||||||
mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
|
mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ private fun fingerprintModel(user: Int) = KeyguardFingerprintListenModel(
|
|||||||
credentialAttempted = false,
|
credentialAttempted = false,
|
||||||
deviceInteractive = false,
|
deviceInteractive = false,
|
||||||
dreaming = false,
|
dreaming = false,
|
||||||
encryptedOrLockdown = false,
|
|
||||||
fingerprintDisabled = false,
|
fingerprintDisabled = false,
|
||||||
fingerprintLockedOut = false,
|
fingerprintLockedOut = false,
|
||||||
goingToSleep = false,
|
goingToSleep = false,
|
||||||
@@ -74,6 +73,7 @@ private fun fingerprintModel(user: Int) = KeyguardFingerprintListenModel(
|
|||||||
primaryUser = false,
|
primaryUser = false,
|
||||||
shouldListenSfpsState = false,
|
shouldListenSfpsState = false,
|
||||||
shouldListenForFingerprintAssistant = false,
|
shouldListenForFingerprintAssistant = false,
|
||||||
|
strongerAuthRequired = false,
|
||||||
switchingUser = false,
|
switchingUser = false,
|
||||||
udfps = false,
|
udfps = false,
|
||||||
userDoesNotHaveTrust = false
|
userDoesNotHaveTrust = false
|
||||||
|
|||||||
@@ -379,9 +379,9 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onBouncerVisibilityChanged_needsStrongAuth_sideFpsHintHidden() {
|
public void onBouncerVisibilityChanged_unlockingWithFingerprintNotAllowed_sideFpsHintHidden() {
|
||||||
setupConditionsToEnableSideFpsHint();
|
setupConditionsToEnableSideFpsHint();
|
||||||
setNeedsStrongAuth(true);
|
setUnlockingWithFingerprintAllowed(false);
|
||||||
reset(mSideFpsController);
|
reset(mSideFpsController);
|
||||||
|
|
||||||
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
|
||||||
@@ -574,7 +574,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
|||||||
attachView();
|
attachView();
|
||||||
setSideFpsHintEnabledFromResources(true);
|
setSideFpsHintEnabledFromResources(true);
|
||||||
setFingerprintDetectionRunning(true);
|
setFingerprintDetectionRunning(true);
|
||||||
setNeedsStrongAuth(false);
|
setUnlockingWithFingerprintAllowed(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachView() {
|
private void attachView() {
|
||||||
@@ -593,9 +593,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
|||||||
enabled);
|
enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setNeedsStrongAuth(boolean needed) {
|
private void setUnlockingWithFingerprintAllowed(boolean allowed) {
|
||||||
when(mKeyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(needed);
|
when(mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()).thenReturn(allowed);
|
||||||
mKeyguardUpdateMonitorCallback.getValue().onStrongAuthStateChanged(/* userId= */ 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupGetSecurityView() {
|
private void setupGetSecurityView() {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
|
|||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
|
||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||||
import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED;
|
import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED;
|
||||||
|
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING_RESTARTING;
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
|
import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
|
import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
|
||||||
|
|
||||||
@@ -281,7 +282,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
componentInfo, FaceSensorProperties.TYPE_UNKNOWN,
|
componentInfo, FaceSensorProperties.TYPE_UNKNOWN,
|
||||||
false /* supportsFaceDetection */, true /* supportsSelfIllumination */,
|
false /* supportsFaceDetection */, true /* supportsSelfIllumination */,
|
||||||
false /* resetLockoutRequiresChallenge */));
|
false /* resetLockoutRequiresChallenge */));
|
||||||
|
|
||||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||||
when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
|
when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
|
||||||
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(List.of(
|
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(List.of(
|
||||||
@@ -594,30 +594,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFingerprintDoesNotAuth_whenEncrypted() {
|
public void testOnlyDetectFingerprint_whenFingerprintUnlockNotAllowed() {
|
||||||
testFingerprintWhenStrongAuth(
|
|
||||||
STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFingerprintDoesNotAuth_whenDpmLocked() {
|
|
||||||
testFingerprintWhenStrongAuth(
|
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFingerprintDoesNotAuth_whenUserLockdown() {
|
|
||||||
testFingerprintWhenStrongAuth(
|
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testFingerprintWhenStrongAuth(int strongAuth) {
|
|
||||||
// Clear invocations, since previous setup (e.g. registering BiometricManager callbacks)
|
// Clear invocations, since previous setup (e.g. registering BiometricManager callbacks)
|
||||||
// will trigger updateBiometricListeningState();
|
// will trigger updateBiometricListeningState();
|
||||||
clearInvocations(mFingerprintManager);
|
clearInvocations(mFingerprintManager);
|
||||||
mKeyguardUpdateMonitor.resetBiometricListeningState();
|
mKeyguardUpdateMonitor.resetBiometricListeningState();
|
||||||
|
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth);
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
|
mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
@@ -928,10 +911,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
faceLockoutMode != BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
|
faceLockoutMode != BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
|
||||||
final boolean fpLocked =
|
final boolean fpLocked =
|
||||||
fingerprintLockoutMode != BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
|
fingerprintLockoutMode != BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
|
||||||
when(mFingerprintManager.getLockoutModeForUser(eq(FINGERPRINT_SENSOR_ID), eq(newUser)))
|
|
||||||
.thenReturn(fingerprintLockoutMode);
|
|
||||||
when(mFaceManager.getLockoutModeForUser(eq(FACE_SENSOR_ID), eq(newUser)))
|
|
||||||
.thenReturn(faceLockoutMode);
|
|
||||||
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
@@ -940,7 +919,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
|
||||||
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
|
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
|
||||||
anyInt());
|
anyInt());
|
||||||
|
// resetFaceManager();
|
||||||
|
// resetFingerprintManager();
|
||||||
|
|
||||||
|
when(mFingerprintManager.getLockoutModeForUser(eq(FINGERPRINT_SENSOR_ID), eq(newUser)))
|
||||||
|
.thenReturn(fingerprintLockoutMode);
|
||||||
|
when(mFaceManager.getLockoutModeForUser(eq(FACE_SENSOR_ID), eq(newUser)))
|
||||||
|
.thenReturn(faceLockoutMode);
|
||||||
final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
|
final CancellationSignal faceCancel = spy(mKeyguardUpdateMonitor.mFaceCancelSignal);
|
||||||
final CancellationSignal fpCancel = spy(mKeyguardUpdateMonitor.mFingerprintCancelSignal);
|
final CancellationSignal fpCancel = spy(mKeyguardUpdateMonitor.mFingerprintCancelSignal);
|
||||||
mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel;
|
mKeyguardUpdateMonitor.mFaceCancelSignal = faceCancel;
|
||||||
@@ -951,14 +936,22 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mKeyguardUpdateMonitor.handleUserSwitchComplete(newUser);
|
mKeyguardUpdateMonitor.handleUserSwitchComplete(newUser);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
verify(faceCancel, faceLocked ? times(1) : never()).cancel();
|
// THEN face and fingerprint listening are always cancelled immediately
|
||||||
verify(fpCancel, fpLocked ? times(1) : never()).cancel();
|
verify(faceCancel).cancel();
|
||||||
verify(callback, faceLocked ? times(1) : never()).onBiometricRunningStateChanged(
|
verify(callback).onBiometricRunningStateChanged(
|
||||||
eq(false), eq(BiometricSourceType.FACE));
|
eq(false), eq(BiometricSourceType.FACE));
|
||||||
verify(callback, fpLocked ? times(1) : never()).onBiometricRunningStateChanged(
|
verify(fpCancel).cancel();
|
||||||
|
verify(callback).onBiometricRunningStateChanged(
|
||||||
eq(false), eq(BiometricSourceType.FINGERPRINT));
|
eq(false), eq(BiometricSourceType.FINGERPRINT));
|
||||||
|
|
||||||
|
// THEN locked out states are updated
|
||||||
assertThat(mKeyguardUpdateMonitor.isFingerprintLockedOut()).isEqualTo(fpLocked);
|
assertThat(mKeyguardUpdateMonitor.isFingerprintLockedOut()).isEqualTo(fpLocked);
|
||||||
assertThat(mKeyguardUpdateMonitor.isFaceLockedOut()).isEqualTo(faceLocked);
|
assertThat(mKeyguardUpdateMonitor.isFaceLockedOut()).isEqualTo(faceLocked);
|
||||||
|
|
||||||
|
// Fingerprint should be restarted once its cancelled bc on lockout, the device
|
||||||
|
// can still detectFingerprint (and if it's not locked out, fingerprint can listen)
|
||||||
|
assertThat(mKeyguardUpdateMonitor.mFingerprintRunningState)
|
||||||
|
.isEqualTo(BIOMETRIC_STATE_CANCELLING_RESTARTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1144,9 +1137,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
// GIVEN status bar state is on the keyguard
|
// GIVEN status bar state is on the keyguard
|
||||||
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
|
||||||
|
|
||||||
// WHEN user hasn't authenticated since last boot
|
// WHEN user hasn't authenticated since last boot, cannot unlock with FP
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
.thenReturn(STRONG_AUTH_REQUIRED_AFTER_BOOT);
|
|
||||||
|
|
||||||
// THEN we shouldn't listen for udfps
|
// THEN we shouldn't listen for udfps
|
||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false);
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false);
|
||||||
@@ -1259,8 +1251,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
|
||||||
|
|
||||||
// WHEN device in lock down
|
// WHEN device in lock down
|
||||||
when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
|
|
||||||
|
|
||||||
// THEN we shouldn't listen for udfps
|
// THEN we shouldn't listen for udfps
|
||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false);
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController
|
|||||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.leak.RotationUtils
|
import com.android.systemui.util.leak.RotationUtils
|
||||||
import javax.inject.Provider
|
import com.android.systemui.util.mockito.any
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Assert.assertFalse
|
import org.junit.Assert.assertFalse
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
@@ -46,15 +46,16 @@ import org.junit.Test
|
|||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.ArgumentCaptor
|
import org.mockito.ArgumentCaptor
|
||||||
import org.mockito.ArgumentMatchers
|
import org.mockito.ArgumentMatchers
|
||||||
|
import org.mockito.ArgumentMatchers.eq
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.any
|
import org.mockito.Mockito.`when`
|
||||||
import org.mockito.Mockito.never
|
import org.mockito.Mockito.never
|
||||||
import org.mockito.Mockito.reset
|
import org.mockito.Mockito.reset
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.Mockito.`when`
|
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
import org.mockito.MockitoSession
|
import org.mockito.MockitoSession
|
||||||
import org.mockito.quality.Strictness
|
import org.mockito.quality.Strictness
|
||||||
|
import javax.inject.Provider
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@@ -118,12 +119,13 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFingerprintTrigger_KeyguardShowing_Ripple() {
|
fun testFingerprintTrigger_KeyguardShowing_Ripple() {
|
||||||
// GIVEN fp exists, keyguard is showing, user doesn't need strong auth
|
// GIVEN fp exists, keyguard is showing, unlocking with fp allowed
|
||||||
val fpsLocation = Point(5, 5)
|
val fpsLocation = Point(5, 5)
|
||||||
`when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
|
`when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
|
||||||
controller.onViewAttached()
|
controller.onViewAttached()
|
||||||
`when`(keyguardStateController.isShowing).thenReturn(true)
|
`when`(keyguardStateController.isShowing).thenReturn(true)
|
||||||
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)
|
`when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
|
eq(BiometricSourceType.FINGERPRINT))).thenReturn(true)
|
||||||
|
|
||||||
// WHEN fingerprint authenticated
|
// WHEN fingerprint authenticated
|
||||||
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
|
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
|
||||||
@@ -140,11 +142,12 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFingerprintTrigger_KeyguardNotShowing_NoRipple() {
|
fun testFingerprintTrigger_KeyguardNotShowing_NoRipple() {
|
||||||
// GIVEN fp exists & user doesn't need strong auth
|
// GIVEN fp exists & unlocking with fp allowed
|
||||||
val fpsLocation = Point(5, 5)
|
val fpsLocation = Point(5, 5)
|
||||||
`when`(authController.udfpsLocation).thenReturn(fpsLocation)
|
`when`(authController.udfpsLocation).thenReturn(fpsLocation)
|
||||||
controller.onViewAttached()
|
controller.onViewAttached()
|
||||||
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)
|
`when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
|
eq(BiometricSourceType.FINGERPRINT))).thenReturn(true)
|
||||||
|
|
||||||
// WHEN keyguard is NOT showing & fingerprint authenticated
|
// WHEN keyguard is NOT showing & fingerprint authenticated
|
||||||
`when`(keyguardStateController.isShowing).thenReturn(false)
|
`when`(keyguardStateController.isShowing).thenReturn(false)
|
||||||
@@ -160,15 +163,16 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFingerprintTrigger_StrongAuthRequired_NoRipple() {
|
fun testFingerprintTrigger_biometricUnlockNotAllowed_NoRipple() {
|
||||||
// GIVEN fp exists & keyguard is showing
|
// GIVEN fp exists & keyguard is showing
|
||||||
val fpsLocation = Point(5, 5)
|
val fpsLocation = Point(5, 5)
|
||||||
`when`(authController.udfpsLocation).thenReturn(fpsLocation)
|
`when`(authController.udfpsLocation).thenReturn(fpsLocation)
|
||||||
controller.onViewAttached()
|
controller.onViewAttached()
|
||||||
`when`(keyguardStateController.isShowing).thenReturn(true)
|
`when`(keyguardStateController.isShowing).thenReturn(true)
|
||||||
|
|
||||||
// WHEN user needs strong auth & fingerprint authenticated
|
// WHEN unlocking with fingerprint is NOT allowed & fingerprint authenticated
|
||||||
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(true)
|
`when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
|
eq(BiometricSourceType.FINGERPRINT))).thenReturn(false)
|
||||||
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
|
val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
|
||||||
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
|
verify(keyguardUpdateMonitor).registerCallback(captor.capture())
|
||||||
captor.value.onBiometricAuthenticated(
|
captor.value.onBiometricAuthenticated(
|
||||||
@@ -182,13 +186,14 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFaceTriggerBypassEnabled_Ripple() {
|
fun testFaceTriggerBypassEnabled_Ripple() {
|
||||||
// GIVEN face auth sensor exists, keyguard is showing & strong auth isn't required
|
// GIVEN face auth sensor exists, keyguard is showing & unlocking with face is allowed
|
||||||
val faceLocation = Point(5, 5)
|
val faceLocation = Point(5, 5)
|
||||||
`when`(authController.faceSensorLocation).thenReturn(faceLocation)
|
`when`(authController.faceSensorLocation).thenReturn(faceLocation)
|
||||||
controller.onViewAttached()
|
controller.onViewAttached()
|
||||||
|
|
||||||
`when`(keyguardStateController.isShowing).thenReturn(true)
|
`when`(keyguardStateController.isShowing).thenReturn(true)
|
||||||
`when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)
|
`when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
|
BiometricSourceType.FACE)).thenReturn(true)
|
||||||
|
|
||||||
// WHEN bypass is enabled & face authenticated
|
// WHEN bypass is enabled & face authenticated
|
||||||
`when`(bypassController.canBypass()).thenReturn(true)
|
`when`(bypassController.canBypass()).thenReturn(true)
|
||||||
@@ -275,6 +280,8 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
`when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
|
`when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
|
||||||
controller.onViewAttached()
|
controller.onViewAttached()
|
||||||
`when`(keyguardStateController.isShowing).thenReturn(true)
|
`when`(keyguardStateController.isShowing).thenReturn(true)
|
||||||
|
`when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
|
BiometricSourceType.FINGERPRINT)).thenReturn(true)
|
||||||
`when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
|
`when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
|
||||||
|
|
||||||
controller.showUnlockRipple(BiometricSourceType.FINGERPRINT)
|
controller.showUnlockRipple(BiometricSourceType.FINGERPRINT)
|
||||||
@@ -295,6 +302,8 @@ class AuthRippleControllerTest : SysuiTestCase() {
|
|||||||
`when`(keyguardStateController.isShowing).thenReturn(true)
|
`when`(keyguardStateController.isShowing).thenReturn(true)
|
||||||
`when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
|
`when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
|
||||||
`when`(authController.isUdfpsFingerDown).thenReturn(true)
|
`when`(authController.isUdfpsFingerDown).thenReturn(true)
|
||||||
|
`when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
|
eq(BiometricSourceType.FACE))).thenReturn(true)
|
||||||
|
|
||||||
controller.showUnlockRipple(BiometricSourceType.FACE)
|
controller.showUnlockRipple(BiometricSourceType.FACE)
|
||||||
assertTrue("reveal didn't start on keyguardFadingAway",
|
assertTrue("reveal didn't start on keyguardFadingAway",
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.hardware.biometrics.BiometricSourceType;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
@@ -398,6 +399,8 @@ public class KeyguardBouncerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShow_delaysIfFaceAuthIsRunning() {
|
public void testShow_delaysIfFaceAuthIsRunning() {
|
||||||
|
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE))
|
||||||
|
.thenReturn(true);
|
||||||
when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
|
when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
|
||||||
mBouncer.show(true /* reset */);
|
mBouncer.show(true /* reset */);
|
||||||
|
|
||||||
@@ -410,9 +413,10 @@ public class KeyguardBouncerTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testShow_doesNotDelaysIfFaceAuthIsLockedOut() {
|
public void testShow_doesNotDelaysIfFaceAuthIsNotAllowed() {
|
||||||
when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
|
when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
|
||||||
when(mKeyguardUpdateMonitor.isFaceLockedOut()).thenReturn(true);
|
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(BiometricSourceType.FACE))
|
||||||
|
.thenReturn(false);
|
||||||
mBouncer.show(true /* reset */);
|
mBouncer.show(true /* reset */);
|
||||||
|
|
||||||
verify(mHandler, never()).postDelayed(any(), anyLong());
|
verify(mHandler, never()).postDelayed(any(), anyLong());
|
||||||
|
|||||||
Reference in New Issue
Block a user