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
This commit is contained in:
Lucas Dupin
2018-02-05 10:49:03 -08:00
parent 7b2354ece2
commit 8c7cb02f1f
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;
@@ -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

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