Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSceneRepositoryImplTest.kt +21 −0 Original line number Diff line number Diff line Loading @@ -21,18 +21,23 @@ 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 @@ -44,8 +49,10 @@ class CommunalSceneRepositoryImplTest : SysuiTestCase() { private val Kosmos.underTest by Kosmos.Fixture { CommunalSceneRepositoryImpl( applicationScope = applicationCoroutineScope, backgroundScope = backgroundScope, sceneDataSource = delegator, delegator = delegator, ) } Loading Loading @@ -83,4 +90,18 @@ 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 +2 −11 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ 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 @@ -91,7 +90,6 @@ 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 @@ -112,9 +110,7 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { kosmos.fakeUserRepository.setUserInfos(listOf(mainUser, secondaryUser)) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) if (glanceableHubV2()) { kosmos.setCommunalV2ConfigEnabled(true) } mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB) } @Test Loading @@ -124,9 +120,7 @@ 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 @@ -1218,10 +1212,7 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf( FLAG_COMMUNAL_RESPONSIVE_GRID, FLAG_GLANCEABLE_HUB_V2, ) return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_RESPONSIVE_GRID) } private val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt +9 −25 Original line number Diff line number Diff line Loading @@ -18,18 +18,15 @@ package com.android.systemui.communal.widgets import android.appwidget.AppWidgetProviderInfo import android.content.pm.UserInfo import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.ext.junit.runners.AndroidJUnit4 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 @@ -57,13 +54,10 @@ 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(ParameterizedAndroidJunit4::class) @EnableFlags(FLAG_COMMUNAL_HUB) class CommunalAppWidgetHostStartableTest(flags: FlagsParameterization) : SysuiTestCase() { @RunWith(AndroidJUnit4::class) class CommunalAppWidgetHostStartableTest : SysuiTestCase() { private val kosmos = testKosmos() @Mock private lateinit var appWidgetHost: CommunalAppWidgetHost Loading @@ -77,27 +71,12 @@ class CommunalAppWidgetHostStartableTest(flags: FlagsParameterization) : SysuiTe 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) kosmos.setCommunalV2ConfigEnabled(true) mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB) widgetManager = kosmos.mockGlanceableHubWidgetManager helper = kosmos.fakeGlanceableHubMultiUserHelper Loading Loading @@ -348,4 +327,9 @@ class CommunalAppWidgetHostStartableTest(flags: FlagsParameterization) : SysuiTe 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 +26 −50 Original line number Diff line number Diff line Loading @@ -21,12 +21,8 @@ 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.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR import com.android.systemui.Flags 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 @@ -36,12 +32,10 @@ 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 com.google.common.truth.Truth import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Ignore import org.junit.Test Loading @@ -52,10 +46,12 @@ import org.mockito.Mockito.reset @RunWith(AndroidJUnit4::class) class FromGoneTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher().apply { testKosmos().apply { this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private val underTest = kosmos.fromGoneTransitionInteractor private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy @Before fun setUp() { Loading @@ -65,8 +61,8 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { @Test @Ignore("Fails due to fix for b/324432820 - will re-enable once permanent fix is submitted.") fun testDoesNotTransitionToLockscreen_ifStartedButNotFinishedInGone() = kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( listOf( TransitionStep( from = KeyguardState.LOCKSCREEN, Loading @@ -81,74 +77,54 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { ), testScope, ) reset(fakeKeyguardTransitionRepositorySpy) fakeKeyguardRepository.setKeyguardShowing(true) reset(keyguardTransitionRepository) kosmos.fakeKeyguardRepository.setKeyguardShowing(true) runCurrent() // We're in the middle of a LOCKSCREEN -> GONE transition. assertThat(fakeKeyguardTransitionRepositorySpy).noTransitionsStarted() assertThat(keyguardTransitionRepository).noTransitionsStarted() } @Test @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_ifFinishedInGone() = kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(fakeKeyguardTransitionRepositorySpy) fakeKeyguardRepository.setKeyguardShowing(true) reset(keyguardTransitionRepository) kosmos.fakeKeyguardRepository.setKeyguardShowing(true) runCurrent() // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(fakeKeyguardTransitionRepositorySpy) assertThat(keyguardTransitionRepository) .startedTransition(to = KeyguardState.LOCKSCREEN) } @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_ifFinishedInGone_wmRefactor() = kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(fakeKeyguardTransitionRepositorySpy) reset(keyguardTransitionRepository) // Trigger lockdown. fakeBiometricSettingsRepository.setAuthenticationFlags( kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags( AuthenticationFlags( 0, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN, ) ) runCurrent() // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(fakeKeyguardTransitionRepositorySpy) assertThat(keyguardTransitionRepository) .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 +59 −2 Original line number Diff line number Diff line Loading @@ -19,13 +19,16 @@ 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 @@ -56,6 +59,9 @@ 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 @@ -71,8 +77,10 @@ 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 @@ -94,17 +102,37 @@ 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 @@ -113,4 +141,33 @@ 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 +21 −0 Original line number Diff line number Diff line Loading @@ -21,18 +21,23 @@ 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 @@ -44,8 +49,10 @@ class CommunalSceneRepositoryImplTest : SysuiTestCase() { private val Kosmos.underTest by Kosmos.Fixture { CommunalSceneRepositoryImpl( applicationScope = applicationCoroutineScope, backgroundScope = backgroundScope, sceneDataSource = delegator, delegator = delegator, ) } Loading Loading @@ -83,4 +90,18 @@ 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 +2 −11 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ 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 @@ -91,7 +90,6 @@ 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 @@ -112,9 +110,7 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { kosmos.fakeUserRepository.setUserInfos(listOf(mainUser, secondaryUser)) kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true) if (glanceableHubV2()) { kosmos.setCommunalV2ConfigEnabled(true) } mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB) } @Test Loading @@ -124,9 +120,7 @@ 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 @@ -1218,10 +1212,7 @@ class CommunalInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { @JvmStatic @Parameters(name = "{0}") fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf( FLAG_COMMUNAL_RESPONSIVE_GRID, FLAG_GLANCEABLE_HUB_V2, ) return FlagsParameterization.allCombinationsOf(FLAG_COMMUNAL_RESPONSIVE_GRID) } private val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt +9 −25 Original line number Diff line number Diff line Loading @@ -18,18 +18,15 @@ package com.android.systemui.communal.widgets import android.appwidget.AppWidgetProviderInfo import android.content.pm.UserInfo import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.ext.junit.runners.AndroidJUnit4 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 @@ -57,13 +54,10 @@ 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(ParameterizedAndroidJunit4::class) @EnableFlags(FLAG_COMMUNAL_HUB) class CommunalAppWidgetHostStartableTest(flags: FlagsParameterization) : SysuiTestCase() { @RunWith(AndroidJUnit4::class) class CommunalAppWidgetHostStartableTest : SysuiTestCase() { private val kosmos = testKosmos() @Mock private lateinit var appWidgetHost: CommunalAppWidgetHost Loading @@ -77,27 +71,12 @@ class CommunalAppWidgetHostStartableTest(flags: FlagsParameterization) : SysuiTe 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) kosmos.setCommunalV2ConfigEnabled(true) mSetFlagsRule.enableFlags(FLAG_COMMUNAL_HUB) widgetManager = kosmos.mockGlanceableHubWidgetManager helper = kosmos.fakeGlanceableHubMultiUserHelper Loading Loading @@ -348,4 +327,9 @@ class CommunalAppWidgetHostStartableTest(flags: FlagsParameterization) : SysuiTe 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 +26 −50 Original line number Diff line number Diff line Loading @@ -21,12 +21,8 @@ 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.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR import com.android.systemui.Flags 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 @@ -36,12 +32,10 @@ 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 com.google.common.truth.Truth import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Ignore import org.junit.Test Loading @@ -52,10 +46,12 @@ import org.mockito.Mockito.reset @RunWith(AndroidJUnit4::class) class FromGoneTransitionInteractorTest : SysuiTestCase() { private val kosmos = testKosmos().useUnconfinedTestDispatcher().apply { testKosmos().apply { this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy } private val testScope = kosmos.testScope private val underTest = kosmos.fromGoneTransitionInteractor private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy @Before fun setUp() { Loading @@ -65,8 +61,8 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { @Test @Ignore("Fails due to fix for b/324432820 - will re-enable once permanent fix is submitted.") fun testDoesNotTransitionToLockscreen_ifStartedButNotFinishedInGone() = kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( listOf( TransitionStep( from = KeyguardState.LOCKSCREEN, Loading @@ -81,74 +77,54 @@ class FromGoneTransitionInteractorTest : SysuiTestCase() { ), testScope, ) reset(fakeKeyguardTransitionRepositorySpy) fakeKeyguardRepository.setKeyguardShowing(true) reset(keyguardTransitionRepository) kosmos.fakeKeyguardRepository.setKeyguardShowing(true) runCurrent() // We're in the middle of a LOCKSCREEN -> GONE transition. assertThat(fakeKeyguardTransitionRepositorySpy).noTransitionsStarted() assertThat(keyguardTransitionRepository).noTransitionsStarted() } @Test @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_ifFinishedInGone() = kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(fakeKeyguardTransitionRepositorySpy) fakeKeyguardRepository.setKeyguardShowing(true) reset(keyguardTransitionRepository) kosmos.fakeKeyguardRepository.setKeyguardShowing(true) runCurrent() // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(fakeKeyguardTransitionRepositorySpy) assertThat(keyguardTransitionRepository) .startedTransition(to = KeyguardState.LOCKSCREEN) } @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) fun testTransitionsToLockscreen_ifFinishedInGone_wmRefactor() = kosmos.runTest { fakeKeyguardTransitionRepositorySpy.sendTransitionSteps( testScope.runTest { keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.LOCKSCREEN, to = KeyguardState.GONE, testScope, ) reset(fakeKeyguardTransitionRepositorySpy) reset(keyguardTransitionRepository) // Trigger lockdown. fakeBiometricSettingsRepository.setAuthenticationFlags( kosmos.fakeBiometricSettingsRepository.setAuthenticationFlags( AuthenticationFlags( 0, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN, ) ) runCurrent() // We're in the middle of a GONE -> LOCKSCREEN transition. assertThat(fakeKeyguardTransitionRepositorySpy) assertThat(keyguardTransitionRepository) .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 +59 −2 Original line number Diff line number Diff line Loading @@ -19,13 +19,16 @@ 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 @@ -56,6 +59,9 @@ 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 @@ -71,8 +77,10 @@ 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 @@ -94,17 +102,37 @@ 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 @@ -113,4 +141,33 @@ 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 } }