From 739a6809148883b3562ed70bba4d18deed78fd1a Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Tue, 23 Mar 2021 00:37:34 +0800 Subject: [PATCH] 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 --- .../InputMethodManagerService.java | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 52401cfdee935..2173cd720d497 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -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); - showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, - SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY); - } else { - res = InputBindResult.NULL_EDITOR_INFO; - } + // 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); 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; }