diff options
| author | 2023-09-14 17:56:33 +0000 | |
|---|---|---|
| committer | 2023-09-20 22:01:40 +0000 | |
| commit | 8cde9e25074c1395b955f8f026c4433765a7580a (patch) | |
| tree | e1478a309904164823b89f4039cf6450671521ea | |
| parent | 71a57780ef4a28de80d5fdb115046e8b7e747c6c (diff) | |
Introduce communal scene
This change introduces a communal scene that is placed to the right of
keyguard, and is protected by a config that is disabled by default.
Bug: 300483707
Fix: 300483707
Test: atest LockscreenSceneViewModelTest
Test: atest SceneFrameworkIntegrationTest
Test: atest SystemUiRoboTests:CommunalInteractorTest
Test: enable config_communalServiceEnabled in titan overlay, flexiglass on
(see go/flexiglass-dev-guide), swipe left on keyguard and see communal
scene
Test: without titan overlay change, flexiglass on, swipe left on
keyguard and nothing happens
Change-Id: I43429f68702895ba085cad09749dbfb33264bb60
19 files changed, 300 insertions, 19 deletions
diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/CommunalSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/CommunalSceneModule.kt new file mode 100644 index 000000000000..f80a90659545 --- /dev/null +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/CommunalSceneModule.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import dagger.Module + +@Module interface CommunalSceneModule diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/CommunalSceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/CommunalSceneModule.kt new file mode 100644 index 000000000000..94b5db2535ab --- /dev/null +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/CommunalSceneModule.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import com.android.systemui.communal.ui.compose.CommunalScene +import com.android.systemui.scene.shared.model.Scene +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet + +@Module +interface CommunalSceneModule { + @Binds @IntoSet fun communalScene(scene: CommunalScene): Scene +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt new file mode 100644 index 000000000000..0d2ba2824846 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.ui.compose + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import com.android.compose.animation.scene.SceneScope +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.scene.shared.model.Direction +import com.android.systemui.scene.shared.model.SceneKey +import com.android.systemui.scene.shared.model.SceneModel +import com.android.systemui.scene.shared.model.UserAction +import com.android.systemui.scene.ui.composable.ComposableScene +import javax.inject.Inject +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +/** The communal scene shows glanceable hub when the device is locked and docked. */ +@SysUISingleton +class CommunalScene @Inject constructor() : ComposableScene { + override val key = SceneKey.Communal + + override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> = + MutableStateFlow<Map<UserAction, SceneModel>>( + mapOf( + UserAction.Swipe(Direction.RIGHT) to SceneModel(SceneKey.Lockscreen), + ) + ) + .asStateFlow() + + @Composable + override fun SceneScope.Content(modifier: Modifier) { + Box( + modifier = modifier.fillMaxSize().background(Color.White), + ) { + Text( + modifier = Modifier.align(Alignment.Center), + text = "Hello Communal!", + ) + } + } +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt index f1da16862220..77daebb9b8a0 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt @@ -68,11 +68,17 @@ constructor( override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> = viewModel.upDestinationSceneKey - .map { pageKey -> destinationScenes(up = pageKey) } + .map { pageKey -> + destinationScenes(up = pageKey, left = viewModel.leftDestinationSceneKey) + } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, - initialValue = destinationScenes(up = viewModel.upDestinationSceneKey.value) + initialValue = + destinationScenes( + up = viewModel.upDestinationSceneKey.value, + left = viewModel.leftDestinationSceneKey, + ) ) @Composable @@ -88,9 +94,11 @@ constructor( private fun destinationScenes( up: SceneKey?, + left: SceneKey?, ): Map<UserAction, SceneModel> { return buildMap { up?.let { this[UserAction.Swipe(Direction.UP)] = SceneModel(up) } + left?.let { this[UserAction.Swipe(Direction.LEFT)] = SceneModel(left) } this[UserAction.Swipe(Direction.DOWN)] = SceneModel(SceneKey.Shade) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt index 404bf81ee387..2848245c42b1 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt @@ -5,6 +5,7 @@ import com.android.systemui.scene.ui.composable.transitions.bouncerToGoneTransit import com.android.systemui.scene.ui.composable.transitions.goneToQuickSettingsTransition import com.android.systemui.scene.ui.composable.transitions.goneToShadeTransition import com.android.systemui.scene.ui.composable.transitions.lockscreenToBouncerTransition +import com.android.systemui.scene.ui.composable.transitions.lockscreenToCommunalTransition import com.android.systemui.scene.ui.composable.transitions.lockscreenToGoneTransition import com.android.systemui.scene.ui.composable.transitions.lockscreenToQuickSettingsTransition import com.android.systemui.scene.ui.composable.transitions.lockscreenToShadeTransition @@ -13,7 +14,7 @@ import com.android.systemui.scene.ui.composable.transitions.shadeToQuickSettings /** * Comprehensive definition of all transitions between scenes in [SceneContainer]. * - * Transitions are automatically reversible, so define only one transition per scene pair. By + * Transitions are automatically reversible, so define only one transition per scene pair. By\ * convention, use the more common transition direction when defining the pair order, e.g. * Lockscreen to Bouncer rather than Bouncer to Lockscreen. * @@ -27,6 +28,7 @@ val SceneContainerTransitions = transitions { from(Gone, to = Shade) { goneToShadeTransition() } from(Gone, to = QuickSettings) { goneToQuickSettingsTransition() } from(Lockscreen, to = Bouncer) { lockscreenToBouncerTransition() } + from(Lockscreen, to = Communal) { lockscreenToCommunalTransition() } from(Lockscreen, to = Shade) { lockscreenToShadeTransition() } from(Lockscreen, to = QuickSettings) { lockscreenToQuickSettingsTransition() } from(Lockscreen, to = Gone) { lockscreenToGoneTransition() } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/TransitionSceneKeys.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/TransitionSceneKeys.kt index 8d0d7050dcca..5336bf646231 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/TransitionSceneKeys.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/TransitionSceneKeys.kt @@ -8,6 +8,7 @@ val Bouncer = SceneKey.Bouncer.toTransitionSceneKey() val Shade = SceneKey.Shade.toTransitionSceneKey() val QuickSettings = SceneKey.QuickSettings.toTransitionSceneKey() val Gone = SceneKey.Gone.toTransitionSceneKey() +val Communal = SceneKey.Communal.toTransitionSceneKey() // TODO(b/293899074): Remove this file once we can use the scene keys from SceneTransitionLayout. fun SceneKey.toTransitionSceneKey(): SceneTransitionSceneKey { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToCommunalTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToCommunalTransition.kt new file mode 100644 index 000000000000..ea8110ad8518 --- /dev/null +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToCommunalTransition.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene.ui.composable.transitions + +import androidx.compose.animation.core.tween +import com.android.compose.animation.scene.Edge +import com.android.compose.animation.scene.TransitionBuilder +import com.android.systemui.scene.ui.composable.Communal +import com.android.systemui.scene.ui.composable.Lockscreen + +fun TransitionBuilder.lockscreenToCommunalTransition() { + spec = tween(durationMillis = 500) + + // Translate lockscreen to the left. + translate(Lockscreen.rootElementKey, Edge.Left) + + // Translate communal from the right. + translate(Communal.rootElementKey, Edge.Right) +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt new file mode 100644 index 000000000000..ea3ddacd7d5e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepository.kt @@ -0,0 +1,21 @@ +package com.android.systemui.communal.data.repository + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags +import javax.inject.Inject + +/** Encapsulates the state of communal mode. */ +interface CommunalRepository { + /** Whether communal features are enabled. */ + val isCommunalEnabled: Boolean +} + +@SysUISingleton +class CommunalRepositoryImpl +@Inject +constructor( + featureFlags: FeatureFlagsClassic, +) : CommunalRepository { + override val isCommunalEnabled = featureFlags.isEnabled(Flags.COMMUNAL_HUB) +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepositoryModule.kt new file mode 100644 index 000000000000..9d95b9eb262a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalRepositoryModule.kt @@ -0,0 +1,9 @@ +package com.android.systemui.communal.data.repository + +import dagger.Binds +import dagger.Module + +@Module +interface CommunalRepositoryModule { + @Binds fun communalRepository(impl: CommunalRepositoryImpl): CommunalRepository +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt index 6dc305e6f826..9fb8da3e76af 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt @@ -16,6 +16,7 @@ package com.android.systemui.communal.domain.interactor +import com.android.systemui.communal.data.repository.CommunalRepository import com.android.systemui.communal.data.repository.CommunalWidgetRepository import com.android.systemui.communal.shared.CommunalAppWidgetInfo import com.android.systemui.dagger.SysUISingleton @@ -27,8 +28,12 @@ import kotlinx.coroutines.flow.Flow class CommunalInteractor @Inject constructor( + communalRepository: CommunalRepository, widgetRepository: CommunalWidgetRepository, ) { + /** Whether communal features are enabled. */ + val isCommunalEnabled: Boolean = communalRepository.isCommunalEnabled + /** A flow of info about the widget to be displayed, or null if widget is unavailable. */ val appWidgetInfo: Flow<CommunalAppWidgetInfo?> = widgetRepository.stopwatchAppWidgetInfo } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index 13dfe24e7e19..03c166c05a62 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -37,6 +37,7 @@ import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.classifier.FalsingModule; +import com.android.systemui.communal.data.repository.CommunalRepositoryModule; import com.android.systemui.communal.data.repository.CommunalWidgetRepositoryModule; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; @@ -93,6 +94,7 @@ import kotlinx.coroutines.CoroutineDispatcher; KeyguardStatusViewComponent.class, KeyguardUserSwitcherComponent.class}, includes = { + CommunalRepositoryModule.class, CommunalWidgetRepositoryModule.class, FalsingModule.class, KeyguardDataQuickAffordanceModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt index cfcbdac4c4e9..91b33572345d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.ui.viewmodel import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor +import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.scene.shared.model.SceneKey @@ -34,6 +35,7 @@ class LockscreenSceneViewModel constructor( @Application applicationScope: CoroutineScope, authenticationInteractor: AuthenticationInteractor, + communalInteractor: CommunalInteractor, val longPress: KeyguardLongPressViewModel, ) { /** The key of the scene we should switch to when swiping up. */ @@ -53,4 +55,12 @@ constructor( SceneKey.Bouncer } } + + /** The key of the scene we should switch to when swiping left. */ + val leftDestinationSceneKey: SceneKey? = + if (communalInteractor.isCommunalEnabled) { + SceneKey.Communal + } else { + null + } } diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt index b36ec3274083..0f3acaf7fc0c 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt @@ -33,6 +33,7 @@ import dagger.multibindings.IntoMap includes = [ BouncerSceneModule::class, + CommunalSceneModule::class, EmptySceneModule::class, GoneSceneModule::class, LockscreenSceneModule::class, @@ -65,6 +66,7 @@ interface SceneContainerFrameworkModule { sceneKeys = listOf( SceneKey.Gone, + SceneKey.Communal, SceneKey.Lockscreen, SceneKey.Bouncer, SceneKey.Shade, diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt index e7811e39aa6f..609d2b93a36e 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneKey.kt @@ -16,7 +16,11 @@ package com.android.systemui.scene.shared.model -/** Keys of all known scenes. */ +/** + * Keys of all known scenes. + * + * PLEASE KEEP THE KEYS SORTED ALPHABETICALLY. + */ sealed class SceneKey( private val loggingName: String, ) { @@ -26,6 +30,9 @@ sealed class SceneKey( */ object Bouncer : SceneKey("bouncer") + /** The communal scene shows the glanceable hub when device is locked and docked. */ + object Communal : SceneKey("communal") + /** * "Gone" is not a real scene but rather the absence of scenes when we want to skip showing any * content from the scene framework. @@ -35,14 +42,14 @@ sealed class SceneKey( /** The lockscreen is the scene that shows when the device is locked. */ object Lockscreen : SceneKey("lockscreen") + /** The quick settings scene shows the quick setting tiles. */ + object QuickSettings : SceneKey("quick_settings") + /** * The shade is the scene whose primary purpose is to show a scrollable list of notifications. */ object Shade : SceneKey("shade") - /** The quick settings scene shows the quick setting tiles. */ - object QuickSettings : SceneKey("quick_settings") - override fun toString(): String { return loggingName } diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt index d28f530f04f3..ddf788e47bf2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt @@ -21,6 +21,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase +import com.android.systemui.communal.data.repository.FakeCommunalRepository import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository import com.android.systemui.communal.shared.CommunalAppWidgetInfo import com.android.systemui.coroutines.collectLastValue @@ -44,6 +45,7 @@ class CommunalInteractorTest : SysuiTestCase() { private lateinit var testScope: TestScope + private lateinit var communalRepository: FakeCommunalRepository private lateinit var widgetRepository: FakeCommunalWidgetRepository private lateinit var interactor: CommunalInteractor @@ -52,12 +54,13 @@ class CommunalInteractorTest : SysuiTestCase() { MockitoAnnotations.initMocks(this) testScope = TestScope() + communalRepository = FakeCommunalRepository() widgetRepository = FakeCommunalWidgetRepository() - interactor = CommunalInteractor(widgetRepository) + interactor = CommunalInteractor(communalRepository, widgetRepository) } @Test - fun testAppWidgetInfoFlow() = + fun appWidgetInfoFlow() = testScope.runTest { val lastAppWidgetInfo = collectLastValue(interactor.appWidgetInfo) runCurrent() @@ -67,4 +70,22 @@ class CommunalInteractorTest : SysuiTestCase() { runCurrent() assertThat(lastAppWidgetInfo()).isEqualTo(stopwatchAppWidgetInfo) } + + @Test + fun communalEnabled() = + testScope.runTest { + communalRepository.setIsCommunalEnabled(true) + + val interactor = CommunalInteractor(communalRepository, widgetRepository) + assertThat(interactor.isCommunalEnabled).isTrue() + } + + @Test + fun communalDisabled() = + testScope.runTest { + communalRepository.setIsCommunalEnabled(false) + + val interactor = CommunalInteractor(communalRepository, widgetRepository) + assertThat(interactor.isCommunalEnabled).isFalse() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt index f40ccfde5a92..1681cfdce822 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt @@ -42,15 +42,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { repository = utils.authenticationRepository(), ) - private val underTest = - LockscreenSceneViewModel( - applicationScope = testScope.backgroundScope, - authenticationInteractor = authenticationInteractor, - longPress = - KeyguardLongPressViewModel( - interactor = mock(), - ), - ) + private val underTest = createLockscreenSceneViewModel() @Test fun upTransitionSceneKey_canSwipeToUnlock_gone() = @@ -74,4 +66,34 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { assertThat(upTransitionSceneKey).isEqualTo(SceneKey.Bouncer) } + + @Test + fun leftTransitionSceneKey_communalIsEnabled_communal() = + testScope.runTest { + utils.communalRepository.setIsCommunalEnabled(true) + val underTest = createLockscreenSceneViewModel() + + assertThat(underTest.leftDestinationSceneKey).isEqualTo(SceneKey.Communal) + } + + @Test + fun leftTransitionSceneKey_communalIsDisabled_null() = + testScope.runTest { + utils.communalRepository.setIsCommunalEnabled(false) + val underTest = createLockscreenSceneViewModel() + + assertThat(underTest.leftDestinationSceneKey).isNull() + } + + private fun createLockscreenSceneViewModel(): LockscreenSceneViewModel { + return LockscreenSceneViewModel( + applicationScope = testScope.backgroundScope, + authenticationInteractor = authenticationInteractor, + communalInteractor = utils.communalInteractor(), + longPress = + KeyguardLongPressViewModel( + interactor = mock(), + ), + ) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt index 78385cd516c8..12ab24a62066 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt @@ -99,6 +99,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { sceneInteractor = sceneInteractor, ) + private val communalInteractor = utils.communalInteractor() + private val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(sceneContainerConfig.initialSceneKey) @@ -125,6 +127,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { LockscreenSceneViewModel( applicationScope = testScope.backgroundScope, authenticationInteractor = authenticationInteractor, + communalInteractor = communalInteractor, longPress = KeyguardLongPressViewModel( interactor = mock(), diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt new file mode 100644 index 000000000000..e1c6ddefc13b --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalRepository.kt @@ -0,0 +1,10 @@ +package com.android.systemui.communal.data.repository + +/** Fake implementation of [CommunalRepository]. */ +class FakeCommunalRepository : CommunalRepository { + override var isCommunalEnabled = false + + fun setIsCommunalEnabled(value: Boolean) { + isCommunalEnabled = value + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt index 2d79e0f5f1e4..1620dc278950 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt @@ -31,6 +31,9 @@ import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollectorFake import com.android.systemui.classifier.domain.interactor.FalsingInteractor import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository +import com.android.systemui.communal.data.repository.FakeCommunalRepository +import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository +import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeCommandQueue @@ -94,7 +97,10 @@ class SceneTestUtils( ) } } - + val communalRepository: FakeCommunalRepository by lazy { FakeCommunalRepository() } + private val communalWidgetRepository: FakeCommunalWidgetRepository by lazy { + FakeCommunalWidgetRepository() + } val powerRepository: FakePowerRepository by lazy { FakePowerRepository() } private val context = test.context @@ -171,6 +177,13 @@ class SceneTestUtils( ) } + fun communalInteractor(): CommunalInteractor { + return CommunalInteractor( + communalRepository = communalRepository, + widgetRepository = communalWidgetRepository, + ) + } + fun bouncerInteractor( authenticationInteractor: AuthenticationInteractor, sceneInteractor: SceneInteractor, |