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

Commit f6bd0528 authored by Julia Tuttle's avatar Julia Tuttle Committed by Android (Google) Code Review
Browse files

Merge "Flexiglass: fix erroneously-split shade at boot" into main

parents 1dc809a4 6a5612bc
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -22,13 +22,13 @@ import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.testKosmos
import com.google.common.truth.Truth
import com.google.common.truth.Truth.assertThat
@@ -43,6 +43,7 @@ import org.junit.runner.RunWith
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableSceneContainer
class ShadeInteractorSceneContainerImplTest : SysuiTestCase() {

    private val kosmos = testKosmos()
@@ -50,7 +51,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() {
    private val configurationRepository = kosmos.fakeConfigurationRepository
    private val keyguardRepository = kosmos.fakeKeyguardRepository
    private val sceneInteractor = kosmos.sceneInteractor
    private val shadeRepository = kosmos.shadeRepository
    private val shadeTestUtil = kosmos.shadeTestUtil

    private val underTest = kosmos.shadeInteractorSceneContainerImpl

@@ -60,7 +61,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() {
            val actual by collectLastValue(underTest.qsExpansion)

            // WHEN split shade is enabled and QS is expanded
            overrideResource(R.bool.config_use_split_notification_shade, true)
            shadeTestUtil.setSplitShade(true)
            configurationRepository.onAnyConfigurationChange()
            runCurrent()
            val transitionState =
@@ -89,7 +90,7 @@ class ShadeInteractorSceneContainerImplTest : SysuiTestCase() {

            // WHEN split shade is not enabled and QS is expanded
            keyguardRepository.setStatusBarState(StatusBarState.SHADE)
            overrideResource(R.bool.config_use_split_notification_shade, false)
            shadeTestUtil.setSplitShade(false)
            configurationRepository.onAnyConfigurationChange()
            runCurrent()
            val progress = MutableStateFlow(.3f)
+15 −11
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.systemui.keyguard.ui.viewmodel.aodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.keyguardRootViewModel
import com.android.systemui.kosmos.testScope
import com.android.systemui.res.R
import com.android.systemui.shade.data.repository.fakeShadeRepository
import com.android.systemui.shade.mockLargeScreenHeaderHelper
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
@@ -135,11 +136,14 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
    val communalSceneRepository
        get() = kosmos.communalSceneRepository

    val shadeRepository
        get() = kosmos.fakeShadeRepository

    lateinit var underTest: SharedNotificationContainerViewModel

    @Before
    fun setUp() {
        overrideResource(R.bool.config_use_split_notification_shade, false)
        shadeTestUtil.setSplitShade(false)
        movementFlow = MutableStateFlow(BurnInModel())
        whenever(aodBurnInViewModel.movement(any())).thenReturn(movementFlow)
        underTest = kosmos.sharedNotificationContainerViewModel
@@ -148,7 +152,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
    @Test
    fun validateMarginStartInSplitShade() =
        testScope.runTest {
            overrideResource(R.bool.config_use_split_notification_shade, true)
            shadeTestUtil.setSplitShade(true)
            overrideResource(R.dimen.notification_panel_margin_horizontal, 20)

            val dimens by collectLastValue(underTest.configurationBasedDimensions)
@@ -161,7 +165,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
    @Test
    fun validateMarginStart() =
        testScope.runTest {
            overrideResource(R.bool.config_use_split_notification_shade, false)
            shadeTestUtil.setSplitShade(false)
            overrideResource(R.dimen.notification_panel_margin_horizontal, 20)

            val dimens by collectLastValue(underTest.configurationBasedDimensions)
@@ -175,7 +179,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
    fun validatePaddingTopInSplitShade_usesLargeHeaderHelper() =
        testScope.runTest {
            whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(5)
            overrideResource(R.bool.config_use_split_notification_shade, true)
            shadeTestUtil.setSplitShade(true)
            overrideResource(R.bool.config_use_large_screen_shade_header, true)
            overrideResource(R.dimen.large_screen_shade_header_height, 10)
            overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
@@ -191,7 +195,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
    fun validatePaddingTopInNonSplitShade_usesLargeScreenHeader() =
        testScope.runTest {
            whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(10)
            overrideResource(R.bool.config_use_split_notification_shade, false)
            shadeTestUtil.setSplitShade(false)
            overrideResource(R.bool.config_use_large_screen_shade_header, true)
            overrideResource(R.dimen.large_screen_shade_header_height, 10)
            overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
@@ -207,7 +211,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
    fun validatePaddingTopInNonSplitShade_doesNotUseLargeScreenHeader() =
        testScope.runTest {
            whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(10)
            overrideResource(R.bool.config_use_split_notification_shade, false)
            shadeTestUtil.setSplitShade(false)
            overrideResource(R.bool.config_use_large_screen_shade_header, false)
            overrideResource(R.dimen.large_screen_shade_header_height, 10)
            overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
@@ -508,7 +512,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
            val bounds by collectLastValue(underTest.bounds)

            // When not in split shade
            overrideResource(R.bool.config_use_split_notification_shade, false)
            shadeTestUtil.setSplitShade(false)
            configurationRepository.onAnyConfigurationChange()
            runCurrent()

@@ -567,7 +571,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S

            // When in split shade
            whenever(largeScreenHeaderHelper.getLargeScreenHeaderHeight()).thenReturn(5)
            overrideResource(R.bool.config_use_split_notification_shade, true)
            shadeTestUtil.setSplitShade(true)
            overrideResource(R.bool.config_use_large_screen_shade_header, true)
            overrideResource(R.dimen.large_screen_shade_header_height, 10)
            overrideResource(R.dimen.keyguard_split_shade_top_margin, 50)
@@ -628,7 +632,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
            advanceTimeBy(50L)
            showLockscreen()

            overrideResource(R.bool.config_use_split_notification_shade, false)
            shadeTestUtil.setSplitShade(false)
            configurationRepository.onAnyConfigurationChange()

            assertThat(maxNotifications).isEqualTo(10)
@@ -656,7 +660,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
            advanceTimeBy(50L)
            showLockscreen()

            overrideResource(R.bool.config_use_split_notification_shade, false)
            shadeTestUtil.setSplitShade(false)
            configurationRepository.onAnyConfigurationChange()

            assertThat(maxNotifications).isEqualTo(10)
@@ -690,7 +694,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
            // Show lockscreen with shade expanded
            showLockscreenWithShadeExpanded()

            overrideResource(R.bool.config_use_split_notification_shade, false)
            shadeTestUtil.setSplitShade(false)
            configurationRepository.onAnyConfigurationChange()

            // -1 means No Limit
+5 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import javax.inject.Inject
@@ -46,6 +47,10 @@ constructor(
    sharedNotificationContainerInteractor: SharedNotificationContainerInteractor,
    repository: ShadeRepository,
) : BaseShadeInteractor {
    init {
        SceneContainerFlag.assertInLegacyMode()
    }

    /**
     * The amount [0-1] that the shade has been opened. Uses stateIn to avoid redundant calculations
     * in downstream flows.
+8 −3
Original line number Diff line number Diff line
@@ -22,8 +22,9 @@ import com.android.compose.animation.scene.SceneKey
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -43,8 +44,12 @@ class ShadeInteractorSceneContainerImpl
constructor(
    @Application scope: CoroutineScope,
    sceneInteractor: SceneInteractor,
    sharedNotificationContainerInteractor: SharedNotificationContainerInteractor,
    shadeRepository: ShadeRepository,
) : BaseShadeInteractor {
    init {
        SceneContainerFlag.assertInNewMode()
    }

    override val shadeExpansion: StateFlow<Float> =
        sceneBasedExpansion(sceneInteractor, SceneFamilies.NotifShade)
            .traceAsCounter("panel_expansion") { (it * 100f).toInt() }
@@ -55,7 +60,7 @@ constructor(

    override val qsExpansion: StateFlow<Float> =
        combine(
                sharedNotificationContainerInteractor.isSplitShadeEnabled,
                shadeRepository.isShadeLayoutWide,
                shadeExpansion,
                sceneBasedQsExpansion,
            ) { isSplitShadeEnabled, shadeExpansion, qsExpansion ->
+28 −8
Original line number Diff line number Diff line
@@ -23,7 +23,9 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.LargeScreenHeaderHelper
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.policy.SplitShadeStateController
import dagger.Lazy
import javax.inject.Inject
@@ -43,7 +45,8 @@ class SharedNotificationContainerInteractor
constructor(
    configurationRepository: ConfigurationRepository,
    private val context: Context,
    private val splitShadeStateController: SplitShadeStateController,
    private val splitShadeStateController: Lazy<SplitShadeStateController>,
    private val shadeInteractor: Lazy<ShadeInteractor>,
    keyguardInteractor: KeyguardInteractor,
    deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
    largeScreenHeaderHelperLazy: Lazy<LargeScreenHeaderHelper>,
@@ -56,16 +59,33 @@ constructor(
    /** An internal modification was made to notifications */
    val notificationStackChanged = _notificationStackChanged.debounce(20L)

    private val configurationChangeEvents =
        configurationRepository.onAnyConfigurationChange.onStart { emit(Unit) }

    /* Warning: Even though the value it emits only contains the split shade status, this flow must
     * emit a value whenever the configuration *or* the split shade status changes. Adding a
     * distinctUntilChanged() to this would cause configurationBasedDimensions to miss configuration
     * updates that affect other resources, like margins or the large screen header flag.
     */
    private val dimensionsUpdateEventsWithShouldUseSplitShade: Flow<Boolean> =
        if (SceneContainerFlag.isEnabled) {
            combine(configurationChangeEvents, shadeInteractor.get().isShadeLayoutWide) {
                _,
                isShadeLayoutWide ->
                isShadeLayoutWide
            }
        } else {
            configurationChangeEvents.map {
                splitShadeStateController.get().shouldUseSplitNotificationShade(context.resources)
            }
        }

    val configurationBasedDimensions: Flow<ConfigurationBasedDimensions> =
        configurationRepository.onAnyConfigurationChange
            .onStart { emit(Unit) }
            .map { _ ->
        dimensionsUpdateEventsWithShouldUseSplitShade
            .map { shouldUseSplitShade ->
                with(context.resources) {
                    ConfigurationBasedDimensions(
                        useSplitShade =
                            splitShadeStateController.shouldUseSplitNotificationShade(
                                context.resources
                            ),
                        useSplitShade = shouldUseSplitShade,
                        useLargeScreenHeader =
                            getBoolean(R.bool.config_use_large_screen_shade_header),
                        marginHorizontal =
Loading