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

Commit 84bf2fea authored by Sherry Zhou's avatar Sherry Zhou
Browse files

Fix notification stack height returning shelfHeight when there's no notficiations at all

Though we can get shelfHeight from NotifStackCalculator, but it should
not happen according to the comment, so we check if there's
notifications by activeNotficationsInteractor

Bug: 404689882
Flag: com.android.systemui.shared.extended_wallpaper_effects
Test: atest SharedNotificationContainerViewModelTest

Change-Id: Ida087275758cba4b0d507a50f49d91fe262046d2
parent ad8d04de
Loading
Loading
Loading
Loading
+103 −15
Original line number Diff line number Diff line
@@ -63,14 +63,16 @@ import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.setTransition
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.domain.interactor.enableDualShade
import com.android.systemui.shade.domain.interactor.enableSingleShade
import com.android.systemui.shade.domain.interactor.enableSplitShade
import com.android.systemui.shade.mockLargeScreenHeaderHelper
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.data.repository.setActiveNotifs
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel.HorizontalPosition
import com.android.systemui.testKosmos
@@ -1356,7 +1358,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S

    @Test
    @DisableSceneContainer
    fun notificationAbsoluteBottom() =
    fun notificationAbsoluteBottom_maxNotificationChanged() =
        testScope.runTest {
            var notificationCount = 2
            val calculateSpace = { _: Float, _: Boolean -> notificationCount }
@@ -1365,24 +1367,22 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
            val calculateHeight = { count: Int -> count * heightForNotification + shelfHeight }
            val stackAbsoluteBottom by
                collectLastValue(
                    underTest.getNotificationStackAbsoluteBottom(
                    underTest.getNotificationStackAbsoluteBottomOnLockscreen(
                        calculateSpace,
                        calculateHeight,
                        shelfHeight,
                    )
                )
            advanceTimeBy(50L)
            kosmos.activeNotificationListRepository.setActiveNotifs(notificationCount)
            showLockscreen()

            shadeTestUtil.setSplitShade(false)
            keyguardInteractor.setNotificationContainerBounds(
                NotificationContainerBounds(top = 100F, bottom = 300F)
            )
            configurationRepository.onAnyConfigurationChange()

            sharedNotificationContainerInteractor.notificationStackChanged()
            advanceTimeBy(50L)
            assertThat(stackAbsoluteBottom).isEqualTo(150F)

            // Also updates when directly requested (as it would from NotificationStackScrollLayout)
            notificationCount = 3
            sharedNotificationContainerInteractor.notificationStackChanged()
            advanceTimeBy(50L)
@@ -1391,36 +1391,124 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S

    @Test
    @DisableSceneContainer
    fun notificationAbsoluteBottom_maxNotificationIsZero_noShelfHeight() =
    fun notificationAbsoluteBottom_noNotificationOnLockscreen() =
        testScope.runTest {
            var notificationCount = 2
            val notificationCount = 0
            val calculateSpace = { _: Float, _: Boolean -> notificationCount }
            val shelfHeight = 10F
            val heightForNotification = 20F
            val calculateHeight = { count: Int -> count * heightForNotification + shelfHeight }
            val stackAbsoluteBottom by
                collectLastValue(
                    underTest.getNotificationStackAbsoluteBottom(
                    underTest.getNotificationStackAbsoluteBottomOnLockscreen(
                        calculateSpace,
                        calculateHeight,
                        shelfHeight,
                    )
                )
            showLockscreen()
            shadeTestUtil.setSplitShade(false)
            keyguardInteractor.setNotificationContainerBounds(
                NotificationContainerBounds(top = 100F, bottom = 300F)
            )
            kosmos.activeNotificationListRepository.setActiveNotifs(notificationCount)
            advanceTimeBy(50L)

            assertThat(stackAbsoluteBottom).isEqualTo(0F)
        }

    @Test
    @DisableSceneContainer
    fun notificationAbsoluteBottomOnLockscreen_heightChangedWithoutMaxNotificationChange() =
        testScope.runTest {
            val notificationCount = 2
            val calculateSpace = { _: Float, _: Boolean -> notificationCount }
            var shelfHeight = 10F
            val heightForNotification = 20F
            val calculateHeight = { count: Int -> count * heightForNotification + shelfHeight }
            val stackAbsoluteBottom by
                collectLastValue(
                    underTest.getNotificationStackAbsoluteBottomOnLockscreen(
                        calculateSpace,
                        calculateHeight,
                    )
                )
            kosmos.activeNotificationListRepository.setActiveNotifs(notificationCount)
            showLockscreen()

            shadeTestUtil.setSplitShade(false)
            keyguardInteractor.setNotificationContainerBounds(
                NotificationContainerBounds(top = 100F, bottom = 300F)
            )
            configurationRepository.onAnyConfigurationChange()

            sharedNotificationContainerInteractor.notificationStackChanged()
            advanceTimeBy(50L)
            assertThat(stackAbsoluteBottom).isEqualTo(150F)

            notificationCount = 0
            shelfHeight = 0f
            sharedNotificationContainerInteractor.notificationStackChanged()
            advanceTimeBy(50L)
            assertThat(stackAbsoluteBottom).isEqualTo(100F)
            assertThat(stackAbsoluteBottom).isEqualTo(140F)
        }

    @Test
    @DisableSceneContainer
    fun notificationAbsoluteBottomOnLockscreen_zeroOnHomescreen() =
        testScope.runTest {
            val calculateSpace = { _: Float, _: Boolean -> -1 }
            val shelfHeight = 10F
            val heightForNotification = 20F
            val calculateHeight = { count: Int -> count * heightForNotification + shelfHeight }
            val stackAbsoluteBottom by
                collectLastValue(
                    underTest.getNotificationStackAbsoluteBottomOnLockscreen(
                        calculateSpace,
                        calculateHeight,
                    )
                )
            advanceTimeBy(50L)

            shadeTestUtil.setSplitShade(false)
            keyguardInteractor.setNotificationContainerBounds(
                NotificationContainerBounds(top = 100F, bottom = 300F)
            )
            kosmos.setTransition(
                sceneTransition = Idle(Scenes.Gone),
                stateTransition = TransitionStep(from = LOCKSCREEN, to = GONE),
            )
            assertThat(stackAbsoluteBottom).isEqualTo(0F)
        }

    @Test
    @DisableSceneContainer
    fun notificationAbsoluteBottom_notReactToHeightChangeOnShade() =
        testScope.runTest {
            val notificationCount = 2
            val calculateSpace = { _: Float, _: Boolean -> notificationCount }
            val shelfHeight = 10F
            val heightForNotification = 20F
            val calculateHeight = { count: Int -> count * heightForNotification + shelfHeight }
            val stackAbsoluteBottom by
                collectLastValue(
                    underTest.getNotificationStackAbsoluteBottomOnLockscreen(
                        calculateSpace,
                        calculateHeight,
                    )
                )
            showLockscreen()
            shadeTestUtil.setSplitShade(false)
            kosmos.activeNotificationListRepository.setActiveNotifs(notificationCount)
            keyguardInteractor.setNotificationContainerBounds(
                NotificationContainerBounds(top = 100F, bottom = 300F)
            )
            advanceTimeBy(50L)
            assertThat(stackAbsoluteBottom).isEqualTo(150F)

            showLockscreenWithQSExpanded()
            keyguardInteractor.setNotificationContainerBounds(
                NotificationContainerBounds(top = 200F, bottom = 300F)
            )
            advanceTimeBy(50L)
            assertThat(stackAbsoluteBottom).isEqualTo(150F)
        }

    @Test
+1 −2
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ constructor(
                        if (extendedWallpaperEffects()) {
                            launch {
                                combine(
                                        viewModel.getNotificationStackAbsoluteBottom(
                                        viewModel.getNotificationStackAbsoluteBottomOnLockscreen(
                                            calculateMaxNotifications = calculateMaxNotifications,
                                            calculateHeight = { maxNotifications ->
                                                notificationStackSizeCalculator.computeHeight(
@@ -157,7 +157,6 @@ constructor(
                                                    stack = controller.view,
                                                )
                                            },
                                            controller.getShelfHeight().toFloat(),
                                        ),
                                        viewModel.configurationBasedDimensions.map { it.marginTop },
                                        ::Pair,
+32 −18
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
import com.android.systemui.shade.shared.model.ShadeMode.Dual
import com.android.systemui.shade.shared.model.ShadeMode.Single
import com.android.systemui.shade.shared.model.ShadeMode.Split
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
@@ -111,6 +112,7 @@ import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
@@ -178,6 +180,7 @@ constructor(
    headsUpNotificationInteractor: Lazy<HeadsUpNotificationInteractor>,
    private val largeScreenHeaderHelperLazy: Lazy<LargeScreenHeaderHelper>,
    unfoldTransitionInteractor: UnfoldTransitionInteractor,
    val activeNotificationsInteractor: ActiveNotificationsInteractor,
) : FlowDumperImpl(dumpManager) {

    /**
@@ -868,32 +871,43 @@ constructor(
     * @param calculateHeight is calling computeHeight in NotificationStackSizeCalculator The edge
     *   case is that when maxNotifications is 0, we won't take shelfHeight into account
     */
    fun getNotificationStackAbsoluteBottom(
    fun getNotificationStackAbsoluteBottomOnLockscreen(
        calculateMaxNotifications: (Float, Boolean) -> Int,
        calculateHeight: (Int) -> Float,
        shelfHeight: Float,
    ): Flow<Float> {
        SceneContainerFlag.assertInLegacyMode()

        return combine(
                getLockscreenDisplayConfig(calculateMaxNotifications).map { (_, maxNotifications) ->
                    val height = calculateHeight(maxNotifications)
                    if (maxNotifications == 0) {
                        height - shelfHeight
                    } else {
                        height
                    }
                activeNotificationsInteractor.areAnyNotificationsPresent,
                isOnLockscreen,
                ::Pair,
            )
            .flatMapLatest { (hasNotifications, isOnLockscreen) ->
                if (hasNotifications && isOnLockscreen) {
                    combine(
                            getLockscreenDisplayConfig(calculateMaxNotifications).map {
                                (_, maxNotifications) ->
                                maxNotifications
                            },
                            bounds.map { it.top },
                            isOnLockscreenWithoutShade,
            ) { height, top, isOnLockscreenWithoutShade ->
                if (isOnLockscreenWithoutShade) {
                            interactor.notificationStackChanged,
                        ) {
                            maxNotifications,
                            top,
                            isOnLockscreenWithoutShade,
                            notificationStackChanged ->
                            if (isOnLockscreenWithoutShade && maxNotifications != -1) {
                                val height = calculateHeight(maxNotifications)
                                top + height
                            } else {
                                null
                            }
                        }
                        .filterNotNull()
                } else {
                    flowOf(0f)
                }
            }
    }

    fun notificationStackChanged() {
+2 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.domain.interactor.shadeModeInteractor
import com.android.systemui.shade.largeScreenHeaderHelper
import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
@@ -116,5 +117,6 @@ val Kosmos.sharedNotificationContainerViewModel by Fixture {
        unfoldTransitionInteractor = unfoldTransitionInteractor,
        glanceableHubToAodTransitionViewModel = glanceableHubToAodTransitionViewModel,
        aodToGlanceableHubTransitionViewModel = aodToGlanceableHubTransitionViewModel,
        activeNotificationsInteractor = activeNotificationsInteractor,
    )
}