Merge "RESTRICT AUTOMERGE Fix detect biometric logic." into tm-qpr-dev
This commit is contained in:
@@ -814,6 +814,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onBiometricDetected(int userId, BiometricSourceType biometricSourceType,
|
||||||
|
boolean isStrongBiometric) {
|
||||||
|
Assert.isMainThread();
|
||||||
|
Trace.beginSection("KeyGuardUpdateMonitor#onBiometricDetected");
|
||||||
|
for (int i = 0; i < mCallbacks.size(); i++) {
|
||||||
|
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
|
||||||
|
if (cb != null) {
|
||||||
|
cb.onBiometricDetected(userId, biometricSourceType, isStrongBiometric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Trace.endSection();
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected void onFingerprintAuthenticated(int userId, boolean isStrongBiometric) {
|
protected void onFingerprintAuthenticated(int userId, boolean isStrongBiometric) {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
@@ -890,6 +903,20 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleBiometricDetected(int authUserId, BiometricSourceType biometricSourceType,
|
||||||
|
boolean isStrongBiometric) {
|
||||||
|
Trace.beginSection("KeyGuardUpdateMonitor#handlerBiometricDetected");
|
||||||
|
onBiometricDetected(authUserId, biometricSourceType, isStrongBiometric);
|
||||||
|
if (biometricSourceType == FINGERPRINT) {
|
||||||
|
mLogger.logFingerprintDetected(authUserId, isStrongBiometric);
|
||||||
|
} else if (biometricSourceType == FACE) {
|
||||||
|
mLogger.logFaceDetected(authUserId, isStrongBiometric);
|
||||||
|
setFaceRunningState(BIOMETRIC_STATE_STOPPED);
|
||||||
|
}
|
||||||
|
|
||||||
|
Trace.endSection();
|
||||||
|
}
|
||||||
|
|
||||||
private void handleFingerprintAuthenticated(int authUserId, boolean isStrongBiometric) {
|
private void handleFingerprintAuthenticated(int authUserId, boolean isStrongBiometric) {
|
||||||
Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
|
Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
|
||||||
if (mHandler.hasCallbacks(mFpCancelNotReceived)) {
|
if (mHandler.hasCallbacks(mFpCancelNotReceived)) {
|
||||||
@@ -941,9 +968,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|
|
||||||
private void onFingerprintCancelNotReceived() {
|
private void onFingerprintCancelNotReceived() {
|
||||||
mLogger.e("Fp cancellation not received, transitioning to STOPPED");
|
mLogger.e("Fp cancellation not received, transitioning to STOPPED");
|
||||||
|
final boolean wasCancellingRestarting = mFingerprintRunningState
|
||||||
|
== BIOMETRIC_STATE_CANCELLING_RESTARTING;
|
||||||
mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
|
mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
|
||||||
|
if (wasCancellingRestarting) {
|
||||||
|
KeyguardUpdateMonitor.this.updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
|
||||||
|
} else {
|
||||||
KeyguardUpdateMonitor.this.updateFingerprintListeningState(BIOMETRIC_ACTION_STOP);
|
KeyguardUpdateMonitor.this.updateFingerprintListeningState(BIOMETRIC_ACTION_STOP);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleFingerprintError(int msgId, String errString) {
|
private void handleFingerprintError(int msgId, String errString) {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
@@ -1029,6 +1062,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
() -> updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE),
|
() -> updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE),
|
||||||
getBiometricLockoutDelay());
|
getBiometricLockoutDelay());
|
||||||
} else {
|
} else {
|
||||||
|
boolean temporaryLockoutReset = wasLockout && !mFingerprintLockedOut;
|
||||||
|
if (temporaryLockoutReset) {
|
||||||
|
mLogger.d("temporaryLockoutReset - stopListeningForFingerprint() to stop"
|
||||||
|
+ " detectFingerprint");
|
||||||
|
stopListeningForFingerprint();
|
||||||
|
}
|
||||||
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
|
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1728,10 +1767,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final FingerprintManager.FingerprintDetectionCallback mFingerprintDetectionCallback =
|
||||||
|
(sensorId, userId, isStrongBiometric) -> {
|
||||||
|
// Trigger the fingerprint detected path so the bouncer can be shown
|
||||||
|
handleBiometricDetected(userId, FINGERPRINT, isStrongBiometric);
|
||||||
|
};
|
||||||
|
|
||||||
private final FaceManager.FaceDetectionCallback mFaceDetectionCallback
|
private final FaceManager.FaceDetectionCallback mFaceDetectionCallback
|
||||||
= (sensorId, userId, isStrongBiometric) -> {
|
= (sensorId, userId, isStrongBiometric) -> {
|
||||||
// Trigger the face success path so the bouncer can be shown
|
// Trigger the face detected path so the bouncer can be shown
|
||||||
handleFaceAuthenticated(userId, isStrongBiometric);
|
handleBiometricDetected(userId, FACE, isStrongBiometric);
|
||||||
};
|
};
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -2759,8 +2804,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
|
|
||||||
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
|
boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
|
||||||
&& shouldListenBouncerState && shouldListenUdfpsState
|
&& shouldListenBouncerState && shouldListenUdfpsState
|
||||||
&& shouldListenSideFpsState
|
&& shouldListenSideFpsState;
|
||||||
&& !isFingerprintLockedOut();
|
|
||||||
logListenerModelData(
|
logListenerModelData(
|
||||||
new KeyguardFingerprintListenModel(
|
new KeyguardFingerprintListenModel(
|
||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
@@ -2819,8 +2863,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
final boolean supportsDetect = !mFaceSensorProperties.isEmpty()
|
final boolean supportsDetect = !mFaceSensorProperties.isEmpty()
|
||||||
&& mFaceSensorProperties.get(0).supportsFaceDetection
|
&& mFaceSensorProperties.get(0).supportsFaceDetection
|
||||||
&& canBypass && !mPrimaryBouncerIsOrWillBeShowing
|
&& canBypass && !mPrimaryBouncerIsOrWillBeShowing
|
||||||
&& !isUserInLockdown(user)
|
&& !isUserInLockdown(user);
|
||||||
&& !isFingerprintLockedOut();
|
|
||||||
final boolean faceAuthAllowedOrDetectionIsNeeded = faceAuthAllowed || supportsDetect;
|
final boolean faceAuthAllowedOrDetectionIsNeeded = faceAuthAllowed || supportsDetect;
|
||||||
|
|
||||||
// If the face or fp has recently been authenticated do not attempt to authenticate again.
|
// If the face or fp has recently been authenticated do not attempt to authenticate again.
|
||||||
@@ -2916,11 +2959,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
mLogger.v("startListeningForFingerprint - detect");
|
mLogger.v("startListeningForFingerprint - detect");
|
||||||
mFpm.detectFingerprint(
|
mFpm.detectFingerprint(
|
||||||
mFingerprintCancelSignal,
|
mFingerprintCancelSignal,
|
||||||
(sensorId, user, isStrongBiometric) -> {
|
mFingerprintDetectionCallback,
|
||||||
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");
|
mLogger.v("startListeningForFingerprint - authenticate");
|
||||||
|
|||||||
@@ -214,13 +214,21 @@ public class KeyguardUpdateMonitorCallback {
|
|||||||
public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) { }
|
public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a biometric is recognized.
|
* Called when a biometric is authenticated.
|
||||||
* @param userId the user id for which the biometric sample was authenticated
|
* @param userId the user id for which the biometric sample was authenticated
|
||||||
* @param biometricSourceType
|
* @param biometricSourceType
|
||||||
*/
|
*/
|
||||||
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
|
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
|
||||||
boolean isStrongBiometric) { }
|
boolean isStrongBiometric) { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a biometric is detected but not successfully authenticated.
|
||||||
|
* @param userId the user id for which the biometric sample was detected
|
||||||
|
* @param biometricSourceType
|
||||||
|
*/
|
||||||
|
public void onBiometricDetected(int userId, BiometricSourceType biometricSourceType,
|
||||||
|
boolean isStrongBiometric) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when biometric authentication provides help string (e.g. "Try again")
|
* Called when biometric authentication provides help string (e.g. "Try again")
|
||||||
* @param msgId
|
* @param msgId
|
||||||
|
|||||||
@@ -167,6 +167,20 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
|
|||||||
}, {"Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1"})
|
}, {"Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun logFaceDetected(userId: Int, isStrongBiometric: Boolean) {
|
||||||
|
logBuffer.log(TAG, DEBUG, {
|
||||||
|
int1 = userId
|
||||||
|
bool1 = isStrongBiometric
|
||||||
|
}, {"Face detected: userId: $int1, isStrongBiometric: $bool1"})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logFingerprintDetected(userId: Int, isStrongBiometric: Boolean) {
|
||||||
|
logBuffer.log(TAG, DEBUG, {
|
||||||
|
int1 = userId
|
||||||
|
bool1 = isStrongBiometric
|
||||||
|
}, {"Fingerprint detected: userId: $int1, isStrongBiometric: $bool1"})
|
||||||
|
}
|
||||||
|
|
||||||
fun logFingerprintError(msgId: Int, originalErrMsg: String) {
|
fun logFingerprintError(msgId: Int, originalErrMsg: String) {
|
||||||
logBuffer.log(TAG, DEBUG, {
|
logBuffer.log(TAG, DEBUG, {
|
||||||
str1 = originalErrMsg
|
str1 = originalErrMsg
|
||||||
|
|||||||
@@ -382,6 +382,17 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
|||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBiometricDetected(int userId, BiometricSourceType biometricSourceType,
|
||||||
|
boolean isStrongBiometric) {
|
||||||
|
Trace.beginSection("BiometricUnlockController#onBiometricDetected");
|
||||||
|
if (mUpdateMonitor.isGoingToSleep()) {
|
||||||
|
Trace.endSection();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
startWakeAndUnlock(MODE_SHOW_BOUNCER);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
|
public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
|
||||||
boolean isStrongBiometric) {
|
boolean isStrongBiometric) {
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
|
|||||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
|
||||||
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_HELP_FACE_NOT_AVAILABLE;
|
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING;
|
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING_RESTARTING;
|
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.HAL_POWER_PRESS_TIMEOUT;
|
import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
|
||||||
@@ -614,19 +613,47 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnlyDetectFingerprint_whenFingerprintUnlockNotAllowed() {
|
public void testOnlyDetectFingerprint_whenFingerprintUnlockNotAllowed() {
|
||||||
// Clear invocations, since previous setup (e.g. registering BiometricManager callbacks)
|
givenDetectFingerprintWithClearingFingerprintManagerInvocations();
|
||||||
// will trigger updateBiometricListeningState();
|
|
||||||
clearInvocations(mFingerprintManager);
|
|
||||||
mKeyguardUpdateMonitor.resetBiometricListeningState();
|
|
||||||
|
|
||||||
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
|
|
||||||
verifyFingerprintAuthenticateNeverCalled();
|
verifyFingerprintAuthenticateNeverCalled();
|
||||||
verifyFingerprintDetectCall();
|
verifyFingerprintDetectCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDetectFingerprint_biometricDetectCallback() {
|
||||||
|
ArgumentCaptor<FingerprintManager.FingerprintDetectionCallback> fpDetectCallbackCaptor =
|
||||||
|
ArgumentCaptor.forClass(FingerprintManager.FingerprintDetectionCallback.class);
|
||||||
|
|
||||||
|
givenDetectFingerprintWithClearingFingerprintManagerInvocations();
|
||||||
|
verify(mFingerprintManager).detectFingerprint(
|
||||||
|
any(), fpDetectCallbackCaptor.capture(), anyInt());
|
||||||
|
fpDetectCallbackCaptor.getValue().onFingerprintDetected(0, 0, true);
|
||||||
|
|
||||||
|
// THEN verify keyguardUpdateMonitorCallback receives a detect callback
|
||||||
|
// and NO authenticate callbacks
|
||||||
|
verify(mTestCallback).onBiometricDetected(
|
||||||
|
eq(0), eq(BiometricSourceType.FINGERPRINT), eq(true));
|
||||||
|
verify(mTestCallback, never()).onBiometricAuthenticated(
|
||||||
|
anyInt(), any(), anyBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDetectFace_biometricDetectCallback() {
|
||||||
|
ArgumentCaptor<FaceManager.FaceDetectionCallback> faceDetectCallbackCaptor =
|
||||||
|
ArgumentCaptor.forClass(FaceManager.FaceDetectionCallback.class);
|
||||||
|
|
||||||
|
givenDetectFace();
|
||||||
|
verify(mFaceManager).detectFace(any(), faceDetectCallbackCaptor.capture(), anyInt());
|
||||||
|
faceDetectCallbackCaptor.getValue().onFaceDetected(0, 0, false);
|
||||||
|
|
||||||
|
// THEN verify keyguardUpdateMonitorCallback receives a detect callback
|
||||||
|
// and NO authenticate callbacks
|
||||||
|
verify(mTestCallback).onBiometricDetected(
|
||||||
|
eq(0), eq(BiometricSourceType.FACE), eq(false));
|
||||||
|
verify(mTestCallback, never()).onBiometricAuthenticated(
|
||||||
|
anyInt(), any(), anyBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnlockingWithFaceAllowed_strongAuthTrackerUnlockingWithBiometricAllowed() {
|
public void testUnlockingWithFaceAllowed_strongAuthTrackerUnlockingWithBiometricAllowed() {
|
||||||
// GIVEN unlocking with biometric is allowed
|
// GIVEN unlocking with biometric is allowed
|
||||||
@@ -655,7 +682,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
strongAuthNotRequired();
|
strongAuthNotRequired();
|
||||||
|
|
||||||
// WHEN fingerprint is locked out
|
// WHEN fingerprint is locked out
|
||||||
fingerprintErrorLockedOut();
|
fingerprintErrorTemporaryLockedOut();
|
||||||
|
|
||||||
// THEN unlocking with face is not allowed
|
// THEN unlocking with face is not allowed
|
||||||
Assert.assertFalse(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
Assert.assertFalse(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
@@ -678,7 +705,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
strongAuthNotRequired();
|
strongAuthNotRequired();
|
||||||
|
|
||||||
// WHEN fingerprint is locked out
|
// WHEN fingerprint is locked out
|
||||||
fingerprintErrorLockedOut();
|
fingerprintErrorTemporaryLockedOut();
|
||||||
|
|
||||||
// THEN unlocking with fingerprint is not allowed
|
// THEN unlocking with fingerprint is not allowed
|
||||||
Assert.assertFalse(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
Assert.assertFalse(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
@@ -702,7 +729,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
Assert.assertTrue(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
|
Assert.assertTrue(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
|
||||||
|
|
||||||
// WHEN fingerprint is locked out
|
// WHEN fingerprint is locked out
|
||||||
fingerprintErrorLockedOut();
|
fingerprintErrorTemporaryLockedOut();
|
||||||
|
|
||||||
// THEN user is NOT considered as "having trust" and bouncer cannot be skipped
|
// THEN user is NOT considered as "having trust" and bouncer cannot be skipped
|
||||||
Assert.assertFalse(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
|
Assert.assertFalse(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
|
||||||
@@ -764,11 +791,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nofaceDetect_whenStrongAuthRequiredAndBypassUdfpsSupportedAndFpRunning() {
|
public void nofaceDetect_whenStrongAuthRequiredAndBypassUdfpsSupportedAndFpRunning() {
|
||||||
// GIVEN mocked keyguardUpdateMonitorCallback
|
|
||||||
KeyguardUpdateMonitorCallback keyguardUpdateMonitorCallback =
|
|
||||||
mock(KeyguardUpdateMonitorCallback.class);
|
|
||||||
mKeyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback);
|
|
||||||
|
|
||||||
// GIVEN bypass is enabled, face detection is supported
|
// GIVEN bypass is enabled, face detection is supported
|
||||||
lockscreenBypassIsAllowed();
|
lockscreenBypassIsAllowed();
|
||||||
supportsFaceDetection();
|
supportsFaceDetection();
|
||||||
@@ -787,22 +809,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
verifyFaceAuthenticateNeverCalled();
|
verifyFaceAuthenticateNeverCalled();
|
||||||
|
|
||||||
// THEN biometric help message sent to callback
|
// THEN biometric help message sent to callback
|
||||||
verify(keyguardUpdateMonitorCallback).onBiometricHelp(
|
verify(mTestCallback).onBiometricHelp(
|
||||||
eq(BIOMETRIC_HELP_FACE_NOT_AVAILABLE), anyString(), eq(BiometricSourceType.FACE));
|
eq(BIOMETRIC_HELP_FACE_NOT_AVAILABLE), anyString(), eq(BiometricSourceType.FACE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void faceDetect_whenStrongAuthRequiredAndBypass() {
|
public void faceDetect_whenStrongAuthRequiredAndBypass() {
|
||||||
// GIVEN bypass is enabled, face detection is supported and strong auth is required
|
givenDetectFace();
|
||||||
lockscreenBypassIsAllowed();
|
|
||||||
supportsFaceDetection();
|
|
||||||
strongAuthRequiredEncrypted();
|
|
||||||
keyguardIsVisible();
|
|
||||||
// fingerprint is NOT running, UDFPS is NOT supported
|
|
||||||
|
|
||||||
// WHEN the device wakes up
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
|
|
||||||
// FACE detect is triggered, not authenticate
|
// FACE detect is triggered, not authenticate
|
||||||
verifyFaceDetectCall();
|
verifyFaceDetectCall();
|
||||||
@@ -818,39 +831,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
verifyFaceDetectNeverCalled();
|
verifyFaceDetectNeverCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void noFaceRun_whenFpLockout() {
|
|
||||||
// GIVEN bypass is enabled, face detection is supported and strong auth is required
|
|
||||||
lockscreenBypassIsAllowed();
|
|
||||||
supportsFaceDetection();
|
|
||||||
strongAuthRequiredEncrypted();
|
|
||||||
keyguardIsVisible();
|
|
||||||
// fingerprint is NOT running, UDFPS is NOT supported
|
|
||||||
|
|
||||||
// GIVEN fp is locked out
|
|
||||||
when(mFingerprintManager.getLockoutModeForUser(eq(FINGERPRINT_SENSOR_ID), anyInt()))
|
|
||||||
.thenReturn(BIOMETRIC_LOCKOUT_TIMED);
|
|
||||||
mKeyguardUpdateMonitor.handleUserSwitchComplete(0);
|
|
||||||
assertThat(mKeyguardUpdateMonitor.isFingerprintLockedOut()).isEqualTo(true);
|
|
||||||
|
|
||||||
// WHEN the device wakes up
|
|
||||||
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
|
||||||
mTestableLooper.processAllMessages();
|
|
||||||
|
|
||||||
// FACE detect is NOT triggered and face authenticate is NOT triggered
|
|
||||||
verifyFaceDetectNeverCalled();
|
|
||||||
verifyFaceAuthenticateNeverCalled();
|
|
||||||
|
|
||||||
// WHEN bouncer becomes visible
|
|
||||||
setKeyguardBouncerVisibility(true);
|
|
||||||
clearInvocations(mFaceManager);
|
|
||||||
|
|
||||||
// THEN face scanning is not run
|
|
||||||
mKeyguardUpdateMonitor.requestFaceAuth(FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
|
|
||||||
verifyFaceAuthenticateNeverCalled();
|
|
||||||
verifyFaceDetectNeverCalled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noFaceDetect_whenStrongAuthRequiredAndBypass_faceDetectionUnsupported() {
|
public void noFaceDetect_whenStrongAuthRequiredAndBypass_faceDetectionUnsupported() {
|
||||||
// GIVEN bypass is enabled, face detection is NOT supported and strong auth is required
|
// GIVEN bypass is enabled, face detection is NOT supported and strong auth is required
|
||||||
@@ -1159,8 +1139,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
// Fingerprint should be cancelled on lockout if going to lockout state, else
|
// Fingerprint should be cancelled on lockout if going to lockout state, else
|
||||||
// restarted if it's not
|
// restarted if it's not
|
||||||
assertThat(mKeyguardUpdateMonitor.mFingerprintRunningState)
|
assertThat(mKeyguardUpdateMonitor.mFingerprintRunningState)
|
||||||
.isEqualTo(fpLocked
|
.isEqualTo(BIOMETRIC_STATE_CANCELLING_RESTARTING);
|
||||||
? BIOMETRIC_STATE_CANCELLING : BIOMETRIC_STATE_CANCELLING_RESTARTING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1619,7 +1598,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
|
||||||
|
|
||||||
// Fingerprint is locked out.
|
// Fingerprint is locked out.
|
||||||
fingerprintErrorLockedOut();
|
fingerprintErrorTemporaryLockedOut();
|
||||||
|
|
||||||
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
|
assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
|
||||||
}
|
}
|
||||||
@@ -2428,6 +2407,29 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
eq(false));
|
eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void detectFingerprint_onTemporaryLockoutReset_authenticateFingerprint() {
|
||||||
|
ArgumentCaptor<FingerprintManager.LockoutResetCallback> fpLockoutResetCallbackCaptor =
|
||||||
|
ArgumentCaptor.forClass(FingerprintManager.LockoutResetCallback.class);
|
||||||
|
verify(mFingerprintManager).addLockoutResetCallback(fpLockoutResetCallbackCaptor.capture());
|
||||||
|
|
||||||
|
// GIVEN device is locked out
|
||||||
|
fingerprintErrorTemporaryLockedOut();
|
||||||
|
|
||||||
|
// GIVEN FP detection is running
|
||||||
|
givenDetectFingerprintWithClearingFingerprintManagerInvocations();
|
||||||
|
verifyFingerprintDetectCall();
|
||||||
|
verifyFingerprintAuthenticateNeverCalled();
|
||||||
|
|
||||||
|
// WHEN temporary lockout resets
|
||||||
|
fpLockoutResetCallbackCaptor.getValue().onLockoutReset(0);
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
|
// THEN fingerprint detect state should cancel & then restart (for authenticate call)
|
||||||
|
assertThat(mKeyguardUpdateMonitor.mFingerprintRunningState)
|
||||||
|
.isEqualTo(BIOMETRIC_STATE_CANCELLING_RESTARTING);
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyFingerprintAuthenticateNeverCalled() {
|
private void verifyFingerprintAuthenticateNeverCalled() {
|
||||||
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
|
||||||
anyInt(), anyInt());
|
anyInt(), anyInt());
|
||||||
@@ -2532,7 +2534,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
mKeyguardUpdateMonitor.setSwitchingUser(true);
|
mKeyguardUpdateMonitor.setSwitchingUser(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fingerprintErrorLockedOut() {
|
private void fingerprintErrorTemporaryLockedOut() {
|
||||||
mKeyguardUpdateMonitor.mFingerprintAuthenticationCallback
|
mKeyguardUpdateMonitor.mFingerprintAuthenticationCallback
|
||||||
.onAuthenticationError(FINGERPRINT_ERROR_LOCKOUT, "Fingerprint locked out");
|
.onAuthenticationError(FINGERPRINT_ERROR_LOCKOUT, "Fingerprint locked out");
|
||||||
}
|
}
|
||||||
@@ -2672,6 +2674,30 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
receiver.setPendingResult(pendingResult);
|
receiver.setPendingResult(pendingResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void givenDetectFingerprintWithClearingFingerprintManagerInvocations() {
|
||||||
|
// Clear invocations, since previous setup (e.g. registering BiometricManager callbacks)
|
||||||
|
// will trigger updateBiometricListeningState();
|
||||||
|
clearInvocations(mFingerprintManager);
|
||||||
|
mKeyguardUpdateMonitor.resetBiometricListeningState();
|
||||||
|
|
||||||
|
when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void givenDetectFace() {
|
||||||
|
// GIVEN bypass is enabled, face detection is supported and strong auth is required
|
||||||
|
lockscreenBypassIsAllowed();
|
||||||
|
supportsFaceDetection();
|
||||||
|
strongAuthRequiredEncrypted();
|
||||||
|
keyguardIsVisible();
|
||||||
|
// fingerprint is NOT running, UDFPS is NOT supported
|
||||||
|
|
||||||
|
// WHEN the device wakes up
|
||||||
|
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
|
||||||
|
mTestableLooper.processAllMessages();
|
||||||
|
}
|
||||||
|
|
||||||
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
|
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
|
||||||
int subscription = simInited
|
int subscription = simInited
|
||||||
? 1/* mock subid=1 */ : SubscriptionManager.PLACEHOLDER_SUBSCRIPTION_ID_BASE;
|
? 1/* mock subid=1 */ : SubscriptionManager.PLACEHOLDER_SUBSCRIPTION_ID_BASE;
|
||||||
|
|||||||
@@ -537,6 +537,26 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
|||||||
verify(mVibratorHelper).vibrateAuthError(anyString());
|
verify(mVibratorHelper).vibrateAuthError(anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onFingerprintDetect_showBouncer() {
|
||||||
|
// WHEN fingerprint detect occurs
|
||||||
|
mBiometricUnlockController.onBiometricDetected(UserHandle.USER_CURRENT,
|
||||||
|
BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
|
||||||
|
|
||||||
|
// THEN shows primary bouncer
|
||||||
|
verify(mStatusBarKeyguardViewManager).showPrimaryBouncer(anyBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onFaceDetect_showBouncer() {
|
||||||
|
// WHEN face detect occurs
|
||||||
|
mBiometricUnlockController.onBiometricDetected(UserHandle.USER_CURRENT,
|
||||||
|
BiometricSourceType.FACE, false /* isStrongBiometric */);
|
||||||
|
|
||||||
|
// THEN shows primary bouncer
|
||||||
|
verify(mStatusBarKeyguardViewManager).showPrimaryBouncer(anyBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
private void givenFingerprintModeUnlockCollapsing() {
|
private void givenFingerprintModeUnlockCollapsing() {
|
||||||
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
||||||
when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);
|
when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);
|
||||||
|
|||||||
@@ -452,13 +452,6 @@ public class FingerprintService extends SystemService {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
|
|
||||||
// If this happens, something in KeyguardUpdateMonitor is wrong. This should only
|
|
||||||
// ever be invoked when the user is encrypted or lockdown.
|
|
||||||
Slog.e(TAG, "detectFingerprint invoked when user is not encrypted or lockdown");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
|
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
|
||||||
if (provider == null) {
|
if (provider == null) {
|
||||||
Slog.w(TAG, "Null provider for detectFingerprint");
|
Slog.w(TAG, "Null provider for detectFingerprint");
|
||||||
|
|||||||
Reference in New Issue
Block a user