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

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

Merge changes If9501500,I321d8023 into main

* changes:
  Smooth burn-in transitions
  Fix AOD icon flicker during GONE->AOD
parents 195728a0 b2eb12e9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.ui.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags as AConfigFlags
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -68,6 +69,8 @@ class AodBurnInViewModelTest : SysuiTestCase() {

    @Before
    fun setUp() {
        mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)

        MockitoAnnotations.initMocks(this)
        whenever(burnInInteractor.keyguardBurnIn).thenReturn(burnInFlow)
        kosmos.burnInInteractor = burnInInteractor
+17 −0
Original line number Diff line number Diff line
@@ -115,6 +115,23 @@ class KeyguardRootViewModelTest : SysuiTestCase() {
            assertThat(isVisible?.isAnimating).isFalse()
        }

    @Test
    fun iconContainer_isNotVisible_onKeyguard_dontShowWhenGoneToAodTransitionRunning() =
        testScope.runTest {
            val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
            runCurrent()
            keyguardTransitionRepository.sendTransitionSteps(
                from = KeyguardState.GONE,
                to = KeyguardState.AOD,
                testScope,
            )
            whenever(screenOffAnimationController.shouldShowAodIconsWhenShade()).thenReturn(false)
            runCurrent()

            assertThat(isVisible?.value).isFalse()
            assertThat(isVisible?.isAnimating).isFalse()
        }

    @Test
    fun iconContainer_isVisible_bypassEnabled() =
        testScope.runTest {
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ constructor(
                BurnInModel(translationX, translationY, burnInHelperWrapper.burnInScale())
            }
            .distinctUntilChanged()
            .stateIn(scope, SharingStarted.Lazily, BurnInModel())

    /**
     * Use for max burn-in offsets that are NOT specified in pixels. This flow will recalculate the
+2 −0
Original line number Diff line number Diff line
@@ -98,6 +98,8 @@ constructor(
                        val modeOnCanceled =
                            if (lastStartedStep.from == KeyguardState.LOCKSCREEN) {
                                TransitionModeOnCanceled.REVERSE
                            } else if (lastStartedStep.from == KeyguardState.GONE) {
                                TransitionModeOnCanceled.RESET
                            } else {
                                TransitionModeOnCanceled.LAST_VALUE
                            }
+37 −6
Original line number Diff line number Diff line
@@ -112,6 +112,38 @@ constructor(
            interpolator: Interpolator = LINEAR,
            name: String? = null
        ): Flow<Float> {
            return sharedFlowWithState(
                    duration = duration,
                    onStep = onStep,
                    startTime = startTime,
                    onStart = onStart,
                    onCancel = onCancel,
                    onFinish = onFinish,
                    interpolator = interpolator,
                    name = name,
                )
                .mapNotNull { stateToValue -> stateToValue.value }
        }

        /**
         * Transitions will occur over a [transitionDuration] with [TransitionStep]s being emitted
         * in the range of [0, 1]. View animations should begin and end within a subset of this
         * range. This function maps the [startTime] and [duration] into [0, 1], when this subset is
         * valid.
         *
         * Will return a [StateToValue], which encompasses the calculated value as well as the
         * transitionState that is associated with it.
         */
        fun sharedFlowWithState(
            duration: Duration,
            onStep: (Float) -> Float,
            startTime: Duration = 0.milliseconds,
            onStart: (() -> Unit)? = null,
            onCancel: (() -> Float)? = null,
            onFinish: (() -> Float)? = null,
            interpolator: Interpolator = LINEAR,
            name: String? = null
        ): Flow<StateToValue> {
            if (!duration.isPositive()) {
                throw IllegalArgumentException("duration must be a positive number: $duration")
            }
@@ -164,7 +196,6 @@ constructor(
                        .also { logger.logTransitionStep(name, step, it.value) }
                }
                .distinctUntilChanged()
                .mapNotNull { stateToValue -> stateToValue.value }
        }

        /**
@@ -174,9 +205,9 @@ constructor(
            return sharedFlow(duration = 1.milliseconds, onStep = { value }, onFinish = { value })
        }
    }
}

data class StateToValue(
        val transitionState: TransitionState,
        val value: Float?,
    val transitionState: TransitionState = TransitionState.FINISHED,
    val value: Float? = 0f,
)
}
Loading