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

Commit c8b9a1fa authored by Selim Cinek's avatar Selim Cinek
Browse files

Fixed an issue where all appear and disappear animations were linear

Since the cycling flag was introduced, all notification animations
that were adding or removing a notification were linear.

Bug: 397658189
Flag: com.android.systemui.notification_appear_nonlinear
Test: atest SystemUITests
Change-Id: I2ce2710dcb336dc066aac345b301d95cbe8ed229
parent b3bd93da
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1938,6 +1938,16 @@ flag {
   bug: "382531177"
}

flag {
   name: "notification_appear_nonlinear"
   namespace: "systemui"
   description: "Fix linear usage of notification appear"
   bug: "397658189"
   metadata {
     purpose: PURPOSE_BUGFIX
   }
}

flag {
  name: "disable_shade_trackpad_two_finger_swipe"
  namespace: "systemui"
+3 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ class StackStateAnimatorTest : SysuiTestCase() {
                /* delay= */ 0L,
                /* duration= */ ANIMATION_DURATION_HEADS_UP_APPEAR.toLong(),
                /* isHeadsUpAppear= */ true,
                /* isHeadsUpCycling= */ false,
                /* onEndRunnable= */ null,
            )
    }
@@ -111,6 +112,7 @@ class StackStateAnimatorTest : SysuiTestCase() {
                /* delay= */ 0L,
                /* duration= */ ANIMATION_DURATION_HEADS_UP_APPEAR.toLong(),
                /* isHeadsUpAppear= */ true,
                /* isHeadsUpCycling= */ false,
                /* onEndRunnable= */ null,
            )
    }
