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

Commit f0d8808f authored by Ben Lin's avatar Ben Lin
Browse files

Convert KeyguardlessScene into using SceneContainerStartable.

The scene will remain the same, but SceneContainerStartable now has
logic to no-op on scenes a device does not support.

Bug: 2982234162
Test: Build
Flag: ACONFIG com.android.systemui.scene_container DEVELOPMENT
Change-Id: I3940244588fe51254b7c74595b057e15dc8d783f
parent f0694c53
Loading
Loading
Loading
Loading
+48 −7
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.sceneContainerConfig
import com.android.systemui.scene.sceneContainerConfig
import com.android.systemui.scene.sceneKeys
import com.android.systemui.scene.sceneKeys
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.testKosmos
import com.android.systemui.testKosmos
@@ -39,7 +40,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith


@@ -54,19 +54,46 @@ class SceneInteractorTest : SysuiTestCase() {


    private lateinit var underTest: SceneInteractor
    private lateinit var underTest: SceneInteractor


    @Before
    @Test
    fun setUp() {
    fun allSceneKeys() {
        underTest = kosmos.sceneInteractor
        underTest = kosmos.sceneInteractor
        assertThat(underTest.allSceneKeys()).isEqualTo(kosmos.sceneKeys)
    }
    }


    @Test
    @Test
    fun allSceneKeys() {
    fun changeScene_toUnknownScene_doesNothing() =
        assertThat(underTest.allSceneKeys()).isEqualTo(kosmos.sceneKeys)
        testScope.runTest {
            val sceneKeys =
                listOf(
                    Scenes.QuickSettings,
                    Scenes.Shade,
                    Scenes.Lockscreen,
                    Scenes.Gone,
                    Scenes.Communal,
                )
            val navigationDistances =
                mapOf(
                    Scenes.Gone to 0,
                    Scenes.Lockscreen to 0,
                    Scenes.Communal to 1,
                    Scenes.Shade to 2,
                    Scenes.QuickSettings to 3,
                )
            kosmos.sceneContainerConfig =
                SceneContainerConfig(sceneKeys, Scenes.Lockscreen, navigationDistances)
            underTest = kosmos.sceneInteractor
            val currentScene by collectLastValue(underTest.currentScene)
            val previousScene = currentScene
            assertThat(previousScene).isNotEqualTo(Scenes.Bouncer)
            underTest.changeScene(Scenes.Bouncer, "reason")
            assertThat(currentScene).isEqualTo(previousScene)
        }
        }


    @Test
    @Test
    fun changeScene() =
    fun changeScene() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor

            val currentScene by collectLastValue(underTest.currentScene)
            val currentScene by collectLastValue(underTest.currentScene)
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)


@@ -77,6 +104,8 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun changeScene_toGoneWhenUnl_doesNotThrow() =
    fun changeScene_toGoneWhenUnl_doesNotThrow() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor

            val currentScene by collectLastValue(underTest.currentScene)
            val currentScene by collectLastValue(underTest.currentScene)
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)


@@ -91,11 +120,15 @@ class SceneInteractorTest : SysuiTestCase() {


    @Test(expected = IllegalStateException::class)
    @Test(expected = IllegalStateException::class)
    fun changeScene_toGoneWhenStillLocked_throws() =
    fun changeScene_toGoneWhenStillLocked_throws() =
        testScope.runTest { underTest.changeScene(Scenes.Gone, "reason") }
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            underTest.changeScene(Scenes.Gone, "reason")
        }


    @Test
    @Test
    fun sceneChanged_inDataSource() =
    fun sceneChanged_inDataSource() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val currentScene by collectLastValue(underTest.currentScene)
            val currentScene by collectLastValue(underTest.currentScene)
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)


