Loading packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +2 −43 Original line number Diff line number Diff line Loading @@ -36,53 +36,40 @@ import com.android.systemui.authentication.domain.interactor.authenticationInter import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.BouncerActionButtonInteractor import com.android.systemui.bouncer.domain.interactor.bouncerActionButtonInteractor import com.android.systemui.bouncer.domain.interactor.bouncerInteractor import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.bouncerViewModel import com.android.systemui.classifier.domain.interactor.falsingInteractor import com.android.systemui.classifier.falsingCollector import com.android.systemui.classifier.falsingManager import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel import com.android.systemui.kosmos.testScope import com.android.systemui.media.controls.domain.pipeline.MediaDataManager import com.android.systemui.model.SysUiState import com.android.systemui.model.sceneContainerPlugin 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.qs.footerActionsController import com.android.systemui.qs.footerActionsViewModelFactory import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.sceneContainerStartable import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.domain.startable.SceneContainerStartable import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.shared.model.fakeSceneDataSource import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import com.android.systemui.settings.FakeDisplayTracker import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModel import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor import com.android.systemui.telephony.data.repository.fakeTelephonyRepository import com.android.systemui.testKosmos import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor Loading Loading @@ -155,8 +142,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { .apply { setTransitionState(transitionState) } } private val bouncerInteractor by lazy { kosmos.bouncerInteractor } private lateinit var mobileConnectionsRepository: FakeMobileConnectionsRepository private lateinit var bouncerActionButtonInteractor: BouncerActionButtonInteractor private lateinit var bouncerViewModel: BouncerViewModel Loading @@ -177,7 +162,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { private lateinit var shadeSceneViewModel: ShadeSceneViewModel private val keyguardInteractor by lazy { kosmos.keyguardInteractor } private val powerInteractor by lazy { kosmos.powerInteractor } private var bouncerSceneJob: Job? = null Loading Loading @@ -233,32 +217,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { unfoldTransitionInteractor = kosmos.unfoldTransitionInteractor, ) val displayTracker = FakeDisplayTracker(context) val sysUiState = SysUiState(displayTracker, kosmos.sceneContainerPlugin) val startable = SceneContainerStartable( applicationScope = testScope.backgroundScope, sceneInteractor = sceneInteractor, deviceEntryInteractor = deviceEntryInteractor, deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor, bouncerInteractor = bouncerInteractor, keyguardInteractor = keyguardInteractor, sysUiState = sysUiState, displayId = displayTracker.defaultDisplayId, sceneLogger = mock(), falsingCollector = kosmos.falsingCollector, falsingManager = kosmos.falsingManager, powerInteractor = powerInteractor, simBouncerInteractor = dagger.Lazy { kosmos.simBouncerInteractor }, authenticationInteractor = dagger.Lazy { kosmos.authenticationInteractor }, windowController = mock(), deviceProvisioningInteractor = kosmos.deviceProvisioningInteractor, centralSurfaces = mock(), headsUpInteractor = kosmos.headsUpNotificationInteractor, occlusionInteractor = kosmos.sceneContainerOcclusionInteractor, faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor, shadeInteractor = kosmos.shadeInteractor, ) val startable = kosmos.sceneContainerStartable startable.start() assertWithMessage("Initial scene key mismatch!") Loading packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +95 −48 Original line number Diff line number Diff line Loading @@ -27,47 +27,40 @@ import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.domain.interactor.authenticationInteractor import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.bouncerInteractor import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.falsingCollector import com.android.systemui.classifier.falsingManager import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.model.sysUiState import com.android.systemui.power.data.repository.fakePowerRepository 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.PowerInteractorFactory import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.power.shared.model.WakefulnessState import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.sceneContainerStartable import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.shared.model.fakeSceneDataSource import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shared.system.QuickStepContract import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.notificationShadeWindowController import com.android.systemui.statusbar.phone.centralSurfaces import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository import com.android.systemui.statusbar.policy.data.repository.fakeDeviceProvisioningRepository import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat Loading @@ -82,10 +75,8 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations Loading @@ -95,21 +86,17 @@ import org.mockito.MockitoAnnotations @EnableSceneContainer class SceneContainerStartableTest : SysuiTestCase() { @Mock private lateinit var windowController: NotificationShadeWindowController @Mock private lateinit var centralSurfaces: CentralSurfaces private val kosmos = testKosmos() private val testScope = kosmos.testScope private val sceneInteractor by lazy { kosmos.sceneInteractor } private val authenticationInteractor by lazy { kosmos.authenticationInteractor } private val bouncerInteractor by lazy { kosmos.bouncerInteractor } private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository } private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor } private val keyguardInteractor by lazy { kosmos.keyguardInteractor } private val sysUiState = spy(kosmos.sysUiState) private val falsingCollector: FalsingCollector = mock() private val powerInteractor = PowerInteractorFactory.create().powerInteractor private val sysUiState = kosmos.sysUiState private val falsingCollector = mock<FalsingCollector>().also { kosmos.falsingCollector = it } private val fakeSceneDataSource = kosmos.fakeSceneDataSource private val windowController = kosmos.notificationShadeWindowController private val centralSurfaces = kosmos.centralSurfaces private val powerInteractor = kosmos.powerInteractor private lateinit var underTest: SceneContainerStartable Loading @@ -117,30 +104,7 @@ class SceneContainerStartableTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) underTest = SceneContainerStartable( applicationScope = testScope.backgroundScope, sceneInteractor = sceneInteractor, deviceEntryInteractor = deviceEntryInteractor, deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor, bouncerInteractor = bouncerInteractor, keyguardInteractor = keyguardInteractor, sysUiState = sysUiState, displayId = Display.DEFAULT_DISPLAY, sceneLogger = mock(), falsingCollector = falsingCollector, falsingManager = kosmos.falsingManager, powerInteractor = powerInteractor, simBouncerInteractor = { kosmos.simBouncerInteractor }, authenticationInteractor = { authenticationInteractor }, windowController = windowController, deviceProvisioningInteractor = kosmos.deviceProvisioningInteractor, centralSurfaces = centralSurfaces, headsUpInteractor = kosmos.headsUpNotificationInteractor, occlusionInteractor = kosmos.sceneContainerOcclusionInteractor, faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor, shadeInteractor = kosmos.shadeInteractor, ) underTest = kosmos.sceneContainerStartable } @Test Loading Loading @@ -879,7 +843,7 @@ class SceneContainerStartableTest : SysuiTestCase() { } @Test fun hydrateWindowFocus() = fun hydrateWindowController_setNotificationShadeFocusable() = testScope.runTest { val currentDesiredSceneKey by collectLastValue(sceneInteractor.currentScene) val transitionStateFlow = Loading Loading @@ -932,6 +896,89 @@ class SceneContainerStartableTest : SysuiTestCase() { verify(windowController, times(2)).setNotificationShadeFocusable(false) } @Test fun hydrateWindowController_setKeyguardShowing() = testScope.runTest { underTest.start() val notificationShadeWindowController = kosmos.notificationShadeWindowController val transitionStateFlow = prepareState(initialSceneKey = Scenes.Lockscreen) val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) verify(notificationShadeWindowController).setKeyguardShowing(true) emulateSceneTransition(transitionStateFlow, Scenes.Bouncer) verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true) emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen) verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true) emulateSceneTransition(transitionStateFlow, Scenes.Shade) verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true) emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen) verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true) } @Test fun hydrateWindowController_setBouncerShowing() = testScope.runTest { underTest.start() val notificationShadeWindowController = kosmos.notificationShadeWindowController val transitionStateFlow = prepareState(initialSceneKey = Scenes.Lockscreen) val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) verify(notificationShadeWindowController, never()).setBouncerShowing(true) verify(notificationShadeWindowController, times(1)).setBouncerShowing(false) emulateSceneTransition(transitionStateFlow, Scenes.Bouncer) verify(notificationShadeWindowController, times(1)).setBouncerShowing(true) verify(notificationShadeWindowController, times(1)).setBouncerShowing(false) emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen) verify(notificationShadeWindowController, times(1)).setBouncerShowing(true) verify(notificationShadeWindowController, times(2)).setBouncerShowing(false) kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) assertThat(currentScene).isEqualTo(Scenes.Gone) verify(notificationShadeWindowController, times(1)).setBouncerShowing(true) verify(notificationShadeWindowController, times(2)).setBouncerShowing(false) emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen) verify(notificationShadeWindowController, times(1)).setBouncerShowing(true) verify(notificationShadeWindowController, times(2)).setBouncerShowing(false) emulateSceneTransition(transitionStateFlow, Scenes.Bouncer) verify(notificationShadeWindowController, times(2)).setBouncerShowing(true) verify(notificationShadeWindowController, times(2)).setBouncerShowing(false) } @Test fun hydrateWindowController_setKeyguardOccluded() = testScope.runTest { underTest.start() val notificationShadeWindowController = kosmos.notificationShadeWindowController prepareState(initialSceneKey = Scenes.Lockscreen) val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) verify(notificationShadeWindowController, never()).setKeyguardOccluded(true) verify(notificationShadeWindowController, times(1)).setKeyguardOccluded(false) kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( true, mock() ) runCurrent() verify(notificationShadeWindowController, times(1)).setKeyguardOccluded(true) verify(notificationShadeWindowController, times(1)).setKeyguardOccluded(false) kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(false) runCurrent() verify(notificationShadeWindowController, times(1)).setKeyguardOccluded(true) verify(notificationShadeWindowController, times(2)).setKeyguardOccluded(false) } @Test fun hydrateInteractionState_whileLocked() = testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +35 −15 Original line number Diff line number Diff line Loading @@ -117,9 +117,9 @@ constructor( hydrateSystemUiState() collectFalsingSignals() respondToFalsingDetections() hydrateWindowFocus() hydrateInteractionState() handleBouncerOverscroll() hydrateWindowController() } else { sceneLogger.logFrameworkEnabled( isEnabled = false, Loading Loading @@ -403,6 +403,40 @@ constructor( } } private fun hydrateWindowController() { applicationScope.launch { sceneInteractor.transitionState .mapNotNull { transitionState -> (transitionState as? ObservableTransitionState.Idle)?.scene } .distinctUntilChanged() .collect { sceneKey -> windowController.setNotificationShadeFocusable(sceneKey != Scenes.Gone) } } applicationScope.launch { deviceEntryInteractor.isDeviceEntered.collect { isDeviceEntered -> windowController.setKeyguardShowing(!isDeviceEntered) } } applicationScope.launch { sceneInteractor.currentScene .map { it == Scenes.Bouncer } .distinctUntilChanged() .collect { isBouncerShowing -> windowController.setBouncerShowing(isBouncerShowing) } } applicationScope.launch { occlusionInteractor.invisibleDueToOcclusion.collect { invisibleDueToOcclusion -> windowController.setKeyguardOccluded(invisibleDueToOcclusion) } } } /** Collects and reports signals into the falsing system. */ private fun collectFalsingSignals() { applicationScope.launch { Loading Loading @@ -464,20 +498,6 @@ constructor( } } /** Keeps the focus state of the window view up-to-date. */ private fun hydrateWindowFocus() { applicationScope.launch { sceneInteractor.transitionState .mapNotNull { transitionState -> (transitionState as? ObservableTransitionState.Idle)?.scene } .distinctUntilChanged() .collect { sceneKey -> windowController.setNotificationShadeFocusable(sceneKey != Scenes.Gone) } } } /** Keeps the interaction state of [CentralSurfaces] up-to-date. */ private fun hydrateInteractionState() { applicationScope.launch { Loading packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingCollectorKosmos.kt +1 −1 Original line number Diff line number Diff line Loading @@ -18,4 +18,4 @@ package com.android.systemui.classifier import com.android.systemui.kosmos.Kosmos val Kosmos.falsingCollector by Kosmos.Fixture { FalsingCollectorFake() } var Kosmos.falsingCollector by Kosmos.Fixture<FalsingCollector> { FalsingCollectorFake() } packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt +6 −3 Original line number Diff line number Diff line Loading @@ -19,10 +19,13 @@ package com.android.systemui.model import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.settings.displayTracker import org.mockito.Mockito.spy val Kosmos.sysUiState by Fixture { spy( SysUiState( displayTracker, sceneContainerPlugin, ) ) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +2 −43 Original line number Diff line number Diff line Loading @@ -36,53 +36,40 @@ import com.android.systemui.authentication.domain.interactor.authenticationInter import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.BouncerActionButtonInteractor import com.android.systemui.bouncer.domain.interactor.bouncerActionButtonInteractor import com.android.systemui.bouncer.domain.interactor.bouncerInteractor import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.bouncerViewModel import com.android.systemui.classifier.domain.interactor.falsingInteractor import com.android.systemui.classifier.falsingCollector import com.android.systemui.classifier.falsingManager import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel import com.android.systemui.kosmos.testScope import com.android.systemui.media.controls.domain.pipeline.MediaDataManager import com.android.systemui.model.SysUiState import com.android.systemui.model.sceneContainerPlugin 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.qs.footerActionsController import com.android.systemui.qs.footerActionsViewModelFactory import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.sceneContainerStartable import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.domain.startable.SceneContainerStartable import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.shared.model.fakeSceneDataSource import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel import com.android.systemui.settings.FakeDisplayTracker import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModel import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor import com.android.systemui.telephony.data.repository.fakeTelephonyRepository import com.android.systemui.testKosmos import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor Loading Loading @@ -155,8 +142,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { .apply { setTransitionState(transitionState) } } private val bouncerInteractor by lazy { kosmos.bouncerInteractor } private lateinit var mobileConnectionsRepository: FakeMobileConnectionsRepository private lateinit var bouncerActionButtonInteractor: BouncerActionButtonInteractor private lateinit var bouncerViewModel: BouncerViewModel Loading @@ -177,7 +162,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { private lateinit var shadeSceneViewModel: ShadeSceneViewModel private val keyguardInteractor by lazy { kosmos.keyguardInteractor } private val powerInteractor by lazy { kosmos.powerInteractor } private var bouncerSceneJob: Job? = null Loading Loading @@ -233,32 +217,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { unfoldTransitionInteractor = kosmos.unfoldTransitionInteractor, ) val displayTracker = FakeDisplayTracker(context) val sysUiState = SysUiState(displayTracker, kosmos.sceneContainerPlugin) val startable = SceneContainerStartable( applicationScope = testScope.backgroundScope, sceneInteractor = sceneInteractor, deviceEntryInteractor = deviceEntryInteractor, deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor, bouncerInteractor = bouncerInteractor, keyguardInteractor = keyguardInteractor, sysUiState = sysUiState, displayId = displayTracker.defaultDisplayId, sceneLogger = mock(), falsingCollector = kosmos.falsingCollector, falsingManager = kosmos.falsingManager, powerInteractor = powerInteractor, simBouncerInteractor = dagger.Lazy { kosmos.simBouncerInteractor }, authenticationInteractor = dagger.Lazy { kosmos.authenticationInteractor }, windowController = mock(), deviceProvisioningInteractor = kosmos.deviceProvisioningInteractor, centralSurfaces = mock(), headsUpInteractor = kosmos.headsUpNotificationInteractor, occlusionInteractor = kosmos.sceneContainerOcclusionInteractor, faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor, shadeInteractor = kosmos.shadeInteractor, ) val startable = kosmos.sceneContainerStartable startable.start() assertWithMessage("Initial scene key mismatch!") Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +95 −48 Original line number Diff line number Diff line Loading @@ -27,47 +27,40 @@ import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.domain.interactor.authenticationInteractor import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.bouncerInteractor import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.falsingCollector import com.android.systemui.classifier.falsingManager import com.android.systemui.coroutines.collectLastValue import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.model.sysUiState import com.android.systemui.power.data.repository.fakePowerRepository 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.PowerInteractorFactory import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.power.shared.model.WakefulnessState import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.sceneContainerStartable import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.shared.model.fakeSceneDataSource import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shared.system.QuickStepContract import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.notificationShadeWindowController import com.android.systemui.statusbar.phone.centralSurfaces import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository import com.android.systemui.statusbar.policy.data.repository.fakeDeviceProvisioningRepository import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor import com.android.systemui.testKosmos import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat Loading @@ -82,10 +75,8 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations Loading @@ -95,21 +86,17 @@ import org.mockito.MockitoAnnotations @EnableSceneContainer class SceneContainerStartableTest : SysuiTestCase() { @Mock private lateinit var windowController: NotificationShadeWindowController @Mock private lateinit var centralSurfaces: CentralSurfaces private val kosmos = testKosmos() private val testScope = kosmos.testScope private val sceneInteractor by lazy { kosmos.sceneInteractor } private val authenticationInteractor by lazy { kosmos.authenticationInteractor } private val bouncerInteractor by lazy { kosmos.bouncerInteractor } private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository } private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor } private val keyguardInteractor by lazy { kosmos.keyguardInteractor } private val sysUiState = spy(kosmos.sysUiState) private val falsingCollector: FalsingCollector = mock() private val powerInteractor = PowerInteractorFactory.create().powerInteractor private val sysUiState = kosmos.sysUiState private val falsingCollector = mock<FalsingCollector>().also { kosmos.falsingCollector = it } private val fakeSceneDataSource = kosmos.fakeSceneDataSource private val windowController = kosmos.notificationShadeWindowController private val centralSurfaces = kosmos.centralSurfaces private val powerInteractor = kosmos.powerInteractor private lateinit var underTest: SceneContainerStartable Loading @@ -117,30 +104,7 @@ class SceneContainerStartableTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) underTest = SceneContainerStartable( applicationScope = testScope.backgroundScope, sceneInteractor = sceneInteractor, deviceEntryInteractor = deviceEntryInteractor, deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor, bouncerInteractor = bouncerInteractor, keyguardInteractor = keyguardInteractor, sysUiState = sysUiState, displayId = Display.DEFAULT_DISPLAY, sceneLogger = mock(), falsingCollector = falsingCollector, falsingManager = kosmos.falsingManager, powerInteractor = powerInteractor, simBouncerInteractor = { kosmos.simBouncerInteractor }, authenticationInteractor = { authenticationInteractor }, windowController = windowController, deviceProvisioningInteractor = kosmos.deviceProvisioningInteractor, centralSurfaces = centralSurfaces, headsUpInteractor = kosmos.headsUpNotificationInteractor, occlusionInteractor = kosmos.sceneContainerOcclusionInteractor, faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor, shadeInteractor = kosmos.shadeInteractor, ) underTest = kosmos.sceneContainerStartable } @Test Loading Loading @@ -879,7 +843,7 @@ class SceneContainerStartableTest : SysuiTestCase() { } @Test fun hydrateWindowFocus() = fun hydrateWindowController_setNotificationShadeFocusable() = testScope.runTest { val currentDesiredSceneKey by collectLastValue(sceneInteractor.currentScene) val transitionStateFlow = Loading Loading @@ -932,6 +896,89 @@ class SceneContainerStartableTest : SysuiTestCase() { verify(windowController, times(2)).setNotificationShadeFocusable(false) } @Test fun hydrateWindowController_setKeyguardShowing() = testScope.runTest { underTest.start() val notificationShadeWindowController = kosmos.notificationShadeWindowController val transitionStateFlow = prepareState(initialSceneKey = Scenes.Lockscreen) val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) verify(notificationShadeWindowController).setKeyguardShowing(true) emulateSceneTransition(transitionStateFlow, Scenes.Bouncer) verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true) emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen) verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true) emulateSceneTransition(transitionStateFlow, Scenes.Shade) verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true) emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen) verify(notificationShadeWindowController, times(1)).setKeyguardShowing(true) } @Test fun hydrateWindowController_setBouncerShowing() = testScope.runTest { underTest.start() val notificationShadeWindowController = kosmos.notificationShadeWindowController val transitionStateFlow = prepareState(initialSceneKey = Scenes.Lockscreen) val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) verify(notificationShadeWindowController, never()).setBouncerShowing(true) verify(notificationShadeWindowController, times(1)).setBouncerShowing(false) emulateSceneTransition(transitionStateFlow, Scenes.Bouncer) verify(notificationShadeWindowController, times(1)).setBouncerShowing(true) verify(notificationShadeWindowController, times(1)).setBouncerShowing(false) emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen) verify(notificationShadeWindowController, times(1)).setBouncerShowing(true) verify(notificationShadeWindowController, times(2)).setBouncerShowing(false) kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) assertThat(currentScene).isEqualTo(Scenes.Gone) verify(notificationShadeWindowController, times(1)).setBouncerShowing(true) verify(notificationShadeWindowController, times(2)).setBouncerShowing(false) emulateSceneTransition(transitionStateFlow, Scenes.Lockscreen) verify(notificationShadeWindowController, times(1)).setBouncerShowing(true) verify(notificationShadeWindowController, times(2)).setBouncerShowing(false) emulateSceneTransition(transitionStateFlow, Scenes.Bouncer) verify(notificationShadeWindowController, times(2)).setBouncerShowing(true) verify(notificationShadeWindowController, times(2)).setBouncerShowing(false) } @Test fun hydrateWindowController_setKeyguardOccluded() = testScope.runTest { underTest.start() val notificationShadeWindowController = kosmos.notificationShadeWindowController prepareState(initialSceneKey = Scenes.Lockscreen) val currentScene by collectLastValue(sceneInteractor.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) verify(notificationShadeWindowController, never()).setKeyguardOccluded(true) verify(notificationShadeWindowController, times(1)).setKeyguardOccluded(false) kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop( true, mock() ) runCurrent() verify(notificationShadeWindowController, times(1)).setKeyguardOccluded(true) verify(notificationShadeWindowController, times(1)).setKeyguardOccluded(false) kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(false) runCurrent() verify(notificationShadeWindowController, times(1)).setKeyguardOccluded(true) verify(notificationShadeWindowController, times(2)).setKeyguardOccluded(false) } @Test fun hydrateInteractionState_whileLocked() = testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +35 −15 Original line number Diff line number Diff line Loading @@ -117,9 +117,9 @@ constructor( hydrateSystemUiState() collectFalsingSignals() respondToFalsingDetections() hydrateWindowFocus() hydrateInteractionState() handleBouncerOverscroll() hydrateWindowController() } else { sceneLogger.logFrameworkEnabled( isEnabled = false, Loading Loading @@ -403,6 +403,40 @@ constructor( } } private fun hydrateWindowController() { applicationScope.launch { sceneInteractor.transitionState .mapNotNull { transitionState -> (transitionState as? ObservableTransitionState.Idle)?.scene } .distinctUntilChanged() .collect { sceneKey -> windowController.setNotificationShadeFocusable(sceneKey != Scenes.Gone) } } applicationScope.launch { deviceEntryInteractor.isDeviceEntered.collect { isDeviceEntered -> windowController.setKeyguardShowing(!isDeviceEntered) } } applicationScope.launch { sceneInteractor.currentScene .map { it == Scenes.Bouncer } .distinctUntilChanged() .collect { isBouncerShowing -> windowController.setBouncerShowing(isBouncerShowing) } } applicationScope.launch { occlusionInteractor.invisibleDueToOcclusion.collect { invisibleDueToOcclusion -> windowController.setKeyguardOccluded(invisibleDueToOcclusion) } } } /** Collects and reports signals into the falsing system. */ private fun collectFalsingSignals() { applicationScope.launch { Loading Loading @@ -464,20 +498,6 @@ constructor( } } /** Keeps the focus state of the window view up-to-date. */ private fun hydrateWindowFocus() { applicationScope.launch { sceneInteractor.transitionState .mapNotNull { transitionState -> (transitionState as? ObservableTransitionState.Idle)?.scene } .distinctUntilChanged() .collect { sceneKey -> windowController.setNotificationShadeFocusable(sceneKey != Scenes.Gone) } } } /** Keeps the interaction state of [CentralSurfaces] up-to-date. */ private fun hydrateInteractionState() { applicationScope.launch { Loading
packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingCollectorKosmos.kt +1 −1 Original line number Diff line number Diff line Loading @@ -18,4 +18,4 @@ package com.android.systemui.classifier import com.android.systemui.kosmos.Kosmos val Kosmos.falsingCollector by Kosmos.Fixture { FalsingCollectorFake() } var Kosmos.falsingCollector by Kosmos.Fixture<FalsingCollector> { FalsingCollectorFake() }
packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt +6 −3 Original line number Diff line number Diff line Loading @@ -19,10 +19,13 @@ package com.android.systemui.model import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.settings.displayTracker import org.mockito.Mockito.spy val Kosmos.sysUiState by Fixture { spy( SysUiState( displayTracker, sceneContainerPlugin, ) ) }