Add Sticky keys A11Y feature flag and Setting
DD: go/pk_accessibility
Bug: 294546335
Test: None
Change-Id: Ib7812876b7201188704c21ad05150ecc92ed0b05
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 145dbf2..cb9c333 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -17,6 +17,7 @@
package android.hardware.input;
import static com.android.hardware.input.Flags.keyboardA11yBounceKeysFlag;
+import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag;
import android.Manifest;
import android.annotation.FloatRange;
@@ -401,4 +402,49 @@
UserHandle.USER_CURRENT);
}
+ /**
+ * Whether Accessibility sticky keys is enabled.
+ *
+ * <p>
+ * 'Sticky keys' is an accessibility feature that assists users who have physical
+ * disabilities or help users reduce repetitive strain injury. It serializes keystrokes
+ * instead of pressing multiple keys at a time, allowing the user to press and release a
+ * modifier key, such as Shift, Ctrl, Alt, or any other modifier key, and have it remain
+ * active until any other key is pressed.
+ * </p>
+ *
+ * @hide
+ */
+ public static boolean isAccessibilityStickyKeysEnabled(@NonNull Context context) {
+ if (!keyboardA11yStickyKeysFlag()) {
+ return false;
+ }
+ return Settings.System.getIntForUser(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_STICKY_KEYS, 0, UserHandle.USER_CURRENT) != 0;
+ }
+
+ /**
+ * Set Accessibility sticky keys feature enabled/disabled.
+ *
+ * <p>
+ * 'Sticky keys' is an accessibility feature that assists users who have physical
+ * disabilities or help users reduce repetitive strain injury. It serializes keystrokes
+ * instead of pressing multiple keys at a time, allowing the user to press and release a
+ * modifier key, such as Shift, Ctrl, Alt, or any other modifier key, and have it remain
+ * active until any other key is pressed.
+ * </p>
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.WRITE_SETTINGS)
+ public static void setAccessibilityStickyKeysEnabled(@NonNull Context context,
+ boolean enabled) {
+ if (!keyboardA11yStickyKeysFlag()) {
+ return;
+ }
+ Settings.System.putIntForUser(context.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_STICKY_KEYS, enabled ? 1 : 0,
+ UserHandle.USER_CURRENT);
+ }
+
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2cc56d8..290ae4a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7801,6 +7801,15 @@
public static final String ACCESSIBILITY_BOUNCE_KEYS = "accessibility_bounce_keys";
/**
+ * Whether to enable sticky keys for Physical Keyboard accessibility.
+ *
+ * This is a boolean value that determines if Sticky keys feature is enabled.
+ *
+ * @hide
+ */
+ public static final String ACCESSIBILITY_STICKY_KEYS = "accessibility_sticky_keys";
+
+ /**
* Whether stylus button presses are disabled. This is a boolean that
* determines if stylus buttons are ignored.
*
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index ec456e0..2167a8a 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -74,6 +74,7 @@
Settings.Secure.TTS_DEFAULT_LOCALE,
Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS,
+ Settings.Secure.ACCESSIBILITY_STICKY_KEYS,
Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, // moved to global
Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, // moved to global
Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT, // moved to global
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 5ad14ce..868623f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -120,6 +120,7 @@
VALIDATORS.put(Secure.TTS_DEFAULT_LOCALE, TTS_LIST_VALIDATOR);
VALIDATORS.put(Secure.SHOW_IME_WITH_HARD_KEYBOARD, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_BOUNCE_KEYS, ANY_INTEGER_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_STICKY_KEYS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.WIFI_NUM_OPEN_NETWORKS_KEPT, NON_NEGATIVE_INTEGER_VALIDATOR);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 972f857..24e23003 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -3511,6 +3511,13 @@
mNative.setAccessibilityBounceKeysThreshold(thresholdTimeMs);
}
+ /**
+ * Sets whether Accessibility sticky keys is enabled.
+ */
+ public void setAccessibilityStickyKeysEnabled(boolean enabled) {
+ mNative.setAccessibilityStickyKeysEnabled(enabled);
+ }
+
interface KeyboardBacklightControllerInterface {
default void incrementKeyboardBacklight(int deviceId) {}
default void decrementKeyboardBacklight(int deviceId) {}
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index 0012eab1..c9668a2 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -87,7 +87,9 @@
Map.entry(Settings.System.getUriFor(Settings.System.SHOW_ROTARY_INPUT),
(reason) -> updateShowRotaryInput()),
Map.entry(Settings.System.getUriFor(Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS),
- (reason) -> updateAccessibilityBounceKeys()));
+ (reason) -> updateAccessibilityBounceKeys()),
+ Map.entry(Settings.System.getUriFor(Settings.Secure.ACCESSIBILITY_STICKY_KEYS),
+ (reason) -> updateAccessibilityStickyKeys()));
}
/**
@@ -223,4 +225,9 @@
mService.setAccessibilityBounceKeysThreshold(
InputSettings.getAccessibilityBounceKeysThreshold(mContext));
}
+
+ private void updateAccessibilityStickyKeys() {
+ mService.setAccessibilityStickyKeysEnabled(
+ InputSettings.isAccessibilityStickyKeysEnabled(mContext));
+ }
}
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index 49bbe9a..829b660 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -251,6 +251,11 @@
*/
void setAccessibilityBounceKeysThreshold(int thresholdTimeMs);
+ /**
+ * Notify if Accessibility sticky keys is enabled/disabled from InputSettings.
+ */
+ void setAccessibilityStickyKeysEnabled(boolean enabled);
+
/** The native implementation of InputManagerService methods. */
class NativeImpl implements NativeInputManagerService {
/** Pointer to native input manager service object, used by native code. */
@@ -508,5 +513,8 @@
@Override
public native void setAccessibilityBounceKeysThreshold(int thresholdTimeMs);
+
+ @Override
+ public native void setAccessibilityStickyKeysEnabled(boolean enabled);
}
}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index bc05e77..0dd0564 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -2747,6 +2747,14 @@
}
}
+static void nativeSetAccessibilityStickyKeysEnabled(JNIEnv* env, jobject nativeImplObj,
+ jboolean enabled) {
+ NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
+ if (ENABLE_INPUT_FILTER_RUST) {
+ im->getInputManager()->getInputFilter().setAccessibilityStickyKeysEnabled(enabled);
+ }
+}
+
// ----------------------------------------------------------------------------
static const JNINativeMethod gInputManagerMethods[] = {
@@ -2848,6 +2856,8 @@
{"setStylusPointerIconEnabled", "(Z)V", (void*)nativeSetStylusPointerIconEnabled},
{"setAccessibilityBounceKeysThreshold", "(I)V",
(void*)nativeSetAccessibilityBounceKeysThreshold},
+ {"setAccessibilityStickyKeysEnabled", "(Z)V",
+ (void*)nativeSetAccessibilityStickyKeysEnabled},
};
#define FIND_CLASS(var, className) \