diff --git a/res/layout/dialog_a11y_bounce_key.xml b/res/layout/dialog_a11y_bounce_key.xml new file mode 100644 index 00000000000..7e236925e18 --- /dev/null +++ b/res/layout/dialog_a11y_bounce_key.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 600c08ce70d..3f09598e997 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4520,11 +4520,21 @@ Bounce keys - The keyboard ignores quickly repeated presses of the same key within %1$d ms + The keyboard ignores quickly repeated presses of the same key + + Bounce key threshold + + Choose the duration of time your keyboard ignores repeated key presses + + 0.2s + + 0.4s + + 0.6s Slow keys - Adjusts the time it takes for a key press to activate to %1$d ms + Adjusts the time it takes for a key press to activate Sticky keys @@ -4532,7 +4542,7 @@ Mouse keys - Use the physical keyboard to control the mouse. + Use your keyboard to control the pointer Keyboard shortcuts diff --git a/res/xml/physical_keyboard_a11y_settings.xml b/res/xml/physical_keyboard_a11y_settings.xml index eb787d0353f..62479f91502 100644 --- a/res/xml/physical_keyboard_a11y_settings.xml +++ b/res/xml/physical_keyboard_a11y_settings.xml @@ -32,9 +32,10 @@ android:defaultValue="false" settings:controller="com.android.settings.inputmethod.KeyboardAccessibilityStickyKeysController"/> - @@ -42,6 +43,7 @@ android:key="accessibility_slow_keys" android:title="@string/slow_keys" android:defaultValue="false" + android:summary="@string/slow_keys_summary" settings:controller="com.android.settings.inputmethod.KeyboardAccessibilitySlowKeysController" /> { + RadioGroup radioGroup = + mAlertDialog.findViewById(R.id.bounce_key_value_group); + int checkedRadioButtonId = radioGroup.getCheckedRadioButtonId(); + int threshold = checkedRadioButtonId == R.id.bounce_key_value_600 ? 600 + : checkedRadioButtonId == R.id.bounce_key_value_400 ? 400 + : checkedRadioButtonId == R.id.bounce_key_value_200 + ? 200 : 0; + InputSettings.setAccessibilityBounceKeysThreshold(context, threshold); + }) + .setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.dismiss()) + .create(); + mAlertDialog.setOnShowListener(dialog -> { + RadioGroup radioGroup = mAlertDialog.findViewById(R.id.bounce_key_value_group); + int bounceKeysThreshold = InputSettings.getAccessibilityBounceKeysThreshold(context); + switch (bounceKeysThreshold) { + case 600 -> radioGroup.check(R.id.bounce_key_value_600); + case 400 -> radioGroup.check(R.id.bounce_key_value_400); + default -> radioGroup.check(R.id.bounce_key_value_200); + } + }); + } } diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java index 7c7ad37a359..57ae88a85f5 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityMouseKeysController.java @@ -23,14 +23,25 @@ import android.provider.Settings; import androidx.annotation.NonNull; import androidx.lifecycle.LifecycleObserver; +import androidx.preference.PreferenceScreen; +import androidx.preference.TwoStatePreference; public class KeyboardAccessibilityMouseKeysController extends - KeyboardAccessibilityController implements + InputSettingPreferenceController implements LifecycleObserver { + + private TwoStatePreference mTwoStatePreference; + public KeyboardAccessibilityMouseKeysController(@NonNull Context context, @NonNull String key) { super(context, key); } + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mTwoStatePreference = screen.findPreference(getPreferenceKey()); + } + @Override public boolean isChecked() { return InputSettings.isAccessibilityMouseKeysEnabled(mContext); @@ -51,9 +62,11 @@ public class KeyboardAccessibilityMouseKeysController extends } @Override - protected void updateKeyboardAccessibilitySettings() { - setChecked( - InputSettings.isAccessibilityMouseKeysEnabled(mContext)); + protected void onInputSettingUpdated() { + if (mTwoStatePreference != null) { + mTwoStatePreference.setChecked( + InputSettings.isAccessibilityMouseKeysEnabled(mContext)); + } } @Override diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java index 5110663e4ad..d8602df9c3e 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilitySlowKeysController.java @@ -23,18 +23,26 @@ import android.provider.Settings; import androidx.annotation.NonNull; import androidx.lifecycle.LifecycleObserver; - -import com.android.settings.R; +import androidx.preference.PreferenceScreen; +import androidx.preference.TwoStatePreference; public class KeyboardAccessibilitySlowKeysController extends - KeyboardAccessibilityController implements + InputSettingPreferenceController implements LifecycleObserver { public static final int SLOW_KEYS_THRESHOLD = 500; + private TwoStatePreference mTwoStatePreference; + public KeyboardAccessibilitySlowKeysController(@NonNull Context context, @NonNull String key) { super(context, key); } + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mTwoStatePreference = screen.findPreference(getPreferenceKey()); + } + @Override public boolean isChecked() { return InputSettings.isAccessibilitySlowKeysEnabled(mContext); @@ -54,16 +62,12 @@ public class KeyboardAccessibilitySlowKeysController extends : UNSUPPORTED_ON_DEVICE; } - @NonNull @Override - public CharSequence getSummary() { - return mContext.getString(R.string.slow_keys_summary, SLOW_KEYS_THRESHOLD); - } - - @Override - protected void updateKeyboardAccessibilitySettings() { - setChecked( - InputSettings.isAccessibilitySlowKeysEnabled(mContext)); + protected void onInputSettingUpdated() { + if (mTwoStatePreference != null) { + mTwoStatePreference.setChecked( + InputSettings.isAccessibilitySlowKeysEnabled(mContext)); + } } @Override diff --git a/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java b/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java index a62d80bee2c..fd2cb2e6e11 100644 --- a/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java +++ b/src/com/android/settings/inputmethod/KeyboardAccessibilityStickyKeysController.java @@ -23,15 +23,26 @@ import android.provider.Settings; import androidx.annotation.NonNull; import androidx.lifecycle.LifecycleObserver; +import androidx.preference.PreferenceScreen; +import androidx.preference.TwoStatePreference; public class KeyboardAccessibilityStickyKeysController extends - KeyboardAccessibilityController implements + InputSettingPreferenceController implements LifecycleObserver { + + private TwoStatePreference mTwoStatePreference; + public KeyboardAccessibilityStickyKeysController(@NonNull Context context, @NonNull String key) { super(context, key); } + @Override + public void displayPreference(@NonNull PreferenceScreen screen) { + super.displayPreference(screen); + mTwoStatePreference = screen.findPreference(getPreferenceKey()); + } + @Override public boolean isChecked() { return InputSettings.isAccessibilityStickyKeysEnabled(mContext); @@ -52,9 +63,11 @@ public class KeyboardAccessibilityStickyKeysController extends } @Override - protected void updateKeyboardAccessibilitySettings() { - setChecked( - InputSettings.isAccessibilityStickyKeysEnabled(mContext)); + protected void onInputSettingUpdated() { + if (mTwoStatePreference != null) { + mTwoStatePreference.setChecked( + InputSettings.isAccessibilityStickyKeysEnabled(mContext)); + } } @Override diff --git a/tests/robotests/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysControllerTest.java index 8ac5a5dee65..d16f6975d0e 100644 --- a/tests/robotests/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysControllerTest.java +++ b/tests/robotests/src/com/android/settings/inputmethod/KeyboardAccessibilityBounceKeysControllerTest.java @@ -18,39 +18,59 @@ package com.android.settings.inputmethod; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; + import android.content.Context; import android.hardware.input.InputSettings; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; +import android.widget.RadioGroup; +import androidx.appcompat.app.AlertDialog; +import androidx.preference.Preference; + +import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settings.keyboard.Flags; +import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricTestRunner.class) @Config(shadows = { com.android.settings.testutils.shadow.ShadowFragment.class, + ShadowAlertDialogCompat.class, }) public class KeyboardAccessibilityBounceKeysControllerTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Rule + public MockitoRule mMockitoRule = MockitoJUnit.rule(); + private static final String PREFERENCE_KEY = "accessibility_bounce_keys"; + @Mock + private Preference mPreference; private Context mContext; private KeyboardAccessibilityBounceKeysController mKeyboardAccessibilityBounceKeysController; @Before public void setUp() { mContext = RuntimeEnvironment.application; + mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat); mKeyboardAccessibilityBounceKeysController = new KeyboardAccessibilityBounceKeysController( mContext, - "accessibility_bounce_keys"); + PREFERENCE_KEY); + when(mPreference.getKey()).thenReturn(PREFERENCE_KEY); } @Test @@ -82,4 +102,28 @@ public class KeyboardAccessibilityBounceKeysControllerTest { assertThat(isEnabled).isFalse(); } + + @Test + public void handlePreferenceTreeClick_dialogShows() { + mKeyboardAccessibilityBounceKeysController.handlePreferenceTreeClick(mPreference); + + AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + + assertThat(alertDialog.isShowing()).isTrue(); + } + + @Test + public void handlePreferenceTreeClick_performClickOn200_updatesBounceKeysThreshold() { + mKeyboardAccessibilityBounceKeysController.handlePreferenceTreeClick(mPreference); + AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + RadioGroup radioGroup = alertDialog.findViewById(R.id.bounce_key_value_group); + radioGroup.check(R.id.bounce_key_value_200); + + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick(); + ShadowLooper.idleMainLooper(); + + assertThat(alertDialog.isShowing()).isFalse(); + int threshold = InputSettings.getAccessibilityBounceKeysThreshold(mContext); + assertThat(threshold).isEqualTo(200); + } }