Loading packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt +24 −4 Original line number Diff line number Diff line Loading @@ -254,6 +254,22 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { assertThat(playSuccessHaptic).isNotNull() } @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() = Loading Loading @@ -299,6 +315,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { private fun configureDeviceEntryFromBiometricSource( isFpUnlock: Boolean = false, isFaceUnlock: Boolean = false, bypassEnabled: Boolean = true, ) { // Mock DeviceEntrySourceInteractor#deviceEntryBiometricAuthSuccessState if (isFpUnlock) { Loading @@ -314,12 +331,15 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { ) // Mock DeviceEntrySourceInteractor#faceWakeAndUnlockMode = MODE_UNLOCK_COLLAPSING // if the successful face authentication will bypass keyguard if (bypassEnabled) { kosmos.sceneInteractor.setTransitionState( MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Lockscreen) ) ) } } underTest = kosmos.deviceEntryHapticsInteractor } Loading packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt +18 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -50,6 +51,8 @@ class DeviceEntryHapticsInteractor constructor( biometricSettingsRepository: BiometricSettingsRepository, deviceEntryBiometricAuthInteractor: DeviceEntryBiometricAuthInteractor, deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor, keyguardBypassInteractor: KeyguardBypassInteractor, deviceEntryFingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor, deviceEntrySourceInteractor: DeviceEntrySourceInteractor, fingerprintPropertyRepository: FingerprintPropertyRepository, Loading Loading @@ -82,7 +85,7 @@ constructor( emit(recentPowerButtonPressThresholdMs * -1L - 1L) } val playSuccessHaptic: Flow<Unit> = private val playHapticsOnDeviceEntry: Flow<Boolean> = deviceEntrySourceInteractor.deviceEntryFromBiometricSource .sample( combine( Loading @@ -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") Loading packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -34,6 +35,8 @@ val Kosmos.deviceEntryHapticsInteractor by DeviceEntryHapticsInteractor( biometricSettingsRepository = biometricSettingsRepository, deviceEntryBiometricAuthInteractor = deviceEntryBiometricAuthInteractor, deviceEntryFaceAuthInteractor = deviceEntryFaceAuthInteractor, keyguardBypassInteractor = keyguardBypassInteractor, deviceEntryFingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor, deviceEntrySourceInteractor = deviceEntrySourceInteractor, fingerprintPropertyRepository = fingerprintPropertyRepository, Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorTest.kt +24 −4 Original line number Diff line number Diff line Loading @@ -254,6 +254,22 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { assertThat(playSuccessHaptic).isNotNull() } @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() = Loading Loading @@ -299,6 +315,7 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { private fun configureDeviceEntryFromBiometricSource( isFpUnlock: Boolean = false, isFaceUnlock: Boolean = false, bypassEnabled: Boolean = true, ) { // Mock DeviceEntrySourceInteractor#deviceEntryBiometricAuthSuccessState if (isFpUnlock) { Loading @@ -314,12 +331,15 @@ class DeviceEntryHapticsInteractorTest : SysuiTestCase() { ) // Mock DeviceEntrySourceInteractor#faceWakeAndUnlockMode = MODE_UNLOCK_COLLAPSING // if the successful face authentication will bypass keyguard if (bypassEnabled) { kosmos.sceneInteractor.setTransitionState( MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Lockscreen) ) ) } } underTest = kosmos.deviceEntryHapticsInteractor } Loading
packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractor.kt +18 −3 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -50,6 +51,8 @@ class DeviceEntryHapticsInteractor constructor( biometricSettingsRepository: BiometricSettingsRepository, deviceEntryBiometricAuthInteractor: DeviceEntryBiometricAuthInteractor, deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor, keyguardBypassInteractor: KeyguardBypassInteractor, deviceEntryFingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor, deviceEntrySourceInteractor: DeviceEntrySourceInteractor, fingerprintPropertyRepository: FingerprintPropertyRepository, Loading Loading @@ -82,7 +85,7 @@ constructor( emit(recentPowerButtonPressThresholdMs * -1L - 1L) } val playSuccessHaptic: Flow<Unit> = private val playHapticsOnDeviceEntry: Flow<Boolean> = deviceEntrySourceInteractor.deviceEntryFromBiometricSource .sample( combine( Loading @@ -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") Loading
packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryHapticsInteractorKosmos.kt +3 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -34,6 +35,8 @@ val Kosmos.deviceEntryHapticsInteractor by DeviceEntryHapticsInteractor( biometricSettingsRepository = biometricSettingsRepository, deviceEntryBiometricAuthInteractor = deviceEntryBiometricAuthInteractor, deviceEntryFaceAuthInteractor = deviceEntryFaceAuthInteractor, keyguardBypassInteractor = keyguardBypassInteractor, deviceEntryFingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor, deviceEntrySourceInteractor = deviceEntrySourceInteractor, fingerprintPropertyRepository = fingerprintPropertyRepository, Loading