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

Commit 11844145 authored by Michal Brzezinski's avatar Michal Brzezinski
Browse files

Fixing tiles on lockscreen and scrims transitions with QS expanded

This is quick and safe fix for most bottom tiles not working on lockscreen. We’re updating QS state based on shade transition from KEYGUARD to SHADE_LOCKED. For long term we’d likely prefer to not switch expansion state manually but rather for it to be changed automatically by increasing QS height as it’s done in UNLOCKED state.

Making QS state up-to-date changes scrim transitions as they depend on QS expansion. That caused b/230340979 in the past where scrim is dark for too long when transitioning between shade locked and bouncer. It was mostly caused by qs expansion being interpolated before calculated tint transition - all start and end values are still correct.

The easiest and low risk fix is to adjust scrim transition interpolation and that results in:
- Landscape: it doesn’t keep transition the same, but I think it still looks pretty good and - as a bonus - prevents issue of QS footer background being visible (b/232408997)
- Portrait: Two cases here on lockscreen: going directly to expanded QS or expanding shade and then expanding QS. Both of them didn’t look great to start with but this change makes it a bit better.

This change doesn’t influence handheld transitions as there start and end state tints are the same.

Bug: 228198572
Bug: 232365192
Test: manual
Change-Id: If5c00316bad5ba17a5a359b7ab8bf970ee709121
parent 92e59dde
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -4707,6 +4707,11 @@ public class NotificationPanelViewController extends PanelViewController {
                    duration = StackStateAnimator.ANIMATION_DURATION_STANDARD;
                    duration = StackStateAnimator.ANIMATION_DURATION_STANDARD;
                }
                }
                mKeyguardStatusBarViewController.animateKeyguardStatusBarOut(startDelay, duration);
                mKeyguardStatusBarViewController.animateKeyguardStatusBarOut(startDelay, duration);
                if (mSplitShadeEnabled) {
                    // temporary workaround for QS height not being updated during lockscreen to
                    // shade transition
                    setQsExpanded(true);
                }
                updateQSMinHeight();
                updateQSMinHeight();
            } else if (oldState == StatusBarState.SHADE_LOCKED
            } else if (oldState == StatusBarState.SHADE_LOCKED
                    && statusBarState == KEYGUARD) {
                    && statusBarState == KEYGUARD) {
+11 −1
Original line number Original line Diff line number Diff line
@@ -906,9 +906,19 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
        }
        }
        if (mQsExpansion > 0) {
        if (mQsExpansion > 0) {
            behindAlpha = MathUtils.lerp(behindAlpha, mDefaultScrimAlpha, mQsExpansion);
            behindAlpha = MathUtils.lerp(behindAlpha, mDefaultScrimAlpha, mQsExpansion);
            float tintProgress = mQsExpansion;
            if (mStatusBarKeyguardViewManager.isBouncerInTransit()) {
                // this is case of - on lockscreen - going from expanded QS to bouncer.
                // Because mQsExpansion is already interpolated and transition between tints
                // is too slow, we want to speed it up and make it more aligned to bouncer
                // showing up progress. This issue is visible on large screens, both portrait and
                // split shade because then transition is between very different tints
                tintProgress = BouncerPanelExpansionCalculator
                        .showBouncerProgress(mPanelExpansionFraction);
            }
            int stateTint = mClipsQsScrim ? ScrimState.SHADE_LOCKED.getNotifTint()
            int stateTint = mClipsQsScrim ? ScrimState.SHADE_LOCKED.getNotifTint()
                    : ScrimState.SHADE_LOCKED.getBehindTint();
                    : ScrimState.SHADE_LOCKED.getBehindTint();
            behindTint = ColorUtils.blendARGB(behindTint, stateTint, mQsExpansion);
            behindTint = ColorUtils.blendARGB(behindTint, stateTint, tintProgress);
        }
        }


        // If the keyguard is going away, we should not be opaque.
        // If the keyguard is going away, we should not be opaque.
