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

Commit 1c7b4e56 authored by Josh Tsuji's avatar Josh Tsuji
Browse files

Fix NotificationLaunchAnimator in the refactor.

We hand the RemoteAnimationTarget to the launch animator, so we need to set it to alpha = 0f to ensure it does not flicker in the meantime.

Since the WmLockscreenVisibilityManager retains control over the remote animation lifecycle, we also need to make sure to keep the animation alive until it's done running, or it'll jump-cut in.

Bug: 278086361
Test: atest KeyguardSurfaceBehindInteractorTest
Flag: ACONFIG com.android.systemui.keyguard_wm_state_refactor DEVELOPMENT
Change-Id: I84714e31ca13c22409e294135b8cd48997bf749e
parent 8bc520e8
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.systemui.keyguard.data.repository.KeyguardSurfaceBehindReposi
import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.isSurfaceVisible
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
import com.android.systemui.util.kotlin.toPx
import dagger.Lazy
import javax.inject.Inject
@@ -44,6 +45,7 @@ constructor(
    transitionInteractor: KeyguardTransitionInteractor,
    inWindowLauncherUnlockAnimationInteractor: Lazy<InWindowLauncherUnlockAnimationInteractor>,
    swipeToDismissInteractor: SwipeToDismissInteractor,
    notificationLaunchInteractor: NotificationLaunchAnimationInteractor,
) {
    /**
     * The view params to use for the surface. These params describe the alpha/translation values to
@@ -53,10 +55,20 @@ constructor(
        combine(
                transitionInteractor.startedKeyguardTransitionStep,
                transitionInteractor.currentKeyguardState,
            ) { startedStep, currentState ->
                notificationLaunchInteractor.isLaunchAnimationRunning,
            ) { startedStep, currentState, notifAnimationRunning ->
                // If we're in transition to GONE, special unlock animation params apply.
                if (startedStep.to == KeyguardState.GONE && currentState != KeyguardState.GONE) {
                    if (inWindowLauncherUnlockAnimationInteractor.get().isLauncherUnderneath()) {
                    if (notifAnimationRunning) {
                        // If the notification launch animation is running, leave the alpha at 0f.
                        // The ActivityLaunchAnimator will morph it from the notification at the
                        // appropriate time.
                        return@combine KeyguardSurfaceBehindModel(
                            alpha = 0f,
                        )
                    } else if (
                        inWindowLauncherUnlockAnimationInteractor.get().isLauncherUnderneath()
                    ) {
                        // The Launcher icons have their own translation/alpha animations during the
                        // in-window animation. We'll just make the surface visible and let Launcher
                        // do its thing.
+11 −6
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
@@ -26,7 +28,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import javax.inject.Inject

@SysUISingleton
class WindowManagerLockscreenVisibilityInteractor
@@ -37,6 +38,7 @@ constructor(
    surfaceBehindInteractor: KeyguardSurfaceBehindInteractor,
    fromLockscreenInteractor: FromLockscreenTransitionInteractor,
    fromBouncerInteractor: FromPrimaryBouncerTransitionInteractor,
    notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor,
) {
    private val defaultSurfaceBehindVisibility =
        transitionInteractor.finishedKeyguardState.map(::isSurfaceVisible)
@@ -72,8 +74,7 @@ constructor(
     */
    @OptIn(ExperimentalCoroutinesApi::class)
    val surfaceBehindVisibility: Flow<Boolean> =
        transitionInteractor
                .isInTransitionToAnyState
        transitionInteractor.isInTransitionToAnyState
            .flatMapLatest { isInTransition ->
                if (!isInTransition) {
                    defaultSurfaceBehindVisibility
@@ -99,12 +100,16 @@ constructor(
        combine(
                transitionInteractor.isInTransitionToState(KeyguardState.GONE),
                transitionInteractor.finishedKeyguardState,
                surfaceBehindInteractor.isAnimatingSurface
            ) { isInTransitionToGone, finishedState, isAnimatingSurface ->
                surfaceBehindInteractor.isAnimatingSurface,
                notificationLaunchAnimationInteractor.isLaunchAnimationRunning,
            ) { isInTransitionToGone, finishedState, isAnimatingSurface, notifLaunchRunning ->
                // Using the animation if we're animating it directly, or if the
                // ActivityLaunchAnimator is in the process of animating it.
                val animationsRunning = isAnimatingSurface || notifLaunchRunning
                // We may still be animating the surface after the keyguard is fully GONE, since
                // some animations (like the translation spring) are not tied directly to the
                // transition step amount.
                isInTransitionToGone || (finishedState == KeyguardState.GONE && isAnimatingSurface)
                isInTransitionToGone || (finishedState == KeyguardState.GONE && animationsRunning)
            }
            .distinctUntilChanged()

+35 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.util.mockTopActivityClassName
import com.android.systemui.kosmos.testScope
import com.android.systemui.shared.system.activityManagerWrapper
import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.assertValuesMatch
import com.google.common.truth.Truth.assertThat
@@ -192,4 +193,38 @@ class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
                )
                .inOrder()
        }

    @Test
    fun testSurfaceBehindModel_fromNotificationLaunch() =
        testScope.runTest {
            val values by collectValues(underTest.viewParams)
            runCurrent()

            kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
            runCurrent()

            transitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.LOCKSCREEN,
                    to = KeyguardState.GONE,
                    transitionState = TransitionState.STARTED,
                )
            )
            runCurrent()

            transitionRepository.sendTransitionStep(
                TransitionStep(
                    from = KeyguardState.LOCKSCREEN,
                    to = KeyguardState.GONE,
                    transitionState = TransitionState.RUNNING,
                    value = 0.5f,
                )
            )
            runCurrent()

            values.assertValuesMatch(
                // We should be at alpha = 0f during the animation.
                { it == KeyguardSurfaceBehindModel(alpha = 0f) },
            )
        }
}
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.domain.interactor
import android.content.applicationContext
import com.android.systemui.keyguard.data.repository.keyguardSurfaceBehindRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor

var Kosmos.keyguardSurfaceBehindInteractor by
    Kosmos.Fixture {
@@ -30,5 +31,6 @@ var Kosmos.keyguardSurfaceBehindInteractor by
                inWindowLauncherUnlockAnimationInteractor
            },
            swipeToDismissInteractor = swipeToDismissInteractor,
            notificationLaunchInteractor = notificationLaunchAnimationInteractor,
        )
    }
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.domain.interactor

import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor

val Kosmos.windowManagerLockscreenVisibilityInteractor by
    Kosmos.Fixture {
@@ -26,5 +27,6 @@ val Kosmos.windowManagerLockscreenVisibilityInteractor by
            surfaceBehindInteractor = keyguardSurfaceBehindInteractor,
            fromLockscreenInteractor = fromLockscreenTransitionInteractor,
            fromBouncerInteractor = fromPrimaryBouncerTransitionInteractor,
            notificationLaunchAnimationInteractor = notificationLaunchAnimationInteractor,
        )
    }
Loading