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

Commit ca834953 authored by Matt Pietal's avatar Matt Pietal Committed by Android (Google) Code Review
Browse files

Merge changes Ic0f507ad,I87f02c4b into main

* changes:
  Use shared flow for transition animations
  Migrate OCCLUDED<->LOCKSCREEN alpha/translation
parents 233a081b b499a105
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeCommandQueue
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
@@ -53,7 +54,6 @@ class KeyguardInteractorTest : SysuiTestCase() {
    private val sceneInteractor = testUtils.sceneInteractor()
    private val commandQueue = FakeCommandQueue()
    private val bouncerRepository = FakeKeyguardBouncerRepository()
    private val configurationRepository = FakeConfigurationRepository()
    private val shadeRepository = FakeShadeRepository()
    private val transitionState: MutableStateFlow<ObservableTransitionState> =
        MutableStateFlow(ObservableTransitionState.Idle(SceneKey.Gone))
@@ -65,7 +65,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
            powerInteractor = PowerInteractorFactory.create().powerInteractor,
            sceneContainerFlags = testUtils.sceneContainerFlags,
            bouncerRepository = bouncerRepository,
            configurationRepository = configurationRepository,
            configurationInteractor = ConfigurationInteractor(FakeConfigurationRepository()),
            shadeRepository = shadeRepository,
            sceneInteractorProvider = { sceneInteractor },
        )
