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

Commit f4e75afd authored by Tiger's avatar Tiger
Browse files

Cancel existing insets animation if the side is changed

If the side of an insets source is changed, the coordinates will be
stale and cannot be trusted. This CL fast-forward the animation to the
end state by cancelling it.

This CL also:
- restores the logic about setting mHasPendingPosition which was removed
  accidentally in commit: ac6cde62,
- refines the logic about deciding the visible state of the animation,
  and
- fixes potential leaks of insets hints when mHasPendingPosition.

Fix: 322448072
Fix: 349901745
Flag: EXEMPT bugfix
Test: atest InsetsAnimationControlImplTest InsetsSourceConsumerTest
Change-Id: Ic83ab109ea4d486583d75b578cefad16df678666
parent cd59885b
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -221,13 +221,13 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {

    @Override
    public boolean setControl(@Nullable InsetsSourceControl control, int[] showTypes,
            int[] hideTypes) {
            int[] hideTypes, int[] cancelTypes) {
        if (Flags.refactorInsetsController()) {
            return super.setControl(control, showTypes, hideTypes);
            return super.setControl(control, showTypes, hideTypes, cancelTypes);
        } else {
            ImeTracing.getInstance().triggerClientDump("ImeInsetsSourceConsumer#setControl",
                    mController.getHost().getInputMethodManager(), null /* icProto */);
            if (!super.setControl(control, showTypes, hideTypes)) {
            if (!super.setControl(control, showTypes, hideTypes, cancelTypes)) {
                return false;
            }
            if (control == null && !mIsRequestedVisibleAwaitingLeash) {
+12 −6
Original line number Diff line number Diff line
@@ -371,6 +371,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        mPendingInsets = mLayoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN
                ? mShownInsets : mHiddenInsets;
        mPendingAlpha = 1f;
        mPendingFraction = 1f;
        applyChangeInsets(null);
        mCancelled = true;
        mListener.onCancelled(mReadyDispatched ? this : null);
@@ -486,6 +487,17 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        if (controls == null) {
            return;
        }

        final boolean visible = mPendingFraction == 0
                // The first frame of ANIMATION_TYPE_SHOW should be invisible since it is
                // animated from the hidden state.
                ? mAnimationType != ANIMATION_TYPE_SHOW
                : mPendingFraction < 1f || (mFinished
                        ? mShownOnFinish
                        // If the animation is cancelled, mFinished and mShownOnFinish are not set.
                        // Here uses mLayoutInsetsDuringAnimation to decide if it should be visible.
                        : mLayoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN);

        // TODO: Implement behavior when inset spans over multiple types
        for (int i = controls.size() - 1; i >= 0; i--) {
            final InsetsSourceControl control = controls.valueAt(i);
@@ -498,12 +510,6 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
            }
            addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);

            // The first frame of ANIMATION_TYPE_SHOW should be invisible since it is animated from
            // the hidden state.
            final boolean visible = mPendingFraction == 0
                    ? mAnimationType != ANIMATION_TYPE_SHOW
                    : !mFinished || mShownOnFinish;

            if (outState != null && source != null) {
                outState.addSource(new InsetsSource(source)
                        .setVisible(visible)
+9 −4
Original line number Diff line number Diff line
@@ -960,6 +960,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        int consumedControlCount = 0;
        final @InsetsType int[] showTypes = new int[1];
        final @InsetsType int[] hideTypes = new int[1];
        final @InsetsType int[] cancelTypes = new int[1];
        ImeTracker.Token statsToken = null;

        // Ensure to update all existing source consumers
@@ -985,7 +986,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

            // control may be null, but we still need to update the control to null if it got
            // revoked.
            consumer.setControl(control, showTypes, hideTypes);
            consumer.setControl(control, showTypes, hideTypes, cancelTypes);
        }

        // Ensure to create source consumers if not available yet.
@@ -993,7 +994,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
                final InsetsSourceControl control = mTmpControlArray.valueAt(i);
                getSourceConsumer(control.getId(), control.getType())
                        .setControl(control, showTypes, hideTypes);
                        .setControl(control, showTypes, hideTypes, cancelTypes);
            }
        }

@@ -1005,6 +1006,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        }
        mTmpControlArray.clear();

        if (cancelTypes[0] != 0) {
            cancelExistingControllers(cancelTypes[0]);
        }

        // Do not override any animations that the app started in the OnControllableInsetsChanged
        // listeners.
        int animatingTypes = invokeControllableInsetsChangedListeners();
@@ -2157,12 +2162,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                        new InsetsSourceControl(ID_IME_CAPTION_BAR, captionBar(),
                                null /* leash */, false /* initialVisible */,
                                new Point(), Insets.NONE),
                        new int[1], new int[1]);
                        new int[1], new int[1], new int[1]);
            } else {
                mState.removeSource(ID_IME_CAPTION_BAR);
                InsetsSourceConsumer sourceConsumer = mSourceConsumers.get(ID_IME_CAPTION_BAR);
                if (sourceConsumer != null) {
                    sourceConsumer.setControl(null, new int[1], new int[1]);
                    sourceConsumer.setControl(null, new int[1], new int[1], new int[1]);
                }
            }
            mHost.notifyInsetsChanged();
