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

Commit cdeb4bb5 authored by Lucas Silva's avatar Lucas Silva
Browse files

Remove custom timeout logic from hub v2

In v2, we can let PowerManagerService handle the timeout behavior since
we no longer keep the dream active underneath the hub.

Bug: 394915563
Test: atest CommunalSceneStartableTest
Flag: com.android.systemui.glanceable_hub_v2
Change-Id: I24d7db4c09e17a4852cbc9d842352904ba4527fc
parent fad62f2c
Loading
Loading
Loading
Loading
+259 −281
Original line number Diff line number Diff line
@@ -24,45 +24,47 @@ import android.provider.Settings
import androidx.test.filters.SmallTest
import com.android.internal.logging.uiEventLoggerFake
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled
import com.android.systemui.communal.shared.log.CommunalUiEvent
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.dock.dockManager
import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.notificationShadeWindowController
import com.android.systemui.statusbar.phone.centralSurfacesOptional
import com.android.systemui.testKosmos
import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth.assertThat
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
import platform.test.runner.parameterized.Parameters

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(ParameterizedAndroidJunit4::class)
@EnableFlags(FLAG_COMMUNAL_HUB)
@@ -74,7 +76,8 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
        @JvmStatic
        @Parameters(name = "{0}")
        fun getParams(): List<FlagsParameterization> {
            return FlagsParameterization.allCombinationsOf().andSceneContainer()
            return FlagsParameterization.allCombinationsOf(FLAG_GLANCEABLE_HUB_V2)
                .andSceneContainer()
        }
    }

