Loading packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +9 −1 Original line number Diff line number Diff line Loading @@ -270,6 +270,7 @@ private fun SceneScope.SingleShade( ) val isEmptySpaceClickable by viewModel.isEmptySpaceClickable.collectAsStateWithLifecycle() val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle() val isQsEnabled by viewModel.isQsEnabled.collectAsStateWithLifecycle() val shouldPunchHoleBehindScrim = layoutState.isTransitioningBetween(Scenes.Gone, Scenes.Shade) || Loading Loading @@ -372,6 +373,7 @@ private fun SceneScope.SingleShade( Modifier.padding(bottom = qqsLayoutPaddingBottom) }, usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia, isQsEnabled = isQsEnabled, isInSplitShade = false, ) Loading Loading @@ -427,6 +429,7 @@ private fun SceneScope.SplitShade( val screenCornerRadius = LocalScreenCornerRadius.current val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsStateWithLifecycle() val isQsEnabled by viewModel.isQsEnabled.collectAsStateWithLifecycle() val isCustomizerShowing by viewModel.qsSceneAdapter.isCustomizerShowing.collectAsStateWithLifecycle() val customizingAnimationDuration by Loading Loading @@ -582,6 +585,7 @@ private fun SceneScope.SplitShade( dimensionResource(id = R.dimen.qs_horizontal_margin) ), carouselController = mediaCarouselController, isQsEnabled = isQsEnabled, isInSplitShade = true, ) } Loading Loading @@ -635,10 +639,14 @@ private fun SceneScope.ShadeMediaCarousel( mediaHost: MediaHost, carouselController: MediaCarouselController, mediaOffsetProvider: ShadeMediaOffsetProvider, isInSplitShade: Boolean, isQsEnabled: Boolean, modifier: Modifier = Modifier, usingCollapsedLandscapeMedia: Boolean = false, isInSplitShade: Boolean, ) { if (!isQsEnabled) { return } MediaCarousel( modifier = modifier.fillMaxWidth(), isVisible = isVisible, Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt +20 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.shade.ui.viewmodel import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS import android.platform.test.annotations.DisableFlags import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 Loading @@ -42,6 +43,7 @@ import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.shared.flag.DualShade import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository import com.android.systemui.testKosmos import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider import com.google.common.truth.Truth.assertThat Loading @@ -49,6 +51,7 @@ import java.util.Locale import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest Loading Loading @@ -158,10 +161,7 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { underTest.unfoldTranslationX(isOnStartSide = true), underTest.unfoldTranslationX(isOnStartSide = false), ) { start, end -> Translations( start = start, end = end, ) Translations(start = start, end = end) } ) Loading @@ -186,6 +186,20 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { assertThat(translations?.end).isEqualTo(-0f) } @Test fun disable2QuickSettings_isQsEnabledIsFalse() = testScope.runTest { val isQsEnabled by collectLastValue(underTest.isQsEnabled) assertThat(isQsEnabled).isTrue() kosmos.fakeDisableFlagsRepository.disableFlags.update { it.copy(disable2 = DISABLE2_QUICK_SETTINGS) } runCurrent() assertThat(isQsEnabled).isFalse() } private fun prepareConfiguration(): Int { val configuration = context.resources.configuration configuration.setLayoutDirection(Locale.US) Loading @@ -193,7 +207,7 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { val maxTranslation = 10 kosmos.fakeConfigurationRepository.setDimensionPixelSize( R.dimen.notification_side_paddings, maxTranslation maxTranslation, ) return maxTranslation } Loading Loading @@ -224,8 +238,5 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { runCurrent() } private data class Translations( val start: Float, val end: Float, ) private data class Translations(val start: Float, val end: Float) } packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt +20 −4 Original line number Diff line number Diff line Loading @@ -30,15 +30,21 @@ import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.util.concurrent.atomic.AtomicBoolean import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach /** * Models UI state used to render the content of the shade scene. Loading @@ -54,6 +60,7 @@ constructor( val brightnessMirrorViewModelFactory: BrightnessMirrorViewModel.Factory, val mediaCarouselInteractor: MediaCarouselInteractor, shadeInteractor: ShadeInteractor, private val disableFlagsInteractor: DisableFlagsInteractor, private val footerActionsViewModelFactory: FooterActionsViewModel.Factory, private val footerActionsController: FooterActionsController, private val unfoldTransitionInteractor: UnfoldTransitionInteractor, Loading @@ -70,12 +77,21 @@ constructor( val isMediaVisible: StateFlow<Boolean> = mediaCarouselInteractor.hasActiveMediaOrRecommendation private val _isQsEnabled = MutableStateFlow(!disableFlagsInteractor.disableFlags.value.isQuickSettingsEnabled()) val isQsEnabled: StateFlow<Boolean> = _isQsEnabled.asStateFlow() private val footerActionsControllerInitialized = AtomicBoolean(false) override suspend fun onActivated(): Nothing { deviceEntryInteractor.isDeviceEntered.collect { isDeviceEntered -> _isEmptySpaceClickable.value = !isDeviceEntered } override suspend fun onActivated(): Nothing = coroutineScope { deviceEntryInteractor.isDeviceEntered .onEach { isDeviceEntered -> _isEmptySpaceClickable.value = !isDeviceEntered } .launchIn(this) disableFlagsInteractor.disableFlags .map { it.isQuickSettingsEnabled() } .onEach { _isQsEnabled.value = it } .launchIn(this) awaitCancellation() } /** Loading packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.systemui.qs.ui.adapter.qsSceneAdapter import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModelFactory import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor val Kosmos.shadeSceneContentViewModel: ShadeSceneContentViewModel by Fixture { Loading @@ -35,6 +36,7 @@ val Kosmos.shadeSceneContentViewModel: ShadeSceneContentViewModel by Fixture { brightnessMirrorViewModelFactory = brightnessMirrorViewModelFactory, mediaCarouselInteractor = mediaCarouselInteractor, shadeInteractor = shadeInteractor, disableFlagsInteractor = disableFlagsInteractor, footerActionsViewModelFactory = footerActionsViewModelFactory, footerActionsController = footerActionsController, unfoldTransitionInteractor = unfoldTransitionInteractor, Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +9 −1 Original line number Diff line number Diff line Loading @@ -270,6 +270,7 @@ private fun SceneScope.SingleShade( ) val isEmptySpaceClickable by viewModel.isEmptySpaceClickable.collectAsStateWithLifecycle() val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle() val isQsEnabled by viewModel.isQsEnabled.collectAsStateWithLifecycle() val shouldPunchHoleBehindScrim = layoutState.isTransitioningBetween(Scenes.Gone, Scenes.Shade) || Loading Loading @@ -372,6 +373,7 @@ private fun SceneScope.SingleShade( Modifier.padding(bottom = qqsLayoutPaddingBottom) }, usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia, isQsEnabled = isQsEnabled, isInSplitShade = false, ) Loading Loading @@ -427,6 +429,7 @@ private fun SceneScope.SplitShade( val screenCornerRadius = LocalScreenCornerRadius.current val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsStateWithLifecycle() val isQsEnabled by viewModel.isQsEnabled.collectAsStateWithLifecycle() val isCustomizerShowing by viewModel.qsSceneAdapter.isCustomizerShowing.collectAsStateWithLifecycle() val customizingAnimationDuration by Loading Loading @@ -582,6 +585,7 @@ private fun SceneScope.SplitShade( dimensionResource(id = R.dimen.qs_horizontal_margin) ), carouselController = mediaCarouselController, isQsEnabled = isQsEnabled, isInSplitShade = true, ) } Loading Loading @@ -635,10 +639,14 @@ private fun SceneScope.ShadeMediaCarousel( mediaHost: MediaHost, carouselController: MediaCarouselController, mediaOffsetProvider: ShadeMediaOffsetProvider, isInSplitShade: Boolean, isQsEnabled: Boolean, modifier: Modifier = Modifier, usingCollapsedLandscapeMedia: Boolean = false, isInSplitShade: Boolean, ) { if (!isQsEnabled) { return } MediaCarousel( modifier = modifier.fillMaxWidth(), isVisible = isVisible, Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt +20 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.shade.ui.viewmodel import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS import android.platform.test.annotations.DisableFlags import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 Loading @@ -42,6 +43,7 @@ import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.shared.flag.DualShade import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository import com.android.systemui.testKosmos import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider import com.google.common.truth.Truth.assertThat Loading @@ -49,6 +51,7 @@ import java.util.Locale import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest Loading Loading @@ -158,10 +161,7 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { underTest.unfoldTranslationX(isOnStartSide = true), underTest.unfoldTranslationX(isOnStartSide = false), ) { start, end -> Translations( start = start, end = end, ) Translations(start = start, end = end) } ) Loading @@ -186,6 +186,20 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { assertThat(translations?.end).isEqualTo(-0f) } @Test fun disable2QuickSettings_isQsEnabledIsFalse() = testScope.runTest { val isQsEnabled by collectLastValue(underTest.isQsEnabled) assertThat(isQsEnabled).isTrue() kosmos.fakeDisableFlagsRepository.disableFlags.update { it.copy(disable2 = DISABLE2_QUICK_SETTINGS) } runCurrent() assertThat(isQsEnabled).isFalse() } private fun prepareConfiguration(): Int { val configuration = context.resources.configuration configuration.setLayoutDirection(Locale.US) Loading @@ -193,7 +207,7 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { val maxTranslation = 10 kosmos.fakeConfigurationRepository.setDimensionPixelSize( R.dimen.notification_side_paddings, maxTranslation maxTranslation, ) return maxTranslation } Loading Loading @@ -224,8 +238,5 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { runCurrent() } private data class Translations( val start: Float, val end: Float, ) private data class Translations(val start: Float, val end: Float) }
packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModel.kt +20 −4 Original line number Diff line number Diff line Loading @@ -30,15 +30,21 @@ import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import java.util.concurrent.atomic.AtomicBoolean import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach /** * Models UI state used to render the content of the shade scene. Loading @@ -54,6 +60,7 @@ constructor( val brightnessMirrorViewModelFactory: BrightnessMirrorViewModel.Factory, val mediaCarouselInteractor: MediaCarouselInteractor, shadeInteractor: ShadeInteractor, private val disableFlagsInteractor: DisableFlagsInteractor, private val footerActionsViewModelFactory: FooterActionsViewModel.Factory, private val footerActionsController: FooterActionsController, private val unfoldTransitionInteractor: UnfoldTransitionInteractor, Loading @@ -70,12 +77,21 @@ constructor( val isMediaVisible: StateFlow<Boolean> = mediaCarouselInteractor.hasActiveMediaOrRecommendation private val _isQsEnabled = MutableStateFlow(!disableFlagsInteractor.disableFlags.value.isQuickSettingsEnabled()) val isQsEnabled: StateFlow<Boolean> = _isQsEnabled.asStateFlow() private val footerActionsControllerInitialized = AtomicBoolean(false) override suspend fun onActivated(): Nothing { deviceEntryInteractor.isDeviceEntered.collect { isDeviceEntered -> _isEmptySpaceClickable.value = !isDeviceEntered } override suspend fun onActivated(): Nothing = coroutineScope { deviceEntryInteractor.isDeviceEntered .onEach { isDeviceEntered -> _isEmptySpaceClickable.value = !isDeviceEntered } .launchIn(this) disableFlagsInteractor.disableFlags .map { it.isQuickSettingsEnabled() } .onEach { _isQsEnabled.value = it } .launchIn(this) awaitCancellation() } /** Loading
packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import com.android.systemui.qs.ui.adapter.qsSceneAdapter import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModelFactory import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor val Kosmos.shadeSceneContentViewModel: ShadeSceneContentViewModel by Fixture { Loading @@ -35,6 +36,7 @@ val Kosmos.shadeSceneContentViewModel: ShadeSceneContentViewModel by Fixture { brightnessMirrorViewModelFactory = brightnessMirrorViewModelFactory, mediaCarouselInteractor = mediaCarouselInteractor, shadeInteractor = shadeInteractor, disableFlagsInteractor = disableFlagsInteractor, footerActionsViewModelFactory = footerActionsViewModelFactory, footerActionsController = footerActionsController, unfoldTransitionInteractor = unfoldTransitionInteractor, Loading