diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index d741cc8bda8e7..2d30f4c0082d6 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 59c44ed6635f3..2b16e740d0ba1 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; @@ -692,11 +698,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 @@ -750,45 +757,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); + } } }