From 118441454b4c5b2626b0a88ff5def2b80ab7d6af Mon Sep 17 00:00:00 2001 From: Michal Brzezinski Date: Tue, 17 May 2022 17:32:43 +0200 Subject: [PATCH] Fixing tiles on lockscreen and scrims transitions with QS expanded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../NotificationPanelViewController.java | 5 ++ .../statusbar/phone/ScrimController.java | 12 +++- .../statusbar/phone/ScrimControllerTest.java | 59 ++++++++++++++----- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 2dbbb145d968b..1e34006c66953 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -4707,6 +4707,11 @@ public class NotificationPanelViewController extends PanelViewController { duration = StackStateAnimator.ANIMATION_DURATION_STANDARD; } mKeyguardStatusBarViewController.animateKeyguardStatusBarOut(startDelay, duration); + if (mSplitShadeEnabled) { + // temporary workaround for QS height not being updated during lockscreen to + // shade transition + setQsExpanded(true); + } updateQSMinHeight(); } else if (oldState == StatusBarState.SHADE_LOCKED && statusBarState == KEYGUARD) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 0e77866bef1de..5e7dc115d7f9d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -906,9 +906,19 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump } if (mQsExpansion > 0) { 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() : 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. diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 5f8dda3595633..09009c6ee2601 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -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.SEMI_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; @@ -275,7 +277,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void transitionToShadeLocked() { - mScrimController.transitionTo(ScrimState.SHADE_LOCKED); + mScrimController.transitionTo(SHADE_LOCKED); mScrimController.setQsPosition(1f, 0); finishAnimationsImmediately(); @@ -293,7 +295,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void transitionToShadeLocked_clippingQs() { mScrimController.setClipsQsScrim(true); - mScrimController.transitionTo(ScrimState.SHADE_LOCKED); + mScrimController.transitionTo(SHADE_LOCKED); mScrimController.setQsPosition(1f, 0); finishAnimationsImmediately(); @@ -542,7 +544,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void transitionToKeyguardBouncer() { - mScrimController.transitionTo(ScrimState.BOUNCER); + mScrimController.transitionTo(BOUNCER); finishAnimationsImmediately(); // Front scrim should be transparent // Back scrim should be visible without tint @@ -561,7 +563,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void transitionToKeyguardBouncer_clippingQs() { mScrimController.setClipsQsScrim(true); - mScrimController.transitionTo(ScrimState.BOUNCER); + mScrimController.transitionTo(BOUNCER); finishAnimationsImmediately(); // Front scrim should be transparent // Back scrim should be clipping QS @@ -581,7 +583,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void disableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() { mScrimController.setClipsQsScrim(true); - mScrimController.transitionTo(ScrimState.BOUNCER); + mScrimController.transitionTo(BOUNCER); mScrimController.setClipsQsScrim(false); @@ -602,7 +604,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void enableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() { mScrimController.setClipsQsScrim(false); - mScrimController.transitionTo(ScrimState.BOUNCER); + mScrimController.transitionTo(BOUNCER); mScrimController.setClipsQsScrim(true); @@ -672,9 +674,9 @@ public class ScrimControllerTest extends SysuiTestCase { finishAnimationsImmediately(); assertEquals(mScrimState, ScrimState.UNLOCKED); - mScrimController.transitionTo(ScrimState.BOUNCER); + mScrimController.transitionTo(BOUNCER); finishAnimationsImmediately(); - assertEquals(mScrimState, ScrimState.BOUNCER); + assertEquals(mScrimState, BOUNCER); mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED); finishAnimationsImmediately(); @@ -1081,9 +1083,9 @@ public class ScrimControllerTest extends SysuiTestCase { HashSet lowPowerModeStates = new HashSet<>(Arrays.asList( ScrimState.OFF, ScrimState.AOD, ScrimState.PULSING)); HashSet 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.UNLOCKED, ScrimState.SHADE_LOCKED, ScrimState.AUTH_SCRIMMED, + ScrimState.UNLOCKED, SHADE_LOCKED, ScrimState.AUTH_SCRIMMED, ScrimState.AUTH_SCRIMMED_SHADE)); for (ScrimState state : ScrimState.values()) { @@ -1228,7 +1230,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void testNotificationScrimVisible_afterOpeningShadeFromLockscreen() { mScrimController.setRawPanelExpansionFraction(1); - mScrimController.transitionTo(ScrimState.SHADE_LOCKED); + mScrimController.transitionTo(SHADE_LOCKED); finishAnimationsImmediately(); assertScrimAlpha(Map.of( @@ -1236,11 +1238,27 @@ public class ScrimControllerTest extends SysuiTestCase { 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 public void expansionNotificationAlpha_shadeLocked_bouncerActive_usesBouncerInterpolator() { when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(true); - mScrimController.transitionTo(ScrimState.SHADE_LOCKED); + mScrimController.transitionTo(SHADE_LOCKED); float expansion = 0.8f; float expectedAlpha = @@ -1256,7 +1274,7 @@ public class ScrimControllerTest extends SysuiTestCase { public void expansionNotificationAlpha_shadeLocked_bouncerNotActive_usesShadeInterpolator() { when(mStatusBarKeyguardViewManager.isBouncerInTransit()).thenReturn(false); - mScrimController.transitionTo(ScrimState.SHADE_LOCKED); + mScrimController.transitionTo(SHADE_LOCKED); float expansion = 0.8f; float expectedAlpha = ShadeInterpolation.getNotificationScrimAlpha(expansion); @@ -1352,7 +1370,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void testNotificationTransparency_followsTransitionToFullShade() { - mScrimController.transitionTo(ScrimState.SHADE_LOCKED); + mScrimController.transitionTo(SHADE_LOCKED); mScrimController.setRawPanelExpansionFraction(1.0f); finishAnimationsImmediately(); float shadeLockedAlpha = mNotificationsScrim.getViewAlpha(); @@ -1379,7 +1397,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void notificationTransparency_followsNotificationScrimProgress() { - mScrimController.transitionTo(ScrimState.SHADE_LOCKED); + mScrimController.transitionTo(SHADE_LOCKED); mScrimController.setRawPanelExpansionFraction(1.0f); finishAnimationsImmediately(); mScrimController.transitionTo(ScrimState.KEYGUARD); @@ -1473,7 +1491,7 @@ public class ScrimControllerTest extends SysuiTestCase { mScrimBehind, TRANSPARENT, mNotificationsScrim, TRANSPARENT)); - mScrimController.transitionTo(ScrimState.SHADE_LOCKED); + mScrimController.transitionTo(SHADE_LOCKED); finishAnimationsImmediately(); assertScrimAlpha(Map.of( mScrimInFront, TRANSPARENT, @@ -1504,6 +1522,15 @@ public class ScrimControllerTest extends SysuiTestCase { 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 scrimToTint) { scrimToTint.forEach((scrim, hasTint) -> assertScrimTint(scrim, hasTint)); }