@@ -82,54 +85,48 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
        mSetFlagsRule.setFlagsParameterization(flags)
    }

    private val kosmos = testKosmos()
    private val kosmos = testKosmos().useUnconfinedTestDispatcher()

    private lateinit var underTest: CommunalSceneStartable

    @Before
    fun setUp() {
        with(kosmos) {
            fakeSettings.putIntForUser(
                Settings.System.SCREEN_OFF_TIMEOUT,
                SCREEN_TIMEOUT,
                UserHandle.USER_CURRENT,
            )
            kosmos.fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)

            underTest =
    private val Kosmos.underTest by
        Kosmos.Fixture {
            CommunalSceneStartable(
                        dockManager = dockManager,
                communalInteractor = communalInteractor,
                communalSettingsInteractor = communalSettingsInteractor,
                communalSceneInteractor = communalSceneInteractor,
                        keyguardTransitionInteractor = keyguardTransitionInteractor,
                keyguardInteractor = keyguardInteractor,
                systemSettings = fakeSettings,
                notificationShadeWindowController = notificationShadeWindowController,
                        applicationScope = applicationCoroutineScope,
                bgScope = applicationCoroutineScope,
                mainDispatcher = testDispatcher,
                        centralSurfacesOpt = centralSurfacesOptional,
                uiEventLogger = uiEventLoggerFake,
            )
                    .apply { start() }
        }

    @Before
    fun setUp() {
        with(kosmos) {
            fakeSettings.putIntForUser(
                Settings.System.SCREEN_OFF_TIMEOUT,
                SCREEN_TIMEOUT,
                UserHandle.USER_CURRENT,
            )
            fakeFeatureFlagsClassic.set(COMMUNAL_SERVICE_ENABLED, true)

            underTest.start()

            // Make communal available so that communalInteractor.desiredScene accurately reflects
            // scene changes instead of just returning Blank.
            with(kosmos.testScope) {
                launch { setCommunalAvailable(true) }
                testScheduler.runCurrent()
            }
            runBlocking { setCommunalAvailable(true) }
            setCommunalV2ConfigEnabled(true)
        }
    }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_SCENE_CONTAINER, FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_whenDreaming_goesToBlank() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is dreaming and on communal.
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            val scene by collectLastValue(communalSceneInteractor.currentScene)
@@ -139,15 +136,13 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
            advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
            assertThat(scene).isEqualTo(CommunalScenes.Blank)
        }
        }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_SCENE_CONTAINER, FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_notDreaming_staysOnCommunal() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is not dreaming and on communal.
                updateDreaming(false)
            fakeKeyguardRepository.setDreaming(false)
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            // Scene stays as Communal
@@ -155,15 +150,13 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
            val scene by collectLastValue(communalSceneInteractor.currentScene)
            assertThat(scene).isEqualTo(CommunalScenes.Communal)
        }
        }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_SCENE_CONTAINER, FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_dreamStopped_staysOnCommunal() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is dreaming and on communal.
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            val scene by collectLastValue(communalSceneInteractor.currentScene)
@@ -175,19 +168,17 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()

            // Dream stops, timeout is cancelled and device stays on hub, because the regular
            // screen timeout will take effect at this point.
                updateDreaming(false)
            fakeKeyguardRepository.setDreaming(false)
            advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
            assertThat(scene).isEqualTo(CommunalScenes.Communal)
        }
        }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_SCENE_CONTAINER, FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_dreamStartedHalfway_goesToCommunal() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is on communal, but not dreaming.
                updateDreaming(false)
            fakeKeyguardRepository.setDreaming(false)
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            val scene by collectLastValue(communalSceneInteractor.currentScene)
@@ -195,44 +186,40 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()

            // Wait a bit, but not long enough to timeout, then start dreaming.
            advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            assertThat(scene).isEqualTo(CommunalScenes.Communal)

            // Device times out after one screen timeout interval, dream doesn't reset timeout.
            advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
            assertThat(scene).isEqualTo(CommunalScenes.Blank)
        }
        }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_SCENE_CONTAINER, FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_dreamAfterInitialTimeout_goesToBlank() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is on communal.
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            // Device stays on the hub after the timeout since we're not dreaming.
                advanceTimeBy(SCREEN_TIMEOUT.milliseconds * 2)
            testScope.advanceTimeBy(SCREEN_TIMEOUT.milliseconds * 2)
            val scene by collectLastValue(communalSceneInteractor.currentScene)
            assertThat(scene).isEqualTo(CommunalScenes.Communal)

            // Start dreaming.
                updateDreaming(true)
                advanceTimeBy(KeyguardInteractor.IS_ABLE_TO_DREAM_DELAY_MS)
            fakeKeyguardRepository.setDreaming(true)
            advanceTimeBy(KeyguardInteractor.IS_ABLE_TO_DREAM_DELAY_MS.milliseconds)

            // Hub times out immediately.
            assertThat(scene).isEqualTo(CommunalScenes.Blank)
        }
        }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_SCENE_CONTAINER, FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_userActivityTriggered_resetsTimeout() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is dreaming and on communal.
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            val scene by collectLastValue(communalSceneInteractor.currentScene)
@@ -252,17 +239,15 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
            advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
            assertThat(scene).isEqualTo(CommunalScenes.Blank)
        }
        }

    @Test
    @DisableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_SCENE_CONTAINER, FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_screenTimeoutChanged() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            fakeSettings.putInt(Settings.System.SCREEN_OFF_TIMEOUT, SCREEN_TIMEOUT * 2)

            // Device is dreaming and on communal.
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")

            val scene by collectLastValue(communalSceneInteractor.currentScene)
@@ -278,15 +263,14 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
                .isEqualTo(CommunalUiEvent.COMMUNAL_HUB_TIMEOUT.id)
            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
        }
        }

    @Test
    @EnableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_withSceneContainer_whenDreaming_goesToBlank() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is dreaming and on communal.
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            sceneInteractor.changeScene(Scenes.Communal, "test")

            val scene by collectLastValue(sceneInteractor.currentScene)
@@ -296,15 +280,14 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
            advanceTimeBy(SCREEN_TIMEOUT.milliseconds)
            assertThat(scene).isEqualTo(Scenes.Dream)
        }
        }

    @Test
    @EnableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_withSceneContainer_notDreaming_staysOnCommunal() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is not dreaming and on communal.
                updateDreaming(false)
            fakeKeyguardRepository.setDreaming(false)
            sceneInteractor.changeScene(Scenes.Communal, "test")

            // Scene stays as Communal
