Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6383e738 authored by Joshua McCloskey's avatar Joshua McCloskey
Browse files

Spit up FingerprintManagerInteractor 2/N

Test: atest, screenshot tests passed
Flag: com.android.settings.flags.fingerprint_v2_enrollment
Change-Id: I1a2cf61290906e112a5a0129ef7ed3587d14de7e
parent d0ea9bc2
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -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.UdfpsEnrollInteractor
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.VibrationInteractorImpl
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.RenameFingerprintInteractor
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 java.util.concurrent.Executors
import kotlinx.coroutines.MainScope
@@ -97,11 +99,11 @@ class BiometricsEnvironment(
        com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser
      )
    )
  private val fingerprintEnrollmentRepository =
    FingerprintEnrollmentRepositoryImpl(fingerprintManager, userRepo, fingerprintSettingsRepository,
      backgroundDispatcher, applicationScope)
  private val fingerprintSensorRepository: FingerprintSensorRepository =
    FingerprintSensorRepositoryImpl(fingerprintManager, backgroundDispatcher, applicationScope)
  private val fingerprintEnrollmentRepository =
    FingerprintEnrollmentRepositoryImpl(fingerprintManager, userRepo, fingerprintSettingsRepository,
      backgroundDispatcher, applicationScope, fingerprintSensorRepository)
  private val debuggingRepository: DebuggingRepository = DebuggingRepositoryImpl()
  private val udfpsDebugRepo = UdfpsEnrollDebugRepositoryImpl()

