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

Commit de595bc2 authored by Ming-Shin Lu's avatar Ming-Shin Lu Committed by Android (Google) Code Review
Browse files

Merge changes Ib7baf280,Id3aebca3

* changes:
  Remove TODO in InputMethodStressTest
  Fix WIC#hide(ime()) no-op after WIC#show(ime()) in Activity#onCreate
parents 04010075 c49c7b45
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
                ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_NOTIFY_HIDDEN);

        getImm().notifyImeHidden(mController.getHost().getWindowToken(), statsToken);
        mIsRequestedVisibleAwaitingControl = false;
        Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
    }

+47 −14
Original line number Diff line number Diff line
@@ -552,7 +552,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            this.useInsetsAnimationThread = useInsetsAnimationThread;
        }

        final @InsetsType int types;
        @InsetsType int types;
        final WindowInsetsAnimationControlListener listener;
        final long durationMs;
        final Interpolator interpolator;
@@ -1006,19 +1006,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        }
        // Handle pending request ready in case there was one set.
        if (fromIme && mPendingImeControlRequest != null) {
            PendingControlRequest pendingRequest = mPendingImeControlRequest;
            mPendingImeControlRequest = null;
            mHandler.removeCallbacks(mPendingControlTimeout);

            // We are about to playing the default animation. Passing a null frame indicates the
            // controlled types should be animated regardless of the frame.
            controlAnimationUnchecked(
                    pendingRequest.types, pendingRequest.cancellationSignal,
                    pendingRequest.listener, null /* frame */,
                    true /* fromIme */, pendingRequest.durationMs, pendingRequest.interpolator,
                    pendingRequest.animationType,
                    pendingRequest.layoutInsetsDuringAnimation,
                    pendingRequest.useInsetsAnimationThread, statsToken);
            handlePendingControlRequest(statsToken);
            return;
        }

@@ -1061,6 +1049,27 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        applyAnimation(typesReady, true /* show */, fromIme, statsToken);
    }

    /**
     * Handle the {@link #mPendingImeControlRequest} when
     * - The IME insets is ready to show.
     * - The IME insets has being requested invisible.
     */
    private void handlePendingControlRequest(@Nullable ImeTracker.Token statsToken) {
        PendingControlRequest pendingRequest = mPendingImeControlRequest;
        mPendingImeControlRequest = null;
        mHandler.removeCallbacks(mPendingControlTimeout);

        // We are about to playing the default animation. Passing a null frame indicates the
        // controlled types should be animated regardless of the frame.
        controlAnimationUnchecked(
                pendingRequest.types, pendingRequest.cancellationSignal,
                pendingRequest.listener, null /* frame */,
                true /* fromIme */, pendingRequest.durationMs, pendingRequest.interpolator,
                pendingRequest.animationType,
                pendingRequest.layoutInsetsDuringAnimation,
                pendingRequest.useInsetsAnimationThread, statsToken);
    }

    @Override
    public void hide(@InsetsType int types) {
        ImeTracker.Token statsToken = null;
@@ -1084,6 +1093,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
        }
        int typesReady = 0;
        boolean hasImeRequestedHidden = false;
        final boolean hadPendingImeControlRequest = mPendingImeControlRequest != null;
        for (int type = FIRST; type <= LAST; type = type << 1) {
            if ((types & type) == 0) {
                continue;
@@ -1091,6 +1102,22 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            @AnimationType final int animationType = getAnimationType(type);
            final boolean requestedVisible = (type & mRequestedVisibleTypes) != 0;
            final boolean isImeAnimation = type == ime();
            if (mPendingImeControlRequest != null && !requestedVisible) {
                // Remove the hide insets type from the pending show request.
                mPendingImeControlRequest.types &= ~type;
                if (mPendingImeControlRequest.types == 0) {
                    abortPendingImeControlRequest();
                }
            }
            if (isImeAnimation && !requestedVisible && animationType == ANIMATION_TYPE_NONE) {
                hasImeRequestedHidden = true;
                // Ensure to request hide IME in case there is any pending requested visible
                // being applied from setControl when receiving the insets control.
                if (hadPendingImeControlRequest
                        || getImeSourceConsumer().isRequestedVisibleAwaitingControl()) {
                    getImeSourceConsumer().requestHide(fromIme, statsToken);
                }
            }
            if (!requestedVisible && animationType == ANIMATION_TYPE_NONE
                    || animationType == ANIMATION_TYPE_HIDE) {
                // no-op: already hidden or animating out (because window visibility is
@@ -1106,6 +1133,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
            }
            typesReady |= type;
        }
        if (hasImeRequestedHidden && mPendingImeControlRequest != null) {
            // Handle the pending show request for other insets types since the IME insets has being
            // requested hidden.
            handlePendingControlRequest(statsToken);
            getImeSourceConsumer().removeSurface();
        }
        applyAnimation(typesReady, false /* show */, fromIme, statsToken);
    }