@@ -312,15 +295,14 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
            val scene by collectLastValue(sceneInteractor.currentScene)
            assertThat(scene).isEqualTo(Scenes.Communal)
        }
        }

    @Test
    @EnableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_withSceneContainer_dreamStopped_staysOnCommunal() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is dreaming and on communal.
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            sceneInteractor.changeScene(Scenes.Communal, "test")

            val scene by collectLastValue(sceneInteractor.currentScene)
@@ -332,19 +314,18 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()

            // Dream stops, timeout is cancelled and device stays on hub, because the regular
            // screen timeout will take effect at this point.
                updateDreaming(false)
            fakeKeyguardRepository.setDreaming(false)
            advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
            assertThat(scene).isEqualTo(Scenes.Communal)
        }
        }

    @Test
    @EnableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_withSceneContainer_dreamStartedHalfway_goesToCommunal() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is on communal, but not dreaming.
                updateDreaming(false)
            fakeKeyguardRepository.setDreaming(false)
            sceneInteractor.changeScene(Scenes.Communal, "test")

            val scene by collectLastValue(sceneInteractor.currentScene)
@@ -352,20 +333,19 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()

            // Wait a bit, but not long enough to timeout, then start dreaming.
            advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            assertThat(scene).isEqualTo(Scenes.Communal)

            // Device times out after one screen timeout interval, dream doesn't reset timeout.
            advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
            assertThat(scene).isEqualTo(Scenes.Dream)
        }
        }

    @Test
    @EnableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_withSceneContainer_dreamAfterInitialTimeout_goesToBlank() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is on communal.
            sceneInteractor.changeScene(Scenes.Communal, "test")

@@ -375,21 +355,20 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
            assertThat(scene).isEqualTo(Scenes.Communal)

            // Start dreaming.
                updateDreaming(true)
                advanceTimeBy(KeyguardInteractor.IS_ABLE_TO_DREAM_DELAY_MS)
            fakeKeyguardRepository.setDreaming(true)
            advanceTimeBy(KeyguardInteractor.IS_ABLE_TO_DREAM_DELAY_MS.milliseconds)

            // Hub times out immediately.
            assertThat(scene).isEqualTo(Scenes.Dream)
        }
        }

    @Test
    @EnableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_withSceneContainer_userActivityTriggered_resetsTimeout() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            // Device is dreaming and on communal.
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            sceneInteractor.changeScene(Scenes.Communal, "test")

            val scene by collectLastValue(sceneInteractor.currentScene)
@@ -409,17 +388,16 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
            advanceTimeBy((SCREEN_TIMEOUT / 2).milliseconds)
            assertThat(scene).isEqualTo(Scenes.Dream)
        }
        }

    @Test
    @EnableFlags(FLAG_SCENE_CONTAINER)
    @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun hubTimeout_withSceneContainer_screenTimeoutChanged() =
        with(kosmos) {
            testScope.runTest {
        kosmos.runTest {
            fakeSettings.putInt(Settings.System.SCREEN_OFF_TIMEOUT, SCREEN_TIMEOUT * 2)

            // Device is dreaming and on communal.
                updateDreaming(true)
            fakeKeyguardRepository.setDreaming(true)
            sceneInteractor.changeScene(Scenes.Communal, "test")

            val scene by collectLastValue(sceneInteractor.currentScene)
@@ -435,11 +413,11 @@ class CommunalSceneStartableTest(flags: FlagsParameterization) : SysuiTestCase()
                .isEqualTo(CommunalUiEvent.COMMUNAL_HUB_TIMEOUT.id)
            assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
        }
        }

    private fun TestScope.updateDreaming(dreaming: Boolean) =
        with(kosmos) {
            fakeKeyguardRepository.setDreaming(dreaming)
            runCurrent()
        }
    /**
     * Advances time by duration + 1 millisecond, to ensure that tasks scheduled to run at
     * currentTime + duration are scheduled.
     */
    private fun Kosmos.advanceTimeBy(duration: Duration) =
        testScope.advanceTimeBy(duration + 1.milliseconds)
}
+68 −115

File changed.

Preview size limit exceeded, changes collapsed.