Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39af13d2 authored by Ale Nijamkin's avatar Ale Nijamkin Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Lockscreen scene returns to portrait mode." into main

parents 0136d6e4 d66f0827
Loading
Loading
Loading
Loading
+2 −43
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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
@@ -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!")
+95 −48
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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

@@ -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
@@ -879,7 +843,7 @@ class SceneContainerStartableTest : SysuiTestCase() {
        }

    @Test
    fun hydrateWindowFocus() =
    fun hydrateWindowController_setNotificationShadeFocusable() =
        testScope.runTest {
            val currentDesiredSceneKey by collectLastValue(sceneInteractor.currentScene)
            val transitionStateFlow =
@@ -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 {
+35 −15
Original line number Diff line number Diff line
@@ -117,9 +117,9 @@ constructor(
            hydrateSystemUiState()
            collectFalsingSignals()
            respondToFalsingDetections()
            hydrateWindowFocus()
            hydrateInteractionState()
            handleBouncerOverscroll()
            hydrateWindowController()
        } else {
            sceneLogger.logFrameworkEnabled(
                isEnabled = false,
@@ -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 {
@@ -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 {
+1 −1
Original line number Diff line number Diff line
@@ -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() }
+6 −3
Original line number Diff line number Diff line
@@ -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