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

Commit 5f550c26 authored by Nick Chameyev's avatar Nick Chameyev
Browse files

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
parent ab202686
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -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,
+21 −17
Original line number Diff line number Diff line
@@ -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=");
+43 −0
Original line number Diff line number Diff line
@@ -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);