Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf9a253a authored by Kevin Chyn's avatar Kevin Chyn
Browse files

8/n: Add additional multi-sensor reject logic

Send haptic feedback if face is rejected and UDFPS is not "active"

Bug: 193089985
Test: atest CoexCoordinatorTest
Test: manual
Change-Id: I3b8d172b0f3cbf890344f6db3e1deff15f8737d3
parent fa8b98f9
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -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)) {
                    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);
+34 −0
Original line number Diff line number Diff line
@@ -258,6 +258,40 @@ 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 testNonKeyguard_rejectAndNotLockedOut() {
        mCoexCoordinator.reset();