From 8c7cb02f1faae349c0653b4b594ce8ea9f305cee Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Mon, 5 Feb 2018 10:49:03 -0800 Subject: [PATCH] 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 --- packages/SystemUI/res/values/ids.xml | 1 - .../statusbar/phone/ScrimController.java | 79 +++++++++---------- .../systemui/statusbar/phone/ScrimState.java | 7 -- .../statusbar/phone/ScrimControllerTest.java | 11 ++- 4 files changed, 47 insertions(+), 51 deletions(-) diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index f9aa8216ec114..7537026d1b548 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -47,7 +47,6 @@ - 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 44e0c257ef24b..eb4e9b3221e31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -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) { - blankDisplay(); - } + 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,45 +752,33 @@ 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) { - if (mCallback != null) { - mCallback.onDisplayBlanked(); - mScreenBlankingCallbackCalled = true; - } - Runnable blankingCallback = () -> { - mScrimInFront.setTag(TAG_KEY_ANIM_BLANK, null); - mBlankScreen = false; - // Try again. - updateScrims(); - }; - - // 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); + 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; } - }); - 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(); - } + Runnable blankingCallback = () -> { + mPendingFrameCallback = null; + mBlankScreen = false; + // Try again. + updateScrims(); + }; + + // 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); + } + + @VisibleForTesting + protected void doOnTheNextFrame(Choreographer.FrameCallback callback) { + Choreographer.getInstance().postFrameCallback(callback); } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java index 314d6aa2bf57d..381e4af31853f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java @@ -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); - } } }, 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 6d2691c899f2c..43e16dbeaeed9 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 @@ -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); + } } }