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

Commit 2e85fcf2 authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "Fix legacy udfps occluded state transitions" into main

parents d2ec9ccb 544725f5
Loading
Loading
Loading
Loading
+123 −2
Original line number Diff line number Diff line
@@ -396,7 +396,7 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest :
                .onDozeAmountChanged(
                    eq(.3f),
                    eq(.3f),
                    eq(UdfpsKeyguardViewLegacy.ANIMATION_UNLOCKED_SCREEN_OFF)
                    eq(UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF)
                )

            transitionRepository.sendTransitionStep(
@@ -413,9 +413,130 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest :
                .onDozeAmountChanged(
                    eq(1f),
                    eq(1f),
                    eq(UdfpsKeyguardViewLegacy.ANIMATION_UNLOCKED_SCREEN_OFF)
                    eq(UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF)
                )

            job.cancel()
        }

    @Test
    fun aodToOccluded_dozeAmountChanged() =
        testScope.runTest {
            // GIVEN view is attached
            mController.onViewAttached()
            Mockito.reset(mView)

            val job = mController.listenForAodToOccludedTransitions(this)

            // WHEN transitioning from aod to occluded
            transitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.AOD,
                    to = KeyguardState.OCCLUDED,
                    value = .3f,
                    transitionState = TransitionState.RUNNING
                )
            )
            runCurrent()
            // THEN doze amount is updated
            verify(mView)
                .onDozeAmountChanged(eq(.7f), eq(.7f), eq(UdfpsKeyguardViewLegacy.ANIMATION_NONE))

            transitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.AOD,
                    to = KeyguardState.OCCLUDED,
                    value = 1f,
                    transitionState = TransitionState.FINISHED
                )
            )
            runCurrent()
            // THEN doze amount is updated
            verify(mView)
                .onDozeAmountChanged(eq(0f), eq(0f), eq(UdfpsKeyguardViewLegacy.ANIMATION_NONE))

            job.cancel()
        }

    @Test
    fun occludedToAod_dozeAmountChanged() =
        testScope.runTest {
            // GIVEN view is attached
            mController.onViewAttached()
            Mockito.reset(mView)

            val job = mController.listenForOccludedToAodTransition(this)

            // WHEN transitioning from occluded to aod
            transitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.OCCLUDED,
                    to = KeyguardState.AOD,
                    value = .3f,
                    transitionState = TransitionState.RUNNING
                )
            )
            runCurrent()
            // THEN doze amount is updated
            verify(mView)
                .onDozeAmountChanged(
                    eq(.3f),
                    eq(.3f),
                    eq(UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF)
                )

            transitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.OCCLUDED,
                    to = KeyguardState.AOD,
                    value = 1f,
                    transitionState = TransitionState.FINISHED
                )
            )
            runCurrent()
            // THEN doze amount is updated
            verify(mView)
                .onDozeAmountChanged(
                    eq(1f),
                    eq(1f),
                    eq(UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF)
                )

            job.cancel()
        }

    @Test
    fun cancelledAodToLockscreen_dozeAmountChangedToZero() =
        testScope.runTest {
            // GIVEN view is attached
            mController.onViewAttached()
            Mockito.reset(mView)

            val job = mController.listenForLockscreenAodTransitions(this)
            // WHEN aod to lockscreen transition is cancelled
            transitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.AOD,
                    to = KeyguardState.LOCKSCREEN,
                    value = 1f,
                    transitionState = TransitionState.CANCELED
                )
            )
            runCurrent()
            // ... and WHEN the next transition is from lockscreen => occluded
            transitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.LOCKSCREEN,
                    to = KeyguardState.OCCLUDED,
                    value = .4f,
                    transitionState = TransitionState.STARTED
                )
            )
            runCurrent()

            // THEN doze amount is updated to zero
            verify(mView)
                .onDozeAmountChanged(eq(0f), eq(0f), eq(UdfpsKeyguardViewLegacy.ANIMATION_NONE))
            job.cancel()
        }
}
+55 −8
Original line number Diff line number Diff line
@@ -26,11 +26,13 @@ import com.android.app.animation.Interpolators
import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.biometrics.UdfpsKeyguardViewLegacy.ANIMATION_UNLOCKED_SCREEN_OFF
import com.android.systemui.biometrics.UdfpsKeyguardViewLegacy.ANIMATE_APPEAR_ON_SCREEN_OFF
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.ui.adapter.UdfpsKeyguardViewControllerAdapter
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -49,7 +51,7 @@ import java.io.PrintWriter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch

