diff options
author | Ming-Shin Lu <lumark@google.com> | 2020-09-28 15:21:53 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-09-28 15:21:53 +0000 |
commit | a308227709d4056e15e318aef407630148138520 (patch) | |
tree | 76ff08fcdd785f600439ae2cce07b8cb63641dc2 | |
parent | a51344f79258e29b84a5314eddc993c1a38486ea (diff) | |
parent | 44ecc735ec0fe98c49265247b35cfbbf4af60463 (diff) | |
download | base-a308227709d4056e15e318aef407630148138520.tar.gz |
Merge "RESTRICT AUTOMERGE Reland "Fix showing keyboard without editor focused.."" into rvc-qpr-dev
5 files changed, 67 insertions, 15 deletions
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 0d21673dfc71..5f8b13b5b548 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -611,7 +611,8 @@ public final class InputMethodManager { @Override public void startInputAsyncOnWindowFocusGain(View focusedView, @SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus) { - final int startInputFlags = getStartInputFlags(focusedView, 0); + int startInputFlags = getStartInputFlags(focusedView, 0); + startInputFlags |= StartInputFlags.WINDOW_GAINED_FOCUS; final ImeFocusController controller = getFocusController(); if (controller == null) { diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java index 37f68233db53..3bcba75ec163 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java +++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java @@ -224,6 +224,8 @@ public final class InputMethodDebug { return "HIDE_DOCKED_STACK_ATTACHED"; case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION: return "HIDE_RECENTS_ANIMATION"; + case SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR: + return "HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR"; default: return "Unknown=" + reason; } diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java index 4b968b45f122..f46626be48a8 100644 --- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java +++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java @@ -47,7 +47,8 @@ import java.lang.annotation.Retention; SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME, SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED, SoftInputShowHideReason.HIDE_RECENTS_ANIMATION, - SoftInputShowHideReason.HIDE_BUBBLES}) + SoftInputShowHideReason.HIDE_BUBBLES, + SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR}) public @interface SoftInputShowHideReason { /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */ int SHOW_SOFT_INPUT = 0; @@ -147,4 +148,17 @@ public @interface SoftInputShowHideReason { * switching, or collapsing Bubbles. */ int HIDE_BUBBLES = 19; + + /** + * Hide soft input when focusing the same window (e.g. screen turned-off and turn-on) which no + * valid focused editor. + * + * Note: From Android R, the window focus change callback is processed by InputDispatcher, + * some focus behavior changes (e.g. There are an activity with a dialog window, after + * screen turned-off and turned-on, before Android R the window focus sequence would be + * the activity first and then the dialog focused, however, in R the focus sequence would be + * only the dialog focused as it's the latest window with input focus) makes we need to hide + * soft-input when the same window focused again to align with the same behavior prior to R. + */ + int HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR = 20; } diff --git a/core/java/com/android/internal/inputmethod/StartInputFlags.java b/core/java/com/android/internal/inputmethod/StartInputFlags.java index 5a8d2c227256..ac83987ef12c 100644 --- a/core/java/com/android/internal/inputmethod/StartInputFlags.java +++ b/core/java/com/android/internal/inputmethod/StartInputFlags.java @@ -47,4 +47,10 @@ public @interface StartInputFlags { * documented hence we probably need to revisit this though. */ int INITIAL_CONNECTION = 4; + + /** + * The start input happens when the window gained focus to call + * {@code android.view.inputmethod.InputMethodManager#startInputAsyncOnWindowFocusGain}. + */ + int WINDOW_GAINED_FOCUS = 8; } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 7cce78bb661d..bcfbcd124e71 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -3275,6 +3275,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) { + if (mCurClient == null || mCurClient.curSession == null) { + return false; + } if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0 && (mShowExplicitlyRequested || mShowForced)) { if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide"); @@ -3459,7 +3462,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // pre-rendering not supported on low-ram devices. cs.shouldPreRenderIme = DebugFlags.FLAG_PRE_RENDER_IME_VIEWS.value() && !mIsLowRam; - if (mCurFocusedWindow == windowToken) { + final boolean sameWindowFocused = mCurFocusedWindow == windowToken; + final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0; + final boolean startInputByWinGainedFocus = + (startInputFlags & StartInputFlags.WINDOW_GAINED_FOCUS) != 0; + + if (sameWindowFocused && isTextEditor) { if (DEBUG) { Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client + " attribute=" + attribute + ", token = " + windowToken @@ -3474,6 +3482,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, null, null, null, -1, null); } + mCurFocusedWindow = windowToken; mCurFocusedWindowSoftInputMode = softInputMode; mCurFocusedWindowClient = cs; @@ -3491,7 +3500,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub == LayoutParams.SOFT_INPUT_ADJUST_RESIZE || mRes.getConfiguration().isLayoutSizeAtLeast( Configuration.SCREENLAYOUT_SIZE_LARGE); - final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0; // We want to start input before showing the IME, but after closing // it. We want to do this after closing it to help the IME disappear @@ -3502,7 +3510,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub InputBindResult res = null; switch (softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE) { case LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: - if (!isTextEditor || !doAutoShow) { + if (!sameWindowFocused && (!isTextEditor || !doAutoShow)) { if (LayoutParams.mayUseInputMethod(windowFlags)) { // There is no focus view, and this window will // be behind any soft input window, so hide the @@ -3551,9 +3559,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } break; case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: - if (DEBUG) Slog.v(TAG, "Window asks to hide input"); - hideCurrentInputLocked(mCurFocusedWindow, 0, null, - SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); + if (!sameWindowFocused) { + if (DEBUG) Slog.v(TAG, "Window asks to hide input"); + hideCurrentInputLocked(mCurFocusedWindow, 0, null, + SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); + } break; case LayoutParams.SOFT_INPUT_STATE_VISIBLE: if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { @@ -3578,13 +3588,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (DEBUG) Slog.v(TAG, "Window asks to always show input"); if (InputMethodUtils.isSoftInputModeStateVisibleAllowed( unverifiedTargetSdkVersion, startInputFlags)) { - if (attribute != null) { - res = startInputUncheckedLocked(cs, inputContext, missingMethods, - attribute, startInputFlags, startInputReason); - didStart = true; + if (!sameWindowFocused) { + if (attribute != null) { + res = startInputUncheckedLocked(cs, inputContext, missingMethods, + attribute, startInputFlags, startInputReason); + didStart = true; + } + showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, + SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE); } - showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, - SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE); } else { Slog.e(TAG, "SOFT_INPUT_STATE_ALWAYS_VISIBLE is ignored because" + " there is no focused view that also returns true from" @@ -3595,7 +3607,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!didStart) { if (attribute != null) { - if (!DebugFlags.FLAG_OPTIMIZE_START_INPUT.value() + if (sameWindowFocused) { + // On previous platforms, when Dialogs re-gained focus, the Activity behind + // would briefly gain focus first, and dismiss the IME. + // On R that behavior has been fixed, but unfortunately apps have come + // to rely on this behavior to hide the IME when the editor no longer has focus + // To maintain compatibility, we are now hiding the IME when we don't have + // an editor upon refocusing a window. + if (startInputByWinGainedFocus) { + hideCurrentInputLocked(mCurFocusedWindow, 0, null, + SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR); + } + res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, + startInputFlags, startInputReason); + } else if (!DebugFlags.FLAG_OPTIMIZE_START_INPUT.value() || (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0) { res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, startInputFlags, startInputReason); @@ -3609,6 +3634,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return res; } + private boolean isImeVisible() { + return (mImeWindowVis & InputMethodService.IME_VISIBLE) != 0; + } + private boolean canShowInputMethodPickerLocked(IInputMethodClient client) { // TODO(yukawa): multi-display support. final int uid = Binder.getCallingUid(); |