Merge "Refine biometrics accessibility interactor" into main

This commit is contained in:
Treehugger Robot
2024-10-18 07:35:36 +00:00
committed by Android (Google) Code Review
7 changed files with 44 additions and 24 deletions

View File

@@ -133,11 +133,8 @@ class BiometricsEnvironment(
fun createRenameFingerprintInteractor(): RenameFingerprintInteractor = fun createRenameFingerprintInteractor(): RenameFingerprintInteractor =
RenameFingerprintsInteractorImpl(fingerprintManager, context.userId, backgroundDispatcher) RenameFingerprintsInteractorImpl(fingerprintManager, context.userId, backgroundDispatcher)
val accessibilityInteractor: AccessibilityInteractor by lazy { fun createAccessibilityInteractor(): AccessibilityInteractor {
AccessibilityInteractorImpl( return AccessibilityInteractorImpl(context.getSystemService(AccessibilityManager::class.java)!!)
context.getSystemService(AccessibilityManager::class.java)!!,
applicationScope,
)
} }
val foldStateInteractor: FoldStateInteractor by lazy { FoldStateInteractorImpl(context) } val foldStateInteractor: FoldStateInteractor by lazy { FoldStateInteractorImpl(context) }
@@ -157,7 +154,7 @@ class BiometricsEnvironment(
val enrollStageInteractor: EnrollStageInteractor by lazy { EnrollStageInteractorImpl() } val enrollStageInteractor: EnrollStageInteractor by lazy { EnrollStageInteractorImpl() }
val udfpsEnrollInteractor: UdfpsEnrollInteractor by lazy { val udfpsEnrollInteractor: UdfpsEnrollInteractor by lazy {
UdfpsEnrollInteractorImpl(context, accessibilityInteractor) UdfpsEnrollInteractorImpl(context, createAccessibilityInteractor())
} }
val sensorInteractor: FingerprintSensorInteractor by lazy { val sensorInteractor: FingerprintSensorInteractor by lazy {

View File

@@ -16,6 +16,8 @@
package com.android.settings.biometrics.fingerprint2.domain.interactor 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 android.view.accessibility.AccessibilityManager
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
@@ -27,26 +29,38 @@ import kotlinx.coroutines.flow.stateIn
/** Represents all of the information on accessibility state. */ /** Represents all of the information on accessibility state. */
interface AccessibilityInteractor { interface AccessibilityInteractor {
/** A flow that contains whether or not accessibility is enabled */ /** 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( class AccessibilityInteractorImpl(
accessibilityManager: AccessibilityManager, private val accessibilityManager: AccessibilityManager,
applicationScope: CoroutineScope,
) : AccessibilityInteractor { ) : AccessibilityInteractor {
/** A flow that contains whether or not accessibility is enabled */ /** A flow that contains whether or not accessibility is enabled */
override val isAccessibilityEnabled: Flow<Boolean> = override fun isEnabledFlow(scope: CoroutineScope): Flow<Boolean> =
callbackFlow { callbackFlow {
val listener = val listener =
AccessibilityManager.AccessibilityStateChangeListener { enabled -> trySend(enabled) } AccessibilityManager.AccessibilityStateChangeListener { enabled -> trySend(enabled) }
accessibilityManager.addAccessibilityStateChangeListener(listener) accessibilityManager.addAccessibilityStateChangeListener(listener)
// This clause will be called when no one is listening to the flow // This clause will be called when no one is listening to the flow
awaitClose { accessibilityManager.removeAccessibilityStateChangeListener(listener) } awaitClose { accessibilityManager.removeAccessibilityStateChangeListener(listener) }
} }
.stateIn( .stateIn(
applicationScope, // This is going to tied to the activity scope scope,
SharingStarted.WhileSubscribed(), // When no longer subscribed, we removeTheListener SharingStarted.WhileSubscribed(), // When no longer subscribed, we removeTheListener
false, 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)
}
} }

View File

@@ -19,6 +19,7 @@ package com.android.settings.biometrics.fingerprint2.domain.interactor
import android.content.Context import android.content.Context
import android.graphics.PointF import android.graphics.PointF
import android.util.TypedValue import android.util.TypedValue
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
@@ -87,7 +88,7 @@ class UdfpsEnrollInteractorImpl(
override val guidedEnrollmentOffset: Flow<PointF> = override val guidedEnrollmentOffset: Flow<PointF> =
combine( combine(
_guidedEnrollment, _guidedEnrollment,
accessibilityInteractor.isAccessibilityEnabled, accessibilityInteractor.isEnabledFlow(MainScope()),
isGuidedEnrollment, isGuidedEnrollment,
) { point, accessibilityEnabled, guidedEnrollmentEnabled -> ) { point, accessibilityEnabled, guidedEnrollmentEnabled ->
if (accessibilityEnabled || !guidedEnrollmentEnabled) { if (accessibilityEnabled || !guidedEnrollmentEnabled) {

View File

@@ -179,7 +179,7 @@ class UdfpsViewModel(
/** Indicates if accessibility is enabled */ /** Indicates if accessibility is enabled */
val accessibilityEnabled = val accessibilityEnabled =
accessibilityInteractor.isAccessibilityEnabled.shareIn( accessibilityInteractor.isEnabledFlow(viewModelScope).shareIn(
this.viewModelScope, this.viewModelScope,
SharingStarted.Eagerly, SharingStarted.Eagerly,
replay = 1, replay = 1,
@@ -425,7 +425,7 @@ class UdfpsViewModel(
biometricEnvironment.enrollStageInteractor, biometricEnvironment.enrollStageInteractor,
biometricEnvironment.orientationInteractor, biometricEnvironment.orientationInteractor,
biometricEnvironment.udfpsEnrollInteractor, biometricEnvironment.udfpsEnrollInteractor,
biometricEnvironment.accessibilityInteractor, biometricEnvironment.createAccessibilityInteractor(),
biometricEnvironment.sensorInteractor, biometricEnvironment.sensorInteractor,
biometricEnvironment.touchEventInteractor, biometricEnvironment.touchEventInteractor,
biometricEnvironment.createSensorPropertiesInteractor(), biometricEnvironment.createSensorPropertiesInteractor(),

View File

@@ -84,7 +84,7 @@ class FingerprintEnrollFindSensorViewModel(
/** Represents the stream of showing udfps lottie and whether accessibility is enabled. */ /** Represents the stream of showing udfps lottie and whether accessibility is enabled. */
val udfpsLottieInfo: Flow<Boolean> = val udfpsLottieInfo: Flow<Boolean> =
_showUdfpsLottie.combine(accessibilityInteractor.isAccessibilityEnabled) { _showUdfpsLottie.combine(accessibilityInteractor.isEnabledFlow(viewModelScope)) {
_, _,
isAccessibilityEnabled -> isAccessibilityEnabled ->
isAccessibilityEnabled isAccessibilityEnabled
@@ -213,7 +213,7 @@ class FingerprintEnrollFindSensorViewModel(
provider[FingerprintGatekeeperViewModel::class], provider[FingerprintGatekeeperViewModel::class],
provider[BackgroundViewModel::class], provider[BackgroundViewModel::class],
provider[FingerprintFlowViewModel::class], provider[FingerprintFlowViewModel::class],
biometricEnvironment.accessibilityInteractor, biometricEnvironment.createAccessibilityInteractor(),
biometricEnvironment.foldStateInteractor, biometricEnvironment.foldStateInteractor,
biometricEnvironment.orientationInteractor, biometricEnvironment.orientationInteractor,
biometricEnvironment.createSensorPropertiesInteractor(), biometricEnvironment.createSensorPropertiesInteractor(),

View File

@@ -44,6 +44,7 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Fing
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
import com.android.settings.testutils2.FakeFingerprintManagerInteractor import com.android.settings.testutils2.FakeFingerprintManagerInteractor
import com.android.systemui.biometrics.shared.model.toFingerprintSensor import com.android.systemui.biometrics.shared.model.toFingerprintSensor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
@@ -73,7 +74,10 @@ class Injector(step: FingerprintNavigationStep.UiStep) {
var accessibilityInteractor = var accessibilityInteractor =
object : 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 = var foldStateInteractor =

View File

@@ -39,6 +39,7 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Fing
import com.android.settings.testutils2.FakeFingerprintManagerInteractor import com.android.settings.testutils2.FakeFingerprintManagerInteractor
import com.android.systemui.biometrics.shared.model.toFingerprintSensor import com.android.systemui.biometrics.shared.model.toFingerprintSensor
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@@ -106,7 +107,10 @@ class FingerprintEnrollFindSensorViewModelV2Test {
) )
accessibilityInteractor = accessibilityInteractor =
object : 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 = foldStateInteractor =
object : FoldStateInteractor { object : FoldStateInteractor {