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

Commit a79b8851 authored by Adrian Roos's avatar Adrian Roos
Browse files

InsetsController: Add missing onWindowInsetsAnimationEnd when cancelling

Fixes a few issues around cancelling insets animations:

- dispatch the onEnd callback when the animation gets cancelled
- When using the CancellationSignal, we need to properly cancel the
  animation, and not just the controller - otherwise we never actually
  remove it from mRunningAnimations.
- Now that cancellation dispatches to apps, make sure they do not
  restart a different animation of the same type we just cancelled

Bug: 156740834
Test: atest WindowInsetsAnimationControllerTests
Change-Id: I4c36470a816ff8e3b92cd03090b8e947a2234f13
parent b0033693
Loading
Loading
Loading
Loading
+27 −8
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@ import java.util.function.BiFunction;
 */
public class InsetsController implements WindowInsetsController, InsetsAnimationControlCallbacks {

    private int mTypesBeingCancelled;

    public interface Host {

        Handler getHandler();
@@ -778,6 +780,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            @AnimationType int animationType,
            @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
            boolean useInsetsAnimationThread) {
        if ((types & mTypesBeingCancelled) != 0) {
            throw new IllegalStateException("Cannot start a new insets animation of "
                    + Type.toString(types)
                    + " while an existing " + Type.toString(mTypesBeingCancelled)
                    + " is being cancelled.");
        }
        if (types == 0) {
            // nothing to animate.
            listener.onCancelled(null);
@@ -827,7 +835,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                        animationType);
        mRunningAnimations.add(new RunningAnimation(runner, animationType));
        if (cancellationSignal != null) {
            cancellationSignal.setOnCancelListener(runner::cancel);
            cancellationSignal.setOnCancelListener(() -> {
                cancelAnimation(runner, true /* invokeCallback */);
            });
        }
        if (layoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN) {
            showDirectly(types);
@@ -915,6 +925,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    }

    private void cancelExistingControllers(@InsetsType int types) {
        final int originalmTypesBeingCancelled = mTypesBeingCancelled;
        mTypesBeingCancelled |= types;
        try {
            for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
                InsetsAnimationControlRunner control = mRunningAnimations.get(i).runner;
                if ((control.getTypes() & types) != 0) {
@@ -924,6 +937,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            if ((types & ime()) != 0) {
                abortPendingImeControlRequest();
            }
        } finally {
            mTypesBeingCancelled = originalmTypesBeingCancelled;
        }
    }

    private void abortPendingImeControlRequest() {
@@ -977,6 +993,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                        mHost.notifyInsetsChanged();
                    }
                }
                if (invokeCallback && runningAnimation.startDispatched) {
                    dispatchAnimationEnd(runningAnimation.runner.getAnimation());
                }
                break;
            }
        }