From 8be7fa86551fd28b0e95ad2e015cdf58feaf0e24 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Mon, 1 Aug 2022 16:46:07 -0300 Subject: [PATCH] Improve accessibility of SMS code keyboard. --- .../components/NumericKeyboardView.kt | 75 +++++++++ .../registration/VerificationPinKeyboard.java | 36 +---- .../main/res/layout/numeric_keyboard_view.xml | 152 ++++++++++++++++++ .../res/layout/verification_code_view.xml | 6 + .../layout/verification_pin_keyboard_view.xml | 2 +- app/src/main/res/values/strings.xml | 14 ++ app/src/main/res/xml/pin_keyboard.xml | 27 ---- 7 files changed, 256 insertions(+), 56 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/components/NumericKeyboardView.kt create mode 100644 app/src/main/res/layout/numeric_keyboard_view.xml delete mode 100644 app/src/main/res/xml/pin_keyboard.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/NumericKeyboardView.kt b/app/src/main/java/org/thoughtcrime/securesms/components/NumericKeyboardView.kt new file mode 100644 index 0000000000..83b0f57533 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/components/NumericKeyboardView.kt @@ -0,0 +1,75 @@ +package org.thoughtcrime.securesms.components + +import android.content.Context +import android.util.AttributeSet +import android.widget.ImageView +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import org.thoughtcrime.securesms.R + +/** + * A "forced" EN US Numeric keyboard designed solely for SMS code entry. This + * "upgrade" over KeyboardView will ensure that the keyboard is navigable via + * TalkBack and will read out keys as they are selected by the user. This is + * not a perfect solution, but save being able to force the system keyboard to + * appear in EN US, this is the best we can do for the time being. + */ +class NumericKeyboardView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null +) : ConstraintLayout(context, attrs) { + + var listener: Listener? = null + + init { + inflate(context, R.layout.numeric_keyboard_view, this) + + findViewById(R.id.numeric_keyboard_1).setOnClickListener { + listener?.onKeyPress(1) + } + + findViewById(R.id.numeric_keyboard_2).setOnClickListener { + listener?.onKeyPress(2) + } + + findViewById(R.id.numeric_keyboard_3).setOnClickListener { + listener?.onKeyPress(3) + } + + findViewById(R.id.numeric_keyboard_4).setOnClickListener { + listener?.onKeyPress(4) + } + + findViewById(R.id.numeric_keyboard_5).setOnClickListener { + listener?.onKeyPress(5) + } + + findViewById(R.id.numeric_keyboard_6).setOnClickListener { + listener?.onKeyPress(6) + } + + findViewById(R.id.numeric_keyboard_7).setOnClickListener { + listener?.onKeyPress(7) + } + + findViewById(R.id.numeric_keyboard_8).setOnClickListener { + listener?.onKeyPress(8) + } + + findViewById(R.id.numeric_keyboard_9).setOnClickListener { + listener?.onKeyPress(9) + } + + findViewById(R.id.numeric_keyboard_0).setOnClickListener { + listener?.onKeyPress(0) + } + + findViewById(R.id.numeric_keyboard_back).setOnClickListener { + listener?.onKeyPress(-1) + } + } + + interface Listener { + fun onKeyPress(keyCode: Int) + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/registration/VerificationPinKeyboard.java b/app/src/main/java/org/thoughtcrime/securesms/components/registration/VerificationPinKeyboard.java index c511bdc126..d6185e25c8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/registration/VerificationPinKeyboard.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/registration/VerificationPinKeyboard.java @@ -3,8 +3,6 @@ package org.thoughtcrime.securesms.components.registration; import android.content.Context; import android.graphics.PorterDuff; -import android.inputmethodservice.Keyboard; -import android.inputmethodservice.KeyboardView; import android.os.Build; import android.util.AttributeSet; import android.view.View; @@ -21,17 +19,18 @@ import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.components.NumericKeyboardView; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.concurrent.ListenableFuture; import org.thoughtcrime.securesms.util.concurrent.SettableFuture; public class VerificationPinKeyboard extends FrameLayout { - private KeyboardView keyboardView; - private ProgressBar progressBar; - private ImageView successView; - private ImageView failureView; - private ImageView lockedView; + private NumericKeyboardView keyboardView; + private ProgressBar progressBar; + private ImageView successView; + private ImageView failureView; + private ImageView lockedView; private OnKeyPressListener listener; @@ -65,27 +64,8 @@ public class VerificationPinKeyboard extends FrameLayout { this.failureView = findViewById(R.id.failure); this.lockedView = findViewById(R.id.locked); - keyboardView.setPreviewEnabled(false); - keyboardView.setKeyboard(new Keyboard(getContext(), R.xml.pin_keyboard)); - keyboardView.setOnKeyboardActionListener(new KeyboardView.OnKeyboardActionListener() { - @Override - public void onPress(int primaryCode) { - if (listener != null) listener.onKeyPress(primaryCode); - } - @Override - public void onRelease(int primaryCode) {} - @Override - public void onKey(int primaryCode, int[] keyCodes) {} - @Override - public void onText(CharSequence text) {} - @Override - public void swipeLeft() {} - @Override - public void swipeRight() {} - @Override - public void swipeDown() {} - @Override - public void swipeUp() {} + keyboardView.setListener(keyCode -> { + if (listener != null) listener.onKeyPress(keyCode); }); displayKeyboard(); diff --git a/app/src/main/res/layout/numeric_keyboard_view.xml b/app/src/main/res/layout/numeric_keyboard_view.xml new file mode 100644 index 0000000000..c3588e51a6 --- /dev/null +++ b/app/src/main/res/layout/numeric_keyboard_view.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/verification_code_view.xml b/app/src/main/res/layout/verification_code_view.xml index a69499ad65..1d6bfa265b 100644 --- a/app/src/main/res/layout/verification_code_view.xml +++ b/app/src/main/res/layout/verification_code_view.xml @@ -22,6 +22,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:importantForAccessibility="yes" android:textColor="@color/signal_inverse_primary" android:textSize="28sp" tools:text="0" /> @@ -44,6 +45,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:importantForAccessibility="yes" android:textColor="@color/signal_inverse_primary" android:textSize="28sp" tools:text="1" /> @@ -66,6 +68,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:importantForAccessibility="yes" android:textColor="@color/signal_inverse_primary" android:textSize="28sp" tools:text="2" /> @@ -78,6 +81,7 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginStart="4dp" + android:importantForAccessibility="no" android:text="-" android:textColor="@color/signal_inverse_primary" android:textSize="28sp" @@ -101,6 +105,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:importantForAccessibility="yes" android:textColor="@color/signal_inverse_primary" android:textSize="28sp" tools:text="3" /> @@ -123,6 +128,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:importantForAccessibility="yes" android:textColor="@color/signal_inverse_primary" android:textSize="28sp" tools:text="4" /> diff --git a/app/src/main/res/layout/verification_pin_keyboard_view.xml b/app/src/main/res/layout/verification_pin_keyboard_view.xml index c02ef34475..c5c6bd0d54 100644 --- a/app/src/main/res/layout/verification_pin_keyboard_view.xml +++ b/app/src/main/res/layout/verification_pin_keyboard_view.xml @@ -2,7 +2,7 @@ - Record phrase Before you can disable your PIN, you must record your payments recovery phrase to ensure you can recover your payments account. + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 0 + + Backspace + %d minute diff --git a/app/src/main/res/xml/pin_keyboard.xml b/app/src/main/res/xml/pin_keyboard.xml deleted file mode 100644 index 0c1ad1c1f0..0000000000 --- a/app/src/main/res/xml/pin_keyboard.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file