Merge "Don't animate when state is immediate"

This commit is contained in:
Lucas Dupin
2018-03-02 21:28:26 +00:00
committed by Android (Google) Code Review
2 changed files with 134 additions and 64 deletions

View File

@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.app.AlarmManager;
import android.app.WallpaperManager;
@@ -362,7 +361,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
*
* The expansion fraction is tied to the scrim opacity.
*
* @param fraction From 0 to 1 where 0 means collapse and 1 expanded.
* @param fraction From 0 to 1 where 0 means collapsed and 1 expanded.
*/
public void setPanelExpansion(float fraction) {
if (mExpansionFraction != fraction) {
@@ -381,8 +380,25 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
if (mPinnedHeadsUpCount != 0) {
updateHeadsUpScrim(false);
}
updateScrim(false /* animate */, mScrimInFront, mCurrentInFrontAlpha);
updateScrim(false /* animate */, mScrimBehind, mCurrentBehindAlpha);
setOrAdaptCurrentAnimation(mScrimBehind);
setOrAdaptCurrentAnimation(mScrimInFront);
}
}
private void setOrAdaptCurrentAnimation(View scrim) {
if (!isAnimating(scrim)) {
updateScrimColor(scrim, getCurrentScrimAlpha(scrim), getCurrentScrimTint(scrim));
} else {
ValueAnimator previousAnimator = (ValueAnimator) scrim.getTag(TAG_KEY_ANIM);
float alpha = getCurrentScrimAlpha(scrim);
float previousEndValue = (Float) scrim.getTag(TAG_END_ALPHA);
float previousStartValue = (Float) scrim.getTag(TAG_START_ALPHA);
float relativeDiff = alpha - previousEndValue;
float newStartValue = previousStartValue + relativeDiff;
scrim.setTag(TAG_START_ALPHA, newStartValue);
scrim.setTag(TAG_END_ALPHA, alpha);
previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
}
}
@@ -523,14 +539,14 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
setScrimAlpha(mScrimInFront, alpha);
}
private void setScrimAlpha(View scrim, float alpha) {
private void setScrimAlpha(ScrimView scrim, float alpha) {
if (alpha == 0f) {
scrim.setClickable(false);
} else {
// Eat touch events (unless dozing).
scrim.setClickable(!(mState == ScrimState.AOD));
}
updateScrim(mAnimateChange, scrim, alpha);
updateScrim(scrim, alpha);
}
private void updateScrimColor(View scrim, float alpha, int tint) {
@@ -554,21 +570,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
dispatchScrimsVisible();
}
private int getCurrentScrimTint(View scrim) {
return scrim == mScrimInFront ? mCurrentInFrontTint : mCurrentBehindTint;
}
private void startScrimAnimation(final View scrim, float current) {
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
final int initialScrimTint = scrim instanceof ScrimView ? ((ScrimView) scrim).getTint() :
Color.TRANSPARENT;
anim.addUpdateListener(animation -> {
final float startAlpha = (Float) scrim.getTag(TAG_START_ALPHA);
final float animAmount = (float) animation.getAnimatedValue();
final int finalScrimTint = scrim == mScrimInFront ?
mCurrentInFrontTint : mCurrentBehindTint;
float finalScrimAlpha = scrim == mScrimInFront ?
mCurrentInFrontAlpha : mCurrentBehindAlpha;
float alpha = MathUtils.lerp(current, finalScrimAlpha, animAmount);
final int finalScrimTint = getCurrentScrimTint(scrim);
final float finalScrimAlpha = getCurrentScrimAlpha(scrim);
float alpha = MathUtils.lerp(startAlpha, finalScrimAlpha, animAmount);
alpha = MathUtils.constrain(alpha, 0f, 1f);
int tint = ColorUtils.blendARGB(initialScrimTint, finalScrimTint, animAmount);
updateScrimColor(scrim, alpha, tint);
dispatchScrimsVisible();
@@ -579,12 +591,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
final int finalScrimTint = scrim == mScrimInFront ?
mCurrentInFrontTint : mCurrentBehindTint;
float finalScrimAlpha = scrim == mScrimInFront ?
mCurrentInFrontAlpha : mCurrentBehindAlpha;
updateScrimColor(scrim, finalScrimAlpha, finalScrimTint);
if (mKeyguardFadingOutInProgress) {
mKeyguardFadeoutAnimation = null;
mKeyguardFadingOutInProgress = false;
@@ -600,12 +606,42 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
}
});
anim.start();
if (mAnimateKeyguardFadingOut) {
mKeyguardFadingOutInProgress = true;
mKeyguardFadeoutAnimation = anim;
}
// Cache alpha values because we might want to update this animator in the future if
// the user expands the panel while the animation is still running.
scrim.setTag(TAG_START_ALPHA, current);
scrim.setTag(TAG_END_ALPHA, getCurrentScrimAlpha(scrim));
scrim.setTag(TAG_KEY_ANIM, anim);
anim.start();
}
private float getCurrentScrimAlpha(View scrim) {
if (scrim == mScrimInFront) {
return mCurrentInFrontAlpha;
} else if (scrim == mScrimBehind) {
return mCurrentBehindAlpha;
} else if (scrim == mHeadsUpScrim) {
return calculateHeadsUpAlpha();
} else {
throw new IllegalArgumentException("Unknown scrim view");
}
}
private int getCurrentScrimTint(View scrim) {
if (scrim == mScrimInFront) {
return mCurrentInFrontTint;
} else if (scrim == mScrimBehind) {
return mCurrentBehindTint;
} else if (scrim == mHeadsUpScrim) {
return Color.TRANSPARENT;
} else {
throw new IllegalArgumentException("Unknown scrim view");
}
}
protected Interpolator getInterpolator() {
@@ -693,7 +729,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
private void updateHeadsUpScrim(boolean animate) {
updateScrim(animate, mHeadsUpScrim, calculateHeadsUpAlpha());
if (animate) {
mAnimationDuration = ANIMATION_DURATION;
cancelAnimator((ValueAnimator) mHeadsUpScrim.getTag(TAG_KEY_ANIM));
startScrimAnimation(mHeadsUpScrim, mHeadsUpScrim.getAlpha());
} else {
setOrAdaptCurrentAnimation(mHeadsUpScrim);
}
}
@VisibleForTesting
@@ -701,32 +743,28 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mOnAnimationFinished = onAnimationFinished;
}
private void updateScrim(boolean animate, View scrim, float alpha) {
final float currentAlpha = scrim instanceof ScrimView ? ((ScrimView) scrim).getViewAlpha()
: scrim.getAlpha();
private void updateScrim(ScrimView scrim, float alpha) {
final float currentAlpha = scrim.getViewAlpha();
ValueAnimator previousAnimator = ViewState.getChildTag(scrim, TAG_KEY_ANIM);
float animEndValue = -1;
if (previousAnimator != null) {
if (animate || alpha == currentAlpha) {
if (mAnimateChange) {
// We are not done yet! Defer calling the finished listener.
if (animate) {
mDeferFinishedListener = true;
}
cancelAnimator(previousAnimator);
mDeferFinishedListener = false;
} else {
animEndValue = ViewState.getChildTag(scrim, TAG_END_ALPHA);
mDeferFinishedListener = true;
}
// Previous animators should always be cancelled. Not doing so would cause
// overlap, especially on states that don't animate, leading to flickering,
// and in the worst case, an internal state that doesn't represent what
// transitionTo requested.
cancelAnimator(previousAnimator);
mDeferFinishedListener = false;
}
if (mPendingFrameCallback != null) {
// Display is off and we're waiting.
cancelAnimator(previousAnimator);
return;
} else if (mBlankScreen) {
// Need to blank the display before continuing.
cancelAnimator(previousAnimator);
blankDisplay();
return;
} else if (!mScreenBlankingCallbackCalled) {
@@ -744,36 +782,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
}
final ScrimView scrimView = scrim instanceof ScrimView ? (ScrimView) scrim : null;
final boolean wantsAlphaUpdate = alpha != currentAlpha && alpha != animEndValue;
final boolean wantsAlphaUpdate = alpha != currentAlpha;
final boolean wantsTintUpdate = scrimView != null
&& scrimView.getTint() != getCurrentScrimTint(scrimView);
if (wantsAlphaUpdate || wantsTintUpdate) {
if (animate) {
final float fromAlpha = scrimView == null ? scrim.getAlpha()
: scrimView.getViewAlpha();
startScrimAnimation(scrim, fromAlpha);
scrim.setTag(TAG_START_ALPHA, currentAlpha);
scrim.setTag(TAG_END_ALPHA, alpha);
if (mAnimateChange) {
startScrimAnimation(scrim, currentAlpha);
} else {
if (previousAnimator != null) {
float previousStartValue = ViewState.getChildTag(scrim, TAG_START_ALPHA);
float previousEndValue = ViewState.getChildTag(scrim, TAG_END_ALPHA);
// we need to increase all animation keyframes of the previous animator by the
// relative change to the end value
PropertyValuesHolder[] values = previousAnimator.getValues();
float relativeDiff = alpha - previousEndValue;
float newStartValue = previousStartValue + relativeDiff;
newStartValue = Math.max(0, Math.min(1.0f, newStartValue));
values[0].setFloatValues(newStartValue, alpha);
scrim.setTag(TAG_START_ALPHA, newStartValue);
scrim.setTag(TAG_END_ALPHA, alpha);
previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
} else {
// update the alpha directly
updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
onFinished();
}
// update the alpha directly
updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
onFinished();
}
} else {
onFinished();

View File

@@ -77,7 +77,7 @@ public class ScrimControllerTest extends SysuiTestCase {
mLightBarController = mock(LightBarController.class);
mScrimBehind = new ScrimView(getContext());
mScrimInFront = new ScrimView(getContext());
mHeadsUpScrim = mock(View.class);
mHeadsUpScrim = new View(getContext());
mWakeLock = mock(WakeLock.class);
mAlarmManager = mock(AlarmManager.class);
mAlwaysOnEnabled = true;
@@ -384,6 +384,56 @@ public class ScrimControllerTest extends SysuiTestCase {
testConservesNotificationDensity(3 /* count */, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY);
}
@Test
public void testHeadsUpScrimOpacity() {
mScrimController.setPanelExpansion(0f);
mScrimController.onHeadsUpPinned(null /* row */);
mScrimController.finishAnimationsImmediately();
Assert.assertNotEquals("Heads-up scrim should be visible", 0f,
mHeadsUpScrim.getAlpha(), 0.01f);
mScrimController.onHeadsUpUnPinned(null /* row */);
mScrimController.finishAnimationsImmediately();
Assert.assertEquals("Heads-up scrim should have disappeared", 0f,
mHeadsUpScrim.getAlpha(), 0.01f);
}
@Test
public void testHeadsUpScrimCounting() {
mScrimController.setPanelExpansion(0f);
mScrimController.onHeadsUpPinned(null /* row */);
mScrimController.onHeadsUpPinned(null /* row */);
mScrimController.onHeadsUpPinned(null /* row */);
mScrimController.finishAnimationsImmediately();
Assert.assertNotEquals("Heads-up scrim should be visible", 0f,
mHeadsUpScrim.getAlpha(), 0.01f);
mScrimController.onHeadsUpUnPinned(null /* row */);
mScrimController.finishAnimationsImmediately();
Assert.assertEquals("Heads-up scrim should only disappear when counter reaches 0", 1f,
mHeadsUpScrim.getAlpha(), 0.01f);
mScrimController.onHeadsUpUnPinned(null /* row */);
mScrimController.onHeadsUpUnPinned(null /* row */);
mScrimController.finishAnimationsImmediately();
Assert.assertEquals("Heads-up scrim should have disappeared", 0f,
mHeadsUpScrim.getAlpha(), 0.01f);
}
@Test
public void testNoHeadsUpScrimExpanded() {
mScrimController.setPanelExpansion(1f);
mScrimController.onHeadsUpPinned(null /* row */);
mScrimController.finishAnimationsImmediately();
Assert.assertEquals("Heads-up scrim should not be visible when shade is expanded", 0f,
mHeadsUpScrim.getAlpha(), 0.01f);
}
/**
* Conserves old notification density after leaving state and coming back.
*
@@ -458,6 +508,7 @@ public class ScrimControllerTest extends SysuiTestCase {
// Force finish all animations.
endAnimation(mScrimBehind, TAG_KEY_ANIM);
endAnimation(mScrimInFront, TAG_KEY_ANIM);
endAnimation(mHeadsUpScrim, TAG_KEY_ANIM);
if (!animationFinished[0]) {
throw new IllegalStateException("Animation never finished");
@@ -470,7 +521,7 @@ public class ScrimControllerTest extends SysuiTestCase {
return wasCancelled;
}
private void endAnimation(ScrimView scrimView, int tag) {
private void endAnimation(View scrimView, int tag) {
Animator animator = (Animator) scrimView.getTag(tag);
if (animator != null) {
animator.end();