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

Commit 09782711 authored by Hao Dong's avatar Hao Dong
Browse files

Remove FingerprintStateViewModel.

Since FingerprintStateViewModel is too general as a view model, this CL
removes it and adds more concrete flows in FingerprintSettingsViewModel
and FingerprintEnrollViewModel.

Test: atest FingerprintManagerInteractorTest
Test: atest FingerprintSettingsViewModelTest
Test: Verified enroll/deletion/renaming/authentication flows on Settings

Change-Id: I3a0662195c4989de0813b92bccda9d36a7f7e32a
parent 4fda9e8e
Loading
Loading
Loading
Loading
+15 −13
Original line number Diff line number Diff line
@@ -47,6 +47,12 @@ interface FingerprintManagerInteractor {
  /** Returns the max enrollable fingerprints, note during SUW this might be 1 */
  val maxEnrollableFingerprints: Flow<Int>

  /** Returns true if a user can enroll a fingerprint false otherwise. */
  val canEnrollFingerprints: Flow<Boolean>

  /** Retrieves the sensor properties of a device */
  val sensorPropertiesInternal: Flow<FingerprintSensorPropertiesInternal?>

  /** Runs [FingerprintManager.authenticate] */
  suspend fun authenticate(): FingerprintAuthAttemptViewModel

@@ -60,9 +66,6 @@ interface FingerprintManagerInteractor {
   */
  suspend fun generateChallenge(gateKeeperPasswordHandle: Long): Pair<Long, ByteArray>

  /** Returns true if a user can enroll a fingerprint false otherwise. */
  fun canEnrollFingerprints(numFingerprints: Int): Flow<Boolean>

  /**
   * Removes the given fingerprint, returning true if it was successfully removed and false
   * otherwise
@@ -77,9 +80,6 @@ interface FingerprintManagerInteractor {

  /** Indicates if the press to auth feature has been enabled */
  suspend fun pressToAuthEnabled(): Boolean

  /** Retrieves the sensor properties of a device */
  suspend fun sensorPropertiesInternal(): List<FingerprintSensorPropertiesInternal>
}

class FingerprintManagerInteractorImpl(
@@ -120,8 +120,15 @@ class FingerprintManagerInteractorImpl(
    )
  }

  override fun canEnrollFingerprints(numFingerprints: Int): Flow<Boolean> = flow {
    emit(numFingerprints < maxFingerprints)
  override val canEnrollFingerprints: Flow<Boolean> = flow {
    emit(
      fingerprintManager.getEnrolledFingerprints(applicationContext.userId).size < maxFingerprints
    )
  }

  override val sensorPropertiesInternal = flow {
    val sensorPropertiesInternal = fingerprintManager.sensorPropertiesInternal
    emit(if (sensorPropertiesInternal.isEmpty()) null else sensorPropertiesInternal.first())
  }

  override val maxEnrollableFingerprints = flow { emit(maxFingerprints) }
@@ -165,11 +172,6 @@ class FingerprintManagerInteractorImpl(
    it.resume(pressToAuthProvider())
  }

  override suspend fun sensorPropertiesInternal(): List<FingerprintSensorPropertiesInternal> =
    suspendCancellableCoroutine {
      it.resume(fingerprintManager.sensorPropertiesInternal)
    }

  override suspend fun authenticate(): FingerprintAuthAttemptViewModel =
    suspendCancellableCoroutine { c: CancellableContinuation<FingerprintAuthAttemptViewModel> ->
      val authenticationCallback =
+0 −12
Original line number Diff line number Diff line
@@ -16,18 +16,6 @@

package com.android.settings.biometrics.fingerprint2.shared.model

import android.hardware.fingerprint.FingerprintSensorPropertiesInternal

/** Represents the fingerprint data nad the relevant state. */
data class FingerprintStateViewModel(
  val fingerprintViewModels: List<FingerprintViewModel>,
  val canEnroll: Boolean,
  val maxFingerprints: Int,
  val hasSideFps: Boolean,
  val pressToAuth: Boolean,
  val sensorProps: FingerprintSensorPropertiesInternal,
)

data class FingerprintViewModel(
  val name: String,
  val fingerId: Int,
+5 −3
Original line number Diff line number Diff line
@@ -47,10 +47,10 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.Finge
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Confirmation
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Education
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Enrollment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollmentNavigationViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Finish
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Intro
@@ -179,8 +179,10 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
      )[FingerprintEnrollmentNavigationViewModel::class.java]

    // Initialize FingerprintViewModel
    ViewModelProvider(this, FingerprintViewModel.FingerprintViewModelFactory(interactor))[
      FingerprintViewModel::class.java]
    ViewModelProvider(
      this,
      FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory(interactor)
    )[FingerprintEnrollViewModel::class.java]

    // Initialize scroll view model
    ViewModelProvider(this, FingerprintScrollViewModel.FingerprintScrollViewModelFactory())[
+9 −11
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.android.settings.R
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollmentNavigationViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Unicorn
import com.google.android.setupcompat.template.FooterBarMixin
import com.google.android.setupcompat.template.FooterButton
@@ -76,7 +76,7 @@ class FingerprintEnrollmentIntroV2Fragment : Fragment(R.layout.fingerprint_v2_en
  private lateinit var footerBarMixin: FooterBarMixin
  private lateinit var textModel: TextModel
  private lateinit var navigationViewModel: FingerprintEnrollmentNavigationViewModel
  private lateinit var fingerprintStateViewModel: FingerprintViewModel
  private lateinit var fingerprintEnrollViewModel: FingerprintEnrollViewModel
  private lateinit var fingerprintScrollViewModel: FingerprintScrollViewModel
  private lateinit var gateKeeperViewModel: FingerprintGatekeeperViewModel

@@ -84,8 +84,8 @@ class FingerprintEnrollmentIntroV2Fragment : Fragment(R.layout.fingerprint_v2_en
    super.onCreate(savedInstanceState)
    navigationViewModel =
      ViewModelProvider(requireActivity())[FingerprintEnrollmentNavigationViewModel::class.java]
    fingerprintStateViewModel =
      ViewModelProvider(requireActivity())[FingerprintViewModel::class.java]
    fingerprintEnrollViewModel =
      ViewModelProvider(requireActivity())[FingerprintEnrollViewModel::class.java]
    fingerprintScrollViewModel =
      ViewModelProvider(requireActivity())[FingerprintScrollViewModel::class.java]
    gateKeeperViewModel =
@@ -98,13 +98,11 @@ class FingerprintEnrollmentIntroV2Fragment : Fragment(R.layout.fingerprint_v2_en
    lifecycleScope.launch {
      combine(
          navigationViewModel.enrollType,
          fingerprintStateViewModel.fingerprintStateViewModel,
        ) { enrollType, fingerprintStateViewModel ->
          Pair(enrollType, fingerprintStateViewModel)
          fingerprintEnrollViewModel.sensorType,
        ) { enrollType, sensorType ->
          Pair(enrollType, sensorType)
        }
        .collect { (enrollType, fingerprintStateViewModel) ->
          val sensorProps = fingerprintStateViewModel?.sensorProps

        .collect { (enrollType, sensorType) ->
          textModel =
            when (enrollType) {
              Unicorn -> getUnicornTextModel()
@@ -145,7 +143,7 @@ class FingerprintEnrollmentIntroV2Fragment : Fragment(R.layout.fingerprint_v2_en

            val iconShield: ImageView = view.requireViewById(R.id.icon_shield)
            val footerMessage6: TextView = view.requireViewById(R.id.footer_message_6)
            when (sensorProps?.sensorType) {
            when (sensorType) {
              FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC,
              FingerprintSensorProperties.TYPE_UDFPS_OPTICAL -> {
                footerMessage6.visibility = View.VISIBLE
+44 −0
Original line number Diff line number Diff line
@@ -16,66 +16,29 @@

package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel

import android.hardware.fingerprint.FingerprintSensorProperties
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractor
import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintStateViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.last
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.transform

/** Represents all of the fingerprint information needed for fingerprint enrollment. */
class FingerprintViewModel(fingerprintManagerInteractor: FingerprintManagerInteractor) :
class FingerprintEnrollViewModel(fingerprintManagerInteractor: FingerprintManagerInteractor) :
  ViewModel() {

  private val _fingerprintViewModel: MutableStateFlow<FingerprintStateViewModel?> =
    MutableStateFlow(null)
  /** Represents the stream of [FingerprintSensorProperties.SensorType] */
  val sensorType: Flow<Int> =
    fingerprintManagerInteractor.sensorPropertiesInternal.transform { it?.sensorType }

  /**
   * A flow that contains a [FingerprintStateViewModel] which contains the relevant information for
   * enrollment
   */
  val fingerprintStateViewModel: Flow<FingerprintStateViewModel?> =
    _fingerprintViewModel.asStateFlow()

  init {
    viewModelScope.launch {
      val enrolledFingerprints =
        fingerprintManagerInteractor.enrolledFingerprints.last().map {
          com.android.settings.biometrics.fingerprint2.shared.model.FingerprintViewModel(
            it.name,
            it.fingerId,
            it.deviceId
          )
        }
      val sensorProps = fingerprintManagerInteractor.sensorPropertiesInternal().first()
      val maxFingerprints = 5
      _fingerprintViewModel.update {
        FingerprintStateViewModel(
          enrolledFingerprints,
          enrolledFingerprints.size < maxFingerprints,
          maxFingerprints,
          sensorProps.isAnySidefpsType,
          false,
          sensorProps,
        )
      }
    }
  }

  class FingerprintViewModelFactory(val interactor: FingerprintManagerInteractor) :
  class FingerprintEnrollViewModelFactory(val interactor: FingerprintManagerInteractor) :
    ViewModelProvider.Factory {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(
      modelClass: Class<T>,
    ): T {

      return FingerprintViewModel(interactor) as T
      return FingerprintEnrollViewModel(interactor) as T
    }
  }
}
Loading