From 033b7e5620eea5e57b0dfeed6586f291ac22ba7a Mon Sep 17 00:00:00 2001 From: MiltonWu Date: Thu, 17 Oct 2024 07:48:37 +0000 Subject: [PATCH] Refine biometrics accessibility interactor 1. support non-flow version isEnabled 2. support send announment Bug: 372385781 Test: Function works w/o build break Flag: EXEMPT feature flag protected on override project Change-Id: I2867edf9e9b9cc9190888e257a203acd7877ab3b --- .../fingerprint2/BiometricsEnvironment.kt | 9 ++--- .../interactor/AccessibilityInteractor.kt | 36 +++++++++++++------ .../interactor/UdfpsEnrollInteractor.kt | 3 +- .../udfps/ui/viewmodel/UdfpsViewModel.kt | 4 +-- .../FingerprintEnrollFindSensorViewModel.kt | 4 +-- .../biometrics/fingerprint/Injector.kt | 6 +++- ...gerprintEnrollFindSensorViewModelV2Test.kt | 6 +++- 7 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt b/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt index 761a9c3a871..50ac3cdcee5 100644 --- a/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt +++ b/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt @@ -133,11 +133,8 @@ class BiometricsEnvironment( 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 @@ class BiometricsEnvironment( 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 e1a08e6cda2..9f62ed03572 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 @@ import kotlinx.coroutines.flow.stateIn /** Represents all of the information on accessibility state. */ interface AccessibilityInteractor { /** A flow that contains whether or not accessibility is enabled */ - val isAccessibilityEnabled: Flow + fun isEnabledFlow(scope: CoroutineScope): Flow + 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 = + override fun isEnabledFlow(scope: CoroutineScope): Flow = 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 006060a54b9..62c51aeb527 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 @@ package com.android.settings.biometrics.fingerprint2.domain.interactor 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 @@ class UdfpsEnrollInteractorImpl( override val guidedEnrollmentOffset: Flow = 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 658c6c747c2..df46aa4c8a5 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 @@ class UdfpsViewModel( /** Indicates if accessibility is enabled */ val accessibilityEnabled = - accessibilityInteractor.isAccessibilityEnabled.shareIn( + accessibilityInteractor.isEnabledFlow(viewModelScope).shareIn( this.viewModelScope, SharingStarted.Eagerly, replay = 1, @@ -425,7 +425,7 @@ class UdfpsViewModel( 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 9b2cdde7cef..b27cfdd2eea 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 @@ class FingerprintEnrollFindSensorViewModel( /** Represents the stream of showing udfps lottie and whether accessibility is enabled. */ val udfpsLottieInfo: Flow = - _showUdfpsLottie.combine(accessibilityInteractor.isAccessibilityEnabled) { + _showUdfpsLottie.combine(accessibilityInteractor.isEnabledFlow(viewModelScope)) { _, isAccessibilityEnabled -> isAccessibilityEnabled @@ -213,7 +213,7 @@ class FingerprintEnrollFindSensorViewModel( 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 e7fc3ed3d66..a5d0461e4a3 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.Fing 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 @@ class Injector(step: FingerprintNavigationStep.UiStep) { var accessibilityInteractor = object : AccessibilityInteractor { - override val isAccessibilityEnabled: Flow = flowOf(true) + override fun isEnabledFlow(scope: CoroutineScope): Flow = 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 04cece83cd0..a8c5e684d33 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.biometrics.fingerprint2.ui.enrollment.viewmodel.Fing 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 @@ class FingerprintEnrollFindSensorViewModelV2Test { ) accessibilityInteractor = object : AccessibilityInteractor { - override val isAccessibilityEnabled: Flow = flowOf(false) + override fun isEnabledFlow(scope: CoroutineScope): Flow = flowOf(true) + override val isEnabled: Boolean + get() = true + override fun announce(clazz: Class<*>, announcement: CharSequence?) {} } foldStateInteractor = object : FoldStateInteractor {