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

Commit fa8e4216 authored by Joshua Tsuji's avatar Joshua Tsuji
Browse files

Without modifying existing logic, animate out bubbles in reverse of the way they animate in.

Also, fixes a bug where the last bubble doesn't animate out because the stack view resizes before the animation completes.

This tries to do the same thing as ag/8943690 but without changing hasBubbles logic since that was causing issues.

Test: atest SystemUITests
Fixes: 134514227
Change-Id: I90893f1e510ebecbe26d77f2bdc0d2c9bb435548
parent 698d9e89
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -802,6 +802,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
        if (mStackView == null) {
            return;
        }

        if (mStatusBarStateListener.getCurrentState() == SHADE && hasBubbles()) {
            // Bubbles only appear in unlocked shade
            mStackView.setVisibility(hasBubbles() ? VISIBLE : INVISIBLE);
@@ -812,12 +813,23 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
        // Let listeners know if bubble state changed.
        boolean hadBubbles = mStatusBarWindowController.getBubblesShowing();
        boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE;
        mStatusBarWindowController.setBubblesShowing(hasBubblesShowing);
        if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) {
            mStateChangeListener.onHasBubblesChanged(hasBubblesShowing);
        }

        mStackView.updateContentDescription();

        // If we don't have bubbles, but there's transient bubbles, keep the stack view visible and
        // the status bar window expanded until they finish animating out.
        if (!hasBubbles() && mStackView.hasTransientBubbles()) {
            mStackView.setVisibility(VISIBLE);
            mStackView.runActionAfterTransientViewAnimations(() -> {
                mStackView.setVisibility(INVISIBLE);
                mStatusBarWindowController.setBubblesShowing(false);
            });
        } else {
            mStatusBarWindowController.setBubblesShowing(hasBubblesShowing);
        }
    }

    /**
+8 −0
Original line number Diff line number Diff line
@@ -664,6 +664,10 @@ public class BubbleStackView extends FrameLayout {
        return mIsExpanded;
    }

    void runActionAfterTransientViewAnimations(Runnable after) {
        mStackAnimationController.runActionAfterAllViewsAndTransientRemoved(after);
    }

    /**
     * The {@link BubbleView} that is expanded, null if one does not exist.
     */
@@ -694,6 +698,10 @@ public class BubbleStackView extends FrameLayout {
        }
    }

    boolean hasTransientBubbles() {
        return mBubbleContainer.getTransientViewCount() > 0;
    }

    // via BubbleData.Listener
    void addBubble(Bubble bubble) {
        if (DEBUG_BUBBLE_STACK_VIEW) {
+32 −6
Original line number Diff line number Diff line
@@ -144,6 +144,11 @@ public class StackAnimationController extends
     */
    private boolean mFirstBubbleSpringingToTouch = false;

    /**
     * Action to run after all views, including transient views, have been removed from the layout.
     */
    @Nullable private Runnable mAfterAllViewsAndTransientRemoved = null;

    /** Horizontal offset of bubbles in the stack. */
    private float mStackOffset;
    /** Diameter of the bubble icon. */
@@ -560,6 +565,14 @@ public class StackAnimationController extends
                });
    }

    /**
     * Sets an action to run after all views, including transient views, have been removed from the
     * layout.
     */
    public void runActionAfterAllViewsAndTransientRemoved(Runnable action) {
        mAfterAllViewsAndTransientRemoved = action;
    }

    /**
     * Springs the first bubble to the given final position, with the rest of the stack 'following'.
     */
@@ -647,13 +660,26 @@ public class StackAnimationController extends

    @Override
    void onChildRemoved(View child, int index, Runnable finishRemoval) {
        // Animate the removing view in the opposite direction of the stack.
        final float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X);
        animationForChild(child)
                .alpha(0f, finishRemoval /* after */)
                .scaleX(ANIMATE_IN_STARTING_SCALE)
                .scaleY(ANIMATE_IN_STARTING_SCALE)
                .translationX(mStackPosition.x - (-xOffset * ANIMATE_TRANSLATION_FACTOR))
                .alpha(0f,
                        finishRemoval /* after */,
                        () -> {
                            // If this was the last transient view, run the callback.
                            if (mLayout.getTransientViewCount() == 0
                                    && mAfterAllViewsAndTransientRemoved != null) {

                                // If a 'real' view was added while we were animating out, don't run
                                // the callback since all views haven't been removed.
                                if (mLayout.getChildCount() == 0) {
                                    mAfterAllViewsAndTransientRemoved.run();
                                }

                                mAfterAllViewsAndTransientRemoved = null;
                            }
                        } /* after */)
                .scaleX(0f)
                .scaleY(0f)
                .withStiffness(ANIMATE_IN_STIFFNESS)
                .start();

        if (mLayout.getChildCount() > 0) {
+0 −2
Original line number Diff line number Diff line
@@ -224,7 +224,6 @@ public class BubbleControllerTest extends SysuiTestCase {
        verify(mBubbleStateChangeListener).onHasBubblesChanged(true);

        mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
        assertFalse(mStatusBarWindowController.getBubblesShowing());
        assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
        verify(mNotificationEntryManager, times(2)).updateNotifications();
        verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
@@ -262,7 +261,6 @@ public class BubbleControllerTest extends SysuiTestCase {
        assertTrue(mBubbleController.hasBubbles());

        mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE);
        assertFalse(mStatusBarWindowController.getBubblesShowing());
        verify(mNotificationEntryManager, times(3)).updateNotifications();
        assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().key));
        assertNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().key));