+130 −159
Original line number Diff line number Diff line
@@ -19,14 +19,11 @@ package com.android.systemui.keyguard.ui.viewmodel
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
@@ -38,16 +35,12 @@ import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.util.mockito.mock
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@@ -55,223 +48,201 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
    private lateinit var underTest: DreamingToLockscreenTransitionViewModel
    private lateinit var repository: FakeKeyguardTransitionRepository
    private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository

    @Before
    fun setUp() {
        repository = FakeKeyguardTransitionRepository()
        fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
        val interactor =
            KeyguardTransitionInteractorFactory.create(
                    scope = TestScope().backgroundScope,
                    repository = repository,
                )
                .keyguardTransitionInteractor
        underTest =
            DreamingToLockscreenTransitionViewModel(
                interactor,
                mock(),
                DeviceEntryUdfpsInteractor(
                    fingerprintPropertyRepository = fingerprintPropertyRepository,
                    fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository(),
                    biometricSettingsRepository = FakeBiometricSettingsRepository(),
                ),
            )
    }
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
    private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
    private val underTest = kosmos.dreamingToLockscreenTransitionViewModel

    @Test
    fun dreamOverlayTranslationY() =
        runTest(UnconfinedTestDispatcher()) {
            val values = mutableListOf<Float>()

        testScope.runTest {
            val pixels = 100
            val job =
                underTest.dreamOverlayTranslationY(pixels).onEach { values.add(it) }.launchIn(this)

            repository.sendTransitionStep(step(0f, STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.3f))
            repository.sendTransitionStep(step(0.5f))
            repository.sendTransitionStep(step(0.6f))
            repository.sendTransitionStep(step(0.8f))
            repository.sendTransitionStep(step(1f))
            val values by collectValues(underTest.dreamOverlayTranslationY(pixels))

            keyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.3f),
                    step(0.5f),
                    step(0.6f),
                    step(0.8f),
                    step(1f),
                ),
                testScope,
            )

            assertThat(values.size).isEqualTo(7)
            values.forEach { assertThat(it).isIn(Range.closed(0f, 100f)) }

            job.cancel()
        }

    @Test
    fun dreamOverlayFadeOut() =
        runTest(UnconfinedTestDispatcher()) {
            val values = mutableListOf<Float>()

            val job = underTest.dreamOverlayAlpha.onEach { values.add(it) }.launchIn(this)
        testScope.runTest {
            val values by collectValues(underTest.dreamOverlayAlpha)

            keyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    // Should start running here...
            repository.sendTransitionStep(step(0f, STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.1f))
            repository.sendTransitionStep(step(0.5f))
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.1f),
                    step(0.5f),
                    // ...up to here
            repository.sendTransitionStep(step(1f))
                    step(1f),
                ),
                testScope,
            )

            // Only two values should be present, since the dream overlay runs for a small fraction
            // of the overall animation time
            assertThat(values.size).isEqualTo(4)
            values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }

            job.cancel()
        }

    @Test
    fun lockscreenFadeIn() =
        runTest(UnconfinedTestDispatcher()) {
            val values = mutableListOf<Float>()

            val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)

            repository.sendTransitionStep(step(0f, STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.1f))
            repository.sendTransitionStep(step(0.2f))
            repository.sendTransitionStep(step(0.3f))
            repository.sendTransitionStep(step(1f))
        testScope.runTest {
            val values by collectValues(underTest.lockscreenAlpha)

            keyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.1f),
                    step(0.2f),
                    step(0.3f),
                    step(1f),
                ),
                testScope,
            )

            assertThat(values.size).isEqualTo(4)
            values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }

            job.cancel()
        }

    @Test
    fun deviceEntryParentViewFadeIn() =
        runTest(UnconfinedTestDispatcher()) {
            val values = mutableListOf<Float>()

            val job = underTest.deviceEntryParentViewAlpha.onEach { values.add(it) }.launchIn(this)

            repository.sendTransitionStep(step(0f, STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.1f))
            repository.sendTransitionStep(step(0.2f))
            repository.sendTransitionStep(step(0.3f))
            repository.sendTransitionStep(step(1f))
        testScope.runTest {
            val values by collectValues(underTest.deviceEntryParentViewAlpha)

            keyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.1f),
                    step(0.2f),
                    step(0.3f),
                    step(1f),
                ),
                testScope,
            )

            assertThat(values.size).isEqualTo(4)
            values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }

            job.cancel()
        }

    @Test
    fun deviceEntryBackgroundViewAppear() =
        runTest(UnconfinedTestDispatcher()) {
        testScope.runTest {
            fingerprintPropertyRepository.setProperties(
                sensorId = 0,
                strength = SensorStrength.STRONG,
                sensorType = FingerprintSensorType.UDFPS_OPTICAL,
                sensorLocations = emptyMap(),
            )
            val values = mutableListOf<Float>()

            val job =
                underTest.deviceEntryBackgroundViewAlpha.onEach { values.add(it) }.launchIn(this)

            repository.sendTransitionStep(step(0f, STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.1f))
            repository.sendTransitionStep(step(0.2f))
            repository.sendTransitionStep(step(0.3f))
            repository.sendTransitionStep(step(1f))
            val values by collectValues(underTest.deviceEntryBackgroundViewAlpha)

            keyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.1f),
                    step(0.2f),
                    step(0.3f),
                    step(1f),
                ),
                testScope,
            )

            values.forEach { assertThat(it).isEqualTo(1f) }

            job.cancel()
        }

    @Test
    fun deviceEntryBackground_noUdfps_noUpdates() =
        runTest(UnconfinedTestDispatcher()) {
        testScope.runTest {
            fingerprintPropertyRepository.setProperties(
                sensorId = 0,
                strength = SensorStrength.STRONG,
                sensorType = FingerprintSensorType.REAR,
                sensorLocations = emptyMap(),
            )
            val values = mutableListOf<Float>()

            val job =
                underTest.deviceEntryBackgroundViewAlpha.onEach { values.add(it) }.launchIn(this)

            repository.sendTransitionStep(step(0f, STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.1f))
            repository.sendTransitionStep(step(0.2f))
            repository.sendTransitionStep(step(0.3f))
            repository.sendTransitionStep(step(1f))
            val values by collectValues(underTest.deviceEntryBackgroundViewAlpha)

            keyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.1f),
                    step(0.2f),
                    step(0.3f),
                    step(1f),
                ),
                testScope,
            )

            assertThat(values.size).isEqualTo(0) // no updates

            job.cancel()
        }

    @Test
    fun lockscreenTranslationY() =
        runTest(UnconfinedTestDispatcher()) {
            val values = mutableListOf<Float>()

        testScope.runTest {
            val pixels = 100
            val job =
                underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)

            repository.sendTransitionStep(step(0f, STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.3f))
            repository.sendTransitionStep(step(0.5f))
            repository.sendTransitionStep(step(1f))
            val values by collectValues(underTest.lockscreenTranslationY(pixels))

            keyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.3f),
                    step(0.5f),
                    step(1f),
                ),
                testScope,
            )

            assertThat(values.size).isEqualTo(5)
            values.forEach { assertThat(it).isIn(Range.closed(-100f, 0f)) }

            job.cancel()
        }

    @Test
    fun transitionEnded() =
        runTest(UnconfinedTestDispatcher()) {
            val values = mutableListOf<TransitionStep>()

            val job = underTest.transitionEnded.onEach { values.add(it) }.launchIn(this)

            repository.sendTransitionStep(TransitionStep(DOZING, DREAMING, 0.0f, STARTED))
            repository.sendTransitionStep(TransitionStep(DOZING, DREAMING, 1.0f, FINISHED))

            repository.sendTransitionStep(TransitionStep(DREAMING, LOCKSCREEN, 0.0f, STARTED))
            repository.sendTransitionStep(TransitionStep(DREAMING, LOCKSCREEN, 0.1f, RUNNING))
            repository.sendTransitionStep(TransitionStep(DREAMING, LOCKSCREEN, 1.0f, FINISHED))

            repository.sendTransitionStep(TransitionStep(LOCKSCREEN, DREAMING, 0.0f, STARTED))
            repository.sendTransitionStep(TransitionStep(LOCKSCREEN, DREAMING, 0.5f, RUNNING))
            repository.sendTransitionStep(TransitionStep(LOCKSCREEN, DREAMING, 1.0f, FINISHED))

            repository.sendTransitionStep(TransitionStep(DREAMING, GONE, 0.0f, STARTED))
            repository.sendTransitionStep(TransitionStep(DREAMING, GONE, 0.5f, RUNNING))
            repository.sendTransitionStep(TransitionStep(DREAMING, GONE, 1.0f, CANCELED))

            repository.sendTransitionStep(TransitionStep(DREAMING, AOD, 0.0f, STARTED))
            repository.sendTransitionStep(TransitionStep(DREAMING, AOD, 1.0f, FINISHED))
        testScope.runTest {
            val values by collectValues(underTest.transitionEnded)

            keyguardTransitionRepository.sendTransitionSteps(
                listOf(
                    TransitionStep(DOZING, DREAMING, 0.0f, STARTED),
                    TransitionStep(DOZING, DREAMING, 1.0f, FINISHED),
                    TransitionStep(DREAMING, LOCKSCREEN, 0.0f, STARTED),
                    TransitionStep(DREAMING, LOCKSCREEN, 0.1f, RUNNING),
                    TransitionStep(DREAMING, LOCKSCREEN, 1.0f, FINISHED),
                    TransitionStep(LOCKSCREEN, DREAMING, 0.0f, STARTED),
                    TransitionStep(LOCKSCREEN, DREAMING, 0.5f, RUNNING),
                    TransitionStep(LOCKSCREEN, DREAMING, 1.0f, FINISHED),
                    TransitionStep(DREAMING, GONE, 0.0f, STARTED),
                    TransitionStep(DREAMING, GONE, 0.5f, RUNNING),
                    TransitionStep(DREAMING, GONE, 1.0f, CANCELED),
                    TransitionStep(DREAMING, AOD, 0.0f, STARTED),
                    TransitionStep(DREAMING, AOD, 1.0f, FINISHED),
                ),
                testScope,
            )

            assertThat(values.size).isEqualTo(3)
            values.forEach {
                assertThat(it.transitionState == FINISHED || it.transitionState == CANCELED)
                    .isTrue()
            }

            job.cancel()
        }

    private fun step(value: Float, state: TransitionState = RUNNING): TransitionStep {
+38 −50
Original line number Diff line number Diff line
@@ -19,85 +19,73 @@ package com.android.systemui.keyguard.ui.viewmodel
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
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.testKosmos
import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class GoneToDreamingTransitionViewModelTest : SysuiTestCase() {
    private lateinit var underTest: GoneToDreamingTransitionViewModel
    private lateinit var repository: FakeKeyguardTransitionRepository

    @Before
    fun setUp() {
        repository = FakeKeyguardTransitionRepository()
        val interactor =
            KeyguardTransitionInteractorFactory.create(
                    scope = TestScope().backgroundScope,
                    repository = repository,
                )
                .keyguardTransitionInteractor
        underTest = GoneToDreamingTransitionViewModel(interactor)
    }
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private val repository = kosmos.fakeKeyguardTransitionRepository
    private val underTest = kosmos.goneToDreamingTransitionViewModel

    @Test
    fun lockscreenFadeOut() =
        runTest(UnconfinedTestDispatcher()) {
            val values = mutableListOf<Float>()

            val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this)
    fun runTest() =
        testScope.runTest {
            val values by collectValues(underTest.lockscreenAlpha)

            repository.sendTransitionSteps(
                listOf(
                    // Should start running here...
            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.1f))
            repository.sendTransitionStep(step(0.2f))
            repository.sendTransitionStep(step(0.3f))
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.1f),
                    step(0.2f),
                    step(0.3f),
                    // ...up to here
            repository.sendTransitionStep(step(1f))
                    step(1f),
                ),
                testScope,
            )

            // Only three values should be present, since the dream overlay runs for a small
            // fraction of the overall animation time
            assertThat(values.size).isEqualTo(5)
            values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }

            job.cancel()
        }

    @Test
    fun lockscreenTranslationY() =
        runTest(UnconfinedTestDispatcher()) {
            val values = mutableListOf<Float>()

        testScope.runTest {
            val pixels = 100
            val job =
                underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this)
            val values by collectValues(underTest.lockscreenTranslationY(pixels))

            repository.sendTransitionSteps(
                listOf(
                    // Should start running here...
            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
            repository.sendTransitionStep(step(0f))
            repository.sendTransitionStep(step(0.3f))
            repository.sendTransitionStep(step(0.5f))
                    step(0f, TransitionState.STARTED),
                    step(0f),
                    step(0.3f),
                    step(0.5f),
                    // And a final reset event on CANCEL
            repository.sendTransitionStep(step(0.8f, TransitionState.CANCELED))
                    step(0.8f, TransitionState.CANCELED)
                ),
                testScope,
            )

            assertThat(values.size).isEqualTo(5)
            values.forEach { assertThat(it).isIn(Range.closed(0f, 100f)) }

            job.cancel()
        }

    private fun step(
+1 −6
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.systemui.flags.Flags
import com.android.systemui.flags.featureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.TransitionState
@@ -55,11 +54,7 @@ class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() {
    private val repository = kosmos.fakeKeyguardTransitionRepository
    private val shadeRepository = kosmos.shadeRepository
    private val keyguardRepository = kosmos.fakeKeyguardRepository
    private val underTest =
        LockscreenToDreamingTransitionViewModel(
            interactor = kosmos.keyguardTransitionInteractor,
            shadeDependentFlows = kosmos.shadeDependentFlows,
        )
    private val underTest = kosmos.lockscreenToDreamingTransitionViewModel

    @Test
    fun lockscreenFadeOut() =
+14 −11

File changed.

Preview size limit exceeded, changes collapsed.

Loading