diff options
9 files changed, 142 insertions, 0 deletions
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java index d93953231eaf..fdbd3197fb79 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.keyboardA11ySlowKeysFlag; import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag; import static com.android.input.flags.Flags.enableInputFilterRustImpl; @@ -68,6 +69,12 @@ public class InputSettings { */ public static final int MAX_ACCESSIBILITY_BOUNCE_KEYS_THRESHOLD_MILLIS = 5000; + /** + * The maximum allowed Accessibility slow keys threshold. + * @hide + */ + public static final int MAX_ACCESSIBILITY_SLOW_KEYS_THRESHOLD_MILLIS = 5000; + private InputSettings() { } @@ -419,6 +426,86 @@ public class InputSettings { } /** + * Whether Accessibility slow keys feature flags is enabled. + * + * <p> + * 'Slow keys' is an accessibility feature to aid users who have physical disabilities, that + * allows the user to specify the duration for which one must press-and-hold a key before the + * system accepts the keypress. + * </p> + * + * @hide + */ + public static boolean isAccessibilitySlowKeysFeatureFlagEnabled() { + return keyboardA11ySlowKeysFlag() && enableInputFilterRustImpl(); + } + + /** + * Whether Accessibility slow keys is enabled. + * + * <p> + * 'Slow keys' is an accessibility feature to aid users who have physical disabilities, that + * allows the user to specify the duration for which one must press-and-hold a key before the + * system accepts the keypress. + * </p> + * + * @hide + */ + public static boolean isAccessibilitySlowKeysEnabled(@NonNull Context context) { + return getAccessibilitySlowKeysThreshold(context) != 0; + } + + /** + * Get Accessibility slow keys threshold duration in milliseconds. + * + * <p> + * 'Slow keys' is an accessibility feature to aid users who have physical disabilities, that + * allows the user to specify the duration for which one must press-and-hold a key before the + * system accepts the keypress. + * </p> + * + * @hide + */ + public static int getAccessibilitySlowKeysThreshold(@NonNull Context context) { + if (!isAccessibilitySlowKeysFeatureFlagEnabled()) { + return 0; + } + return Settings.Secure.getIntForUser(context.getContentResolver(), + Settings.Secure.ACCESSIBILITY_SLOW_KEYS, 0, UserHandle.USER_CURRENT); + } + + /** + * Set Accessibility slow keys threshold duration in milliseconds. + * @param thresholdTimeMillis time duration for which a key should be pressed to be registered + * in the system. The threshold must be between 0 and + * {@link MAX_ACCESSIBILITY_SLOW_KEYS_THRESHOLD_MILLIS} + * + * <p> + * 'Slow keys' is an accessibility feature to aid users who have physical disabilities, that + * allows the user to specify the duration for which one must press-and-hold a key before the + * system accepts the keypress. + * </p> + * + * @hide + */ + @RequiresPermission(Manifest.permission.WRITE_SETTINGS) + public static void setAccessibilitySlowKeysThreshold(@NonNull Context context, + int thresholdTimeMillis) { + if (!isAccessibilitySlowKeysFeatureFlagEnabled()) { + return; + } + if (thresholdTimeMillis < 0 + || thresholdTimeMillis > MAX_ACCESSIBILITY_SLOW_KEYS_THRESHOLD_MILLIS) { + throw new IllegalArgumentException( + "Provided Slow keys threshold should be in range [0, " + + MAX_ACCESSIBILITY_SLOW_KEYS_THRESHOLD_MILLIS + "]"); + } + Settings.Secure.putIntForUser(context.getContentResolver(), + Settings.Secure.ACCESSIBILITY_SLOW_KEYS, thresholdTimeMillis, + UserHandle.USER_CURRENT); + } + + /** * Whether Accessibility sticky keys feature is enabled. * * <p> diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig index 362fe78b14b8..0ed6569afd2a 100644 --- a/core/java/android/hardware/input/input_framework.aconfig +++ b/core/java/android/hardware/input/input_framework.aconfig @@ -29,4 +29,11 @@ flag { name: "pointer_coords_is_resampled_api" description: "Makes MotionEvent.PointerCoords#isResampled() a public API" bug: "298197511" +} + +flag { + namespace: "input_native" + name: "keyboard_a11y_slow_keys_flag" + description: "Controls if the slow keys accessibility feature for physical keyboard is available to the user" + bug: "294546335" }
\ No newline at end of file diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index ecd6f22607b6..755f6d68fc8d 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7881,6 +7881,17 @@ public final class Settings { public static final String ACCESSIBILITY_BOUNCE_KEYS = "accessibility_bounce_keys"; /** + * Whether to enable slow keys for Physical Keyboard accessibility. + * + * If set to non-zero value, any key press on physical keyboard needs to be pressed and + * held for the provided threshold duration (in milliseconds) to be registered in the + * system. + * + * @hide + */ + public static final String ACCESSIBILITY_SLOW_KEYS = "accessibility_slow_keys"; + + /** * Whether to enable sticky keys for Physical Keyboard accessibility. * * This is a boolean value that determines if Sticky keys feature is enabled. @@ -12276,6 +12287,8 @@ public final class Settings { CLONE_TO_MANAGED_PROFILE.add(LOCATION_MODE); CLONE_TO_MANAGED_PROFILE.add(SHOW_IME_WITH_HARD_KEYBOARD); CLONE_TO_MANAGED_PROFILE.add(ACCESSIBILITY_BOUNCE_KEYS); + CLONE_TO_MANAGED_PROFILE.add(ACCESSIBILITY_SLOW_KEYS); + CLONE_TO_MANAGED_PROFILE.add(ACCESSIBILITY_STICKY_KEYS); CLONE_TO_MANAGED_PROFILE.add(NOTIFICATION_BUBBLES); CLONE_TO_MANAGED_PROFILE.add(NOTIFICATION_HISTORY_ENABLED); } diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 8ae50eb7ffad..8ad5f244b659 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 @@ public class SecureSettings { Settings.Secure.TTS_DEFAULT_LOCALE, Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS, + Settings.Secure.ACCESSIBILITY_SLOW_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 diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index 285c8c969343..d854df38a9ef 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 @@ public class SecureSettingsValidators { 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_SLOW_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); diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 67c23fc4db12..338744bfc227 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -3614,6 +3614,13 @@ public class InputManagerService extends IInputManager.Stub } /** + * Sets Accessibility slow keys threshold in milliseconds. + */ + public void setAccessibilitySlowKeysThreshold(int thresholdTimeMs) { + mNative.setAccessibilitySlowKeysThreshold(thresholdTimeMs); + } + + /** * Sets whether Accessibility sticky keys is enabled. */ public void setAccessibilityStickyKeysEnabled(boolean enabled) { diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java index 572d844d752d..165dfe445751 100644 --- a/services/core/java/com/android/server/input/InputSettingsObserver.java +++ b/services/core/java/com/android/server/input/InputSettingsObserver.java @@ -89,6 +89,8 @@ class InputSettingsObserver extends ContentObserver { (reason) -> updateShowRotaryInput()), Map.entry(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BOUNCE_KEYS), (reason) -> updateAccessibilityBounceKeys()), + Map.entry(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_SLOW_KEYS), + (reason) -> updateAccessibilitySlowKeys()), Map.entry(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_STICKY_KEYS), (reason) -> updateAccessibilityStickyKeys())); } @@ -228,6 +230,11 @@ class InputSettingsObserver extends ContentObserver { InputSettings.getAccessibilityBounceKeysThreshold(mContext)); } + private void updateAccessibilitySlowKeys() { + mService.setAccessibilitySlowKeysThreshold( + InputSettings.getAccessibilitySlowKeysThreshold(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 8aec8ca7a23f..a79a1354771c 100644 --- a/services/core/java/com/android/server/input/NativeInputManagerService.java +++ b/services/core/java/com/android/server/input/NativeInputManagerService.java @@ -257,6 +257,11 @@ interface NativeInputManagerService { void setAccessibilityBounceKeysThreshold(int thresholdTimeMs); /** + * Notify if Accessibility slow keys threshold is changed from InputSettings. + */ + void setAccessibilitySlowKeysThreshold(int thresholdTimeMs); + + /** * Notify if Accessibility sticky keys is enabled/disabled from InputSettings. */ void setAccessibilityStickyKeysEnabled(boolean enabled); @@ -526,6 +531,9 @@ interface NativeInputManagerService { public native void setAccessibilityBounceKeysThreshold(int thresholdTimeMs); @Override + public native void setAccessibilitySlowKeysThreshold(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 8bc41af8af62..82ff36acfac3 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -2775,6 +2775,15 @@ static void nativeSetAccessibilityBounceKeysThreshold(JNIEnv* env, jobject nativ } } +static void nativeSetAccessibilitySlowKeysThreshold(JNIEnv* env, jobject nativeImplObj, + jint thresholdTimeMs) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); + if (ENABLE_INPUT_FILTER_RUST) { + im->getInputManager()->getInputFilter().setAccessibilitySlowKeysThreshold( + static_cast<nsecs_t>(thresholdTimeMs) * 1000000); + } +} + static void nativeSetAccessibilityStickyKeysEnabled(JNIEnv* env, jobject nativeImplObj, jboolean enabled) { NativeInputManager* im = getNativeInputManager(env, nativeImplObj); @@ -2887,6 +2896,8 @@ static const JNINativeMethod gInputManagerMethods[] = { {"setStylusPointerIconEnabled", "(Z)V", (void*)nativeSetStylusPointerIconEnabled}, {"setAccessibilityBounceKeysThreshold", "(I)V", (void*)nativeSetAccessibilityBounceKeysThreshold}, + {"setAccessibilitySlowKeysThreshold", "(I)V", + (void*)nativeSetAccessibilitySlowKeysThreshold}, {"setAccessibilityStickyKeysEnabled", "(Z)V", (void*)nativeSetAccessibilityStickyKeysEnabled}, }; |