Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt +37 −5 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepos import com.android.systemui.keyguard.data.repository.keyguardClockRepository import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.ClockSizeSetting import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.DozeTransitionModel import com.android.systemui.keyguard.shared.model.KeyguardState Loading Loading @@ -68,6 +69,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() { fun clockSize_sceneContainerFlagOff_basedOnRepository() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.DYNAMIC) kosmos.keyguardClockRepository.setClockSize(ClockSize.LARGE) assertThat(value).isEqualTo(ClockSize.LARGE) Loading @@ -75,6 +77,17 @@ class KeyguardClockInteractorTest : SysuiTestCase() { assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @DisableSceneContainer fun clockSize_sceneContainerFlagOff_smallClockSettingSelected_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.SMALL) kosmos.keyguardClockRepository.setClockSize(ClockSize.LARGE) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockSize_forceSmallClock_SMALL() = Loading @@ -91,59 +104,78 @@ class KeyguardClockInteractorTest : SysuiTestCase() { @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSingle_hasNotifs_SMALL() = fun clockSize_sceneContainerFlagOn_shadeModeSingle_hasNotifs_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.shadeRepository.setShadeLayoutWide(false) kosmos.activeNotificationListRepository.setActiveNotifs(1) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSingle_hasMedia_SMALL() = fun clockSize_sceneContainerFlagOn_shadeModeSingle_hasMedia_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.shadeRepository.setShadeLayoutWide(false) val userMedia = MediaData().copy(active = true) kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSplit_isMediaVisible_SMALL() = fun clockSize_sceneContainerFlagOn_shadeModeSplit_isMediaVisible_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) val userMedia = MediaData().copy(active = true) kosmos.shadeRepository.setShadeLayoutWide(true) kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) kosmos.keyguardRepository.setIsDozing(false) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSplit_noMedia_LARGE() = fun clockSize_sceneContainerFlagOn_shadeModeSplit_noMedia_LARGE() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.shadeRepository.setShadeLayoutWide(true) kosmos.keyguardRepository.setIsDozing(false) assertThat(value).isEqualTo(ClockSize.LARGE) } @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSplit_isDozing_LARGE() = fun clockSize_sceneContainerFlagOn_shadeModeSplit_isDozing_LARGE() = testScope.runTest { val value by collectLastValue(underTest.clockSize) val userMedia = MediaData().copy(active = true) kosmos.shadeRepository.setShadeLayoutWide(true) kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) kosmos.keyguardRepository.setIsDozing(true) assertThat(value).isEqualTo(ClockSize.LARGE) } @Test @EnableSceneContainer fun clockSize_sceneContainerFlagOn_shadeModeSplit_smallClockSettingSelectd_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) val userMedia = MediaData().copy(active = true) kosmos.fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.SMALL) kosmos.shadeRepository.setShadeLayoutWide(true) kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) kosmos.keyguardRepository.setIsDozing(true) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockShouldBeCentered_sceneContainerFlagOn_notSplitMode_true() = Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt +10 −39 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.keyguardClockRepository import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.ClockSizeSetting import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel.ClockLayout import com.android.systemui.kosmos.testScope Loading Loading @@ -55,17 +54,18 @@ import platform.test.runner.parameterized.Parameters @SmallTest @RunWith(ParameterizedAndroidJunit4::class) class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { val kosmos = testKosmos() val testScope = kosmos.testScope val underTest by lazy { kosmos.keyguardClockViewModel } val res = context.resources @Mock lateinit var clockController: ClockController @Mock lateinit var largeClock: ClockFaceController @Mock lateinit var smallClock: ClockFaceController private val kosmos = testKosmos() private val testScope = kosmos.testScope private val underTest by lazy { kosmos.keyguardClockViewModel } private val res = context.resources var config = ClockConfig("TEST", "Test", "") var faceConfig = ClockFaceConfig() @Mock private lateinit var clockController: ClockController @Mock private lateinit var largeClock: ClockFaceController @Mock private lateinit var smallClock: ClockFaceController private var config = ClockConfig("TEST", "Test", "") private var faceConfig = ClockFaceConfig() init { mSetFlagsRule.setFlagsParameterization(flags) Loading Loading @@ -195,35 +195,6 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase() assertThat(hasCustomPositionUpdatedAnimation).isEqualTo(false) } @Test fun testClockSize_alwaysSmallClockSize() = testScope.runTest { val value by collectLastValue(underTest.clockSize) with(kosmos) { fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.SMALL) keyguardClockRepository.setClockSize(ClockSize.LARGE) } assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @DisableSceneContainer fun testClockSize_dynamicClockSize() = testScope.runTest { with(kosmos) { val value by collectLastValue(underTest.clockSize) fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.DYNAMIC) keyguardClockRepository.setClockSize(ClockSize.SMALL) assertThat(value).isEqualTo(ClockSize.SMALL) keyguardClockRepository.setClockSize(ClockSize.LARGE) assertThat(value).isEqualTo(ClockSize.LARGE) } } @Test fun isLargeClockVisible_whenLargeClockSize_isTrue() = testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt +41 −26 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.data.repository.KeyguardClockRepository import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.ClockSizeSetting import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING import com.android.systemui.keyguard.shared.model.KeyguardState.GONE Loading @@ -33,12 +32,13 @@ import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarou import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockId import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiAod import com.android.systemui.statusbar.notification.promoted.domain.interactor.AODPromotedNotificationInteractor import com.android.systemui.util.kotlin.combine import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import com.android.systemui.wallpapers.domain.interactor.WallpaperFocalAreaInteractor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope Loading @@ -61,7 +61,7 @@ constructor( mediaCarouselInteractor: MediaCarouselInteractor, activeNotificationsInteractor: ActiveNotificationsInteractor, aodPromotedNotificationInteractor: AODPromotedNotificationInteractor, shadeInteractor: ShadeInteractor, shadeModeInteractor: ShadeModeInteractor, keyguardInteractor: KeyguardInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, headsUpNotificationInteractor: HeadsUpNotificationInteractor, Loading @@ -70,8 +70,13 @@ constructor( private val wallpaperFocalAreaInteractor: WallpaperFocalAreaInteractor, ) { private val isOnAod: Flow<Boolean> = keyguardTransitionInteractor.currentKeyguardState.map { it == KeyguardState.AOD } keyguardTransitionInteractor.currentKeyguardState.map { it == AOD } /** * The clock size setting explicitly selected by the user. When it is `SMALL`, the large clock * is never shown. When it is `DYNAMIC`, the clock size gets determined based on a combination * of system signals. */ val selectedClockSize: StateFlow<ClockSizeSetting> = keyguardClockRepository.selectedClockSize val currentClockId: Flow<ClockId> = keyguardClockRepository.currentClockId Loading Loading @@ -103,16 +108,16 @@ constructor( activeNotificationsInteractor.areAnyNotificationsPresent } val clockSize: StateFlow<ClockSize> = private val dynamicClockSize: Flow<ClockSize> = if (SceneContainerFlag.isEnabled) { combine( shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, areAnyNotificationsPresent, mediaCarouselInteractor.hasActiveMediaOrRecommendation, keyguardInteractor.isDozing, isOnAod, ) { isShadeLayoutWide, hasNotifs, hasMedia, isDozing, isOnAod -> return@combine when { when { keyguardClockRepository.shouldForceSmallClock && !isOnAod -> ClockSize.SMALL !isShadeLayoutWide && (hasNotifs || hasMedia) -> ClockSize.SMALL !isShadeLayoutWide -> ClockSize.LARGE Loading @@ -120,19 +125,29 @@ constructor( else -> ClockSize.LARGE } } } else { keyguardClockRepository.clockSize } val clockSize: StateFlow<ClockSize> = selectedClockSize .flatMapLatestConflated { selectedSize -> if (selectedSize == ClockSizeSetting.SMALL) { flowOf(ClockSize.SMALL) } else { dynamicClockSize } } .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), started = SharingStarted.Eagerly, initialValue = ClockSize.LARGE, ) } else { keyguardClockRepository.clockSize } val clockShouldBeCentered: Flow<Boolean> = if (SceneContainerFlag.isEnabled) { combine( shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, areAnyNotificationsPresent, isAodPromotedNotificationPresent, isOnAod, Loading @@ -156,7 +171,7 @@ constructor( } } else { combine( shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, areAnyNotificationsPresent, isAodPromotedNotificationPresent, keyguardInteractor.dozeTransitionModel, Loading Loading @@ -203,7 +218,7 @@ constructor( val renderedClockId: ClockId get() { return clock?.let { clock -> clock.config.id } return clock?.config?.id ?: run { Log.e(TAG, "No clock is available") "MISSING_CLOCK_ID" Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt +5 −5 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.Edge import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.StateToValue Loading @@ -35,6 +34,7 @@ import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlin.math.max import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted Loading @@ -51,6 +51,7 @@ import kotlinx.coroutines.flow.stateIn * Models UI state for elements that need to apply anti-burn-in tactics when showing in AOD * (always-on display). */ @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton class AodBurnInViewModel @Inject Loading Loading @@ -184,10 +185,9 @@ constructor( keyguardClockViewModel.currentClock.value ?.config ?.useAlternateSmartspaceAODTransition == true // Only scale large non-weather clocks // elements in large weather clock will translate the same as smartspace val useScaleOnly = (!useAltAod) && keyguardClockViewModel.clockSize.value == ClockSize.LARGE // Only scale large non-weather clocks elements in large weather clock will translate // the same as smartspace val useScaleOnly = (!useAltAod) && keyguardClockViewModel.isLargeClockVisible.value val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolated).toInt() val translationY = max(params.topInset - params.minViewY, burnInY) Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt +7 −19 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import android.content.Context import android.content.res.Resources import androidx.annotation.VisibleForTesting import androidx.constraintlayout.helper.widget.Layer import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.customization.R as customR Loading @@ -27,11 +26,10 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.ClockSizeSetting import com.android.systemui.plugins.clocks.ClockPreviewConfig import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel import com.android.systemui.statusbar.ui.SystemBarUtilsProxy import javax.inject.Inject Loading @@ -47,11 +45,11 @@ import kotlinx.coroutines.flow.stateIn class KeyguardClockViewModel @Inject constructor( val context: Context, private val context: Context, keyguardClockInteractor: KeyguardClockInteractor, @Application private val applicationScope: CoroutineScope, aodNotificationIconViewModel: NotificationIconContainerAlwaysOnDisplayViewModel, @get:VisibleForTesting val shadeInteractor: ShadeInteractor, private val shadeModeInteractor: ShadeModeInteractor, private val systemBarUtils: SystemBarUtilsProxy, @ShadeDisplayAware configurationInteractor: ConfigurationInteractor, // TODO: b/374267505 - Use ShadeDisplayAware resources here. Loading @@ -59,17 +57,7 @@ constructor( ) { var burnInLayer: Layer? = null val clockSize: StateFlow<ClockSize> = combine(keyguardClockInteractor.selectedClockSize, keyguardClockInteractor.clockSize) { selectedSize, clockSize -> if (selectedSize == ClockSizeSetting.SMALL) ClockSize.SMALL else clockSize } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, initialValue = ClockSize.LARGE, ) val clockSize: StateFlow<ClockSize> = keyguardClockInteractor.clockSize val isLargeClockVisible: StateFlow<Boolean> = clockSize Loading Loading @@ -118,7 +106,7 @@ constructor( combine( isLargeClockVisible, clockShouldBeCentered, shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, currentClock, ) { isLargeClockVisible, clockShouldBeCentered, isShadeLayoutWide, currentClock -> if (currentClock?.config?.useCustomClockScene == true) { Loading Loading @@ -163,7 +151,7 @@ constructor( fun getSmallClockTopMargin(): Int { return ClockPreviewConfig( context, shadeInteractor.isShadeLayoutWide.value, shadeModeInteractor.isShadeLayoutWide.value, SceneContainerFlag.isEnabled, ) .getSmallClockTopPadding(systemBarUtils.getStatusBarHeaderHeightKeyguard()) Loading @@ -172,7 +160,7 @@ constructor( val smallClockTopMargin = combine( configurationInteractor.onAnyConfigurationChange, shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, ) { _, _ -> getSmallClockTopMargin() } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorTest.kt +37 −5 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepos import com.android.systemui.keyguard.data.repository.keyguardClockRepository import com.android.systemui.keyguard.data.repository.keyguardRepository import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.ClockSizeSetting import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.DozeTransitionModel import com.android.systemui.keyguard.shared.model.KeyguardState Loading Loading @@ -68,6 +69,7 @@ class KeyguardClockInteractorTest : SysuiTestCase() { fun clockSize_sceneContainerFlagOff_basedOnRepository() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.DYNAMIC) kosmos.keyguardClockRepository.setClockSize(ClockSize.LARGE) assertThat(value).isEqualTo(ClockSize.LARGE) Loading @@ -75,6 +77,17 @@ class KeyguardClockInteractorTest : SysuiTestCase() { assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @DisableSceneContainer fun clockSize_sceneContainerFlagOff_smallClockSettingSelected_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.SMALL) kosmos.keyguardClockRepository.setClockSize(ClockSize.LARGE) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockSize_forceSmallClock_SMALL() = Loading @@ -91,59 +104,78 @@ class KeyguardClockInteractorTest : SysuiTestCase() { @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSingle_hasNotifs_SMALL() = fun clockSize_sceneContainerFlagOn_shadeModeSingle_hasNotifs_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.shadeRepository.setShadeLayoutWide(false) kosmos.activeNotificationListRepository.setActiveNotifs(1) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSingle_hasMedia_SMALL() = fun clockSize_sceneContainerFlagOn_shadeModeSingle_hasMedia_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.shadeRepository.setShadeLayoutWide(false) val userMedia = MediaData().copy(active = true) kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSplit_isMediaVisible_SMALL() = fun clockSize_sceneContainerFlagOn_shadeModeSplit_isMediaVisible_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) val userMedia = MediaData().copy(active = true) kosmos.shadeRepository.setShadeLayoutWide(true) kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) kosmos.keyguardRepository.setIsDozing(false) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSplit_noMedia_LARGE() = fun clockSize_sceneContainerFlagOn_shadeModeSplit_noMedia_LARGE() = testScope.runTest { val value by collectLastValue(underTest.clockSize) kosmos.shadeRepository.setShadeLayoutWide(true) kosmos.keyguardRepository.setIsDozing(false) assertThat(value).isEqualTo(ClockSize.LARGE) } @Test @EnableSceneContainer fun clockSize_SceneContainerFlagOn_shadeModeSplit_isDozing_LARGE() = fun clockSize_sceneContainerFlagOn_shadeModeSplit_isDozing_LARGE() = testScope.runTest { val value by collectLastValue(underTest.clockSize) val userMedia = MediaData().copy(active = true) kosmos.shadeRepository.setShadeLayoutWide(true) kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) kosmos.keyguardRepository.setIsDozing(true) assertThat(value).isEqualTo(ClockSize.LARGE) } @Test @EnableSceneContainer fun clockSize_sceneContainerFlagOn_shadeModeSplit_smallClockSettingSelectd_SMALL() = testScope.runTest { val value by collectLastValue(underTest.clockSize) val userMedia = MediaData().copy(active = true) kosmos.fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.SMALL) kosmos.shadeRepository.setShadeLayoutWide(true) kosmos.mediaFilterRepository.addSelectedUserMediaEntry(userMedia) kosmos.keyguardRepository.setIsDozing(true) assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @EnableSceneContainer fun clockShouldBeCentered_sceneContainerFlagOn_notSplitMode_true() = Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt +10 −39 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.keyguardClockRepository import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.ClockSizeSetting import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel.ClockLayout import com.android.systemui.kosmos.testScope Loading Loading @@ -55,17 +54,18 @@ import platform.test.runner.parameterized.Parameters @SmallTest @RunWith(ParameterizedAndroidJunit4::class) class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { val kosmos = testKosmos() val testScope = kosmos.testScope val underTest by lazy { kosmos.keyguardClockViewModel } val res = context.resources @Mock lateinit var clockController: ClockController @Mock lateinit var largeClock: ClockFaceController @Mock lateinit var smallClock: ClockFaceController private val kosmos = testKosmos() private val testScope = kosmos.testScope private val underTest by lazy { kosmos.keyguardClockViewModel } private val res = context.resources var config = ClockConfig("TEST", "Test", "") var faceConfig = ClockFaceConfig() @Mock private lateinit var clockController: ClockController @Mock private lateinit var largeClock: ClockFaceController @Mock private lateinit var smallClock: ClockFaceController private var config = ClockConfig("TEST", "Test", "") private var faceConfig = ClockFaceConfig() init { mSetFlagsRule.setFlagsParameterization(flags) Loading Loading @@ -195,35 +195,6 @@ class KeyguardClockViewModelTest(flags: FlagsParameterization) : SysuiTestCase() assertThat(hasCustomPositionUpdatedAnimation).isEqualTo(false) } @Test fun testClockSize_alwaysSmallClockSize() = testScope.runTest { val value by collectLastValue(underTest.clockSize) with(kosmos) { fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.SMALL) keyguardClockRepository.setClockSize(ClockSize.LARGE) } assertThat(value).isEqualTo(ClockSize.SMALL) } @Test @DisableSceneContainer fun testClockSize_dynamicClockSize() = testScope.runTest { with(kosmos) { val value by collectLastValue(underTest.clockSize) fakeKeyguardClockRepository.setSelectedClockSize(ClockSizeSetting.DYNAMIC) keyguardClockRepository.setClockSize(ClockSize.SMALL) assertThat(value).isEqualTo(ClockSize.SMALL) keyguardClockRepository.setClockSize(ClockSize.LARGE) assertThat(value).isEqualTo(ClockSize.LARGE) } } @Test fun isLargeClockVisible_whenLargeClockSize_isTrue() = testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt +41 −26 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.data.repository.KeyguardClockRepository import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.ClockSizeSetting import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING import com.android.systemui.keyguard.shared.model.KeyguardState.GONE Loading @@ -33,12 +32,13 @@ import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarou import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockId import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiAod import com.android.systemui.statusbar.notification.promoted.domain.interactor.AODPromotedNotificationInteractor import com.android.systemui.util.kotlin.combine import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import com.android.systemui.wallpapers.domain.interactor.WallpaperFocalAreaInteractor import javax.inject.Inject import kotlinx.coroutines.CoroutineScope Loading @@ -61,7 +61,7 @@ constructor( mediaCarouselInteractor: MediaCarouselInteractor, activeNotificationsInteractor: ActiveNotificationsInteractor, aodPromotedNotificationInteractor: AODPromotedNotificationInteractor, shadeInteractor: ShadeInteractor, shadeModeInteractor: ShadeModeInteractor, keyguardInteractor: KeyguardInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, headsUpNotificationInteractor: HeadsUpNotificationInteractor, Loading @@ -70,8 +70,13 @@ constructor( private val wallpaperFocalAreaInteractor: WallpaperFocalAreaInteractor, ) { private val isOnAod: Flow<Boolean> = keyguardTransitionInteractor.currentKeyguardState.map { it == KeyguardState.AOD } keyguardTransitionInteractor.currentKeyguardState.map { it == AOD } /** * The clock size setting explicitly selected by the user. When it is `SMALL`, the large clock * is never shown. When it is `DYNAMIC`, the clock size gets determined based on a combination * of system signals. */ val selectedClockSize: StateFlow<ClockSizeSetting> = keyguardClockRepository.selectedClockSize val currentClockId: Flow<ClockId> = keyguardClockRepository.currentClockId Loading Loading @@ -103,16 +108,16 @@ constructor( activeNotificationsInteractor.areAnyNotificationsPresent } val clockSize: StateFlow<ClockSize> = private val dynamicClockSize: Flow<ClockSize> = if (SceneContainerFlag.isEnabled) { combine( shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, areAnyNotificationsPresent, mediaCarouselInteractor.hasActiveMediaOrRecommendation, keyguardInteractor.isDozing, isOnAod, ) { isShadeLayoutWide, hasNotifs, hasMedia, isDozing, isOnAod -> return@combine when { when { keyguardClockRepository.shouldForceSmallClock && !isOnAod -> ClockSize.SMALL !isShadeLayoutWide && (hasNotifs || hasMedia) -> ClockSize.SMALL !isShadeLayoutWide -> ClockSize.LARGE Loading @@ -120,19 +125,29 @@ constructor( else -> ClockSize.LARGE } } } else { keyguardClockRepository.clockSize } val clockSize: StateFlow<ClockSize> = selectedClockSize .flatMapLatestConflated { selectedSize -> if (selectedSize == ClockSizeSetting.SMALL) { flowOf(ClockSize.SMALL) } else { dynamicClockSize } } .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), started = SharingStarted.Eagerly, initialValue = ClockSize.LARGE, ) } else { keyguardClockRepository.clockSize } val clockShouldBeCentered: Flow<Boolean> = if (SceneContainerFlag.isEnabled) { combine( shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, areAnyNotificationsPresent, isAodPromotedNotificationPresent, isOnAod, Loading @@ -156,7 +171,7 @@ constructor( } } else { combine( shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, areAnyNotificationsPresent, isAodPromotedNotificationPresent, keyguardInteractor.dozeTransitionModel, Loading Loading @@ -203,7 +218,7 @@ constructor( val renderedClockId: ClockId get() { return clock?.let { clock -> clock.config.id } return clock?.config?.id ?: run { Log.e(TAG, "No clock is available") "MISSING_CLOCK_ID" Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt +5 −5 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.Edge import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.ui.StateToValue Loading @@ -35,6 +34,7 @@ import com.android.systemui.shade.ShadeDisplayAware import javax.inject.Inject import kotlin.math.max import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted Loading @@ -51,6 +51,7 @@ import kotlinx.coroutines.flow.stateIn * Models UI state for elements that need to apply anti-burn-in tactics when showing in AOD * (always-on display). */ @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton class AodBurnInViewModel @Inject Loading Loading @@ -184,10 +185,9 @@ constructor( keyguardClockViewModel.currentClock.value ?.config ?.useAlternateSmartspaceAODTransition == true // Only scale large non-weather clocks // elements in large weather clock will translate the same as smartspace val useScaleOnly = (!useAltAod) && keyguardClockViewModel.clockSize.value == ClockSize.LARGE // Only scale large non-weather clocks elements in large weather clock will translate // the same as smartspace val useScaleOnly = (!useAltAod) && keyguardClockViewModel.isLargeClockVisible.value val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolated).toInt() val translationY = max(params.topInset - params.minViewY, burnInY) Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt +7 −19 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import android.content.Context import android.content.res.Resources import androidx.annotation.VisibleForTesting import androidx.constraintlayout.helper.widget.Layer import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.customization.R as customR Loading @@ -27,11 +26,10 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.keyguard.shared.model.ClockSizeSetting import com.android.systemui.plugins.clocks.ClockPreviewConfig import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.ShadeDisplayAware import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shade.domain.interactor.ShadeModeInteractor import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel import com.android.systemui.statusbar.ui.SystemBarUtilsProxy import javax.inject.Inject Loading @@ -47,11 +45,11 @@ import kotlinx.coroutines.flow.stateIn class KeyguardClockViewModel @Inject constructor( val context: Context, private val context: Context, keyguardClockInteractor: KeyguardClockInteractor, @Application private val applicationScope: CoroutineScope, aodNotificationIconViewModel: NotificationIconContainerAlwaysOnDisplayViewModel, @get:VisibleForTesting val shadeInteractor: ShadeInteractor, private val shadeModeInteractor: ShadeModeInteractor, private val systemBarUtils: SystemBarUtilsProxy, @ShadeDisplayAware configurationInteractor: ConfigurationInteractor, // TODO: b/374267505 - Use ShadeDisplayAware resources here. Loading @@ -59,17 +57,7 @@ constructor( ) { var burnInLayer: Layer? = null val clockSize: StateFlow<ClockSize> = combine(keyguardClockInteractor.selectedClockSize, keyguardClockInteractor.clockSize) { selectedSize, clockSize -> if (selectedSize == ClockSizeSetting.SMALL) ClockSize.SMALL else clockSize } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, initialValue = ClockSize.LARGE, ) val clockSize: StateFlow<ClockSize> = keyguardClockInteractor.clockSize val isLargeClockVisible: StateFlow<Boolean> = clockSize Loading Loading @@ -118,7 +106,7 @@ constructor( combine( isLargeClockVisible, clockShouldBeCentered, shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, currentClock, ) { isLargeClockVisible, clockShouldBeCentered, isShadeLayoutWide, currentClock -> if (currentClock?.config?.useCustomClockScene == true) { Loading Loading @@ -163,7 +151,7 @@ constructor( fun getSmallClockTopMargin(): Int { return ClockPreviewConfig( context, shadeInteractor.isShadeLayoutWide.value, shadeModeInteractor.isShadeLayoutWide.value, SceneContainerFlag.isEnabled, ) .getSmallClockTopPadding(systemBarUtils.getStatusBarHeaderHeightKeyguard()) Loading @@ -172,7 +160,7 @@ constructor( val smallClockTopMargin = combine( configurationInteractor.onAnyConfigurationChange, shadeInteractor.isShadeLayoutWide, shadeModeInteractor.isShadeLayoutWide, ) { _, _ -> getSmallClockTopMargin() } Loading