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

Commit a9bce5b1 authored by Ats Jenk's avatar Ats Jenk
Browse files

Clean up StackAnimationController when bubbles removed

Fixes a memory leak with StackAnimationController not being removed from
shell singleton FloatingContentCoordinator.

StackAnimationController registers a FloatingContent instance in
FloatingContentCoordinator when the first bubble is added.
FloatingContent is an inner class of StackAnimationController and will
hold a ref to the parent object.

StackAnimationController unregisters the FloatContent instance when the
last bubble is removed. For StackAnimationController to receive this
information, it has to the active controller for the BubbleStackView
PhysicsAnimationLayout.

When bubbles are expanded, StackAnimationController is not the active
controller. And it will not receive callbacks that a bubble view is
removed.
This means that it never unregisters the FloatinContent instance from
FloatingContentCoordinator singleton.

Updating the logic expose a new method from StackAnimationController so
it can be notified explicitly when the last bubble is removed.
Updating BubbleStackView to always notify StackAnimationController, even
if it is not the active controller (bubbles expanded), that the last
bubble has been removed.
When StackAnimationController is notified that the last bubble is
removed, it will unregister the FloatingContent from
FloatingContentCoordinator.

Bug: 432211683
Test: atest WMShellUnitTests:StackAnimationControllerTest
Flag: EXEMPT, bugfix
Change-Id: I3b938132685530e4641211a93ebfc4615798bc96
parent 9301bb86
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -2177,6 +2177,9 @@ public class BubbleStackView extends FrameLayout
            // bubble window so do that at the end of the animation so we see the scrim animate).
            BadgedImageView iconView = bubble.getIconView();
            final BubbleViewProvider expandedBubbleBeforeScrim = mExpandedBubble;
            // Notify the stack anim controller before running the scrim animation. In case
            // another bubble gets added during it.
            mStackAnimationController.onLastBubbleRemoved();
            showScrim(false, () -> {
                mRemovingLastBubbleWhileExpanded = false;
                bubble.cleanupExpandedView();
@@ -2201,6 +2204,7 @@ public class BubbleStackView extends FrameLayout
            return;
        } else if (getBubbleCount() == 1) {
            mExpandedBubble = null;
            mStackAnimationController.onLastBubbleRemoved();
        }
        // Remove it from the views
        for (int i = 0; i < getBubbleCount(); i++) {
+7 −4
Original line number Diff line number Diff line
@@ -425,6 +425,13 @@ public class StackAnimationController extends
        return stackPos;
    }

    /**
     * Clean up state when all bubbles have been removed
     */
    public void onLastBubbleRemoved() {
        mFloatingContentCoordinator.onContentRemoved(mStackFloatingContent);
    }

    /** Description of current animation controller state. */
    public void dump(PrintWriter pw) {
        pw.println("StackAnimationController state:");
@@ -749,10 +756,6 @@ public class StackAnimationController extends
        } else {
            // When all children are removed ensure stack position is sane
            mPositioner.setRestingPosition(mPositioner.getRestingPosition());

            // Remove the stack from the coordinator since we don't have any bubbles and aren't
            // visible.
            mFloatingContentCoordinator.onContentRemoved(mStackFloatingContent);
        }
    }

+4 −0
Original line number Diff line number Diff line
@@ -261,6 +261,10 @@ public class StackAnimationControllerTest extends PhysicsAnimationLayoutTestCase
            mLayout.removeView(mLayout.getChildAt(0));
        }

        // FloatingContentCoordinator only reacts to onLastBubbleRemoved
        verify(mFloatingContentCoordinator, never()).onContentRemoved(any());

        mStackController.onLastBubbleRemoved();
        verify(mFloatingContentCoordinator, times(1)).onContentRemoved(any());
    }