summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nikolas Havrikov <havrikov@google.com> 2021-10-08 09:01:54 +0000
committer Nikolas Havrikov <havrikov@google.com> 2021-12-20 12:06:10 +0100
commit94506d40f217e00cdd2000bc8e1cefab0fe317b6 (patch)
tree6b0b3203bc7675d918146aeb684c9d171ffc94bc
parent6560e43b0604b441fb91babc516788aa2be073fa (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.txt1
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodBindingController.java11
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java38
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;
}