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

Commit 8c7cb02f authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Display blanking logic improvements

Blank display immediatelly when requested, display power controller
will fade out the screen using ColorFade.

SysUI just needs to fade the UI back in when we're in control of
the transition again.

Change-Id: I9d58de3d39c0288f5c82c0c04c86cb43bb3d02c4
Fixes: 72527083
Test: receive notification on AOD, wait.
Test: receive notification on AOD, fp unlock
Test: wake up, unlock, pull notification shade
Test: atest packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
Bug: 71913808
parent 7b2354ec
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@
    <item type="id" name="qs_icon_tag"/>
    <item type="id" name="qs_slash_tag"/>
    <item type="id" name="scrim"/>
    <item type="id" name="scrim_blanking"/>
    <item type="id" name="scrim_target"/>
    <item type="id" name="scrim_alpha_start"/>
    <item type="id" name="scrim_alpha_end"/>
+37 −42
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.os.Handler;
import android.os.Trace;
import android.util.Log;
import android.util.MathUtils;
import android.view.Choreographer;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -111,7 +112,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
    protected static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;

    static final int TAG_KEY_ANIM = R.id.scrim;
    static final int TAG_KEY_ANIM_BLANK = R.id.scrim_blanking;
    private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
    private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
    private static final int TAG_END_ALPHA = R.id.scrim_alpha_end;
@@ -166,6 +166,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
    private boolean mScreenBlankingCallbackCalled;
    private Callback mCallback;
    private boolean mWallpaperSupportsAmbientMode;
    private Choreographer.FrameCallback mPendingFrameCallback;

    private final WakeLock mWakeLock;
    private boolean mWakeLockHeld;
@@ -248,6 +249,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
        mCurrentInFrontAlpha = state.getFrontAlpha();
        mCurrentBehindAlpha = state.getBehindAlpha();

        if (mPendingFrameCallback != null) {
            Choreographer.getInstance().removeFrameCallback(mPendingFrameCallback);
            mPendingFrameCallback = null;
        }

        // Showing/hiding the keyguard means that scrim colors have to be switched, not necessary
        // to do the same when you're just showing the brightness mirror.
        mNeedsDrawableColorUpdate = state != ScrimState.BRIGHTNESS_MIRROR;
@@ -687,11 +693,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
            }
        }

        final boolean blankingInProgress = mScrimInFront.getTag(TAG_KEY_ANIM_BLANK) != null;
        if (mBlankScreen || blankingInProgress) {
            if (!blankingInProgress) {
        if (mPendingFrameCallback != null) {
            // Display is off and we're waiting.
            return;
        } else if (mBlankScreen) {
            // Need to blank the display before continuing.
            blankDisplay();
            }
            return;
        } else if (!mScreenBlankingCallbackCalled) {
            // Not blanking the screen. Letting the callback know that we're ready
@@ -745,27 +752,18 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
    }

    private void blankDisplay() {
        final float initialAlpha = mScrimInFront.getViewAlpha();
        final int initialTint = mScrimInFront.getTint();
        ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
        anim.addUpdateListener(animation -> {
            final float amount = (float) animation.getAnimatedValue();
            float animAlpha = MathUtils.lerp(initialAlpha, 1, amount);
            int animTint = ColorUtils.blendARGB(initialTint, Color.BLACK, amount);
            updateScrimColor(mScrimInFront, animAlpha, animTint);
            dispatchScrimsVisible();
        });
        anim.setInterpolator(getInterpolator());
        anim.setDuration(mDozeParameters.getPulseInDuration());
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
        updateScrimColor(mScrimInFront, 1, Color.BLACK);

        // Notify callback that the screen is completely black and we're
        // ready to change the display power mode
        mPendingFrameCallback = frameTimeNanos -> {
            if (mCallback != null) {
                mCallback.onDisplayBlanked();
                mScreenBlankingCallbackCalled = true;
            }

            Runnable blankingCallback = () -> {
                    mScrimInFront.setTag(TAG_KEY_ANIM_BLANK, null);
                mPendingFrameCallback = null;
                mBlankScreen = false;
                // Try again.
                updateScrims();
@@ -774,16 +772,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
            // Setting power states can happen after we push out the frame. Make sure we
            // stay fully opaque until the power state request reaches the lower levels.
            getHandler().postDelayed(blankingCallback, 100);

        };
        doOnTheNextFrame(mPendingFrameCallback);
    }
        });
        anim.start();
        mScrimInFront.setTag(TAG_KEY_ANIM_BLANK, anim);

        // Finish animation if we're already at its final state
        if (initialAlpha == 1 && mScrimInFront.getTint() == Color.BLACK) {
            anim.end();
        }
    @VisibleForTesting
    protected void doOnTheNextFrame(Choreographer.FrameCallback callback) {
        Choreographer.getInstance().postFrameCallback(callback);
    }

    @VisibleForTesting
+0 −7
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ public enum ScrimState {
                    // set our scrim to black in this frame to avoid flickering and
                    // fade it out afterwards.
                    mBlankScreen = true;
                    updateScrimColor(mScrimInFront, 1, Color.BLACK);
                }
            } else {
                mAnimationDuration = ScrimController.ANIMATION_DURATION;
@@ -86,9 +85,6 @@ public enum ScrimState {
    AOD(3) {
        @Override
        public void prepare(ScrimState previousState) {
            if (previousState == ScrimState.PULSING && !mCanControlScreenOff) {
                updateScrimColor(mScrimInFront, 1, Color.BLACK);
            }
            final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
            final boolean wasPulsing = previousState == ScrimState.PULSING;
            mBlankScreen = wasPulsing && !mCanControlScreenOff;
@@ -115,9 +111,6 @@ public enum ScrimState {
                    && !mKeyguardUpdateMonitor.hasLockscreenWallpaper() ? 0f : 1f;
            mCurrentBehindTint = Color.BLACK;
            mBlankScreen = mDisplayRequiresBlanking;
            if (mDisplayRequiresBlanking) {
                updateScrimColor(mScrimInFront, 1, Color.BLACK);
            }
        }
    },

+10 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.os.Looper;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Choreographer;
import android.view.View;

import com.android.keyguard.KeyguardUpdateMonitor;
@@ -374,7 +375,6 @@ public class ScrimControllerTest extends SysuiTestCase {
            onPreDraw();

            // Force finish screen blanking.
            endAnimation(mScrimInFront, TAG_KEY_ANIM_BLANK);
            mHandler.dispatchQueuedMessages();
            // Force finish all animations.
            endAnimation(mScrimBehind, TAG_KEY_ANIM);
@@ -401,6 +401,15 @@ public class ScrimControllerTest extends SysuiTestCase {
        protected WakeLock createWakeLock() {
            return mWakeLock;
        }

        /**
         * Do not wait for a frame since we're in a test environment.
         * @param callback What to execute.
         */
        @Override
        protected void doOnTheNextFrame(Choreographer.FrameCallback callback) {
            callback.doFrame(0);
        }
    }

}