diff options
| author | 2024-08-24 18:03:12 +0000 | |
|---|---|---|
| committer | 2024-08-24 18:03:12 +0000 | |
| commit | 79675a50a38bce9c4990f60a96e5bd1943aed493 (patch) | |
| tree | e371a43f613c9af08647f764c1fc5fa10e90febc | |
| parent | b76107157d2236447f5824d6c9d4434460c5a725 (diff) | |
| parent | 5e77e6a4157431424963af6a1c35e284cc7c45ab (diff) | |
Merge changes I72b746ba,I0c319c40,Ic81a900a,I5694044a into main
* changes:
Tapping on the lockscreen should trigger face auth
Navigating to the compose bouncer should trigger face auth
Fix issue where face auth doesn't run when bouncer is launched from secure camera
Fix face auth not running as expected when flexiglass is enabled.
10 files changed, 210 insertions, 45 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index 91259a65eff9..3e75cebb1c7d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -34,6 +34,7 @@ import android.hardware.face.FaceSensorPropertiesInternal import android.os.CancellationSignal import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.compose.animation.scene.ObservableTransitionState import com.android.internal.logging.InstanceId.fakeInstanceId import com.android.internal.logging.UiEventLogger import com.android.systemui.Flags as AConfigFlags @@ -55,6 +56,7 @@ import com.android.systemui.deviceentry.shared.model.FaceDetectionStatus import com.android.systemui.deviceentry.shared.model.SuccessFaceAuthenticationStatus import com.android.systemui.display.data.repository.displayRepository import com.android.systemui.dump.DumpManager +import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.keyguard.data.repository.BiometricType import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository @@ -77,6 +79,9 @@ import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor +import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.testKosmos import com.android.systemui.user.data.model.SelectionStatus @@ -90,6 +95,7 @@ import com.google.common.truth.Truth.assertThat import java.io.PrintWriter import java.io.StringWriter import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent @@ -136,12 +142,12 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { @Captor private lateinit var faceLockoutResetCallback: ArgumentCaptor<FaceManager.LockoutResetCallback> - private val testDispatcher = kosmos.testDispatcher + private val testDispatcher by lazy { kosmos.testDispatcher } - private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository - private val testScope = kosmos.testScope - private val fakeUserRepository = kosmos.fakeUserRepository - private val fakeExecutor = kosmos.fakeExecutor + private val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository } + private val testScope by lazy { kosmos.testScope } + private val fakeUserRepository by lazy { kosmos.fakeUserRepository } + private val fakeExecutor by lazy { kosmos.fakeExecutor } private lateinit var authStatus: FlowValue<FaceAuthenticationStatus?> private lateinit var detectStatus: FlowValue<FaceDetectionStatus?> private lateinit var authRunning: FlowValue<Boolean?> @@ -149,18 +155,19 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { private lateinit var lockedOut: FlowValue<Boolean?> private lateinit var canFaceAuthRun: FlowValue<Boolean?> private lateinit var authenticated: FlowValue<Boolean?> - private val biometricSettingsRepository = kosmos.fakeBiometricSettingsRepository - private val deviceEntryFingerprintAuthRepository = + private val biometricSettingsRepository by lazy { kosmos.fakeBiometricSettingsRepository } + private val deviceEntryFingerprintAuthRepository by lazy { kosmos.fakeDeviceEntryFingerprintAuthRepository - private val trustRepository = kosmos.fakeTrustRepository - private val keyguardRepository = kosmos.fakeKeyguardRepository - private val powerInteractor = kosmos.powerInteractor - private val keyguardInteractor = kosmos.keyguardInteractor - private val alternateBouncerInteractor = kosmos.alternateBouncerInteractor - private val displayStateInteractor = kosmos.displayStateInteractor - private val bouncerRepository = kosmos.fakeKeyguardBouncerRepository - private val displayRepository = kosmos.displayRepository - private val keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor + } + private val trustRepository by lazy { kosmos.fakeTrustRepository } + private val keyguardRepository by lazy { kosmos.fakeKeyguardRepository } + private val powerInteractor by lazy { kosmos.powerInteractor } + private val keyguardInteractor by lazy { kosmos.keyguardInteractor } + private val alternateBouncerInteractor by lazy { kosmos.alternateBouncerInteractor } + private val displayStateInteractor by lazy { kosmos.displayStateInteractor } + private val bouncerRepository by lazy { kosmos.fakeKeyguardBouncerRepository } + private val displayRepository by lazy { kosmos.displayRepository } + private val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor } private lateinit var featureFlags: FakeFeatureFlags private var wasAuthCancelled = false @@ -180,9 +187,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { whenever(bypassController.bypassEnabled).thenReturn(true) underTest = createDeviceEntryFaceAuthRepositoryImpl(faceManager, bypassController) - mSetFlagsRule.disableFlags( - AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR, - ) + if (!SceneContainerFlag.isEnabled) { + mSetFlagsRule.disableFlags( + AConfigFlags.FLAG_KEYGUARD_WM_STATE_REFACTOR, + ) + } } private fun createDeviceEntryFaceAuthRepositoryImpl( @@ -227,6 +236,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { powerInteractor, keyguardInteractor, alternateBouncerInteractor, + { kosmos.sceneInteractor }, faceDetectBuffer, faceAuthBuffer, keyguardTransitionInteractor, @@ -547,6 +557,24 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } @Test + @EnableSceneContainer + fun withSceneContainerEnabled_authenticateDoesNotRunWhenKeyguardIsGoingAway() = + testScope.runTest { + testGatingCheckForFaceAuth(sceneContainerEnabled = true) { + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + KeyguardState.LOCKSCREEN, + KeyguardState.UNDEFINED, + value = 0.5f, + transitionState = TransitionState.RUNNING + ), + validateStep = false + ) + runCurrent() + } + } + + @Test fun authenticateDoesNotRunWhenDeviceIsGoingToSleep() = testScope.runTest { testGatingCheckForFaceAuth { @@ -595,6 +623,31 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } @Test + @EnableSceneContainer + fun withSceneContainer_authenticateRunsWhenSecureCameraIsActiveIfBouncerIsShowing() = + testScope.runTest { + initCollectors() + allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled = true) + bouncerRepository.setAlternateVisible(false) + + // launch secure camera + keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) + keyguardRepository.setKeyguardOccluded(true) + kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "for-test") + runCurrent() + assertThat(canFaceAuthRun()).isFalse() + + // but bouncer is shown after that. + kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "for-test") + kosmos.sceneInteractor.setTransitionState( + MutableStateFlow(ObservableTransitionState.Idle(Scenes.Bouncer)) + ) + runCurrent() + + assertThat(canFaceAuthRun()).isTrue() + } + + @Test fun authenticateDoesNotRunOnUnsupportedPosture() = testScope.runTest { testGatingCheckForFaceAuth { @@ -841,6 +894,24 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } @Test + @EnableSceneContainer + fun withSceneContainer_faceDetectDoesNotRunWhenKeyguardGoingAway() = + testScope.runTest { + testGatingCheckForDetect(sceneContainerEnabled = true) { + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + KeyguardState.LOCKSCREEN, + KeyguardState.UNDEFINED, + value = 0.5f, + transitionState = TransitionState.RUNNING + ), + validateStep = false + ) + runCurrent() + } + } + + @Test fun detectDoesNotRunWhenDeviceSleepingStartingToSleep() = testScope.runTest { testGatingCheckForDetect { @@ -1052,10 +1123,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } private suspend fun TestScope.testGatingCheckForFaceAuth( + sceneContainerEnabled: Boolean = false, gatingCheckModifier: suspend () -> Unit ) { initCollectors() - allPreconditionsToRunFaceAuthAreTrue() + allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled) gatingCheckModifier() runCurrent() @@ -1069,7 +1141,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { faceAuthenticateIsNotCalled() // flip the gating check back on. - allPreconditionsToRunFaceAuthAreTrue() + allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled) assertThat(underTest.canRunFaceAuth.value).isTrue() faceAuthenticateIsCalled() @@ -1094,10 +1166,11 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { } private suspend fun TestScope.testGatingCheckForDetect( + sceneContainerEnabled: Boolean = false, gatingCheckModifier: suspend () -> Unit ) { initCollectors() - allPreconditionsToRunFaceAuthAreTrue() + allPreconditionsToRunFaceAuthAreTrue(sceneContainerEnabled) // This will stop face auth from running but is required to be false for detect. biometricSettingsRepository.setIsFaceAuthCurrentlyAllowed(false) @@ -1145,12 +1218,22 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { cancellationSignal.value.setOnCancelListener { wasAuthCancelled = true } } - private suspend fun TestScope.allPreconditionsToRunFaceAuthAreTrue() { + private suspend fun TestScope.allPreconditionsToRunFaceAuthAreTrue( + sceneContainerEnabled: Boolean = false + ) { fakeExecutor.runAllReady() verify(faceManager, atLeastOnce()) .addLockoutResetCallback(faceLockoutResetCallback.capture()) trustRepository.setCurrentUserTrusted(false) - keyguardRepository.setKeyguardGoingAway(false) + if (sceneContainerEnabled) { + // Keyguard is not going away + kosmos.fakeKeyguardTransitionRepository.sendTransitionStep( + TransitionStep(KeyguardState.OFF, KeyguardState.LOCKSCREEN, value = 1.0f), + validateStep = false + ) + } else { + keyguardRepository.setKeyguardGoingAway(false) + } powerInteractor.setAwakeForTest() biometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true) biometricSettingsRepository.setIsFaceAuthSupportedInCurrentPosture(true) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt index 2b2c121fb79a..aee72de22a24 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt @@ -25,8 +25,11 @@ import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.logging.uiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor +import com.android.systemui.deviceentry.shared.FaceAuthUiEvent import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic +import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState @@ -260,6 +263,23 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() { } @Test + fun triggersFaceAuthWhenLockscreenIsClicked() = + testScope.runTest { + collectLastValue(underTest.isMenuVisible) + runCurrent() + kosmos.fakeDeviceEntryFaceAuthRepository.canRunFaceAuth.value = true + + underTest.onClick(100.0f, 100.0f) + runCurrent() + + val runningAuthRequest = + kosmos.fakeDeviceEntryFaceAuthRepository.runningAuthRequest.value + assertThat(runningAuthRequest?.first) + .isEqualTo(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED) + assertThat(runningAuthRequest?.second).isEqualTo(true) + } + + @Test fun showMenu_leaveLockscreen_returnToLockscreen_menuNotVisible() = testScope.runTest { val isMenuVisible by collectLastValue(underTest.isMenuVisible) @@ -302,6 +322,7 @@ class KeyguardTouchHandlingInteractorTest : SysuiTestCase() { broadcastDispatcher = fakeBroadcastDispatcher, accessibilityManager = kosmos.accessibilityManagerWrapper, pulsingGestureListener = kosmos.pulsingGestureListener, + faceAuthInteractor = kosmos.deviceEntryFaceAuthInteractor, ) setUpState() } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt index 9460eaf8abca..d288ccee2ae8 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt @@ -57,7 +57,10 @@ import com.android.systemui.log.FaceAuthenticationLogger import com.android.systemui.log.SessionTracker import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.power.domain.interactor.PowerInteractor +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes +import com.android.systemui.scene.shared.model.Scenes.Bouncer import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.UserRepository @@ -159,6 +162,7 @@ constructor( private val powerInteractor: PowerInteractor, private val keyguardInteractor: KeyguardInteractor, private val alternateBouncerInteractor: AlternateBouncerInteractor, + private val sceneInteractor: dagger.Lazy<SceneInteractor>, @FaceDetectTableLog private val faceDetectLog: TableLogBuffer, @FaceAuthTableLog private val faceAuthLog: TableLogBuffer, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, @@ -385,7 +389,16 @@ constructor( biometricSettingsRepository.isFaceAuthEnrolledAndEnabled, "isFaceAuthEnrolledAndEnabled" ), - Pair(keyguardRepository.isKeyguardGoingAway.isFalse(), "keyguardNotGoingAway"), + Pair( + if (SceneContainerFlag.isEnabled) { + keyguardTransitionInteractor + .isInTransitionWhere(toStatePredicate = { it == KeyguardState.UNDEFINED }) + .isFalse() + } else { + keyguardRepository.isKeyguardGoingAway.isFalse() + }, + "keyguardNotGoingAway" + ), Pair( keyguardTransitionInteractor .isInTransitionWhere(toStatePredicate = KeyguardState::deviceIsAsleepInState) @@ -397,7 +410,11 @@ constructor( .isFalse() .or( alternateBouncerInteractor.isVisible.or( - keyguardInteractor.primaryBouncerShowing + if (SceneContainerFlag.isEnabled) { + sceneInteractor.get().transitionState.map { it.isIdle(Bouncer) } + } else { + keyguardInteractor.primaryBouncerShowing + } ) ), "secureCameraNotActiveOrAnyBouncerIsShowing" diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt index c536d6b4f6f8..183e0e96e765 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt @@ -46,6 +46,9 @@ import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.log.FaceAuthenticationLogger import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.flag.SceneContainerFlag +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.kotlin.pairwise @@ -90,6 +93,7 @@ constructor( private val powerInteractor: PowerInteractor, private val biometricSettingsRepository: BiometricSettingsRepository, private val trustManager: TrustManager, + private val sceneInteractor: Lazy<SceneInteractor>, deviceEntryFaceAuthStatusInteractor: DeviceEntryFaceAuthStatusInteractor, ) : DeviceEntryFaceAuthInteractor { @@ -103,9 +107,7 @@ constructor( keyguardUpdateMonitor.setFaceAuthInteractor(this) observeFaceAuthStateUpdates() faceAuthenticationLogger.interactorStarted() - primaryBouncerInteractor - .get() - .isShowing + isBouncerVisible .whenItFlipsToTrue() .onEach { faceAuthenticationLogger.bouncerVisibilityChanged() @@ -181,19 +183,23 @@ constructor( // auth so that the switched user can unlock the device with face auth. userRepository.selectedUser .pairwise() - .onEach { (previous, curr) -> + .filter { (previous, curr) -> val wasSwitching = previous.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS val isSwitching = curr.selectionStatus == SelectionStatus.SELECTION_IN_PROGRESS - if (wasSwitching && !isSwitching) { - resetLockedOutState(curr.userInfo.id) - yield() - runFaceAuth( - FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING, - // Fallback to detection if bouncer is not showing so that we can detect a - // face and then show the bouncer to the user if face auth can't run - fallbackToDetect = !primaryBouncerInteractor.get().isBouncerShowing() - ) - } + // User switching was in progress and is complete now. + wasSwitching && !isSwitching + } + .map { (_, curr) -> curr.userInfo.id } + .sample(isBouncerVisible, ::Pair) + .onEach { (userId, isBouncerCurrentlyVisible) -> + resetLockedOutState(userId) + yield() + runFaceAuth( + FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING, + // Fallback to detection if bouncer is not showing so that we can detect a + // face and then show the bouncer to the user if face auth can't run + fallbackToDetect = !isBouncerCurrentlyVisible + ) } .launchIn(applicationScope) @@ -210,6 +216,14 @@ constructor( .launchIn(applicationScope) } + private val isBouncerVisible: Flow<Boolean> by lazy { + if (SceneContainerFlag.isEnabled) { + sceneInteractor.get().transitionState.map { it.isIdle(Scenes.Bouncer) } + } else { + primaryBouncerInteractor.get().isShowing + } + } + private suspend fun resetLockedOutState(currentUserId: Int) { val lockoutMode = facePropertyRepository.getLockoutMode(currentUserId) repository.setLockedOut( diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt index cd49c6a4d2e0..4a8ada7f1184 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt @@ -27,6 +27,7 @@ import com.android.internal.logging.UiEventLogger import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.KeyguardRepository @@ -67,6 +68,7 @@ constructor( broadcastDispatcher: BroadcastDispatcher, private val accessibilityManager: AccessibilityManagerWrapper, private val pulsingGestureListener: PulsingGestureListener, + private val faceAuthInteractor: DeviceEntryFaceAuthInteractor, ) { /** Whether the long-press handling feature should be enabled. */ val isLongPressHandlingEnabled: StateFlow<Boolean> = @@ -129,7 +131,8 @@ constructor( } } - /** Notifies that the user has long-pressed on the lock screen. + /** + * Notifies that the user has long-pressed on the lock screen. * * @param isA11yAction: Whether the action was performed as an a11y action */ @@ -174,6 +177,7 @@ constructor( /** Notifies that the lockscreen has been clicked at position [x], [y]. */ fun onClick(x: Float, y: Float) { pulsingGestureListener.onSingleTapUp(x, y) + faceAuthInteractor.onNotificationPanelClicked() } /** Notifies that the lockscreen has been double clicked. */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt index 0b7a3ed3a7c2..6aecc0e2b8fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt @@ -22,6 +22,7 @@ import android.hardware.biometrics.BiometricSourceType import android.os.PowerManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.compose.animation.scene.ObservableTransitionState import com.android.keyguard.keyguardUpdateMonitor import com.android.keyguard.trustManager import com.android.systemui.SysuiTestCase @@ -37,6 +38,7 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.data.repository.fakeFaceWakeUpTriggersConfig import com.android.systemui.deviceentry.shared.FaceAuthUiEvent import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus +import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository @@ -52,12 +54,15 @@ import com.android.systemui.log.logcatLogBuffer import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.power.shared.model.WakeSleepReason +import com.android.systemui.scene.domain.interactor.sceneInteractor +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.testKosmos import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.fakeUserRepository import com.android.systemui.util.mockito.eq 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.runCurrent import kotlinx.coroutines.test.runTest @@ -113,6 +118,7 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { powerInteractor, fakeBiometricSettingsRepository, trustManager, + { kosmos.sceneInteractor }, deviceEntryFaceAuthStatusInteractor, ) } @@ -279,6 +285,22 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() { } @Test + @EnableSceneContainer + fun withSceneContainerEnabled_faceAuthIsRequestedWhenPrimaryBouncerIsVisible() = + testScope.runTest { + underTest.start() + + kosmos.sceneInteractor.changeScene(Scenes.Bouncer, "for-test") + kosmos.sceneInteractor.setTransitionState( + MutableStateFlow(ObservableTransitionState.Idle(Scenes.Bouncer)) + ) + + runCurrent() + assertThat(faceAuthRepository.runningAuthRequest.value) + .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN, false)) + } + + @Test fun faceAuthIsRequestedWhenAlternateBouncerIsVisible() = testScope.runTest { underTest.start() diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt index fc7f69319261..d13419eed281 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt @@ -30,6 +30,7 @@ import com.android.systemui.animation.Expandable import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor import com.android.systemui.dock.DockManagerFake import com.android.systemui.doze.util.BurnInHelperWrapper import com.android.systemui.flags.FakeFeatureFlags @@ -152,9 +153,7 @@ class KeyguardBottomAreaViewModelTest(flags: FlagsParameterization) : SysuiTestC dockManager = DockManagerFake() biometricSettingsRepository = FakeBiometricSettingsRepository() val featureFlags = - FakeFeatureFlags().apply { - set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false) - } + FakeFeatureFlags().apply { set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false) } val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags) val keyguardInteractor = withDeps.keyguardInteractor @@ -223,6 +222,7 @@ class KeyguardBottomAreaViewModelTest(flags: FlagsParameterization) : SysuiTestC broadcastDispatcher = broadcastDispatcher, accessibilityManager = accessibilityManager, pulsingGestureListener = kosmos.pulsingGestureListener, + faceAuthInteractor = kosmos.deviceEntryFaceAuthInteractor, ) underTest = KeyguardBottomAreaViewModel( diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt index b9be04dc0a32..3dfe0eea500f 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorKosmos.kt @@ -33,6 +33,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testDispatcher import com.android.systemui.log.FaceAuthenticationLogger import com.android.systemui.power.domain.interactor.powerInteractor +import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.user.data.repository.userRepository import com.android.systemui.util.mockito.mock import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -57,6 +58,7 @@ val Kosmos.deviceEntryFaceAuthInteractor by powerInteractor = powerInteractor, biometricSettingsRepository = biometricSettingsRepository, trustManager = trustManager, + sceneInteractor = { sceneInteractor }, deviceEntryFaceAuthStatusInteractor = deviceEntryFaceAuthStatusInteractor, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt index 73799b63a6fc..769612c988ba 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt @@ -20,6 +20,7 @@ import android.content.applicationContext import android.view.accessibility.accessibilityManagerWrapper import com.android.internal.logging.uiEventLogger import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor import com.android.systemui.flags.featureFlagsClassic import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.kosmos.Kosmos @@ -38,5 +39,6 @@ val Kosmos.keyguardTouchHandlingInteractor by broadcastDispatcher = broadcastDispatcher, accessibilityManager = accessibilityManagerWrapper, pulsingGestureListener = pulsingGestureListener, + faceAuthInteractor = deviceEntryFaceAuthInteractor, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt index ae8b411a4b95..f84c3bdfdaf1 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt @@ -24,7 +24,7 @@ import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.domain.resolver.sceneFamilyResolvers import com.android.systemui.scene.shared.logger.sceneLogger -val Kosmos.sceneInteractor by +val Kosmos.sceneInteractor: SceneInteractor by Kosmos.Fixture { SceneInteractor( applicationScope = applicationCoroutineScope, |