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

Commit fe3efd66 authored by Kevin Chyn's avatar Kevin Chyn Committed by Automerger Merge Worker
Browse files

Merge changes I02898d24,I3b8d172b into sc-dev am: 8fa96139 am: a7cd696a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15350821

Change-Id: I053133f8007d000ffe9ba4253d4789184bb0be33
parents 528c2df4 a7cd696a
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);
+68 −0
Original line number Diff line number Diff line
@@ -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();