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

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

Merge "Removing IMS surface in InputMethodService#hideSoftInput after hiding the window" into main

parents 793ae050 5edf6c37
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -990,6 +990,8 @@ public class InputMethodService extends AbstractInputMethodService {
            }
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            if (android.view.inputmethod.Flags.refactorInsetsController()) {
                // After the IME window was hidden, we can remove its surface
                scheduleImeSurfaceRemoval();
                // The hide request first finishes the animation and then proceeds to the server
                // side, finally reaching here, marking this the end state.
                ImeTracker.forLogging().onHidden(statsToken);
+5 −1
Original line number Diff line number Diff line
@@ -1299,8 +1299,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            // Handle the pending show request for other insets types since the IME insets
            // has being requested hidden.
            handlePendingControlRequest(statsToken);
            if (!Flags.refactorInsetsController()) {
                // the surface can't be removed until the end of the animation. This is handled by
                // IMMS after the window was requested to be hidden.
                getImeSourceConsumer().removeSurface();
            }
        }
        applyAnimation(typesReady, false /* show */, fromIme, false /* skipsCallbacks */,
                statsToken);
    }
+3 −1
Original line number Diff line number Diff line
@@ -230,7 +230,9 @@ public class InsetsSourceConsumerTest {
                    new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash,
                            false /* initialVisible */, new Point(), Insets.NONE),
                    new int[1], hideTypes, new int[1], new int[1]);
            if (!android.view.inputmethod.Flags.refactorInsetsController()) {
                assertTrue(mRemoveSurfaceCalled);
            }
            assertEquals(0, hideTypes[0]);
        });

+7 −3
Original line number Diff line number Diff line
@@ -324,10 +324,12 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
                        }
                        applyVisibilityToLeash(imeSourceControl);
                    }
                    if (!android.view.inputmethod.Flags.refactorInsetsController()) {
                        if (!mImeShowing) {
                            removeImeSurface(mDisplayId);
                        }
                    }
                }
            } else {
                if (!android.view.inputmethod.Flags.refactorInsetsController()
                        && mAnimation != null) {
@@ -663,7 +665,9 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
                        ImeTracker.forLogging().onProgress(mStatsToken,
                                ImeTracker.PHASE_WM_ANIMATION_RUNNING);
                        t.hide(animatingLeash);
                        if (!android.view.inputmethod.Flags.refactorInsetsController()) {
                            removeImeSurface(mDisplayId);
                        }
                        if (android.view.inputmethod.Flags.refactorInsetsController()) {
                            setVisibleDirectly(false /* visible */, statsToken);
                        }
+60 −0
Original line number Diff line number Diff line
@@ -40,10 +40,14 @@ import android.content.res.Configuration;
import android.graphics.Insets;
import android.os.Build;
import android.os.RemoteException;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import android.server.wm.WindowManagerStateHelper;
import android.util.Log;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
import android.view.WindowManagerGlobal;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.Flags;
@@ -72,6 +76,7 @@ import org.junit.Test;
import org.junit.rules.TestName;
import org.junit.runner.RunWith;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -244,6 +249,61 @@ public class InputMethodServiceTest {
                EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown");
    }

    /**
     * This checks that the surface is removed after the window was hidden in
     * InputMethodService#hideSoftInput
     */
    @Test
    @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
    public void testSurfaceRemovedAfterHideSoftInput() {
        setShowImeWithHardKeyboard(true /* enabled */);

        // Triggers to show IME via public API.
        verifyInputViewStatusOnMainSync(() -> mActivity.showImeWithWindowInsetsController(),
                EVENT_SHOW, true /* eventExpected */, true /* shown */, "IME is shown");
        assertWithMessage("IME is shown").that(mInputMethodService.isInputViewShown()).isTrue();

        final var window = mInputMethodService.getWindow().getWindow();
        assertWithMessage("IME window exists").that(window).isNotNull();
        assertWithMessage("IME window showing").that(
                window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE);

        mActivity.getWindow().getDecorView().setWindowInsetsAnimationCallback(
                new WindowInsetsAnimation.Callback(
                        WindowInsetsAnimation.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE) {
                    @NonNull
                    @Override
                    public WindowInsetsAnimation.Bounds onStart(
                            @NonNull WindowInsetsAnimation animation,
                            @NonNull WindowInsetsAnimation.Bounds bounds) {
                        return super.onStart(animation, bounds);
                    }

                    @NonNull
                    @Override
                    public WindowInsets onProgress(@NonNull WindowInsets insets,
                            @NonNull List<WindowInsetsAnimation> runningAnimations) {
                        assertWithMessage("IME surface not removed during the animation").that(
                                window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE);
                        return insets;
                    }

                    @Override
                    public void onEnd(@NonNull WindowInsetsAnimation animation) {
                        assertWithMessage(
                                "IME surface not removed before the end of the animation").that(
                                window.getDecorView().getVisibility()).isEqualTo(View.VISIBLE);
                        super.onEnd(animation);
                    }
                });

        // Triggers to hide IME via public API.
        verifyInputViewStatusOnMainSync(() -> mActivity.hideImeWithWindowInsetsController(),
                EVENT_HIDE, true /* eventExpected */, false /* shown */, "IME is not shown");
        eventually(() -> assertWithMessage("IME window not showing").that(
                window.getDecorView().getVisibility()).isEqualTo(View.GONE));
    }

    /**
     * This checks the result of calling IMS#requestShowSelf and IMS#requestHideSelf.
     */