summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml2
-rw-r--r--packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt60
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt8
5 files changed, 62 insertions, 27 deletions
diff --git a/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
index 4002f7808637..1e4a07f5fc30 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_one_pane_layout.xml
@@ -22,7 +22,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:accessibilityLiveRegion="assertive"
- android:importantForAccessibility="yes"
+ android:importantForAccessibility="auto"
android:clickable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/rightGuideline"
diff --git a/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
index 3c8cb6860a41..8234c24a7e17 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_two_pane_layout.xml
@@ -23,7 +23,7 @@ android:layout_height="match_parent">
android:layout_width="0dp"
android:layout_height="0dp"
android:accessibilityLiveRegion="assertive"
- android:importantForAccessibility="yes"
+ android:importantForAccessibility="auto"
android:clickable="false"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 3b22e13f29a2..80d06f4a2d37 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -27,6 +27,7 @@ import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO
+import android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES
import android.view.accessibility.AccessibilityManager
import android.widget.Button
import android.widget.ImageView
@@ -43,7 +44,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieCompositionFactory
-import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.biometrics.Utils.ellipsize
import com.android.systemui.biometrics.shared.model.BiometricModalities
import com.android.systemui.biometrics.shared.model.BiometricModality
@@ -63,6 +63,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
private const val TAG = "BiometricViewBinder"
@@ -123,25 +124,6 @@ object BiometricViewBinder {
val confirmationButton = view.requireViewById<Button>(R.id.button_confirm)
val retryButton = view.requireViewById<Button>(R.id.button_try_again)
- // Handles custom "Cancel Authentication" talkback action
- val cancelDelegate: AccessibilityDelegateCompat =
- object : AccessibilityDelegateCompat() {
- override fun onInitializeAccessibilityNodeInfo(
- host: View,
- info: AccessibilityNodeInfoCompat,
- ) {
- super.onInitializeAccessibilityNodeInfo(host, info)
- info.addAction(
- AccessibilityActionCompat(
- AccessibilityNodeInfoCompat.ACTION_CLICK,
- view.context.getString(R.string.biometric_dialog_cancel_authentication),
- )
- )
- }
- }
- ViewCompat.setAccessibilityDelegate(backgroundView, cancelDelegate)
- ViewCompat.setAccessibilityDelegate(cancelButton, cancelDelegate)
-
// TODO(b/330788871): temporary workaround for the unsafe callbacks & legacy controllers
val adapter =
Spaghetti(
@@ -155,6 +137,33 @@ object BiometricViewBinder {
var boundSize = false
view.repeatWhenAttached {
+ // Handles custom "Cancel Authentication" talkback action
+ val cancelDelegate: AccessibilityDelegateCompat =
+ object : AccessibilityDelegateCompat() {
+ override fun onInitializeAccessibilityNodeInfo(
+ host: View,
+ info: AccessibilityNodeInfoCompat,
+ ) {
+ super.onInitializeAccessibilityNodeInfo(host, info)
+ lifecycleScope.launch {
+ // Clears UDFPS guidance hint after focus moves to cancel view
+ viewModel.onClearUdfpsGuidanceHint(
+ accessibilityManager.isTouchExplorationEnabled
+ )
+ }
+ info.addAction(
+ AccessibilityActionCompat(
+ AccessibilityNodeInfoCompat.ACTION_CLICK,
+ view.context.getString(
+ R.string.biometric_dialog_cancel_authentication
+ ),
+ )
+ )
+ }
+ }
+ ViewCompat.setAccessibilityDelegate(backgroundView, cancelDelegate)
+ ViewCompat.setAccessibilityDelegate(cancelButton, cancelDelegate)
+
// these do not change and need to be set before any size transitions
val modalities = viewModel.modalities.first()
@@ -404,11 +413,16 @@ object BiometricViewBinder {
}
false
}
+
launch {
viewModel.accessibilityHint.collect { message ->
- if (message.isNotBlank()) {
- udfpsGuidanceView.contentDescription = message
- }
+ udfpsGuidanceView.importantForAccessibility =
+ if (message == null) {
+ IMPORTANT_FOR_ACCESSIBILITY_NO
+ } else {
+ IMPORTANT_FOR_ACCESSIBILITY_YES
+ }
+ udfpsGuidanceView.contentDescription = message
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index 4e17a2658ee7..27fc1878cc99 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -187,10 +187,10 @@ constructor(
}
}
- private val _accessibilityHint = MutableSharedFlow<String>()
+ private val _accessibilityHint = MutableSharedFlow<String?>()
/** Hint for talkback directional guidance */
- val accessibilityHint: Flow<String> = _accessibilityHint.asSharedFlow()
+ val accessibilityHint: Flow<String?> = _accessibilityHint.asSharedFlow()
private val _isAuthenticating: MutableStateFlow<Boolean> = MutableStateFlow(false)
@@ -923,6 +923,19 @@ constructor(
return false
}
+ /** Clears the message used for UDFPS directional guidance */
+ suspend fun onClearUdfpsGuidanceHint(touchExplorationEnabled: Boolean) {
+ if (
+ modalities.first().hasUdfps &&
+ touchExplorationEnabled &&
+ !isAuthenticated.first().isAuthenticated
+ ) {
+ // Add delay to make sure we read the guidance message before clearing it
+ delay(1000)
+ _accessibilityHint.emit(null)
+ }
+ }
+
/**
* Switch to the credential view.
*
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index bf79d11b2fb8..515a10792c02 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -1482,6 +1482,14 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
} else {
assertThat(hint.isNullOrBlank()).isTrue()
}
+
+ kosmos.promptViewModel.onClearUdfpsGuidanceHint(true)
+
+ if (testCase.modalities.hasUdfps) {
+ assertThat(hint).isNull()
+ } else {
+ assertThat(hint.isNullOrBlank()).isTrue()
+ }
}
@Test