diff options
7 files changed, 42 insertions, 61 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt index e0515000b232..454c15667f22 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt @@ -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) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index 9adf24f32c0c..1743e056b65c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt index 69da67e055fe..1e7bec257432 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryBiometricAuthInteractor.kt @@ -68,10 +68,4 @@ constructor( emptyFlow() } } - - /** Triggered if a face failure occurs regardless of the mode. */ - val faceFailure: Flow<FailedFaceAuthenticationStatus> = - deviceEntryFaceAuthInteractor.authenticationStatus.filterIsInstance< - FailedFaceAuthenticationStatus - >() } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt index 38e0503440f9..09936839c590 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt @@ -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 {} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt index 45801ba3517a..626a0555ee5e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt @@ -333,7 +333,7 @@ object KeyguardRootViewBinder { if (deviceEntryHapticsInteractor != null && vibratorHelper != null) { launch { - deviceEntryHapticsInteractor.playSuccessHaptic.collect { + deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry.collect { if (msdlFeedback()) { msdlPlayer?.playToken( MSDLToken.UNLOCK, diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt index 4753b9ac0457..7bb831baec20 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt @@ -687,7 +687,7 @@ constructor( if (!isDeviceEntered) { coroutineScope { launch { - deviceEntryHapticsInteractor.playSuccessHaptic + deviceEntryHapticsInteractor.playSuccessHapticOnDeviceEntry .sample(sceneInteractor.currentScene) .collect { currentScene -> if (Flags.msdlFeedback()) { diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt index 6f570a86b19e..cd4b09c5267a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt @@ -21,7 +21,6 @@ import com.android.systemui.biometrics.data.repository.fingerprintPropertyReposi 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.kosmos.Kosmos import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.util.time.systemClock @@ -31,8 +30,6 @@ val Kosmos.deviceEntryHapticsInteractor by DeviceEntryHapticsInteractor( biometricSettingsRepository = biometricSettingsRepository, deviceEntryBiometricAuthInteractor = deviceEntryBiometricAuthInteractor, - deviceEntryFaceAuthInteractor = deviceEntryFaceAuthInteractor, - keyguardBypassInteractor = keyguardBypassInteractor, deviceEntryFingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor, deviceEntrySourceInteractor = deviceEntrySourceInteractor, fingerprintPropertyRepository = fingerprintPropertyRepository, |