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

Commit 0791d97e authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Fix flickering when switching display power modes

So far we've been Waiting for the next frame but it doesn't
mean that it will be visible on the screen.

We're usually rendering with 2 buffers and it's possible that
we'll switch the display power mode before anything has hit
the display.

Increased the timeout for now until we have a better alternative.

Change-Id: I63afc8a9139a4ccbba4f16f5569717e22217da9a
Fixes: 72527083
Test: manual
Test: packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
parent 0aeb3743
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
    private float mNotificationDensity;

    // Scrim blanking callbacks
    private Choreographer.FrameCallback mPendingFrameCallback;
    private Runnable mPendingFrameCallback;
    private Runnable mBlankingTransitionRunnable;

    private final WakeLock mWakeLock;
@@ -240,7 +240,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo

        // Cancel blanking transitions that were pending before we requested a new state
        if (mPendingFrameCallback != null) {
            Choreographer.getInstance().removeFrameCallback(mPendingFrameCallback);
            mScrimBehind.removeCallbacks(mPendingFrameCallback);
            mPendingFrameCallback = null;
        }
        if (getHandler().hasCallbacks(mBlankingTransitionRunnable)) {
@@ -278,7 +278,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
            // with too many things at this case, in order to not skip the initial frames.
            mScrimInFront.postOnAnimationDelayed(this::scheduleUpdate, 16);
            mAnimationDelay = StatusBar.FADE_KEYGUARD_START_DELAY;
        } else if (!mDozeParameters.getAlwaysOn() && oldState == ScrimState.AOD
        } else if ((!mDozeParameters.getAlwaysOn() && oldState == ScrimState.AOD)
                || (mState == ScrimState.AOD && !mDozeParameters.getDisplayNeedsBlanking())) {
            // Scheduling a frame isn't enough when:
            //  • Leaving doze and we need to modify scrim color immediately
@@ -727,7 +727,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo

        // Notify callback that the screen is completely black and we're
        // ready to change the display power mode
        mPendingFrameCallback = frameTimeNanos -> {
        mPendingFrameCallback = () -> {
            if (mCallback != null) {
                mCallback.onDisplayBlanked();
                mScreenBlankingCallbackCalled = true;
@@ -743,7 +743,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo

            // 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.
            final int delay = mScreenOn ? 16 : 500;
            final int delay = mScreenOn ? 32 : 500;
            if (DEBUG) {
                Log.d(TAG, "Fading out scrims with delay: " + delay);
            }
@@ -752,9 +752,15 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
        doOnTheNextFrame(mPendingFrameCallback);
    }

    /**
     * Executes a callback after the frame has hit the display.
     * @param callback What to run.
     */
    @VisibleForTesting
    protected void doOnTheNextFrame(Choreographer.FrameCallback callback) {
        Choreographer.getInstance().postFrameCallback(callback);
    protected void doOnTheNextFrame(Runnable callback) {
        // Just calling View#postOnAnimation isn't enough because the frame might not have reached
        // the display yet. A timeout is the safest solution.
        mScrimBehind.postOnAnimationDelayed(callback, 32 /* delayMillis */);
    }

    @VisibleForTesting
+2 −4
Original line number Diff line number Diff line
@@ -39,10 +39,8 @@ 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.internal.util.Preconditions;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.ScrimView;
@@ -557,8 +555,8 @@ public class ScrimControllerTest extends SysuiTestCase {
         * @param callback What to execute.
         */
        @Override
        protected void doOnTheNextFrame(Choreographer.FrameCallback callback) {
            callback.doFrame(0);
        protected void doOnTheNextFrame(Runnable callback) {
            callback.run();
        }
    }