Merge "Refine biometrics accessibility interactor" into main
diff --git a/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt b/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt
index 761a9c3..50ac3cd 100644
--- a/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt
@@ -133,11 +133,8 @@
fun createRenameFingerprintInteractor(): RenameFingerprintInteractor =
RenameFingerprintsInteractorImpl(fingerprintManager, context.userId, backgroundDispatcher)
- val accessibilityInteractor: AccessibilityInteractor by lazy {
- AccessibilityInteractorImpl(
- context.getSystemService(AccessibilityManager::class.java)!!,
- applicationScope,
- )
+ fun createAccessibilityInteractor(): AccessibilityInteractor {
+ return AccessibilityInteractorImpl(context.getSystemService(AccessibilityManager::class.java)!!)
}
val foldStateInteractor: FoldStateInteractor by lazy { FoldStateInteractorImpl(context) }
@@ -157,7 +154,7 @@
val enrollStageInteractor: EnrollStageInteractor by lazy { EnrollStageInteractorImpl() }
val udfpsEnrollInteractor: UdfpsEnrollInteractor by lazy {
- UdfpsEnrollInteractorImpl(context, accessibilityInteractor)
+ UdfpsEnrollInteractorImpl(context, createAccessibilityInteractor())
}
val sensorInteractor: FingerprintSensorInteractor by lazy {
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
index e1a08e6..9f62ed0 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
@@ -16,6 +16,8 @@
package com.android.settings.biometrics.fingerprint2.domain.interactor
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityEvent.TYPE_ANNOUNCEMENT
import android.view.accessibility.AccessibilityManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
@@ -27,26 +29,38 @@
/** Represents all of the information on accessibility state. */
interface AccessibilityInteractor {
/** A flow that contains whether or not accessibility is enabled */
- val isAccessibilityEnabled: Flow<Boolean>
+ fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean>
+ val isEnabled: Boolean
+ fun announce(clazz: Class<*>, announcement: CharSequence?)
}
class AccessibilityInteractorImpl(
- accessibilityManager: AccessibilityManager,
- applicationScope: CoroutineScope,
+ private val accessibilityManager: AccessibilityManager,
) : AccessibilityInteractor {
/** A flow that contains whether or not accessibility is enabled */
- override val isAccessibilityEnabled: Flow<Boolean> =
+ override fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean> =
callbackFlow {
- val listener =
- AccessibilityManager.AccessibilityStateChangeListener { enabled -> trySend(enabled) }
- accessibilityManager.addAccessibilityStateChangeListener(listener)
+ val listener =
+ AccessibilityManager.AccessibilityStateChangeListener { enabled -> trySend(enabled) }
+ accessibilityManager.addAccessibilityStateChangeListener(listener)
- // This clause will be called when no one is listening to the flow
- awaitClose { accessibilityManager.removeAccessibilityStateChangeListener(listener) }
- }
+ // This clause will be called when no one is listening to the flow
+ awaitClose { accessibilityManager.removeAccessibilityStateChangeListener(listener) }
+ }
.stateIn(
- applicationScope, // This is going to tied to the activity scope
+ scope,
SharingStarted.WhileSubscribed(), // When no longer subscribed, we removeTheListener
false,
)
+
+ override val isEnabled: Boolean
+ get() = accessibilityManager.isEnabled
+
+ override fun announce(clazz: Class<*>, announcement: CharSequence?) {
+ val event = AccessibilityEvent(TYPE_ANNOUNCEMENT)
+ event.className = clazz.javaClass.name
+ event.packageName = clazz.packageName
+ event.text.add(announcement)
+ accessibilityManager.sendAccessibilityEvent(event)
+ }
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/UdfpsEnrollInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/UdfpsEnrollInteractor.kt
index 006060a..62c51ae 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/UdfpsEnrollInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/UdfpsEnrollInteractor.kt
@@ -19,6 +19,7 @@
import android.content.Context
import android.graphics.PointF
import android.util.TypedValue
+import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
@@ -87,7 +88,7 @@
override val guidedEnrollmentOffset: Flow<PointF> =
combine(
_guidedEnrollment,
- accessibilityInteractor.isAccessibilityEnabled,
+ accessibilityInteractor.isEnabledFlow(MainScope()),
isGuidedEnrollment,
) { point, accessibilityEnabled, guidedEnrollmentEnabled ->
if (accessibilityEnabled || !guidedEnrollmentEnabled) {
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsViewModel.kt
index 658c6c7..df46aa4 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsViewModel.kt
@@ -179,7 +179,7 @@
/** Indicates if accessibility is enabled */
val accessibilityEnabled =
- accessibilityInteractor.isAccessibilityEnabled.shareIn(
+ accessibilityInteractor.isEnabledFlow(viewModelScope).shareIn(
this.viewModelScope,
SharingStarted.Eagerly,
replay = 1,
@@ -425,7 +425,7 @@
biometricEnvironment.enrollStageInteractor,
biometricEnvironment.orientationInteractor,
biometricEnvironment.udfpsEnrollInteractor,
- biometricEnvironment.accessibilityInteractor,
+ biometricEnvironment.createAccessibilityInteractor(),
biometricEnvironment.sensorInteractor,
biometricEnvironment.touchEventInteractor,
biometricEnvironment.createSensorPropertiesInteractor(),
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollFindSensorViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollFindSensorViewModel.kt
index 9b2cdde..b27cfdd 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollFindSensorViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollFindSensorViewModel.kt
@@ -84,7 +84,7 @@
/** Represents the stream of showing udfps lottie and whether accessibility is enabled. */
val udfpsLottieInfo: Flow<Boolean> =
- _showUdfpsLottie.combine(accessibilityInteractor.isAccessibilityEnabled) {
+ _showUdfpsLottie.combine(accessibilityInteractor.isEnabledFlow(viewModelScope)) {
_,
isAccessibilityEnabled ->
isAccessibilityEnabled
@@ -213,7 +213,7 @@
provider[FingerprintGatekeeperViewModel::class],
provider[BackgroundViewModel::class],
provider[FingerprintFlowViewModel::class],
- biometricEnvironment.accessibilityInteractor,
+ biometricEnvironment.createAccessibilityInteractor(),
biometricEnvironment.foldStateInteractor,
biometricEnvironment.orientationInteractor,
biometricEnvironment.createSensorPropertiesInteractor(),
diff --git a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
index e7fc3ed..a5d0461 100644
--- a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
+++ b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
@@ -44,6 +44,7 @@
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
import com.android.settings.testutils2.FakeFingerprintManagerInteractor
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -73,7 +74,10 @@
var accessibilityInteractor =
object : AccessibilityInteractor {
- override val isAccessibilityEnabled: Flow<Boolean> = flowOf(true)
+ override fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean> = flowOf(true)
+ override val isEnabled: Boolean
+ get() = true
+ override fun announce(clazz: Class<*>, announcement: CharSequence?) {}
}
var foldStateInteractor =
diff --git a/tests/unit/src/com/android/settings/fingerprint2/enrollment/viewmodel/FingerprintEnrollFindSensorViewModelV2Test.kt b/tests/unit/src/com/android/settings/fingerprint2/enrollment/viewmodel/FingerprintEnrollFindSensorViewModelV2Test.kt
index 04cece8..a8c5e68 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/enrollment/viewmodel/FingerprintEnrollFindSensorViewModelV2Test.kt
+++ b/tests/unit/src/com/android/settings/fingerprint2/enrollment/viewmodel/FingerprintEnrollFindSensorViewModelV2Test.kt
@@ -39,6 +39,7 @@
import com.android.settings.testutils2.FakeFingerprintManagerInteractor
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -106,7 +107,10 @@
)
accessibilityInteractor =
object : AccessibilityInteractor {
- override val isAccessibilityEnabled: Flow<Boolean> = flowOf(false)
+ override fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean> = flowOf(true)
+ override val isEnabled: Boolean
+ get() = true
+ override fun announce(clazz: Class<*>, announcement: CharSequence?) {}
}
foldStateInteractor =
object : FoldStateInteractor {