@@ -107,6 +140,7 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun transitionState() =
    fun transitionState() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val underTest = kosmos.sceneContainerRepository
            val underTest = kosmos.sceneContainerRepository
            val transitionState =
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                MutableStateFlow<ObservableTransitionState>(
@@ -143,6 +177,7 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun transitioningTo() =
    fun transitioningTo() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Idle(underTest.currentScene.value)
                    ObservableTransitionState.Idle(underTest.currentScene.value)
@@ -179,6 +214,7 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun isTransitionUserInputOngoing_idle_false() =
    fun isTransitionUserInputOngoing_idle_false() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Idle(Scenes.Shade)
                    ObservableTransitionState.Idle(Scenes.Shade)
@@ -193,6 +229,7 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun isTransitionUserInputOngoing_transition_true() =
    fun isTransitionUserInputOngoing_transition_true() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Transition(
                    ObservableTransitionState.Transition(
@@ -213,6 +250,7 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun isTransitionUserInputOngoing_updateMidTransition_false() =
    fun isTransitionUserInputOngoing_updateMidTransition_false() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Transition(
                    ObservableTransitionState.Transition(
@@ -244,6 +282,7 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun isTransitionUserInputOngoing_updateOnIdle_false() =
    fun isTransitionUserInputOngoing_updateOnIdle_false() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Transition(
                    ObservableTransitionState.Transition(
@@ -268,6 +307,7 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun isVisible() =
    fun isVisible() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val isVisible by collectLastValue(underTest.isVisible)
            val isVisible by collectLastValue(underTest.isVisible)
            assertThat(isVisible).isTrue()
            assertThat(isVisible).isTrue()


@@ -281,6 +321,7 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun isVisible_duringRemoteUserInteraction_forcedVisible() =
    fun isVisible_duringRemoteUserInteraction_forcedVisible() =
        testScope.runTest {
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            underTest.setVisible(false, "reason")
            underTest.setVisible(false, "reason")
            val isVisible by collectLastValue(underTest.isVisible)
            val isVisible by collectLastValue(underTest.isVisible)
            assertThat(isVisible).isFalse()
            assertThat(isVisible).isFalse()
+40 −21
Original line number Original line Diff line number Diff line
@@ -16,10 +16,16 @@


package com.android.systemui.scene
package com.android.systemui.scene


import com.android.systemui.CoreStartable
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
import com.android.systemui.scene.domain.startable.SceneContainerStartable
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.Scenes
import dagger.Binds
import dagger.Module
import dagger.Module
import dagger.Provides
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap


/** Scene framework Dagger module suitable for variants that want to exclude "keyguard" scenes. */
/** Scene framework Dagger module suitable for variants that want to exclude "keyguard" scenes. */
@Module(
@Module(
@@ -31,9 +37,21 @@ import dagger.Provides
            ShadeSceneModule::class,
            ShadeSceneModule::class,
        ],
        ],
)
)
object KeyguardlessSceneContainerFrameworkModule {
interface KeyguardlessSceneContainerFrameworkModule {


    // TODO(b/298234162): provide a SceneContainerStartable without lockscreen and bouncer.
    @Binds
    @IntoMap
    @ClassKey(SceneContainerStartable::class)
    fun containerStartable(impl: SceneContainerStartable): CoreStartable

    @Binds
    @IntoMap
    @ClassKey(WindowRootViewVisibilityInteractor::class)
    fun bindWindowRootViewVisibilityInteractor(
        impl: WindowRootViewVisibilityInteractor
    ): CoreStartable

    companion object {


        @Provides
        @Provides
        fun containerConfig(): SceneContainerConfig {
        fun containerConfig(): SceneContainerConfig {
@@ -56,3 +74,4 @@ object KeyguardlessSceneContainerFrameworkModule {
            )
            )
        }
        }
    }
    }
}
+0 −8
Original line number Original line Diff line number Diff line
@@ -81,14 +81,6 @@ constructor(
        toScene: SceneKey,
        toScene: SceneKey,
        transitionKey: TransitionKey? = null,
        transitionKey: TransitionKey? = null,
    ) {
    ) {
        check(allSceneKeys().contains(toScene)) {
            """
                Cannot set the desired scene key to "$toScene". The configuration does not
                contain a scene with that key.
            """
                .trimIndent()
        }

        dataSource.changeScene(
        dataSource.changeScene(
            toScene = toScene,
            toScene = toScene,
            transitionKey = transitionKey,
            transitionKey = transitionKey,
+4 −0
Original line number Original line Diff line number Diff line
@@ -162,6 +162,10 @@ constructor(
        loggingReason: String,
        loggingReason: String,
        transitionKey: TransitionKey? = null,
        transitionKey: TransitionKey? = null,
    ) {
    ) {
        if (!repository.allSceneKeys().contains(toScene)) {
            return
        }

        check(
        check(
            toScene != Scenes.Gone || deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked
            toScene != Scenes.Gone || deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked
        ) {
        ) {
+6 −2
Original line number Original line Diff line number Diff line
@@ -57,12 +57,14 @@ import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNoti
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import com.android.systemui.util.asIndenting
import com.android.systemui.util.asIndenting
import com.android.systemui.util.kotlin.getOrNull
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.sample
import com.android.systemui.util.kotlin.sample
import com.android.systemui.util.printSection
import com.android.systemui.util.printSection
import com.android.systemui.util.println
import com.android.systemui.util.println
import dagger.Lazy
import dagger.Lazy
import java.io.PrintWriter
import java.io.PrintWriter
import java.util.Optional
import javax.inject.Inject
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -107,7 +109,7 @@ constructor(
    private val authenticationInteractor: Lazy<AuthenticationInteractor>,
    private val authenticationInteractor: Lazy<AuthenticationInteractor>,
    private val windowController: NotificationShadeWindowController,
    private val windowController: NotificationShadeWindowController,
    private val deviceProvisioningInteractor: DeviceProvisioningInteractor,
    private val deviceProvisioningInteractor: DeviceProvisioningInteractor,
    private val centralSurfaces: CentralSurfaces,
    private val centralSurfacesOptLazy: Lazy<Optional<CentralSurfaces>>,
    private val headsUpInteractor: HeadsUpNotificationInteractor,
    private val headsUpInteractor: HeadsUpNotificationInteractor,
    private val occlusionInteractor: SceneContainerOcclusionInteractor,
    private val occlusionInteractor: SceneContainerOcclusionInteractor,
    private val faceUnlockInteractor: DeviceEntryFaceAuthInteractor,
    private val faceUnlockInteractor: DeviceEntryFaceAuthInteractor,
@@ -115,6 +117,8 @@ constructor(
    private val uiEventLogger: UiEventLogger,
    private val uiEventLogger: UiEventLogger,
    private val sceneBackInteractor: SceneBackInteractor,
    private val sceneBackInteractor: SceneBackInteractor,
) : CoreStartable {
) : CoreStartable {
    private val centralSurfaces: CentralSurfaces?
        get() = centralSurfacesOptLazy.get().getOrNull()


    override fun start() {
    override fun start() {
        if (SceneContainerFlag.isEnabled) {
        if (SceneContainerFlag.isEnabled) {
@@ -542,7 +546,7 @@ constructor(
                }
                }
                .collect { isInteractingOrNull ->
                .collect { isInteractingOrNull ->
                    isInteractingOrNull?.let { isInteracting ->
                    isInteractingOrNull?.let { isInteracting ->
                        centralSurfaces.setInteracting(
                        centralSurfaces?.setInteracting(
                            StatusBarManager.WINDOW_STATUS_BAR,
                            StatusBarManager.WINDOW_STATUS_BAR,
                            isInteracting,
                            isInteracting,
                        )
                        )
Loading