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

Commit 186fbcc2 authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "Only show auth ripple on keyguard" into sc-dev

parents 043dc863 3ab0be34
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2143,7 +2143,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        final boolean shouldListenUdfpsState = !isUdfps
                || (!getUserCanSkipBouncer(getCurrentUser())
                    && !isEncryptedOrLockdown(getCurrentUser())
                    && mStrongAuthTracker.hasUserAuthenticatedSinceBoot()
                    && !userNeedsStrongAuth()
                    && userDoesNotHaveTrust);

        return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState
+10 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.settingslib.Utils
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.Command
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.ViewController
@@ -45,6 +46,7 @@ class AuthRippleController @Inject constructor(
    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
    private val commandRegistry: CommandRegistry,
    private val notificationShadeWindowController: NotificationShadeWindowController,
    private val bypassController: KeyguardBypassController,
    rippleView: AuthRippleView?
) : ViewController<AuthRippleView>(rippleView) {
    private var fingerprintSensorLocation: PointF? = null
@@ -69,12 +71,20 @@ class AuthRippleController @Inject constructor(
    }

    private fun showRipple(biometricSourceType: BiometricSourceType?) {
        if (!keyguardUpdateMonitor.isKeyguardVisible ||
            keyguardUpdateMonitor.userNeedsStrongAuth()) {
            return
        }

        if (biometricSourceType == BiometricSourceType.FINGERPRINT &&
            fingerprintSensorLocation != null) {
            mView.setSensorLocation(fingerprintSensorLocation!!)
            showRipple()
        } else if (biometricSourceType == BiometricSourceType.FACE &&
            faceSensorLocation != null) {
            if (!bypassController.canBypass()) {
                return
            }
            mView.setSensorLocation(faceSensorLocation!!)
            showRipple()
        }
+7 −4
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.keyguard;
import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;

import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
@@ -477,7 +479,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
    @Test
    public void testFingerprintDoesNotAuth_whenEncrypted() {
        testFingerprintWhenStrongAuth(
                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
                STRONG_AUTH_REQUIRED_AFTER_BOOT);
    }

    @Test
@@ -576,7 +578,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
    @Test
    public void skipsAuthentication_whenEncryptedKeyguard() {
        when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
                STRONG_AUTH_REQUIRED_AFTER_BOOT);
        mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);

        mKeyguardUpdateMonitor.dispatchStartedWakingUp();
@@ -588,7 +590,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
    @Test
    public void requiresAuthentication_whenEncryptedKeyguard_andBypass() {
        testStrongAuthExceptOnBouncer(
                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
                STRONG_AUTH_REQUIRED_AFTER_BOOT);
    }

    @Test
@@ -893,7 +895,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
        mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);

        // WHEN user hasn't authenticated since last boot
        when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(false);
        when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
                .thenReturn(STRONG_AUTH_REQUIRED_AFTER_BOOT);

        // THEN we shouldn't listen for udfps
        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(false);
+81 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import org.junit.Before
import org.junit.Test
@@ -49,6 +50,7 @@ class AuthRippleControllerTest : SysuiTestCase() {
    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
    @Mock private lateinit var authController: AuthController
    @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
    @Mock private lateinit var bypassController: KeyguardBypassController

    @Before
    fun setUp() {
@@ -60,45 +62,120 @@ class AuthRippleControllerTest : SysuiTestCase() {
            keyguardUpdateMonitor,
            commandRegistry,
            notificationShadeWindowController,
            bypassController,
            rippleView
        )
        controller.init()
    }

    @Test
    fun testFingerprintTriggerRipple() {
    fun testFingerprintTrigger_Ripple() {
        // GIVEN fp exists, keyguard is visible, user doesn't need strong auth
        val fpsLocation = PointF(5f, 5f)
        `when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
        controller.onViewAttached()
        `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
        `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)

        // WHEN fingerprint authenticated
        val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
        verify(keyguardUpdateMonitor).registerCallback(captor.capture())

        captor.value.onBiometricAuthenticated(
            0 /* userId */,
            BiometricSourceType.FINGERPRINT /* type */,
            false /* isStrongBiometric */)

        // THEN update sensor location and show ripple
        verify(rippleView).setSensorLocation(fpsLocation)
        verify(rippleView).startRipple(any())
    }

    @Test
    fun testFaceTriggerRipple() {
    fun testFingerprintTrigger_KeyguardNotVisible_NoRipple() {
        // GIVEN fp exists & user doesn't need strong auth
        val fpsLocation = PointF(5f, 5f)
        `when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
        controller.onViewAttached()
        `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)

        // WHEN keyguard is NOT visible & fingerprint authenticated
        `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(false)
        val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
        verify(keyguardUpdateMonitor).registerCallback(captor.capture())
        captor.value.onBiometricAuthenticated(
            0 /* userId */,
            BiometricSourceType.FINGERPRINT /* type */,
            false /* isStrongBiometric */)

        // THEN no ripple
        verify(rippleView, never()).startRipple(any())
    }

    @Test
    fun testFingerprintTrigger_StrongAuthRequired_NoRipple() {
        // GIVEN fp exists & keyguard is visible
        val fpsLocation = PointF(5f, 5f)
        `when`(authController.udfpsSensorLocation).thenReturn(fpsLocation)
        controller.onViewAttached()
        `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)

        // WHEN user needs strong auth & fingerprint authenticated
        `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(true)
        val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
        verify(keyguardUpdateMonitor).registerCallback(captor.capture())
        captor.value.onBiometricAuthenticated(
            0 /* userId */,
            BiometricSourceType.FINGERPRINT /* type */,
            false /* isStrongBiometric */)

        // THEN no ripple
        verify(rippleView, never()).startRipple(any())
    }

    @Test
    fun testFaceTriggerBypassEnabled_Ripple() {
        // GIVEN face auth sensor exists, keyguard is visible & strong auth isn't required
        val faceLocation = PointF(5f, 5f)
        `when`(authController.faceAuthSensorLocation).thenReturn(faceLocation)
        controller.onViewAttached()

        `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true)
        `when`(keyguardUpdateMonitor.userNeedsStrongAuth()).thenReturn(false)

        // WHEN bypass is enabled & face authenticated
        `when`(bypassController.canBypass()).thenReturn(true)
        val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
        verify(keyguardUpdateMonitor).registerCallback(captor.capture())

        captor.value.onBiometricAuthenticated(
            0 /* userId */,
            BiometricSourceType.FACE /* type */,
            false /* isStrongBiometric */)

        // THEN show ripple
        verify(rippleView).setSensorLocation(faceLocation)
        verify(rippleView).startRipple(any())
    }

    @Test
    fun testFaceTriggerNonBypass_NoRipple() {
        // GIVEN face auth sensor exists
        val faceLocation = PointF(5f, 5f)
        `when`(authController.faceAuthSensorLocation).thenReturn(faceLocation)
        controller.onViewAttached()

        // WHEN bypass isn't enabled & face authenticated
        `when`(bypassController.canBypass()).thenReturn(false)
        val captor = ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback::class.java)
        verify(keyguardUpdateMonitor).registerCallback(captor.capture())
        captor.value.onBiometricAuthenticated(
            0 /* userId */,
            BiometricSourceType.FACE /* type */,
            false /* isStrongBiometric */)

        // THEN no ripple
        verify(rippleView, never()).startRipple(any())
    }

    @Test
    fun testNullFaceSensorLocationDoesNothing() {
        `when`(authController.faceAuthSensorLocation).thenReturn(null)