diff options
| author | 2021-10-08 09:01:54 +0000 | |
|---|---|---|
| committer | 2021-12-20 12:06:10 +0100 | |
| commit | 94506d40f217e00cdd2000bc8e1cefab0fe317b6 (patch) | |
| tree | 6b0b3203bc7675d918146aeb684c9d171ffc94bc | |
| parent | 6560e43b0604b441fb91babc516788aa2be073fa (diff) | |
Enable preventing IME startup for non-edit views
This CL introduces the config_preventImeStartupUnlessTextEditor
configuration option, which is disabled by default.
When enabled, this prevents the IMMS from triggering an onStartInput
unless the window receiving focus contains a text editor element
or IME startup was explicitly requested by the client app.
Bug: 199887357
Bug: 37617707
Test: set the config option to true in an overlay
Test: manually on adt3 and another android tv device
Test: atest CtsInputMethodTestCases
Change-Id: Iacb29cfdb3825248ee8c40e610652f697aa2d6da
| -rw-r--r-- | core/api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/res/res/values/config.xml | 4 | ||||
| -rw-r--r-- | core/res/res/values/public.xml | 2 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/inputmethod/InputMethodBindingController.java | 11 | ||||
| -rw-r--r-- | services/core/java/com/android/server/inputmethod/InputMethodManagerService.java | 38 |
6 files changed, 49 insertions, 8 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 89dc678360f1..8184f8f51ac1 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 be32c42eb30d..baee71b14c83 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2897,6 +2897,10 @@ <!-- Make the IME killable by the lowmemorykiller by raising its oom_score_adj. --> <bool name="config_killableInputMethods">false</bool> + <!-- Prevent the InputMethodManagerService from starting up the IME unless + the currently focused view is a text editor. --> + <bool name="config_preventImeStartupUnlessTextEditor">false</bool> + <!-- The list of classes that should be added to the notification ranking pipeline. See {@link com.android.server.notification.NotificationSignalExtractor} If you add a new extractor to this list make sure to update diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 3d3c86006871..561206a6a290 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3311,6 +3311,8 @@ <staging-public-group type="bool" first-id="0x01cf0000"> <!-- @hide @SystemApi --> <public name="config_systemCaptionsServiceCallsEnabled" /> + <!-- @hide @TestApi --> + <public name="config_preventImeStartupUnlessTextEditor" /> </staging-public-group> <staging-public-group type="fraction" first-id="0x01ce0000"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 527865f77257..bcd8d6650a88 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2250,6 +2250,7 @@ <java-symbol type="bool" name="config_autoResetAirplaneMode" /> <java-symbol type="string" name="config_notificationAccessConfirmationActivity" /> <java-symbol type="bool" name="config_killableInputMethods" /> + <java-symbol type="bool" name="config_preventImeStartupUnlessTextEditor" /> <java-symbol type="layout" name="resolver_list" /> <java-symbol type="id" name="resolver_list" /> diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java index c5dc23e30822..375f1c76487f 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java @@ -496,8 +496,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 da3729d7498f..4bf9b560deff 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -261,6 +261,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; @@ -1648,6 +1658,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") @@ -2311,7 +2323,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 = getSelectedMethodId(); if (selectedMethodId == null) { @@ -2360,6 +2372,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. @@ -3302,7 +3326,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, @@ -3343,7 +3367,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; @@ -3382,7 +3406,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, @@ -3413,7 +3437,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, @@ -3432,7 +3456,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, @@ -3461,7 +3485,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } res = startInputUncheckedLocked(cs, inputContext, attribute, startInputFlags, - startInputReason); + startInputReason, unverifiedTargetSdkVersion); } else { res = InputBindResult.NULL_EDITOR_INFO; } |