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

Commit c8506b48 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fade out behind scrim when transitioning from lockscreen to dream" into main

parents 63a49a11 03f6a844
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1228,6 +1228,16 @@ flag {
  }
}

flag {
  name: "dream_transition_fixes"
  namespace: "systemui"
  description: "Flags some minor transition fixes for opening the dream"
  bug: "409720192"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
    name: "dream_overlay_updated_ui"
    namespace: "systemui"
+38 −38
Original line number Diff line number Diff line
@@ -19,27 +19,26 @@ package com.android.systemui.keyguard.ui.viewmodel
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.Flags
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.collectValues
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.shade.ShadeTestUtil
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.statusbar.phone.ScrimState
import com.android.systemui.testKosmos
import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -51,13 +50,9 @@ import platform.test.runner.parameterized.Parameters
class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {

    private val kosmos =
        testKosmos().apply {
        testKosmos().useUnconfinedTestDispatcher().apply {
            fakeFeatureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) }
        }
    private val testScope = kosmos.testScope
    private lateinit var repository: FakeKeyguardTransitionRepository
    private lateinit var shadeTestUtil: ShadeTestUtil
    private lateinit var keyguardRepository: FakeKeyguardRepository
    private lateinit var underTest: LockscreenToDreamingTransitionViewModel

    // add to init block
@@ -75,17 +70,14 @@ class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization)

    @Before
    fun setUp() {
        repository = kosmos.fakeKeyguardTransitionRepository
        shadeTestUtil = kosmos.shadeTestUtil
        keyguardRepository = kosmos.fakeKeyguardRepository
        underTest = kosmos.lockscreenToDreamingTransitionViewModel
    }

    @Test
    fun lockscreenFadeOut() =
        testScope.runTest {
        kosmos.runTest {
            val values by collectValues(underTest.lockscreenAlpha)
            repository.sendTransitionSteps(
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                steps =
                    listOf(
                        step(0f, TransitionState.STARTED), // Should start running here...
@@ -106,12 +98,11 @@ class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization)

    @Test
    fun lockscreenFadeOut_shadeExpanded() =
        testScope.runTest {
        kosmos.runTest {
            val values by collectValues(underTest.lockscreenAlpha)
            shadeExpanded(true)
            runCurrent()

            repository.sendTransitionSteps(
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                steps =
                    listOf(
                        step(0f, TransitionState.STARTED),
@@ -130,9 +121,9 @@ class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization)

    @Test
    fun shortcutsFadeOut() =
        testScope.runTest {
        kosmos.runTest {
            val values by collectValues(underTest.shortcutsAlpha)
            repository.sendTransitionSteps(
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                steps =
                    listOf(
                        step(0f, TransitionState.STARTED), // Should start running here...
@@ -153,12 +144,11 @@ class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization)

    @Test
    fun shortcutsFadeOut_shadeExpanded() =
        testScope.runTest {
        kosmos.runTest {
            val values by collectValues(underTest.shortcutsAlpha)
            shadeExpanded(true)
            runCurrent()

            repository.sendTransitionSteps(
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                steps =
                    listOf(
                        step(0f, TransitionState.STARTED),
@@ -177,11 +167,11 @@ class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization)

    @Test
    fun lockscreenTranslationY() =
        testScope.runTest {
        kosmos.runTest {
            val pixels = 100
            val values by collectValues(underTest.lockscreenTranslationY(pixels))

            repository.sendTransitionSteps(
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                steps =
                    listOf(
                        step(0f, TransitionState.STARTED), // Should start running here...
@@ -202,12 +192,11 @@ class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization)

    @Test
    fun deviceEntryParentViewAlpha_shadeExpanded() =
        testScope.runTest {
        kosmos.runTest {
            val values by collectValues(underTest.deviceEntryParentViewAlpha)
            shadeExpanded(true)
            runCurrent()

            repository.sendTransitionSteps(
            fakeKeyguardTransitionRepository.sendTransitionSteps(
                steps =
                    listOf(
                        step(0f, TransitionState.STARTED),
@@ -226,26 +215,37 @@ class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization)

    @Test
    fun deviceEntryParentViewAlpha_shadeNotExpanded() =
        testScope.runTest {
        kosmos.runTest {
            val actual by collectLastValue(underTest.deviceEntryParentViewAlpha)
            shadeExpanded(false)
            runCurrent()

            // fade out
            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
            fakeKeyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
            assertThat(actual).isEqualTo(1f)

            repository.sendTransitionStep(step(.1f))
            fakeKeyguardTransitionRepository.sendTransitionStep(step(.1f))
            assertThat(actual).isIn(Range.open(.1f, .9f))

            // alpha is 1f before the full transition starts ending
            repository.sendTransitionStep(step(0.8f))
            fakeKeyguardTransitionRepository.sendTransitionStep(step(0.8f))
            assertThat(actual).isEqualTo(0f)

            repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
            fakeKeyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED))
            assertThat(actual).isEqualTo(0f)
        }

    @Test
    fun scrimAlpha() =
        kosmos.runTest {
            val value by collectLastValue(underTest.scrimAlpha)

            for (step in listOf(0f, 0.2f, 0.5f, 0.8f, 1.0f)) {
                fakeKeyguardTransitionRepository.sendTransitionStep(step(step))
                assertThat(value?.behindAlpha)
                    .isEqualTo((1 - step) * ScrimState.KEYGUARD.behindAlpha)
            }
        }

    private fun step(
        value: Float,
        state: TransitionState = TransitionState.RUNNING,
@@ -259,11 +259,11 @@ class LockscreenToDreamingTransitionViewModelTest(flags: FlagsParameterization)
        )
    }

    private fun shadeExpanded(expanded: Boolean) {
    private fun Kosmos.shadeExpanded(expanded: Boolean) {
        if (expanded) {
            shadeTestUtil.setQsExpansion(1f)
        } else {
            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
            fakeKeyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
            shadeTestUtil.setQsExpansion(0f)
            shadeTestUtil.setLockscreenShadeExpansion(0f)
        }
+27 −14
Original line number Diff line number Diff line
@@ -23,15 +23,19 @@ import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
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.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.collectValues
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.phone.ScrimState
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -41,24 +45,21 @@ import org.junit.runner.RunWith
@DisableSceneContainer
@RunWith(AndroidJUnit4::class)
class PrimaryBouncerToDreamingTransitionViewModelTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
    private lateinit var underTest: PrimaryBouncerToDreamingTransitionViewModel

    @Before
    fun setUp() {
        keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
        underTest = kosmos.primaryBouncerToDreamingTransitionViewModel
    }

    @Test
    fun blurRadiusGoesToMinImmediately() =
        testScope.runTest {
        kosmos.runTest {
            val values by collectValues(underTest.windowBlurRadius)
            kosmos.keyguardWindowBlurTestUtil.shadeExpanded(false)
            keyguardWindowBlurTestUtil.shadeExpanded(false)

            kosmos.keyguardWindowBlurTestUtil.assertTransitionToBlurRadius(
            keyguardWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
                startValue = kosmos.blurConfig.maxBlurRadiusPx,
                endValue = kosmos.blurConfig.minBlurRadiusPx,
@@ -70,11 +71,11 @@ class PrimaryBouncerToDreamingTransitionViewModelTest : SysuiTestCase() {
    @Test
    @EnableFlags(Flags.FLAG_NOTIFICATION_SHADE_BLUR)
    fun blurRadiusRemainsAtMaxIfShadeIsExpandedAndShadeBlurIsEnabled() =
        testScope.runTest {
        kosmos.runTest {
            val values by collectValues(underTest.windowBlurRadius)
            kosmos.keyguardWindowBlurTestUtil.shadeExpanded(true)
            keyguardWindowBlurTestUtil.shadeExpanded(true)

            kosmos.keyguardWindowBlurTestUtil.assertTransitionToBlurRadius(
            keyguardWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
                startValue = kosmos.blurConfig.maxBlurRadiusPx,
                endValue = kosmos.blurConfig.maxBlurRadiusPx,
@@ -86,10 +87,10 @@ class PrimaryBouncerToDreamingTransitionViewModelTest : SysuiTestCase() {

    @Test
    fun notificationBlurDropsToMinWhenGoingBackFromPrimaryBouncerToDreaming() =
        testScope.runTest {
        kosmos.runTest {
            val values by collectValues(underTest.notificationBlurRadius)

            kosmos.keyguardWindowBlurTestUtil.assertTransitionToBlurRadius(
            keyguardWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
                startValue = kosmos.blurConfig.minBlurRadiusPx,
                endValue = kosmos.blurConfig.minBlurRadiusPx,
@@ -99,6 +100,18 @@ class PrimaryBouncerToDreamingTransitionViewModelTest : SysuiTestCase() {
            )
        }

    @Test
    fun scrimAlpha() =
        kosmos.runTest {
            val value by collectLastValue(underTest.scrimAlpha)

            for (step in listOf(0f, 0.2f, 0.5f, 0.8f, 1.0f)) {
                fakeKeyguardTransitionRepository.sendTransitionStep(step(step))
                assertThat(value?.behindAlpha)
                    .isEqualTo((1 - step) * ScrimState.KEYGUARD.behindAlpha)
            }
        }

    private fun step(value: Float, state: TransitionState = RUNNING): TransitionStep {
        return TransitionStep(
            from = KeyguardState.PRIMARY_BOUNCER,
+20 −0
Original line number Diff line number Diff line
@@ -22,11 +22,14 @@ import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionI
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.ScrimAlpha
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.statusbar.phone.ScrimState
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

/**
 * Breaks down LOCKSCREEN->DREAMING transition into discrete steps for corresponding views to
@@ -76,6 +79,23 @@ constructor(animationFlow: KeyguardTransitionAnimationFlow) : DeviceEntryIconTra
            onCancel = { 0f },
        )

    // Fade out behind scrim as it's on top of the dream.
    val scrimAlpha: Flow<ScrimAlpha> =
        transitionAnimation
            .sharedFlowWithShade(
                duration = 250.milliseconds,
                onStep = { step, isShadeExpanded ->
                    (1 - step) *
                        (if (isShadeExpanded) ScrimState.SHADE_LOCKED.behindAlpha
                        else ScrimState.KEYGUARD.behindAlpha)
                },
                onFinish = { 0f },
                // Shade is closed by ACTION_CLOSE_SYSTEM_DIALOGS when dream starts, so we'll be
                // returning to the keyguard with no shade open.
                onCancel = { ScrimState.KEYGUARD.behindAlpha },
            )
            .map { ScrimAlpha(behindAlpha = it) }

    companion object {
        @JvmField val DREAMING_ANIMATION_DURATION_MS = TO_DREAMING_DURATION.inWholeMilliseconds
    }
+14 −0
Original line number Diff line number Diff line
@@ -22,12 +22,15 @@ import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransit
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.ScrimAlpha
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.statusbar.phone.ScrimState
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

@SysUISingleton
class PrimaryBouncerToDreamingTransitionViewModel
@@ -76,4 +79,15 @@ constructor(blurConfig: BlurConfig, animationFlow: KeyguardTransitionAnimationFl

    override val notificationBlurRadius: Flow<Float> =
        transitionAnimation.immediatelyTransitionTo(blurConfig.minBlurRadiusPx)

    // Fade out behind scrim as it's on top of the dream.
    val scrimAlpha: Flow<ScrimAlpha> =
        transitionAnimation
            .sharedFlow(
                duration = FromPrimaryBouncerTransitionInteractor.TO_DREAMING_DURATION,
                onStep = { step -> (1 - step) * ScrimState.BOUNCER.behindAlpha },
                onFinish = { 0f },
                onCancel = { ScrimState.BOUNCER.behindAlpha },
            )
            .map { ScrimAlpha(behindAlpha = it) }
}
Loading