diff --git a/core/api/test-current.txt b/core/api/test-current.txt index b37c9387ede31..f48c717fd1b45 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -59,6 +59,7 @@ package android { public static final class R.bool { field public static final int config_assistantOnTopOfDream = 17891333; // 0x1110005 field public static final int config_perDisplayFocusEnabled = 17891332; // 0x1110004 + field public static final int config_preventImeStartupUnlessTextEditor; field public static final int config_remoteInsetsControllerControlsSystemBars = 17891334; // 0x1110006 } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index bd0604e03fee5..7d8bceaf89e94 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2897,6 +2897,10 @@ false + + false + + + diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7687b93cf760d..ba4aa81766e0e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2250,6 +2250,7 @@ + diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java index 4c7077626e960..8c88d4c48837e 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java @@ -510,8 +510,17 @@ final class InputMethodBindingController { return; } + // No IME is currently connected. Reestablish the main connection. + if (!mHasConnection) { + if (DEBUG) { + Slog.d(TAG, "Cannot show input: no IME bound. Rebinding."); + } + bindCurrentMethodLocked(); + return; + } + long bindingDuration = SystemClock.uptimeMillis() - mLastBindTime; - if (mHasConnection && bindingDuration >= TIME_TO_RECONNECT) { + if (bindingDuration >= TIME_TO_RECONNECT) { // The client has asked to have the input method shown, but // we have been sitting here too long with a connection to the // service and no interface received, so let's disconnect/connect diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 34ea86be0de12..7d1be14d4d31a 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -262,6 +262,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private static final String ACTION_SHOW_INPUT_METHOD_PICKER = "com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER"; + /** + * When set, {@link #startInputUncheckedLocked} will return + * {@link InputBindResult#NO_EDITOR} instead of starting an IME connection + * unless {@link StartInputFlags#IS_TEXT_EDITOR} is set. This behavior overrides + * {@link LayoutParams#SOFT_INPUT_STATE_VISIBLE SOFT_INPUT_STATE_VISIBLE} and + * {@link LayoutParams#SOFT_INPUT_STATE_ALWAYS_VISIBLE SOFT_INPUT_STATE_ALWAYS_VISIBLE} + * starting from {@link android.os.Build.VERSION_CODES#P}. + */ + private final boolean mPreventImeStartupUnlessTextEditor; + @UserIdInt private int mLastSwitchUserId; @@ -1663,6 +1673,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mSettings, context); mMenuController = new InputMethodMenuController(this); mBindingController = new InputMethodBindingController(this); + mPreventImeStartupUnlessTextEditor = mRes.getBoolean( + com.android.internal.R.bool.config_preventImeStartupUnlessTextEditor); } @GuardedBy("mMethodMap") @@ -2342,7 +2354,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @NonNull InputBindResult startInputUncheckedLocked(@NonNull ClientState cs, IInputContext inputContext, @NonNull EditorInfo attribute, @StartInputFlags int startInputFlags, - @StartInputReason int startInputReason) { + @StartInputReason int startInputReason, int unverifiedTargetSdkVersion) { // If no method is currently selected, do nothing. String selectedMethodId = getSelectedMethodIdLocked(); if (selectedMethodId == null) { @@ -2391,6 +2403,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mCurInputContext = inputContext; mCurAttribute = attribute; + // If configured, we want to avoid starting up the IME if it is not supposed to be showing + if (mPreventImeStartupUnlessTextEditor + && !InputMethodUtils.isSoftInputModeStateVisibleAllowed(unverifiedTargetSdkVersion, + startInputFlags) + && !mShowRequested) { + if (DEBUG) { + Slog.d(TAG, "Avoiding IME startup and unbinding current input method."); + } + mBindingController.unbindCurrentMethodLocked(); + return InputBindResult.NO_EDITOR; + } + // Check if the input method is changing. // We expect the caller has already verified that the client is allowed to access this // display ID. @@ -3334,7 +3358,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } if (attribute != null) { return startInputUncheckedLocked(cs, inputContext, attribute, startInputFlags, - startInputReason); + startInputReason, unverifiedTargetSdkVersion); } return new InputBindResult( InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, @@ -3375,7 +3399,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (isTextEditor && attribute != null && shouldRestoreImeVisibility(windowToken, softInputMode)) { res = startInputUncheckedLocked(cs, inputContext, attribute, startInputFlags, - startInputReason); + startInputReason, unverifiedTargetSdkVersion); showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, SoftInputShowHideReason.SHOW_RESTORE_IME_VISIBILITY); return res; @@ -3414,7 +3438,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (DEBUG) Slog.v(TAG, "Unspecified window will show input"); if (attribute != null) { res = startInputUncheckedLocked(cs, inputContext, attribute, - startInputFlags, startInputReason); + startInputFlags, startInputReason, unverifiedTargetSdkVersion); didStart = true; } showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, @@ -3445,7 +3469,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub unverifiedTargetSdkVersion, startInputFlags)) { if (attribute != null) { res = startInputUncheckedLocked(cs, inputContext, attribute, - startInputFlags, startInputReason); + startInputFlags, startInputReason, unverifiedTargetSdkVersion); didStart = true; } showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, @@ -3464,7 +3488,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!sameWindowFocused) { if (attribute != null) { res = startInputUncheckedLocked(cs, inputContext, attribute, - startInputFlags, startInputReason); + startInputFlags, startInputReason, unverifiedTargetSdkVersion); didStart = true; } showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null, @@ -3493,7 +3517,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } res = startInputUncheckedLocked(cs, inputContext, attribute, startInputFlags, - startInputReason); + startInputReason, unverifiedTargetSdkVersion); } else { res = InputBindResult.NULL_EDITOR_INFO; }