Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryImplTest.kt +0 −21 Original line number Diff line number Diff line Loading @@ -21,23 +21,18 @@ import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.SysuiTestCase import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.backgroundScope import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.scene.shared.model.SceneDataSource import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.mock import org.mockito.kotlin.verify @SmallTest @RunWith(AndroidJUnit4::class) Loading @@ -49,10 +44,8 @@ class CommunalSceneRepositoryImplTest : SysuiTestCase() { private val Kosmos.underTest by Kosmos.Fixture { CommunalSceneRepositoryImpl( applicationScope = applicationCoroutineScope, backgroundScope = backgroundScope, sceneDataSource = delegator, delegator = delegator, ) } Loading Loading @@ -90,18 +83,4 @@ class CommunalSceneRepositoryImplTest : SysuiTestCase() { assertThat(transitionState) .isEqualTo(ObservableTransitionState.Idle(CommunalScenes.Default)) } @Test fun showHubFromPowerButton() = kosmos.runTest { fakeKeyguardRepository.setKeyguardShowing(false) underTest.showHubFromPowerButton() argumentCaptor<SceneDataSource>().apply { verify(delegator).setDelegate(capture()) assertThat(firstValue.currentScene.value).isEqualTo(CommunalScenes.Communal) } } } packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +11 −2 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.systemui.Flags.FLAG_COMMUNAL_HUB import com.android.systemui.Flags.FLAG_COMMUNAL_RESPONSIVE_GRID import com.android.systemui.Flags.FLAG_COMMUNAL_WIDGET_RESIZING import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.glanceableHubV2 import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.broadcastDispatcher import com.android.systemui.communal.data.model.CommunalSmartspaceTimer Loading Loading @@ -90,6 +91,7 @@ import platform.test.runner.parameterized.Parameters @SmallTest @RunWith(ParameterizedAndroidJunit4::class) @EnableFlags(FLAG_COMMUNAL_HUB) class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { private val mainUser = UserInfo(/* id= */ 0, /* name= */ "primary user", /* flags= */ UserInfo.FLAG_MAIN) Loading @@ -110,7 +112,9 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { kosmos.fakeUserRepository.setUserInfos(listOf(mainUser, secondaryUser)) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB) if (glanceableHubV2()) { kosmos.setCommunalV2ConfigEnabled(true) } } @Test Loading @@ -120,7 +124,9 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { assertThat(underTest.isCommunalEnabled.value).isTrue() } /** Test not applicable when [FLAG_GLANCEABLE_HUB_V2] enabled */ @Test @DisableFlags(FLAG_GLANCEABLE_HUB_V2) fun isCommunalAvailable_whenKeyguardShowing_true() = kosmos.runTest { communalSettingsInteractor.setSuppressionReasons(emptyList()) Loading Loading @@ -1212,7 +1218,10 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_RESPONSIVE_GRID) return FlagsParameterization.allCombinationsOf( FLAG_COMMUNAL_RESPONSIVE_GRID, FLAG_GLANCEABLE_HUB_V2, ) } private val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt +25 −9 Original line number Diff line number Diff line Loading @@ -18,15 +18,18 @@ package com.android.systemui.communal.widgets import android.appwidget.AppWidgetProviderInfo import android.content.pm.UserInfo import androidx.test.ext.junit.runners.AndroidJUnit4 import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.filters.SmallTest import com.android.systemui.Flags.FLAG_COMMUNAL_HUB import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.SysuiTestCase import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.domain.interactor.communalSettingsInteractor import com.android.systemui.communal.domain.interactor.setCommunalEnabled import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled import com.android.systemui.communal.shared.model.FakeGlanceableHubMultiUserHelper import com.android.systemui.communal.shared.model.fakeGlanceableHubMultiUserHelper import com.android.systemui.coroutines.collectLastValue Loading Loading @@ -54,10 +57,13 @@ import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @SmallTest @RunWith(AndroidJUnit4::class) class CommunalAppWidgetHostStartableTest : SysuiTestCase() { @RunWith(ParameterizedAndroidJunit4::class) @EnableFlags(FLAG_COMMUNAL_HUB) class CommunalAppWidgetHostStartableTest(flags: FlagsParameterization) : SysuiTestCase() { private val kosmos = testKosmos() @Mock private lateinit var appWidgetHost: CommunalAppWidgetHost Loading @@ -71,12 +77,27 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() { private lateinit var communalInteractorSpy: CommunalInteractor private lateinit var underTest: CommunalAppWidgetHostStartable init { mSetFlagsRule.setFlagsParameterization(flags) } companion object { private val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) private val USER_INFO_WORK = UserInfo(10, "work", UserInfo.FLAG_PROFILE) @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf(FLAG_GLANCEABLE_HUB_V2) } } @Before fun setUp() { MockitoAnnotations.initMocks(this) kosmos.fakeUserRepository.setUserInfos(listOf(MAIN_USER_INFO, USER_INFO_WORK)) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB) kosmos.setCommunalV2ConfigEnabled(true) widgetManager = kosmos.mockGlanceableHubWidgetManager helper = kosmos.fakeGlanceableHubMultiUserHelper Loading Loading @@ -327,9 +348,4 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() { fakeKeyguardRepository.setKeyguardShowing(true) } } private companion object { val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) val USER_INFO_WORK = UserInfo(10, "work", UserInfo.FLAG_PROFILE) } } packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorTest.kt +50 −26 Original line number Diff line number Diff line Loading @@ -21,8 +21,12 @@ import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils import com.android.systemui.Flags import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR import com.android.systemui.SysuiTestCase import com.android.systemui.communal.data.repository.communalSceneRepository import com.android.systemui.communal.domain.interactor.setCommunalV2Enabled import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy Loading @@ -32,10 +36,12 @@ import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.testKosmos import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import com.google.common.truth.Truth import org.junit.Before import org.junit.Ignore import org.junit.Test Loading @@ -46,12 +52,10 @@ import org.mockito.Mockito.reset @RunWith(AndroidJUnit4::class) class FromGoneTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { testKosmos().useUnconfinedTestDispatcher().apply { this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private val underTest = kosmos.fromGoneTransitionInteractor private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy @Before fun setUp() { Loading @@ -61,8 +65,8 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { @Test @Ignore("Fails due to fix for b/324432820 - will re-enable once permanent fix is submitted.") fun testDoesNotTransitionToLockscreen_ifStartedButNotFinishedInGone() = testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( listOf( TransitionStep( from = KeyguardState.LOCKSCREEN, Loading @@ -77,54 +81,74 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { ), testScope, ) reset(keyguardTransitionRepository) kosmos.fakeKeyguardRepository.setKeyguardShowing(true) runCurrent() reset(fakeKeyguardTransitionRepositorySpy) fakeKeyguardRepository.setKeyguardShowing(true) // We're in the middle of a LOCKSCREEN -> GONE transition. assertThat(keyguardTransitionRepository).noTransitionsStarted() assertThat(fakeKeyguardTransitionRepositorySpy).noTransitionsStarted() } @Test @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_ifFinishedInGone() = testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(keyguardTransitionRepository) kosmos.fakeKeyguardRepository.setKeyguardShowing(true) runCurrent() reset(fakeKeyguardTransitionRepositorySpy) fakeKeyguardRepository.setKeyguardShowing(true) // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(keyguardTransitionRepository) assertThat(fakeKeyguardTransitionRepositorySpy) .startedTransition(to = KeyguardState.LOCKSCREEN) } @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_ifFinishedInGone_wmRefactor() = testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(keyguardTransitionRepository) reset(fakeKeyguardTransitionRepositorySpy) // Trigger lockdown. kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags( fakeBiometricSettingsRepository.setAuthenticationFlags( AuthenticationFlags( 0, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN, ) ) runCurrent() // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(keyguardTransitionRepository) assertThat(fakeKeyguardTransitionRepositorySpy) .startedTransition(to = KeyguardState.LOCKSCREEN) } @Test @EnableFlags(FLAG_GLANCEABLE_HUB_V2) @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToGlanceableHub() = kosmos.runTest { val currentScene by collectLastValue(communalSceneRepository.currentScene) fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(fakeKeyguardTransitionRepositorySpy) // Communal is enabled setCommunalV2Enabled(true) Truth.assertThat(currentScene).isEqualTo(CommunalScenes.Blank) fakeKeyguardRepository.setKeyguardShowing(true) Truth.assertThat(currentScene).isEqualTo(CommunalScenes.Communal) assertThat(fakeKeyguardTransitionRepositorySpy).noTransitionsStarted() } } packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt +2 −59 Original line number Diff line number Diff line Loading @@ -19,16 +19,13 @@ package com.android.systemui.communal.data.repository import android.content.res.Configuration import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.OverlayKey import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.TransitionKey import com.android.systemui.communal.dagger.Communal import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.scene.shared.model.SceneDataSource import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow Loading Loading @@ -59,9 +56,6 @@ interface CommunalSceneRepository { /** Immediately snaps to the desired scene. */ fun snapToScene(toScene: SceneKey) /** Shows the hub from a power button press. */ suspend fun showHubFromPowerButton() /** * Updates the transition state of the hub [SceneTransitionLayout]. * Loading @@ -77,10 +71,8 @@ interface CommunalSceneRepository { class CommunalSceneRepositoryImpl @Inject constructor( @Application private val applicationScope: CoroutineScope, @Background backgroundScope: CoroutineScope, @Communal private val sceneDataSource: SceneDataSource, @Communal private val delegator: SceneDataSourceDelegator, ) : CommunalSceneRepository { override val currentScene: StateFlow<SceneKey> = sceneDataSource.currentScene Loading @@ -102,37 +94,17 @@ constructor( _communalContainerOrientation.asStateFlow() override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) { applicationScope.launch { // SceneTransitionLayout state updates must be triggered on the thread the STL was // created on. sceneDataSource.changeScene(toScene, transitionKey) } } override fun snapToScene(toScene: SceneKey) { applicationScope.launch { // SceneTransitionLayout state updates must be triggered on the thread the STL was // created on. sceneDataSource.snapToScene(toScene) } } override fun setCommunalContainerOrientation(orientation: Int) { _communalContainerOrientation.value = orientation } override suspend fun showHubFromPowerButton() { // If keyguard is not showing yet, the hub view is not ready and the // [SceneDataSourceDelegator] will still be using the default [NoOpSceneDataSource] // and initial key, which is Blank. This means that when the hub container loads, it // will default to not showing the hub. Attempting to set the scene in this state // is simply ignored by the [NoOpSceneDataSource]. Instead, we temporarily override // it with a new one that defaults to Communal. This delegate will be overwritten // once the [CommunalContainer] loads. // TODO(b/392969914): show the hub first instead of forcing the scene. delegator.setDelegate(NoOpSceneDataSource(CommunalScenes.Communal)) } /** * Updates the transition state of the hub [SceneTransitionLayout]. * Loading @@ -141,33 +113,4 @@ constructor( override fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) { _transitionState.value = transitionState } /** Noop implementation of a scene data source that always returns the initial [SceneKey]. */ private class NoOpSceneDataSource(initialSceneKey: SceneKey) : SceneDataSource { override val currentScene: StateFlow<SceneKey> = MutableStateFlow(initialSceneKey).asStateFlow() override val currentOverlays: StateFlow<Set<OverlayKey>> = MutableStateFlow(emptySet<OverlayKey>()).asStateFlow() override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) = Unit override fun snapToScene(toScene: SceneKey) = Unit override fun showOverlay(overlay: OverlayKey, transitionKey: TransitionKey?) = Unit override fun hideOverlay(overlay: OverlayKey, transitionKey: TransitionKey?) = Unit override fun replaceOverlay( from: OverlayKey, to: OverlayKey, transitionKey: TransitionKey?, ) = Unit override fun instantlyShowOverlay(overlay: OverlayKey) = Unit override fun instantlyHideOverlay(overlay: OverlayKey) = Unit override fun freezeAndAnimateToCurrentState() = Unit } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryImplTest.kt +0 −21 Original line number Diff line number Diff line Loading @@ -21,23 +21,18 @@ import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.SysuiTestCase import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.backgroundScope import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.scene.shared.model.SceneDataSource import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.mock import org.mockito.kotlin.verify @SmallTest @RunWith(AndroidJUnit4::class) Loading @@ -49,10 +44,8 @@ class CommunalSceneRepositoryImplTest : SysuiTestCase() { private val Kosmos.underTest by Kosmos.Fixture { CommunalSceneRepositoryImpl( applicationScope = applicationCoroutineScope, backgroundScope = backgroundScope, sceneDataSource = delegator, delegator = delegator, ) } Loading Loading @@ -90,18 +83,4 @@ class CommunalSceneRepositoryImplTest : SysuiTestCase() { assertThat(transitionState) .isEqualTo(ObservableTransitionState.Idle(CommunalScenes.Default)) } @Test fun showHubFromPowerButton() = kosmos.runTest { fakeKeyguardRepository.setKeyguardShowing(false) underTest.showHubFromPowerButton() argumentCaptor<SceneDataSource>().apply { verify(delegator).setDelegate(capture()) assertThat(firstValue.currentScene.value).isEqualTo(CommunalScenes.Communal) } } }
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +11 −2 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import com.android.systemui.Flags.FLAG_COMMUNAL_HUB import com.android.systemui.Flags.FLAG_COMMUNAL_RESPONSIVE_GRID import com.android.systemui.Flags.FLAG_COMMUNAL_WIDGET_RESIZING import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.glanceableHubV2 import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.broadcastDispatcher import com.android.systemui.communal.data.model.CommunalSmartspaceTimer Loading Loading @@ -90,6 +91,7 @@ import platform.test.runner.parameterized.Parameters @SmallTest @RunWith(ParameterizedAndroidJunit4::class) @EnableFlags(FLAG_COMMUNAL_HUB) class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { private val mainUser = UserInfo(/* id= */ 0, /* name= */ "primary user", /* flags= */ UserInfo.FLAG_MAIN) Loading @@ -110,7 +112,9 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { kosmos.fakeUserRepository.setUserInfos(listOf(mainUser, secondaryUser)) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB) if (glanceableHubV2()) { kosmos.setCommunalV2ConfigEnabled(true) } } @Test Loading @@ -120,7 +124,9 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { assertThat(underTest.isCommunalEnabled.value).isTrue() } /** Test not applicable when [FLAG_GLANCEABLE_HUB_V2] enabled */ @Test @DisableFlags(FLAG_GLANCEABLE_HUB_V2) fun isCommunalAvailable_whenKeyguardShowing_true() = kosmos.runTest { communalSettingsInteractor.setSuppressionReasons(emptyList()) Loading Loading @@ -1212,7 +1218,10 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_RESPONSIVE_GRID) return FlagsParameterization.allCombinationsOf( FLAG_COMMUNAL_RESPONSIVE_GRID, FLAG_GLANCEABLE_HUB_V2, ) } private val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt +25 −9 Original line number Diff line number Diff line Loading @@ -18,15 +18,18 @@ package com.android.systemui.communal.widgets import android.appwidget.AppWidgetProviderInfo import android.content.pm.UserInfo import androidx.test.ext.junit.runners.AndroidJUnit4 import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.filters.SmallTest import com.android.systemui.Flags.FLAG_COMMUNAL_HUB import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.SysuiTestCase import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository import com.android.systemui.communal.domain.interactor.CommunalInteractor import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.domain.interactor.communalSettingsInteractor import com.android.systemui.communal.domain.interactor.setCommunalEnabled import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled import com.android.systemui.communal.shared.model.FakeGlanceableHubMultiUserHelper import com.android.systemui.communal.shared.model.fakeGlanceableHubMultiUserHelper import com.android.systemui.coroutines.collectLastValue Loading Loading @@ -54,10 +57,13 @@ import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @SmallTest @RunWith(AndroidJUnit4::class) class CommunalAppWidgetHostStartableTest : SysuiTestCase() { @RunWith(ParameterizedAndroidJunit4::class) @EnableFlags(FLAG_COMMUNAL_HUB) class CommunalAppWidgetHostStartableTest(flags: FlagsParameterization) : SysuiTestCase() { private val kosmos = testKosmos() @Mock private lateinit var appWidgetHost: CommunalAppWidgetHost Loading @@ -71,12 +77,27 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() { private lateinit var communalInteractorSpy: CommunalInteractor private lateinit var underTest: CommunalAppWidgetHostStartable init { mSetFlagsRule.setFlagsParameterization(flags) } companion object { private val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) private val USER_INFO_WORK = UserInfo(10, "work", UserInfo.FLAG_PROFILE) @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf(FLAG_GLANCEABLE_HUB_V2) } } @Before fun setUp() { MockitoAnnotations.initMocks(this) kosmos.fakeUserRepository.setUserInfos(listOf(MAIN_USER_INFO, USER_INFO_WORK)) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB) kosmos.setCommunalV2ConfigEnabled(true) widgetManager = kosmos.mockGlanceableHubWidgetManager helper = kosmos.fakeGlanceableHubMultiUserHelper Loading Loading @@ -327,9 +348,4 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() { fakeKeyguardRepository.setKeyguardShowing(true) } } private companion object { val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) val USER_INFO_WORK = UserInfo(10, "work", UserInfo.FLAG_PROFILE) } }
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorTest.kt +50 −26 Original line number Diff line number Diff line Loading @@ -21,8 +21,12 @@ import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils import com.android.systemui.Flags import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR import com.android.systemui.SysuiTestCase import com.android.systemui.communal.data.repository.communalSceneRepository import com.android.systemui.communal.domain.interactor.setCommunalV2Enabled import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy Loading @@ -32,10 +36,12 @@ import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.testKosmos import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import com.google.common.truth.Truth import org.junit.Before import org.junit.Ignore import org.junit.Test Loading @@ -46,12 +52,10 @@ import org.mockito.Mockito.reset @RunWith(AndroidJUnit4::class) class FromGoneTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().apply { testKosmos().useUnconfinedTestDispatcher().apply { this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private val underTest = kosmos.fromGoneTransitionInteractor private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy @Before fun setUp() { Loading @@ -61,8 +65,8 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { @Test @Ignore("Fails due to fix for b/324432820 - will re-enable once permanent fix is submitted.") fun testDoesNotTransitionToLockscreen_ifStartedButNotFinishedInGone() = testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( listOf( TransitionStep( from = KeyguardState.LOCKSCREEN, Loading @@ -77,54 +81,74 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { ), testScope, ) reset(keyguardTransitionRepository) kosmos.fakeKeyguardRepository.setKeyguardShowing(true) runCurrent() reset(fakeKeyguardTransitionRepositorySpy) fakeKeyguardRepository.setKeyguardShowing(true) // We're in the middle of a LOCKSCREEN -> GONE transition. assertThat(keyguardTransitionRepository).noTransitionsStarted() assertThat(fakeKeyguardTransitionRepositorySpy).noTransitionsStarted() } @Test @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_ifFinishedInGone() = testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(keyguardTransitionRepository) kosmos.fakeKeyguardRepository.setKeyguardShowing(true) runCurrent() reset(fakeKeyguardTransitionRepositorySpy) fakeKeyguardRepository.setKeyguardShowing(true) // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(keyguardTransitionRepository) assertThat(fakeKeyguardTransitionRepositorySpy) .startedTransition(to = KeyguardState.LOCKSCREEN) } @Test @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_ifFinishedInGone_wmRefactor() = testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(keyguardTransitionRepository) reset(fakeKeyguardTransitionRepositorySpy) // Trigger lockdown. kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags( fakeBiometricSettingsRepository.setAuthenticationFlags( AuthenticationFlags( 0, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN, ) ) runCurrent() // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(keyguardTransitionRepository) assertThat(fakeKeyguardTransitionRepositorySpy) .startedTransition(to = KeyguardState.LOCKSCREEN) } @Test @EnableFlags(FLAG_GLANCEABLE_HUB_V2) @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionToGlanceableHub() = kosmos.runTest { val currentScene by collectLastValue(communalSceneRepository.currentScene) fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(fakeKeyguardTransitionRepositorySpy) // Communal is enabled setCommunalV2Enabled(true) Truth.assertThat(currentScene).isEqualTo(CommunalScenes.Blank) fakeKeyguardRepository.setKeyguardShowing(true) Truth.assertThat(currentScene).isEqualTo(CommunalScenes.Communal) assertThat(fakeKeyguardTransitionRepositorySpy).noTransitionsStarted() } }
packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt +2 −59 Original line number Diff line number Diff line Loading @@ -19,16 +19,13 @@ package com.android.systemui.communal.data.repository import android.content.res.Configuration import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.OverlayKey import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.TransitionKey import com.android.systemui.communal.dagger.Communal import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.scene.shared.model.SceneDataSource import com.android.systemui.scene.shared.model.SceneDataSourceDelegator import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow Loading Loading @@ -59,9 +56,6 @@ interface CommunalSceneRepository { /** Immediately snaps to the desired scene. */ fun snapToScene(toScene: SceneKey) /** Shows the hub from a power button press. */ suspend fun showHubFromPowerButton() /** * Updates the transition state of the hub [SceneTransitionLayout]. * Loading @@ -77,10 +71,8 @@ interface CommunalSceneRepository { class CommunalSceneRepositoryImpl @Inject constructor( @Application private val applicationScope: CoroutineScope, @Background backgroundScope: CoroutineScope, @Communal private val sceneDataSource: SceneDataSource, @Communal private val delegator: SceneDataSourceDelegator, ) : CommunalSceneRepository { override val currentScene: StateFlow<SceneKey> = sceneDataSource.currentScene Loading @@ -102,37 +94,17 @@ constructor( _communalContainerOrientation.asStateFlow() override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) { applicationScope.launch { // SceneTransitionLayout state updates must be triggered on the thread the STL was // created on. sceneDataSource.changeScene(toScene, transitionKey) } } override fun snapToScene(toScene: SceneKey) { applicationScope.launch { // SceneTransitionLayout state updates must be triggered on the thread the STL was // created on. sceneDataSource.snapToScene(toScene) } } override fun setCommunalContainerOrientation(orientation: Int) { _communalContainerOrientation.value = orientation } override suspend fun showHubFromPowerButton() { // If keyguard is not showing yet, the hub view is not ready and the // [SceneDataSourceDelegator] will still be using the default [NoOpSceneDataSource] // and initial key, which is Blank. This means that when the hub container loads, it // will default to not showing the hub. Attempting to set the scene in this state // is simply ignored by the [NoOpSceneDataSource]. Instead, we temporarily override // it with a new one that defaults to Communal. This delegate will be overwritten // once the [CommunalContainer] loads. // TODO(b/392969914): show the hub first instead of forcing the scene. delegator.setDelegate(NoOpSceneDataSource(CommunalScenes.Communal)) } /** * Updates the transition state of the hub [SceneTransitionLayout]. * Loading @@ -141,33 +113,4 @@ constructor( override fun setTransitionState(transitionState: Flow<ObservableTransitionState>?) { _transitionState.value = transitionState } /** Noop implementation of a scene data source that always returns the initial [SceneKey]. */ private class NoOpSceneDataSource(initialSceneKey: SceneKey) : SceneDataSource { override val currentScene: StateFlow<SceneKey> = MutableStateFlow(initialSceneKey).asStateFlow() override val currentOverlays: StateFlow<Set<OverlayKey>> = MutableStateFlow(emptySet<OverlayKey>()).asStateFlow() override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) = Unit override fun snapToScene(toScene: SceneKey) = Unit override fun showOverlay(overlay: OverlayKey, transitionKey: TransitionKey?) = Unit override fun hideOverlay(overlay: OverlayKey, transitionKey: TransitionKey?) = Unit override fun replaceOverlay( from: OverlayKey, to: OverlayKey, transitionKey: TransitionKey?, ) = Unit override fun instantlyShowOverlay(overlay: OverlayKey) = Unit override fun instantlyHideOverlay(overlay: OverlayKey) = Unit override fun freezeAndAnimateToCurrentState() = Unit } }