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

Commit e83700cb authored by Gus Prevas's avatar Gus Prevas
Browse files

Fixes background animation when dismissing top item in a section.

This change modifies the code that computes the target bounds for each
notification section's background to reuse the logic used to compute
the overall background's bounds.  This allows us to avoid, for example,
animating the bottom section's background downwards when dismissing the
first item in that section when that item will eventually end up exactly
where the background's top already is.

Change-Id: I3153ac47915e194b9355354593c81e84c89fc8a3
Fixes: 120873029
Test: manual
parent bb28a036
Loading
Loading
Loading
Loading
+64 −39
Original line number Diff line number Diff line
@@ -16,10 +16,8 @@

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

import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator
        .ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator
        .ANIMATION_DURATION_SWIPE;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
import static com.android.systemui.statusbar.phone.NotificationIconAreaController.LOW_PRIORITY;

import android.animation.Animator;
@@ -2157,19 +2155,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
            }
            return;
        }
        NotificationSection firstSection = getFirstVisibleSection();
        int top = 0;
        if (firstSection != null) {
            ActivatableNotificationView firstView = firstSection.getFirstVisibleChild();
            // Round Y up to avoid seeing the background during animation
            int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView));
            if (mAnimateNextBackgroundTop || firstSection.isTargetTop(finalTranslationY)) {
                // we're ending up at the same location as we are now, lets just skip the animation
                top = finalTranslationY;
            } else {
                top = (int) Math.ceil(firstView.getTranslationY());
            }
        }
        int top = getSectionTopOrFinalTop(getFirstVisibleSection(), mAnimateNextBackgroundTop);
        NotificationSection lastSection = getLastVisibleSection();
        ActivatableNotificationView lastView =
                mShelf.hasItemsInStableShelf() && mShelf.getVisibility() != GONE
@@ -2177,21 +2163,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
                        : lastSection == null ? null : lastSection.getLastVisibleChild();
        int bottom;
        if (lastView != null) {
            int finalTranslationY;
            if (lastView == mShelf) {
                finalTranslationY = (int) mShelf.getTranslationY();
            } else {
                finalTranslationY = (int) ViewState.getFinalTranslationY(lastView);
            }
            int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
            int finalBottom = finalTranslationY + finalHeight - lastView.getClipBottomAmount();
            if (mAnimateNextBackgroundBottom || lastSection.isTargetBottom(finalBottom)) {
                // we're ending up at the same location as we are now, lets just skip the animation
                bottom = finalBottom;
            } else {
                bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
                        - lastView.getClipBottomAmount());
            }
            bottom = getSectionBottomOrFinalBottom(
                    lastSection, lastView, mAnimateNextBackgroundBottom);
        } else {
            top = mTopPadding;
            bottom = top;
@@ -2207,6 +2180,57 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
        setSectionBoundsByPriority(left, right, top, bottom, mSections[0], mSections[1]);
    }

    private int getSectionTopOrFinalTop(
            @Nullable NotificationSection section, boolean alreadyAnimating) {
        int top = 0;
        if (section != null) {
            ActivatableNotificationView firstView = section.getFirstVisibleChild();
            // Round Y up to avoid seeing the background during animation
            int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView));
            if (alreadyAnimating || section.isTargetTop(finalTranslationY)) {
                // we're ending up at the same location as we are now, let's just skip the animation
                top = finalTranslationY;
            } else {
                top = (int) Math.ceil(firstView.getTranslationY());
            }
        }
        return top;
    }

    private int getSectionBottomOrFinalBottom(
            @Nullable NotificationSection section, boolean alreadyAnimating) {
        return section == null ? 0
                : getSectionBottomOrFinalBottom(
                        section, section.getLastVisibleChild(), alreadyAnimating);
    }

    private int getSectionBottomOrFinalBottom(
            NotificationSection section,
            ActivatableNotificationView lastView,
            boolean alreadyAnimating) {
        int bottom = 0;
        if (lastView != null) {
            float finalTranslationY;
            if (lastView == mShelf) {
                finalTranslationY = mShelf.getTranslationY();
            } else {
                finalTranslationY = ViewState.getFinalTranslationY(lastView);
            }
            int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
            // Round Y down to avoid seeing the background during animation
            int finalBottom = (int) Math.floor(
                    finalTranslationY + finalHeight - lastView.getClipBottomAmount());
            if (alreadyAnimating || section.isTargetBottom(finalBottom)) {
                // we're ending up at the same location as we are now, lets just skip the animation
                bottom = finalBottom;
            } else {
                bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
                        - lastView.getClipBottomAmount());
            }
        }
        return bottom;
    }

    private void setSectionBoundsByPriority(int left, int right, int top, int bottom,
            NotificationSection highPrioritySection, NotificationSection lowPrioritySection) {
        if (NotificationUtils.useNewInterruptionModel(mContext)) {
@@ -2214,13 +2238,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
            ActivatableNotificationView lastChildAboveGap = getLastHighPriorityChild();
            ActivatableNotificationView firstChildBelowGap = getFirstLowPriorityChild();
            if (lastChildAboveGap != null && firstChildBelowGap != null) {
                int gapTop =
                        (int) Math.max(top,
                                Math.min(lastChildAboveGap.getTranslationY()
                                                + lastChildAboveGap.getActualHeight(),
                                        bottom));
                int gapBottom = (int) Math.max(top,
                        Math.min(firstChildBelowGap.getTranslationY(), bottom));
                int gapTop = getSectionBottomOrFinalBottom(
                        highPrioritySection, mAnimateNextSectionBoundsChange);
                gapTop = Math.max(top, Math.min(gapTop, bottom));

                int gapBottom = getSectionTopOrFinalTop(
                        lowPrioritySection, mAnimateNextSectionBoundsChange);
                gapBottom = Math.max(top, Math.min(gapBottom, bottom));

                highPrioritySection.getBounds().set(left, top, right, gapTop);
                lowPrioritySection.getBounds().set(left, gapBottom, right, bottom);
            } else if (lastChildAboveGap != null) {