+8 −2
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public class InsetsSourceConsumer {

    /**
     * Updates the control delivered from the server.

     *
     * @param showTypes An integer array with a single entry that determines which types a show
     *                  animation should be run after setting the control.
     * @param hideTypes An integer array with a single entry that determines which types a hide
@@ -131,7 +131,7 @@ public class InsetsSourceConsumer {
     * @return Whether the control has changed from the server
     */
    public boolean setControl(@Nullable InsetsSourceControl control,
            @InsetsType int[] showTypes, @InsetsType int[] hideTypes) {
            @InsetsType int[] showTypes, @InsetsType int[] hideTypes, int[] cancelTypes) {
        if (Objects.equals(mSourceControl, control)) {
            if (mSourceControl != null && mSourceControl != control) {
                mSourceControl.release(SurfaceControl::release);
@@ -166,6 +166,12 @@ public class InsetsSourceConsumer {
            // Reset the applier to the default one which has the most lightweight implementation.
            setSurfaceParamsApplier(InsetsAnimationControlRunner.SurfaceParamsApplier.DEFAULT);
        } else {
            if (lastControl != null && InsetsSource.getInsetSide(lastControl.getInsetsHint())
                    != InsetsSource.getInsetSide(control.getInsetsHint())) {
                // The source has been moved to a different side. The coordinates are stale.
                // Canceling existing animation if there is any.
                cancelTypes[0] |= mType;
            }
            final boolean requestedVisible = isRequestedVisibleAwaitingControl();
            final SurfaceControl oldLeash = lastControl != null ? lastControl.getLeash() : null;
            final SurfaceControl newLeash = control.getLeash();
+2 −2
Original line number Diff line number Diff line
@@ -100,14 +100,14 @@ public class InsetsAnimationControlImplTest {
        topConsumer.setControl(
                new InsetsSourceControl(ID_STATUS_BAR, WindowInsets.Type.statusBars(),
                        mStatusLeash, true, new Point(0, 0), Insets.of(0, 100, 0, 0)),
                new int[1], new int[1]);
                new int[1], new int[1], new int[1]);

        InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(ID_NAVIGATION_BAR,
                WindowInsets.Type.navigationBars(), mInsetsState, mMockController);
        navConsumer.setControl(
                new InsetsSourceControl(ID_NAVIGATION_BAR, WindowInsets.Type.navigationBars(),
                        mNavLeash, true, new Point(400, 0), Insets.of(0, 0, 100, 0)),
                new int[1], new int[1]);
                new int[1], new int[1], new int[1]);
        mMockController.setRequestedVisibleTypes(0, WindowInsets.Type.navigationBars());
        navConsumer.applyLocalVisibilityOverride();

Loading