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

Commit 7df4286a authored by Joshua Tsuji's avatar Joshua Tsuji
Browse files

Ensure that removing/removed views can't affect chained animations.

This is done by a) checking that indexOfChild >= 0 when chaining, since both transient and removed views will fail this test, and b) canceling animations on removed views.

Fixes: 129142553
Test: Add 25 bubbles simultaneously and then cancel them all at the same time while some are still animating in.
Change-Id: Idfa55e340debd6fb71d3dff6cd47223177f89555
parent 81a29a19
Loading
Loading
Loading
Loading
+6 −21
Original line number Original line Diff line number Diff line
@@ -226,9 +226,6 @@ public class PhysicsAnimationLayout extends FrameLayout {
    protected final HashMap<DynamicAnimation.ViewProperty, Runnable> mEndActionForProperty =
    protected final HashMap<DynamicAnimation.ViewProperty, Runnable> mEndActionForProperty =
            new HashMap<>();
            new HashMap<>();


    /** Set of currently rendered transient views. */
    private final Set<View> mTransientViews = new HashSet<>();

    /** The currently active animation controller. */
    /** The currently active animation controller. */
    private PhysicsAnimationController mController;
    private PhysicsAnimationController mController;


@@ -328,18 +325,6 @@ public class PhysicsAnimationLayout extends FrameLayout {
        removeView(getChildAt(index));
        removeView(getChildAt(index));
    }
    }


    @Override
    public void addTransientView(View view, int index) {
        super.addTransientView(view, index);
        mTransientViews.add(view);
    }

    @Override
    public void removeTransientView(View view) {
        super.removeTransientView(view);
        mTransientViews.remove(view);
    }

    /** Immediately moves the view from wherever it currently is, to the given index. */
    /** Immediately moves the view from wherever it currently is, to the given index. */
    public void moveViewTo(View view, int index) {
    public void moveViewTo(View view, int index) {
        super.removeView(view);
        super.removeView(view);
@@ -363,7 +348,9 @@ public class PhysicsAnimationLayout extends FrameLayout {
            // Tell the controller to animate this view out, and call the callback when it's
            // Tell the controller to animate this view out, and call the callback when it's
            // finished.
            // finished.
            mController.onChildRemoved(view, index, () -> {
            mController.onChildRemoved(view, index, () -> {
                // Done animating, remove the transient view.
                // The controller says it's done with the transient view, cancel animations in case
                // any are still running and then remove it.
                cancelAnimationsOnView(view);
                removeTransientView(view);
                removeTransientView(view);


                if (callback != null) {
                if (callback != null) {
@@ -470,13 +457,11 @@ public class PhysicsAnimationLayout extends FrameLayout {
            DynamicAnimation.ViewProperty property, View child, int index) {
            DynamicAnimation.ViewProperty property, View child, int index) {
        SpringAnimation newAnim = new SpringAnimation(child, property);
        SpringAnimation newAnim = new SpringAnimation(child, property);
        newAnim.addUpdateListener((animation, value, velocity) -> {
        newAnim.addUpdateListener((animation, value, velocity) -> {
            final int indexOfChild = indexOfChild(child);
            final int nextAnimInChain =
            final int nextAnimInChain =
                    mController.getNextAnimationInChain(property, indexOfChild(child));
                    mController.getNextAnimationInChain(property, indexOfChild);


            // If the controller doesn't want us to chain, or if we're a transient view in the
            if (nextAnimInChain == PhysicsAnimationController.NONE || indexOfChild < 0) {
            // process of being removed, don't chain.
            if (nextAnimInChain == PhysicsAnimationController.NONE
                    || mTransientViews.contains(child)) {
                return;
                return;
            }
            }