Spit up FingerprintManagerInteractor 2/N
Test: atest, screenshot tests passed Flag: com.android.settings.flags.fingerprint_v2_enrollment Change-Id: I1a2cf61290906e112a5a0129ef7ed3587d14de7e
This commit is contained in:
@@ -58,6 +58,7 @@ import com.android.settings.biometrics.fingerprint2.domain.interactor.SensorInte
|
|||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.TouchEventInteractor
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.TouchEventInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractor
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractorImpl
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractorImpl
|
||||||
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.UserInteractorImpl
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractor
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractorImpl
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractorImpl
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.AuthenitcateInteractor
|
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.AuthenitcateInteractor
|
||||||
@@ -67,6 +68,7 @@ import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.Genera
|
|||||||
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.RemoveFingerprintInteractor
|
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.RemoveFingerprintInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.RenameFingerprintInteractor
|
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.RenameFingerprintInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.SensorInteractor
|
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.SensorInteractor
|
||||||
|
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.UserInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.Settings
|
import com.android.settings.biometrics.fingerprint2.lib.model.Settings
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
@@ -97,11 +99,11 @@ class BiometricsEnvironment(
|
|||||||
com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser
|
com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private val fingerprintEnrollmentRepository =
|
|
||||||
FingerprintEnrollmentRepositoryImpl(fingerprintManager, userRepo, fingerprintSettingsRepository,
|
|
||||||
backgroundDispatcher, applicationScope)
|
|
||||||
private val fingerprintSensorRepository: FingerprintSensorRepository =
|
private val fingerprintSensorRepository: FingerprintSensorRepository =
|
||||||
FingerprintSensorRepositoryImpl(fingerprintManager, backgroundDispatcher, applicationScope)
|
FingerprintSensorRepositoryImpl(fingerprintManager, backgroundDispatcher, applicationScope)
|
||||||
|
private val fingerprintEnrollmentRepository =
|
||||||
|
FingerprintEnrollmentRepositoryImpl(fingerprintManager, userRepo, fingerprintSettingsRepository,
|
||||||
|
backgroundDispatcher, applicationScope, fingerprintSensorRepository)
|
||||||
private val debuggingRepository: DebuggingRepository = DebuggingRepositoryImpl()
|
private val debuggingRepository: DebuggingRepository = DebuggingRepositoryImpl()
|
||||||
private val udfpsDebugRepo = UdfpsEnrollDebugRepositoryImpl()
|
private val udfpsDebugRepo = UdfpsEnrollDebugRepositoryImpl()
|
||||||
|
|
||||||
@@ -118,11 +120,13 @@ class BiometricsEnvironment(
|
|||||||
EnrollFingerprintInteractorImpl(context.userId, fingerprintManager, Settings)
|
EnrollFingerprintInteractorImpl(context.userId, fingerprintManager, Settings)
|
||||||
|
|
||||||
fun createFingerprintsEnrolledInteractor(): EnrolledFingerprintsInteractorImpl =
|
fun createFingerprintsEnrolledInteractor(): EnrolledFingerprintsInteractorImpl =
|
||||||
EnrolledFingerprintsInteractorImpl(fingerprintManager, context.userId)
|
EnrolledFingerprintsInteractorImpl(fingerprintEnrollmentRepository)
|
||||||
|
|
||||||
fun createAuthenticateInteractor(): AuthenitcateInteractor =
|
fun createAuthenticateInteractor(): AuthenitcateInteractor =
|
||||||
AuthenticateInteractorImpl(fingerprintManager, context.userId)
|
AuthenticateInteractorImpl(fingerprintManager, context.userId)
|
||||||
|
|
||||||
|
fun createUserInteractor(): UserInteractor = UserInteractorImpl(userRepo)
|
||||||
|
|
||||||
fun createRemoveFingerprintInteractor(): RemoveFingerprintInteractor =
|
fun createRemoveFingerprintInteractor(): RemoveFingerprintInteractor =
|
||||||
RemoveFingerprintsInteractorImpl(fingerprintManager, context.userId)
|
RemoveFingerprintsInteractorImpl(fingerprintManager, context.userId)
|
||||||
|
|
||||||
|
@@ -23,14 +23,16 @@ import kotlinx.coroutines.CoroutineDispatcher
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.filterNotNull
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
/** Repository that contains information about fingerprint enrollments. */
|
/** Repository that contains information about fingerprint enrollments. */
|
||||||
@@ -38,20 +40,31 @@ interface FingerprintEnrollmentRepository {
|
|||||||
/** The current enrollments of the user */
|
/** The current enrollments of the user */
|
||||||
val currentEnrollments: Flow<List<FingerprintData>?>
|
val currentEnrollments: Flow<List<FingerprintData>?>
|
||||||
|
|
||||||
|
/** Indicates the maximum fingerprints that are enrollable * */
|
||||||
|
val maxFingerprintsEnrollable: Flow<Int>
|
||||||
|
|
||||||
/** Indicates if a user can enroll another fingerprint */
|
/** Indicates if a user can enroll another fingerprint */
|
||||||
val canEnrollUser: Flow<Boolean>
|
val canEnrollUser: Flow<Boolean>
|
||||||
|
|
||||||
fun maxFingerprintsEnrollable(): Int
|
/**
|
||||||
|
* Indicates if we should use the default settings for maximum enrollments or the sensor props
|
||||||
|
* from the fingerprint sensor
|
||||||
|
*/
|
||||||
|
fun setShouldUseSettingsMaxFingerprints(useSettings: Boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FingerprintEnrollmentRepositoryImpl(
|
class FingerprintEnrollmentRepositoryImpl(
|
||||||
fingerprintManager: FingerprintManager,
|
private val fingerprintManager: FingerprintManager,
|
||||||
userRepo: UserRepo,
|
userRepo: UserRepo,
|
||||||
private val settingsRepository: FingerprintSettingsRepository,
|
settingsRepository: FingerprintSettingsRepository,
|
||||||
backgroundDispatcher: CoroutineDispatcher,
|
backgroundDispatcher: CoroutineDispatcher,
|
||||||
applicationScope: CoroutineScope,
|
applicationScope: CoroutineScope,
|
||||||
|
sensorRepo: FingerprintSensorRepository,
|
||||||
) : FingerprintEnrollmentRepository {
|
) : FingerprintEnrollmentRepository {
|
||||||
|
|
||||||
|
private val _shouldUseSettingsMaxFingerprints = MutableStateFlow(false)
|
||||||
|
val shouldUseSettingsMaxFingerprints = _shouldUseSettingsMaxFingerprints.asStateFlow()
|
||||||
|
|
||||||
private val enrollmentChangedFlow: Flow<Int?> =
|
private val enrollmentChangedFlow: Flow<Int?> =
|
||||||
callbackFlow {
|
callbackFlow {
|
||||||
val callback =
|
val callback =
|
||||||
@@ -72,27 +85,34 @@ class FingerprintEnrollmentRepositoryImpl(
|
|||||||
override val currentEnrollments: Flow<List<FingerprintData>> =
|
override val currentEnrollments: Flow<List<FingerprintData>> =
|
||||||
userRepo.currentUser
|
userRepo.currentUser
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.flatMapLatest { currentUser ->
|
.combine(enrollmentChangedFlow) { currentUser, _ -> getFingerprintsForUser(currentUser) }
|
||||||
enrollmentChangedFlow.map { enrollmentChanged ->
|
|
||||||
if (enrollmentChanged == null || enrollmentChanged == currentUser) {
|
|
||||||
fingerprintManager
|
|
||||||
.getEnrolledFingerprints(currentUser)
|
|
||||||
?.map { (FingerprintData(it.name.toString(), it.biometricId, it.deviceId)) }
|
|
||||||
?.toList()
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
.flowOn(backgroundDispatcher)
|
.flowOn(backgroundDispatcher)
|
||||||
|
|
||||||
override val canEnrollUser: Flow<Boolean> =
|
override val maxFingerprintsEnrollable: Flow<Int> =
|
||||||
currentEnrollments.map {
|
shouldUseSettingsMaxFingerprints.combine(sensorRepo.fingerprintSensor) {
|
||||||
it?.size?.let { it < settingsRepository.maxEnrollableFingerprints() } ?: false
|
shouldUseSettings,
|
||||||
|
sensor ->
|
||||||
|
if (shouldUseSettings) {
|
||||||
|
settingsRepository.maxEnrollableFingerprints()
|
||||||
|
} else {
|
||||||
|
sensor.maxEnrollmentsPerUser
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun maxFingerprintsEnrollable(): Int {
|
override val canEnrollUser: Flow<Boolean> =
|
||||||
return settingsRepository.maxEnrollableFingerprints()
|
currentEnrollments.combine(maxFingerprintsEnrollable) { enrollments, maxFingerprints ->
|
||||||
|
enrollments.size < maxFingerprints
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setShouldUseSettingsMaxFingerprints(useSettings: Boolean) {
|
||||||
|
_shouldUseSettingsMaxFingerprints.update { useSettings }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFingerprintsForUser(userId: Int): List<FingerprintData>? {
|
||||||
|
return fingerprintManager
|
||||||
|
.getEnrolledFingerprints(userId)
|
||||||
|
?.map { (FingerprintData(it.name.toString(), it.biometricId, it.deviceId)) }
|
||||||
|
?.toList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,10 @@
|
|||||||
package com.android.settings.biometrics.fingerprint2.data.repository
|
package com.android.settings.biometrics.fingerprint2.data.repository
|
||||||
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A repository responsible for indicating the current user.
|
* A repository responsible for indicating the current user.
|
||||||
@@ -27,8 +30,18 @@ interface UserRepo {
|
|||||||
* This flow indicates the current user.
|
* This flow indicates the current user.
|
||||||
*/
|
*/
|
||||||
val currentUser: Flow<Int>
|
val currentUser: Flow<Int>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current user.
|
||||||
|
*/
|
||||||
|
fun updateUser(user: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserRepoImpl(val currUser: Int): UserRepo {
|
class UserRepoImpl(currUser: Int): UserRepo {
|
||||||
override val currentUser: Flow<Int> = flowOf(currUser)
|
private val _currentUser = MutableStateFlow(currUser)
|
||||||
|
override val currentUser = _currentUser.asStateFlow()
|
||||||
|
|
||||||
|
override fun updateUser(user: Int) {
|
||||||
|
_currentUser.update { user }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,11 +21,14 @@ import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.CanEnr
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
class CanEnrollFingerprintsInteractorImpl(
|
class CanEnrollFingerprintsInteractorImpl(
|
||||||
val fingerprintEnrollmentRepository: FingerprintEnrollmentRepository
|
private val fingerprintEnrollmentRepository: FingerprintEnrollmentRepository
|
||||||
) : CanEnrollFingerprintsInteractor {
|
) : CanEnrollFingerprintsInteractor {
|
||||||
override val canEnrollFingerprints: Flow<Boolean> = fingerprintEnrollmentRepository.canEnrollUser
|
override val canEnrollFingerprints: Flow<Boolean> = fingerprintEnrollmentRepository.canEnrollUser
|
||||||
/** Indicates the maximum fingerprints enrollable for a given user */
|
/** Indicates the maximum fingerprints enrollable for a given user */
|
||||||
override fun maxFingerprintsEnrollable(): Int {
|
override val maxFingerprintsEnrollable: Flow<Int> =
|
||||||
return fingerprintEnrollmentRepository.maxFingerprintsEnrollable()
|
fingerprintEnrollmentRepository.maxFingerprintsEnrollable
|
||||||
|
|
||||||
|
override fun setShouldUseSettingsMaxFingerprints(useSettings: Boolean) {
|
||||||
|
fingerprintEnrollmentRepository.setShouldUseSettingsMaxFingerprints(useSettings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,22 +16,14 @@
|
|||||||
|
|
||||||
package com.android.settings.biometrics.fingerprint2.domain.interactor
|
package com.android.settings.biometrics.fingerprint2.domain.interactor
|
||||||
|
|
||||||
import android.hardware.fingerprint.FingerprintManager
|
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintEnrollmentRepository
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.EnrolledFingerprintsInteractor
|
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.EnrolledFingerprintsInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
|
import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
|
|
||||||
class EnrolledFingerprintsInteractorImpl(
|
class EnrolledFingerprintsInteractorImpl(
|
||||||
private val fingerprintManager: FingerprintManager,
|
private val fingerprintEnrollmentRepository: FingerprintEnrollmentRepository
|
||||||
userId: Int,
|
|
||||||
) : EnrolledFingerprintsInteractor {
|
) : EnrolledFingerprintsInteractor {
|
||||||
override val enrolledFingerprints: Flow<List<FingerprintData>?> = flow {
|
override val enrolledFingerprints: Flow<List<FingerprintData>?> =
|
||||||
emit(
|
fingerprintEnrollmentRepository.currentEnrollments
|
||||||
fingerprintManager
|
|
||||||
.getEnrolledFingerprints(userId)
|
|
||||||
?.map { (FingerprintData(it.name.toString(), it.biometricId, it.deviceId)) }
|
|
||||||
?.toList()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.biometrics.fingerprint2.domain.interactor
|
||||||
|
|
||||||
|
import com.android.settings.biometrics.fingerprint2.data.repository.UserRepo
|
||||||
|
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.UserInteractor
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class UserInteractorImpl(private val userRepo: UserRepo) : UserInteractor {
|
||||||
|
override val currentUser: Flow<Int> = userRepo.currentUser
|
||||||
|
|
||||||
|
override fun updateUser(user: Int) = userRepo.updateUser(user)
|
||||||
|
}
|
@@ -23,5 +23,17 @@ interface CanEnrollFingerprintsInteractor {
|
|||||||
/** Returns true if a user can enroll a fingerprint false otherwise. */
|
/** Returns true if a user can enroll a fingerprint false otherwise. */
|
||||||
val canEnrollFingerprints: Flow<Boolean>
|
val canEnrollFingerprints: Flow<Boolean>
|
||||||
/** Indicates the maximum fingerprints enrollable for a given user */
|
/** Indicates the maximum fingerprints enrollable for a given user */
|
||||||
fun maxFingerprintsEnrollable(): Int
|
val maxFingerprintsEnrollable: Flow<Int>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if we should use the default settings for maximum enrollments or the sensor props
|
||||||
|
* from the fingerprint sensor. This can be useful if you are supporting HIDL & AIDL enrollment
|
||||||
|
* types from one code base. Prior to AIDL there was no way to determine how many
|
||||||
|
* fingerprints were enrollable, Settings relied on
|
||||||
|
* com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser.
|
||||||
|
*
|
||||||
|
* Typically Fingerprints with AIDL HAL's should not use this
|
||||||
|
* (setShouldUseSettingsMaxFingerprints(false))
|
||||||
|
*/
|
||||||
|
fun setShouldUseSettingsMaxFingerprints(useSettings: Boolean)
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.biometrics.fingerprint2.lib.domain.interactor
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
interface UserInteractor {
|
||||||
|
/**
|
||||||
|
* This flow indicates the current user.
|
||||||
|
*/
|
||||||
|
val currentUser: Flow<Int>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current user.
|
||||||
|
*/
|
||||||
|
fun updateUser(user: Int)
|
||||||
|
}
|
@@ -43,7 +43,6 @@ import kotlinx.coroutines.flow.first
|
|||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.sample
|
import kotlinx.coroutines.flow.sample
|
||||||
import kotlinx.coroutines.flow.transform
|
|
||||||
import kotlinx.coroutines.flow.transformLatest
|
import kotlinx.coroutines.flow.transformLatest
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -72,10 +71,12 @@ class FingerprintSettingsViewModel(
|
|||||||
|
|
||||||
/** Represents the stream of the information of "Add Fingerprint" preference. */
|
/** Represents the stream of the information of "Add Fingerprint" preference. */
|
||||||
val addFingerprintPrefInfo: Flow<Pair<Boolean, Int>> =
|
val addFingerprintPrefInfo: Flow<Pair<Boolean, Int>> =
|
||||||
_enrolledFingerprints.filterOnlyWhenSettingsIsShown().combine(
|
combine(
|
||||||
canEnrollFingerprintsInteractor.canEnrollFingerprints
|
_enrolledFingerprints.filterOnlyWhenSettingsIsShown(),
|
||||||
) { _, canEnrollFingerprints ->
|
canEnrollFingerprintsInteractor.canEnrollFingerprints,
|
||||||
Pair(canEnrollFingerprints, canEnrollFingerprintsInteractor.maxFingerprintsEnrollable())
|
canEnrollFingerprintsInteractor.maxFingerprintsEnrollable,
|
||||||
|
) { _, canEnrollFingerprints, maxFingerprints ->
|
||||||
|
Pair(canEnrollFingerprints, maxFingerprints)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Represents the stream of visibility of sfps preference. */
|
/** Represents the stream of visibility of sfps preference. */
|
||||||
|
@@ -38,8 +38,12 @@ import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
|||||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.flow.transform
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
|
||||||
/** Fake to be used by other classes to easily fake the FingerprintManager implementation. */
|
/** Fake to be used by other classes to easily fake the FingerprintManager implementation. */
|
||||||
class FakeFingerprintManagerInteractor :
|
class FakeFingerprintManagerInteractor :
|
||||||
@@ -52,7 +56,7 @@ class FakeFingerprintManagerInteractor :
|
|||||||
RenameFingerprintInteractor,
|
RenameFingerprintInteractor,
|
||||||
SensorInteractor {
|
SensorInteractor {
|
||||||
|
|
||||||
var enrollableFingerprints: Int = 5
|
private val enrollableFingerprints = MutableStateFlow(5)
|
||||||
var enrolledFingerprintsInternal: MutableList<FingerprintData> = mutableListOf()
|
var enrolledFingerprintsInternal: MutableList<FingerprintData> = mutableListOf()
|
||||||
var challengeToGenerate: Pair<Long, ByteArray> = Pair(-1L, byteArrayOf())
|
var challengeToGenerate: Pair<Long, ByteArray> = Pair(-1L, byteArrayOf())
|
||||||
var authenticateAttempt = FingerprintAuthAttemptModel.Success(1)
|
var authenticateAttempt = FingerprintAuthAttemptModel.Success(1)
|
||||||
@@ -82,13 +86,13 @@ class FakeFingerprintManagerInteractor :
|
|||||||
override val enrolledFingerprints: Flow<List<FingerprintData>> = flow {
|
override val enrolledFingerprints: Flow<List<FingerprintData>> = flow {
|
||||||
emit(enrolledFingerprintsInternal)
|
emit(enrolledFingerprintsInternal)
|
||||||
}
|
}
|
||||||
override val canEnrollFingerprints: Flow<Boolean> = flow {
|
override val canEnrollFingerprints: Flow<Boolean> = enrollableFingerprints.transform {
|
||||||
emit(enrolledFingerprintsInternal.size < enrollableFingerprints)
|
emit(enrolledFingerprintsInternal.size < it)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun maxFingerprintsEnrollable(): Int {
|
override val maxFingerprintsEnrollable: Flow<Int> = enrollableFingerprints.asStateFlow()
|
||||||
return enrollableFingerprints
|
|
||||||
}
|
override fun setShouldUseSettingsMaxFingerprints(useSettings: Boolean) {}
|
||||||
|
|
||||||
override val sensorPropertiesInternal: Flow<FingerprintSensor?> = flow { emit(sensorProp) }
|
override val sensorPropertiesInternal: Flow<FingerprintSensor?> = flow { emit(sensorProp) }
|
||||||
override val hasSideFps: Flow<Boolean> =
|
override val hasSideFps: Flow<Boolean> =
|
||||||
@@ -110,4 +114,7 @@ class FakeFingerprintManagerInteractor :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setMaxEnrollableFingerprints(fingerprints: Int) {
|
||||||
|
enrollableFingerprints.update { fingerprints }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
|||||||
import android.os.CancellationSignal
|
import android.os.CancellationSignal
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import com.android.settings.biometrics.GatekeeperPasswordProvider
|
import com.android.settings.biometrics.GatekeeperPasswordProvider
|
||||||
|
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintEnrollmentRepository
|
||||||
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintEnrollmentRepositoryImpl
|
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintEnrollmentRepositoryImpl
|
||||||
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
|
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
|
||||||
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSettingsRepositoryImpl
|
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSettingsRepositoryImpl
|
||||||
@@ -61,7 +62,7 @@ import kotlinx.coroutines.cancelAndJoin
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.last
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
@@ -106,9 +107,14 @@ class FingerprintManagerInteractorTest {
|
|||||||
private val flow: FingerprintFlow = Default
|
private val flow: FingerprintFlow = Default
|
||||||
private val maxFingerprints = 5
|
private val maxFingerprints = 5
|
||||||
private val currUser = MutableStateFlow(0)
|
private val currUser = MutableStateFlow(0)
|
||||||
|
private lateinit var fingerprintEnrollRepo: FingerprintEnrollmentRepository
|
||||||
private val userRepo =
|
private val userRepo =
|
||||||
object : UserRepo {
|
object : UserRepo {
|
||||||
override val currentUser: Flow<Int> = currUser
|
override val currentUser: Flow<Int> = currUser
|
||||||
|
|
||||||
|
override fun updateUser(user: Int) {
|
||||||
|
currUser.update { user }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -133,17 +139,18 @@ class FingerprintManagerInteractorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val settingsRepository = FingerprintSettingsRepositoryImpl(maxFingerprints)
|
val settingsRepository = FingerprintSettingsRepositoryImpl(maxFingerprints)
|
||||||
val fingerprintEnrollmentRepository =
|
fingerprintEnrollRepo =
|
||||||
FingerprintEnrollmentRepositoryImpl(
|
FingerprintEnrollmentRepositoryImpl(
|
||||||
fingerprintManager,
|
fingerprintManager,
|
||||||
userRepo,
|
userRepo,
|
||||||
settingsRepository,
|
settingsRepository,
|
||||||
backgroundDispatcher,
|
backgroundDispatcher,
|
||||||
backgroundScope,
|
backgroundScope,
|
||||||
|
fingerprintSensorRepository,
|
||||||
)
|
)
|
||||||
|
|
||||||
enrolledFingerprintsInteractorUnderTest =
|
enrolledFingerprintsInteractorUnderTest =
|
||||||
EnrolledFingerprintsInteractorImpl(fingerprintManager, userId)
|
EnrolledFingerprintsInteractorImpl(fingerprintEnrollRepo)
|
||||||
generateChallengeInteractorUnderTest =
|
generateChallengeInteractorUnderTest =
|
||||||
GenerateChallengeInteractorImpl(fingerprintManager, userId, gateKeeperPasswordProvider)
|
GenerateChallengeInteractorImpl(fingerprintManager, userId, gateKeeperPasswordProvider)
|
||||||
removeFingerprintsInteractorUnderTest =
|
removeFingerprintsInteractorUnderTest =
|
||||||
@@ -153,7 +160,7 @@ class FingerprintManagerInteractorTest {
|
|||||||
authenticateInteractorImplUnderTest = AuthenticateInteractorImpl(fingerprintManager, userId)
|
authenticateInteractorImplUnderTest = AuthenticateInteractorImpl(fingerprintManager, userId)
|
||||||
|
|
||||||
canEnrollFingerprintsInteractorUnderTest =
|
canEnrollFingerprintsInteractorUnderTest =
|
||||||
CanEnrollFingerprintsInteractorImpl(fingerprintEnrollmentRepository)
|
CanEnrollFingerprintsInteractorImpl(fingerprintEnrollRepo)
|
||||||
|
|
||||||
enrollInteractorUnderTest = EnrollFingerprintInteractorImpl(userId, fingerprintManager, flow)
|
enrollInteractorUnderTest = EnrollFingerprintInteractorImpl(userId, fingerprintManager, flow)
|
||||||
}
|
}
|
||||||
@@ -163,9 +170,16 @@ class FingerprintManagerInteractorTest {
|
|||||||
testScope.runTest {
|
testScope.runTest {
|
||||||
whenever(fingerprintManager.getEnrolledFingerprints(anyInt())).thenReturn(emptyList())
|
whenever(fingerprintManager.getEnrolledFingerprints(anyInt())).thenReturn(emptyList())
|
||||||
|
|
||||||
val emptyFingerprintList: List<Fingerprint> = emptyList()
|
var list: List<FingerprintData>? = null
|
||||||
assertThat(enrolledFingerprintsInteractorUnderTest.enrolledFingerprints.last())
|
val job =
|
||||||
.isEqualTo(emptyFingerprintList)
|
testScope.launch {
|
||||||
|
enrolledFingerprintsInteractorUnderTest.enrolledFingerprints.collect { list = it }
|
||||||
|
}
|
||||||
|
|
||||||
|
runCurrent()
|
||||||
|
job.cancelAndJoin()
|
||||||
|
|
||||||
|
assertThat(list!!.isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -174,10 +188,19 @@ class FingerprintManagerInteractorTest {
|
|||||||
val expected = Fingerprint("Finger 1,", 2, 3L)
|
val expected = Fingerprint("Finger 1,", 2, 3L)
|
||||||
val fingerprintList: List<Fingerprint> = listOf(expected)
|
val fingerprintList: List<Fingerprint> = listOf(expected)
|
||||||
whenever(fingerprintManager.getEnrolledFingerprints(anyInt())).thenReturn(fingerprintList)
|
whenever(fingerprintManager.getEnrolledFingerprints(anyInt())).thenReturn(fingerprintList)
|
||||||
|
// This causes the enrolled fingerprints to be updated
|
||||||
|
|
||||||
|
var list: List<FingerprintData>? = null
|
||||||
|
val job =
|
||||||
|
testScope.launch {
|
||||||
|
enrolledFingerprintsInteractorUnderTest.enrolledFingerprints.collect { list = it }
|
||||||
|
}
|
||||||
|
|
||||||
|
runCurrent()
|
||||||
|
job.cancelAndJoin()
|
||||||
|
|
||||||
val list = enrolledFingerprintsInteractorUnderTest.enrolledFingerprints.last()
|
|
||||||
assertThat(list!!.size).isEqualTo(fingerprintList.size)
|
assertThat(list!!.size).isEqualTo(fingerprintList.size)
|
||||||
val actual = list[0]
|
val actual = list!![0]
|
||||||
assertThat(actual.name).isEqualTo(expected.name)
|
assertThat(actual.name).isEqualTo(expected.name)
|
||||||
assertThat(actual.fingerId).isEqualTo(expected.biometricId)
|
assertThat(actual.fingerId).isEqualTo(expected.biometricId)
|
||||||
assertThat(actual.deviceId).isEqualTo(expected.deviceId)
|
assertThat(actual.deviceId).isEqualTo(expected.deviceId)
|
||||||
@@ -220,11 +243,7 @@ class FingerprintManagerInteractorTest {
|
|||||||
whenever(fingerprintManager.getEnrolledFingerprints(anyInt())).thenReturn(fingerprintList)
|
whenever(fingerprintManager.getEnrolledFingerprints(anyInt())).thenReturn(fingerprintList)
|
||||||
|
|
||||||
var result: Boolean? = null
|
var result: Boolean? = null
|
||||||
val job =
|
val job = testScope.launch { fingerprintEnrollRepo.canEnrollUser.collect { result = it } }
|
||||||
testScope.launch {
|
|
||||||
canEnrollFingerprintsInteractorUnderTest.canEnrollFingerprints.collect { result = it }
|
|
||||||
}
|
|
||||||
|
|
||||||
runCurrent()
|
runCurrent()
|
||||||
job.cancelAndJoin()
|
job.cancelAndJoin()
|
||||||
|
|
||||||
|
@@ -112,7 +112,7 @@ class FingerprintEnrollConfirmationViewModelTest {
|
|||||||
.toFingerprintSensor()
|
.toFingerprintSensor()
|
||||||
|
|
||||||
fakeFingerprintManagerInteractor.enrolledFingerprintsInternal = mutableListOf()
|
fakeFingerprintManagerInteractor.enrolledFingerprintsInternal = mutableListOf()
|
||||||
fakeFingerprintManagerInteractor.enrollableFingerprints = 5
|
fakeFingerprintManagerInteractor.setMaxEnrollableFingerprints(5)
|
||||||
|
|
||||||
var canEnrollFingerprints: Boolean = false
|
var canEnrollFingerprints: Boolean = false
|
||||||
val job = launch {
|
val job = launch {
|
||||||
|
Reference in New Issue
Block a user