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

Commit 4ca49cf8 authored by András Kurucz's avatar András Kurucz Committed by Android (Google) Code Review
Browse files

Merge "[Dual Shade] Clip Notifications by the QS panel" into main

parents 6d2d5f80 c1406cd8
Loading
Loading
Loading
Loading
+31 −2
Original line number Diff line number Diff line
@@ -31,10 +31,14 @@ import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.ContentScope
@@ -59,6 +63,8 @@ import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.ui.composable.Overlay
import com.android.systemui.shade.ui.composable.CollapsedShadeHeader
import com.android.systemui.shade.ui.composable.OverlayShade
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import com.android.systemui.statusbar.phone.ui.StatusBarIconController
@@ -96,13 +102,37 @@ constructor(
    override fun ContentScope.Content(modifier: Modifier) {
        val viewModel =
            rememberViewModel("QuickSettingsShadeOverlay") { contentViewModelFactory.create() }
        val panelCornerRadius =
            with(LocalDensity.current) { OverlayShade.Dimensions.PanelCornerRadius.toPx().toInt() }

        // set the bounds to null when the QuickSettings overlay disappears
        DisposableEffect(Unit) { onDispose { viewModel.onPanelShapeChanged(null) } }

        OverlayShade(
            panelAlignment = Alignment.TopEnd,
            modifier = modifier,
            onScrimClicked = viewModel::onScrimClicked,
        ) {
            Column {
            Column(
                modifier =
                    Modifier.onPlaced { coordinates ->
                        val boundsInWindow = coordinates.boundsInWindow()
                        val shadeScrimBounds =
                            ShadeScrimBounds(
                                left = boundsInWindow.left,
                                top = boundsInWindow.top,
                                right = boundsInWindow.right,
                                bottom = boundsInWindow.bottom,
                            )
                        val shape =
                            ShadeScrimShape(
                                bounds = shadeScrimBounds,
                                topRadius = 0,
                                bottomRadius = panelCornerRadius,
                            )
                        viewModel.onPanelShapeChanged(shape)
                    }
            ) {
                if (viewModel.showHeader) {
                    CollapsedShadeHeader(
                        viewModelFactory = viewModel.shadeHeaderViewModelFactory,
@@ -112,7 +142,6 @@ constructor(
                        statusBarIconController = statusBarIconController,
                    )
                }

                ShadeBody(viewModel = viewModel.quickSettingsContainerViewModel)
            }

+20 −0
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.shared.flag.DualShade
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
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -143,6 +146,23 @@ class QuickSettingsShadeOverlayContentViewModelTest : SysuiTestCase() {
            assertThat(underTest.showHeader).isFalse()
        }

    @Test
    fun onPanelShapeChanged() =
        testScope.runTest {
            val actual by
                collectLastValue(kosmos.notificationStackAppearanceInteractor.qsPanelShape)
            val expected =
                ShadeScrimShape(
                    bounds = ShadeScrimBounds(left = 10f, top = 0f, right = 710f, bottom = 600f),
                    topRadius = 0,
                    bottomRadius = 100,
                )

            underTest.onPanelShapeChanged(expected)

            assertThat(expected).isEqualTo(actual)
        }

    private fun TestScope.lockDevice() {
        val currentScene by collectLastValue(sceneInteractor.currentScene)
        kosmos.powerInteractor.setAsleepForTest()
+4 −3
Original line number Diff line number Diff line
@@ -74,7 +74,8 @@ class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
        testScope.runTest {
            val radius = MutableStateFlow(32)
            val leftOffset = MutableStateFlow(0)
            val shape by collectLastValue(scrollViewModel.shadeScrimShape(radius, leftOffset))
            val shape by
                collectLastValue(scrollViewModel.notificationScrimShape(radius, leftOffset))

            // When: receive scrim bounds
            placeholderViewModel.onScrimBoundsChanged(
@@ -87,7 +88,7 @@ class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
                        bounds =
                            ShadeScrimBounds(left = 0f, top = 200f, right = 100f, bottom = 550f),
                        topRadius = 32,
                        bottomRadius = 0
                        bottomRadius = 0,
                    )
                )

@@ -104,7 +105,7 @@ class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
                        bounds =
                            ShadeScrimBounds(left = 10f, top = 200f, right = 100f, bottom = 550f),
                        topRadius = 24,
                        bottomRadius = 0
                        bottomRadius = 0,
                    )
                )

+36 −20
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.data.repository.shadeRepository
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -40,27 +41,38 @@ class NotificationStackAppearanceInteractorTest : SysuiTestCase() {
    private val underTest = kosmos.notificationStackAppearanceInteractor

    @Test
    fun stackBounds() =
    fun stackNotificationScrimBounds() =
        testScope.runTest {
            val stackBounds by collectLastValue(underTest.shadeScrimBounds)
            val stackBounds by collectLastValue(underTest.notificationShadeScrimBounds)

            val bounds1 =
                ShadeScrimBounds(
                    top = 100f,
                    bottom = 200f,
                )
            underTest.setShadeScrimBounds(bounds1)
            val bounds1 = ShadeScrimBounds(top = 100f, bottom = 200f)
            underTest.setNotificationShadeScrimBounds(bounds1)
            assertThat(stackBounds).isEqualTo(bounds1)

            val bounds2 =
                ShadeScrimBounds(
                    top = 200f,
                    bottom = 300f,
                )
            underTest.setShadeScrimBounds(bounds2)
            val bounds2 = ShadeScrimBounds(top = 200f, bottom = 300f)
            underTest.setNotificationShadeScrimBounds(bounds2)
            assertThat(stackBounds).isEqualTo(bounds2)
        }

    @Test
    fun setQsPanelShape() =
        testScope.runTest {
            val actual by collectLastValue(underTest.qsPanelShape)

            val expected1 =
                ShadeScrimShape(
                    bounds = ShadeScrimBounds(top = 0f, bottom = 100f),
                    topRadius = 0,
                    bottomRadius = 10,
                )
            underTest.setQsPanelShape(expected1)
            assertThat(actual).isEqualTo(expected1)

            val expected2 = expected1.copy(topRadius = 10)
            underTest.setQsPanelShape(expected2)
            assertThat(expected2).isEqualTo(actual)
        }

    @Test
    fun stackRounding() =
        testScope.runTest {
@@ -76,13 +88,17 @@ class NotificationStackAppearanceInteractorTest : SysuiTestCase() {
        }

    @Test(expected = IllegalStateException::class)
    fun setStackBounds_withImproperBounds_throwsException() =
    fun stackNotificationScrimBounds_withImproperBounds_throwsException() =
        testScope.runTest {
            underTest.setShadeScrimBounds(
                ShadeScrimBounds(
                    top = 100f,
                    bottom = 99f,
                )
            underTest.setNotificationShadeScrimBounds(ShadeScrimBounds(top = 100f, bottom = 99f))
        }

    @Test(expected = IllegalStateException::class)
    fun setQsPanelShape_withImproperBounds_throwsException() =
        testScope.runTest {
            val invalidBounds = ShadeScrimBounds(top = 0f, bottom = -10f)
            underTest.setQsPanelShape(
                ShadeScrimShape(bounds = invalidBounds, topRadius = 10, bottomRadius = 10)
            )
        }

+4 −2
Original line number Diff line number Diff line
@@ -38,12 +38,14 @@ class NotificationsPlaceholderViewModelTest : SysuiTestCase() {
    private val underTest by lazy { kosmos.notificationsPlaceholderViewModel }

    @Test
    fun onBoundsChanged() =
    fun onScrimBoundsChanged() =
        kosmos.testScope.runTest {
            val bounds = ShadeScrimBounds(left = 5f, top = 15f, right = 25f, bottom = 35f)
            underTest.onScrimBoundsChanged(bounds)
            val stackBounds by
                collectLastValue(kosmos.notificationStackAppearanceInteractor.shadeScrimBounds)
                collectLastValue(
                    kosmos.notificationStackAppearanceInteractor.notificationShadeScrimBounds
                )
            assertThat(stackBounds).isEqualTo(bounds)
        }
}
Loading