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

Commit 48441703 authored by Kohsuke Yatoh's avatar Kohsuke Yatoh
Browse files

Notify IMMS synchronously on IME insets hidden.

Currently, IMMS will be notified asynchronously when an IME hide
animation finishes, via message dispatching through IMS
(IMM#notifyImeHidden -> IMS#notifyImeHidden -> IMMS#hideMySoftInput).
This creates a race condition when IMM#showSoftInput or WIC#show is
called around the end of hide animation.

This CL fixes the race condition by synchronously and directly
calling IMMS#hideSoftInput from IMM#notifyImeHidden.

Note that there is still another race condition for IMM#showSoftInput
(not WIC#show) if it's called during an IME hide animation;
IMM#showSoftInput ended up calling WIC#show asynchronously, but at that
time the running IME hide animation may have already been finished
successfully and WIC#show may fail to cancel the hide animation
(then the cleanup IMM#notifyImeHidden hides the IME again disruptively).
I will fix the latter issue in a separate CL.

Bug: 221483132
Bug: 225674038
Test: atest InputMethodStressTest
Test: atest CtsInputMethodTestCases
Test: atest WindowInsetsAnimationControllerTests
Change-Id: I7c71dc5a1d6b61aa79d1666f0e257e6401e4adb2
(cherry picked from commit 9065310f)
Merged-In: I7c71dc5a1d6b61aa79d1666f0e257e6401e4adb2
parent 6584dbb6
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
    private static final int DO_APP_PRIVATE_COMMAND = 100;
    private static final int DO_FINISH_SESSION = 110;
    private static final int DO_VIEW_CLICKED = 115;
    private static final int DO_NOTIFY_IME_HIDDEN = 120;
    private static final int DO_REMOVE_IME_SURFACE = 130;
    private static final int DO_FINISH_INPUT = 140;
    private static final int DO_INVALIDATE_INPUT = 150;
@@ -133,10 +132,6 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
                mInputMethodSession.viewClicked(msg.arg1 == 1);
                return;
            }
            case DO_NOTIFY_IME_HIDDEN: {
                mInputMethodSession.notifyImeHidden();
                return;
            }
            case DO_REMOVE_IME_SURFACE: {
                mInputMethodSession.removeImeSurface();
                return;
@@ -197,11 +192,6 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
                mCaller.obtainMessageI(DO_VIEW_CLICKED, focusChanged ? 1 : 0));
    }

    @Override
    public void notifyImeHidden() {
        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_NOTIFY_IME_HIDDEN));
    }

    @Override
    public void removeImeSurface() {
        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_IME_SURFACE));
+0 −12
Original line number Diff line number Diff line
@@ -1058,10 +1058,6 @@ public class InputMethodService extends AbstractInputMethodService {
        return viewRoot == null ? null : viewRoot.getInputToken();
    }

    private void notifyImeHidden() {
        requestHideSelf(0);
    }

    private void scheduleImeSurfaceRemoval() {
        if (mShowInputRequested || mWindowVisible || mWindow == null
                || mImeSurfaceScheduledForRemoval) {
@@ -1224,14 +1220,6 @@ public class InputMethodService extends AbstractInputMethodService {
            InputMethodService.this.onUpdateCursorAnchorInfo(info);
        }

        /**
         * Notify IME that window is hidden.
         * @hide
         */
        public final void notifyImeHidden() {
            InputMethodService.this.notifyImeHidden();
        }

        /**
         * Notify IME that surface can be now removed.
         * @hide
+2 −2
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import static android.view.InsetsController.AnimationType;
import static android.view.InsetsState.ITYPE_IME;

import android.annotation.Nullable;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.Trace;
import android.util.proto.ProtoOutputStream;
@@ -104,7 +103,8 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    }

    /**
     * Notify {@link InputMethodService} that IME window is hidden.
     * Notify {@link com.android.server.inputmethod.InputMethodManagerService} that
     * IME insets are hidden.
     */
    @Override
    void notifyHidden() {
+8 −2
Original line number Diff line number Diff line
@@ -2521,7 +2521,7 @@ public final class InputMethodManager {
    }

    /**
     * Notify IME directly that it is no longer visible.
     * Notify IMMS that IME insets are no longer visible.
     *
     * @param windowToken the window from which this request originates. If this doesn't match the
     *                    currently served view, the request is ignored.
@@ -2533,7 +2533,13 @@ public final class InputMethodManager {
        synchronized (mH) {
            if (mCurrentInputMethodSession != null && mCurRootView != null
                    && mCurRootView.getWindowToken() == windowToken) {
                mCurrentInputMethodSession.notifyImeHidden();
                try {
                    mService.hideSoftInput(mClient, windowToken, 0 /* flags */,
                            null /* resultReceiver */,
                            SoftInputShowHideReason.HIDE_SOFT_INPUT);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
        }
    }
+0 −7
Original line number Diff line number Diff line
@@ -194,13 +194,6 @@ public interface InputMethodSession {
     */
    public void updateCursorAnchorInfo(CursorAnchorInfo cursorAnchorInfo);

    /**
     * Notifies {@link android.inputmethodservice.InputMethodService} that IME has been
     * hidden from user.
     * @hide
     */
    public void notifyImeHidden();

    /**
     * Notify IME directly to remove surface as it is no longer visible.
     * @hide
Loading