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

Commit c8b709e0 authored by Stas Zakrevskyi's avatar Stas Zakrevskyi
Browse files

Adjust screen off animation behavior for MinMode

When MinMode is active, `DozeParameters` now enables "Always On" and
forces `shouldAnimateDozingChange` to true. In
`UnlockedScreenOffAnimationController`, MinMode triggers a `LiftReveal`
effect, uses a shorter animation duration, and skips the delayed showing
of the AOD UI.

Flag: EXEMPT no API changes
Bug: 434541632
Test: Manual testing with/without MinMode
Change-Id: I2cced071c9802ce0b6ffa32796cfba476ac45e63
parent 730784ab
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -353,7 +353,7 @@ public class DozeParametersTest extends SysuiTestCase {

        when(mMinModeManager.isMinModeEnabled()).thenReturn(true);

        assertThat(mDozeParameters.getAlwaysOn()).isFalse();
        assertThat(mDozeParameters.getAlwaysOn()).isTrue();
    }

    @Test
@@ -362,7 +362,7 @@ public class DozeParametersTest extends SysuiTestCase {
        when(mScreenOffAnimationController.shouldAnimateDozingChange()).thenReturn(true);
        when(mMinModeManager.isMinModeEnabled()).thenReturn(true);

        assertThat(mDozeParameters.shouldAnimateDozingChange()).isFalse();
        assertThat(mDozeParameters.shouldAnimateDozingChange()).isTrue();
    }

    private void setDisplayNeedsBlankingForTest(boolean needsBlanking) {
+37 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import androidx.test.filters.SmallTest
import com.android.internal.jank.InteractionJankMonitor
import com.android.server.display.feature.flags.Flags as displayManagerFlags
import com.android.server.power.feature.flags.Flags as powerManagerFlags
import com.android.systemui.DejankUtils
import com.android.systemui.SysuiTestCase
import com.android.systemui.display.domain.interactor.DisplayStateInteractor
import com.android.systemui.keyguard.KeyguardViewMediator
@@ -33,6 +34,8 @@ import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.shade.ShadeViewController
import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.shade.domain.interactor.ShadeLockscreenInteractor
import com.android.systemui.statusbar.LiftReveal
import com.android.systemui.statusbar.LightRevealEffect
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.StatusBarStateControllerImpl
@@ -70,6 +73,7 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
    @Mock private lateinit var notifShadeWindowController: NotificationShadeWindowController
    @Mock private lateinit var lightRevealScrim: LightRevealScrim
    @Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
    @Mock private lateinit var revealEffect: LightRevealEffect
    @Mock private lateinit var statusBarStateController: StatusBarStateControllerImpl
    @Mock private lateinit var interactionJankMonitor: InteractionJankMonitor
    @Mock private lateinit var powerManager: PowerManager
@@ -81,6 +85,7 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        `when`(lightRevealScrim.revealEffect).thenReturn(revealEffect)
        controller =
            UnlockedScreenOffAnimationController(
                context,
@@ -209,4 +214,36 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() {
        controller.startAnimation()
        assertFalse(controller.isAnimationPlaying())
    }

    @Test
    fun testMinMode_noAodUi() {
        `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true)
        `when`(dozeParameters.isMinModeActive()).thenReturn(true)
        `when`(displayStateInteractor.isDefaultDisplayOff).thenReturn(MutableStateFlow(false))

        controller.startAnimation()

        assertFalse(controller.shouldAnimateInKeyguard())

        val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
        verify(handler).postDelayed(callbackCaptor.capture(), anyLong())
        callbackCaptor.value.run()

        verify(shadeLockscreenInteractor, never()).showAodUi()
    }

    @Test
    fun testMinMode_usesLiftReveal() {
        DejankUtils.setImmediate(true)
        `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true)
        `when`(dozeParameters.isMinModeActive()).thenReturn(true)
        `when`(displayStateInteractor.isDefaultDisplayOff).thenReturn(MutableStateFlow(false))

        controller.startAnimation()

        verify(lightRevealScrim).revealEffect = LiftReveal

        // Clean up
        DejankUtils.setImmediate(false)
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -285,10 +285,11 @@ public class DozeParameters implements

    /**
     * Checks if always on is available and enabled for the current user.
     * If minmode is active, always on is enabled to control the screen off animation.
     * @return {@code true} if enabled and available.
     */
    public boolean getAlwaysOn() {
        return mDozeAlwaysOn && !mBatteryController.isAodPowerSave() && !isMinModeActive();
        return (mDozeAlwaysOn && !mBatteryController.isAodPowerSave()) || isMinModeActive();
    }

    /**
@@ -362,8 +363,12 @@ public class DozeParameters implements
        return mScreenOffAnimationController.shouldShowLightRevealScrim();
    }

    /**
     * Whether we should animate the transition to or from Dozing.
     * This is true if either the screen off animation controller or minmode is active.
     */
    public boolean shouldAnimateDozingChange() {
        return mScreenOffAnimationController.shouldAnimateDozingChange() && !isMinModeActive();
        return mScreenOffAnimationController.shouldAnimateDozingChange() || isMinModeActive();
    }

    /**
+16 −1
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
import com.android.systemui.shade.domain.interactor.ShadeLockscreenInteractor
import com.android.systemui.shared.Flags.ambientAod
import com.android.systemui.statusbar.CircleReveal
import com.android.systemui.statusbar.LiftReveal
import com.android.systemui.statusbar.LightRevealEffect
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.StatusBarState
@@ -48,6 +50,7 @@ private const val ANIMATE_IN_KEYGUARD_DELAY = 600L

/** Duration for the light reveal portion of the animation. */
private const val LIGHT_REVEAL_ANIMATION_DURATION = 500L
private const val LIGHT_REVEAL_ANIMATION_DURATION_MINMODE = 100L

/**
 * Controller for the unlocked screen off animation, which runs when the device is going to sleep
@@ -83,6 +86,7 @@ constructor(
    private var initialized = false

    private lateinit var lightRevealScrim: LightRevealScrim
    private lateinit var revealEffect: LightRevealEffect

    private var animatorDurationScale = 1f
    private var shouldAnimateInKeyguard = false
@@ -128,6 +132,11 @@ constructor(
                    }

                    override fun onAnimationStart(animation: Animator) {
                        if (dozeParameters.get().isMinModeActive()) {
                            lightRevealScrim.revealEffect = LiftReveal
                        } else {
                            lightRevealScrim.revealEffect = revealEffect
                        }
                        interactionJankMonitor.begin(
                            notifShadeWindowControllerLazy.get().windowRootView,
                            CUJ_SCREEN_OFF,
@@ -158,6 +167,7 @@ constructor(
    ) {
        this.initialized = true
        this.lightRevealScrim = lightRevealScrim
        this.revealEffect = lightRevealScrim.revealEffect
        this.centralSurfaces = centralSurfaces

        updateAnimatorDurationScale()
@@ -281,7 +291,12 @@ constructor(
        if (shouldPlayUnlockedScreenOffAnimation()) {
            decidedToAnimateGoingToSleep = true

            shouldAnimateInKeyguard = true
            shouldAnimateInKeyguard = !dozeParameters.get().isMinModeActive()
            if (shouldAnimateInKeyguard) {
                lightRevealAnimator.setDuration(LIGHT_REVEAL_ANIMATION_DURATION)
            } else {
                lightRevealAnimator.setDuration(LIGHT_REVEAL_ANIMATION_DURATION_MINMODE)
            }

            // Start the animation on the next frame. startAnimation() is called after
            // PhoneWindowManager makes a binder call to System UI on