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

Commit b4efdcbe authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Reverting to a previous state of face auth haptics." into main

parents 1cb0b93f 4fea664d
Loading
Loading
Loading
Loading
+16 −14
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.systemui.statusbar.phone.dozeScrimController
import com.android.systemui.statusbar.phone.screenOffAnimationController
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy
@@ -105,7 +106,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
    @Test
    fun nonPowerButtonFPS_vibrateSuccess() =
        testScope.runTest {
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            enrollFingerprint(FingerprintSensorType.UDFPS_ULTRASONIC)
            runCurrent()
            enterDeviceFromFingerprintUnlockLegacy()
@@ -116,7 +117,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
    @Test
    fun powerButtonFPS_vibrateSuccess() =
        testScope.runTest {
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
            kosmos.fakeKeyEventRepository.setPowerButtonDown(false)

@@ -133,7 +134,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
    @Test
    fun powerButtonFPS_powerDown_doNotVibrateSuccess() =
        testScope.runTest {
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
            kosmos.fakeKeyEventRepository.setPowerButtonDown(true) // power button is currently DOWN

@@ -150,7 +151,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
    @Test
    fun powerButtonFPS_powerButtonRecentlyPressed_doNotVibrateSuccess() =
        testScope.runTest {
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
            kosmos.fakeKeyEventRepository.setPowerButtonDown(false)

@@ -174,14 +175,14 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
        }

    @Test
    fun nonPowerButtonFPS_coExFaceFailure_vibrateError() =
    fun nonPowerButtonFPS_coExFaceFailure_doNotVibrateError() =
        testScope.runTest {
            val playErrorHaptic by collectLastValue(underTest.playErrorHaptic)
            enrollFingerprint(FingerprintSensorType.UDFPS_ULTRASONIC)
            enrollFace()
            runCurrent()
            faceFailure()
            assertThat(playErrorHaptic).isNotNull()
            assertThat(playErrorHaptic).isNull()
        }

    @Test
@@ -211,7 +212,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
        testScope.runTest {
            kosmos.configureKeyguardBypass(isBypassAvailable = false)
            underTest = kosmos.deviceEntryHapticsInteractor
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            enrollFingerprint(FingerprintSensorType.UDFPS_ULTRASONIC)
            runCurrent()
            configureDeviceEntryFromBiometricSource(isFpUnlock = true)
@@ -225,7 +226,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
        testScope.runTest {
            kosmos.configureKeyguardBypass(isBypassAvailable = false)
            underTest = kosmos.deviceEntryHapticsInteractor
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
            kosmos.fakeKeyEventRepository.setPowerButtonDown(false)

@@ -246,18 +247,19 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
            enrollFace()
            kosmos.configureKeyguardBypass(isBypassAvailable = true)
            underTest = kosmos.deviceEntryHapticsInteractor
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            configureDeviceEntryFromBiometricSource(isFaceUnlock = true)
            verifyDeviceEntryFromFaceAuth()
            assertThat(playSuccessHaptic).isNotNull()
        }

    @OptIn(ExperimentalCoroutinesApi::class)
    @EnableSceneContainer
    @Test
    fun playSuccessHaptic_onFaceAuthSuccess_whenBypassDisabled_sceneContainer() =
    fun skipSuccessHaptic_onFaceAuthSuccess_whenBypassDisabled_sceneContainer() =
        testScope.runTest {
            underTest = kosmos.deviceEntryHapticsInteractor
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)

            enrollFace()
            kosmos.configureKeyguardBypass(isBypassAvailable = false)
@@ -265,7 +267,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
            configureDeviceEntryFromBiometricSource(isFaceUnlock = true, bypassEnabled = false)
            kosmos.fakeDeviceEntryFaceAuthRepository.isAuthenticated.value = true

            assertThat(playSuccessHaptic).isNotNull()
            assertThat(playSuccessHaptic).isNull()
        }

    @EnableSceneContainer
@@ -274,7 +276,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
        testScope.runTest {
            kosmos.configureKeyguardBypass(isBypassAvailable = false)
            underTest = kosmos.deviceEntryHapticsInteractor
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
            // power button is currently DOWN
            kosmos.fakeKeyEventRepository.setPowerButtonDown(true)
@@ -295,7 +297,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() {
        testScope.runTest {
            kosmos.configureKeyguardBypass(isBypassAvailable = false)
            underTest = kosmos.deviceEntryHapticsInteractor
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic)
            val playSuccessHaptic by collectLastValue(underTest.playSuccessHapticOnDeviceEntry)
            enrollFingerprint(FingerprintSensorType.POWER_BUTTON)
            kosmos.fakeKeyEventRepository.setPowerButtonDown(false)

+15 −17
Original line number Diff line number Diff line
@@ -863,7 +863,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
            whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playSuccessHaptic by
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)

            setupBiometricAuth(hasUdfps = true)
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -885,7 +885,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
            whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playSuccessHaptic by
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)

            setupBiometricAuth(hasUdfps = true)
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -907,7 +907,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
            whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playSuccessHaptic by
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)

            setupBiometricAuth(hasSfps = true)
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -930,7 +930,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
            whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playSuccessHaptic by
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)

            setupBiometricAuth(hasSfps = true)
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1033,7 +1033,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
            whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playSuccessHaptic by
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)

            setupBiometricAuth(hasSfps = true)
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1056,7 +1056,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
            whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playSuccessHaptic by
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)

            setupBiometricAuth(hasSfps = true)
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1079,7 +1079,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
            whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playSuccessHaptic by
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)

            setupBiometricAuth(hasSfps = true)
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1102,7 +1102,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
            whenever(kosmos.keyguardUpdateMonitor.isDeviceInteractive).thenReturn(true)
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playSuccessHaptic by
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHaptic)
                collectLastValue(deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry)

            setupBiometricAuth(hasSfps = true)
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
@@ -1160,7 +1160,7 @@ class SceneContainerStartableTest : SysuiTestCase() {

    @Test
    @DisableFlags(Flags.FLAG_MSDL_FEEDBACK)
    fun playsFaceErrorHaptics_nonSfps_coEx() =
    fun skipsFaceErrorHaptics_nonSfps_coEx() =
        testScope.runTest {
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playErrorHaptic by collectLastValue(deviceEntryHapticsInteractor.playErrorHaptic)
@@ -1172,15 +1172,14 @@ class SceneContainerStartableTest : SysuiTestCase() {
            underTest.start()
            updateFaceAuthStatus(isSuccess = false)

            assertThat(playErrorHaptic).isNotNull()
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
            verify(vibratorHelper).vibrateAuthError(anyString())
            assertThat(playErrorHaptic).isNull()
            verify(vibratorHelper, never()).vibrateAuthError(anyString())
            verify(vibratorHelper, never()).vibrateAuthSuccess(anyString())
        }

    @Test
    @EnableFlags(Flags.FLAG_MSDL_FEEDBACK)
    fun playsMSDLFaceErrorHaptics_nonSfps_coEx() =
    fun skipsMSDLFaceErrorHaptics_nonSfps_coEx() =
        testScope.runTest {
            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
            val playErrorHaptic by collectLastValue(deviceEntryHapticsInteractor.playErrorHaptic)
@@ -1192,10 +1191,9 @@ class SceneContainerStartableTest : SysuiTestCase() {
            underTest.start()
            updateFaceAuthStatus(isSuccess = false)

            assertThat(playErrorHaptic).isNotNull()
            assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
            assertThat(msdlPlayer.latestTokenPlayed).isEqualTo(MSDLToken.FAILURE)
            assertThat(msdlPlayer.latestPropertiesPlayed).isEqualTo(authInteractionProperties)
            assertThat(playErrorHaptic).isNull()
            assertThat(msdlPlayer.latestTokenPlayed).isNull()
            assertThat(msdlPlayer.latestPropertiesPlayed).isNull()
        }

    @Test
+0 −6
Original line number Diff line number Diff line
@@ -68,10 +68,4 @@ constructor(
                emptyFlow()
            }
        }

    /** Triggered if a face failure occurs regardless of the mode. */
    val faceFailure: Flow<FailedFaceAuthenticationStatus> =
        deviceEntryFaceAuthInteractor.authenticationStatus.filterIsInstance<
            FailedFaceAuthenticationStatus
        >()
}
+9 −19
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardBypassInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.util.kotlin.FlowDumperImpl
@@ -49,8 +48,6 @@ class DeviceEntryHapticsInteractor
constructor(
    biometricSettingsRepository: BiometricSettingsRepository,
    deviceEntryBiometricAuthInteractor: DeviceEntryBiometricAuthInteractor,
    deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor,
    keyguardBypassInteractor: KeyguardBypassInteractor,
    deviceEntryFingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
    deviceEntrySourceInteractor: DeviceEntrySourceInteractor,
    fingerprintPropertyRepository: FingerprintPropertyRepository,
@@ -83,7 +80,12 @@ constructor(
                emit(recentPowerButtonPressThresholdMs * -1L - 1L)
            }

    private val playHapticsOnDeviceEntry: Flow<Boolean> =
    /**
     * Indicates when success haptics should play when the device is entered. This always occurs on
     * successful fingerprint authentications. It also occurs on successful face authentication but
     * only if the lockscreen is bypassed.
     */
    val playSuccessHapticOnDeviceEntry: Flow<Unit> =
        deviceEntrySourceInteractor.deviceEntryFromBiometricSource
            .sample(
                combine(
@@ -93,29 +95,17 @@ constructor(
                    ::Triple,
                )
            )
            .map { (sideFpsEnrolled, powerButtonDown, lastPowerButtonWakeup) ->
            .filter { (sideFpsEnrolled, powerButtonDown, lastPowerButtonWakeup) ->
                val sideFpsAllowsHaptic =
                    !powerButtonDown &&
                        systemClock.uptimeMillis() - lastPowerButtonWakeup >
                            recentPowerButtonPressThresholdMs
                val allowHaptic = !sideFpsEnrolled || sideFpsAllowsHaptic
                if (!allowHaptic) {
                    logger.d(
                        "Skip success entry haptic from power button. Recent power button press or button is down."
                    )
                    logger.d("Skip success haptic. Recent power button press or button is down.")
                }
                allowHaptic
            }

    private val playHapticsOnFaceAuthSuccessAndBypassDisabled: Flow<Boolean> =
        deviceEntryFaceAuthInteractor.isAuthenticated
            .filter { it }
            .sample(keyguardBypassInteractor.isBypassAvailable)
            .map { !it }

    val playSuccessHaptic: Flow<Unit> =
        merge(playHapticsOnDeviceEntry, playHapticsOnFaceAuthSuccessAndBypassDisabled)
            .filter { it }
            // map to Unit
            .map {}
            .dumpWhileCollecting("playSuccessHaptic")
@@ -123,7 +113,7 @@ constructor(
    private val playErrorHapticForBiometricFailure: Flow<Unit> =
        merge(
                deviceEntryFingerprintAuthInteractor.fingerprintFailure,
                deviceEntryBiometricAuthInteractor.faceFailure,
                deviceEntryBiometricAuthInteractor.faceOnlyFaceFailure,
            )
            // map to Unit
            .map {}
+1 −1
Original line number Diff line number Diff line
@@ -333,7 +333,7 @@ object KeyguardRootViewBinder {

                    if (deviceEntryHapticsInteractor != null && vibratorHelper != null) {
                        launch {
                            deviceEntryHapticsInteractor.playSuccessHaptic.collect {
                            deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry.collect {
                                if (msdlFeedback()) {
                                    msdlPlayer?.playToken(
                                        MSDLToken.UNLOCK,
Loading