+43 −16
Original line number Original line Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.phone;
import static com.android.systemui.statusbar.phone.ScrimController.OPAQUE;
import static com.android.systemui.statusbar.phone.ScrimController.OPAQUE;
import static com.android.systemui.statusbar.phone.ScrimController.SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.ScrimController.SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.ScrimController.TRANSPARENT;
import static com.android.systemui.statusbar.phone.ScrimController.TRANSPARENT;
import static com.android.systemui.statusbar.phone.ScrimState.BOUNCER;
import static com.android.systemui.statusbar.phone.ScrimState.SHADE_LOCKED;


import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertThat;


@@ -275,7 +277,7 @@ public class ScrimControllerTest extends SysuiTestCase {


    @Test
    @Test
    public void transitionToShadeLocked() {
    public void transitionToShadeLocked() {
        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
        mScrimController.transitionTo(SHADE_LOCKED);
        mScrimController.setQsPosition(1f, 0);
        mScrimController.setQsPosition(1f, 0);
        finishAnimationsImmediately();
        finishAnimationsImmediately();


@@ -293,7 +295,7 @@ public class ScrimControllerTest extends SysuiTestCase {
    @Test
    @Test
    public void transitionToShadeLocked_clippingQs() {
    public void transitionToShadeLocked_clippingQs() {
        mScrimController.setClipsQsScrim(true);
        mScrimController.setClipsQsScrim(true);
        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
        mScrimController.transitionTo(SHADE_LOCKED);
        mScrimController.setQsPosition(1f, 0);
        mScrimController.setQsPosition(1f, 0);
        finishAnimationsImmediately();
        finishAnimationsImmediately();


@@ -542,7 +544,7 @@ public class ScrimControllerTest extends SysuiTestCase {


    @Test
    @Test
    public void transitionToKeyguardBouncer() {
    public void transitionToKeyguardBouncer() {
        mScrimController.transitionTo(ScrimState.BOUNCER);
        mScrimController.transitionTo(BOUNCER);
        finishAnimationsImmediately();
        finishAnimationsImmediately();
        // Front scrim should be transparent
        // Front scrim should be transparent
        // Back scrim should be visible without tint
        // Back scrim should be visible without tint
@@ -561,7 +563,7 @@ public class ScrimControllerTest extends SysuiTestCase {
    @Test
    @Test
    public void transitionToKeyguardBouncer_clippingQs() {
    public void transitionToKeyguardBouncer_clippingQs() {
        mScrimController.setClipsQsScrim(true);
        mScrimController.setClipsQsScrim(true);
        mScrimController.transitionTo(ScrimState.BOUNCER);
        mScrimController.transitionTo(BOUNCER);
        finishAnimationsImmediately();
        finishAnimationsImmediately();
        // Front scrim should be transparent
        // Front scrim should be transparent
        // Back scrim should be clipping QS
        // Back scrim should be clipping QS
@@ -581,7 +583,7 @@ public class ScrimControllerTest extends SysuiTestCase {
    @Test
    @Test
    public void disableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() {
    public void disableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() {
        mScrimController.setClipsQsScrim(true);
        mScrimController.setClipsQsScrim(true);
        mScrimController.transitionTo(ScrimState.BOUNCER);
        mScrimController.transitionTo(BOUNCER);


        mScrimController.setClipsQsScrim(false);
        mScrimController.setClipsQsScrim(false);


@@ -602,7 +604,7 @@ public class ScrimControllerTest extends SysuiTestCase {
    @Test
    @Test
    public void enableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() {
    public void enableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() {
        mScrimController.setClipsQsScrim(false);
        mScrimController.setClipsQsScrim(false);
        mScrimController.transitionTo(ScrimState.BOUNCER);
        mScrimController.transitionTo(BOUNCER);


        mScrimController.setClipsQsScrim(true);
        mScrimController.setClipsQsScrim(true);


@@ -672,9 +674,9 @@ public class ScrimControllerTest extends SysuiTestCase {
        finishAnimationsImmediately();
        finishAnimationsImmediately();
        assertEquals(mScrimState, ScrimState.UNLOCKED);
        assertEquals(mScrimState, ScrimState.UNLOCKED);


        mScrimController.transitionTo(ScrimState.BOUNCER);
        mScrimController.transitionTo(BOUNCER);
        finishAnimationsImmediately();
        finishAnimationsImmediately();
        assertEquals(mScrimState, ScrimState.BOUNCER);
        assertEquals(mScrimState, BOUNCER);


        mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
        mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
        finishAnimationsImmediately();
        finishAnimationsImmediately();
@@ -1081,9 +1083,9 @@ public class ScrimControllerTest extends SysuiTestCase {
        HashSet<ScrimState> lowPowerModeStates = new HashSet<>(Arrays.asList(
        HashSet<ScrimState> lowPowerModeStates = new HashSet<>(Arrays.asList(
                ScrimState.OFF, ScrimState.AOD, ScrimState.PULSING));
                ScrimState.OFF, ScrimState.AOD, ScrimState.PULSING));
        HashSet<ScrimState> regularStates = new HashSet<>(Arrays.asList(
        HashSet<ScrimState> regularStates = new HashSet<>(Arrays.asList(
                ScrimState.UNINITIALIZED, ScrimState.KEYGUARD, ScrimState.BOUNCER,
                ScrimState.UNINITIALIZED, ScrimState.KEYGUARD, BOUNCER,
                ScrimState.DREAMING, ScrimState.BOUNCER_SCRIMMED, ScrimState.BRIGHTNESS_MIRROR,
                ScrimState.DREAMING, ScrimState.BOUNCER_SCRIMMED, ScrimState.BRIGHTNESS_MIRROR,
                ScrimState.UNLOCKED, ScrimState.SHADE_LOCKED, ScrimState.AUTH_SCRIMMED,
                ScrimState.UNLOCKED, SHADE_LOCKED, ScrimState.AUTH_SCRIMMED,
                ScrimState.AUTH_SCRIMMED_SHADE));
                ScrimState.AUTH_SCRIMMED_SHADE));


        for (ScrimState state : ScrimState.values()) {
        for (ScrimState state : ScrimState.values()) {
@@ -1228,7 +1230,7 @@ public class ScrimControllerTest extends SysuiTestCase {
    @Test
    @Test
    public void testNotificationScrimVisible_afterOpeningShadeFromLockscreen() {
    public void testNotificationScrimVisible_afterOpeningShadeFromLockscreen() {
        mScrimController.setRawPanelExpansionFraction(1);
        mScrimController.setRawPanelExpansionFraction(1);
        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
        mScrimController.transitionTo(SHADE_LOCKED);
        finishAnimationsImmediately();
        finishAnimationsImmediately();


        assertScrimAlpha(Map.of(
        assertScrimAlpha(Map.of(
@@ -1236,11 +1238,27 @@ public class ScrimControllerTest extends SysuiTestCase {
                mNotificationsScrim, OPAQUE));
                mNotificationsScrim, OPAQUE));
    }
    }


    @Test
    public void qsExpansion_BehindTint_shadeLocked_bouncerActive_usesBouncerProgress() {
        when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(true);
        // clipping doesn't change tested logic but allows to assert scrims more in line with
        // their expected large screen behaviour
        mScrimController.setClipsQsScrim(false);
        mScrimController.transitionTo(SHADE_LOCKED);

        mScrimController.setQsPosition(1f, 100 /* value doesn't matter */);
        assertTintAfterExpansion(mScrimBehind, SHADE_LOCKED.getBehindTint(), /* expansion= */ 1f);

        mScrimController.setQsPosition(0.8f, 100 /* value doesn't matter */);
        // panel expansion of 0.6 means its fully transitioned with bouncer progress interpolation
        assertTintAfterExpansion(mScrimBehind, BOUNCER.getBehindTint(), /* expansion= */ 0.6f);
    }

    @Test
    @Test
    public void expansionNotificationAlpha_shadeLocked_bouncerActive_usesBouncerInterpolator() {
    public void expansionNotificationAlpha_shadeLocked_bouncerActive_usesBouncerInterpolator() {
        when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(true);
        when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(true);


        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
        mScrimController.transitionTo(SHADE_LOCKED);


        float expansion = 0.8f;
        float expansion = 0.8f;
        float expectedAlpha =
        float expectedAlpha =
@@ -1256,7 +1274,7 @@ public class ScrimControllerTest extends SysuiTestCase {
    public void expansionNotificationAlpha_shadeLocked_bouncerNotActive_usesShadeInterpolator() {
    public void expansionNotificationAlpha_shadeLocked_bouncerNotActive_usesShadeInterpolator() {
        when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false);
        when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false);


        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
        mScrimController.transitionTo(SHADE_LOCKED);


        float expansion = 0.8f;
        float expansion = 0.8f;
        float expectedAlpha = ShadeInterpolation.getNotificationScrimAlpha(expansion);
        float expectedAlpha = ShadeInterpolation.getNotificationScrimAlpha(expansion);
@@ -1352,7 +1370,7 @@ public class ScrimControllerTest extends SysuiTestCase {


    @Test
    @Test
    public void testNotificationTransparency_followsTransitionToFullShade() {
    public void testNotificationTransparency_followsTransitionToFullShade() {
        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
        mScrimController.transitionTo(SHADE_LOCKED);
        mScrimController.setRawPanelExpansionFraction(1.0f);
        mScrimController.setRawPanelExpansionFraction(1.0f);
        finishAnimationsImmediately();
        finishAnimationsImmediately();
        float shadeLockedAlpha = mNotificationsScrim.getViewAlpha();
        float shadeLockedAlpha = mNotificationsScrim.getViewAlpha();
@@ -1379,7 +1397,7 @@ public class ScrimControllerTest extends SysuiTestCase {


    @Test
    @Test
    public void notificationTransparency_followsNotificationScrimProgress() {
    public void notificationTransparency_followsNotificationScrimProgress() {
        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
        mScrimController.transitionTo(SHADE_LOCKED);
        mScrimController.setRawPanelExpansionFraction(1.0f);
        mScrimController.setRawPanelExpansionFraction(1.0f);
        finishAnimationsImmediately();
        finishAnimationsImmediately();
        mScrimController.transitionTo(ScrimState.KEYGUARD);
        mScrimController.transitionTo(ScrimState.KEYGUARD);
@@ -1473,7 +1491,7 @@ public class ScrimControllerTest extends SysuiTestCase {
                mScrimBehind, TRANSPARENT,
                mScrimBehind, TRANSPARENT,
                mNotificationsScrim, TRANSPARENT));
                mNotificationsScrim, TRANSPARENT));


        mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
        mScrimController.transitionTo(SHADE_LOCKED);
        finishAnimationsImmediately();
        finishAnimationsImmediately();
        assertScrimAlpha(Map.of(
        assertScrimAlpha(Map.of(
                mScrimInFront, TRANSPARENT,
                mScrimInFront, TRANSPARENT,
@@ -1504,6 +1522,15 @@ public class ScrimControllerTest extends SysuiTestCase {
        assertEquals(expectedAlpha, scrim.getViewAlpha(), 0.2);
        assertEquals(expectedAlpha, scrim.getViewAlpha(), 0.2);
    }
    }


    private void assertTintAfterExpansion(ScrimView scrim, int expectedTint, float expansion) {
        String message = "Tint test failed with expected scrim tint: "
                + Integer.toHexString(expectedTint) + " and actual tint: "
                + Integer.toHexString(scrim.getTint()) + " for scrim: " + getScrimName(scrim);
        mScrimController.setRawPanelExpansionFraction(expansion);
        finishAnimationsImmediately();
        assertEquals(message, expectedTint, scrim.getTint(), 0.1);
    }

    private void assertScrimTinted(Map<ScrimView, Boolean> scrimToTint) {
    private void assertScrimTinted(Map<ScrimView, Boolean> scrimToTint) {
        scrimToTint.forEach((scrim, hasTint) -> assertScrimTint(scrim, hasTint));
        scrimToTint.forEach((scrim, hasTint) -> assertScrimTint(scrim, hasTint));
    }
    }