diff options
| author | 2025-02-21 07:23:14 -0800 | |
|---|---|---|
| committer | 2025-02-21 07:23:14 -0800 | |
| commit | 7bd784c73d91a23bf8adb706b1594ae28f957fc9 (patch) | |
| tree | e7bab481fc03e97e8e9157ff63bab2257179d7f5 | |
| parent | 42afa7c7aceaa1eb76146389dd66ef6def7f3d0c (diff) | |
| parent | c8b9a1fa24ee56cabaec579bb34f6e78dee1f0d8 (diff) | |
Merge "Fixed an issue where all appear and disappear animations were linear" into main
8 files changed, 84 insertions, 50 deletions
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index eb5b22f6c82c..f2c76ba25079 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -1939,6 +1939,16 @@ flag { } 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" description: "Disables expansion of the shade via two finger swipe on a trackpad" diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt index 67415de86d9b..e7be20e7c3cb 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackStateAnimatorTest.kt @@ -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(), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index b0773276a3e9..4ed9dcee072e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -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(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index d2800d7c1b71..4c744086fea4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java index da664f864f06..292f74a65554 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java @@ -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(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java index cd228e7872c1..a064d1c5b701 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java @@ -260,7 +260,7 @@ public abstract class StackScrollerDecorView extends ExpandableView { @Override public long performRemoveAnimation(long duration, long delay, float translationDirection, boolean isHeadsUpAnimation, - Runnable onStartedRunnable, + boolean isHeadsUpCycling, Runnable onStartedRunnable, Runnable onFinishedRunnable, AnimatorListenerAdapter animationListener, ClipSide clipSide) { // TODO: Use duration @@ -279,7 +279,7 @@ public abstract class StackScrollerDecorView extends ExpandableView { @Override public void performAddAnimation(long delay, long duration, boolean isHeadsUpAppear, - Runnable endRunnable) { + boolean isHeadsUpCycling, Runnable endRunnable) { // TODO: use delay and duration setContentVisibleAnimated(true); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt index bd7bd596438a..4d10a527d53b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt @@ -70,14 +70,15 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie } override fun performRemoveAnimation( - duration: Long, - delay: Long, - translationDirection: Float, - isHeadsUpAnimation: Boolean, - onStartedRunnable: Runnable?, - onFinishedRunnable: Runnable?, - animationListener: AnimatorListenerAdapter?, - clipSide: ClipSide + duration: Long, + delay: Long, + translationDirection: Float, + isHeadsUpAnimation: Boolean, + isHeadsUpCycling: Boolean, + onStartedRunnable: Runnable?, + onFinishedRunnable: Runnable?, + animationListener: AnimatorListenerAdapter?, + clipSide: ClipSide, ): Long { return 0 } @@ -86,7 +87,8 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie delay: Long, duration: Long, isHeadsUpAppear: Boolean, - onEnd: Runnable? + isHeadsUpCycling: Boolean, + onEnd: Runnable?, ) { // No animation, it doesn't need it, this would be local } @@ -103,9 +105,7 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie assertMediaContainerVisibility(visibility) } - /** - * visibility should be aligned with MediaContainerView visibility on the keyguard. - */ + /** visibility should be aligned with MediaContainerView visibility on the keyguard. */ private fun isVisibilityValid(visibility: Int): Boolean { val currentViewState = viewState as? MediaContainerViewState ?: return true val shouldBeGone = !currentViewState.shouldBeVisible @@ -113,8 +113,7 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie } /** - * b/298213983 - * MediaContainerView's visibility is changed to VISIBLE when it should be GONE. + * b/298213983 MediaContainerView's visibility is changed to VISIBLE when it should be GONE. * This method check this state and logs. */ private fun assertMediaContainerVisibility(visibility: Int) { @@ -122,8 +121,10 @@ class MediaContainerView(context: Context, attrs: AttributeSet?) : ExpandableVie if (currentViewState is MediaContainerViewState) { if (!currentViewState.shouldBeVisible && visibility == VISIBLE) { - Log.wtf("MediaContainerView", "MediaContainerView should be GONE " + - "but its visibility changed to VISIBLE") + Log.wtf( + "MediaContainerView", + "MediaContainerView should be GONE " + "but its visibility changed to VISIBLE", + ) } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java index 5e0d57ebb3fe..2b052236a921 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java @@ -506,8 +506,8 @@ public class StackStateAnimator { } changingView.performRemoveAnimation(ANIMATION_DURATION_APPEAR_DISAPPEAR, 0 /* delay */, translationDirection, false /* isHeadsUpAppear */, - startAnimation, postAnimation, getGlobalAnimationFinishedListener(), - ExpandableView.ClipSide.BOTTOM); + false /* isHeadsUpCycling */, startAnimation, postAnimation, + getGlobalAnimationFinishedListener(), ExpandableView.ClipSide.BOTTOM); needsCustomAnimation = true; } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) { @@ -538,7 +538,7 @@ public class StackStateAnimator { }; } changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_CYCLING, - /* isHeadsUpAppear= */ true, onAnimationEnd); + /* isHeadsUpAppear= */ true, /* isHeadsUpCycling= */ true, onAnimationEnd); } else if (event.animationType == ANIMATION_TYPE_HEADS_UP_APPEAR) { mHeadsUpAppearChildren.add(changingView); @@ -559,7 +559,7 @@ public class StackStateAnimator { onAnimationEnd = () -> mLogger.appearAnimationEnded(finalKey); } changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR, - /* isHeadsUpAppear= */ true, onAnimationEnd); + /* isHeadsUpAppear= */ true, /* isHeadsUpCycling= */ false, onAnimationEnd); } else if (event.animationType == ANIMATION_TYPE_HEADS_UP_CYCLING_OUT) { mHeadsUpDisappearChildren.add(changingView); Runnable endRunnable = null; @@ -629,6 +629,7 @@ public class StackStateAnimator { // translation, the actual translation is in StackScrollAlgorithm. /* translationDirection= */ 0.0f, /* isHeadsUpAnimation= */ true, + /* isHeadsUpCycling= */ true, startAnimation, postAnimation, getGlobalAnimationFinishedListener(), ExpandableView.ClipSide.TOP); mAnimationProperties.delay += removeAnimationDelay; @@ -706,6 +707,7 @@ public class StackStateAnimator { long removeAnimationDelay = changingView.performRemoveAnimation( ANIMATION_DURATION_HEADS_UP_DISAPPEAR, 0, 0.0f, true /* isHeadsUpAppear */, + false /* isHeadsUpCycling */, startAnimation, postAnimation, getGlobalAnimationFinishedListener(), ExpandableView.ClipSide.BOTTOM); mAnimationProperties.delay += removeAnimationDelay; |