Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +1 −1 Original line number Diff line number Diff line Loading @@ -294,7 +294,7 @@ private fun ContentScope.QuickSettingsScene( } // ############# Media ############### val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle() val isMediaVisible = viewModel.isMediaVisible val mediaInRow = isMediaVisible && isLandscape() val mediaOffset by animateSceneDpAsState(value = InQS, key = MediaLandscapeTopOffset, canOverflow = false) Loading packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +9 −17 Original line number Diff line number Diff line Loading @@ -206,8 +206,7 @@ private fun ContentScope.ShadeScene( shadeSession: SaveableSession, usingCollapsedLandscapeMedia: Boolean, ) { val shadeMode by viewModel.shadeMode.collectAsStateWithLifecycle() when (shadeMode) { when (viewModel.shadeMode) { is ShadeMode.Single -> SingleShade( notificationStackScrollView = notificationStackScrollView, Loading Loading @@ -261,15 +260,12 @@ private fun ContentScope.SingleShade( key = QuickSettings.SharedValues.TilesSquishiness, canOverflow = false, ) 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) || layoutState.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Shade) // Media is visible and we are in landscape on a small height screen val mediaInRow = isMediaVisible && isLandscape() val mediaInRow = viewModel.isMediaVisible && isLandscape() val mediaOffset by animateContentDpAsState( value = QuickSettings.SharedValues.MediaOffset.inQqs(mediaInRow), Loading Loading @@ -322,7 +318,7 @@ private fun ContentScope.SingleShade( ) Layout( modifier = Modifier.thenIf(isEmptySpaceClickable) { Modifier.thenIf(viewModel.isEmptySpaceClickable) { Modifier.clickable { viewModel.onEmptySpaceClicked() } }, content = { Loading @@ -348,7 +344,7 @@ private fun ContentScope.SingleShade( val qqsLayoutPaddingBottom = dimensionResource(id = R.dimen.qqs_layout_padding_bottom) ShadeMediaCarousel( isVisible = isMediaVisible, isVisible = viewModel.isMediaVisible, isInRow = mediaInRow, mediaHost = mediaHost, mediaOffsetProvider = mediaOffsetProvider, Loading @@ -364,7 +360,7 @@ private fun ContentScope.SingleShade( Modifier.padding(bottom = qqsLayoutPaddingBottom) }, usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia, isQsEnabled = isQsEnabled, isQsEnabled = viewModel.isQsEnabled, isInSplitShade = false, ) Loading @@ -379,7 +375,7 @@ private fun ContentScope.SingleShade( stackBottomPadding = navBarHeight, supportNestedScrolling = true, onEmptySpaceClick = viewModel::onEmptySpaceClicked.takeIf { isEmptySpaceClickable }, viewModel::onEmptySpaceClicked.takeIf { viewModel.isEmptySpaceClickable }, modifier = Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.Notifications) .padding(horizontal = shadeHorizontalPadding), Loading Loading @@ -416,7 +412,6 @@ private fun ContentScope.SplitShade( jankMonitor: InteractionJankMonitor, ) { 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 @@ -472,9 +467,6 @@ private fun ContentScope.SplitShade( onDispose { notificationsPlaceholderViewModel.setAlphaForBrightnessMirror(1f) } } val isEmptySpaceClickable by viewModel.isEmptySpaceClickable.collectAsStateWithLifecycle() val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle() val brightnessMirrorShowingModifier = Modifier.graphicsLayer { alpha = contentAlpha } val mediaOffsetProvider = remember { Loading Loading @@ -555,7 +547,7 @@ private fun ContentScope.SplitShade( } ShadeMediaCarousel( isVisible = isMediaVisible, isVisible = viewModel.isMediaVisible, isInRow = false, mediaHost = mediaHost, mediaOffsetProvider = mediaOffsetProvider, Loading @@ -570,7 +562,7 @@ private fun ContentScope.SplitShade( dimensionResource(id = R.dimen.qs_horizontal_margin) ), carouselController = mediaCarouselController, isQsEnabled = isQsEnabled, isQsEnabled = viewModel.isQsEnabled, isInSplitShade = true, ) } Loading Loading @@ -598,7 +590,7 @@ private fun ContentScope.SplitShade( shouldPunchHoleBehindScrim = false, supportNestedScrolling = false, onEmptySpaceClick = viewModel::onEmptySpaceClicked.takeIf { isEmptySpaceClickable }, viewModel::onEmptySpaceClicked.takeIf { viewModel.isEmptySpaceClickable }, modifier = Modifier.weight(1f) .fillMaxHeight() Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModelTest.kt +9 −15 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue 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.domain.pipeline.interactor.mediaCarouselInteractor Loading @@ -35,8 +36,8 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.domain.startable.sceneContainerStartable import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModelFactory import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.disableDualShade import com.android.systemui.shade.domain.interactor.enableSplitShade import com.android.systemui.shade.domain.interactor.shadeModeInteractor import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModelFactory import com.android.systemui.testKosmos Loading @@ -44,8 +45,6 @@ import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever 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 Loading @@ -53,14 +52,13 @@ import org.junit.runner.RunWith import org.mockito.Mockito.times import org.mockito.Mockito.verify @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) @RunWithLooper @EnableSceneContainer class QuickSettingsSceneContentViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val testScope = kosmos.testScope private val qsFlexiglassAdapter = FakeQSSceneAdapter({ mock() }) private val footerActionsViewModel = mock<FooterActionsViewModel>() Loading Loading @@ -104,31 +102,29 @@ class QuickSettingsSceneContentViewModelTest : SysuiTestCase() { @Test fun addAndRemoveMedia_mediaVisibilityIsUpdated() = testScope.runTest { val isMediaVisible by collectLastValue(underTest.isMediaVisible) val userMedia = MediaData(active = true) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() kosmos.mediaFilterRepository.addCurrentUserMediaEntry(userMedia) assertThat(isMediaVisible).isTrue() assertThat(underTest.isMediaVisible).isTrue() kosmos.mediaFilterRepository.removeCurrentUserMediaEntry(userMedia.instanceId) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() } @Test fun addInactiveMedia_mediaVisibilityIsUpdated() = testScope.runTest { val isMediaVisible by collectLastValue(underTest.isMediaVisible) val userMedia = MediaData(active = false) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() kosmos.mediaFilterRepository.addCurrentUserMediaEntry(userMedia) assertThat(isMediaVisible).isTrue() assertThat(underTest.isMediaVisible).isTrue() } @Test Loading @@ -136,9 +132,7 @@ class QuickSettingsSceneContentViewModelTest : SysuiTestCase() { testScope.runTest { val scene by collectLastValue(sceneInteractor.currentScene) // switch to split shade kosmos.shadeRepository.setShadeLayoutWide(true) runCurrent() kosmos.enableSplitShade() assertThat(scene).isEqualTo(Scenes.Shade) } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt +25 −45 Original line number Diff line number Diff line Loading @@ -33,26 +33,28 @@ import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus 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 import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.disableDualShade 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.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 import java.util.Locale import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test Loading @@ -64,10 +66,8 @@ import org.junit.runner.RunWith @EnableSceneContainer class ShadeSceneContentViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val testScope = kosmos.testScope private val sceneInteractor by lazy { kosmos.sceneInteractor } private val shadeRepository by lazy { kosmos.shadeRepository } private val underTest: ShadeSceneContentViewModel by lazy { kosmos.shadeSceneContentViewModel } Loading @@ -80,36 +80,31 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { @Test fun isEmptySpaceClickable_deviceUnlocked_false() = testScope.runTest { val isEmptySpaceClickable by collectLastValue(underTest.isEmptySpaceClickable) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.Pin ) setDeviceEntered(true) runCurrent() assertThat(isEmptySpaceClickable).isFalse() assertThat(underTest.isEmptySpaceClickable).isFalse() } @Test fun isEmptySpaceClickable_deviceLockedSecurely_true() = testScope.runTest { val isEmptySpaceClickable by collectLastValue(underTest.isEmptySpaceClickable) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.Pin ) runCurrent() assertThat(isEmptySpaceClickable).isTrue() assertThat(underTest.isEmptySpaceClickable).isTrue() } @Test fun onEmptySpaceClicked_deviceLockedSecurely_switchesToLockscreen() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.currentScene) val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.Pin ) runCurrent() underTest.onEmptySpaceClicked() Loading @@ -117,35 +112,32 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { } @Test fun addAndRemoveMedia_mediaVisibilityisUpdated() = fun addAndRemoveMedia_mediaVisibilityIsUpdated() = testScope.runTest { val isMediaVisible by collectLastValue(underTest.isMediaVisible) val userMedia = MediaData(active = true) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() kosmos.mediaFilterRepository.addCurrentUserMediaEntry(userMedia) assertThat(isMediaVisible).isTrue() assertThat(underTest.isMediaVisible).isTrue() kosmos.mediaFilterRepository.removeCurrentUserMediaEntry(userMedia.instanceId) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() } @Test fun shadeMode() = testScope.runTest { val shadeMode by collectLastValue(underTest.shadeMode) kosmos.enableSplitShade() assertThat(underTest.shadeMode).isEqualTo(ShadeMode.Split) shadeRepository.setShadeLayoutWide(true) assertThat(shadeMode).isEqualTo(ShadeMode.Split) kosmos.enableSingleShade() assertThat(underTest.shadeMode).isEqualTo(ShadeMode.Single) shadeRepository.setShadeLayoutWide(false) assertThat(shadeMode).isEqualTo(ShadeMode.Single) shadeRepository.setShadeLayoutWide(true) assertThat(shadeMode).isEqualTo(ShadeMode.Split) kosmos.enableDualShade() assertThat(underTest.shadeMode).isEqualTo(ShadeMode.Dual) } @Test Loading Loading @@ -186,15 +178,13 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { @Test fun disable2QuickSettings_isQsEnabledIsFalse() = testScope.runTest { val isQsEnabled by collectLastValue(underTest.isQsEnabled) assertThat(isQsEnabled).isTrue() assertThat(underTest.isQsEnabled).isTrue() kosmos.fakeDisableFlagsRepository.disableFlags.update { it.copy(disable2 = DISABLE2_QUICK_SETTINGS) } runCurrent() assertThat(isQsEnabled).isFalse() assertThat(underTest.isQsEnabled).isFalse() } private fun prepareConfiguration(): Int { Loading @@ -219,25 +209,15 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) runCurrent() assertThat(isDeviceUnlocked).isTrue() } setScene( if (isEntered) { Scenes.Gone } else { Scenes.Lockscreen } ) setScene(if (isEntered) Scenes.Gone else Scenes.Lockscreen) assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isEqualTo(isEntered) } private fun TestScope.setScene(key: SceneKey) { sceneInteractor.changeScene(key, "test") sceneInteractor.setTransitionState( MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(key)) ) runCurrent() private fun setScene(key: SceneKey) { kosmos.sceneInteractor.changeScene(key, "test") kosmos.sceneInteractor.setTransitionState(flowOf(ObservableTransitionState.Idle(key))) } private data class Translations(val start: Float, val end: Float) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt +7 −21 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintA import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.lifecycle.activateIn import com.android.systemui.qs.ui.adapter.fakeQSSceneAdapter import com.android.systemui.scene.domain.interactor.sceneInteractor Loading @@ -51,9 +52,7 @@ import com.android.systemui.shade.domain.startable.shadeStartable import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test Loading @@ -65,7 +64,7 @@ import org.junit.runner.RunWith @EnableSceneContainer class ShadeUserActionsViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val testScope = kosmos.testScope private val sceneInteractor by lazy { kosmos.sceneInteractor } private val qsSceneAdapter by lazy { kosmos.fakeQSSceneAdapter } Loading Loading @@ -148,7 +147,6 @@ class ShadeUserActionsViewModelTest : SysuiTestCase() { kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.None ) runCurrent() sceneInteractor.changeScene(Scenes.Gone, "reason") assertThat((actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene) Loading @@ -161,7 +159,6 @@ class ShadeUserActionsViewModelTest : SysuiTestCase() { testScope.runTest { val actions by collectLastValue(underTest.actions) kosmos.enableSplitShade() runCurrent() assertThat(actions?.get(Swipe.Up)?.transitionKey).isEqualTo(ToSplitShade) } Loading @@ -171,7 +168,6 @@ class ShadeUserActionsViewModelTest : SysuiTestCase() { testScope.runTest { val actions by collectLastValue(underTest.actions) kosmos.enableSingleShade() runCurrent() assertThat(actions?.get(Swipe.Up)?.transitionKey).isNull() } Loading Loading @@ -245,29 +241,19 @@ class ShadeUserActionsViewModelTest : SysuiTestCase() { } } private fun TestScope.setDeviceEntered(isEntered: Boolean) { private fun setDeviceEntered(isEntered: Boolean) { if (isEntered) { // Unlock the device marking the device has entered. kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) runCurrent() } setScene( if (isEntered) { Scenes.Gone } else { Scenes.Lockscreen } ) setScene(if (isEntered) Scenes.Gone else Scenes.Lockscreen) assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isEqualTo(isEntered) } private fun TestScope.setScene(key: SceneKey) { private fun setScene(key: SceneKey) { sceneInteractor.changeScene(key, "test") sceneInteractor.setTransitionState( MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(key)) ) runCurrent() sceneInteractor.setTransitionState(flowOf(ObservableTransitionState.Idle(key))) } } Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +1 −1 Original line number Diff line number Diff line Loading @@ -294,7 +294,7 @@ private fun ContentScope.QuickSettingsScene( } // ############# Media ############### val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle() val isMediaVisible = viewModel.isMediaVisible val mediaInRow = isMediaVisible && isLandscape() val mediaOffset by animateSceneDpAsState(value = InQS, key = MediaLandscapeTopOffset, canOverflow = false) Loading
packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt +9 −17 Original line number Diff line number Diff line Loading @@ -206,8 +206,7 @@ private fun ContentScope.ShadeScene( shadeSession: SaveableSession, usingCollapsedLandscapeMedia: Boolean, ) { val shadeMode by viewModel.shadeMode.collectAsStateWithLifecycle() when (shadeMode) { when (viewModel.shadeMode) { is ShadeMode.Single -> SingleShade( notificationStackScrollView = notificationStackScrollView, Loading Loading @@ -261,15 +260,12 @@ private fun ContentScope.SingleShade( key = QuickSettings.SharedValues.TilesSquishiness, canOverflow = false, ) 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) || layoutState.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Shade) // Media is visible and we are in landscape on a small height screen val mediaInRow = isMediaVisible && isLandscape() val mediaInRow = viewModel.isMediaVisible && isLandscape() val mediaOffset by animateContentDpAsState( value = QuickSettings.SharedValues.MediaOffset.inQqs(mediaInRow), Loading Loading @@ -322,7 +318,7 @@ private fun ContentScope.SingleShade( ) Layout( modifier = Modifier.thenIf(isEmptySpaceClickable) { Modifier.thenIf(viewModel.isEmptySpaceClickable) { Modifier.clickable { viewModel.onEmptySpaceClicked() } }, content = { Loading @@ -348,7 +344,7 @@ private fun ContentScope.SingleShade( val qqsLayoutPaddingBottom = dimensionResource(id = R.dimen.qqs_layout_padding_bottom) ShadeMediaCarousel( isVisible = isMediaVisible, isVisible = viewModel.isMediaVisible, isInRow = mediaInRow, mediaHost = mediaHost, mediaOffsetProvider = mediaOffsetProvider, Loading @@ -364,7 +360,7 @@ private fun ContentScope.SingleShade( Modifier.padding(bottom = qqsLayoutPaddingBottom) }, usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia, isQsEnabled = isQsEnabled, isQsEnabled = viewModel.isQsEnabled, isInSplitShade = false, ) Loading @@ -379,7 +375,7 @@ private fun ContentScope.SingleShade( stackBottomPadding = navBarHeight, supportNestedScrolling = true, onEmptySpaceClick = viewModel::onEmptySpaceClicked.takeIf { isEmptySpaceClickable }, viewModel::onEmptySpaceClicked.takeIf { viewModel.isEmptySpaceClickable }, modifier = Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.Notifications) .padding(horizontal = shadeHorizontalPadding), Loading Loading @@ -416,7 +412,6 @@ private fun ContentScope.SplitShade( jankMonitor: InteractionJankMonitor, ) { 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 @@ -472,9 +467,6 @@ private fun ContentScope.SplitShade( onDispose { notificationsPlaceholderViewModel.setAlphaForBrightnessMirror(1f) } } val isEmptySpaceClickable by viewModel.isEmptySpaceClickable.collectAsStateWithLifecycle() val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle() val brightnessMirrorShowingModifier = Modifier.graphicsLayer { alpha = contentAlpha } val mediaOffsetProvider = remember { Loading Loading @@ -555,7 +547,7 @@ private fun ContentScope.SplitShade( } ShadeMediaCarousel( isVisible = isMediaVisible, isVisible = viewModel.isMediaVisible, isInRow = false, mediaHost = mediaHost, mediaOffsetProvider = mediaOffsetProvider, Loading @@ -570,7 +562,7 @@ private fun ContentScope.SplitShade( dimensionResource(id = R.dimen.qs_horizontal_margin) ), carouselController = mediaCarouselController, isQsEnabled = isQsEnabled, isQsEnabled = viewModel.isQsEnabled, isInSplitShade = true, ) } Loading Loading @@ -598,7 +590,7 @@ private fun ContentScope.SplitShade( shouldPunchHoleBehindScrim = false, supportNestedScrolling = false, onEmptySpaceClick = viewModel::onEmptySpaceClicked.takeIf { isEmptySpaceClickable }, viewModel::onEmptySpaceClicked.takeIf { viewModel.isEmptySpaceClickable }, modifier = Modifier.weight(1f) .fillMaxHeight() Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneContentViewModelTest.kt +9 −15 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue 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.domain.pipeline.interactor.mediaCarouselInteractor Loading @@ -35,8 +36,8 @@ import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.domain.startable.sceneContainerStartable import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModelFactory import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.disableDualShade import com.android.systemui.shade.domain.interactor.enableSplitShade import com.android.systemui.shade.domain.interactor.shadeModeInteractor import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModelFactory import com.android.systemui.testKosmos Loading @@ -44,8 +45,6 @@ import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever 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 Loading @@ -53,14 +52,13 @@ import org.junit.runner.RunWith import org.mockito.Mockito.times import org.mockito.Mockito.verify @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) @RunWithLooper @EnableSceneContainer class QuickSettingsSceneContentViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val testScope = kosmos.testScope private val qsFlexiglassAdapter = FakeQSSceneAdapter({ mock() }) private val footerActionsViewModel = mock<FooterActionsViewModel>() Loading Loading @@ -104,31 +102,29 @@ class QuickSettingsSceneContentViewModelTest : SysuiTestCase() { @Test fun addAndRemoveMedia_mediaVisibilityIsUpdated() = testScope.runTest { val isMediaVisible by collectLastValue(underTest.isMediaVisible) val userMedia = MediaData(active = true) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() kosmos.mediaFilterRepository.addCurrentUserMediaEntry(userMedia) assertThat(isMediaVisible).isTrue() assertThat(underTest.isMediaVisible).isTrue() kosmos.mediaFilterRepository.removeCurrentUserMediaEntry(userMedia.instanceId) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() } @Test fun addInactiveMedia_mediaVisibilityIsUpdated() = testScope.runTest { val isMediaVisible by collectLastValue(underTest.isMediaVisible) val userMedia = MediaData(active = false) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() kosmos.mediaFilterRepository.addCurrentUserMediaEntry(userMedia) assertThat(isMediaVisible).isTrue() assertThat(underTest.isMediaVisible).isTrue() } @Test Loading @@ -136,9 +132,7 @@ class QuickSettingsSceneContentViewModelTest : SysuiTestCase() { testScope.runTest { val scene by collectLastValue(sceneInteractor.currentScene) // switch to split shade kosmos.shadeRepository.setShadeLayoutWide(true) runCurrent() kosmos.enableSplitShade() assertThat(scene).isEqualTo(Scenes.Shade) } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneContentViewModelTest.kt +25 −45 Original line number Diff line number Diff line Loading @@ -33,26 +33,28 @@ import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus 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 import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.data.repository.shadeRepository import com.android.systemui.shade.domain.interactor.disableDualShade 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.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 import java.util.Locale import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test Loading @@ -64,10 +66,8 @@ import org.junit.runner.RunWith @EnableSceneContainer class ShadeSceneContentViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val testScope = kosmos.testScope private val sceneInteractor by lazy { kosmos.sceneInteractor } private val shadeRepository by lazy { kosmos.shadeRepository } private val underTest: ShadeSceneContentViewModel by lazy { kosmos.shadeSceneContentViewModel } Loading @@ -80,36 +80,31 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { @Test fun isEmptySpaceClickable_deviceUnlocked_false() = testScope.runTest { val isEmptySpaceClickable by collectLastValue(underTest.isEmptySpaceClickable) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.Pin ) setDeviceEntered(true) runCurrent() assertThat(isEmptySpaceClickable).isFalse() assertThat(underTest.isEmptySpaceClickable).isFalse() } @Test fun isEmptySpaceClickable_deviceLockedSecurely_true() = testScope.runTest { val isEmptySpaceClickable by collectLastValue(underTest.isEmptySpaceClickable) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.Pin ) runCurrent() assertThat(isEmptySpaceClickable).isTrue() assertThat(underTest.isEmptySpaceClickable).isTrue() } @Test fun onEmptySpaceClicked_deviceLockedSecurely_switchesToLockscreen() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.currentScene) val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene) kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.Pin ) runCurrent() underTest.onEmptySpaceClicked() Loading @@ -117,35 +112,32 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { } @Test fun addAndRemoveMedia_mediaVisibilityisUpdated() = fun addAndRemoveMedia_mediaVisibilityIsUpdated() = testScope.runTest { val isMediaVisible by collectLastValue(underTest.isMediaVisible) val userMedia = MediaData(active = true) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() kosmos.mediaFilterRepository.addCurrentUserMediaEntry(userMedia) assertThat(isMediaVisible).isTrue() assertThat(underTest.isMediaVisible).isTrue() kosmos.mediaFilterRepository.removeCurrentUserMediaEntry(userMedia.instanceId) assertThat(isMediaVisible).isFalse() assertThat(underTest.isMediaVisible).isFalse() } @Test fun shadeMode() = testScope.runTest { val shadeMode by collectLastValue(underTest.shadeMode) kosmos.enableSplitShade() assertThat(underTest.shadeMode).isEqualTo(ShadeMode.Split) shadeRepository.setShadeLayoutWide(true) assertThat(shadeMode).isEqualTo(ShadeMode.Split) kosmos.enableSingleShade() assertThat(underTest.shadeMode).isEqualTo(ShadeMode.Single) shadeRepository.setShadeLayoutWide(false) assertThat(shadeMode).isEqualTo(ShadeMode.Single) shadeRepository.setShadeLayoutWide(true) assertThat(shadeMode).isEqualTo(ShadeMode.Split) kosmos.enableDualShade() assertThat(underTest.shadeMode).isEqualTo(ShadeMode.Dual) } @Test Loading Loading @@ -186,15 +178,13 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { @Test fun disable2QuickSettings_isQsEnabledIsFalse() = testScope.runTest { val isQsEnabled by collectLastValue(underTest.isQsEnabled) assertThat(isQsEnabled).isTrue() assertThat(underTest.isQsEnabled).isTrue() kosmos.fakeDisableFlagsRepository.disableFlags.update { it.copy(disable2 = DISABLE2_QUICK_SETTINGS) } runCurrent() assertThat(isQsEnabled).isFalse() assertThat(underTest.isQsEnabled).isFalse() } private fun prepareConfiguration(): Int { Loading @@ -219,25 +209,15 @@ class ShadeSceneContentViewModelTest : SysuiTestCase() { kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) runCurrent() assertThat(isDeviceUnlocked).isTrue() } setScene( if (isEntered) { Scenes.Gone } else { Scenes.Lockscreen } ) setScene(if (isEntered) Scenes.Gone else Scenes.Lockscreen) assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isEqualTo(isEntered) } private fun TestScope.setScene(key: SceneKey) { sceneInteractor.changeScene(key, "test") sceneInteractor.setTransitionState( MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(key)) ) runCurrent() private fun setScene(key: SceneKey) { kosmos.sceneInteractor.changeScene(key, "test") kosmos.sceneInteractor.setTransitionState(flowOf(ObservableTransitionState.Idle(key))) } private data class Translations(val start: Float, val end: Float) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActionsViewModelTest.kt +7 −21 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintA import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.lifecycle.activateIn import com.android.systemui.qs.ui.adapter.fakeQSSceneAdapter import com.android.systemui.scene.domain.interactor.sceneInteractor Loading @@ -51,9 +52,7 @@ import com.android.systemui.shade.domain.startable.shadeStartable import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test Loading @@ -65,7 +64,7 @@ import org.junit.runner.RunWith @EnableSceneContainer class ShadeUserActionsViewModelTest : SysuiTestCase() { private val kosmos = testKosmos() private val kosmos = testKosmos().useUnconfinedTestDispatcher() private val testScope = kosmos.testScope private val sceneInteractor by lazy { kosmos.sceneInteractor } private val qsSceneAdapter by lazy { kosmos.fakeQSSceneAdapter } Loading Loading @@ -148,7 +147,6 @@ class ShadeUserActionsViewModelTest : SysuiTestCase() { kosmos.fakeAuthenticationRepository.setAuthenticationMethod( AuthenticationMethodModel.None ) runCurrent() sceneInteractor.changeScene(Scenes.Gone, "reason") assertThat((actions?.get(Swipe.Up) as? UserActionResult.ChangeScene)?.toScene) Loading @@ -161,7 +159,6 @@ class ShadeUserActionsViewModelTest : SysuiTestCase() { testScope.runTest { val actions by collectLastValue(underTest.actions) kosmos.enableSplitShade() runCurrent() assertThat(actions?.get(Swipe.Up)?.transitionKey).isEqualTo(ToSplitShade) } Loading @@ -171,7 +168,6 @@ class ShadeUserActionsViewModelTest : SysuiTestCase() { testScope.runTest { val actions by collectLastValue(underTest.actions) kosmos.enableSingleShade() runCurrent() assertThat(actions?.get(Swipe.Up)?.transitionKey).isNull() } Loading Loading @@ -245,29 +241,19 @@ class ShadeUserActionsViewModelTest : SysuiTestCase() { } } private fun TestScope.setDeviceEntered(isEntered: Boolean) { private fun setDeviceEntered(isEntered: Boolean) { if (isEntered) { // Unlock the device marking the device has entered. kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( SuccessFingerprintAuthenticationStatus(0, true) ) runCurrent() } setScene( if (isEntered) { Scenes.Gone } else { Scenes.Lockscreen } ) setScene(if (isEntered) Scenes.Gone else Scenes.Lockscreen) assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isEqualTo(isEntered) } private fun TestScope.setScene(key: SceneKey) { private fun setScene(key: SceneKey) { sceneInteractor.changeScene(key, "test") sceneInteractor.setTransitionState( MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(key)) ) runCurrent() sceneInteractor.setTransitionState(flowOf(ObservableTransitionState.Idle(key))) } }