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

Commit dfca56d7 authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

Fix unexpected IME switcher dialog hidden

Previous CL[1] gives a wrong signal for IMMS might thought the IME
surface parent has changed by transfering to the new IME control
target, but actually that signal mixtured the forcing IME parent
flag, so IME switcher dialog may hidden in such misleading way.

Also, in WM didn't consider the control change might related
to the app is relaunching case, and it's the intermediate state we
should not report to IMMS for this misleading control changed signal.
(i.e. in WindowState#removeImmediately, if the window is during
relaunching and we should not set null IME input target to affect
DC#updateImeParent)

[1]: Iae3dd713b1e980067d28debea4e0a03707aa7938

Fix: 224998014
Fix: 215448483
Fix: 227553661
Test: manul as below steps:
1)  Installed alternate keyboard app (swift keyboard).
2). From all apps > Tap on search > Keyboard pops up
    > Swipe up navigation to exit all apps.
3). From all apps > Open Settings > Tap on Search > Keyboard pops up
    > Tap on switch input button on navigation and observing.
4). Expect IME switcher dialog should be shown and not be dismissed.

Change-Id: Ib0813e2c12909ede4e582eb3499599e3cc253490
parent 3fda2bf2
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -133,10 +133,13 @@ public abstract class InputMethodManagerInternal {
     *
     * @param windowToken the window token that is now in control, or {@code null} if no client
     *                   window is in control of the IME.
     * @param imeParentChanged {@code true} when the window manager thoughts the IME surface parent
     *                         will end up to change later, or {@code false} otherwise.
     */
    public abstract void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged);
    public abstract void reportImeControl(@Nullable IBinder windowToken);

    /**
     * Indicates that the IME window has re-parented to the new target when the IME control changed.
     */
    public abstract void onImeParentChanged();

    /**
     * Destroys the IME surface.
@@ -226,8 +229,11 @@ public abstract class InputMethodManagerInternal {
                }

                @Override
                public void reportImeControl(@Nullable IBinder windowToken,
                        boolean imeParentChanged) {
                public void reportImeControl(@Nullable IBinder windowToken) {
                }

                @Override
                public void onImeParentChanged() {
                }

                @Override
+11 −7
Original line number Diff line number Diff line
@@ -5620,21 +5620,25 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
        }

        @Override
        public void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged) {
        public void reportImeControl(@Nullable IBinder windowToken) {
            synchronized (ImfLock.class) {
                if (mCurFocusedWindow != windowToken) {
                    // mCurPerceptible was set by the focused window, but it is no longer in
                    // control, so we reset mCurPerceptible.
                    mCurPerceptible = true;
                }
                if (imeParentChanged) {
                    // Hide the IME method menu earlier when the IME surface parent will change in
            }
        }

        @Override
        public void onImeParentChanged() {
            synchronized (ImfLock.class) {
                // Hide the IME method menu when the IME surface parent will change in
                // case seeing the dialog dismiss flickering during the next focused window
                // starting the input connection.
                mMenuController.hideInputMethodMenu();
            }
        }
        }

        @Override
        public void removeImeSurface() {
+5 −6
Original line number Diff line number Diff line
@@ -4257,18 +4257,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        // Update Ime parent when IME insets leash created or the new IME layering target might
        // updated from setImeLayeringTarget, which is the best time that default IME visibility
        // has been settled down after IME control target changed.
        final boolean imeParentChanged =
                prevImeControlTarget != mImeControlTarget || forceUpdateImeParent;
        if (imeParentChanged) {
        final boolean imeControlChanged = prevImeControlTarget != mImeControlTarget;
        if (imeControlChanged || forceUpdateImeParent) {
            updateImeParent();
        }

        final WindowState win = InsetsControlTarget.asWindowOrNull(mImeControlTarget);
        final IBinder token = win != null ? win.mClient.asBinder() : null;
        // Note: not allowed to call into IMMS with the WM lock held, hence the post.
        mWmService.mH.post(() ->
                InputMethodManagerInternal.get().reportImeControl(token, imeParentChanged)
        );
        mWmService.mH.post(() -> InputMethodManagerInternal.get().reportImeControl(token));
    }

    void updateImeParent() {
@@ -4290,6 +4287,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            // do a force update to make sure there is a layer set for the new parent.
            assignRelativeLayerForIme(getSyncTransaction(), true /* forceUpdate */);
            scheduleAnimation();

            mWmService.mH.post(() -> InputMethodManagerInternal.get().onImeParentChanged());
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -2465,7 +2465,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            dc.setImeLayeringTarget(null);
            dc.computeImeTarget(true /* updateImeTarget */);
        }
        if (dc.getImeInputTarget() == this) {
        if (dc.getImeInputTarget() == this
                && (mActivityRecord == null || !mActivityRecord.isRelaunching())) {
            dc.updateImeInputAndControlTarget(null);
        }