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

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

Restore the last IME visiblity of the app window when allowed

Since when bring an existing app task to foreground or quick switching
app task with gesture navigation will first see the task snapshot
during app transition,

If the task previously focused and shown IME, even the task may hide
IME when switching to the next task, As the goal of
go/ime-transition-improve-s mentioned, if the task is still focused by
editor, we should keep the original focused IME shown and keep
the input connection focused state when navigating back to the
original task.

Bug: 166736352
Test: atest CtsInputMethodTestcases
Test: manual by focusing app with an editor to show keyboard,
      switch the app task to the next with gesture nav and then
      switched back, expected the soft-keyboard is still shown.

Change-Id: I63b144bed6c37569d79fba1c2b63dd4f1074f0f6
parent 5f630223
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -116,8 +116,9 @@ public final class ImeFocusController {
        if (!hasWindowFocus || !mHasImeFocus || isInLocalFocusMode(windowAttribute)) {
            return;
        }
        View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView;
        if (DEBUG) {
            Log.v(TAG, "onWindowFocus: " + focusedView
            Log.v(TAG, "onWindowFocus: " + viewForWindowFocus
                    + " softInputMode=" + InputMethodDebug.softInputModeToString(
                    windowAttribute.softInputMode));
        }
@@ -128,8 +129,8 @@ public final class ImeFocusController {
            if (DEBUG) Log.v(TAG, "Restarting due to isRestartOnNextWindowFocus as true");
            forceFocus = true;
        }

        // Update mNextServedView when focusedView changed.
        final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView;
        onViewFocusChanged(viewForWindowFocus, true);

        // Starting new input when the next focused view is same as served view but the currently
+2 −0
Original line number Diff line number Diff line
@@ -228,6 +228,8 @@ public final class InputMethodDebug {
                return "HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR";
            case SoftInputShowHideReason.HIDE_REMOVE_CLIENT:
                return "HIDE_REMOVE_CLIENT";
            case SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY:
                return "SHOW_RESTORE_IME_VISIBILITY";
            default:
                return "Unknown=" + reason;
        }
+8 −1
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ import java.lang.annotation.Retention;
        SoftInputShowHideReason.HIDE_RECENTS_ANIMATION,
        SoftInputShowHideReason.HIDE_BUBBLES,
        SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR,
        SoftInputShowHideReason.HIDE_REMOVE_CLIENT})
        SoftInputShowHideReason.HIDE_REMOVE_CLIENT,
        SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY})
public @interface SoftInputShowHideReason {
    /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
    int SHOW_SOFT_INPUT = 0;
@@ -167,4 +168,10 @@ public @interface SoftInputShowHideReason {
     * Hide soft input when a {@link com.android.internal.view.IInputMethodClient} is removed.
     */
    int HIDE_REMOVE_CLIENT = 21;

    /**
     * Show soft input when the system invoking
     * {@link com.android.server.wm.WindowManagerInternal#shouldRestoreImeVisibility}.
     */
    int SHOW_RESTORE_IME_VISIBILITY = 22;
}
+14 −0
Original line number Diff line number Diff line
@@ -3537,6 +3537,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        boolean didStart = false;

        InputBindResult res = null;
        // We shows the IME when the system allows the IME focused target window to restore the
        // IME visibility (e.g. switching to the app task when last time the IME is visible).
        if (isTextEditor && mWindowManagerInternal.shouldRestoreImeVisibility(windowToken)) {
            if (attribute != null) {
                res = startInputUncheckedLocked(cs, inputContext, missingMethods,
                        attribute, startInputFlags, startInputReason);
                showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null,
                        SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY);
            } else {
                res = InputBindResult.NULL_EDITOR_INFO;
            }
            return res;
        }

        switch (softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE) {
            case LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
                if (!sameWindowFocused && (!isTextEditor || !doAutoShow)) {
+9 −0
Original line number Diff line number Diff line
@@ -667,4 +667,13 @@ public abstract class WindowManagerInternal {
     * Moves the {@link WindowToken} {@code binder} to the display specified by {@code displayId}.
     */
    public abstract void moveWindowTokenToDisplay(IBinder binder, int displayId);

    /**
     * Checks whether the given window should restore the last IME visibility.
     *
     * @param imeTargetWindowToken The token of the (IME target) window
     * @return {@code true} when the system allows to restore the IME visibility,
     *         {@code false} otherwise.
     */
    public abstract boolean shouldRestoreImeVisibility(IBinder imeTargetWindowToken);
}
Loading