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

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

Merge "[flexiglass] Makes window focusable." into main

parents fce3e66f b9217cc6
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -265,7 +265,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
                powerInteractor = powerInteractor,
                powerInteractor = powerInteractor,
                bouncerInteractor = bouncerInteractor,
                bouncerInteractor = bouncerInteractor,
                simBouncerInteractor = dagger.Lazy { utils.simBouncerInteractor },
                simBouncerInteractor = dagger.Lazy { utils.simBouncerInteractor },
                authenticationInteractor = dagger.Lazy { utils.authenticationInteractor() }
                authenticationInteractor = dagger.Lazy { utils.authenticationInteractor() },
                windowController = mock(),
            )
            )
        startable.start()
        startable.start()


+83 −16
Original line number Original line Diff line number Diff line
@@ -37,6 +37,7 @@ import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.ObservableTransitionState
import com.android.systemui.scene.shared.model.ObservableTransitionState
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -46,18 +47,24 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.TestScope
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
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.Mock
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.never
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations


@SmallTest
@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWith(AndroidJUnit4::class)
@EnableFlags(AconfigFlags.FLAG_SCENE_CONTAINER)
@EnableFlags(AconfigFlags.FLAG_SCENE_CONTAINER)
class SceneContainerStartableTest : SysuiTestCase() {
class SceneContainerStartableTest : SysuiTestCase() {


    @Mock private lateinit var windowController: NotificationShadeWindowController

    private val utils = SceneTestUtils(this)
    private val utils = SceneTestUtils(this)
    private val testScope = utils.testScope
    private val testScope = utils.testScope
    private val sceneInteractor = utils.sceneInteractor()
    private val sceneInteractor = utils.sceneInteractor()
@@ -77,7 +84,13 @@ class SceneContainerStartableTest : SysuiTestCase() {
    private val falsingCollector: FalsingCollector = mock()
    private val falsingCollector: FalsingCollector = mock()
    private val powerInteractor = PowerInteractorFactory.create().powerInteractor
    private val powerInteractor = PowerInteractorFactory.create().powerInteractor


    private val underTest =
    private lateinit var underTest: SceneContainerStartable

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)

        underTest =
            SceneContainerStartable(
            SceneContainerStartable(
                applicationScope = testScope.backgroundScope,
                applicationScope = testScope.backgroundScope,
                sceneInteractor = sceneInteractor,
                sceneInteractor = sceneInteractor,
@@ -92,7 +105,9 @@ class SceneContainerStartableTest : SysuiTestCase() {
                bouncerInteractor = bouncerInteractor,
                bouncerInteractor = bouncerInteractor,
                simBouncerInteractor = dagger.Lazy { utils.simBouncerInteractor },
                simBouncerInteractor = dagger.Lazy { utils.simBouncerInteractor },
                authenticationInteractor = dagger.Lazy { authenticationInteractor },
                authenticationInteractor = dagger.Lazy { authenticationInteractor },
                windowController = windowController,
            )
            )
    }


    @Test
    @Test
    fun hydrateVisibility() =
    fun hydrateVisibility() =
@@ -655,6 +670,58 @@ class SceneContainerStartableTest : SysuiTestCase() {
            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
            assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
        }
        }


    @Test
    fun hydrateWindowFocus() =
        testScope.runTest {
            val currentDesiredSceneKey by
                collectLastValue(sceneInteractor.desiredScene.map { it.key })
            val transitionStateFlow =
                prepareState(
                    isDeviceUnlocked = true,
                    initialSceneKey = SceneKey.Gone,
                )
            assertThat(currentDesiredSceneKey).isEqualTo(SceneKey.Gone)
            verify(windowController, never()).setNotificationShadeFocusable(anyBoolean())

            underTest.start()
            runCurrent()
            verify(windowController, times(1)).setNotificationShadeFocusable(false)

            sceneInteractor.changeScene(SceneModel(SceneKey.Shade), "reason")
            transitionStateFlow.value =
                ObservableTransitionState.Transition(
                    fromScene = SceneKey.Gone,
                    toScene = SceneKey.Shade,
                    progress = flowOf(0.5f),
                    isInitiatedByUserInput = false,
                    isUserInputOngoing = flowOf(false),
                )
            runCurrent()
            verify(windowController, times(1)).setNotificationShadeFocusable(false)

            sceneInteractor.onSceneChanged(SceneModel(SceneKey.Shade), "reason")
            transitionStateFlow.value = ObservableTransitionState.Idle(SceneKey.Shade)
            runCurrent()
            verify(windowController, times(1)).setNotificationShadeFocusable(true)

            sceneInteractor.changeScene(SceneModel(SceneKey.Gone), "reason")
            transitionStateFlow.value =
                ObservableTransitionState.Transition(
                    fromScene = SceneKey.Shade,
                    toScene = SceneKey.Gone,
                    progress = flowOf(0.5f),
                    isInitiatedByUserInput = false,
                    isUserInputOngoing = flowOf(false),
                )
            runCurrent()
            verify(windowController, times(1)).setNotificationShadeFocusable(true)

            sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone), "reason")
            transitionStateFlow.value = ObservableTransitionState.Idle(SceneKey.Gone)
            runCurrent()
            verify(windowController, times(2)).setNotificationShadeFocusable(false)
        }

    private fun TestScope.prepareState(
    private fun TestScope.prepareState(
        isDeviceUnlocked: Boolean = false,
        isDeviceUnlocked: Boolean = false,
        isBypassEnabled: Boolean = false,
        isBypassEnabled: Boolean = false,
+17 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICA
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import com.android.systemui.util.asIndenting
import com.android.systemui.util.asIndenting
import com.android.systemui.util.printSection
import com.android.systemui.util.printSection
@@ -83,6 +84,7 @@ constructor(
    private val powerInteractor: PowerInteractor,
    private val powerInteractor: PowerInteractor,
    private val simBouncerInteractor: Lazy<SimBouncerInteractor>,
    private val simBouncerInteractor: Lazy<SimBouncerInteractor>,
    private val authenticationInteractor: Lazy<AuthenticationInteractor>,
    private val authenticationInteractor: Lazy<AuthenticationInteractor>,
    private val windowController: NotificationShadeWindowController,
) : CoreStartable {
) : CoreStartable {


    override fun start() {
    override fun start() {
@@ -92,6 +94,7 @@ constructor(
            automaticallySwitchScenes()
            automaticallySwitchScenes()
            hydrateSystemUiState()
            hydrateSystemUiState()
            collectFalsingSignals()
            collectFalsingSignals()
            hydrateWindowFocus()
        } else {
        } else {
            sceneLogger.logFrameworkEnabled(
            sceneLogger.logFrameworkEnabled(
                isEnabled = false,
                isEnabled = false,
@@ -348,6 +351,20 @@ 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 != SceneKey.Gone)
                }
        }
    }

    private fun switchToScene(targetSceneKey: SceneKey, loggingReason: String) {
    private fun switchToScene(targetSceneKey: SceneKey, loggingReason: String) {
        sceneInteractor.changeScene(
        sceneInteractor.changeScene(
            scene = SceneModel(targetSceneKey),
            scene = SceneModel(targetSceneKey),