Merge changes I02898d24,I3b8d172b into sc-dev
* changes: 9/n: Add test case for udfps rejection after face rejection 8/n: Add additional multi-sensor reject logic
This commit is contained in:
@@ -268,11 +268,18 @@ public class CoexCoordinator {
|
||||
AuthenticationClient<?> udfps = mClientMap.getOrDefault(SENSOR_TYPE_UDFPS, null);
|
||||
AuthenticationClient<?> face = mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
|
||||
if (isCurrentFaceAuth(client)) {
|
||||
// UDFPS should still be running in this case, do not vibrate. However, we
|
||||
// should notify the callback and finish the client, so that Keyguard and
|
||||
// BiometricScheduler do not get stuck.
|
||||
Slog.d(TAG, "Face rejected in multi-sensor auth, udfps: " + udfps);
|
||||
callback.handleLifecycleAfterAuth();
|
||||
if (isUdfpsActivelyAuthing(udfps)) {
|
||||
// UDFPS should still be running in this case, do not vibrate. However, we
|
||||
// should notify the callback and finish the client, so that Keyguard and
|
||||
// BiometricScheduler do not get stuck.
|
||||
Slog.d(TAG, "Face rejected in multi-sensor auth, udfps: " + udfps);
|
||||
callback.handleLifecycleAfterAuth();
|
||||
} else {
|
||||
// UDFPS is not actively authenticating (finger not touching, already
|
||||
// rejected, etc).
|
||||
callback.sendHapticFeedback();
|
||||
callback.handleLifecycleAfterAuth();
|
||||
}
|
||||
} else if (isCurrentUdfps(client)) {
|
||||
// Face should either be running, or have already finished
|
||||
SuccessfulAuth auth = popSuccessfulFaceAuthIfExists(currentTimeMillis);
|
||||
|
||||
@@ -258,6 +258,74 @@ public class CoexCoordinatorTest {
|
||||
verify(mCallback).handleLifecycleAfterAuth();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyguard_faceRejectedWhenUdfpsTouching_thenUdfpsRejected() {
|
||||
mCoexCoordinator.reset();
|
||||
|
||||
AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
|
||||
when(faceClient.isKeyguard()).thenReturn(true);
|
||||
when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
|
||||
|
||||
AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
|
||||
withSettings().extraInterfaces(Udfps.class));
|
||||
when(udfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
|
||||
when(udfpsClient.isKeyguard()).thenReturn(true);
|
||||
when(((Udfps) udfpsClient).isPointerDown()).thenReturn(true);
|
||||
|
||||
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
|
||||
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
|
||||
|
||||
mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, faceClient,
|
||||
LockoutTracker.LOCKOUT_NONE, mCallback);
|
||||
verify(mCallback, never()).sendHapticFeedback();
|
||||
verify(mCallback).handleLifecycleAfterAuth();
|
||||
|
||||
// BiometricScheduler removes the face authentication client after rejection
|
||||
mCoexCoordinator.removeAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
|
||||
|
||||
// Then UDFPS rejected
|
||||
CoexCoordinator.Callback udfpsCallback = mock(CoexCoordinator.Callback.class);
|
||||
mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, udfpsClient,
|
||||
LockoutTracker.LOCKOUT_NONE, udfpsCallback);
|
||||
verify(udfpsCallback).sendHapticFeedback();
|
||||
verify(udfpsCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
|
||||
verify(mCallback, never()).sendHapticFeedback();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyguard_udfpsRejected_thenFaceRejected() {
|
||||
mCoexCoordinator.reset();
|
||||
|
||||
AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
|
||||
when(faceClient.isKeyguard()).thenReturn(true);
|
||||
when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
|
||||
|
||||
AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
|
||||
withSettings().extraInterfaces(Udfps.class));
|
||||
when(udfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
|
||||
when(udfpsClient.isKeyguard()).thenReturn(true);
|
||||
when(((Udfps) udfpsClient).isPointerDown()).thenReturn(true);
|
||||
|
||||
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
|
||||
mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
|
||||
|
||||
mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, udfpsClient,
|
||||
LockoutTracker.LOCKOUT_NONE, mCallback);
|
||||
// Client becomes paused, but finger does not necessarily lift, since we suppress the haptic
|
||||
when(udfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED_PAUSED);
|
||||
verify(mCallback, never()).sendHapticFeedback();
|
||||
verify(mCallback).handleLifecycleAfterAuth();
|
||||
|
||||
// Then face rejected. Note that scheduler leaves UDFPS in the CoexCoordinator since
|
||||
// unlike face, its lifecycle becomes "paused" instead of "finished".
|
||||
CoexCoordinator.Callback faceCallback = mock(CoexCoordinator.Callback.class);
|
||||
mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, faceClient,
|
||||
LockoutTracker.LOCKOUT_NONE, faceCallback);
|
||||
verify(faceCallback).sendHapticFeedback();
|
||||
verify(faceCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
|
||||
verify(mCallback, never()).sendHapticFeedback();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonKeyguard_rejectAndNotLockedOut() {
|
||||
mCoexCoordinator.reset();
|
||||
|
||||
Reference in New Issue
Block a user