Loading packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt +1 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ constructor( OverlayShade( panelElement = NotificationsShade.Elements.Panel, alignmentOnWideScreens = Alignment.TopStart, enableTransparency = viewModel.isTransparencyEnabled, modifier = modifier, onScrimClicked = viewModel::onScrimClicked, header = { Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt +3 −1 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ constructor( OverlayShade( panelElement = QuickSettingsShade.Elements.Panel, alignmentOnWideScreens = Alignment.TopEnd, enableTransparency = quickSettingsContainerViewModel.isTransparencyEnabled, onScrimClicked = contentViewModel::onScrimClicked, header = { OverlayShadeHeader( Loading Loading @@ -284,7 +285,8 @@ fun ContentScope.QuickSettingsLayout( containerColors = ContainerColors( idleColor = Color.Transparent, mirrorColor = OverlayShade.Colors.PanelBackground, mirrorColor = OverlayShade.Colors.panelBackground(viewModel.isTransparencyEnabled), ), modifier = Modifier.fillMaxWidth(), ) Loading packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt +29 −23 Original line number Diff line number Diff line Loading @@ -42,10 +42,10 @@ import androidx.compose.ui.unit.Dp import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.LowestZIndexContentPicker import com.android.compose.modifiers.thenIf import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.mechanics.behavior.VerticalExpandContainerSpec import com.android.mechanics.behavior.verticalExpandContainerBackground import com.android.systemui.Flags import com.android.systemui.res.R import com.android.systemui.shade.ui.ShadeColors.notificationScrim import com.android.systemui.shade.ui.ShadeColors.shadePanel Loading @@ -56,6 +56,7 @@ import com.android.systemui.shade.ui.composable.OverlayShade.rememberShadeExpans fun ContentScope.OverlayShade( panelElement: ElementKey, alignmentOnWideScreens: Alignment, enableTransparency: Boolean, onScrimClicked: () -> Unit, modifier: Modifier = Modifier, header: @Composable () -> Unit, Loading @@ -63,15 +64,16 @@ fun ContentScope.OverlayShade( ) { val isFullWidth = isFullWidthShade() Box(modifier) { Scrim(onClicked = onScrimClicked) Scrim(showBackgroundColor = enableTransparency, onClicked = onScrimClicked) Box( modifier = Modifier.fillMaxSize().panelContainerPadding(isFullWidth), contentAlignment = if (isFullWidth) Alignment.TopCenter else alignmentOnWideScreens, ) { Panel( modifier = Modifier .overscroll(verticalOverscrollEffect) enableTransparency = enableTransparency, modifier = Modifier.overscroll(verticalOverscrollEffect) .element(panelElement) .panelWidth(isFullWidth), header = header.takeIf { isFullWidth }, Loading @@ -86,19 +88,25 @@ fun ContentScope.OverlayShade( } @Composable private fun ContentScope.Scrim(onClicked: () -> Unit, modifier: Modifier = Modifier) { private fun ContentScope.Scrim( showBackgroundColor: Boolean, onClicked: () -> Unit, modifier: Modifier = Modifier, ) { val scrimBackgroundColor = OverlayShade.Colors.ScrimBackground Spacer( modifier = modifier .element(OverlayShade.Elements.Scrim) .fillMaxSize() .background(OverlayShade.Colors.ScrimBackground) .thenIf(showBackgroundColor) { Modifier.background(scrimBackgroundColor) } .clickable(onClick = onClicked, interactionSource = null, indication = null) ) } @Composable private fun ContentScope.Panel( enableTransparency: Boolean, modifier: Modifier = Modifier, header: (@Composable () -> Unit)?, content: @Composable () -> Unit, Loading @@ -108,7 +116,7 @@ private fun ContentScope.Panel( modifier .disableSwipesWhenScrolling() .verticalExpandContainerBackground( backgroundColor = OverlayShade.Colors.PanelBackground, backgroundColor = OverlayShade.Colors.panelBackground(enableTransparency), spec = rememberShadeExpansionMotion(isFullWidthShade()), ) ) { Loading Loading @@ -162,21 +170,19 @@ object OverlayShade { val ScrimBackground: Color @Composable @ReadOnlyComposable get() = if (Flags.notificationShadeBlur()) { Color(notificationScrim(LocalContext.current, /* blurSupported= */ true)) } else { Color.Transparent } get() = Color(notificationScrim(LocalContext.current, /* blurSupported= */ true)) val PanelBackground: Color @Composable @ReadOnlyComposable get() = Color(shadePanel( fun panelBackground(transparencyEnabled: Boolean): Color { return Color( shadePanel( context = LocalContext.current, blurSupported = Flags.notificationShadeBlur(), withScrim = false )) blurSupported = transparencyEnabled, withScrim = false, ) ) } } object Dimensions { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt +34 −0 Original line number Diff line number Diff line Loading @@ -17,9 +17,12 @@ package com.android.systemui.notifications.ui.viewmodel import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags.FLAG_NOTIFICATION_SHADE_BLUR import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository import com.android.systemui.authentication.domain.interactor.AuthenticationResult Loading @@ -43,6 +46,7 @@ import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.ui.viewmodel.notificationsShadeOverlayContentViewModel import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository import com.android.systemui.testKosmos import com.android.systemui.window.data.repository.fakeWindowRootViewBlurRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.update Loading Loading @@ -152,6 +156,36 @@ class NotificationsShadeOverlayContentViewModelTest : SysuiTestCase() { assertThat(underTest.showMedia).isFalse() } @Test @DisableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOff_isDisabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = true runCurrent() assertThat(underTest.isTransparencyEnabled).isFalse() } @Test @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOn_blurSupported_isEnabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = true runCurrent() assertThat(underTest.isTransparencyEnabled).isTrue() } @Test @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOn_blurUnsupported_isDisabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = false runCurrent() assertThat(underTest.isTransparencyEnabled).isFalse() } private fun TestScope.lockDevice() { val currentScene by collectLastValue(sceneInteractor.currentScene) kosmos.powerInteractor.setAsleepForTest() Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelTest.kt +33 −7 Original line number Diff line number Diff line Loading @@ -16,12 +16,16 @@ package com.android.systemui.qs.ui.viewmodel import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags.FLAG_NOTIFICATION_SHADE_BLUR import com.android.systemui.SysuiTestCase import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.lifecycle.activateIn import com.android.systemui.media.controls.data.repository.mediaFilterRepository import com.android.systemui.media.controls.shared.model.MediaData Loading @@ -29,15 +33,13 @@ import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragmen import com.android.systemui.scene.domain.startable.sceneContainerStartable import com.android.systemui.shade.domain.interactor.enableDualShade import com.android.systemui.testKosmos import com.android.systemui.window.data.repository.fakeWindowRootViewBlurRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper Loading @@ -45,7 +47,7 @@ import org.junit.runner.RunWith class QuickSettingsContainerViewModelTest : SysuiTestCase() { private val kosmos = testKosmos().apply { testKosmos().useUnconfinedTestDispatcher().apply { usingMediaInComposeFragment = false // This is not for the compose fragment } private val testScope = kosmos.testScope Loading @@ -65,7 +67,6 @@ class QuickSettingsContainerViewModelTest : SysuiTestCase() { fun showMedia_activeMedia_true() = testScope.runTest { kosmos.mediaFilterRepository.addCurrentUserMediaEntry(MediaData(active = true)) runCurrent() assertThat(underTest.showMedia).isTrue() } Loading @@ -74,7 +75,6 @@ class QuickSettingsContainerViewModelTest : SysuiTestCase() { fun showMedia_InactiveMedia_true() = testScope.runTest { kosmos.mediaFilterRepository.addCurrentUserMediaEntry(MediaData(active = false)) runCurrent() assertThat(underTest.showMedia).isTrue() } Loading @@ -84,8 +84,34 @@ class QuickSettingsContainerViewModelTest : SysuiTestCase() { testScope.runTest { kosmos.mediaFilterRepository.addCurrentUserMediaEntry(MediaData(active = true)) kosmos.mediaFilterRepository.clearCurrentUserMedia() runCurrent() assertThat(underTest.showMedia).isFalse() } @Test @DisableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOff_isDisabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = true assertThat(underTest.isTransparencyEnabled).isFalse() } @Test @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOn_blurSupported_isEnabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = true assertThat(underTest.isTransparencyEnabled).isTrue() } @Test @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOn_blurUnsupported_isDisabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = false assertThat(underTest.isTransparencyEnabled).isFalse() } } Loading
packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeOverlay.kt +1 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ constructor( OverlayShade( panelElement = NotificationsShade.Elements.Panel, alignmentOnWideScreens = Alignment.TopStart, enableTransparency = viewModel.isTransparencyEnabled, modifier = modifier, onScrimClicked = viewModel::onScrimClicked, header = { Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt +3 −1 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ constructor( OverlayShade( panelElement = QuickSettingsShade.Elements.Panel, alignmentOnWideScreens = Alignment.TopEnd, enableTransparency = quickSettingsContainerViewModel.isTransparencyEnabled, onScrimClicked = contentViewModel::onScrimClicked, header = { OverlayShadeHeader( Loading Loading @@ -284,7 +285,8 @@ fun ContentScope.QuickSettingsLayout( containerColors = ContainerColors( idleColor = Color.Transparent, mirrorColor = OverlayShade.Colors.PanelBackground, mirrorColor = OverlayShade.Colors.panelBackground(viewModel.isTransparencyEnabled), ), modifier = Modifier.fillMaxWidth(), ) Loading
packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt +29 −23 Original line number Diff line number Diff line Loading @@ -42,10 +42,10 @@ import androidx.compose.ui.unit.Dp import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.LowestZIndexContentPicker import com.android.compose.modifiers.thenIf import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.mechanics.behavior.VerticalExpandContainerSpec import com.android.mechanics.behavior.verticalExpandContainerBackground import com.android.systemui.Flags import com.android.systemui.res.R import com.android.systemui.shade.ui.ShadeColors.notificationScrim import com.android.systemui.shade.ui.ShadeColors.shadePanel Loading @@ -56,6 +56,7 @@ import com.android.systemui.shade.ui.composable.OverlayShade.rememberShadeExpans fun ContentScope.OverlayShade( panelElement: ElementKey, alignmentOnWideScreens: Alignment, enableTransparency: Boolean, onScrimClicked: () -> Unit, modifier: Modifier = Modifier, header: @Composable () -> Unit, Loading @@ -63,15 +64,16 @@ fun ContentScope.OverlayShade( ) { val isFullWidth = isFullWidthShade() Box(modifier) { Scrim(onClicked = onScrimClicked) Scrim(showBackgroundColor = enableTransparency, onClicked = onScrimClicked) Box( modifier = Modifier.fillMaxSize().panelContainerPadding(isFullWidth), contentAlignment = if (isFullWidth) Alignment.TopCenter else alignmentOnWideScreens, ) { Panel( modifier = Modifier .overscroll(verticalOverscrollEffect) enableTransparency = enableTransparency, modifier = Modifier.overscroll(verticalOverscrollEffect) .element(panelElement) .panelWidth(isFullWidth), header = header.takeIf { isFullWidth }, Loading @@ -86,19 +88,25 @@ fun ContentScope.OverlayShade( } @Composable private fun ContentScope.Scrim(onClicked: () -> Unit, modifier: Modifier = Modifier) { private fun ContentScope.Scrim( showBackgroundColor: Boolean, onClicked: () -> Unit, modifier: Modifier = Modifier, ) { val scrimBackgroundColor = OverlayShade.Colors.ScrimBackground Spacer( modifier = modifier .element(OverlayShade.Elements.Scrim) .fillMaxSize() .background(OverlayShade.Colors.ScrimBackground) .thenIf(showBackgroundColor) { Modifier.background(scrimBackgroundColor) } .clickable(onClick = onClicked, interactionSource = null, indication = null) ) } @Composable private fun ContentScope.Panel( enableTransparency: Boolean, modifier: Modifier = Modifier, header: (@Composable () -> Unit)?, content: @Composable () -> Unit, Loading @@ -108,7 +116,7 @@ private fun ContentScope.Panel( modifier .disableSwipesWhenScrolling() .verticalExpandContainerBackground( backgroundColor = OverlayShade.Colors.PanelBackground, backgroundColor = OverlayShade.Colors.panelBackground(enableTransparency), spec = rememberShadeExpansionMotion(isFullWidthShade()), ) ) { Loading Loading @@ -162,21 +170,19 @@ object OverlayShade { val ScrimBackground: Color @Composable @ReadOnlyComposable get() = if (Flags.notificationShadeBlur()) { Color(notificationScrim(LocalContext.current, /* blurSupported= */ true)) } else { Color.Transparent } get() = Color(notificationScrim(LocalContext.current, /* blurSupported= */ true)) val PanelBackground: Color @Composable @ReadOnlyComposable get() = Color(shadePanel( fun panelBackground(transparencyEnabled: Boolean): Color { return Color( shadePanel( context = LocalContext.current, blurSupported = Flags.notificationShadeBlur(), withScrim = false )) blurSupported = transparencyEnabled, withScrim = false, ) ) } } object Dimensions { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeOverlayContentViewModelTest.kt +34 −0 Original line number Diff line number Diff line Loading @@ -17,9 +17,12 @@ package com.android.systemui.notifications.ui.viewmodel import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags.FLAG_NOTIFICATION_SHADE_BLUR import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository import com.android.systemui.authentication.domain.interactor.AuthenticationResult Loading @@ -43,6 +46,7 @@ import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.shade.ui.viewmodel.notificationsShadeOverlayContentViewModel import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository import com.android.systemui.testKosmos import com.android.systemui.window.data.repository.fakeWindowRootViewBlurRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.update Loading Loading @@ -152,6 +156,36 @@ class NotificationsShadeOverlayContentViewModelTest : SysuiTestCase() { assertThat(underTest.showMedia).isFalse() } @Test @DisableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOff_isDisabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = true runCurrent() assertThat(underTest.isTransparencyEnabled).isFalse() } @Test @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOn_blurSupported_isEnabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = true runCurrent() assertThat(underTest.isTransparencyEnabled).isTrue() } @Test @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOn_blurUnsupported_isDisabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = false runCurrent() assertThat(underTest.isTransparencyEnabled).isFalse() } private fun TestScope.lockDevice() { val currentScene by collectLastValue(sceneInteractor.currentScene) kosmos.powerInteractor.setAsleepForTest() Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelTest.kt +33 −7 Original line number Diff line number Diff line Loading @@ -16,12 +16,16 @@ package com.android.systemui.qs.ui.viewmodel import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags.FLAG_NOTIFICATION_SHADE_BLUR import com.android.systemui.SysuiTestCase import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.lifecycle.activateIn import com.android.systemui.media.controls.data.repository.mediaFilterRepository import com.android.systemui.media.controls.shared.model.MediaData Loading @@ -29,15 +33,13 @@ import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragmen import com.android.systemui.scene.domain.startable.sceneContainerStartable import com.android.systemui.shade.domain.interactor.enableDualShade import com.android.systemui.testKosmos import com.android.systemui.window.data.repository.fakeWindowRootViewBlurRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper Loading @@ -45,7 +47,7 @@ import org.junit.runner.RunWith class QuickSettingsContainerViewModelTest : SysuiTestCase() { private val kosmos = testKosmos().apply { testKosmos().useUnconfinedTestDispatcher().apply { usingMediaInComposeFragment = false // This is not for the compose fragment } private val testScope = kosmos.testScope Loading @@ -65,7 +67,6 @@ class QuickSettingsContainerViewModelTest : SysuiTestCase() { fun showMedia_activeMedia_true() = testScope.runTest { kosmos.mediaFilterRepository.addCurrentUserMediaEntry(MediaData(active = true)) runCurrent() assertThat(underTest.showMedia).isTrue() } Loading @@ -74,7 +75,6 @@ class QuickSettingsContainerViewModelTest : SysuiTestCase() { fun showMedia_InactiveMedia_true() = testScope.runTest { kosmos.mediaFilterRepository.addCurrentUserMediaEntry(MediaData(active = false)) runCurrent() assertThat(underTest.showMedia).isTrue() } Loading @@ -84,8 +84,34 @@ class QuickSettingsContainerViewModelTest : SysuiTestCase() { testScope.runTest { kosmos.mediaFilterRepository.addCurrentUserMediaEntry(MediaData(active = true)) kosmos.mediaFilterRepository.clearCurrentUserMedia() runCurrent() assertThat(underTest.showMedia).isFalse() } @Test @DisableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOff_isDisabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = true assertThat(underTest.isTransparencyEnabled).isFalse() } @Test @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOn_blurSupported_isEnabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = true assertThat(underTest.isTransparencyEnabled).isTrue() } @Test @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR) fun transparencyEnabled_shadeBlurFlagOn_blurUnsupported_isDisabled() = testScope.runTest { kosmos.fakeWindowRootViewBlurRepository.isBlurSupported.value = false assertThat(underTest.isTransparencyEnabled).isFalse() } }