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

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

Fix unexpected IME visibility restores

As CL[1] introduced in android S for restoring IME visibility when
navigating app task for consistent experience if previously the
user was interact IME on the app task.

However, forcibly restoring IME visibility seems not suitable when the
window set the softInputMode like ALWAYS_HIDDEN or STATE_HIDEN with
forwarding navigation. Because the app might leverage this flag to
hide soft-keyboard with showing their own UI for input
(e.g. Dialer or Calculator app).

Add a check to not restore IME visibility to fix unexpected IME
visible when the softInputMode is in the above cases

[1]: I63b144bed6c37569d79fba1c2b63dd4f1074f0f6

Fix: 182116748
Test: atest KeyboardVisibilityControlTest#\
      testRestoreImeVisibility_noRestoreForAlwaysHidden
Change-Id: I5e49f0a48a16e0b4a46b69f36be6a9d88211e5d5
parent 69dd9831
Loading
Loading
Loading
Loading
+23 −9
Original line number Diff line number Diff line
@@ -3541,15 +3541,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        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);
        // Note that we don't restore IME visibility for some cases (e.g. when the soft input
        // state is ALWAYS_HIDDEN or STATE_HIDDEN with forward navigation).
        // Because the app might leverage these flags to hide soft-keyboard with showing their own
        // UI for input.
        if (isTextEditor && attribute != null
                && shouldRestoreImeVisibility(windowToken, softInputMode)) {
            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;
        }

@@ -3673,6 +3674,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        return res;
    }

    private boolean shouldRestoreImeVisibility(IBinder windowToken,
            @SoftInputModeFlags int softInputMode) {
        switch (softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE) {
            case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
                return false;
            case LayoutParams.SOFT_INPUT_STATE_HIDDEN:
                if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
                    return false;
                }
        }
        return mWindowManagerInternal.shouldRestoreImeVisibility(windowToken);
    }

    private boolean isImeVisible() {
        return (mImeWindowVis & InputMethodService.IME_VISIBLE) != 0;
    }