/** Class that coordinates non-HBM animations during keyguard authentication. */
@@ -191,8 +193,38 @@ open class UdfpsKeyguardViewControllerLegacy(
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                listenForBouncerExpansion(this)
                listenForAlternateBouncerVisibility(this)
                listenForOccludedToAodTransition(this)
                listenForGoneToAodTransition(this)
                listenForLockscreenAodTransitions(this)
                listenForAodToOccludedTransitions(this)
            }
        }
    }

    @VisibleForTesting
    suspend fun listenForAodToOccludedTransitions(scope: CoroutineScope): Job {
        return scope.launch {
            transitionInteractor.transition(KeyguardState.AOD, KeyguardState.OCCLUDED).collect {
                transitionStep ->
                view.onDozeAmountChanged(
                    1f - transitionStep.value,
                    1f - transitionStep.value,
                    UdfpsKeyguardViewLegacy.ANIMATION_NONE,
                )
            }
        }
    }

    @VisibleForTesting
    suspend fun listenForOccludedToAodTransition(scope: CoroutineScope): Job {
        return scope.launch {
            transitionInteractor.transition(KeyguardState.OCCLUDED, KeyguardState.AOD).collect {
                transitionStep ->
                view.onDozeAmountChanged(
                    transitionStep.value,
                    transitionStep.value,
                    ANIMATE_APPEAR_ON_SCREEN_OFF,
                )
            }
        }
    }
@@ -204,7 +236,7 @@ open class UdfpsKeyguardViewControllerLegacy(
                view.onDozeAmountChanged(
                    transitionStep.value,
                    transitionStep.value,
                    ANIMATION_UNLOCKED_SCREEN_OFF,
                    ANIMATE_APPEAR_ON_SCREEN_OFF,
                )
            }
        }
@@ -214,6 +246,20 @@ open class UdfpsKeyguardViewControllerLegacy(
    suspend fun listenForLockscreenAodTransitions(scope: CoroutineScope): Job {
        return scope.launch {
            transitionInteractor.dozeAmountTransition.collect { transitionStep ->
                if (transitionStep.transitionState == TransitionState.CANCELED) {
                    if (
                        transitionInteractor.startedKeyguardTransitionStep.first().to !=
                            KeyguardState.AOD
                    ) {
                        // If the next started transition isn't transitioning back to AOD, force
                        // doze amount to be 0f (as if the transition to the lockscreen completed).
                        view.onDozeAmountChanged(
                            0f,
                            0f,
                            UdfpsKeyguardViewLegacy.ANIMATION_NONE,
                        )
                    }
                } else {
                    view.onDozeAmountChanged(
                        transitionStep.value,
                        transitionStep.value,
@@ -222,6 +268,7 @@ open class UdfpsKeyguardViewControllerLegacy(
                }
            }
        }
    }

    @VisibleForTesting
    override suspend fun listenForBouncerExpansion(scope: CoroutineScope): Job {
+4 −4
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ public class UdfpsKeyguardViewLegacy extends UdfpsAnimationView {

        // if we're animating from screen off, we can immediately place the icon in the
        // AoD-burn in location, else we need to translate the icon from LS => AoD.
        final float darkAmountForAnimation = mAnimationType == ANIMATION_UNLOCKED_SCREEN_OFF
        final float darkAmountForAnimation = mAnimationType == ANIMATE_APPEAR_ON_SCREEN_OFF
                ? 1f : mInterpolatedDarkAmount;
        final float burnInOffsetX = MathUtils.lerp(0f,
            getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
@@ -171,7 +171,7 @@ public class UdfpsKeyguardViewLegacy extends UdfpsAnimationView {
                mAnimationType == ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN
                        && (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f);
        final boolean doneAnimatingUnlockedScreenOff =
                mAnimationType == ANIMATION_UNLOCKED_SCREEN_OFF
                mAnimationType == ANIMATE_APPEAR_ON_SCREEN_OFF
                        && (mInterpolatedDarkAmount == 1f);
        if (doneAnimatingBetweenAodAndLS || doneAnimatingUnlockedScreenOff) {
            mAnimationType = ANIMATION_NONE;
@@ -243,10 +243,10 @@ public class UdfpsKeyguardViewLegacy extends UdfpsAnimationView {

    static final int ANIMATION_NONE = 0;
    static final int ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN = 1;
    static final int ANIMATION_UNLOCKED_SCREEN_OFF = 2;
    static final int ANIMATE_APPEAR_ON_SCREEN_OFF = 2;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({ANIMATION_NONE, ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN, ANIMATION_UNLOCKED_SCREEN_OFF})
    @IntDef({ANIMATION_NONE, ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN, ANIMATE_APPEAR_ON_SCREEN_OFF})
    private @interface AnimationType {}

    void onDozeAmountChanged(float linear, float eased, @AnimationType int animationType) {