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

Commit 0df20006 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Iff275d7d,I8cb1c7fb into main

* changes:
  Disable IME predictive back animation in multi-window mode
  Don't play pre-commit velocity slow-down for IME predictive back animation
parents 7150df0d 5d6053e4
Loading
Loading
Loading
Loading
+22 −11
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.graphics.Insets;
import android.util.Log;
import android.view.animation.BackGestureInterpolator;
@@ -137,9 +138,10 @@ public class ImeBackAnimationController implements OnBackAnimationCallback {
    @Override
    public void onBackInvoked() {
        if (!isBackAnimationAllowed() || !mIsPreCommitAnimationInProgress) {
            // play regular hide animation if back-animation is not allowed or if insets control has
            // been cancelled by the system (this can happen in split screen for example)
            mInsetsController.hide(ime());
            // play regular hide animation if predictive back-animation is not allowed or if insets
            // control has been cancelled by the system. This can happen in multi-window mode for
            // example (i.e. split-screen or activity-embedding)
            notifyHideIme();
            return;
        }
        startPostCommitAnim(/*hideIme*/ true);
@@ -209,6 +211,11 @@ public class ImeBackAnimationController implements OnBackAnimationCallback {
        if (triggerBack) {
            mInsetsController.setPredictiveBackImeHideAnimInProgress(true);
            notifyHideIme();
            // requesting IME as invisible during post-commit
            mInsetsController.setRequestedVisibleTypes(0, ime());
            // Changes the animation state. This also notifies RootView of changed insets, which
            // causes it to reset its scrollY to 0f (animated) if it was panned
            mInsetsController.onAnimationStateChanged(ime(), /*running*/ true);
        }
        if (mStartRootScrollY != 0 && !triggerBack) {
            // This causes RootView to update its scroll back to the panned position
@@ -228,12 +235,6 @@ public class ImeBackAnimationController implements OnBackAnimationCallback {
        // the IME away
        mInsetsController.getHost().getInputMethodManager()
                .notifyImeHidden(mInsetsController.getHost().getWindowToken(), statsToken);

        // requesting IME as invisible during post-commit
        mInsetsController.setRequestedVisibleTypes(0, ime());
        // Changes the animation state. This also notifies RootView of changed insets, which causes
        // it to reset its scrollY to 0f (animated) if it was panned
        mInsetsController.onAnimationStateChanged(ime(), /*running*/ true);
    }

    private void reset() {
@@ -254,8 +255,18 @@ public class ImeBackAnimationController implements OnBackAnimationCallback {
    }

    private boolean isBackAnimationAllowed() {
        // back animation is allowed in all cases except when softInputMode is adjust_resize AND
        // there is no app-registered WindowInsetsAnimationCallback AND edge-to-edge is not enabled.

        if (mViewRoot.mContext.getResources().getConfiguration().windowConfiguration
                .getWindowingMode() == WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW) {
            // TODO(b/346726115) enable predictive back animation in multi-window mode in
            //  DisplayImeController
            return false;
        }

        // otherwise, the predictive back animation is allowed in all cases except when
        // 1. softInputMode is adjust_resize AND
        // 2. there is no app-registered WindowInsetsAnimationCallback AND
        // 3. edge-to-edge is not enabled.
        return (mViewRoot.mWindowAttributes.softInputMode & SOFT_INPUT_MASK_ADJUST)
                != SOFT_INPUT_ADJUST_RESIZE
                || (mViewRoot.mView != null && mViewRoot.mView.hasWindowInsetsAnimationCallback())
+2 −1
Original line number Diff line number Diff line
@@ -489,7 +489,8 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
                    return;
                }
                OnBackAnimationCallback animationCallback = getBackAnimationCallback();
                if (animationCallback != null) {
                if (animationCallback != null
                        && !(callback instanceof ImeBackAnimationController)) {
                    mProgressAnimator.onBackInvoked(callback::onBackInvoked);
                } else {
                    mProgressAnimator.reset();
+28 −5
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;

import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Insets;
import android.platform.test.annotations.Presubmit;
@@ -102,6 +103,8 @@ public class ImeBackAnimationControllerTest {
            mViewRoot.setOnContentApplyWindowInsetsListener(
                    mock(Window.OnContentApplyWindowInsetsListener.class));
            mBackAnimationController = new ImeBackAnimationController(mViewRoot, mInsetsController);
            mViewRoot.mContext.getResources().getConfiguration().windowConfiguration
                    .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);

            when(mWindowInsetsAnimationController.getHiddenStateInsets()).thenReturn(Insets.NONE);
            when(mWindowInsetsAnimationController.getShownStateInsets()).thenReturn(IME_INSETS);
@@ -156,8 +159,28 @@ public class ImeBackAnimationControllerTest {
        mBackAnimationController.onBackProgressed(new BackEvent(100f, 0f, 0.5f, EDGE_LEFT));
        // commit back gesture
        mBackAnimationController.onBackInvoked();
        // verify that InsetsController#hide is called
        verify(mInsetsController, times(1)).hide(ime());
        // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
        // getInputMethodManager is called from ImeBackAnimationController)
        verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
        // verify that ImeBackAnimationController does not take control over IME insets
        verify(mInsetsController, never()).controlWindowInsetsAnimation(anyInt(), any(), any(),
                anyBoolean(), anyLong(), any(), anyInt(), anyBoolean());
    }

    @Test
    public void testMultiWindowModeNotPlayingAnim() {
        // setup ViewRoot with WINDOWING_MODE_MULTI_WINDOW
        mViewRoot.mContext.getResources().getConfiguration().windowConfiguration.setWindowingMode(
                WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
        // start back gesture
        mBackAnimationController.onBackStarted(new BackEvent(0f, 0f, 0f, EDGE_LEFT));
        // progress back gesture
        mBackAnimationController.onBackProgressed(new BackEvent(100f, 0f, 0.5f, EDGE_LEFT));
        // commit back gesture
        mBackAnimationController.onBackInvoked();
        // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
        // getInputMethodManager is called from ImeBackAnimationController)
        verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
        // verify that ImeBackAnimationController does not take control over IME insets
        verify(mInsetsController, never()).controlWindowInsetsAnimation(anyInt(), any(), any(),
                anyBoolean(), anyLong(), any(), anyInt(), anyBoolean());
@@ -277,9 +300,9 @@ public class ImeBackAnimationControllerTest {

            // commit back gesture
            mBackAnimationController.onBackInvoked();

            // verify that InsetsController#hide is called
            verify(mInsetsController, times(1)).hide(ime());
            // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
            // getInputMethodManager is called from ImeBackAnimationController)
            verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
        });
    }