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

Commit 5abaab5c authored by Lyn Han's avatar Lyn Han Committed by Android (Google) Code Review
Browse files

Merge changes I07ca8c06,I4985f1f5 into main

* changes:
  [Dual Shade] Fix unresponsive HUN in unlocked QS
  [Dual Shade] Fix HUN drawbounds in QuickSettingsShadeOverlay
parents 836c20ed d2a2f339
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -51,6 +51,9 @@ import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.toAndroidRectF
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.painterResource
@@ -78,6 +81,7 @@ import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.media.remedia.ui.compose.Media
import com.android.systemui.media.remedia.ui.compose.MediaPresentationStyle
import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace
import com.android.systemui.notifications.ui.composable.headsUpTopInset
import com.android.systemui.qs.composefragment.ui.GridAnchor
import com.android.systemui.qs.flags.QsDetailedView
import com.android.systemui.qs.panels.ui.compose.EditMode
@@ -158,6 +162,7 @@ constructor(
            quickSettingsContainerViewModel.brightnessSliderViewModel.showMirror
        val contentAlphaFromBrightnessMirror by
            animateFloatAsState(if (showBrightnessMirror) 0f else 1f)
        val headsUpInset = with(LocalDensity.current) { headsUpTopInset().toPx() }

        val targetBlurRadiusPx: Float by
            remember(layoutState) {
@@ -228,6 +233,15 @@ constructor(
                },
                stackScrollView = notificationStackScrollView.get(),
                viewModel = hunPlaceholderViewModel,
                modifier = Modifier.onGloballyPositioned { layoutCoordinates ->
                    val bounds = layoutCoordinates.boundsInWindow().toAndroidRectF()
                    if (bounds.height() > 0) {
                        // HUN gesture area must extend from the top of the screen for animations
                        bounds.top = 0f
                        bounds.bottom += headsUpInset
                        notificationStackScrollView.get().updateDrawBounds(bounds)
                    }
                }
            )
        }
    }
+68 −1
Original line number Diff line number Diff line
@@ -25,11 +25,16 @@ import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.scene.domain.startable.sceneContainerStartable
import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
import com.android.systemui.shade.domain.interactor.disableDualShade
import com.android.systemui.shade.domain.interactor.enableDualShade
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.statusbar.notification.data.repository.UnconfinedFakeHeadsUpRowRepository
import com.android.systemui.statusbar.notification.headsup.PinnedStatus
import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
@@ -37,6 +42,7 @@ import com.android.systemui.testKosmos
import com.android.systemui.util.state.SynchronouslyObservableState
import com.android.systemui.util.state.observableStateOf
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -46,9 +52,15 @@ import org.junit.runner.RunWith
@EnableSceneContainer
class NotificationScrollViewModelTest : SysuiTestCase() {

    private val kosmos = testKosmos()
    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
    private val Kosmos.underTest by Kosmos.Fixture { notificationScrollViewModel }

    private val fakePinnedHun =
        UnconfinedFakeHeadsUpRowRepository(
            key = "test_hun",
            pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
        )

    @Before
    fun setUp() =
        with(kosmos) {
@@ -152,4 +164,59 @@ class NotificationScrollViewModelTest : SysuiTestCase() {
            brightnessMirrorShowingInteractor.setMirrorShowing(true)
            assertThat(interactive).isFalse()
        }

    @Test
    fun interactive_whenBlurredAndHunIsPinned_isTrue() =
        kosmos.runTest {
            val interactive by collectLastValue(underTest.interactive)
            brightnessMirrorShowingInteractor.setMirrorShowing(false)

            // GIVEN the background is blurred and a HUN is pinned
            setBlur(true)
            setHunIsPinned(true)

            // THEN the notification stack is interactive (because of the HUN)
            assertThat(interactive).isTrue()
        }

    @Test
    fun interactive_whenBlurredAndNoHun_isFalse() =
        kosmos.runTest {
            val interactive by collectLastValue(underTest.interactive)
            brightnessMirrorShowingInteractor.setMirrorShowing(false)

            // GIVEN the background is blurred and no HUN is pinned
            setBlur(true)
            setHunIsPinned(false)

            // THEN the notification stack is NOT interactive
            assertThat(interactive).isFalse()
        }

    @Test
    fun interactive_whenNotBlurredAndHunIsPinned_isTrue() =
        kosmos.runTest {
            val interactive by collectLastValue(underTest.interactive)
            brightnessMirrorShowingInteractor.setMirrorShowing(false)

            // GIVEN the background is not blurred but a HUN is still pinned
            setBlur(false)
            setHunIsPinned(true)

            // THEN the notification stack is interactive
            assertThat(interactive).isTrue()
        }

    private fun Kosmos.setBlur(isBlurred: Boolean) {
        val expansion = if (isBlurred) 1f else 0f
        shadeTestUtil.setQsExpansion(expansion)
    }

    private fun Kosmos.setHunIsPinned(isPinned: Boolean) {
        if (isPinned) {
            headsUpNotificationRepository.setNotifications(listOf(fakePinnedHun))
        } else {
            headsUpNotificationRepository.setNotifications(emptyList())
        }
    }
}
+9 −3
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.LockscreenDisplayConfig
import com.android.systemui.statusbar.notification.stack.domain.interactor.LockscreenNotificationDisplayConfigInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
@@ -80,6 +81,7 @@ constructor(
    shadeModeInteractor: ShadeModeInteractor,
    bouncerInteractor: BouncerInteractor,
    private val remoteInputInteractor: RemoteInputInteractor,
    private val headsUpNotificationInteractor: HeadsUpNotificationInteractor,
    sceneInteractor: SceneInteractor,
    // TODO(b/336364825) Remove Lazy when SceneContainerFlag is released -
    // while the flag is off, creating this object too early results in a crash
@@ -263,8 +265,12 @@ constructor(
     * scene container will handle touches.
     */
    val interactive: Flow<Boolean> =
        combine(blurFraction, brightnessMirrorShowing) { blurFraction, brightnessMirrorShowing ->
                blurFraction != 1f && !brightnessMirrorShowing
        combine(
            blurFraction,
            brightnessMirrorShowing,
            headsUpNotificationInteractor.hasPinnedRows,
        ) { blurFraction, brightnessMirrorShowing, hasPinnedHun ->
            (blurFraction != 1f || hasPinnedHun) && !brightnessMirrorShowing
        }
            .distinctUntilChanged()
            .dumpWhileCollecting("interactive")
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.settings.brightness.domain.interactor.brightnessMirr
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.domain.interactor.shadeModeInteractor
import com.android.systemui.statusbar.domain.interactor.remoteInputInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.lockscreenNotificationDisplayConfigInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor

@@ -39,6 +40,7 @@ val Kosmos.notificationScrollViewModel by Fixture {
        shadeModeInteractor = shadeModeInteractor,
        bouncerInteractor = bouncerInteractor,
        remoteInputInteractor = remoteInputInteractor,
        headsUpNotificationInteractor = headsUpNotificationInteractor,
        sceneInteractor = sceneInteractor,
        keyguardInteractor = { keyguardInteractor },
    )