Use announceForAccessibility to workaround Talkback rate-limitation

Talkback 14.0 has new rate-limitation design to reduce frequency of
TYPE_WINDOW_CONTENT_CHANGED events to once every 30 seconds. Since
showing error and help messages in BiometricPrompt requires sending
events exceeding this frequency, use View#announceForAccessibility as a
workaround (context: b/281765653#comment18)

Test: Manually verified all missing talkback announcements are fixed
Fixes: 289145585
Fixes: 289011350
Fixes: 289006313
Change-Id: I058be826cebe6f3f4ab3fcfd36389d97e44b2189
This commit is contained in:
Grace Cheng
2023-08-02 23:06:10 +00:00
parent fad60a95fd
commit f58e41308b
2 changed files with 21 additions and 15 deletions

View File

@@ -60,6 +60,13 @@ object Utils {
return dp * (density / DisplayMetrics.DENSITY_DEFAULT)
}
/**
* Note: Talkback 14.0 has new rate-limitation design to reduce frequency
* of TYPE_WINDOW_CONTENT_CHANGED events to once every 30 seconds.
* (context: b/281765653#comment18)
* Using {@link View#announceForAccessibility} instead as workaround when sending events
* exceeding this frequency is required.
*/
@JvmStatic
fun notifyAccessibilityContentChanged(am: AccessibilityManager, view: ViewGroup) {
if (!am.isEnabled) {

View File

@@ -45,7 +45,6 @@ import com.android.systemui.biometrics.AuthBiometricView.Callback
import com.android.systemui.biometrics.AuthBiometricViewAdapter
import com.android.systemui.biometrics.AuthIconController
import com.android.systemui.biometrics.AuthPanelController
import com.android.systemui.biometrics.Utils
import com.android.systemui.biometrics.domain.model.BiometricModalities
import com.android.systemui.biometrics.shared.model.BiometricModality
import com.android.systemui.biometrics.shared.model.PromptKind
@@ -80,9 +79,6 @@ object BiometricViewBinder {
applicationScope: CoroutineScope,
): AuthBiometricViewAdapter {
val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!!
fun notifyAccessibilityChanged() {
Utils.notifyAccessibilityContentChanged(accessibilityManager, view)
}
val textColorError =
view.resources.getColor(R.color.biometric_dialog_error, view.context.theme)
@@ -326,21 +322,14 @@ object BiometricViewBinder {
}
}
// not sure why this is here, but the legacy code did it probably needed?
launch {
viewModel.isAuthenticating.collect { isAuthenticating ->
if (isAuthenticating) {
notifyAccessibilityChanged()
}
}
}
// dismiss prompt when authenticated and confirmed
launch {
viewModel.isAuthenticated.collect { authState ->
// Disable background view for cancelling authentication once authenticated,
// and remove from talkback
if (authState.isAuthenticated) {
// Prevents Talkback from speaking subtitle after already authenticated
subtitleView.importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO
backgroundView.setOnClickListener(null)
backgroundView.importantForAccessibility =
IMPORTANT_FOR_ACCESSIBILITY_NO
@@ -349,7 +338,6 @@ object BiometricViewBinder {
view.announceForAccessibility(
view.resources.getString(R.string.biometric_dialog_authenticated)
)
notifyAccessibilityChanged()
launch {
delay(authState.delay)
@@ -381,7 +369,18 @@ object BiometricViewBinder {
!accessibilityManager.isEnabled ||
!accessibilityManager.isTouchExplorationEnabled
notifyAccessibilityChanged()
/**
* Note: Talkback 14.0 has new rate-limitation design to reduce frequency of
* TYPE_WINDOW_CONTENT_CHANGED events to once every 30 seconds. (context:
* b/281765653#comment18) Using {@link View#announceForAccessibility}
* instead as workaround since sending events exceeding this frequency is
* required.
*/
indicatorMessageView?.text?.let {
if (it.isNotBlank()) {
view.announceForAccessibility(it)
}
}
}
}
}