diff options
| author | 2024-12-17 15:08:02 -0800 | |
|---|---|---|
| committer | 2025-01-08 14:24:21 -0800 | |
| commit | 7204034dfa2aa9bb95dcd6f684737d94743a5b91 (patch) | |
| tree | 7a1adb91eaa64b70af91bcb847df7c8d35efe229 | |
| parent | 2ff94617644f13fa18a12087a311a41647aed388 (diff) | |
Playing face auth MSDL haptics when lockscreen does not dismiss.
If the user setting to dismiss the keyguard is turned off, we should
still play haptics when face authentication successfully unlocks the
device. This can be done via a combination of the power state button
state upon device entry, and the face authentication result and the
state of the bypass setting.
Test: DeviceEntryHapticsInteractorTest
Flag: com.android.systemui.msdl_feedback
Bug: 361165906
Change-Id: I99b6a3c3d36373e2a6a2f9b2bee414beb6228793
3 files changed, 45 insertions, 7 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 20d66155e5ca..6c955bf1818d 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 @@ -256,6 +256,22 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { @EnableSceneContainer @Test + fun playSuccessHaptic_onFaceAuthSuccess_whenBypassDisabled_sceneContainer() = + testScope.runTest { + underTest = kosmos.deviceEntryHapticsInteractor + val playSuccessHaptic by collectLastValue(underTest.playSuccessHaptic) + + enrollFace() + kosmos.configureKeyguardBypass(isBypassAvailable = false) + runCurrent() + configureDeviceEntryFromBiometricSource(isFaceUnlock = true, bypassEnabled = false) + kosmos.fakeDeviceEntryFaceAuthRepository.isAuthenticated.value = true + + assertThat(playSuccessHaptic).isNotNull() + } + + @EnableSceneContainer + @Test fun skipSuccessHaptic_onDeviceEntryFromSfps_whenPowerDown_sceneContainer() = testScope.runTest { kosmos.configureKeyguardBypass(isBypassAvailable = false) @@ -299,6 +315,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { private fun configureDeviceEntryFromBiometricSource( isFpUnlock: Boolean = false, isFaceUnlock: Boolean = false, + bypassEnabled: Boolean = true, ) { // Mock DeviceEntrySourceInteractor#deviceEntryBiometricAuthSuccessState if (isFpUnlock) { @@ -314,11 +331,14 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { ) // Mock DeviceEntrySourceInteractor#faceWakeAndUnlockMode = MODE_UNLOCK_COLLAPSING - kosmos.sceneInteractor.setTransitionState( - MutableStateFlow<ObservableTransitionState>( - ObservableTransitionState.Idle(Scenes.Lockscreen) + // if the successful face authentication will bypass keyguard + if (bypassEnabled) { + kosmos.sceneInteractor.setTransitionState( + MutableStateFlow<ObservableTransitionState>( + ObservableTransitionState.Idle(Scenes.Lockscreen) + ) ) - ) + } } underTest = kosmos.deviceEntryHapticsInteractor } 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 41a59a959771..ae6238724042 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,6 +22,7 @@ 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 @@ -50,6 +51,8 @@ class DeviceEntryHapticsInteractor constructor( biometricSettingsRepository: BiometricSettingsRepository, deviceEntryBiometricAuthInteractor: DeviceEntryBiometricAuthInteractor, + deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor, + keyguardBypassInteractor: KeyguardBypassInteractor, deviceEntryFingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor, deviceEntrySourceInteractor: DeviceEntrySourceInteractor, fingerprintPropertyRepository: FingerprintPropertyRepository, @@ -82,7 +85,7 @@ constructor( emit(recentPowerButtonPressThresholdMs * -1L - 1L) } - val playSuccessHaptic: Flow<Unit> = + private val playHapticsOnDeviceEntry: Flow<Boolean> = deviceEntrySourceInteractor.deviceEntryFromBiometricSource .sample( combine( @@ -92,17 +95,29 @@ constructor( ::Triple, ) ) - .filter { (sideFpsEnrolled, powerButtonDown, lastPowerButtonWakeup) -> + .map { (sideFpsEnrolled, powerButtonDown, lastPowerButtonWakeup) -> val sideFpsAllowsHaptic = !powerButtonDown && systemClock.uptimeMillis() - lastPowerButtonWakeup > recentPowerButtonPressThresholdMs val allowHaptic = !sideFpsEnrolled || sideFpsAllowsHaptic if (!allowHaptic) { - logger.d("Skip success haptic. Recent power button press or button is down.") + logger.d( + "Skip success entry haptic from power button. 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") 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 2a7e3e903737..490b89bf6b13 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 @@ -23,6 +23,7 @@ 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 @@ -34,6 +35,8 @@ val Kosmos.deviceEntryHapticsInteractor by DeviceEntryHapticsInteractor( biometricSettingsRepository = biometricSettingsRepository, deviceEntryBiometricAuthInteractor = deviceEntryBiometricAuthInteractor, + deviceEntryFaceAuthInteractor = deviceEntryFaceAuthInteractor, + keyguardBypassInteractor = keyguardBypassInteractor, deviceEntryFingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor, deviceEntrySourceInteractor = deviceEntrySourceInteractor, fingerprintPropertyRepository = fingerprintPropertyRepository, |