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

Commit c4196529 authored by Beverly's avatar Beverly
Browse files

Remove UDFPS dwell animation for ultrasonic devices

Fixes: 352346058
Test: atest AuthRippleControllerTest
Flag: EXEMPT bugfix
Change-Id: I4cbe5a591067fc260323d9c14b484409dfae19f1
parent 9fd26dfb
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -34,7 +34,9 @@ import com.android.settingslib.Utils
import com.android.systemui.CoreStartable
import com.android.systemui.Flags.lightRevealMigration
import com.android.systemui.biometrics.data.repository.FacePropertyRepository
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
import com.android.systemui.biometrics.shared.model.toSensorType
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.domain.interactor.AuthRippleInteractor
import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
@@ -102,6 +104,7 @@ constructor(

    private var udfpsController: UdfpsController? = null
    private var udfpsRadius: Float = -1f
    private var udfpsType: FingerprintSensorType = FingerprintSensorType.UNKNOWN

    override fun start() {
        init()
@@ -370,8 +373,11 @@ constructor(
    private val udfpsControllerCallback =
        object : UdfpsController.Callback {
            override fun onFingerDown() {
                // only show dwell ripple for device entry
                if (keyguardUpdateMonitor.isFingerprintDetectionRunning) {
                // only show dwell ripple for device entry non-ultrasonic udfps
                if (
                    keyguardUpdateMonitor.isFingerprintDetectionRunning &&
                        udfpsType != FingerprintSensorType.UDFPS_ULTRASONIC
                ) {
                    showDwellRipple()
                }
            }
@@ -397,6 +403,7 @@ constructor(
            if (it.size > 0) {
                udfpsController = udfpsControllerProvider.get()
                udfpsRadius = authController.udfpsRadius
                udfpsType = it[0].sensorType.toSensorType()

                if (mView.isAttachedToWindow) {
                    udfpsController?.addCallback(udfpsControllerCallback)
+127 −69
Original line number Diff line number Diff line
@@ -18,6 +18,10 @@ package com.android.systemui.biometrics

import android.graphics.Point
import android.hardware.biometrics.BiometricSourceType
import android.hardware.biometrics.ComponentInfoInternal
import android.hardware.biometrics.SensorLocationInternal
import android.hardware.biometrics.SensorProperties
import android.hardware.fingerprint.FingerprintSensorProperties
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import android.testing.TestableLooper.RunWithLooper
import android.util.DisplayMetrics
@@ -43,6 +47,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.leak.RotationUtils
import com.android.systemui.util.mockito.any
import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.After
import org.junit.Assert.assertFalse
@@ -62,8 +67,6 @@ import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.mockito.MockitoSession
import org.mockito.quality.Strictness
import javax.inject.Provider


@ExperimentalCoroutinesApi
@SmallTest
@@ -79,22 +82,14 @@ class AuthRippleControllerTest : SysuiTestCase() {
    @Mock private lateinit var authController: AuthController
    @Mock private lateinit var authRippleInteractor: AuthRippleInteractor
    @Mock private lateinit var keyguardStateController: KeyguardStateController
    @Mock
    private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
    @Mock
    private lateinit var notificationShadeWindowController: NotificationShadeWindowController
    @Mock
    private lateinit var biometricUnlockController: BiometricUnlockController
    @Mock
    private lateinit var udfpsControllerProvider: Provider<UdfpsController>
    @Mock
    private lateinit var udfpsController: UdfpsController
    @Mock
    private lateinit var statusBarStateController: StatusBarStateController
    @Mock
    private lateinit var lightRevealScrim: LightRevealScrim
    @Mock
    private lateinit var fpSensorProp: FingerprintSensorPropertiesInternal
    @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
    @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
    @Mock private lateinit var biometricUnlockController: BiometricUnlockController
    @Mock private lateinit var udfpsControllerProvider: Provider<UdfpsController>
    @Mock private lateinit var udfpsController: UdfpsController
    @Mock private lateinit var statusBarStateController: StatusBarStateController
    @Mock private lateinit var lightRevealScrim: LightRevealScrim
    @Mock private lateinit var fpSensorProp: FingerprintSensorPropertiesInternal

    private val facePropertyRepository = FakeFacePropertyRepository()
    private val displayMetrics = DisplayMetrics()
@@ -107,7 +102,8 @@ class AuthRippleControllerTest : SysuiTestCase() {
    fun setUp() {
        mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
        MockitoAnnotations.initMocks(this)
        staticMockSession = mockitoSession()
        staticMockSession =
            mockitoSession()
                .mockStatic(RotationUtils::class.java)
                .strictness(Strictness.LENIENT)
                .startMocking()
@@ -116,7 +112,8 @@ class AuthRippleControllerTest : SysuiTestCase() {
        `when`(authController.udfpsProps).thenReturn(listOf(fpSensorProp))
        `when`(udfpsControllerProvider.get()).thenReturn(udfpsController)

        controller = AuthRippleController(
        controller =
            AuthRippleController(
                context,
                authController,
                configurationController,
@@ -150,13 +147,18 @@ class AuthRippleControllerTest : SysuiTestCase() {
        `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
        controller.onViewAttached()
        `when`(keyguardStateController.isShowing).thenReturn(true)
        `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
                eq(BiometricSourceType.FINGERPRINT))).thenReturn(true)
        `when`(
                keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
                    eq(BiometricSourceType.FINGERPRINT)
                )
            )
            .thenReturn(true)

        // WHEN fingerprint authenticated
        verify(biometricUnlockController).addListener(biometricUnlockListener.capture())
        biometricUnlockListener.value
                .onBiometricUnlockedWithKeyguardDismissal(BiometricSourceType.FINGERPRINT)
        biometricUnlockListener.value.onBiometricUnlockedWithKeyguardDismissal(
            BiometricSourceType.FINGERPRINT
        )

        // THEN update sensor location and show ripple
        verify(rippleView).setFingerprintSensorLocation(fpsLocation, 0f)
@@ -169,8 +171,12 @@ class AuthRippleControllerTest : SysuiTestCase() {
        val fpsLocation = Point(5, 5)
        `when`(authController.udfpsLocation).thenReturn(fpsLocation)
        controller.onViewAttached()
        `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
                eq(BiometricSourceType.FINGERPRINT))).thenReturn(true)
        `when`(
                keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
                    eq(BiometricSourceType.FINGERPRINT)
                )
            )
            .thenReturn(true)

        // WHEN keyguard is NOT showing & fingerprint authenticated
        `when`(keyguardStateController.isShowing).thenReturn(false)
@@ -179,7 +185,8 @@ class AuthRippleControllerTest : SysuiTestCase() {
        captor.value.onBiometricAuthenticated(
            0 /* userId */,
            BiometricSourceType.FINGERPRINT /* type */,
            false /* isStrongBiometric */)
            false /* isStrongBiometric */
        )

        // THEN no ripple
        verify(rippleView, never()).startUnlockedRipple(any())
@@ -194,14 +201,19 @@ class AuthRippleControllerTest : SysuiTestCase() {
        `when`(keyguardStateController.isShowing).thenReturn(true)

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

        // THEN no ripple
        verify(rippleView, never()).startUnlockedRipple(any())
@@ -218,7 +230,8 @@ class AuthRippleControllerTest : SysuiTestCase() {
        captor.value.onBiometricAuthenticated(
            0 /* userId */,
            BiometricSourceType.FACE /* type */,
            false /* isStrongBiometric */)
            false /* isStrongBiometric */
        )
        verify(rippleView, never()).startUnlockedRipple(any())
    }

@@ -233,18 +246,17 @@ class AuthRippleControllerTest : SysuiTestCase() {
        captor.value.onBiometricAuthenticated(
            0 /* userId */,
            BiometricSourceType.FINGERPRINT /* type */,
            false /* isStrongBiometric */)
            false /* isStrongBiometric */
        )
        verify(rippleView, never()).startUnlockedRipple(any())
    }

    @Test
    fun registersAndDeregisters() {
        controller.onViewAttached()
        val captor = ArgumentCaptor
            .forClass(KeyguardStateController.Callback::class.java)
        val captor = ArgumentCaptor.forClass(KeyguardStateController.Callback::class.java)
        verify(keyguardStateController).addCallback(captor.capture())
        val captor2 = ArgumentCaptor
            .forClass(WakefulnessLifecycle.Observer::class.java)
        val captor2 = ArgumentCaptor.forClass(WakefulnessLifecycle.Observer::class.java)
        verify(wakefulnessLifecycle).addObserver(captor2.capture())
        controller.onViewDetached()
        verify(keyguardStateController).removeCallback(any())
@@ -259,17 +271,25 @@ class AuthRippleControllerTest : SysuiTestCase() {
        `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation)
        controller.onViewAttached()
        `when`(keyguardStateController.isShowing).thenReturn(true)
        `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
                BiometricSourceType.FINGERPRINT)).thenReturn(true)
        `when`(
                keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
                    BiometricSourceType.FINGERPRINT
                )
            )
            .thenReturn(true)
        `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)

        controller.showUnlockRipple(BiometricSourceType.FINGERPRINT)
        assertTrue("reveal didn't start on keyguardFadingAway",
            controller.startLightRevealScrimOnKeyguardFadingAway)
        assertTrue(
            "reveal didn't start on keyguardFadingAway",
            controller.startLightRevealScrimOnKeyguardFadingAway
        )
        `when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true)
        controller.onKeyguardFadingAwayChanged()
        assertFalse("reveal triggers multiple times",
            controller.startLightRevealScrimOnKeyguardFadingAway)
        assertFalse(
            "reveal triggers multiple times",
            controller.startLightRevealScrimOnKeyguardFadingAway
        )
    }

    @Test
@@ -282,23 +302,27 @@ class AuthRippleControllerTest : SysuiTestCase() {
        `when`(keyguardStateController.isShowing).thenReturn(true)
        `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true)
        `when`(authController.isUdfpsFingerDown).thenReturn(true)
        `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
                eq(BiometricSourceType.FACE))).thenReturn(true)
        `when`(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(eq(BiometricSourceType.FACE)))
            .thenReturn(true)

        controller.showUnlockRipple(BiometricSourceType.FACE)
        assertTrue("reveal didn't start on keyguardFadingAway",
                controller.startLightRevealScrimOnKeyguardFadingAway)
        assertTrue(
            "reveal didn't start on keyguardFadingAway",
            controller.startLightRevealScrimOnKeyguardFadingAway
        )
        `when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true)
        controller.onKeyguardFadingAwayChanged()
        assertFalse("reveal triggers multiple times",
                controller.startLightRevealScrimOnKeyguardFadingAway)
        assertFalse(
            "reveal triggers multiple times",
            controller.startLightRevealScrimOnKeyguardFadingAway
        )
    }

    @Test
    fun testUpdateRippleColor() {
        controller.onViewAttached()
        val captor = ArgumentCaptor
            .forClass(ConfigurationController.ConfigurationListener::class.java)
        val captor =
            ArgumentCaptor.forClass(ConfigurationController.ConfigurationListener::class.java)
        verify(configurationController).addCallback(captor.capture())

        reset(rippleView)
@@ -332,6 +356,40 @@ class AuthRippleControllerTest : SysuiTestCase() {
        verify(rippleView).startDwellRipple(false)
    }

    @Test
    fun testUltrasonicUdfps_onFingerDown_runningForDeviceEntry_doNotShowDwellRipple() {
        // GIVEN UDFPS is ultrasonic
        `when`(authController.udfpsProps)
            .thenReturn(
                listOf(
                    FingerprintSensorPropertiesInternal(
                        0 /* sensorId */,
                        SensorProperties.STRENGTH_STRONG,
                        5 /* maxEnrollmentsPerUser */,
                        listOf<ComponentInfoInternal>(),
                        FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC,
                        false /* halControlsIllumination */,
                        true /* resetLockoutRequiresHardwareAuthToken */,
                        listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
                    )
                )
            )

        // GIVEN fingerprint detection is running on keyguard
        `when`(keyguardUpdateMonitor.isFingerprintDetectionRunning).thenReturn(true)

        // GIVEN view is already attached
        controller.onViewAttached()
        val captor = ArgumentCaptor.forClass(UdfpsController.Callback::class.java)
        verify(udfpsController).addCallback(captor.capture())

        // WHEN finger is down
        captor.value.onFingerDown()

        // THEN never show dwell ripple
        verify(rippleView, never()).startDwellRipple(false)
    }

    @Test
    fun testUdfps_onFingerDown_notDeviceEntry_doesNotShowDwellRipple() {
        // GIVEN fingerprint detection is NOT running on keyguard