@@ -128,6 +130,7 @@ class StackStateAnimatorTest : SysuiTestCase() {
                /* delay= */ eq(0L),
                /* translationDirection= */ eq(0f),
                /* isHeadsUpAnimation= */ eq(true),
                /* isHeadsUpCycling= */ eq(false),
                /* onStartedRunnable= */ any(),
                /* onFinishedRunnable= */ runnableCaptor.capture(),
                /* animationListener= */ any(),
+28 −9
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.systemui.statusbar.notification.row;

import static com.android.systemui.Flags.notificationAppearNonlinear;
import static com.android.systemui.Flags.notificationBackgroundTintOptimization;
import static com.android.systemui.Flags.notificationRowTransparency;
import static com.android.systemui.Flags.physicalNotificationMovement;
import static com.android.systemui.statusbar.notification.row.ExpandableView.ClipSide.BOTTOM;
import static com.android.systemui.statusbar.notification.row.ExpandableView.ClipSide.TOP;

@@ -71,7 +73,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
     * #ALPHA_APPEAR_START_FRACTION.
     */

    private static final float ALPHA_APPEAR_START_FRACTION = .7f;
    private static final float ALPHA_APPEAR_START_FRACTION =
            notificationAppearNonlinear() ? .55f : .7f;
    /**
     * The content should show fully with progress at #ALPHA_APPEAR_END_FRACTION
     * The start of the animation is at #ALPHA_APPEAR_START_FRACTION
@@ -111,6 +114,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
    private float mOverrideAmount;
    private boolean mShadowHidden;
    private boolean mIsHeadsUpAnimation;
    private boolean mIsHeadsUpCycling;
    /* In order to track headsup longpress coorindate. */
    protected Point mTargetPoint;
    private boolean mDismissed;
@@ -349,10 +353,12 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView

    @Override
    public long performRemoveAnimation(long duration, long delay, float translationDirection,
            boolean isHeadsUpAnimation, Runnable onStartedRunnable, Runnable onFinishedRunnable,
            AnimatorListenerAdapter animationListener, ClipSide clipSide) {
            boolean isHeadsUpAnimation, boolean isHeadsUpCycling, Runnable onStartedRunnable,
            Runnable onFinishedRunnable, AnimatorListenerAdapter animationListener,
            ClipSide clipSide) {
        enableAppearDrawing(true);
        mIsHeadsUpAnimation = isHeadsUpAnimation;
        mIsHeadsUpCycling = isHeadsUpCycling;
        if (mDrawingAppearAnimation) {
            startAppearAnimation(false /* isAppearing */, translationDirection,
                    delay, duration, onStartedRunnable, onFinishedRunnable, animationListener,
@@ -370,9 +376,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView

    @Override
    public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
            Runnable onFinishRunnable) {
            boolean isHeadsUpCycling, Runnable onFinishRunnable) {
        enableAppearDrawing(true);
        mIsHeadsUpAnimation = isHeadsUpAppear;
        mIsHeadsUpCycling = isHeadsUpCycling;
        if (mDrawingAppearAnimation) {
            startAppearAnimation(true /* isAppearing */, isHeadsUpAppear ? 0.0f : -1.0f, delay,
                    duration, null, null, null, ClipSide.BOTTOM);
@@ -404,14 +411,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
            targetValue = 0.0f;
        }

        if (NotificationHeadsUpCycling.isEnabled()) {
            // TODO(b/316404716): add avalanche filtering
        if (NotificationHeadsUpCycling.isEnabled() && !useNonLinearAnimation()) {
            mCurrentAppearInterpolator = Interpolators.LINEAR;
        }

        mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction,
                targetValue);
        mAppearAnimator.setInterpolator(mCurrentAppearInterpolator);
        mAppearAnimator.setInterpolator(
                useNonLinearAnimation() ? Interpolators.LINEAR : mCurrentAppearInterpolator);
        mAppearAnimator.setDuration(
                (long) (duration * Math.abs(mAppearAnimationFraction - targetValue)));
        mAppearAnimator.addUpdateListener(animation -> {
@@ -530,7 +537,13 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
     * @param clipSide Which side if view we want to clip from
     */
    private void updateAppearRect(ClipSide clipSide) {
        float interpolatedFraction = mAppearAnimationFraction;
        float interpolatedFraction;
        if (useNonLinearAnimation()) {
            interpolatedFraction = mCurrentAppearInterpolator.getInterpolation(
                    mAppearAnimationFraction);
        } else {
            interpolatedFraction = mAppearAnimationFraction;
        }
        mAppearAnimationTranslation = (1.0f - interpolatedFraction) * mAnimationTranslationY;
        final int fullHeight = getActualHeight();
        float height = fullHeight * interpolatedFraction;
@@ -558,6 +571,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
        }
    }

    private boolean useNonLinearAnimation() {
        return notificationAppearNonlinear() && (!mIsHeadsUpCycling
                || physicalNotificationMovement());
    }

    private void updateAppearRect() {
        updateAppearRect(ClipSide.BOTTOM);
    }
@@ -567,7 +585,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
                mAppearAnimationFraction,
                ALPHA_APPEAR_START_FRACTION,
                ALPHA_APPEAR_END_FRACTION,
                Interpolators.ALPHA_IN
                notificationAppearNonlinear() ? mCurrentAppearInterpolator : Interpolators.ALPHA_IN
        );
    }

@@ -813,6 +831,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
        pw.print("mDrawingAppearAnimation", mDrawingAppearAnimation);
        pw.print("mAppearAnimationFraction", mAppearAnimationFraction);
        pw.print("mIsHeadsUpAnimation", mIsHeadsUpAnimation);
        pw.print("mIsHeadsUpCycling", mIsHeadsUpCycling);
        pw.print("mTargetPoint", mTargetPoint);
        pw.println();
    }
+12 −15
Original line number Diff line number Diff line
@@ -3494,20 +3494,17 @@ public class ExpandableNotificationRow extends ActivatableNotificationView

    @Override
    public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
            Runnable onFinishRunnable) {
            boolean isHeadsUpCycling, Runnable onFinishRunnable) {
        mLogger.logStartAppearAnimation(mLoggingKey, /* isAppear = */ true);
        super.performAddAnimation(delay, duration, isHeadsUpAppear, onFinishRunnable);
        super.performAddAnimation(delay, duration, isHeadsUpAppear, isHeadsUpCycling,
                onFinishRunnable);
    }

    @Override
    public long performRemoveAnimation(
            long duration,
            long delay,
            float translationDirection,
            boolean isHeadsUpAnimation,
            Runnable onStartedRunnable,
            Runnable onFinishedRunnable,
            AnimatorListenerAdapter animationListener, ClipSide clipSide) {
    public long performRemoveAnimation(long duration, long delay, float translationDirection,
            boolean isHeadsUpAnimation, boolean isHeadsUpCycling, Runnable onStartedRunnable,
            Runnable onFinishedRunnable, AnimatorListenerAdapter animationListener,
            ClipSide clipSide) {
        mLogger.logStartAppearAnimation(mLoggingKey, /* isAppear = */ false);
        if (mMenuRow != null && mMenuRow.isMenuVisible()) {
            Animator anim = getTranslateViewAnimator(0f, null /* listener */);
@@ -3522,9 +3519,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        ExpandableNotificationRow.super.performRemoveAnimation(
                                duration, delay, translationDirection, isHeadsUpAnimation,
                                null, onFinishedRunnable, animationListener, ClipSide.BOTTOM);
                        ExpandableNotificationRow.super.performRemoveAnimation(duration, delay,
                                translationDirection, isHeadsUpAnimation, isHeadsUpCycling, null,
                                onFinishedRunnable, animationListener, ClipSide.BOTTOM);
                    }
                });
                anim.start();
@@ -3532,8 +3529,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
            }
        }
        return super.performRemoveAnimation(duration, delay, translationDirection,
                isHeadsUpAnimation, onStartedRunnable, onFinishedRunnable, animationListener,
                clipSide);
                isHeadsUpAnimation, isHeadsUpCycling, onStartedRunnable, onFinishedRunnable,
                animationListener, clipSide);
    }

    @Override
+6 −4
Original line number Diff line number Diff line
@@ -467,7 +467,8 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
     *                             remove animation should be performed upwards,
     *                             such that the  child appears to be going away to the top. 1
     *                             Should mean the opposite.
     * @param isHeadsUpAnimation   Is this a headsUp animation.
     * @param isHeadsUpAnimation   Is this a headsUp animation
     * @param isHeadsUpCycling     Is this the cycling heads up animation
     * @param onFinishedRunnable   A runnable which should be run when the animation is finished.
     * @param animationListener    An animation listener to add to the animation.
     * @return The additional delay, in milliseconds, that this view needs to add before the
@@ -475,7 +476,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
     */
    public abstract long performRemoveAnimation(long duration,
            long delay, float translationDirection, boolean isHeadsUpAnimation,
            Runnable onStartedRunnable,
            boolean isHeadsUpCycling, Runnable onStartedRunnable,
            Runnable onFinishedRunnable,
            AnimatorListenerAdapter animationListener, ClipSide clipSide);

@@ -485,11 +486,12 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
    }

    public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear) {
        performAddAnimation(delay, duration, isHeadsUpAppear, null);
        performAddAnimation(delay, duration, isHeadsUpAppear, false /* isHeadsUpCycling */,
                null);
    }

    public abstract void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear,
            Runnable onEndRunnable);
            boolean isHeadsUpCycling, Runnable onEndRunnable);

    public int getPinnedHeadsUpHeight() {
        return getIntrinsicHeight();
Loading