Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c47ff374 authored by Andreas Miko's avatar Andreas Miko Committed by Android (Google) Code Review
Browse files

Merge "Transform and consolidate transitionValue() API" into main

parents 8d16528f 07ce7a6b
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -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
@@ -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)
@@ -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() =
+57 −79
Original line number Diff line number Diff line
@@ -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
@@ -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)

@@ -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)

@@ -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(
@@ -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")
@@ -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)

@@ -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)

@@ -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")
@@ -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)

@@ -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)
@@ -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)
@@ -294,7 +242,6 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    fun transitioningTo() =
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Idle(underTest.currentScene.value)
@@ -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)
@@ -347,7 +293,6 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    fun isTransitionUserInputOngoing_transition_true() =
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Transition(
@@ -369,7 +314,6 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    fun isTransitionUserInputOngoing_updateMidTransition_false() =
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Transition(
@@ -403,7 +347,6 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    fun isTransitionUserInputOngoing_updateOnIdle_false() =
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(
                    ObservableTransitionState.Transition(
@@ -429,7 +372,6 @@ class SceneInteractorTest : SysuiTestCase() {
    @Test
    fun isVisible() =
        testScope.runTest {
            underTest = kosmos.sceneInteractor
            val isVisible by collectLastValue(underTest.isVisible)
            assertThat(isVisible).isTrue()

@@ -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()
@@ -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)
        }
@@ -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)
        }
}
+5 −3
Original line number Diff line number Diff line
@@ -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
@@ -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,
+11 −14
Original line number Diff line number Diff line
@@ -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
@@ -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.
@@ -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>,
@@ -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()
+15 −0
Original line number Diff line number Diff line
@@ -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].
     *
@@ -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