Merge "Enhance a11y soft keyboard controller"
diff --git a/api/current.txt b/api/current.txt
index ac1a1b9..d971f18 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2819,6 +2819,7 @@
field public static final java.lang.String SERVICE_META_DATA = "android.accessibilityservice";
field public static final int SHOW_MODE_AUTO = 0; // 0x0
field public static final int SHOW_MODE_HIDDEN = 1; // 0x1
+ field public static final int SHOW_MODE_WITH_HARD_KEYBOARD = 2; // 0x2
}
public static abstract class AccessibilityService.GestureResultCallback {
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 829a9444..300a530 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -31,7 +31,6 @@
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
-import android.provider.Settings;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
@@ -398,13 +397,49 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = { "SHOW_MODE_" }, value = {
SHOW_MODE_AUTO,
- SHOW_MODE_HIDDEN
+ SHOW_MODE_HIDDEN,
+ SHOW_MODE_WITH_HARD_KEYBOARD
})
public @interface SoftKeyboardShowMode {}
+ /**
+ * Allow the system to control when the soft keyboard is shown.
+ * @see SoftKeyboardController
+ */
public static final int SHOW_MODE_AUTO = 0;
+
+ /**
+ * Never show the soft keyboard.
+ * @see SoftKeyboardController
+ */
public static final int SHOW_MODE_HIDDEN = 1;
+ /**
+ * Allow the soft keyboard to be shown, even if a hard keyboard is connected
+ * @see SoftKeyboardController
+ */
+ public static final int SHOW_MODE_WITH_HARD_KEYBOARD = 2;
+
+ /**
+ * Mask used to cover the show modes supported in public API
+ * @hide
+ */
+ public static final int SHOW_MODE_MASK = 0x03;
+
+ /**
+ * Bit used to hold the old value of the hard IME setting to restore when a service is shut
+ * down.
+ * @hide
+ */
+ public static final int SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE = 0x20000000;
+
+ /**
+ * Bit for show mode setting to indicate that the user has overridden the hard keyboard
+ * behavior.
+ * @hide
+ */
+ public static final int SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN = 0x40000000;
+
private int mConnectionId = AccessibilityInteractionClient.NO_ID;
private AccessibilityServiceInfo mInfo;
@@ -1147,7 +1182,27 @@
}
/**
- * Used to control and query the soft keyboard show mode.
+ * Used to control, query, and listen for changes to the soft keyboard show mode.
+ * <p>
+ * Accessibility services may request to override the decisions normally made about whether or
+ * not the soft keyboard is shown.
+ * <p>
+ * If multiple services make conflicting requests, the last request is honored. A service may
+ * register a listener to find out if the mode has changed under it.
+ * <p>
+ * If the user takes action to override the behavior behavior requested by an accessibility
+ * service, the user's request takes precendence, the show mode will be reset to
+ * {@link AccessibilityService#SHOW_MODE_AUTO}, and services will no longer be able to control
+ * that aspect of the soft keyboard's behavior.
+ * <p>
+ * Note: Because soft keyboards are independent apps, the framework does not have total control
+ * over their behavior. They may choose to show themselves, or not, without regard to requests
+ * made here. So the framework will make a best effort to deliver the behavior requested, but
+ * cannot guarantee success.
+ *
+ * @see AccessibilityService#SHOW_MODE_AUTO
+ * @see AccessibilityService#SHOW_MODE_HIDDEN
+ * @see AccessibilityService#SHOW_MODE_WITH_HARD_KEYBOARD
*/
public static final class SoftKeyboardController {
private final AccessibilityService mService;
@@ -1217,7 +1272,8 @@
* @param listener the listener to remove, must be non-null
* @return {@code true} if the listener was removed, {@code false} otherwise
*/
- public boolean removeOnShowModeChangedListener(@NonNull OnShowModeChangedListener listener) {
+ public boolean removeOnShowModeChangedListener(
+ @NonNull OnShowModeChangedListener listener) {
if (mListeners == null) {
return false;
}
@@ -1289,32 +1345,32 @@
}
/**
- * Returns the show mode of the soft keyboard. The default show mode is
- * {@code SHOW_MODE_AUTO}, where the soft keyboard is shown when a text input field is
- * focused. An AccessibilityService can also request the show mode
- * {@code SHOW_MODE_HIDDEN}, where the soft keyboard is never shown.
+ * Returns the show mode of the soft keyboard.
*
* @return the current soft keyboard show mode
+ *
+ * @see AccessibilityService#SHOW_MODE_AUTO
+ * @see AccessibilityService#SHOW_MODE_HIDDEN
+ * @see AccessibilityService#SHOW_MODE_WITH_HARD_KEYBOARD
*/
@SoftKeyboardShowMode
public int getShowMode() {
- try {
- return Settings.Secure.getInt(mService.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
- } catch (Settings.SettingNotFoundException e) {
- Log.v(LOG_TAG, "Failed to obtain the soft keyboard mode", e);
- // The settings hasn't been changed yet, so it's value is null. Return the default.
- return 0;
- }
+ final IAccessibilityServiceConnection connection =
+ AccessibilityInteractionClient.getInstance().getConnection(
+ mService.mConnectionId);
+ if (connection != null) {
+ try {
+ return connection.getSoftKeyboardShowMode();
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Failed to set soft keyboard behavior", re);
+ re.rethrowFromSystemServer();
+ }
+ }
+ return SHOW_MODE_AUTO;
}
/**
- * Sets the soft keyboard show mode. The default show mode is
- * {@code SHOW_MODE_AUTO}, where the soft keyboard is shown when a text input field is
- * focused. An AccessibilityService can also request the show mode
- * {@code SHOW_MODE_HIDDEN}, where the soft keyboard is never shown. The
- * The lastto this method will be honored, regardless of any previous calls (including those
- * made by other AccessibilityServices).
+ * Sets the soft keyboard show mode.
* <p>
* <strong>Note:</strong> If the service is not yet connected (e.g.
* {@link AccessibilityService#onServiceConnected()} has not yet been called) or the
@@ -1322,6 +1378,10 @@
*
* @param showMode the new show mode for the soft keyboard
* @return {@code true} on success
+ *
+ * @see AccessibilityService#SHOW_MODE_AUTO
+ * @see AccessibilityService#SHOW_MODE_HIDDEN
+ * @see AccessibilityService#SHOW_MODE_WITH_HARD_KEYBOARD
*/
public boolean setShowMode(@SoftKeyboardShowMode int showMode) {
final IAccessibilityServiceConnection connection =
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 037aeb0..276131f 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -87,6 +87,8 @@
boolean setSoftKeyboardShowMode(int showMode);
+ int getSoftKeyboardShowMode();
+
void setSoftKeyboardCallbackEnabled(boolean enabled);
boolean isAccessibilityButtonAvailable();
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index 44b1f08..0dd7685 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -119,6 +119,10 @@
return false;
}
+ public int getSoftKeyboardShowMode() {
+ return 0;
+ }
+
public void setSoftKeyboardCallbackEnabled(boolean enabled) {}
public boolean isAccessibilityButtonAvailable() {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 2da0818..9c0e110 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -16,12 +16,18 @@
package com.android.server.accessibility;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_MASK;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.accessibility.AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_AUTO;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HIDDEN;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_WITH_HARD_KEYBOARD;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN;
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
@@ -1807,7 +1813,6 @@
updateDisplayDaltonizerLocked(userState);
updateDisplayInversionLocked(userState);
updateMagnificationLocked(userState);
- updateSoftKeyboardShowModeLocked(userState);
scheduleUpdateFingerprintGestureHandling(userState);
scheduleUpdateInputFilter(userState);
scheduleUpdateClientsIfNeededLocked(userState);
@@ -2001,18 +2006,6 @@
return false;
}
- private boolean readSoftKeyboardShowModeChangedLocked(UserState userState) {
- final int softKeyboardShowMode = Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0,
- userState.mUserId);
- if (softKeyboardShowMode != userState.mSoftKeyboardShowMode) {
- userState.mSoftKeyboardShowMode = softKeyboardShowMode;
- return true;
- }
- return false;
- }
-
private void updateTouchExplorationLocked(UserState userState) {
boolean enabled = mUiAutomationManager.isTouchExplorationEnabledLocked();
final int serviceCount = userState.mBoundServices.size();
@@ -2211,34 +2204,6 @@
return false;
}
- private void updateSoftKeyboardShowModeLocked(UserState userState) {
- final int userId = userState.mUserId;
- // Only check whether we need to reset the soft keyboard mode if it is not set to the
- // default.
- if ((userId == mCurrentUserId) && (userState.mSoftKeyboardShowMode != 0)) {
- // Check whether the last AccessibilityService that changed the soft keyboard mode to
- // something other than the default is still enabled and, if not, remove flag and
- // reset to the default soft keyboard behavior.
- boolean serviceChangingSoftKeyboardModeIsEnabled =
- userState.mEnabledServices.contains(userState.mServiceChangingSoftKeyboardMode);
-
- if (!serviceChangingSoftKeyboardModeIsEnabled) {
- final long identity = Binder.clearCallingIdentity();
- try {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
- 0,
- userState.mUserId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- userState.mSoftKeyboardShowMode = 0;
- userState.mServiceChangingSoftKeyboardMode = null;
- notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
- }
- }
- }
-
private void updateFingerprintGestureHandling(UserState userState) {
final List<AccessibilityServiceConnection> services;
synchronized (mLock) {
@@ -2473,6 +2438,15 @@
}
}
+ private void putSecureIntForUser(String key, int value, int userid) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(), key, value, userid);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
class RemoteAccessibilityConnection implements DeathRecipient {
private final int mUid;
private final String mPackageName;
@@ -3683,7 +3657,7 @@
public int mLastSentClientState = -1;
- public int mSoftKeyboardShowMode = 0;
+ private int mSoftKeyboardShowMode = 0;
public boolean mIsNavBarMagnificationAssignedToAccessibilityButton;
public ComponentName mServiceAssignedToAccessibilityButton;
@@ -3744,7 +3718,6 @@
mServiceAssignedToAccessibilityButton = null;
mIsNavBarMagnificationAssignedToAccessibilityButton = false;
mIsAutoclickEnabled = false;
- mSoftKeyboardShowMode = 0;
}
public void addServiceLocked(AccessibilityServiceConnection serviceConnection) {
@@ -3766,6 +3739,11 @@
public void removeServiceLocked(AccessibilityServiceConnection serviceConnection) {
mBoundServices.remove(serviceConnection);
serviceConnection.onRemoved();
+ if ((mServiceChangingSoftKeyboardMode != null)
+ && (mServiceChangingSoftKeyboardMode.equals(
+ serviceConnection.getServiceInfo().getComponentName()))) {
+ setSoftKeyboardModeLocked(SHOW_MODE_AUTO, null);
+ }
// It may be possible to bind a service twice, which confuses the map. Rebuild the map
// to make sure we can still reach a service
mComponentNameToServiceMap.clear();
@@ -3792,6 +3770,134 @@
public Set<ComponentName> getBindingServicesLocked() {
return mBindingServices;
}
+
+ public int getSoftKeyboardShowMode() {
+ return mSoftKeyboardShowMode;
+ }
+
+ /**
+ * Set the soft keyboard mode. This mode is a bit odd, as it spans multiple settings.
+ * The ACCESSIBILITY_SOFT_KEYBOARD_MODE setting can be checked by the rest of the system
+ * to see if it should suppress showing the IME. The SHOW_IME_WITH_HARD_KEYBOARD setting
+ * setting can be changed by the user, and prevents the system from suppressing the soft
+ * keyboard when the hard keyboard is connected. The hard keyboard setting needs to defer
+ * to the user's preference, if they have supplied one.
+ *
+ * @param newMode The new mode
+ * @param requester The service requesting the change, so we can undo it when the
+ * service stops. Set to null if something other than a service is forcing
+ * the change.
+ *
+ * @return Whether or not the soft keyboard mode equals the new mode after the call
+ */
+ public boolean setSoftKeyboardModeLocked(int newMode, @Nullable ComponentName requester) {
+ if ((newMode != SHOW_MODE_AUTO) && (newMode != SHOW_MODE_HIDDEN)
+ && (newMode != SHOW_MODE_WITH_HARD_KEYBOARD))
+ {
+ Slog.w(LOG_TAG, "Invalid soft keyboard mode");
+ return false;
+ }
+ if (mSoftKeyboardShowMode == newMode) return true;
+
+ if (newMode == SHOW_MODE_WITH_HARD_KEYBOARD) {
+ if (hasUserOverriddenHardKeyboardSettingLocked()) {
+ // The user has specified a default for this setting
+ return false;
+ }
+ // Save the original value. But don't do this if the value in settings is already
+ // the new mode. That happens when we start up after a reboot, and we don't want
+ // to overwrite the value we had from when we first started controlling the setting.
+ if (getSoftKeyboardValueFromSettings() != SHOW_MODE_WITH_HARD_KEYBOARD) {
+ setOriginalHardKeyboardValue(
+ Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0) != 0);
+ }
+ putSecureIntForUser(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 1, mUserId);
+ } else if (mSoftKeyboardShowMode == SHOW_MODE_WITH_HARD_KEYBOARD) {
+ putSecureIntForUser(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
+ getOriginalHardKeyboardValue() ? 1 : 0, mUserId);
+ }
+
+ saveSoftKeyboardValueToSettings(newMode);
+ mSoftKeyboardShowMode = newMode;
+ mServiceChangingSoftKeyboardMode = requester;
+ notifySoftKeyboardShowModeChangedLocked(mSoftKeyboardShowMode);
+ return true;
+ }
+
+ /**
+ * If the settings are inconsistent with the internal state, make the internal state
+ * match the settings.
+ */
+ public void reconcileSoftKeyboardModeWithSettingsLocked() {
+ final ContentResolver cr = mContext.getContentResolver();
+ final boolean showWithHardKeyboardSettings =
+ Settings.Secure.getInt(cr, Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0) != 0;
+ if (mSoftKeyboardShowMode == SHOW_MODE_WITH_HARD_KEYBOARD) {
+ if (!showWithHardKeyboardSettings) {
+ // The user has overridden the setting. Respect that and prevent further changes
+ // to this behavior.
+ setSoftKeyboardModeLocked(SHOW_MODE_AUTO, null);
+ setUserOverridesHardKeyboardSettingLocked();
+ }
+ }
+
+ // If the setting and the internal state are out of sync, set both to default
+ if (getSoftKeyboardValueFromSettings() != mSoftKeyboardShowMode)
+ {
+ Slog.e(LOG_TAG,
+ "Show IME setting inconsistent with internal state. Overwriting");
+ setSoftKeyboardModeLocked(SHOW_MODE_AUTO, null);
+ putSecureIntForUser(Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ SHOW_MODE_AUTO, mUserId);
+ }
+ }
+
+ private void setUserOverridesHardKeyboardSettingLocked() {
+ final int softKeyboardSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0);
+ putSecureIntForUser(Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ softKeyboardSetting | SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN,
+ mUserId);
+ }
+
+ private boolean hasUserOverriddenHardKeyboardSettingLocked() {
+ final int softKeyboardSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0);
+ return (softKeyboardSetting & SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN)
+ != 0;
+ }
+
+ private void setOriginalHardKeyboardValue(boolean originalHardKeyboardValue) {
+ final int oldSoftKeyboardSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0);
+ final int newSoftKeyboardSetting = oldSoftKeyboardSetting
+ & (~SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE)
+ | ((originalHardKeyboardValue) ? SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE : 0);
+ putSecureIntForUser(Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ newSoftKeyboardSetting, mUserId);
+ }
+
+ private void saveSoftKeyboardValueToSettings(int softKeyboardShowMode) {
+ final int oldSoftKeyboardSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0);
+ final int newSoftKeyboardSetting = oldSoftKeyboardSetting & (~SHOW_MODE_MASK)
+ | softKeyboardShowMode;
+ putSecureIntForUser(Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ newSoftKeyboardSetting, mUserId);
+ }
+
+ private int getSoftKeyboardValueFromSettings() {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ SHOW_MODE_AUTO) & SHOW_MODE_MASK;
+ }
+
+ private boolean getOriginalHardKeyboardValue() {
+ return (Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0)
+ & SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE) != 0;
+ }
}
private final class AccessibilityContentObserver extends ContentObserver {
@@ -3829,6 +3935,9 @@
private final Uri mAccessibilitySoftKeyboardModeUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
+ private final Uri mShowImeWithHardKeyboardUri = Settings.Secure.getUriFor(
+ Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
+
private final Uri mAccessibilityShortcutServiceIdUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
@@ -3864,6 +3973,8 @@
contentResolver.registerContentObserver(
mAccessibilitySoftKeyboardModeUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
+ mShowImeWithHardKeyboardUri, false, this, UserHandle.USER_ALL);
+ contentResolver.registerContentObserver(
mAccessibilityShortcutServiceIdUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
mAccessibilityButtonComponentIdUri, false, this, UserHandle.USER_ALL);
@@ -3906,11 +4017,9 @@
if (readHighTextContrastEnabledSettingLocked(userState)) {
onUserStateChangedLocked(userState);
}
- } else if (mAccessibilitySoftKeyboardModeUri.equals(uri)) {
- if (readSoftKeyboardShowModeChangedLocked(userState)) {
- notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
- onUserStateChangedLocked(userState);
- }
+ } else if (mAccessibilitySoftKeyboardModeUri.equals(uri)
+ || mShowImeWithHardKeyboardUri.equals(uri)) {
+ userState.reconcileSoftKeyboardModeWithSettingsLocked();
} else if (mAccessibilityShortcutServiceIdUri.equals(uri)) {
if (readAccessibilityShortcutSettingLocked(userState)) {
onUserStateChangedLocked(userState);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 8f92145..6237212 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -218,26 +218,20 @@
if (!isCalledForCurrentUserLocked()) {
return false;
}
+ final UserState userState = mUserStateWeakReference.get();
+ if (userState == null) return false;
+ return userState.setSoftKeyboardModeLocked(showMode, mComponentName);
}
- UserState userState = mUserStateWeakReference.get();
- if (userState == null) return false;
- final long identity = Binder.clearCallingIdentity();
- try {
- // Keep track of the last service to request a non-default show mode. The show mode
- // should be restored to default should this service be disabled.
- userState.mServiceChangingSoftKeyboardMode = (showMode == SHOW_MODE_AUTO)
- ? null : mComponentName;
-
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, showMode,
- userState.mUserId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- return true;
}
@Override
+ public int getSoftKeyboardShowMode() {
+ final UserState userState = mUserStateWeakReference.get();
+ return (userState != null) ? userState.getSoftKeyboardShowMode() : 0;
+ }
+
+
+ @Override
public boolean isAccessibilityButtonAvailable() {
synchronized (mLock) {
if (!isCalledForCurrentUserLocked()) {
diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
index ed3b3e7..ff29311 100644
--- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
@@ -259,6 +259,11 @@
}
@Override
+ public int getSoftKeyboardShowMode() {
+ return 0;
+ }
+
+ @Override
public boolean isAccessibilityButtonAvailable() {
return false;
}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index fd74613..784dfb4 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -51,6 +51,7 @@
import org.xmlpull.v1.XmlSerializer;
import android.Manifest;
+import android.accessibilityservice.AccessibilityService;
import android.annotation.AnyThread;
import android.annotation.BinderThread;
import android.annotation.ColorInt;
@@ -888,10 +889,12 @@
if (showImeUri.equals(uri)) {
updateKeyboardFromSettingsLocked();
} else if (accessibilityRequestingNoImeUri.equals(uri)) {
- mAccessibilityRequestingNoSoftKeyboard = Settings.Secure.getIntForUser(
+ final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
- 0, mUserId) == 1;
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, mUserId);
+ mAccessibilityRequestingNoSoftKeyboard =
+ (accessibilitySoftKeyboardSetting & AccessibilityService.SHOW_MODE_MASK)
+ == AccessibilityService.SHOW_MODE_HIDDEN;
if (mAccessibilityRequestingNoSoftKeyboard) {
final boolean showRequested = mShowRequested;
hideCurrentInputLocked(0, null);