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

Commit 77935600 authored by Johannes Gallmann's avatar Johannes Gallmann Committed by Android (Google) Code Review
Browse files

Merge "Prevent IME predictive back control during hide anim" into main

parents 6c00ad0a a0e471c1
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1307,7 +1307,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            WindowInsetsAnimationControlListener listener,
            boolean fromIme, long durationMs, @Nullable Interpolator interpolator,
            @AnimationType int animationType, boolean fromPredictiveBack) {
        if ((mState.calculateUncontrollableInsetsFromFrame(mFrame) & types) != 0) {
        if ((mState.calculateUncontrollableInsetsFromFrame(mFrame) & types) != 0
                || (fromPredictiveBack && ((mRequestedVisibleTypes & ime()) == 0))) {
            // abort if insets are uncontrollable or if control request is from predictive back but
            // there is already a hide anim in progress
            listener.onCancelled(null);
            return;
        }
+31 −0
Original line number Diff line number Diff line
@@ -1131,6 +1131,37 @@ public class InsetsControllerTest {
        });
    }

    @Test
    public void testPredictiveBackControlRequestCancelledDuringImeHideAnim() {
        prepareControls();
        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
            // show ime as initial state
            if (!Flags.refactorInsetsController()) {
                mController.show(ime(), true /* fromIme */, ImeTracker.Token.empty());
            } else {
                mController.show(ime(), false /* fromIme */, ImeTracker.Token.empty());
            }
            mController.cancelExistingAnimations(); // fast forward show animation
            mViewRoot.getView().getViewTreeObserver().dispatchOnPreDraw();
            assertTrue(mController.getState().peekSource(ID_IME).isVisible());

            // start IME hide animation
            mController.hide(ime(), true /* fromIme */, null /* statsToken */);
            assertEquals(ANIMATION_TYPE_HIDE, mController.getAnimationType(ime()));

            // start control request (for predictive back animation)
            WindowInsetsAnimationControlListener listener =
                    mock(WindowInsetsAnimationControlListener.class);
            mController.controlWindowInsetsAnimation(ime(), /*cancellationSignal*/ null,
                    listener, /*fromIme*/ false, /*duration*/ -1, /*interpolator*/ null,
                    ANIMATION_TYPE_USER, /*fromPredictiveBack*/ true);

            // verify that control request is cancelled and animation type remains HIDE
            verify(listener).onCancelled(any());
            assertEquals(ANIMATION_TYPE_HIDE, mController.getAnimationType(ime()));
        });
    }

    private void waitUntilNextFrame() throws Exception {
        final CountDownLatch latch = new CountDownLatch(1);
        Choreographer.getMainThreadInstance().postCallback(Choreographer.CALLBACK_COMMIT,