Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt +9 −3 Original line number Diff line number Diff line Loading @@ -39,7 +39,9 @@ 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.kosmos.testScope import com.android.systemui.scene.data.repository.Idle import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.data.repository.setSceneTransition import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.shadeTestUtil Loading Loading @@ -290,6 +292,7 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase() testScope, ) kosmos.setSceneTransition(Idle(Scenes.Gone)) // Make sure the value hasn't changed since we're GONE keyguardRepository.topClippingBounds.value = 5 assertThat(topClippingBounds).isEqualTo(1000) Loading Loading @@ -518,12 +521,15 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase() to = KeyguardState.GONE, testScope = testScope, ) kosmos.setSceneTransition(Idle(Scenes.Gone)) assertThat(alpha).isEqualTo(0f) if (!SceneContainerFlag.isEnabled) { // Try pulling down shade and ensure the value doesn't change shadeTestUtil.setQsExpansion(0.5f) assertThat(alpha).isEqualTo(0f) } } @Test fun alpha_idleOnDream_isZero() = Loading packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt +57 −79 Original line number Diff line number Diff line Loading @@ -21,16 +21,19 @@ package com.android.systemui.scene.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.scene.data.repository.Idle import com.android.systemui.scene.data.repository.Transition import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.data.repository.setSceneTransition import com.android.systemui.scene.sceneContainerConfig import com.android.systemui.scene.sceneKeys import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneFamilies import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.shared.model.fakeSceneDataSource Loading @@ -54,48 +57,27 @@ class SceneInteractorTest : SysuiTestCase() { private val testScope = kosmos.testScope private val fakeSceneDataSource = kosmos.fakeSceneDataSource private lateinit var underTest: SceneInteractor private val underTest = kosmos.sceneInteractor @Test fun allSceneKeys() { underTest = kosmos.sceneInteractor assertThat(underTest.allSceneKeys()).isEqualTo(kosmos.sceneKeys) } @Test fun changeScene_toUnknownScene_doesNothing() = testScope.runTest { val sceneKeys = listOf( Scenes.QuickSettings, Scenes.Shade, Scenes.Lockscreen, Scenes.Gone, Scenes.Communal, ) val navigationDistances = mapOf( Scenes.Gone to 0, Scenes.Lockscreen to 0, Scenes.Communal to 1, Scenes.Shade to 2, Scenes.QuickSettings to 3, ) kosmos.sceneContainerConfig = SceneContainerConfig(sceneKeys, Scenes.Lockscreen, navigationDistances) underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) val unknownScene = SceneKey("UNKNOWN") val previousScene = currentScene assertThat(previousScene).isNotEqualTo(Scenes.Bouncer) underTest.changeScene(Scenes.Bouncer, "reason") assertThat(previousScene).isNotEqualTo(unknownScene) underTest.changeScene(unknownScene, "reason") assertThat(currentScene).isEqualTo(previousScene) } @Test fun changeScene() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -106,8 +88,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun changeScene_toGoneWhenUnl_doesNotThrow() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -122,15 +102,11 @@ class SceneInteractorTest : SysuiTestCase() { @Test(expected = IllegalStateException::class) fun changeScene_toGoneWhenStillLocked_throws() = testScope.runTest { underTest = kosmos.sceneInteractor underTest.changeScene(Scenes.Gone, "reason") } testScope.runTest { underTest.changeScene(Scenes.Gone, "reason") } @Test fun changeScene_toGoneWhenTransitionToLockedFromGone() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) val transitionTo by collectLastValue(underTest.transitioningTo) kosmos.sceneContainerRepository.setTransitionState( Loading @@ -155,7 +131,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun changeScene_toHomeSceneFamily() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) underTest.changeScene(SceneFamilies.Home, "reason") Loading @@ -167,37 +142,17 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun snapToScene_toUnknownScene_doesNothing() = testScope.runTest { val sceneKeys = listOf( Scenes.QuickSettings, Scenes.Shade, Scenes.Lockscreen, Scenes.Gone, Scenes.Communal, ) val navigationDistances = mapOf( Scenes.Gone to 0, Scenes.Lockscreen to 0, Scenes.Communal to 1, Scenes.Shade to 2, Scenes.QuickSettings to 3, ) kosmos.sceneContainerConfig = SceneContainerConfig(sceneKeys, Scenes.Lockscreen, navigationDistances) underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) val previousScene = currentScene assertThat(previousScene).isNotEqualTo(Scenes.Bouncer) underTest.snapToScene(Scenes.Bouncer, "reason") val unknownScene = SceneKey("UNKNOWN") assertThat(previousScene).isNotEqualTo(unknownScene) underTest.snapToScene(unknownScene, "reason") assertThat(currentScene).isEqualTo(previousScene) } @Test fun snapToScene() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -208,8 +163,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun snapToScene_toGoneWhenUnl_doesNotThrow() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -224,15 +177,11 @@ class SceneInteractorTest : SysuiTestCase() { @Test(expected = IllegalStateException::class) fun snapToScene_toGoneWhenStillLocked_throws() = testScope.runTest { underTest = kosmos.sceneInteractor underTest.snapToScene(Scenes.Gone, "reason") } testScope.runTest { underTest.snapToScene(Scenes.Gone, "reason") } @Test fun snapToScene_toHomeSceneFamily() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) underTest.snapToScene(SceneFamilies.Home, "reason") Loading @@ -244,7 +193,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun sceneChanged_inDataSource() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -256,14 +204,14 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun transitionState() = testScope.runTest { underTest = kosmos.sceneInteractor val underTest = kosmos.sceneContainerRepository val sceneContainerRepository = kosmos.sceneContainerRepository val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Lockscreen) ) underTest.setTransitionState(transitionState) val reflectedTransitionState by collectLastValue(underTest.transitionState) sceneContainerRepository.setTransitionState(transitionState) val reflectedTransitionState by collectLastValue(sceneContainerRepository.transitionState) assertThat(reflectedTransitionState).isEqualTo(transitionState.value) val progress = MutableStateFlow(1f) Loading @@ -284,7 +232,7 @@ class SceneInteractorTest : SysuiTestCase() { progress.value = 0.9f assertThat(reflectedTransitionState).isEqualTo(transitionState.value) underTest.setTransitionState(null) sceneContainerRepository.setTransitionState(null) assertThat(reflectedTransitionState) .isEqualTo( ObservableTransitionState.Idle(kosmos.sceneContainerConfig.initialSceneKey) Loading @@ -294,7 +242,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun transitioningTo() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(underTest.currentScene.value) Loading Loading @@ -332,7 +279,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_idle_false() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Shade) Loading @@ -347,7 +293,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_transition_true() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( Loading @@ -369,7 +314,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_updateMidTransition_false() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( Loading Loading @@ -403,7 +347,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_updateOnIdle_false() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( Loading @@ -429,7 +372,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isVisible() = testScope.runTest { underTest = kosmos.sceneInteractor val isVisible by collectLastValue(underTest.isVisible) assertThat(isVisible).isTrue() Loading @@ -443,7 +385,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isVisible_duringRemoteUserInteraction_forcedVisible() = testScope.runTest { underTest = kosmos.sceneInteractor underTest.setVisible(false, "reason") val isVisible by collectLastValue(underTest.isVisible) assertThat(isVisible).isFalse() Loading @@ -458,7 +399,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun resolveSceneFamily_home() = testScope.runTest { underTest = kosmos.sceneInteractor assertThat(underTest.resolveSceneFamily(SceneFamilies.Home)) .isEqualTo(kosmos.homeSceneFamilyResolver.resolvedScene) } Loading @@ -466,8 +406,46 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun resolveSceneFamily_nonFamily() = testScope.runTest { underTest = kosmos.sceneInteractor val resolved = underTest.resolveSceneFamily(Scenes.Gone).toList() assertThat(resolved).containsExactly(Scenes.Gone).inOrder() } @Test fun transitionValue_test_idle() = testScope.runTest { val transitionValue by collectLastValue(underTest.transitionProgress(Scenes.Gone)) kosmos.setSceneTransition(Idle(Scenes.Gone)) assertThat(transitionValue).isEqualTo(1f) kosmos.setSceneTransition(Idle(Scenes.Lockscreen)) assertThat(transitionValue).isEqualTo(0f) } @Test fun transitionValue_test_transitions() = testScope.runTest { val transitionValue by collectLastValue(underTest.transitionProgress(Scenes.Gone)) val progress = MutableStateFlow(0f) kosmos.setSceneTransition( Transition(from = Scenes.Lockscreen, to = Scenes.Gone, progress = progress) ) assertThat(transitionValue).isEqualTo(0f) progress.value = 0.4f assertThat(transitionValue).isEqualTo(0.4f) kosmos.setSceneTransition( Transition(from = Scenes.Gone, to = Scenes.Lockscreen, progress = progress) ) progress.value = 0.7f assertThat(transitionValue).isEqualTo(0.3f) kosmos.setSceneTransition( Transition(from = Scenes.Lockscreen, to = Scenes.Shade, progress = progress) ) progress.value = 0.9f assertThat(transitionValue).isEqualTo(0f) } } packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +5 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.animation.ValueAnimator.AnimatorUpdateListener import android.annotation.FloatRange import android.annotation.SuppressLint import android.os.Trace import android.util.Log import com.android.app.tracing.coroutines.withContext Loading Loading @@ -117,10 +118,11 @@ class KeyguardTransitionRepositoryImpl constructor( @Main val mainDispatcher: CoroutineDispatcher, ) : KeyguardTransitionRepository { /* * Each transition between [KeyguardState]s will have an associated Flow. * In order to collect these events, clients should call [transition]. /** * Each transition between [KeyguardState]s will have an associated Flow. In order to collect * these events, clients should call [transition]. */ @SuppressLint("SharedFlowCreation") private val _transitions = MutableSharedFlow<TransitionStep>( replay = 2, Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +11 −14 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.notification.NotificationUtils.interpolate import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.kotlin.sample import javax.inject.Inject Loading @@ -77,6 +77,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine /** * Encapsulates business-logic related to the keyguard but not to a more specific part within it. Loading @@ -91,7 +92,7 @@ constructor( bouncerRepository: KeyguardBouncerRepository, configurationInteractor: ConfigurationInteractor, shadeRepository: ShadeRepository, keyguardTransitionInteractor: KeyguardTransitionInteractor, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, sceneInteractorProvider: Provider<SceneInteractor>, private val fromGoneTransitionInteractor: Provider<FromGoneTransitionInteractor>, private val fromLockscreenTransitionInteractor: Provider<FromLockscreenTransitionInteractor>, Loading Loading @@ -248,21 +249,17 @@ constructor( val isKeyguardGoingAway: Flow<Boolean> = repository.isKeyguardGoingAway /** Keyguard can be clipped at the top as the shade is dragged */ val topClippingBounds: Flow<Int?> = combineTransform( configurationInteractor.onAnyConfigurationChange, keyguardTransitionInteractor .transitionValue(GONE) .map { it == 1f } .onStart { emit(false) } .distinctUntilChanged(), val topClippingBounds: Flow<Int?> by lazy { repository.topClippingBounds ) { _, isGone, topClippingBounds -> if (!isGone) { emit(topClippingBounds) } .sampleFilter( keyguardTransitionInteractor .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE) .onStart { emit(0f) } ) { goneValue -> goneValue != 1f } .distinctUntilChanged() } /** Last point that [KeyguardRootView] view was tapped */ val lastRootViewTapPosition: Flow<Point?> = repository.lastRootViewTapPosition.asStateFlow() Loading packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +15 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,17 @@ constructor( } } fun transitionValue( scene: SceneKey, stateWithoutSceneContainer: KeyguardState, ): Flow<Float> { return if (SceneContainerFlag.isEnabled) { sceneInteractor.get().transitionProgress(scene) } else { transitionValue(stateWithoutSceneContainer) } } /** * The amount of transition into or out of the given [KeyguardState]. * Loading @@ -232,6 +243,10 @@ constructor( fun transitionValue( state: KeyguardState, ): Flow<Float> { if (SceneContainerFlag.isEnabled && state != state.mapToSceneContainerState()) { Log.e(TAG, "SceneContainer is enabled but a deprecated state $state is used.") return transitionValue(state.mapToSceneContainerScene()!!, state) } return getTransitionValueFlow(state) } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt +9 −3 Original line number Diff line number Diff line Loading @@ -39,7 +39,9 @@ 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.kosmos.testScope import com.android.systemui.scene.data.repository.Idle import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.data.repository.setSceneTransition import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.shadeTestUtil Loading Loading @@ -290,6 +292,7 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase() testScope, ) kosmos.setSceneTransition(Idle(Scenes.Gone)) // Make sure the value hasn't changed since we're GONE keyguardRepository.topClippingBounds.value = 5 assertThat(topClippingBounds).isEqualTo(1000) Loading Loading @@ -518,12 +521,15 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase() to = KeyguardState.GONE, testScope = testScope, ) kosmos.setSceneTransition(Idle(Scenes.Gone)) assertThat(alpha).isEqualTo(0f) if (!SceneContainerFlag.isEnabled) { // Try pulling down shade and ensure the value doesn't change shadeTestUtil.setQsExpansion(0.5f) assertThat(alpha).isEqualTo(0f) } } @Test fun alpha_idleOnDream_isZero() = Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt +57 −79 Original line number Diff line number Diff line Loading @@ -21,16 +21,19 @@ package com.android.systemui.scene.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.SceneKey import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.scene.data.repository.Idle import com.android.systemui.scene.data.repository.Transition import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.data.repository.setSceneTransition import com.android.systemui.scene.sceneContainerConfig import com.android.systemui.scene.sceneKeys import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneFamilies import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.shared.model.fakeSceneDataSource Loading @@ -54,48 +57,27 @@ class SceneInteractorTest : SysuiTestCase() { private val testScope = kosmos.testScope private val fakeSceneDataSource = kosmos.fakeSceneDataSource private lateinit var underTest: SceneInteractor private val underTest = kosmos.sceneInteractor @Test fun allSceneKeys() { underTest = kosmos.sceneInteractor assertThat(underTest.allSceneKeys()).isEqualTo(kosmos.sceneKeys) } @Test fun changeScene_toUnknownScene_doesNothing() = testScope.runTest { val sceneKeys = listOf( Scenes.QuickSettings, Scenes.Shade, Scenes.Lockscreen, Scenes.Gone, Scenes.Communal, ) val navigationDistances = mapOf( Scenes.Gone to 0, Scenes.Lockscreen to 0, Scenes.Communal to 1, Scenes.Shade to 2, Scenes.QuickSettings to 3, ) kosmos.sceneContainerConfig = SceneContainerConfig(sceneKeys, Scenes.Lockscreen, navigationDistances) underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) val unknownScene = SceneKey("UNKNOWN") val previousScene = currentScene assertThat(previousScene).isNotEqualTo(Scenes.Bouncer) underTest.changeScene(Scenes.Bouncer, "reason") assertThat(previousScene).isNotEqualTo(unknownScene) underTest.changeScene(unknownScene, "reason") assertThat(currentScene).isEqualTo(previousScene) } @Test fun changeScene() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -106,8 +88,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun changeScene_toGoneWhenUnl_doesNotThrow() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -122,15 +102,11 @@ class SceneInteractorTest : SysuiTestCase() { @Test(expected = IllegalStateException::class) fun changeScene_toGoneWhenStillLocked_throws() = testScope.runTest { underTest = kosmos.sceneInteractor underTest.changeScene(Scenes.Gone, "reason") } testScope.runTest { underTest.changeScene(Scenes.Gone, "reason") } @Test fun changeScene_toGoneWhenTransitionToLockedFromGone() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) val transitionTo by collectLastValue(underTest.transitioningTo) kosmos.sceneContainerRepository.setTransitionState( Loading @@ -155,7 +131,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun changeScene_toHomeSceneFamily() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) underTest.changeScene(SceneFamilies.Home, "reason") Loading @@ -167,37 +142,17 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun snapToScene_toUnknownScene_doesNothing() = testScope.runTest { val sceneKeys = listOf( Scenes.QuickSettings, Scenes.Shade, Scenes.Lockscreen, Scenes.Gone, Scenes.Communal, ) val navigationDistances = mapOf( Scenes.Gone to 0, Scenes.Lockscreen to 0, Scenes.Communal to 1, Scenes.Shade to 2, Scenes.QuickSettings to 3, ) kosmos.sceneContainerConfig = SceneContainerConfig(sceneKeys, Scenes.Lockscreen, navigationDistances) underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) val previousScene = currentScene assertThat(previousScene).isNotEqualTo(Scenes.Bouncer) underTest.snapToScene(Scenes.Bouncer, "reason") val unknownScene = SceneKey("UNKNOWN") assertThat(previousScene).isNotEqualTo(unknownScene) underTest.snapToScene(unknownScene, "reason") assertThat(currentScene).isEqualTo(previousScene) } @Test fun snapToScene() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -208,8 +163,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun snapToScene_toGoneWhenUnl_doesNotThrow() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -224,15 +177,11 @@ class SceneInteractorTest : SysuiTestCase() { @Test(expected = IllegalStateException::class) fun snapToScene_toGoneWhenStillLocked_throws() = testScope.runTest { underTest = kosmos.sceneInteractor underTest.snapToScene(Scenes.Gone, "reason") } testScope.runTest { underTest.snapToScene(Scenes.Gone, "reason") } @Test fun snapToScene_toHomeSceneFamily() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) underTest.snapToScene(SceneFamilies.Home, "reason") Loading @@ -244,7 +193,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun sceneChanged_inDataSource() = testScope.runTest { underTest = kosmos.sceneInteractor val currentScene by collectLastValue(underTest.currentScene) assertThat(currentScene).isEqualTo(Scenes.Lockscreen) Loading @@ -256,14 +204,14 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun transitionState() = testScope.runTest { underTest = kosmos.sceneInteractor val underTest = kosmos.sceneContainerRepository val sceneContainerRepository = kosmos.sceneContainerRepository val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Lockscreen) ) underTest.setTransitionState(transitionState) val reflectedTransitionState by collectLastValue(underTest.transitionState) sceneContainerRepository.setTransitionState(transitionState) val reflectedTransitionState by collectLastValue(sceneContainerRepository.transitionState) assertThat(reflectedTransitionState).isEqualTo(transitionState.value) val progress = MutableStateFlow(1f) Loading @@ -284,7 +232,7 @@ class SceneInteractorTest : SysuiTestCase() { progress.value = 0.9f assertThat(reflectedTransitionState).isEqualTo(transitionState.value) underTest.setTransitionState(null) sceneContainerRepository.setTransitionState(null) assertThat(reflectedTransitionState) .isEqualTo( ObservableTransitionState.Idle(kosmos.sceneContainerConfig.initialSceneKey) Loading @@ -294,7 +242,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun transitioningTo() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(underTest.currentScene.value) Loading Loading @@ -332,7 +279,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_idle_false() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Shade) Loading @@ -347,7 +293,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_transition_true() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( Loading @@ -369,7 +314,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_updateMidTransition_false() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( Loading Loading @@ -403,7 +347,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_updateOnIdle_false() = testScope.runTest { underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( Loading @@ -429,7 +372,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isVisible() = testScope.runTest { underTest = kosmos.sceneInteractor val isVisible by collectLastValue(underTest.isVisible) assertThat(isVisible).isTrue() Loading @@ -443,7 +385,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isVisible_duringRemoteUserInteraction_forcedVisible() = testScope.runTest { underTest = kosmos.sceneInteractor underTest.setVisible(false, "reason") val isVisible by collectLastValue(underTest.isVisible) assertThat(isVisible).isFalse() Loading @@ -458,7 +399,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun resolveSceneFamily_home() = testScope.runTest { underTest = kosmos.sceneInteractor assertThat(underTest.resolveSceneFamily(SceneFamilies.Home)) .isEqualTo(kosmos.homeSceneFamilyResolver.resolvedScene) } Loading @@ -466,8 +406,46 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun resolveSceneFamily_nonFamily() = testScope.runTest { underTest = kosmos.sceneInteractor val resolved = underTest.resolveSceneFamily(Scenes.Gone).toList() assertThat(resolved).containsExactly(Scenes.Gone).inOrder() } @Test fun transitionValue_test_idle() = testScope.runTest { val transitionValue by collectLastValue(underTest.transitionProgress(Scenes.Gone)) kosmos.setSceneTransition(Idle(Scenes.Gone)) assertThat(transitionValue).isEqualTo(1f) kosmos.setSceneTransition(Idle(Scenes.Lockscreen)) assertThat(transitionValue).isEqualTo(0f) } @Test fun transitionValue_test_transitions() = testScope.runTest { val transitionValue by collectLastValue(underTest.transitionProgress(Scenes.Gone)) val progress = MutableStateFlow(0f) kosmos.setSceneTransition( Transition(from = Scenes.Lockscreen, to = Scenes.Gone, progress = progress) ) assertThat(transitionValue).isEqualTo(0f) progress.value = 0.4f assertThat(transitionValue).isEqualTo(0.4f) kosmos.setSceneTransition( Transition(from = Scenes.Gone, to = Scenes.Lockscreen, progress = progress) ) progress.value = 0.7f assertThat(transitionValue).isEqualTo(0.3f) kosmos.setSceneTransition( Transition(from = Scenes.Lockscreen, to = Scenes.Shade, progress = progress) ) progress.value = 0.9f assertThat(transitionValue).isEqualTo(0f) } }
packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +5 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.animation.ValueAnimator.AnimatorUpdateListener import android.annotation.FloatRange import android.annotation.SuppressLint import android.os.Trace import android.util.Log import com.android.app.tracing.coroutines.withContext Loading Loading @@ -117,10 +118,11 @@ class KeyguardTransitionRepositoryImpl constructor( @Main val mainDispatcher: CoroutineDispatcher, ) : KeyguardTransitionRepository { /* * Each transition between [KeyguardState]s will have an associated Flow. * In order to collect these events, clients should call [transition]. /** * Each transition between [KeyguardState]s will have an associated Flow. In order to collect * these events, clients should call [transition]. */ @SuppressLint("SharedFlowCreation") private val _transitions = MutableSharedFlow<TransitionStep>( replay = 2, Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +11 −14 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.notification.NotificationUtils.interpolate import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.kotlin.sample import javax.inject.Inject Loading @@ -77,6 +77,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine /** * Encapsulates business-logic related to the keyguard but not to a more specific part within it. Loading @@ -91,7 +92,7 @@ constructor( bouncerRepository: KeyguardBouncerRepository, configurationInteractor: ConfigurationInteractor, shadeRepository: ShadeRepository, keyguardTransitionInteractor: KeyguardTransitionInteractor, private val keyguardTransitionInteractor: KeyguardTransitionInteractor, sceneInteractorProvider: Provider<SceneInteractor>, private val fromGoneTransitionInteractor: Provider<FromGoneTransitionInteractor>, private val fromLockscreenTransitionInteractor: Provider<FromLockscreenTransitionInteractor>, Loading Loading @@ -248,21 +249,17 @@ constructor( val isKeyguardGoingAway: Flow<Boolean> = repository.isKeyguardGoingAway /** Keyguard can be clipped at the top as the shade is dragged */ val topClippingBounds: Flow<Int?> = combineTransform( configurationInteractor.onAnyConfigurationChange, keyguardTransitionInteractor .transitionValue(GONE) .map { it == 1f } .onStart { emit(false) } .distinctUntilChanged(), val topClippingBounds: Flow<Int?> by lazy { repository.topClippingBounds ) { _, isGone, topClippingBounds -> if (!isGone) { emit(topClippingBounds) } .sampleFilter( keyguardTransitionInteractor .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE) .onStart { emit(0f) } ) { goneValue -> goneValue != 1f } .distinctUntilChanged() } /** Last point that [KeyguardRootView] view was tapped */ val lastRootViewTapPosition: Flow<Point?> = repository.lastRootViewTapPosition.asStateFlow() Loading
packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +15 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,17 @@ constructor( } } fun transitionValue( scene: SceneKey, stateWithoutSceneContainer: KeyguardState, ): Flow<Float> { return if (SceneContainerFlag.isEnabled) { sceneInteractor.get().transitionProgress(scene) } else { transitionValue(stateWithoutSceneContainer) } } /** * The amount of transition into or out of the given [KeyguardState]. * Loading @@ -232,6 +243,10 @@ constructor( fun transitionValue( state: KeyguardState, ): Flow<Float> { if (SceneContainerFlag.isEnabled && state != state.mapToSceneContainerState()) { Log.e(TAG, "SceneContainer is enabled but a deprecated state $state is used.") return transitionValue(state.mapToSceneContainerScene()!!, state) } return getTransitionValueFlow(state) } Loading