Update scrims when changing quick settings clip, fix clipping bounds in split shade

Fixes two issues with scrims background:
  1) Scrims become transparent on pin code bouncer when
     rotating from split shade to non-split shade mode

     This happens because we update mClipQsScrim in ScrimState enum,
     but we don't actually re-apply alpha values and tints
     to the scrim views/drawables. We applied these values
     only when current ScrimState has changed (see transitionTo method).
     When we rotate the device when we are on pin code bouncer
     the state remains the same (BOUNCER), so we didn't apply
     these values.

     Updated the code to set alpha values and tints when
     setClipsQsScrim is called (it invokes applyAndDispatchState
     which invokes applyState).

  2) Background becomes black when we open pin code bouncer when using
     non-split shade mode and rotate the device to split shade mode

     It happened because in
     NotificationPanelViewController.setQSClippingBounds the clipping
     bounds are initialized with zeros and we didn't update
     them in case when we use split notification shade
     and qsPanelBottomY <= 0 (when quick settings are not visible).
     Empty bounds caused absence of the notifications
     scrim which should act as bouncer background.

     Fixed by using non-split shade logic for calculating bounds
     in this case, they cover the entire screen.

Fixes: 188112748
Test: atest com.android.systemui.statusbar.phone.ScrimControllerTest
Test: manual https://drive.google.com/drive/folders/1SRSzT0uQ-mETIVI87Ilr3dxlaUdcG9Go?usp=sharing
Change-Id: I783b2d4f4335447f7abfb210005aa09bfd3e15a8
This commit is contained in:
Nick Chameyev
2021-06-08 15:50:59 +01:00
parent ab202686cb
commit 5f550c269c
3 changed files with 75 additions and 27 deletions

View File

@@ -2224,10 +2224,16 @@ public class NotificationPanelViewController extends PanelViewController {
int right = 0;
final int qsPanelBottomY = calculateQsBottomPosition(computeQsExpansionFraction());
final boolean visible = (computeQsExpansionFraction() > 0 || qsPanelBottomY > 0)
&& !mShouldUseSplitNotificationShade;
final boolean quickSettingsVisible = computeQsExpansionFraction() > 0 || qsPanelBottomY > 0;
if (!mShouldUseSplitNotificationShade) {
if (mShouldUseSplitNotificationShade && quickSettingsVisible) {
mAmbientState.setNotificationScrimTop(mSplitShadeNotificationsTopPadding);
top = Math.max(0, Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding));
bottom = mNotificationStackScrollLayoutController.getHeight();
left = mNotificationStackScrollLayoutController.getLeft();
right = mNotificationStackScrollLayoutController.getRight();
} else {
if (mTransitioningToFullShadeProgress > 0.0f) {
// If we're transitioning, let's use the actual value. The else case
// can be wrong during transitions when waiting for the keyguard to unlock
@@ -2242,16 +2248,11 @@ public class NotificationPanelViewController extends PanelViewController {
// notification bounds should take full screen width regardless of insets
left = 0;
right = getView().getRight() + mDisplayRightInset;
} else if (qsPanelBottomY > 0) { // so bounds are empty on lockscreen
mAmbientState.setNotificationScrimTop(mSplitShadeNotificationsTopPadding);
top = Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding);
bottom = mNotificationStackScrollLayoutController.getHeight();
left = mNotificationStackScrollLayoutController.getLeft();
right = mNotificationStackScrollLayoutController.getRight();
}
// top should never be lower than bottom, otherwise it will be invisible.
top = Math.min(top, bottom);
applyQSClippingBounds(left, top, right, bottom, visible);
applyQSClippingBounds(left, top, right, bottom,
quickSettingsVisible && !mShouldUseSplitNotificationShade);
}
private void applyQSClippingBounds(int left, int top, int right, int bottom,

View File

@@ -359,21 +359,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mAnimateChange = state.getAnimateChange();
mAnimationDuration = state.getAnimationDuration();
mInFrontTint = state.getFrontTint();
mBehindTint = state.getBehindTint();
mNotificationsTint = state.getNotifTint();
mBubbleTint = state.getBubbleTint();
mInFrontAlpha = state.getFrontAlpha();
mBehindAlpha = state.getBehindAlpha();
mBubbleAlpha = state.getBubbleAlpha();
mNotificationsAlpha = state.getNotifAlpha();
if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha) || isNaN(mNotificationsAlpha)) {
throw new IllegalStateException("Scrim opacity is NaN for state: " + state + ", front: "
+ mInFrontAlpha + ", back: " + mBehindAlpha + ", notif: "
+ mNotificationsAlpha);
}
applyStateToAlpha();
applyState();
// Scrim might acquire focus when user is navigating with a D-pad or a keyboard.
// We need to disable focus otherwise AOD would end up with a gray overlay.
@@ -637,7 +623,19 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
}
private void applyStateToAlpha() {
private void applyState() {
mInFrontTint = mState.getFrontTint();
mBehindTint = mState.getBehindTint();
mNotificationsTint = mState.getNotifTint();
mBubbleTint = mState.getBubbleTint();
mInFrontAlpha = mState.getFrontAlpha();
mBehindAlpha = mState.getBehindAlpha();
mBubbleAlpha = mState.getBubbleAlpha();
mNotificationsAlpha = mState.getNotifAlpha();
assertAlphasValid();
if (!mExpansionAffectsAlpha) {
return;
}
@@ -701,6 +699,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mBehindTint = behindTint;
}
}
assertAlphasValid();
}
private void assertAlphasValid() {
if (isNaN(mBehindAlpha) || isNaN(mInFrontAlpha) || isNaN(mNotificationsAlpha)) {
throw new IllegalStateException("Scrim opacity is NaN for state: " + mState
+ ", front: " + mInFrontAlpha + ", back: " + mBehindAlpha + ", notif: "
@@ -740,7 +743,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private void applyAndDispatchState() {
applyStateToAlpha();
applyState();
if (mUpdatePending) {
return;
}
@@ -1209,6 +1212,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
pw.println(" ScrimController: ");
pw.print(" state: ");
pw.println(mState);
pw.println(" mClipQsScrim = " + mState.mClipQsScrim);
pw.print(" frontScrim:");
pw.print(" viewAlpha=");

View File

@@ -555,6 +555,49 @@ public class ScrimControllerTest extends SysuiTestCase {
));
}
@Test
public void disableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() {
mScrimController.setClipsQsScrim(true);
mScrimController.transitionTo(ScrimState.BOUNCER);
mScrimController.setClipsQsScrim(false);
finishAnimationsImmediately();
// Front scrim should be transparent
// Back scrim should be visible without tint
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
mNotificationsScrim, TRANSPARENT,
mScrimBehind, OPAQUE));
assertScrimTinted(Map.of(
mScrimInFront, false,
mScrimBehind, false,
mNotificationsScrim, false
));
}
@Test
public void enableClipQsScrimWithoutStateTransition_updatesTintAndAlpha() {
mScrimController.setClipsQsScrim(false);
mScrimController.transitionTo(ScrimState.BOUNCER);
mScrimController.setClipsQsScrim(true);
finishAnimationsImmediately();
// Front scrim should be transparent
// Back scrim should be clipping QS
// Notif scrim should be visible without tint
assertScrimAlpha(Map.of(
mScrimInFront, TRANSPARENT,
mNotificationsScrim, OPAQUE,
mScrimBehind, OPAQUE));
assertScrimTinted(Map.of(
mScrimInFront, false,
mScrimBehind, true,
mNotificationsScrim, false
));
}
@Test
public void transitionToBouncer() {
mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);