From 0f145252609f93275a7d5935f5a529a73f3fc2b6 Mon Sep 17 00:00:00 2001 From: Jay Aliomer Date: Wed, 12 May 2021 12:35:45 -0400 Subject: [PATCH] Animation reveal animation for HUN and Shelf Test: visual Fixes: b/187175147 Fixes: b/186892139 Change-Id: Ieea6531aecdaae81f681f1c46c6f8f6936655ee2 --- .../systemui/statusbar/NotificationShelf.java | 7 +- .../row/ActivatableNotificationView.java | 102 +++++++----------- .../row/ExpandableNotificationRow.java | 17 --- .../notification/stack/AnimationFilter.java | 10 -- .../stack/StackScrollAlgorithm.java | 3 +- .../stack/StackStateAnimator.java | 20 +--- 6 files changed, 46 insertions(+), 113 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 9dc4ac952b1d1..455e7f3c9225c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -20,14 +20,11 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; -import android.os.SystemProperties; import android.util.AttributeSet; import android.util.MathUtils; -import android.view.DisplayCutout; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; -import android.view.WindowInsets; import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.annotations.VisibleForTesting; @@ -663,8 +660,8 @@ public class NotificationShelf extends ActivatableNotificationView implements boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); iconState.hidden = isAppearing || (view instanceof ExpandableNotificationRow - && ((ExpandableNotificationRow) view).isLowPriority() - && mShelfIcons.hasMaxNumDot()) + && ((ExpandableNotificationRow) view).isLowPriority() + && mShelfIcons.hasMaxNumDot()) || (transitionAmount == 0.0f && !iconState.isAnimating(icon)) || row.isAboveShelf() || row.showingPulsing() 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 3e2bcf9562b04..5befc1de86c89 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 @@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.row; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; @@ -83,7 +82,16 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView * or {@link #setOverrideTintColor(int, float)}. */ protected static final int NO_COLOR = 0; - + /** + * The content of the view should start showing at animation progress value of + * #ALPHA_APPEAR_START_FRACTION. + */ + private static final float ALPHA_APPEAR_START_FRACTION = .4f; + /** + * The content should show fully with progress at #ALPHA_APPEAR_END_FRACTION + * The start of the animation is at #ALPHA_APPEAR_START_FRACTION + */ + private static final float ALPHA_APPEAR_END_FRACTION = 1; private static final Interpolator ACTIVATE_INVERSE_INTERPOLATOR = new PathInterpolator(0.6f, 0, 0.5f, 1); private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR @@ -105,10 +113,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private final Interpolator mSlowOutFastInInterpolator; private final Interpolator mSlowOutLinearInInterpolator; private Interpolator mCurrentAppearInterpolator; - private Interpolator mCurrentAlphaInterpolator; NotificationBackgroundView mBackgroundNormal; - private ObjectAnimator mBackgroundAnimator; private RectF mAppearAnimationRect = new RectF(); private float mAnimationTranslationY; private boolean mDrawingAppearAnimation; @@ -474,8 +480,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private void startAppearAnimation(boolean isAppearing, float translationDirection, long delay, long duration, final Runnable onFinishedRunnable, AnimatorListenerAdapter animationListener) { - cancelAppearAnimation(); mAnimationTranslationY = translationDirection * getActualHeight(); + cancelAppearAnimation(); if (mAppearAnimationFraction == -1.0f) { // not initialized yet, we start anew if (isAppearing) { @@ -491,15 +497,9 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView float targetValue; if (isAppearing) { mCurrentAppearInterpolator = mSlowOutFastInInterpolator; - mCurrentAlphaInterpolator = Interpolators.LINEAR_OUT_SLOW_IN; targetValue = 1.0f; - if (!mIsHeadsUpAnimation && isChildInGroup()) { - // slower fade in of children to avoid visibly overlapping with other children - mCurrentAlphaInterpolator = Interpolators.SLOW_OUT_LINEAR_IN; - } } else { mCurrentAppearInterpolator = Interpolators.FAST_OUT_SLOW_IN; - mCurrentAlphaInterpolator = mSlowOutLinearInInterpolator; targetValue = 0.0f; } mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction, @@ -586,61 +586,23 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView float translationFraction = mCurrentAppearInterpolator.getInterpolation(inverseFraction); float translateYTotalAmount = translationFraction * mAnimationTranslationY; mAppearAnimationTranslation = translateYTotalAmount; - - // handle width animation - float widthFraction = (inverseFraction - (1.0f - HORIZONTAL_ANIMATION_START)) - / (HORIZONTAL_ANIMATION_START - HORIZONTAL_ANIMATION_END); - widthFraction = Math.min(1.0f, Math.max(0.0f, widthFraction)); - widthFraction = mCurrentAppearInterpolator.getInterpolation(widthFraction); - float startWidthFraction = HORIZONTAL_COLLAPSED_REST_PARTIAL; - if (mIsHeadsUpAnimation && !mIsAppearing) { - startWidthFraction = 0; - } - if (mIsAppearing && !mIsHeadsUpAnimation && isChildInGroup()) { - // Children in a group (when not heads up) should simply fade in. - startWidthFraction = 1; - } - float width = MathUtils.lerp(startWidthFraction, 1.0f, 1.0f - widthFraction) - * getWidth(); - float left; - float right; - if (mIsHeadsUpAnimation) { - left = MathUtils.lerp(mHeadsUpLocation, 0, 1.0f - widthFraction); - right = left + width; - } else { - left = getWidth() * 0.5f - width / 2.0f; - right = getWidth() - left; - } - - // handle top animation - float heightFraction = (inverseFraction - (1.0f - VERTICAL_ANIMATION_START)) / - VERTICAL_ANIMATION_START; - heightFraction = Math.max(0.0f, heightFraction); - heightFraction = mCurrentAppearInterpolator.getInterpolation(heightFraction); - - float top; - float bottom; final int actualHeight = getActualHeight(); - if (mAnimationTranslationY > 0.0f) { - bottom = actualHeight - heightFraction * mAnimationTranslationY * 0.1f - - translateYTotalAmount; - top = bottom * heightFraction; - } else { - top = heightFraction * (actualHeight + mAnimationTranslationY) * 0.1f - - translateYTotalAmount; - bottom = actualHeight * (1 - heightFraction) + top * heightFraction; - } - mAppearAnimationRect.set(left, top, right, bottom); - setOutlineRect(left, top + mAppearAnimationTranslation, right, - bottom + mAppearAnimationTranslation); + float bottom = actualHeight * mAppearAnimationFraction; + + setOutlineRect(0, mAppearAnimationTranslation, + getWidth(), bottom + mAppearAnimationTranslation); + } + + private float getAppearAnimationFraction() { + return mAppearAnimationFraction >= 0 ? mAppearAnimationFraction : 1; } private void updateAppearAnimationAlpha() { - float contentAlphaProgress = mAppearAnimationFraction; - contentAlphaProgress = contentAlphaProgress / (1.0f - ALPHA_ANIMATION_END); - contentAlphaProgress = Math.min(1.0f, contentAlphaProgress); - contentAlphaProgress = mCurrentAlphaInterpolator.getInterpolation(contentAlphaProgress); - setContentAlpha(contentAlphaProgress); + float contentAlphaProgress = MathUtils.constrain(mAppearAnimationFraction, + ALPHA_APPEAR_START_FRACTION, ALPHA_APPEAR_END_FRACTION); + float range = ALPHA_APPEAR_END_FRACTION - ALPHA_APPEAR_START_FRACTION; + float alpha = (contentAlphaProgress - ALPHA_APPEAR_START_FRACTION) / range; + setContentAlpha(Interpolators.ALPHA_IN.getInterpolation(alpha)); } private void setContentAlpha(float contentAlpha) { @@ -663,6 +625,22 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView getCurrentBackgroundRadiusBottom()); } + @Override + public float getCurrentBackgroundRadiusTop() { + float fraction = getAppearAnimationFraction(); + return isHeadsUpAnimatingAway() || isHeadsUp() + ? mOutlineRadius * fraction + : super.getCurrentBackgroundRadiusTop(); + } + + @Override + public float getCurrentBackgroundRadiusBottom() { + float fraction = getAppearAnimationFraction(); + return isHeadsUpAnimatingAway() || isHeadsUp() + ? mOutlineRadius * fraction + : super.getCurrentBackgroundRadiusBottom(); + } + private void applyBackgroundRoundness(float topRadius, float bottomRadius) { mBackgroundNormal.setRadius(topRadius, bottomRadius); } 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 c6753b3b42f90..afd36177b13f3 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 @@ -1998,23 +1998,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return false; } - @Override - public float getCurrentTopRoundness() { - if (mExpandAnimationRunning) { - return mTopRoundnessDuringExpandAnimation; - } - - return super.getCurrentTopRoundness(); - } - - @Override - public float getCurrentBottomRoundness() { - if (mExpandAnimationRunning) { - return mBottomRoundnessDuringExpandAnimation; - } - - return super.getCurrentBottomRoundness(); - } public void applyExpandAnimationParams(ExpandAnimationParameters params) { if (params == null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java index 6cd2290374628..5343cbf4f9fa0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java @@ -117,16 +117,6 @@ public class AnimationFilter { NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) { hasGoToFullShadeEvent = true; } - if (ev.animationType == NotificationStackScrollLayout.AnimationEvent - .ANIMATION_TYPE_HEADS_UP_DISAPPEAR) { - customDelay = StackStateAnimator.ANIMATION_DELAY_HEADS_UP; - } else if (ev.animationType == NotificationStackScrollLayout.AnimationEvent - .ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) { - // We need both timeouts when clicking, one to delay it and one for the animation - // to look nice - customDelay = StackStateAnimator.ANIMATION_DELAY_HEADS_UP_CLICKED - + StackStateAnimator.ANIMATION_DELAY_HEADS_UP; - } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 86465b6f6b1ab..9445348a1cf70 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -556,7 +556,7 @@ public class StackScrollAlgorithm { continue; } ExpandableNotificationRow row = (ExpandableNotificationRow) child; - if (!row.isHeadsUp()) { + if (!(row.isHeadsUp() || row.isHeadsUpAnimatingAway())) { continue; } ExpandableViewState childState = row.getViewState(); @@ -603,6 +603,7 @@ public class StackScrollAlgorithm { } } if (row.isHeadsUpAnimatingAway()) { + childState.yTranslation = Math.max(childState.yTranslation, mHeadsUpInset); childState.hidden = false; } } 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 883f9f26c518b..83dc6df5415a4 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 @@ -63,8 +63,6 @@ public class StackStateAnimator { public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32; public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48; public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2; - public static final int ANIMATION_DELAY_HEADS_UP = 120; - public static final int ANIMATION_DELAY_HEADS_UP_CLICKED= 120; private static final int MAX_STAGGER_COUNT = 5; private static final HeadsUpAppearInterpolator HEADS_UP_APPEAR_INTERPOLATOR = new HeadsUpAppearInterpolator(); @@ -424,7 +422,6 @@ public class StackStateAnimator { if (event.headsUpFromBottom) { mTmpState.yTranslation = mHeadsUpAppearHeightBottom; } else { - mTmpState.yTranslation = 0; changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR_CLOSED, true /* isHeadsUpAppear */); } @@ -436,24 +433,11 @@ public class StackStateAnimator { .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) { mHeadsUpDisappearChildren.add(changingView); Runnable endRunnable = null; - // We need some additional delay in case we were removed to make sure we're not - // lagging - int extraDelay = event.animationType == NotificationStackScrollLayout - .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK - ? ANIMATION_DELAY_HEADS_UP_CLICKED - : 0; if (changingView.getParent() == null) { // This notification was actually removed, so we need to add it transiently mHostLayout.addTransientView(changingView, 0); changingView.setTransientContainer(mHostLayout); mTmpState.initFrom(changingView); - mTmpState.yTranslation = 0; - // We temporarily enable Y animations, the real filter will be combined - // afterwards anyway - mAnimationFilter.animateY = true; - mAnimationProperties.delay = extraDelay + ANIMATION_DELAY_HEADS_UP; - mAnimationProperties.duration = ANIMATION_DURATION_HEADS_UP_DISAPPEAR; - mTmpState.animateTo(changingView, mAnimationProperties); endRunnable = () -> removeTransientView(changingView); } float targetLocation = 0; @@ -483,8 +467,8 @@ public class StackStateAnimator { // running anymore, the panel will instantly hide itself. We need to wait until // the animation is fully finished for this though. long removeAnimationDelay = changingView.performRemoveAnimation( - ANIMATION_DURATION_HEADS_UP_DISAPPEAR + ANIMATION_DELAY_HEADS_UP, - extraDelay, 0.0f, true /* isHeadsUpAppear */, targetLocation, + ANIMATION_DURATION_HEADS_UP_DISAPPEAR, + 0, 0.0f, true /* isHeadsUpAppear */, targetLocation, endRunnable, getGlobalAnimationFinishedListener()); mAnimationProperties.delay += removeAnimationDelay; } else if (endRunnable != null) {