+34 −8
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.inputmethod.stresstest;

import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;

import static com.android.inputmethod.stresstest.ImeStressTestUtil.INPUT_METHOD_MANAGER_HIDE_ON_CREATE;
import static com.android.inputmethod.stresstest.ImeStressTestUtil.INPUT_METHOD_MANAGER_SHOW_ON_CREATE;
import static com.android.inputmethod.stresstest.ImeStressTestUtil.REQUEST_FOCUS_ON_CREATE;
@@ -209,8 +211,23 @@ public final class ImeOpenCloseStressTest {
        verifyShowBehavior(activity);
    }

    /**
     * Test IME hidden by calling show and hide IME consecutively with
     * {@link android.view.inputmethod.InputMethodManager} APIs in
     * {@link android.app.Activity#onCreate}.
     *
     * <p> Note for developers: Use {@link WindowManager.LayoutParams#SOFT_INPUT_STATE_UNCHANGED}
     * window flag to avoid some softInputMode visibility flags may take presence over
     * {@link android.view.inputmethod.InputMethodManager} APIs (e.g. use showSoftInput to show
     * IME in {@link android.app.Activity#onCreate} but being hidden by
     * {@link WindowManager.LayoutParams#SOFT_INPUT_STATE_ALWAYS_HIDDEN} window flag after the
     * activity window focused).</p>
     */
    @Test
    public void testShowHideWithInputMethodManager_onCreate() {
        if (mSoftInputFlags != SOFT_INPUT_STATE_UNCHANGED) {
            return;
        }
        // Show and hide with InputMethodManager at onCreate()
        Intent intent =
                createIntent(
@@ -222,10 +239,7 @@ public final class ImeOpenCloseStressTest {
                                INPUT_METHOD_MANAGER_HIDE_ON_CREATE));
        TestActivity activity = TestActivity.start(intent);

        // TODO: The Ime is expected to show first and then hide. But show or hide
        // with InputMethodManager at onCreate() would always fail because the window
        // has not gained focus, so the actual behavior will be the same as auto-show.
        // verifyHideBehavior(activity);
        verifyHideBehavior(activity);
    }

    @Test
@@ -352,8 +366,7 @@ public final class ImeOpenCloseStressTest {
        // Wait until IMMS / IMS handles messages.
        SystemClock.sleep(1000);
        mInstrumentation.waitForIdleSync();
        // TODO(b/248456059): Ime should be hidden but is shown.
        // verifyHideBehavior(activity);
        verifyHideBehavior(activity);

        mInstrumentation.runOnMainSync(activity::showImeWithWindowInsetsController);
        verifyShowBehavior(activity);
@@ -420,11 +433,25 @@ public final class ImeOpenCloseStressTest {
        verifyShowBehaviorNotRequestFocus(activity);
    }

    /**
     * Test IME hidden by calling show and hide IME consecutively with
     * {@link android.view.WindowInsetsController} APIs in {@link android.app.Activity#onCreate}.
     *
     * <p> Note for developers: Use {@link WindowManager.LayoutParams#SOFT_INPUT_STATE_UNCHANGED}
     * window flag to avoid some softInputMode visibility flags may take presence over
     * {@link android.view.WindowInsetsController} APIs (e.g. use showSoftInput to show
     * IME in {@link android.app.Activity#onCreate} but being hidden by
     * {@link WindowManager.LayoutParams#SOFT_INPUT_STATE_ALWAYS_HIDDEN} window flag after the
     * activity window focused).</p>
     */
    @Test
    public void testHideWithWindowInsetsController_onCreate_requestFocus() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
            return;
        }
        if (mSoftInputFlags != SOFT_INPUT_STATE_UNCHANGED) {
            return;
        }
        // Show and hide with InputMethodManager at onCreate()
        Intent intent =
                createIntent(
@@ -436,8 +463,7 @@ public final class ImeOpenCloseStressTest {
                                WINDOW_INSETS_CONTROLLER_HIDE_ON_CREATE));
        TestActivity activity = TestActivity.start(intent);

        // TODO(b/248456059): Ime should be hidden but is shown.
        //verifyHideBehavior(activity);
        verifyHideBehavior(activity);
    }

    @Test