Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3daf3b0e authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Don't animate when state is immediate

Avoid extending animation for states that are
immediate. Also cleaning up a little bit and
avoiding unecessary repaint.

Change-Id: I1644ce0b539cf92083b47cf3587b01f92b239095
Test: atest packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
Test: brightness mirror
Test: receive notification on keyguard while dragging
Test: unlock with fp
Fixes: 73784491
parent ac263ac4
Loading
Loading
Loading
Loading
+81 −62
Original line number Diff line number Diff line
@@ -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;
            }
            // 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;
            } else {
                animEndValue = ViewState.getChildTag(scrim, TAG_END_ALPHA);
            }
        }

        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,37 +782,18 @@ 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);
            } 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());
            if (mAnimateChange) {
                startScrimAnimation(scrim, currentAlpha);
            } else {
                // update the alpha directly
                updateScrimColor(scrim, alpha, getCurrentScrimTint(scrim));
                onFinished();
            }
            }
        } else {
            onFinished();
        }
+53 −2
Original line number Diff line number Diff line
@@ -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();