Merge "RESTRICT AUTOMERGE Reland "Fix showing keyboard without editor focused.."" into rvc-qpr-dev

This commit is contained in:
Ming-Shin Lu
2020-09-28 15:21:53 +00:00
committed by Android (Google) Code Review
5 changed files with 67 additions and 15 deletions

View File

@@ -611,7 +611,8 @@ public final class InputMethodManager {
@Override @Override
public void startInputAsyncOnWindowFocusGain(View focusedView, public void startInputAsyncOnWindowFocusGain(View focusedView,
@SoftInputModeFlags int softInputMode, int windowFlags, boolean forceNewFocus) { @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(); final ImeFocusController controller = getFocusController();
if (controller == null) { if (controller == null) {

View File

@@ -224,6 +224,8 @@ public final class InputMethodDebug {
return "HIDE_DOCKED_STACK_ATTACHED"; return "HIDE_DOCKED_STACK_ATTACHED";
case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION: case SoftInputShowHideReason.HIDE_RECENTS_ANIMATION:
return "HIDE_RECENTS_ANIMATION"; return "HIDE_RECENTS_ANIMATION";
case SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR:
return "HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR";
default: default:
return "Unknown=" + reason; return "Unknown=" + reason;
} }

View File

@@ -47,7 +47,8 @@ import java.lang.annotation.Retention;
SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME, SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME,
SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED, SoftInputShowHideReason.HIDE_DOCKED_STACK_ATTACHED,
SoftInputShowHideReason.HIDE_RECENTS_ANIMATION, SoftInputShowHideReason.HIDE_RECENTS_ANIMATION,
SoftInputShowHideReason.HIDE_BUBBLES}) SoftInputShowHideReason.HIDE_BUBBLES,
SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR})
public @interface SoftInputShowHideReason { public @interface SoftInputShowHideReason {
/** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */ /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
int SHOW_SOFT_INPUT = 0; int SHOW_SOFT_INPUT = 0;
@@ -147,4 +148,17 @@ public @interface SoftInputShowHideReason {
* switching, or collapsing Bubbles. * switching, or collapsing Bubbles.
*/ */
int HIDE_BUBBLES = 19; 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;
} }

View File

@@ -47,4 +47,10 @@ public @interface StartInputFlags {
* documented hence we probably need to revisit this though. * documented hence we probably need to revisit this though.
*/ */
int INITIAL_CONNECTION = 4; 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;
} }

View File

@@ -3275,6 +3275,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver, boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver,
@SoftInputShowHideReason int reason) { @SoftInputShowHideReason int reason) {
if (mCurClient == null || mCurClient.curSession == null) {
return false;
}
if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0 if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
&& (mShowExplicitlyRequested || mShowForced)) { && (mShowExplicitlyRequested || mShowForced)) {
if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide"); 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. // pre-rendering not supported on low-ram devices.
cs.shouldPreRenderIme = DebugFlags.FLAG_PRE_RENDER_IME_VIEWS.value() && !mIsLowRam; 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) { if (DEBUG) {
Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client
+ " attribute=" + attribute + ", token = " + windowToken + " attribute=" + attribute + ", token = " + windowToken
@@ -3474,6 +3482,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY,
null, null, null, -1, null); null, null, null, -1, null);
} }
mCurFocusedWindow = windowToken; mCurFocusedWindow = windowToken;
mCurFocusedWindowSoftInputMode = softInputMode; mCurFocusedWindowSoftInputMode = softInputMode;
mCurFocusedWindowClient = cs; mCurFocusedWindowClient = cs;
@@ -3491,7 +3500,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
== LayoutParams.SOFT_INPUT_ADJUST_RESIZE == LayoutParams.SOFT_INPUT_ADJUST_RESIZE
|| mRes.getConfiguration().isLayoutSizeAtLeast( || mRes.getConfiguration().isLayoutSizeAtLeast(
Configuration.SCREENLAYOUT_SIZE_LARGE); 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 // 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 // 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; InputBindResult res = null;
switch (softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE) { switch (softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE) {
case LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: case LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
if (!isTextEditor || !doAutoShow) { if (!sameWindowFocused && (!isTextEditor || !doAutoShow)) {
if (LayoutParams.mayUseInputMethod(windowFlags)) { if (LayoutParams.mayUseInputMethod(windowFlags)) {
// There is no focus view, and this window will // There is no focus view, and this window will
// be behind any soft input window, so hide the // be behind any soft input window, so hide the
@@ -3551,9 +3559,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
break; break;
case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
if (DEBUG) Slog.v(TAG, "Window asks to hide input"); if (!sameWindowFocused) {
hideCurrentInputLocked(mCurFocusedWindow, 0, null, if (DEBUG) Slog.v(TAG, "Window asks to hide input");
SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE); hideCurrentInputLocked(mCurFocusedWindow, 0, null,
SoftInputShowHideReason.HIDE_ALWAYS_HIDDEN_STATE);
}
break; break;
case LayoutParams.SOFT_INPUT_STATE_VISIBLE: case LayoutParams.SOFT_INPUT_STATE_VISIBLE:
if ((softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { 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 (DEBUG) Slog.v(TAG, "Window asks to always show input");
if (InputMethodUtils.isSoftInputModeStateVisibleAllowed( if (InputMethodUtils.isSoftInputModeStateVisibleAllowed(
unverifiedTargetSdkVersion, startInputFlags)) { unverifiedTargetSdkVersion, startInputFlags)) {
if (attribute != null) { if (!sameWindowFocused) {
res = startInputUncheckedLocked(cs, inputContext, missingMethods, if (attribute != null) {
attribute, startInputFlags, startInputReason); res = startInputUncheckedLocked(cs, inputContext, missingMethods,
didStart = true; 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 { } else {
Slog.e(TAG, "SOFT_INPUT_STATE_ALWAYS_VISIBLE is ignored because" Slog.e(TAG, "SOFT_INPUT_STATE_ALWAYS_VISIBLE is ignored because"
+ " there is no focused view that also returns true from" + " there is no focused view that also returns true from"
@@ -3595,7 +3607,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (!didStart) { if (!didStart) {
if (attribute != null) { 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) { || (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0) {
res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute,
startInputFlags, startInputReason); startInputFlags, startInputReason);
@@ -3609,6 +3634,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return res; return res;
} }
private boolean isImeVisible() {
return (mImeWindowVis & InputMethodService.IME_VISIBLE) != 0;
}
private boolean canShowInputMethodPickerLocked(IInputMethodClient client) { private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
// TODO(yukawa): multi-display support. // TODO(yukawa): multi-display support.
final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid();