Merge "Display blanking logic improvements"

This commit is contained in:
Lucas Dupin
2018-02-07 00:34:28 +00:00
committed by Android (Google) Code Review
4 changed files with 47 additions and 51 deletions

View File

@@ -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"/>

View File

@@ -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

View File

@@ -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);
}
}
},

View File

@@ -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);
}
}
}