@@ -118,11 +120,13 @@ class BiometricsEnvironment(
    EnrollFingerprintInteractorImpl(context.userId, fingerprintManager, Settings)

  fun createFingerprintsEnrolledInteractor(): EnrolledFingerprintsInteractorImpl =
    EnrolledFingerprintsInteractorImpl(fingerprintManager, context.userId)
    EnrolledFingerprintsInteractorImpl(fingerprintEnrollmentRepository)

  fun createAuthenticateInteractor(): AuthenitcateInteractor =
    AuthenticateInteractorImpl(fingerprintManager, context.userId)

  fun createUserInteractor(): UserInteractor = UserInteractorImpl(userRepo)

  fun createRemoveFingerprintInteractor(): RemoveFingerprintInteractor =
    RemoveFingerprintsInteractorImpl(fingerprintManager, context.userId)

+41 −21
Original line number Diff line number Diff line
@@ -23,14 +23,16 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.withContext

/** Repository that contains information about fingerprint enrollments. */
@@ -38,20 +40,31 @@ interface FingerprintEnrollmentRepository {
  /** The current enrollments of the user */
  val currentEnrollments: Flow<List<FingerprintData>?>

  /** Indicates the maximum fingerprints that are enrollable * */
  val maxFingerprintsEnrollable: Flow<Int>

  /** Indicates if a user can enroll another fingerprint */
  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(
  fingerprintManager: FingerprintManager,
  private val fingerprintManager: FingerprintManager,
  userRepo: UserRepo,
  private val settingsRepository: FingerprintSettingsRepository,
  settingsRepository: FingerprintSettingsRepository,
  backgroundDispatcher: CoroutineDispatcher,
  applicationScope: CoroutineScope,
  sensorRepo: FingerprintSensorRepository,
) : FingerprintEnrollmentRepository {

  private val _shouldUseSettingsMaxFingerprints = MutableStateFlow(false)
  val shouldUseSettingsMaxFingerprints = _shouldUseSettingsMaxFingerprints.asStateFlow()

  private val enrollmentChangedFlow: Flow<Int?> =
    callbackFlow {
        val callback =
@@ -72,27 +85,34 @@ class FingerprintEnrollmentRepositoryImpl(
  override val currentEnrollments: Flow<List<FingerprintData>> =
    userRepo.currentUser
      .distinctUntilChanged()
      .flatMapLatest { currentUser ->
        enrollmentChangedFlow.map { enrollmentChanged ->
          if (enrollmentChanged == null || enrollmentChanged == currentUser) {
            fingerprintManager
              .getEnrolledFingerprints(currentUser)
              ?.map { (FingerprintData(it.name.toString(), it.biometricId, it.deviceId)) }
              ?.toList()
      .combine(enrollmentChangedFlow) { currentUser, _ -> getFingerprintsForUser(currentUser) }
      .filterNotNull()
      .flowOn(backgroundDispatcher)

  override val maxFingerprintsEnrollable: Flow<Int> =
    shouldUseSettingsMaxFingerprints.combine(sensorRepo.fingerprintSensor) {
      shouldUseSettings,
      sensor ->
      if (shouldUseSettings) {
        settingsRepository.maxEnrollableFingerprints()
      } else {
            null
        sensor.maxEnrollmentsPerUser
      }
    }
      }
      .filterNotNull()
      .flowOn(backgroundDispatcher)

  override val canEnrollUser: Flow<Boolean> =
    currentEnrollments.map {
      it?.size?.let { it < settingsRepository.maxEnrollableFingerprints() } ?: false
    currentEnrollments.combine(maxFingerprintsEnrollable) { enrollments, maxFingerprints ->
      enrollments.size < maxFingerprints
    }

  override fun maxFingerprintsEnrollable(): Int {
    return settingsRepository.maxEnrollableFingerprints()
  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()
  }
}
+15 −2
Original line number Diff line number Diff line
@@ -17,7 +17,10 @@
package com.android.settings.biometrics.fingerprint2.data.repository

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.update

/**
 * A repository responsible for indicating the current user.
@@ -27,8 +30,18 @@ interface UserRepo {
     * This flow indicates the current user.
     */
    val currentUser: Flow<Int>

    /**
     * Updates the current user.
     */
    fun updateUser(user: Int)
}

class UserRepoImpl(val currUser: Int): UserRepo {
    override val currentUser: Flow<Int> = flowOf(currUser)
class UserRepoImpl(currUser: Int): UserRepo {
    private val _currentUser = MutableStateFlow(currUser)
    override val currentUser = _currentUser.asStateFlow()

    override fun updateUser(user: Int) {
        _currentUser.update { user }
    }
}
+6 −3
Original line number Diff line number Diff line
@@ -21,11 +21,14 @@ import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.CanEnr
import kotlinx.coroutines.flow.Flow

class CanEnrollFingerprintsInteractorImpl(
  val fingerprintEnrollmentRepository: FingerprintEnrollmentRepository
  private val fingerprintEnrollmentRepository: FingerprintEnrollmentRepository
) : CanEnrollFingerprintsInteractor {
  override val canEnrollFingerprints: Flow<Boolean> = fingerprintEnrollmentRepository.canEnrollUser
  /** Indicates the maximum fingerprints enrollable for a given user */
  override fun maxFingerprintsEnrollable(): Int {
    return fingerprintEnrollmentRepository.maxFingerprintsEnrollable()
  override val maxFingerprintsEnrollable: Flow<Int> =
    fingerprintEnrollmentRepository.maxFingerprintsEnrollable

  override fun setShouldUseSettingsMaxFingerprints(useSettings: Boolean) {
    fingerprintEnrollmentRepository.setShouldUseSettingsMaxFingerprints(useSettings)
  }
}
+4 −12
Original line number Diff line number Diff line
@@ -16,22 +16,14 @@

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.model.FingerprintData
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

class EnrolledFingerprintsInteractorImpl(
  private val fingerprintManager: FingerprintManager,
  userId: Int,
  private val fingerprintEnrollmentRepository: FingerprintEnrollmentRepository
) : EnrolledFingerprintsInteractor {
  override val enrolledFingerprints: Flow<List<FingerprintData>?> = flow {
    emit(
      fingerprintManager
        .getEnrolledFingerprints(userId)
        ?.map { (FingerprintData(it.name.toString(), it.biometricId, it.deviceId)) }
        ?.toList()
    )
  }
  override val enrolledFingerprints: Flow<List<FingerprintData>?> =
    fingerprintEnrollmentRepository.currentEnrollments
}
Loading