Updating navigation view model

Test: atest com.android.settings.fingerprint2.ui.enrollment.modules.enrolling.rfps.viewmodel
com.android.settings.fingerprint2.ui.enrollment.viewmodel
com.android.settings.fingerprint2.ui.settings
com.android.settings.fingerprint2.domain.interactor
com.android.settings.fingerprint2.enrollment.viewmodel
Bug: 295205754

Change-Id: I210712ab76050b89452fb871cd2a4fb28bfd4012
diff --git a/Android.bp b/Android.bp
index 737c16c..fc4bf0a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,7 +57,7 @@
         "src/**/*.kt",
     ],
     exclude_srcs: [
-        "src/com/android/settings/biometrics/fingerprint2/shared/**/*.kt",
+        "src/com/android/settings/biometrics/fingerprint2/lib/**/*.kt",
     ],
     use_resource_processor: true,
     resource_dirs: [
diff --git a/src/com/android/settings/biometrics/fingerprint2/conversion/Util.kt b/src/com/android/settings/biometrics/fingerprint2/conversion/Util.kt
index 58ef509..0ef1d25 100644
--- a/src/com/android/settings/biometrics/fingerprint2/conversion/Util.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/conversion/Util.kt
@@ -20,8 +20,8 @@
 import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_UNABLE_TO_PROCESS
 import android.hardware.fingerprint.FingerprintManager
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
 
 object Util {
   fun EnrollReason.toOriginalReason(): Int {
@@ -71,6 +71,4 @@
       this == FINGERPRINT_ERROR_CANCELED,
     )
   }
-
 }
-
diff --git a/src/com/android/settings/biometrics/fingerprint2/data/repository/FingerprintSensorRepo.kt b/src/com/android/settings/biometrics/fingerprint2/data/repository/FingerprintSensorRepo.kt
new file mode 100644
index 0000000..c045b0e
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/data/repository/FingerprintSensorRepo.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.data.repository
+
+import android.hardware.biometrics.ComponentInfoInternal
+import android.hardware.biometrics.SensorLocationInternal
+import android.hardware.biometrics.SensorProperties
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorProperties
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
+import com.android.systemui.biometrics.shared.model.FingerprintSensor
+import com.android.systemui.biometrics.shared.model.toFingerprintSensor
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.withContext
+
+/**
+ * Provides the [FingerprintSensor]
+ *
+ * TODO(b/313493336): Move this to systemui
+ */
+interface FingerprintSensorRepo {
+  /** Get the [FingerprintSensor] */
+  val fingerprintSensor: Flow<FingerprintSensor>
+}
+
+class FingerprintSensorRepoImpl(
+    fingerprintManager: FingerprintManager,
+    backgroundDispatcher: CoroutineDispatcher,
+    activityScope: CoroutineScope,
+) : FingerprintSensorRepo {
+
+  override val fingerprintSensor: Flow<FingerprintSensor> =
+    callbackFlow {
+        val callback =
+          object : IFingerprintAuthenticatorsRegisteredCallback.Stub() {
+            override fun onAllAuthenticatorsRegistered(
+              sensors: List<FingerprintSensorPropertiesInternal>
+            ) {
+              if (sensors.isEmpty()) {
+                trySend(DEFAULT_PROPS)
+              } else {
+                trySend(sensors[0].toFingerprintSensor())
+              }
+            }
+          }
+        withContext(backgroundDispatcher) {
+          fingerprintManager?.addAuthenticatorsRegisteredCallback(callback)
+        }
+        awaitClose {}
+      }
+      .stateIn(activityScope, started = SharingStarted.Eagerly, initialValue = DEFAULT_PROPS)
+
+    companion object {
+        private const val TAG = "FingerprintSensorRepoImpl"
+
+        private val DEFAULT_PROPS =
+            FingerprintSensorPropertiesInternal(
+                -1 /* sensorId */,
+                SensorProperties.STRENGTH_CONVENIENCE,
+                0 /* maxEnrollmentsPerUser */,
+                listOf<ComponentInfoInternal>(),
+                FingerprintSensorProperties.TYPE_UNKNOWN,
+                false /* halControlsIllumination */,
+                true /* resetLockoutRequiresHardwareAuthToken */,
+                listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
+            )
+                .toFingerprintSensor()
+    }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/repository/PressToAuthProviderImpl.kt b/src/com/android/settings/biometrics/fingerprint2/data/repository/PressToAuthRepo.kt
similarity index 67%
rename from src/com/android/settings/biometrics/fingerprint2/repository/PressToAuthProviderImpl.kt
rename to src/com/android/settings/biometrics/fingerprint2/data/repository/PressToAuthRepo.kt
index 38c5335..5909825 100644
--- a/src/com/android/settings/biometrics/fingerprint2/repository/PressToAuthProviderImpl.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/data/repository/PressToAuthRepo.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,13 +14,24 @@
  * limitations under the License.
  */
 
-package com.android.settings.biometrics.fingerprint2.repository
+package com.android.settings.biometrics.fingerprint2.data.repository
 
 import android.content.Context
 import android.provider.Settings
-import com.android.settings.biometrics.fingerprint2.shared.data.repository.PressToAuthProvider
 
-class PressToAuthProviderImpl(val context: Context) : PressToAuthProvider {
+/** Interface that indicates if press to auth is on or off. */
+interface PressToAuthRepo {
+  /** Indicates true if the PressToAuth feature is enabled, false otherwise. */
+  val isEnabled: Boolean
+}
+
+/** Indicates whether or not the press to auth feature is enabled. */
+class PressToAuthRepoImpl(private val context: Context) : PressToAuthRepo {
+  /**
+   * Gets the status of the press to auth feature.
+   *
+   * Returns whether or not the press to auth feature is enabled.
+   */
   override val isEnabled: Boolean
     get() {
       var toReturn: Int =
@@ -43,7 +54,7 @@
           context.contentResolver,
           Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
           toReturn,
-          context.userId
+          context.userId,
         )
       }
       return (toReturn == 1)
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt
index 984d04c..1fbeb44 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt
@@ -26,16 +26,16 @@
 import com.android.settings.biometrics.GatekeeperPasswordProvider
 import com.android.settings.biometrics.fingerprint2.conversion.Util.toEnrollError
 import com.android.settings.biometrics.fingerprint2.conversion.Util.toOriginalReason
-import com.android.settings.biometrics.fingerprint2.shared.data.repository.PressToAuthProvider
-import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
-import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintFlow
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptModel
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
-import com.android.settings.biometrics.fingerprint2.shared.model.SetupWizard
+import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepo
+import com.android.settings.biometrics.fingerprint2.data.repository.PressToAuthRepo
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintFlow
+import com.android.settings.biometrics.fingerprint2.lib.model.SetupWizard
 import com.android.settings.password.ChooseLockSettingsHelper
-import com.android.systemui.biometrics.shared.model.toFingerprintSensor
 import kotlin.coroutines.resume
 import kotlin.coroutines.suspendCoroutine
 import kotlinx.coroutines.CancellableContinuation
@@ -57,8 +57,9 @@
   applicationContext: Context,
   private val backgroundDispatcher: CoroutineDispatcher,
   private val fingerprintManager: FingerprintManager,
+  fingerprintSensorRepo: FingerprintSensorRepo,
   private val gatekeeperPasswordProvider: GatekeeperPasswordProvider,
-  private val pressToAuthProvider: PressToAuthProvider,
+  private val pressToAuthRepo: PressToAuthRepo,
   private val fingerprintFlow: FingerprintFlow,
 ) : FingerprintManagerInteractor {
 
@@ -100,13 +101,7 @@
     )
   }
 
-  override val sensorPropertiesInternal = flow {
-    val sensorPropertiesInternal = fingerprintManager.sensorPropertiesInternal
-    emit(
-      if (sensorPropertiesInternal.isEmpty()) null
-      else sensorPropertiesInternal.first().toFingerprintSensor()
-    )
-  }
+  override val sensorPropertiesInternal = fingerprintSensorRepo.fingerprintSensor
 
   override val maxEnrollableFingerprints = flow { emit(maxFingerprints) }
 
@@ -136,8 +131,7 @@
             totalSteps = remaining + 1
           }
 
-          trySend(FingerEnrollState.EnrollProgress(remaining, totalSteps!!)).onFailure {
-            error ->
+          trySend(FingerEnrollState.EnrollProgress(remaining, totalSteps!!)).onFailure { error ->
             Log.d(TAG, "onEnrollmentProgress($remaining) failed to send, due to $error")
           }
 
@@ -148,13 +142,16 @@
         }
 
         override fun onEnrollmentHelp(helpMsgId: Int, helpString: CharSequence?) {
-          trySend(FingerEnrollState.EnrollHelp(helpMsgId, helpString.toString()))
-            .onFailure { error -> Log.d(TAG, "onEnrollmentHelp failed to send, due to $error") }
+          trySend(FingerEnrollState.EnrollHelp(helpMsgId, helpString.toString())).onFailure { error
+            ->
+            Log.d(TAG, "onEnrollmentHelp failed to send, due to $error")
+          }
         }
 
         override fun onEnrollmentError(errMsgId: Int, errString: CharSequence?) {
-          trySend(errMsgId.toEnrollError(fingerprintFlow == SetupWizard))
-            .onFailure { error -> Log.d(TAG, "onEnrollmentError failed to send, due to $error") }
+          trySend(errMsgId.toEnrollError(fingerprintFlow == SetupWizard)).onFailure { error ->
+            Log.d(TAG, "onEnrollmentError failed to send, due to $error")
+          }
           Log.d(TAG, "onEnrollmentError($errMsgId)")
           streamEnded = true
           enrollRequestOutstanding.update { false }
@@ -185,14 +182,14 @@
         override fun onRemovalError(
           fp: android.hardware.fingerprint.Fingerprint,
           errMsgId: Int,
-          errString: CharSequence
+          errString: CharSequence,
         ) {
           it.resume(false)
         }
 
         override fun onRemovalSucceeded(
           fp: android.hardware.fingerprint.Fingerprint?,
-          remaining: Int
+          remaining: Int,
         ) {
           it.resume(true)
         }
@@ -200,7 +197,7 @@
     fingerprintManager.remove(
       android.hardware.fingerprint.Fingerprint(fp.name, fp.fingerId, fp.deviceId),
       applicationContext.userId,
-      callback
+      callback,
     )
   }
 
@@ -215,7 +212,7 @@
   }
 
   override suspend fun pressToAuthEnabled(): Boolean = suspendCancellableCoroutine {
-    it.resume(pressToAuthProvider.isEnabled)
+    it.resume(pressToAuthRepo.isEnabled)
   }
 
   override suspend fun authenticate(): FingerprintAuthAttemptModel =
@@ -249,7 +246,7 @@
         cancellationSignal,
         authenticationCallback,
         null,
-        applicationContext.userId
+        applicationContext.userId,
       )
     }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/Android.bp b/src/com/android/settings/biometrics/fingerprint2/lib/Android.bp
similarity index 100%
rename from src/com/android/settings/biometrics/fingerprint2/shared/Android.bp
rename to src/com/android/settings/biometrics/fingerprint2/lib/Android.bp
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/AndroidManifest.xml b/src/com/android/settings/biometrics/fingerprint2/lib/AndroidManifest.xml
similarity index 91%
rename from src/com/android/settings/biometrics/fingerprint2/shared/AndroidManifest.xml
rename to src/com/android/settings/biometrics/fingerprint2/lib/AndroidManifest.xml
index e2c97fc..250f0af 100644
--- a/src/com/android/settings/biometrics/fingerprint2/shared/AndroidManifest.xml
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/AndroidManifest.xml
@@ -14,5 +14,5 @@
   ~ limitations under the License.
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.settings.biometrics.fingerprint2.shared">
+    package="com.android.settings.biometrics.fingerprint2.lib">
 </manifest>
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/domain/interactor/FingerprintManagerInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/lib/domain/interactor/FingerprintManagerInteractor.kt
similarity index 82%
rename from src/com/android/settings/biometrics/fingerprint2/shared/domain/interactor/FingerprintManagerInteractor.kt
rename to src/com/android/settings/biometrics/fingerprint2/lib/domain/interactor/FingerprintManagerInteractor.kt
index 94afa49..6e6df23 100644
--- a/src/com/android/settings/biometrics/fingerprint2/shared/domain/interactor/FingerprintManagerInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/domain/interactor/FingerprintManagerInteractor.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.settings.biometrics.fingerprint2.shared.domain.interactor
+package com.android.settings.biometrics.fingerprint2.lib.domain.interactor
 
-import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptModel
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.systemui.biometrics.shared.model.FingerprintSensor
 import kotlinx.coroutines.flow.Flow
 
@@ -56,12 +56,12 @@
 
   /**
    * Runs [FingerprintManager.enroll] with the [hardwareAuthToken] and [EnrollReason] for this
-   * enrollment. Returning the [FingerEnrollState] that represents this fingerprint
-   * enrollment state.
+   * enrollment. Returning the [FingerEnrollState] that represents this fingerprint enrollment
+   * state.
    */
   suspend fun enroll(
-      hardwareAuthToken: ByteArray?,
-      enrollReason: EnrollReason,
+    hardwareAuthToken: ByteArray?,
+    enrollReason: EnrollReason,
   ): Flow<FingerEnrollState>
 
   /**
@@ -78,5 +78,4 @@
 
   /** Indicates if the press to auth feature has been enabled */
   suspend fun pressToAuthEnabled(): Boolean
-
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/model/EnrollReason.kt b/src/com/android/settings/biometrics/fingerprint2/lib/model/EnrollReason.kt
similarity index 93%
rename from src/com/android/settings/biometrics/fingerprint2/shared/model/EnrollReason.kt
rename to src/com/android/settings/biometrics/fingerprint2/lib/model/EnrollReason.kt
index 47a0af0..3cc6497 100644
--- a/src/com/android/settings/biometrics/fingerprint2/shared/model/EnrollReason.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/model/EnrollReason.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.biometrics.fingerprint2.shared.model
+package com.android.settings.biometrics.fingerprint2.lib.model
 
 /** The reason for enrollment */
 enum class EnrollReason {
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerEnrollState.kt b/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerEnrollState.kt
similarity index 81%
rename from src/com/android/settings/biometrics/fingerprint2/shared/model/FingerEnrollState.kt
rename to src/com/android/settings/biometrics/fingerprint2/lib/model/FingerEnrollState.kt
index 4766d59..683397f 100644
--- a/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerEnrollState.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerEnrollState.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.biometrics.fingerprint2.shared.model
+package com.android.settings.biometrics.fingerprint2.lib.model
 
 import android.annotation.StringRes
 
@@ -28,16 +28,12 @@
    *
    * Progress is obtained by (totalStepsRequired - remainingSteps) / totalStepsRequired
    */
-  data class EnrollProgress(
-    val remainingSteps: Int,
-    val totalStepsRequired: Int,
-  ) : FingerEnrollState()
+  data class EnrollProgress(val remainingSteps: Int, val totalStepsRequired: Int) :
+    FingerEnrollState()
 
   /** Represents that recoverable error has been encountered during enrollment. */
-  data class EnrollHelp(
-    @StringRes val helpMsgId: Int,
-    val helpString: String,
-  ) : FingerEnrollState()
+  data class EnrollHelp(@StringRes val helpMsgId: Int, val helpString: String) :
+    FingerEnrollState()
 
   /** Represents that an unrecoverable error has been encountered and the operation is complete. */
   data class EnrollError(
diff --git a/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintAuthAttemptModel.kt b/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintAuthAttemptModel.kt
new file mode 100644
index 0000000..45259e9
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintAuthAttemptModel.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.model
+
+/** Information indicating whether an auth was successful or not */
+sealed class FingerprintAuthAttemptModel {
+  /** Indicates a successful auth attempt has occurred for [fingerId] */
+  data class Success(val fingerId: Int) : FingerprintAuthAttemptModel()
+
+  /** Indicates a failed auth attempt has occurred. */
+  data class Error(val error: Int, val message: String) : FingerprintAuthAttemptModel()
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/data/repository/PressToAuthProvider.kt b/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintData.kt
similarity index 67%
rename from src/com/android/settings/biometrics/fingerprint2/shared/data/repository/PressToAuthProvider.kt
rename to src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintData.kt
index e776b9a..62aa2c7 100644
--- a/src/com/android/settings/biometrics/fingerprint2/shared/data/repository/PressToAuthProvider.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintData.kt
@@ -14,14 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.biometrics.fingerprint2.shared.data.repository
+package com.android.settings.biometrics.fingerprint2.lib.model
 
-/**
- * Interface that indicates if press to auth is on or off.
- */
-interface PressToAuthProvider {
-    /**
-     * Indicates true if the PressToAuth feature is enabled, false otherwise.
-     */
-    val isEnabled: Boolean
-}
\ No newline at end of file
+/** Basic information about an enrolled fingerprint */
+data class FingerprintData(val name: String, val fingerId: Int, val deviceId: Long)
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintFlow.kt b/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintFlow.kt
similarity index 83%
rename from src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintFlow.kt
rename to src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintFlow.kt
index 93c7577..40d7a03 100644
--- a/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintFlow.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/model/FingerprintFlow.kt
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.settings.biometrics.fingerprint2.shared.model
+package com.android.settings.biometrics.fingerprint2.lib.model
 
 /**
- * The [FingerprintFlow] for fingerprint enrollment indicates information on how the flow should behave.
+ * The [FingerprintFlow] for fingerprint enrollment indicates information on how the flow should
+ * behave.
  */
 sealed class FingerprintFlow
 
@@ -32,3 +33,6 @@
 
 /** Flow to specify settings type */
 data object Settings : FingerprintFlow()
+
+/** Indicates that the fast enroll experience should occur */
+data object FastEnroll : FingerprintFlow()
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintData.kt b/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintData.kt
deleted file mode 100644
index b2aa25c..0000000
--- a/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintData.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2023 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.shared.model
-
-data class FingerprintData(
-  val name: String,
-  val fingerId: Int,
-  val deviceId: Long,
-)
-
-sealed class FingerprintAuthAttemptModel {
-  data class Success(
-    val fingerId: Int,
-  ) : FingerprintAuthAttemptModel()
-
-  data class Error(
-    val error: Int,
-    val message: String,
-  ) : FingerprintAuthAttemptModel()
-}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt
index 06307a4..f7e6135 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt
@@ -21,7 +21,6 @@
 import android.content.res.Configuration
 import android.hardware.fingerprint.FingerprintManager
 import android.os.Bundle
-import android.provider.Settings
 import android.util.Log
 import android.view.accessibility.AccessibilityManager
 import androidx.activity.result.contract.ActivityResultContracts
@@ -31,16 +30,18 @@
 import androidx.lifecycle.lifecycleScope
 import com.android.internal.widget.LockPatternUtils
 import com.android.settings.R
+import com.android.settings.SettingsApplication
 import com.android.settings.SetupWizardUtils
 import com.android.settings.Utils.SETTINGS_PACKAGE_NAME
 import com.android.settings.biometrics.BiometricEnrollBase
 import com.android.settings.biometrics.BiometricEnrollBase.CONFIRM_REQUEST
 import com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED
 import com.android.settings.biometrics.GatekeeperPasswordProvider
+import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepoImpl
+import com.android.settings.biometrics.fingerprint2.data.repository.PressToAuthRepoImpl
 import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
-import com.android.settings.biometrics.fingerprint2.shared.model.Default
-import com.android.settings.biometrics.fingerprint2.shared.model.SetupWizard
-import com.android.settings.biometrics.fingerprint2.repository.PressToAuthProviderImpl
+import com.android.settings.biometrics.fingerprint2.lib.model.Default
+import com.android.settings.biometrics.fingerprint2.lib.model.SetupWizard
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollConfirmationV2Fragment
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollEnrollingV2Fragment
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollFindSensorV2Fragment
@@ -49,20 +50,24 @@
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.AccessibilityViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
-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.FingerprintAction
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollEnrollingViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollIntroViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintFlowViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.ConfirmDeviceCredential
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Confirmation
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Education
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Enrollment
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Init
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Introduction
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.TransitionStep
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Finish
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FoldStateViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Intro
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.LaunchConfirmDeviceCredential
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.OrientationStateViewModel
 import com.android.settings.password.ChooseLockGeneric
 import com.android.settings.password.ChooseLockSettingsHelper
@@ -71,7 +76,6 @@
 import com.google.android.setupcompat.util.WizardManagerHelper
 import com.google.android.setupdesign.util.ThemeHelper
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.launch
 
@@ -83,7 +87,7 @@
  */
 class FingerprintEnrollmentV2Activity : FragmentActivity() {
   private lateinit var fingerprintEnrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel
-  private lateinit var navigationViewModel: FingerprintEnrollNavigationViewModel
+  private lateinit var navigationViewModel: FingerprintNavigationViewModel
   private lateinit var gatekeeperViewModel: FingerprintGatekeeperViewModel
   private lateinit var fingerprintEnrollViewModel: FingerprintEnrollViewModel
   private lateinit var accessibilityViewModel: AccessibilityViewModel
@@ -91,6 +95,7 @@
   private lateinit var orientationStateViewModel: OrientationStateViewModel
   private lateinit var fingerprintScrollViewModel: FingerprintScrollViewModel
   private lateinit var backgroundViewModel: BackgroundViewModel
+  private lateinit var fingerprintFlowViewModel: FingerprintFlowViewModel
   private val coroutineDispatcher = Dispatchers.Default
 
   /** Result listener for ChooseLock activity flow. */
@@ -119,6 +124,7 @@
     super.onResume()
     backgroundViewModel.inForeground()
   }
+
   override fun onConfigurationChanged(newConfig: Configuration) {
     super.onConfigurationChanged(newConfig)
     foldStateViewModel.onConfigurationChange(newConfig)
@@ -127,8 +133,20 @@
   private fun onConfirmDevice(resultCode: Int, data: Intent?) {
     val wasSuccessful = resultCode == RESULT_FINISHED || resultCode == Activity.RESULT_OK
     val gateKeeperPasswordHandle = data?.getExtra(EXTRA_KEY_GK_PW_HANDLE) as Long?
+
     lifecycleScope.launch {
+      val confirmDeviceResult =
+        if (wasSuccessful) {
+          FingerprintAction.CONFIRM_DEVICE_SUCCESS
+        } else {
+          FingerprintAction.CONFIRM_DEVICE_FAIL
+        }
       gatekeeperViewModel.onConfirmDevice(wasSuccessful, gateKeeperPasswordHandle)
+      navigationViewModel.update(
+        confirmDeviceResult,
+        ConfirmDeviceCredential::class,
+        "$TAG#onConfirmDevice",
+      )
     }
   }
 
@@ -156,14 +174,21 @@
       ViewModelProvider(this, BackgroundViewModel.BackgroundViewModelFactory())[
         BackgroundViewModel::class.java]
 
+    fingerprintFlowViewModel =
+      ViewModelProvider(this, FingerprintFlowViewModel.FingerprintFlowViewModelFactory(enrollType))[
+        FingerprintFlowViewModel::class.java]
 
-    val interactor =
+    val fingerprintSensorRepo =
+      FingerprintSensorRepoImpl(fingerprintManager, backgroundDispatcher, lifecycleScope)
+
+    val fingerprintManagerInteractor =
       FingerprintManagerInteractorImpl(
         context,
         backgroundDispatcher,
         fingerprintManager,
+        fingerprintSensorRepo,
         GatekeeperPasswordProvider(LockPatternUtils(context)),
-        PressToAuthProviderImpl(context),
+        PressToAuthRepoImpl(context),
         enrollType,
       )
 
@@ -171,27 +196,37 @@
     val token = intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN)
     val gatekeeperInfo = FingerprintGatekeeperViewModel.toGateKeeperInfo(challenge, token)
 
+    val hasConfirmedDeviceCredential = gatekeeperInfo is GatekeeperInfo.GatekeeperPasswordInfo
+
+    navigationViewModel =
+      ViewModelProvider(
+        this,
+        FingerprintNavigationViewModel.FingerprintNavigationViewModelFactory(
+          Init,
+          hasConfirmedDeviceCredential,
+          fingerprintFlowViewModel,
+          fingerprintManagerInteractor,
+        ),
+      )[FingerprintNavigationViewModel::class.java]
+    // Initialize FingerprintEnrollIntroViewModel
+    ViewModelProvider(
+      this,
+      FingerprintEnrollIntroViewModel.FingerprintEnrollIntoViewModelFactory(
+        navigationViewModel,
+        fingerprintFlowViewModel,
+        fingerprintManagerInteractor,
+      ),
+    )[FingerprintEnrollIntroViewModel::class.java]
+
     gatekeeperViewModel =
       ViewModelProvider(
         this,
         FingerprintGatekeeperViewModel.FingerprintGatekeeperViewModelFactory(
           gatekeeperInfo,
-          interactor,
-        )
+          fingerprintManagerInteractor,
+        ),
       )[FingerprintGatekeeperViewModel::class.java]
 
-    navigationViewModel =
-      ViewModelProvider(
-        this,
-        FingerprintEnrollNavigationViewModel.FingerprintEnrollNavigationViewModelFactory(
-          backgroundDispatcher,
-          interactor,
-          gatekeeperViewModel,
-          gatekeeperInfo is GatekeeperInfo.GatekeeperPasswordInfo,
-          enrollType,
-        )
-      )[FingerprintEnrollNavigationViewModel::class.java]
-
     // Initialize FoldStateViewModel
     foldStateViewModel =
       ViewModelProvider(this, FoldStateViewModel.FoldStateViewModelFactory(context))[
@@ -203,10 +238,10 @@
       ViewModelProvider(
         this,
         FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory(
-          interactor,
+          fingerprintManagerInteractor,
           gatekeeperViewModel,
           navigationViewModel,
-        )
+        ),
       )[FingerprintEnrollViewModel::class.java]
 
     // Initialize scroll view model
@@ -220,7 +255,7 @@
         this,
         AccessibilityViewModel.AccessibilityViewModelFactory(
           getSystemService(AccessibilityManager::class.java)!!
-        )
+        ),
       )[AccessibilityViewModel::class.java]
 
     // Initialize OrientationViewModel
@@ -234,8 +269,8 @@
         this,
         FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingViewModelFactory(
           fingerprintEnrollViewModel,
-          backgroundViewModel
-        )
+          backgroundViewModel,
+        ),
       )[FingerprintEnrollEnrollingViewModel::class.java]
 
     // Initialize FingerprintEnrollFindSensorViewModel
@@ -248,36 +283,48 @@
         backgroundViewModel,
         accessibilityViewModel,
         foldStateViewModel,
-        orientationStateViewModel
-      )
+        orientationStateViewModel,
+        fingerprintFlowViewModel,
+      ),
     )[FingerprintEnrollFindSensorViewModel::class.java]
 
     // Initialize RFPS View Model
     ViewModelProvider(
       this,
-      RFPSViewModel.RFPSViewModelFactory(fingerprintEnrollEnrollingViewModel)
+      RFPSViewModel.RFPSViewModelFactory(fingerprintEnrollEnrollingViewModel, navigationViewModel),
     )[RFPSViewModel::class.java]
+    lifecycleScope.launch {
+      navigationViewModel.currentStep.collect { step ->
+        if (step is Init) {
+          Log.d(TAG, "FingerprintNav.init($step)")
+          navigationViewModel.update(FingerprintAction.ACTIVITY_CREATED, Init::class, "$TAG#init")
+        }
+      }
+    }
 
     lifecycleScope.launch {
-      navigationViewModel.navigationViewModel
-        .filterNotNull()
-        .combine(fingerprintEnrollViewModel.sensorType) { nav, sensorType -> Pair(nav, sensorType) }
-        .collect { (nav, sensorType) ->
-          Log.d(TAG, "navigationStep $nav")
-          fingerprintEnrollViewModel.sensorTypeCached = sensorType
-          val isForward = nav.forward
-          val currStep = nav.currStep
-          val theClass: Class<Fragment>? =
-            when (currStep) {
-              Confirmation -> FingerprintEnrollConfirmationV2Fragment::class.java as Class<Fragment>
-              Education -> FingerprintEnrollFindSensorV2Fragment::class.java as Class<Fragment>
+      navigationViewModel.navigateTo.filterNotNull().collect { step ->
+        if (step is ConfirmDeviceCredential) {
+          launchConfirmOrChooseLock(userId)
+          navigationViewModel.update(
+            FingerprintAction.TRANSITION_FINISHED,
+            TransitionStep::class,
+            "$TAG#launchConfirmOrChooseLock",
+          )
+        } else {
+          val theClass: Fragment? =
+            when (step) {
+              Confirmation -> FingerprintEnrollConfirmationV2Fragment()
+              is Education -> {
+                FingerprintEnrollFindSensorV2Fragment(step.sensor.sensorType)
+              }
               is Enrollment -> {
-                when (sensorType) {
-                  FingerprintSensorType.REAR -> RFPSEnrollFragment::class.java as Class<Fragment>
-                  else -> FingerprintEnrollEnrollingV2Fragment::class.java as Class<Fragment>
+                when (step.sensor.sensorType) {
+                  FingerprintSensorType.REAR -> RFPSEnrollFragment()
+                  else -> FingerprintEnrollEnrollingV2Fragment()
                 }
               }
-              Intro -> FingerprintEnrollIntroV2Fragment::class.java as Class<Fragment>
+              Introduction -> FingerprintEnrollIntroV2Fragment()
               else -> null
             }
 
@@ -291,19 +338,31 @@
               .setReorderingAllowed(true)
               .add(R.id.fragment_container_view, theClass, null)
               .commit()
-          } else {
-
-            if (currStep is Finish) {
-              if (currStep.resultCode != null) {
-                finishActivity(currStep.resultCode)
-              } else {
-                finish()
-              }
-            } else if (currStep == LaunchConfirmDeviceCredential) {
-              launchConfirmOrChooseLock(userId)
-            }
+            navigationViewModel.update(
+              FingerprintAction.TRANSITION_FINISHED,
+              TransitionStep::class,
+              "$TAG#fragmentManager.add($theClass)",
+            )
           }
         }
+      }
+    }
+
+    lifecycleScope.launch {
+      navigationViewModel.shouldFinish.filterNotNull().collect {
+        Log.d(TAG, "FingerprintSettingsNav.finishing($it)")
+        if (it.result != null) {
+          finishActivity(it.result as Int)
+        } else {
+          finish()
+        }
+      }
+    }
+
+    lifecycleScope.launch {
+      navigationViewModel.currentScreen.filterNotNull().collect { screen ->
+        Log.d(TAG, "FingerprintSettingsNav.currentScreen($screen)")
+      }
     }
 
     val fromSettingsSummary =
@@ -313,7 +372,7 @@
     ) {
       overridePendingTransition(
         com.google.android.setupdesign.R.anim.sud_slide_next_in,
-        com.google.android.setupdesign.R.anim.sud_slide_next_out
+        com.google.android.setupdesign.R.anim.sud_slide_next_out,
       )
     }
   }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollConfirmationV2Fragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollConfirmationV2Fragment.kt
index b12491f..fd07a95 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollConfirmationV2Fragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollConfirmationV2Fragment.kt
@@ -18,8 +18,6 @@
 
 import android.os.Bundle
 import androidx.fragment.app.Fragment
-import androidx.lifecycle.ViewModelProvider
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel
 
 /**
  * A fragment to indicate that fingerprint enrollment has been completed.
@@ -31,9 +29,5 @@
 
   override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
-    if (savedInstanceState == null) {
-      val navigationViewModel =
-        ViewModelProvider(requireActivity())[FingerprintEnrollNavigationViewModel::class.java]
-    }
   }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollEnrollingV2Fragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollEnrollingV2Fragment.kt
index 0140d57..be30346 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollEnrollingV2Fragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollEnrollingV2Fragment.kt
@@ -18,18 +18,12 @@
 
 import android.os.Bundle
 import androidx.fragment.app.Fragment
-import androidx.lifecycle.ViewModelProvider
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel
 
 /** A fragment that is responsible for enrolling a users fingerprint. */
 class FingerprintEnrollEnrollingV2Fragment : Fragment(R.layout.fingerprint_enroll_enrolling) {
 
   override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
-    if (savedInstanceState == null) {
-      val navigationViewModel =
-        ViewModelProvider(requireActivity())[FingerprintEnrollNavigationViewModel::class.java]
-    }
   }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollFindSensorV2Fragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollFindSensorV2Fragment.kt
index bfd4264..9603e6b 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollFindSensorV2Fragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollFindSensorV2Fragment.kt
@@ -50,7 +50,7 @@
  * 2. Explain to the user how the enrollment process shown by [FingerprintEnrollEnrollingV2Fragment]
  *    will work.
  */
-class FingerprintEnrollFindSensorV2Fragment : Fragment() {
+class FingerprintEnrollFindSensorV2Fragment(val sensorType: FingerprintSensorType) : Fragment() {
   // This is only for non-udfps or non-sfps sensor. For udfps and sfps, we show lottie.
   private var animation: FingerprintFindSensorAnimation? = null
 
@@ -62,7 +62,7 @@
   override fun onCreateView(
     inflater: LayoutInflater,
     container: ViewGroup?,
-    savedInstanceState: Bundle?
+    savedInstanceState: Bundle?,
   ): View? {
 
     val sensorType =
@@ -104,8 +104,7 @@
       }
       lifecycleScope.launch {
         viewModel.showRfpsAnimation.collect {
-          animation =
-            view.findViewById(R.id.fingerprint_sensor_location_animation)
+          animation = view.findViewById(R.id.fingerprint_sensor_location_animation)
           animation!!.startAnimation()
         }
       }
@@ -128,14 +127,7 @@
     footerBarMixin.secondaryButton =
       FooterButton.Builder(requireActivity())
         .setText(R.string.security_settings_fingerprint_enroll_enrolling_skip)
-        .setListener {
-          run {
-            // TODO: Show the dialog for suw
-            Log.d(TAG, "onSkipClicked")
-            // TODO: Finish activity in the root activity instead.
-            requireActivity().finish()
-          }
-        }
+        .setListener { viewModel.secondaryButtonClicked() }
         .setButtonType(FooterButton.ButtonType.SKIP)
         .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Secondary)
         .build()
@@ -146,10 +138,8 @@
       FooterButton.Builder(requireActivity())
         .setText(R.string.security_settings_udfps_enroll_find_sensor_start_button)
         .setListener {
-          run {
-            Log.d(TAG, "onStartButtonClick")
-            viewModel.proceedToEnrolling()
-          }
+          Log.d(TAG, "onStartButtonClick")
+          viewModel.proceedToEnrolling()
         }
         .setButtonType(FooterButton.ButtonType.NEXT)
         .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary)
@@ -159,7 +149,7 @@
   private fun setupLottie(
     view: View,
     lottieAnimation: Int,
-    lottieClickListener: View.OnClickListener? = null
+    lottieClickListener: View.OnClickListener? = null,
   ) {
     val illustrationLottie: LottieAnimationView? = view.findViewById(R.id.illustration_lottie)
     illustrationLottie?.setAnimation(lottieAnimation)
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollIntroV2Fragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollIntroV2Fragment.kt
index 32d201d..53d0ddf 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollIntroV2Fragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollIntroV2Fragment.kt
@@ -24,7 +24,6 @@
 import android.os.Bundle
 import android.text.Html
 import android.text.method.LinkMovementMethod
-import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -36,9 +35,8 @@
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.lifecycleScope
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.Unicorn
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
+import com.android.settings.biometrics.fingerprint2.lib.model.Unicorn
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollIntroViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
@@ -48,6 +46,7 @@
 import com.google.android.setupdesign.template.RequireScrollMixin
 import com.google.android.setupdesign.util.DynamicColorPalette
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.launch
 
 private const val TAG = "FingerprintEnrollmentIntroV2Fragment"
@@ -96,16 +95,14 @@
   private lateinit var footerBarMixin: FooterBarMixin
   private lateinit var textModel: TextModel
 
-  // Note that the ViewModels cannot be requested before the onCreate call
-  private val navigationViewModel: FingerprintEnrollNavigationViewModel by lazy {
-    viewModelProvider[FingerprintEnrollNavigationViewModel::class.java]
+  private val viewModel: FingerprintEnrollIntroViewModel by lazy {
+    viewModelProvider[FingerprintEnrollIntroViewModel::class.java]
   }
-  private val fingerprintViewModel: FingerprintEnrollViewModel by lazy {
-    viewModelProvider[FingerprintEnrollViewModel::class.java]
-  }
+
   private val fingerprintScrollViewModel: FingerprintScrollViewModel by lazy {
     viewModelProvider[FingerprintScrollViewModel::class.java]
   }
+
   private val gateKeeperViewModel: FingerprintGatekeeperViewModel by lazy {
     viewModelProvider[FingerprintGatekeeperViewModel::class.java]
   }
@@ -113,17 +110,16 @@
   override fun onCreateView(
     inflater: LayoutInflater,
     container: ViewGroup?,
-    savedInstanceState: Bundle?
+    savedInstanceState: Bundle?,
   ): View? =
     super.onCreateView(inflater, container, savedInstanceState).also { theView ->
       val view = theView!!
 
       viewLifecycleOwner.lifecycleScope.launch {
-        combine(
-            navigationViewModel.fingerprintFlow,
-            fingerprintViewModel.sensorType,
-          ) { enrollType, sensorType ->
-            Pair(enrollType, sensorType)
+        combine(viewModel.fingerprintFlow, viewModel.sensor.filterNotNull()) {
+            enrollType,
+            sensorType ->
+            Pair(enrollType, sensorType.sensorType)
           }
           .collect { (enrollType, sensorType) ->
             textModel =
@@ -147,7 +143,7 @@
                 R.id.icon_trash_can,
                 R.id.icon_info,
                 R.id.icon_shield,
-                R.id.icon_link
+                R.id.icon_link,
               )
               .forEach { icon ->
                 view.requireViewById<ImageView>(icon).drawable.colorFilter = colorFilter
@@ -186,31 +182,24 @@
       return view
     }
 
-  /**
-   * TODO (b/305269201): This link isn't displaying for screenshot tests.
-   */
+  /** TODO (b/305269201): This link isn't displaying for screenshot tests. */
   private fun setFooterLink(view: View) {
     val footerLink: TextView = view.requireViewById(R.id.footer_learn_more)
     footerLink.movementMethod = LinkMovementMethod.getInstance()
     footerLink.text =
       Html.fromHtml(
         getString(R.string.security_settings_fingerprint_v2_enroll_introduction_message_learn_more),
-        Html.FROM_HTML_MODE_LEGACY
+        Html.FROM_HTML_MODE_LEGACY,
       )
   }
 
-  private fun setupFooterBarAndScrollView(
-    view: View,
-  ) {
+  private fun setupFooterBarAndScrollView(view: View) {
     val scrollView: ScrollView =
       view.requireViewById(com.google.android.setupdesign.R.id.sud_scroll_view)
     scrollView.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES
     // Next button responsible for starting the next fragment.
     val onNextButtonClick: View.OnClickListener =
-      View.OnClickListener {
-        Log.d(TAG, "OnNextClicked")
-        navigationViewModel.nextStep()
-      }
+      View.OnClickListener { viewModel.primaryButtonClicked() }
 
     val layout: GlifLayout = view.findViewById(R.id.setup_wizard_layout)!!
     footerBarMixin = layout.getMixin(FooterBarMixin::class.java)
@@ -225,11 +214,11 @@
     footerBarMixin.setSecondaryButton(
       FooterButton.Builder(requireContext())
         .setText(textModel.negativeButton)
-        .setListener({ Log.d(TAG, "prevClicked") })
+        .setListener { viewModel.onSecondaryButtonClicked() }
         .setButtonType(FooterButton.ButtonType.NEXT)
         .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary)
         .build(),
-      true /* usePrimaryStyle */
+      true, /* usePrimaryStyle */
     )
 
     val primaryButton = footerBarMixin.primaryButton
@@ -242,7 +231,7 @@
       requireContext(),
       primaryButton,
       R.string.security_settings_face_enroll_introduction_more,
-      onNextButtonClick
+      onNextButtonClick,
     )
 
     requireScrollMixin.setOnRequireScrollStateChangedListener { scrollNeeded: Boolean ->
@@ -257,7 +246,7 @@
         if (consented) {
           primaryButton.setText(
             requireContext(),
-            R.string.security_settings_fingerprint_enroll_introduction_agree
+            R.string.security_settings_fingerprint_enroll_introduction_agree,
           )
           secondaryButton.visibility = View.VISIBLE
         } else {
@@ -309,7 +298,7 @@
   private fun getIconColorFilter(): PorterDuffColorFilter {
     return PorterDuffColorFilter(
       DynamicColorPalette.getColor(context, DynamicColorPalette.ColorType.ACCENT),
-      PorterDuff.Mode.SRC_IN
+      PorterDuff.Mode.SRC_IN,
     )
   }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/fragment/RFPSEnrollFragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/fragment/RFPSEnrollFragment.kt
index d8c2f5a..c6e284a 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/fragment/RFPSEnrollFragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/fragment/RFPSEnrollFragment.kt
@@ -32,13 +32,15 @@
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSIconTouchViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.widget.FingerprintErrorDialog
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.widget.IconTouchDialog
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.widget.RFPSProgressBar
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.OrientationStateViewModel
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment
 import com.google.android.setupcompat.template.FooterBarMixin
@@ -49,8 +51,6 @@
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.launch
 
-private const val TAG = "RFPSEnrollFragment"
-
 /** This fragment is responsible for taking care of rear fingerprint enrollment. */
 class RFPSEnrollFragment : Fragment(R.layout.fingerprint_v2_rfps_enroll_enrolling) {
 
@@ -74,11 +74,14 @@
   private val backgroundViewModel: BackgroundViewModel by lazy {
     ViewModelProvider(requireActivity())[BackgroundViewModel::class.java]
   }
+  private val navigationViewModel: FingerprintNavigationViewModel by lazy {
+    ViewModelProvider(requireActivity())[FingerprintNavigationViewModel::class.java]
+  }
 
   override fun onCreateView(
     inflater: LayoutInflater,
     container: ViewGroup?,
-    savedInstanceState: Bundle?
+    savedInstanceState: Bundle?,
   ): View? {
     val view = super.onCreateView(inflater, container, savedInstanceState)!!
     val fragment = this
@@ -99,7 +102,7 @@
     footerBarMixin.secondaryButton =
       FooterButton.Builder(context)
         .setText(R.string.security_settings_fingerprint_enroll_enrolling_skip)
-        .setListener { Log.e(TAG, "skip enrollment!") }
+        .setListener { rfpsViewModel.negativeButtonClicked() }
         .setButtonType(FooterButton.ButtonType.SKIP)
         .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Secondary)
         .build()
@@ -150,7 +153,7 @@
     viewLifecycleOwner.lifecycleScope.launch {
       backgroundViewModel.background
         .filter { inBackground -> inBackground }
-        .collect { rfpsViewModel.stopEnrollment() }
+        .collect { rfpsViewModel.didGoToBackground() }
     }
 
     viewLifecycleOwner.lifecycleScope.launch {
@@ -171,7 +174,6 @@
           .setDuration(200)
           .setInterpolator(linearOutSlowInInterpolator)
           .start()
-
       }
     }
 
@@ -207,6 +209,12 @@
         dismissDialogs()
       }
     }
+
+    viewLifecycleOwner.lifecycleScope.launch {
+      rfpsViewModel.didCompleteEnrollment
+        .filter { it }
+        .collect { rfpsViewModel.finishedSuccessfully() }
+    }
     return view
   }
 
@@ -215,29 +223,19 @@
     viewLifecycleOwner.lifecycleScope.launch {
       try {
         val shouldRestartEnrollment = FingerprintErrorDialog.showInstance(error, fragment)
+        rfpsViewModel.userClickedStopEnrollDialog()
       } catch (exception: Exception) {
         Log.e(TAG, "Exception occurred $exception")
       }
-      onEnrollmentFailed()
     }
   }
 
-  private fun onEnrollmentFailed() {
-    rfpsViewModel.stopEnrollment()
-  }
-
   private fun handleEnrollProgress(progress: FingerEnrollState.EnrollProgress) {
     progressBar.updateProgress(
       progress.remainingSteps.toFloat() / progress.totalStepsRequired.toFloat()
     )
-
-    if (progress.remainingSteps == 0) {
-      performNextStepSuccess()
-    }
   }
 
-  private fun performNextStepSuccess() {}
-
   private fun dismissDialogs() {
     val transaction = parentFragmentManager.beginTransaction()
     for (frag in parentFragmentManager.fragments) {
@@ -249,4 +247,9 @@
     }
     transaction.commitAllowingStateLoss()
   }
+
+  companion object {
+    private const val TAG = "RFPSEnrollFragment"
+    private val navStep = FingerprintNavigationStep.Enrollment::class
+  }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/viewmodel/RFPSIconTouchViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/viewmodel/RFPSIconTouchViewModel.kt
index c16e65c..cbcb1d4 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/viewmodel/RFPSIconTouchViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/viewmodel/RFPSIconTouchViewModel.kt
@@ -38,9 +38,9 @@
   private val _touches: MutableStateFlow<Int> = MutableStateFlow(0)
 
   /**
-   * Whether or not the UI should be showing the dialog. By making this SharingStarted.Eagerly
-   * the first event 0 % 3 == 0 will fire as soon as this view model is created, so it should
-   * be ignored and work as intended.
+   * Whether or not the UI should be showing the dialog. By making this SharingStarted.Eagerly the
+   * first event 0 % 3 == 0 will fire as soon as this view model is created, so it should be ignored
+   * and work as intended.
    */
   val shouldShowDialog: Flow<Boolean> =
     _touches
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/viewmodel/RFPSViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/viewmodel/RFPSViewModel.kt
index 58d604e..99250e6 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/viewmodel/RFPSViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/viewmodel/RFPSViewModel.kt
@@ -19,13 +19,17 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintAction
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollEnrollingViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Enrollment
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.filterIsInstance
+import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.shareIn
 import kotlinx.coroutines.flow.transform
@@ -34,9 +38,10 @@
 /** View Model used by the rear fingerprint enrollment fragment. */
 class RFPSViewModel(
   private val fingerprintEnrollViewModel: FingerprintEnrollEnrollingViewModel,
+  private val navigationViewModel: FingerprintNavigationViewModel,
 ) : ViewModel() {
 
-  /** Value to indicate if the text view is visible or not **/
+  /** Value to indicate if the text view is visible or not */
   private val _textViewIsVisible = MutableStateFlow<Boolean>(false)
   val textViewIsVisible: Flow<Boolean> = _textViewIsVisible.asStateFlow()
 
@@ -61,9 +66,8 @@
   val helpMessage: Flow<FingerEnrollState.EnrollHelp?> =
     enrollFlow
       .filterIsInstance<FingerEnrollState.EnrollHelp>()
-      .shareIn(viewModelScope, SharingStarted.Eagerly, 0).transform {
-        _textViewIsVisible.update { true }
-      }
+      .shareIn(viewModelScope, SharingStarted.Eagerly, 0)
+      .transform { _textViewIsVisible.update { true } }
 
   /**
    * The error message should only be shown once, for scenarios like screen rotations, we don't want
@@ -74,6 +78,8 @@
       .filterIsInstance<FingerEnrollState.EnrollError>()
       .shareIn(viewModelScope, SharingStarted.Eagerly, 0)
 
+  val didCompleteEnrollment: Flow<Boolean> = progress.filterNotNull().map { it.remainingSteps == 0 }
+
   /** Indicates if the consumer is ready for enrollment */
   fun readyForEnrollment() {
     fingerprintEnrollViewModel.canEnroll()
@@ -88,15 +94,51 @@
     _textViewIsVisible.update { isVisible }
   }
 
+  /** Indicates that the user is done with trying to enroll a fingerprint */
+  fun userClickedStopEnrollDialog() {
+    navigationViewModel.update(
+      FingerprintAction.USER_CLICKED_FINISH,
+      navStep,
+      "${TAG}#userClickedStopEnrollingDialog",
+    )
+  }
+
+  /** Indicates that the application went to the background. */
+  fun didGoToBackground() {
+    navigationViewModel.update(
+      FingerprintAction.DID_GO_TO_BACKGROUND,
+      navStep,
+      "${TAG}#didGoToBackground",
+    )
+    stopEnrollment()
+  }
+
+  /** Indicates the negative button has been clicked */
+  fun negativeButtonClicked() {
+    navigationViewModel.update(
+      FingerprintAction.NEGATIVE_BUTTON_PRESSED,
+      navStep,
+      "${TAG}negativeButtonClicked",
+    )
+  }
+
+  fun finishedSuccessfully() {
+    navigationViewModel.update(FingerprintAction.NEXT, navStep, "${TAG}#progressFinished")
+  }
+
   class RFPSViewModelFactory(
     private val fingerprintEnrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel,
+    private val navigationViewModel: FingerprintNavigationViewModel,
   ) : ViewModelProvider.Factory {
 
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
-      return RFPSViewModel(fingerprintEnrollEnrollingViewModel) as T
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
+      return RFPSViewModel(fingerprintEnrollEnrollingViewModel, navigationViewModel) as T
     }
   }
+
+  companion object {
+    private val navStep = Enrollment::class
+    private const val TAG = "RFPSViewModel"
+  }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/widget/FingerprintErrorDialog.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/widget/FingerprintErrorDialog.kt
index b9c628e..9c0040b 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/widget/FingerprintErrorDialog.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/widget/FingerprintErrorDialog.kt
@@ -24,7 +24,7 @@
 import android.util.Log
 import androidx.fragment.app.Fragment
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment
 import kotlin.coroutines.resume
 import kotlinx.coroutines.suspendCancellableCoroutine
@@ -86,39 +86,28 @@
     private const val KEY_TITLE = "fingerprint_title"
     private const val KEY_SHOULD_TRY_AGAIN = "should_try_again"
 
-    suspend fun showInstance(
-        error: FingerEnrollState.EnrollError,
-        fragment: Fragment,
-    ) = suspendCancellableCoroutine { continuation ->
-      val dialog = FingerprintErrorDialog()
-      dialog.onTryAgain = DialogInterface.OnClickListener { _, _ -> continuation.resume(true) }
+    suspend fun showInstance(error: FingerEnrollState.EnrollError, fragment: Fragment) =
+      suspendCancellableCoroutine { continuation ->
+        val dialog = FingerprintErrorDialog()
+        dialog.onTryAgain = DialogInterface.OnClickListener { _, _ -> continuation.resume(true) }
 
-      dialog.onContinue = DialogInterface.OnClickListener { _, _ -> continuation.resume(false) }
+        dialog.onContinue = DialogInterface.OnClickListener { _, _ -> continuation.resume(false) }
 
-      dialog.onCancelListener =
-        DialogInterface.OnCancelListener {
-          Log.d(TAG, "onCancelListener clicked $dialog")
-          continuation.resume(null)
-        }
+        dialog.onCancelListener =
+          DialogInterface.OnCancelListener {
+            Log.d(TAG, "onCancelListener clicked $dialog")
+            continuation.resume(null)
+          }
 
-      continuation.invokeOnCancellation { Log.d(TAG, "invokeOnCancellation $dialog") }
+        continuation.invokeOnCancellation { Log.d(TAG, "invokeOnCancellation $dialog") }
 
-      val bundle = Bundle()
-      bundle.putInt(
-        KEY_TITLE,
-        error.errTitle,
-      )
-      bundle.putInt(
-        KEY_MESSAGE,
-        error.errString,
-      )
-      bundle.putBoolean(
-        KEY_SHOULD_TRY_AGAIN,
-        error.shouldRetryEnrollment,
-      )
-      dialog.arguments = bundle
-      Log.d(TAG, "showing dialog $dialog")
-      dialog.show(fragment.parentFragmentManager, FingerprintErrorDialog::class.java.toString())
-    }
+        val bundle = Bundle()
+        bundle.putInt(KEY_TITLE, error.errTitle)
+        bundle.putInt(KEY_MESSAGE, error.errString)
+        bundle.putBoolean(KEY_SHOULD_TRY_AGAIN, error.shouldRetryEnrollment)
+        dialog.arguments = bundle
+        Log.d(TAG, "showing dialog $dialog")
+        dialog.show(fragment.parentFragmentManager, FingerprintErrorDialog::class.java.toString())
+      }
   }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/AccessibilityViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/AccessibilityViewModel.kt
index a86ad5d..608b370 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/AccessibilityViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/AccessibilityViewModel.kt
@@ -41,15 +41,13 @@
       .stateIn(
         viewModelScope, // This is going to tied to the view model scope
         SharingStarted.WhileSubscribed(), // When no longer subscribed, we removeTheListener
-        false
+        false,
       )
 
   class AccessibilityViewModelFactory(private val accessibilityManager: AccessibilityManager) :
     ViewModelProvider.Factory {
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
       return AccessibilityViewModel(accessibilityManager) as T
     }
   }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollEnrollingViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollEnrollingViewModel.kt
index 7ab315e..63182bb 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollEnrollingViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollEnrollingViewModel.kt
@@ -25,8 +25,8 @@
 import kotlinx.coroutines.flow.update
 
 /**
- * This class is a wrapper around the [FingerprintEnrollViewModel] and decides when
- * the user should or should not be enrolling.
+ * This class is a wrapper around the [FingerprintEnrollViewModel] and decides when the user should
+ * or should not be enrolling.
  */
 class FingerprintEnrollEnrollingViewModel(
   private val fingerprintEnrollViewModel: FingerprintEnrollViewModel,
@@ -72,12 +72,10 @@
 
   class FingerprintEnrollEnrollingViewModelFactory(
     private val fingerprintEnrollViewModel: FingerprintEnrollViewModel,
-    private val backgroundViewModel: BackgroundViewModel
+    private val backgroundViewModel: BackgroundViewModel,
   ) : ViewModelProvider.Factory {
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
       return FingerprintEnrollEnrollingViewModel(fingerprintEnrollViewModel, backgroundViewModel)
         as T
     }
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 7722a46..92261b1 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
@@ -19,8 +19,10 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
-import com.android.settings.biometrics.fingerprint2.shared.model.SetupWizard
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.SetupWizard
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollFindSensorV2Fragment
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Education
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -36,20 +38,22 @@
 
 /** Models the UI state for [FingerprintEnrollFindSensorV2Fragment]. */
 class FingerprintEnrollFindSensorViewModel(
-  private val navigationViewModel: FingerprintEnrollNavigationViewModel,
+  private val navigationViewModel: FingerprintNavigationViewModel,
   private val fingerprintEnrollViewModel: FingerprintEnrollViewModel,
   private val gatekeeperViewModel: FingerprintGatekeeperViewModel,
   backgroundViewModel: BackgroundViewModel,
   accessibilityViewModel: AccessibilityViewModel,
   foldStateViewModel: FoldStateViewModel,
-  orientationStateViewModel: OrientationStateViewModel
+  orientationStateViewModel: OrientationStateViewModel,
+  fingerprintFlowViewModel: FingerprintFlowViewModel,
 ) : ViewModel() {
+
   /** Represents the stream of sensor type. */
   val sensorType: Flow<FingerprintSensorType> =
     fingerprintEnrollViewModel.sensorType.shareIn(
       viewModelScope,
       SharingStarted.WhileSubscribed(),
-      1
+      1,
     )
   private val _isUdfps: Flow<Boolean> =
     sensorType.map {
@@ -103,10 +107,10 @@
           fingerprintEnrollViewModel.sensorType,
           gatekeeperViewModel.hasValidGatekeeperInfo,
           gatekeeperViewModel.gatekeeperInfo,
-          navigationViewModel.navigationViewModel
-        ) { sensorType, hasValidGatekeeperInfo, gatekeeperInfo, navigationViewModel ->
+          navigationViewModel.currentScreen,
+        ) { sensorType, hasValidGatekeeperInfo, gatekeeperInfo, currStep ->
           val shouldStartEnroll =
-            navigationViewModel.currStep == Education &&
+            currStep is Education &&
               sensorType != FingerprintSensorType.UDFPS_OPTICAL &&
               sensorType != FingerprintSensorType.UDFPS_ULTRASONIC &&
               hasValidGatekeeperInfo
@@ -128,22 +132,19 @@
         // Only collect the flow when we should be running.
         if (it) {
           combine(
-              navigationViewModel.fingerprintFlow,
               fingerprintEnrollViewModel.educationEnrollFlow.filterNotNull(),
-            ) { enrollType, educationFlow ->
-              Pair(enrollType, educationFlow)
+              fingerprintFlowViewModel.fingerprintFlow,
+            ) { educationFlow, type ->
+              Pair(educationFlow, type)
             }
-            .collect { (enrollType, educationFlow) ->
+            .collect { (educationFlow, type) ->
               when (educationFlow) {
-                // TODO: Cancel the enroll() when EnrollProgress is received instead of proceeding
-                // to
-                // Enrolling page. Otherwise Enrolling page will receive the EnrollError.
                 is FingerEnrollState.EnrollProgress -> proceedToEnrolling()
                 is FingerEnrollState.EnrollError -> {
                   if (educationFlow.isCancelled) {
                     proceedToEnrolling()
                   } else {
-                    _showErrorDialog.update { Pair(educationFlow.errString, enrollType == SetupWizard) }
+                    _showErrorDialog.update { Pair(educationFlow.errString, type == SetupWizard) }
                   }
                 }
                 is FingerEnrollState.EnrollHelp -> {}
@@ -169,17 +170,28 @@
 
   /** Proceed to EnrollEnrolling page. */
   fun proceedToEnrolling() {
-    navigationViewModel.nextStep()
+    stopEducation()
+    navigationViewModel.update(FingerprintAction.NEXT, navStep, "$TAG#proceedToEnrolling")
+  }
+
+  /** Indicates the secondary button has been clicked */
+  fun secondaryButtonClicked() {
+    navigationViewModel.update(
+      FingerprintAction.NEGATIVE_BUTTON_PRESSED,
+      navStep,
+      "${TAG}#secondaryButtonClicked",
+    )
   }
 
   class FingerprintEnrollFindSensorViewModelFactory(
-    private val navigationViewModel: FingerprintEnrollNavigationViewModel,
+    private val navigationViewModel: FingerprintNavigationViewModel,
     private val fingerprintEnrollViewModel: FingerprintEnrollViewModel,
     private val gatekeeperViewModel: FingerprintGatekeeperViewModel,
     private val backgroundViewModel: BackgroundViewModel,
     private val accessibilityViewModel: AccessibilityViewModel,
     private val foldStateViewModel: FoldStateViewModel,
-    private val orientationStateViewModel: OrientationStateViewModel
+    private val orientationStateViewModel: OrientationStateViewModel,
+    private val fingerprintFlowViewModel: FingerprintFlowViewModel,
   ) : ViewModelProvider.Factory {
     @Suppress("UNCHECKED_CAST")
     override fun <T : ViewModel> create(modelClass: Class<T>): T {
@@ -190,9 +202,15 @@
         backgroundViewModel,
         accessibilityViewModel,
         foldStateViewModel,
-        orientationStateViewModel
+        orientationStateViewModel,
+        fingerprintFlowViewModel,
       )
         as T
     }
   }
+
+  companion object {
+    private const val TAG = "FingerprintEnrollFindSensorViewModel"
+    private val navStep = Education::class
+  }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollIntroViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollIntroViewModel.kt
new file mode 100644
index 0000000..3bf003c
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollIntroViewModel.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 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.ui.enrollment.viewmodel
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintFlow
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Introduction
+import com.android.systemui.biometrics.shared.model.FingerprintSensor
+import kotlinx.coroutines.flow.Flow
+
+/** A view model for fingerprint enroll introduction. */
+class FingerprintEnrollIntroViewModel(
+  val navigationViewModel: FingerprintNavigationViewModel,
+  private val fingerprintFlowViewModel: FingerprintFlowViewModel,
+  private val fingerprintManagerInteractor: FingerprintManagerInteractor,
+) : ViewModel() {
+
+  /** Represents a stream of [FingerprintSensor] */
+  val sensor: Flow<FingerprintSensor?> = fingerprintManagerInteractor.sensorPropertiesInternal
+
+  /** Represents a stream of [FingerprintFlow] */
+  val fingerprintFlow: Flow<FingerprintFlow?> = fingerprintFlowViewModel.fingerprintFlow
+
+  /** Indicates the primary button has been clicked */
+  fun primaryButtonClicked() {
+    navigationViewModel.update(FingerprintAction.NEXT, navStep, "${TAG}#onNextClicked")
+  }
+
+  /** Indicates the secondary button has been clicked */
+  fun onSecondaryButtonClicked() {
+    navigationViewModel.update(
+      FingerprintAction.NEGATIVE_BUTTON_PRESSED,
+      navStep,
+      "${TAG}#negativeButtonClicked",
+    )
+  }
+
+  class FingerprintEnrollIntoViewModelFactory(
+    val navigationViewModel: FingerprintNavigationViewModel,
+    val fingerprintFlowViewModel: FingerprintFlowViewModel,
+    val fingerprintManagerInteractor: FingerprintManagerInteractor,
+  ) : ViewModelProvider.Factory {
+
+    @Suppress("UNCHECKED_CAST")
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
+      return FingerprintEnrollIntroViewModel(
+        navigationViewModel,
+        fingerprintFlowViewModel,
+        fingerprintManagerInteractor,
+      )
+        as T
+    }
+  }
+
+  companion object {
+    val navStep = Introduction::class
+    private const val TAG = "FingerprintEnrollIntroViewModel"
+  }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollViewModel.kt
index c7a1071..c2cff5e 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollViewModel.kt
@@ -18,9 +18,11 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
-import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
-import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Education
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Enrollment
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
@@ -34,7 +36,7 @@
 class FingerprintEnrollViewModel(
   private val fingerprintManagerInteractor: FingerprintManagerInteractor,
   gatekeeperViewModel: FingerprintGatekeeperViewModel,
-  navigationViewModel: FingerprintEnrollNavigationViewModel,
+  val navigationViewModel: FingerprintNavigationViewModel,
 ) : ViewModel() {
 
   /**
@@ -45,8 +47,8 @@
    */
   var sensorTypeCached: FingerprintSensorType? = null
   private var _enrollReason: Flow<EnrollReason?> =
-    navigationViewModel.navigationViewModel.map {
-      when (it.currStep) {
+    navigationViewModel.currentScreen.map {
+      when (it) {
         is Enrollment -> EnrollReason.EnrollEnrolling
         is Education -> EnrollReason.FindSensor
         else -> null
@@ -64,8 +66,7 @@
    * This flow should be the only flow which calls enroll().
    */
   val _enrollFlow: Flow<FingerEnrollState> =
-    combine(gatekeeperViewModel.gatekeeperInfo, _enrollReason) { hardwareAuthToken, enrollReason,
-        ->
+    combine(gatekeeperViewModel.gatekeeperInfo, _enrollReason) { hardwareAuthToken, enrollReason ->
         Pair(hardwareAuthToken, enrollReason)
       }
       .transformLatest {
@@ -110,18 +111,11 @@
   class FingerprintEnrollViewModelFactory(
     val interactor: FingerprintManagerInteractor,
     val gatekeeperViewModel: FingerprintGatekeeperViewModel,
-    val navigationViewModel: FingerprintEnrollNavigationViewModel,
+    val navigationViewModel: FingerprintNavigationViewModel,
   ) : ViewModelProvider.Factory {
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
-      return FingerprintEnrollViewModel(
-        interactor,
-        gatekeeperViewModel,
-        navigationViewModel,
-      )
-        as T
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
+      return FingerprintEnrollViewModel(interactor, gatekeeperViewModel, navigationViewModel) as T
     }
   }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrolllNavigationViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrolllNavigationViewModel.kt
deleted file mode 100644
index 2e5dce0..0000000
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrolllNavigationViewModel.kt
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2023 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.ui.enrollment.viewmodel
-
-import android.util.Log
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
-import androidx.lifecycle.viewModelScope
-import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintFlow
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.shareIn
-import kotlinx.coroutines.flow.update
-import kotlinx.coroutines.launch
-
-private const val TAG = "FingerprintEnrollNavigationViewModel"
-
-/**
- * This class is responsible for sending a [NavigationStep] which indicates where the user is in the
- * Fingerprint Enrollment flow
- */
-class FingerprintEnrollNavigationViewModel(
-  private val dispatcher: CoroutineDispatcher,
-  private val fingerprintManagerInteractor: FingerprintManagerInteractor,
-  private val gatekeeperViewModel: FingerprintGatekeeperViewModel,
-  private val firstStep: NextStepViewModel,
-  private val navState: NavState,
-  private val theFingerprintFlow: FingerprintFlow,
-) : ViewModel() {
-
-  private class InternalNavigationStep(
-    lastStep: NextStepViewModel,
-    nextStep: NextStepViewModel,
-    forward: Boolean,
-    var canNavigate: Boolean,
-  ) : NavigationStep(lastStep, nextStep, forward)
-
-  private var _fingerprintFlow = MutableStateFlow<FingerprintFlow?>(theFingerprintFlow)
-
-  /** A flow that indicates the [FingerprintFlow] */
-  val fingerprintFlow: Flow<FingerprintFlow?> = _fingerprintFlow.asStateFlow()
-
-  private val _navigationStep =
-    MutableStateFlow(
-      InternalNavigationStep(PlaceHolderState, firstStep, forward = false, canNavigate = true)
-    )
-
-  init {
-    viewModelScope.launch {
-      gatekeeperViewModel.credentialConfirmed.filterNotNull().collect {
-        if (_navigationStep.value.currStep is LaunchConfirmDeviceCredential) {
-          if (it) nextStep() else finish()
-        }
-      }
-    }
-  }
-
-  /**
-   * A flow that contains the [NavigationStep] used to indicate where in the enrollment process the
-   * user is.
-   */
-  val navigationViewModel: Flow<NavigationStep> = _navigationStep.asStateFlow()
-
-  /** This action indicates that the UI should actually update the navigation to the given step. */
-  val navigationAction: Flow<NavigationStep?> =
-    _navigationStep.shareIn(viewModelScope, SharingStarted.Lazily, 0)
-
-  /** Used to start the next step of Fingerprint Enrollment. */
-  fun nextStep() {
-    viewModelScope.launch {
-      val currStep = _navigationStep.value.currStep
-      val nextStep = currStep.next(navState)
-      Log.d(TAG, "nextStep(${currStep} -> $nextStep)")
-      _navigationStep.update {
-        InternalNavigationStep(currStep, nextStep, forward = true, canNavigate = false)
-      }
-    }
-  }
-
-  /** Go back a step of fingerprint enrollment. */
-  fun prevStep() {
-    viewModelScope.launch {
-      val currStep = _navigationStep.value.currStep
-      val nextStep = currStep.prev(navState)
-      _navigationStep.update {
-        InternalNavigationStep(currStep, nextStep, forward = false, canNavigate = false)
-      }
-    }
-  }
-
-  private fun finish() {
-    _navigationStep.update {
-      InternalNavigationStep(Finish(null), Finish(null), forward = false, canNavigate = false)
-    }
-  }
-
-  class FingerprintEnrollNavigationViewModelFactory(
-    private val backgroundDispatcher: CoroutineDispatcher,
-    private val fingerprintManagerInteractor: FingerprintManagerInteractor,
-    private val fingerprintGatekeeperViewModel: FingerprintGatekeeperViewModel,
-    private val canSkipConfirm: Boolean,
-    private val fingerprintFlow: FingerprintFlow,
-  ) : ViewModelProvider.Factory {
-
-    @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
-
-      val navState = NavState(canSkipConfirm)
-      return FingerprintEnrollNavigationViewModel(
-        backgroundDispatcher,
-        fingerprintManagerInteractor,
-        fingerprintGatekeeperViewModel,
-        Start.next(navState),
-        navState,
-        fingerprintFlow,
-      )
-        as T
-    }
-  }
-}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintFlowViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintFlowViewModel.kt
new file mode 100644
index 0000000..f076524
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintFlowViewModel.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.ui.enrollment.viewmodel
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintFlow
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.shareIn
+
+class FingerprintFlowViewModel(private val fingerprintFlowType: FingerprintFlow) : ViewModel() {
+  val fingerprintFlow: Flow<FingerprintFlow> =
+    flowOf(fingerprintFlowType).shareIn(viewModelScope, SharingStarted.Eagerly, 1)
+
+  class FingerprintFlowViewModelFactory(val flowType: FingerprintFlow) : ViewModelProvider.Factory {
+
+    @Suppress("UNCHECKED_CAST")
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
+      return FingerprintFlowViewModel(flowType) as T
+    }
+  }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintGatekeeperViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintGatekeeperViewModel.kt
index db93d02..322be6a 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintGatekeeperViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintGatekeeperViewModel.kt
@@ -21,7 +21,7 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
-import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
@@ -29,11 +29,11 @@
 import kotlinx.coroutines.flow.update
 import kotlinx.coroutines.launch
 
-private const val TAG = "FingerprintGatekeeperViewModel"
-
 sealed interface GatekeeperInfo {
   object Invalid : GatekeeperInfo
+
   object Timeout : GatekeeperInfo
+
   data class GatekeeperPasswordInfo(val token: ByteArray?, val passwordHandle: Long?) :
     GatekeeperInfo
 }
@@ -97,7 +97,19 @@
       }
   }
 
+  class FingerprintGatekeeperViewModelFactory(
+    private val gatekeeperInfo: GatekeeperInfo?,
+    private val fingerprintManagerInteractor: FingerprintManagerInteractor,
+  ) : ViewModelProvider.Factory {
+
+    @Suppress("UNCHECKED_CAST")
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
+      return FingerprintGatekeeperViewModel(gatekeeperInfo, fingerprintManagerInteractor) as T
+    }
+  }
+
   companion object {
+    private const val TAG = "FingerprintGatekeeperViewModel"
     /**
      * A function that checks if the challenge and token are valid, in which case a
      * [GatekeeperInfo.GatekeeperPasswordInfo] is provided, else [GatekeeperInfo.Invalid]
@@ -110,17 +122,4 @@
       return GatekeeperInfo.GatekeeperPasswordInfo(token, challenge)
     }
   }
-
-  class FingerprintGatekeeperViewModelFactory(
-    private val gatekeeperInfo: GatekeeperInfo?,
-    private val fingerprintManagerInteractor: FingerprintManagerInteractor,
-  ) : ViewModelProvider.Factory {
-
-    @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
-      return FingerprintGatekeeperViewModel(gatekeeperInfo, fingerprintManagerInteractor) as T
-    }
-  }
 }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintNavigationStep.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintNavigationStep.kt
new file mode 100644
index 0000000..979f953
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintNavigationStep.kt
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2023 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.ui.enrollment.viewmodel
+
+import com.android.settings.biometrics.fingerprint2.lib.model.FastEnroll
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintFlow
+import com.android.systemui.biometrics.shared.model.FingerprintSensor
+
+/**
+ * A [FingerprintAction] event notifies the current [FingerprintNavigationStep] that an event
+ * occurred. Depending on the type of [FingerprintAction] and the current
+ * [FingerprintNavigationStep], the navstep will potentially produce a new
+ * [FingerprintNavigationStep] indicating either 1). Control flow has changed 2). The activity has
+ * finished 3). A transition is required
+ */
+enum class FingerprintAction {
+  NEXT,
+  PREV,
+  CONFIRM_DEVICE_SUCCESS,
+  CONFIRM_DEVICE_FAIL,
+  TRANSITION_FINISHED,
+  DID_GO_TO_BACKGROUND,
+  ACTIVITY_CREATED,
+  NEGATIVE_BUTTON_PRESSED,
+  USER_CLICKED_FINISH,
+}
+
+/** State that can be used to help a [FingerprintNavigationStep] determine the next step to take. */
+data class NavigationState(
+  val flowType: FingerprintFlow,
+  val hasConfirmedDeviceCredential: Boolean,
+  val fingerprintSensor: FingerprintSensor?,
+)
+
+/**
+ * A generic interface for operating on (state, action) -> state? which will produce either another
+ * FingerprintNavStep if something is required, or nothing.
+ *
+ * Note during the lifetime of the Activity, their should only be one [FingerprintNavigationStep] at
+ * a time.
+ */
+sealed interface FingerprintNavigationStep {
+  fun update(state: NavigationState, action: FingerprintAction): FingerprintNavigationStep?
+
+  /**
+   * This indicates that a transition should occur from one screen to another. This class should
+   * contain all necessary info about the transition.
+   *
+   * A transition step will cause a screen to change ownership from the current screen to the
+   * [nextUiStep], after the transition has been completed and a
+   * [FingerprintAction.TRANSITION_FINISHED] has been sent, the [nextUiStep] will be given control.
+   */
+  class TransitionStep(val nextUiStep: UiStep) : FingerprintNavigationStep {
+    override fun update(
+      state: NavigationState,
+      action: FingerprintAction,
+    ): FingerprintNavigationStep? {
+      return when (action) {
+        FingerprintAction.TRANSITION_FINISHED -> nextUiStep
+        else -> null
+      }
+    }
+
+    override fun toString(): String = "TransitionStep(nextUiStep=$nextUiStep)"
+  }
+
+  /** Indicates we should finish the enrolling activity */
+  data class Finish(val result: Int?) : FingerprintNavigationStep {
+    override fun update(
+      state: NavigationState,
+      action: FingerprintAction,
+    ): FingerprintNavigationStep? = null
+  }
+
+  /** UiSteps should have a 1 to 1 mapping between each screen of FingerprintEnrollment */
+  sealed class UiStep : FingerprintNavigationStep
+
+  /** This is the landing page for enrollment, where no content is shown. */
+  data object Init : UiStep() {
+    override fun update(
+      state: NavigationState,
+      action: FingerprintAction,
+    ): FingerprintNavigationStep? {
+      return when (action) {
+        FingerprintAction.ACTIVITY_CREATED -> {
+          if (!state.hasConfirmedDeviceCredential) {
+            TransitionStep(ConfirmDeviceCredential)
+          } else if (state.flowType is FastEnroll) {
+            TransitionStep(Enrollment(state.fingerprintSensor!!))
+          } else {
+            TransitionStep(Introduction)
+          }
+        }
+        else -> null
+      }
+    }
+  }
+
+  /** Indicates the ConfirmDeviceCredential activity is being presented to the user */
+  data object ConfirmDeviceCredential : UiStep() {
+    override fun update(
+      state: NavigationState,
+      action: FingerprintAction,
+    ): FingerprintNavigationStep? {
+      return when (action) {
+        FingerprintAction.CONFIRM_DEVICE_SUCCESS -> TransitionStep(Introduction)
+        FingerprintAction.CONFIRM_DEVICE_FAIL -> Finish(null)
+        else -> null
+      }
+    }
+  }
+
+  /** Indicates the FingerprintIntroduction screen is being presented to the user */
+  data object Introduction : UiStep() {
+    override fun update(
+      state: NavigationState,
+      action: FingerprintAction,
+    ): FingerprintNavigationStep? {
+      return when (action) {
+        FingerprintAction.NEXT -> TransitionStep(Education(state.fingerprintSensor!!))
+        FingerprintAction.NEGATIVE_BUTTON_PRESSED,
+        FingerprintAction.PREV -> Finish(null)
+        else -> null
+      }
+    }
+  }
+
+  /** Indicates the FingerprintEducation screen is being presented to the user */
+  data class Education(val sensor: FingerprintSensor) : UiStep() {
+    override fun update(
+      state: NavigationState,
+      action: FingerprintAction,
+    ): FingerprintNavigationStep? {
+      return when (action) {
+        FingerprintAction.NEXT -> TransitionStep(Enrollment(state.fingerprintSensor!!))
+        FingerprintAction.NEGATIVE_BUTTON_PRESSED,
+        FingerprintAction.PREV -> TransitionStep(Introduction)
+        else -> null
+      }
+    }
+  }
+
+  /** Indicates the Enrollment screen is being presented to the user */
+  data class Enrollment(val sensor: FingerprintSensor) : UiStep() {
+    override fun update(
+      state: NavigationState,
+      action: FingerprintAction,
+    ): FingerprintNavigationStep? {
+      return when (action) {
+        FingerprintAction.NEXT -> TransitionStep(Confirmation)
+        FingerprintAction.NEGATIVE_BUTTON_PRESSED,
+        FingerprintAction.USER_CLICKED_FINISH,
+        FingerprintAction.DID_GO_TO_BACKGROUND -> Finish(null)
+        else -> null
+      }
+    }
+  }
+
+  /** Indicates the Confirmation screen is being presented to the user */
+  data object Confirmation : UiStep() {
+    override fun update(
+      state: NavigationState,
+      action: FingerprintAction,
+    ): FingerprintNavigationStep? {
+      return when (action) {
+        FingerprintAction.NEXT -> Finish(null)
+        FingerprintAction.PREV -> TransitionStep(Education(state.fingerprintSensor!!))
+        else -> null
+      }
+    }
+  }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintNavigationViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintNavigationViewModel.kt
new file mode 100644
index 0000000..26c20cf
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintNavigationViewModel.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2023 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.ui.enrollment.viewmodel
+
+import android.util.Log
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Finish
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.TransitionStep
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.UiStep
+import java.lang.NullPointerException
+import kotlin.reflect.KClass
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combineTransform
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.launch
+
+/**
+ * This class is essentially a wrapper around [FingerprintNavigationStep] that will be used by
+ * fragments/viewmodels that want to consume these events. It should provide no additional
+ * functionality beyond what is available in [FingerprintNavigationStep].
+ */
+class FingerprintNavigationViewModel(
+  step: UiStep,
+  hasConfirmedDeviceCredential: Boolean,
+  flowViewModel: FingerprintFlowViewModel,
+  fingerprintManagerInteractor: FingerprintManagerInteractor,
+) : ViewModel() {
+
+  private var _navStateInternal: MutableStateFlow<NavigationState?> = MutableStateFlow(null)
+
+  init {
+    viewModelScope.launch {
+      flowViewModel.fingerprintFlow
+        .combineTransform(fingerprintManagerInteractor.sensorPropertiesInternal) { flow, props ->
+          if (props?.sensorId != -1) {
+            emit(NavigationState(flow, hasConfirmedDeviceCredential, props))
+          }
+        }
+        .collect { navState -> _navStateInternal.update { navState } }
+    }
+  }
+
+  private var _currentStep = MutableStateFlow<FingerprintNavigationStep?>(step)
+
+  private var _navigateTo: MutableStateFlow<UiStep?> = MutableStateFlow(null)
+  val navigateTo: Flow<UiStep?> = _navigateTo.asStateFlow()
+
+  /**
+   * This indicates a navigation event should occur. Navigation depends on navStateInternal being
+   * present.
+   */
+  val currentStep: Flow<FingerprintNavigationStep> =
+    _currentStep.filterNotNull().combineTransform(_navStateInternal.filterNotNull()) { navigation, _
+      ->
+      emit(navigation)
+    }
+
+  private var _finishState = MutableStateFlow<Finish?>(null)
+
+  /** This indicates the activity should finish. */
+  val shouldFinish: Flow<Finish?> = _finishState.asStateFlow()
+
+  private var _currentScreen = MutableStateFlow<UiStep?>(null)
+
+  /** This indicates what screen should currently be presenting to the user. */
+  val currentScreen: Flow<UiStep?> = _currentScreen.asStateFlow()
+
+  /** See [updateInternal] for more details */
+  fun update(action: FingerprintAction, caller: KClass<*>, debugStr: String) {
+    Log.d(TAG, "$caller.update($action) $debugStr")
+    val currentStep = _currentStep.value
+    val isUiStep = currentStep is UiStep
+    if (currentStep == null) {
+      throw NullPointerException("current step is null")
+    }
+    if (isUiStep && currentStep::class != caller) {
+      throw IllegalAccessError(
+        "Error $currentStep != $caller, $caller should not be sending any events at this time"
+      )
+    }
+    val navState = _navStateInternal.value
+    if (navState == null) {
+      throw NullPointerException("nav state is null")
+    }
+    val nextStep = currentStep.update(navState, action) ?: return
+    Log.d(TAG, "nextStep=$nextStep")
+    // Whenever an state update occurs, everything should be cleared.
+    _currentStep.update { nextStep }
+    _finishState.update { null }
+    _currentScreen.update { null }
+
+    when (nextStep) {
+      is TransitionStep -> {
+        _navigateTo.update { nextStep.nextUiStep }
+      }
+      is Finish -> {
+        _finishState.update { nextStep }
+      }
+      is UiStep -> {
+        _currentScreen.update { nextStep }
+      }
+    }
+  }
+
+  class FingerprintNavigationViewModelFactory(
+    private val step: UiStep,
+    private val hasConfirmedDeviceCredential: Boolean,
+    private val flowViewModel: FingerprintFlowViewModel,
+    private val fingerprintManagerInteractor: FingerprintManagerInteractor,
+  ) : ViewModelProvider.Factory {
+
+    @Suppress("UNCHECKED_CAST")
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
+      return FingerprintNavigationViewModel(
+        step,
+        hasConfirmedDeviceCredential,
+        flowViewModel,
+        fingerprintManagerInteractor,
+      )
+        as T
+    }
+  }
+
+  companion object {
+    private const val TAG = "FingerprintNavigationViewModel"
+  }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintScrollViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintScrollViewModel.kt
index 989d4d3..bc9703d 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintScrollViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintScrollViewModel.kt
@@ -39,9 +39,7 @@
   class FingerprintScrollViewModelFactory : ViewModelProvider.Factory {
 
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
       return FingerprintScrollViewModel() as T
     }
   }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FoldStateViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FoldStateViewModel.kt
index a4c7ff2..94a70b0 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FoldStateViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FoldStateViewModel.kt
@@ -49,9 +49,7 @@
 
   class FoldStateViewModelFactory(private val context: Context) : ViewModelProvider.Factory {
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
       return FoldStateViewModel(context) as T
     }
   }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/NextStepViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/NextStepViewModel.kt
deleted file mode 100644
index b68f6d6..0000000
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/NextStepViewModel.kt
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2023 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.ui.enrollment.viewmodel
-
-/**
- * A class that represents an action that the consumer should transition between lastStep and
- * currStep and in what direction this transition is occurring (e.g. forward or backwards)
- */
-open class NavigationStep(
-  val lastStep: NextStepViewModel,
-  val currStep: NextStepViewModel,
-  val forward: Boolean
-) {
-  override fun toString(): String {
-    return "lastStep=$lastStep, currStep=$currStep, forward=$forward"
-  }
-}
-
-/** The navigation state used by a [NavStep] to determine what the [NextStepViewModel] should be. */
-class NavState(val confirmedDevice: Boolean)
-
-interface NavStep<T> {
-  fun next(state: NavState): T
-  fun prev(state: NavState): T
-}
-
-/**
- * A class to represent a high level step (I.E. EnrollmentIntroduction) for FingerprintEnrollment.
- */
-sealed class NextStepViewModel : NavStep<NextStepViewModel>
-
-/**
- * This is the initial state for the previous step, used to indicate that there have been no
- * previous states.
- */
-object PlaceHolderState : NextStepViewModel() {
-  override fun next(state: NavState): NextStepViewModel = Finish(null)
-
-  override fun prev(state: NavState): NextStepViewModel = Finish(null)
-}
-
-/**
- * This state is the initial state for the current step, and will be used to determine if the user
- * needs to [LaunchConfirmDeviceCredential] if not, it will go to [Intro]
- */
-data object Start : NextStepViewModel() {
-  override fun next(state: NavState): NextStepViewModel =
-    if (state.confirmedDevice) Intro else LaunchConfirmDeviceCredential
-
-  override fun prev(state: NavState): NextStepViewModel = Finish(null)
-}
-
-/** State indicating enrollment has been completed */
-class Finish(val resultCode: Int?) : NextStepViewModel() {
-  override fun next(state: NavState): NextStepViewModel = Finish(resultCode)
-  override fun prev(state: NavState): NextStepViewModel = Finish(null)
-}
-
-/** State for the FingerprintEnrollment introduction */
-data object Intro : NextStepViewModel() {
-  override fun next(state: NavState): NextStepViewModel = Education
-  override fun prev(state: NavState): NextStepViewModel = Finish(null)
-}
-
-/** State for the FingerprintEnrollment education */
-data object Education : NextStepViewModel() {
-  override fun next(state: NavState): NextStepViewModel = Enrollment
-  override fun prev(state: NavState): NextStepViewModel = Intro
-}
-
-/** State for the FingerprintEnrollment enrollment */
-data object Enrollment : NextStepViewModel() {
-  override fun next(state: NavState): NextStepViewModel = Confirmation
-  override fun prev(state: NavState): NextStepViewModel = Education
-}
-
-/** State for the FingerprintEnrollment confirmation */
-object Confirmation : NextStepViewModel() {
-  override fun next(state: NavState): NextStepViewModel = Finish(0)
-  override fun prev(state: NavState): NextStepViewModel = Intro
-}
-
-/**
- * State used to send the user to the ConfirmDeviceCredential activity. This activity can either
- * confirm a users device credential, or have them create one.
- */
-object LaunchConfirmDeviceCredential : NextStepViewModel() {
-  override fun next(state: NavState): NextStepViewModel = Intro
-  override fun prev(state: NavState): NextStepViewModel = Finish(0)
-}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/OrientationStateViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/OrientationStateViewModel.kt
index 2e5f734..dd266e1 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/OrientationStateViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/OrientationStateViewModel.kt
@@ -58,7 +58,7 @@
       .stateIn(
         viewModelScope, // This is going to tied to the view model scope
         SharingStarted.WhileSubscribed(), // When no longer subscribed, we removeTheListener
-        context.display!!.rotation
+        context.display!!.rotation,
       )
 
   fun getRotationFromDefault(rotation: Int): Int {
@@ -73,9 +73,7 @@
 
   class OrientationViewModelFactory(private val context: Context) : ViewModelProvider.Factory {
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
       return OrientationStateViewModel(context) as T
     }
   }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/binder/FingerprintSettingsViewBinder.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/binder/FingerprintSettingsViewBinder.kt
index debdfb8..540e5ee 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/binder/FingerprintSettingsViewBinder.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/binder/FingerprintSettingsViewBinder.kt
@@ -19,8 +19,8 @@
 import android.hardware.fingerprint.FingerprintManager
 import android.util.Log
 import androidx.lifecycle.LifecycleCoroutineScope
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptModel
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.settings.biometrics.fingerprint2.ui.settings.binder.FingerprintSettingsViewBinder.FingerprintView
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.EnrollAdditionalFingerprint
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.EnrollFirstFingerprint
@@ -52,7 +52,7 @@
       userId: Int,
       gateKeeperPasswordHandle: Long?,
       challenge: Long?,
-      challengeToken: ByteArray?
+      challengeToken: ByteArray?,
     )
     /** Helper to launch an add fingerprint request */
     fun launchAddFingerprint(userId: Int, challengeToken: ByteArray?)
@@ -158,7 +158,7 @@
               nextStep.userId,
               nextStep.gateKeeperPasswordHandle,
               nextStep.challenge,
-              nextStep.challengeToken
+              nextStep.challengeToken,
             )
           is EnrollAdditionalFingerprint ->
             view.launchAddFingerprint(nextStep.userId, nextStep.challengeToken)
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintDeletionDialog.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintDeletionDialog.kt
index 71a22eb..46f64de 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintDeletionDialog.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintDeletionDialog.kt
@@ -26,7 +26,7 @@
 import android.os.UserManager
 import androidx.appcompat.app.AlertDialog
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment
 import kotlin.coroutines.resume
 import kotlinx.coroutines.suspendCancellableCoroutine
@@ -75,8 +75,7 @@
       message =
         devicePolicyManager?.resources?.getString(messageId) {
           message + "\n\n" + context.getString(defaultMessageId)
-        }
-          ?: ""
+        } ?: ""
     }
 
     alertDialog =
@@ -85,7 +84,7 @@
         .setMessage(message)
         .setPositiveButton(
           R.string.security_settings_fingerprint_enroll_dialog_delete,
-          onClickListener
+          onClickListener,
         )
         .setNegativeButton(R.string.cancel, onNegativeClickListener)
         .create()
@@ -94,10 +93,11 @@
 
   companion object {
     private const val KEY_FINGERPRINT = "fingerprint"
+
     suspend fun showInstance(
-        fp: FingerprintData,
-        lastFingerprint: Boolean,
-        target: FingerprintSettingsV2Fragment,
+      fp: FingerprintData,
+      lastFingerprint: Boolean,
+      target: FingerprintSettingsV2Fragment,
     ) = suspendCancellableCoroutine { continuation ->
       val dialog = FingerprintDeletionDialog()
       dialog.onClickListener = DialogInterface.OnClickListener { _, _ -> continuation.resume(true) }
@@ -109,7 +109,7 @@
       val bundle = Bundle()
       bundle.putObject(
         KEY_FINGERPRINT,
-        android.hardware.fingerprint.Fingerprint(fp.name, fp.fingerId, fp.deviceId)
+        android.hardware.fingerprint.Fingerprint(fp.name, fp.fingerId, fp.deviceId),
       )
       bundle.putBoolean(KEY_IS_LAST_FINGERPRINT, lastFingerprint)
       dialog.arguments = bundle
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsPreference.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsPreference.kt
index ea26946..09dcb81 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsPreference.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsPreference.kt
@@ -22,7 +22,7 @@
 import androidx.lifecycle.lifecycleScope
 import androidx.preference.PreferenceViewHolder
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.settingslib.widget.TwoTargetPreference
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
@@ -30,10 +30,10 @@
 private const val TAG = "FingerprintSettingsPreference"
 
 class FingerprintSettingsPreference(
-    context: Context,
-    val fingerprintViewModel: FingerprintData,
-    val fragment: FingerprintSettingsV2Fragment,
-    val isLastFingerprint: Boolean
+  context: Context,
+  val fingerprintViewModel: FingerprintData,
+  val fragment: FingerprintSettingsV2Fragment,
+  val isLastFingerprint: Boolean,
 ) : TwoTargetPreference(context) {
   private lateinit var myView: View
 
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsRenameDialog.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsRenameDialog.kt
index ff469f1..9fef0c5 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsRenameDialog.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsRenameDialog.kt
@@ -27,7 +27,7 @@
 import android.widget.ImeAwareEditText
 import androidx.appcompat.app.AlertDialog
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment
 import kotlin.coroutines.resume
 import kotlinx.coroutines.suspendCancellableCoroutine
@@ -78,7 +78,7 @@
           end: Int,
           dest: Spanned?,
           dstart: Int,
-          dend: Int
+          dend: Int,
         ): CharSequence? {
           for (index in start until end) {
             val c = source[index]
@@ -133,13 +133,13 @@
         val bundle = Bundle()
         bundle.putObject(
           KEY_FINGERPRINT,
-          android.hardware.fingerprint.Fingerprint(fp.name, fp.fingerId, fp.deviceId)
+          android.hardware.fingerprint.Fingerprint(fp.name, fp.fingerId, fp.deviceId),
         )
         dialog.arguments = bundle
         Log.d(TAG, "showing dialog $dialog")
         dialog.show(
           target.parentFragmentManager,
-          FingerprintSettingsRenameDialog::class.java.toString()
+          FingerprintSettingsRenameDialog::class.java.toString(),
         )
       }
   }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsV2Fragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsV2Fragment.kt
index c22a5a7..05bb329 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsV2Fragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/fragment/FingerprintSettingsV2Fragment.kt
@@ -45,11 +45,12 @@
 import com.android.settings.biometrics.GatekeeperPasswordProvider
 import com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling
 import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroductionInternal
+import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepoImpl
+import com.android.settings.biometrics.fingerprint2.data.repository.PressToAuthRepoImpl
 import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
-import com.android.settings.biometrics.fingerprint2.repository.PressToAuthProviderImpl
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptModel
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
-import com.android.settings.biometrics.fingerprint2.shared.model.Settings
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.Settings
 import com.android.settings.biometrics.fingerprint2.ui.settings.binder.FingerprintSettingsViewBinder
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.FingerprintSettingsNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.FingerprintSettingsViewModel
@@ -128,12 +129,12 @@
           if (resultCode == BiometricEnrollBase.RESULT_TIMEOUT) {
             navigationViewModel.onEnrollFirstFailure(
               "Received RESULT_TIMEOUT when enrolling",
-              resultCode
+              resultCode,
             )
           } else {
             navigationViewModel.onEnrollFirstFailure(
               "Incorrect resultCode or data was null",
-              resultCode
+              resultCode,
             )
           }
         } else {
@@ -212,21 +213,24 @@
           context.contentResolver,
           Secure.SFPS_PERFORMANT_AUTH_ENABLED,
           toReturn,
-          userHandle
+          userHandle,
         )
       }
 
       toReturn == 1
     }
+    val fingerprintSensorProvider =
+      FingerprintSensorRepoImpl(fingerprintManager, backgroundDispatcher, lifecycleScope)
 
     val interactor =
       FingerprintManagerInteractorImpl(
         context.applicationContext,
         backgroundDispatcher,
         fingerprintManager,
+        fingerprintSensorProvider,
         GatekeeperPasswordProvider(LockPatternUtils(context.applicationContext)),
-        PressToAuthProviderImpl(context),
-        isAnySuw
+        PressToAuthRepoImpl(context),
+        Settings,
       )
 
     val token = intent.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN)
@@ -240,8 +244,8 @@
           interactor,
           backgroundDispatcher,
           token,
-          challenge
-        )
+          challenge,
+        ),
       )[FingerprintSettingsNavigationViewModel::class.java]
 
     settingsViewModel =
@@ -252,15 +256,10 @@
           interactor,
           backgroundDispatcher,
           navigationViewModel,
-        )
+        ),
       )[FingerprintSettingsViewModel::class.java]
 
-    FingerprintSettingsViewBinder.bind(
-      this,
-      settingsViewModel,
-      navigationViewModel,
-      lifecycleScope,
-    )
+    FingerprintSettingsViewBinder.bind(this, settingsViewModel, navigationViewModel, lifecycleScope)
   }
 
   override fun getMetricsCategory(): Int {
@@ -364,7 +363,7 @@
       RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
         activity,
         DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT,
-        requireActivity().userId
+        requireActivity().userId,
       )
     val activity = requireActivity()
     val helpIntent =
@@ -404,7 +403,7 @@
       column.title =
         getString(
           R.string.security_settings_fingerprint_enroll_introduction_v3_message,
-          DeviceHelper.getDeviceName(requireActivity())
+          DeviceHelper.getDeviceName(requireActivity()),
         )
       column.learnMoreOnClickListener = learnMoreClickListener
       column.learnMoreOverrideText =
@@ -437,13 +436,12 @@
       val willDelete =
         fingerprintPreferences()
           .first { it?.fingerprintViewModel == fingerprintViewModel }
-          ?.askUserToDeleteDialog()
-          ?: false
+          ?.askUserToDeleteDialog() ?: false
       if (willDelete) {
         mMetricsFeatureProvider.action(
           context,
           SettingsEnums.ACTION_FINGERPRINT_DELETE,
-          fingerprintViewModel.fingerId
+          fingerprintViewModel.fingerId,
         )
       }
       return willDelete
@@ -466,7 +464,7 @@
         mMetricsFeatureProvider.action(
           context,
           SettingsEnums.ACTION_FINGERPRINT_RENAME,
-          toReturn.first.fingerId
+          toReturn.first.fingerId,
         )
       }
       return toReturn
@@ -518,12 +516,12 @@
     val intent = Intent()
     intent.setClassName(
       SETTINGS_PACKAGE_NAME,
-      FingerprintEnrollIntroductionInternal::class.java.name
+      FingerprintEnrollIntroductionInternal::class.java.name,
     )
     intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true)
     intent.putExtra(
       SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE,
-      SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE
+      SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE,
     )
 
     intent.putExtra(Intent.EXTRA_USER_ID, userId)
@@ -546,7 +544,7 @@
     val intent = Intent()
     intent.setClassName(
       SETTINGS_PACKAGE_NAME,
-      FingerprintEnrollEnrolling::class.qualifiedName.toString()
+      FingerprintEnrollEnrolling::class.qualifiedName.toString(),
     )
     intent.putExtra(Intent.EXTRA_USER_ID, userId)
     intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, challengeToken)
@@ -568,8 +566,7 @@
 
     return category?.let { cat ->
       cat.childrenToList().map { it as FingerprintSettingsPreference? }
-    }
-      ?: emptyList()
+    } ?: emptyList()
   }
 
   private fun PreferenceCategory.childrenToList(): List<Preference> {
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/FingerprintSettingsNavigationViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/FingerprintSettingsNavigationViewModel.kt
index 22a25e1..00b91a8 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/FingerprintSettingsNavigationViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/FingerprintSettingsNavigationViewModel.kt
@@ -21,7 +21,7 @@
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
 import com.android.settings.biometrics.BiometricEnrollBase
-import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
@@ -32,11 +32,11 @@
 
 /** A Viewmodel that represents the navigation of the FingerprintSettings activity. */
 class FingerprintSettingsNavigationViewModel(
-    private val userId: Int,
-    private val fingerprintManagerInteractor: FingerprintManagerInteractor,
-    private val backgroundDispatcher: CoroutineDispatcher,
-    tokenInit: ByteArray?,
-    challengeInit: Long?,
+  private val userId: Int,
+  private val fingerprintManagerInteractor: FingerprintManagerInteractor,
+  private val backgroundDispatcher: CoroutineDispatcher,
+  tokenInit: ByteArray?,
+  challengeInit: Long?,
 ) : ViewModel() {
 
   private var token = tokenInit
@@ -173,17 +173,15 @@
   }
 
   class FingerprintSettingsNavigationModelFactory(
-      private val userId: Int,
-      private val interactor: FingerprintManagerInteractor,
-      private val backgroundDispatcher: CoroutineDispatcher,
-      private val token: ByteArray?,
-      private val challenge: Long?,
+    private val userId: Int,
+    private val interactor: FingerprintManagerInteractor,
+    private val backgroundDispatcher: CoroutineDispatcher,
+    private val token: ByteArray?,
+    private val challenge: Long?,
   ) : ViewModelProvider.Factory {
 
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
 
       return FingerprintSettingsNavigationViewModel(
         userId,
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/FingerprintSettingsViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/FingerprintSettingsViewModel.kt
index 164f79f..80bbb43 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/FingerprintSettingsViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/FingerprintSettingsViewModel.kt
@@ -21,9 +21,9 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
-import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptModel
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
@@ -66,7 +66,7 @@
       emit(
         Pair(
           fingerprintManagerInteractor.canEnrollFingerprints.first(),
-          fingerprintManagerInteractor.maxEnrollableFingerprints.first()
+          fingerprintManagerInteractor.maxEnrollableFingerprints.first(),
         )
       )
     }
@@ -120,7 +120,7 @@
         _isLockedOut,
         _attemptsSoFar,
         _fingerprintSensorType,
-        _sensorNullOrEmpty
+        _sensorNullOrEmpty,
       ) {
         dialogShowing,
         step,
@@ -140,7 +140,7 @@
               "lockedOut=${isLockedOut}," +
               "attempts=${attempts}," +
               "sensorType=${sensorType}" +
-              "sensorNullOrEmpty=${sensorNullOrEmpty}"
+              "sensorNullOrEmpty=${sensorNullOrEmpty}",
           )
         }
         if (sensorNullOrEmpty) {
@@ -294,9 +294,7 @@
   ) : ViewModelProvider.Factory {
 
     @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(
-      modelClass: Class<T>,
-    ): T {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T {
 
       return FingerprintSettingsViewModel(
         userId,
@@ -318,7 +316,7 @@
   flow6: Flow<T6>,
   flow7: Flow<T7>,
   flow8: Flow<T8>,
-  crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R
+  crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R,
 ): Flow<R> {
   return combine(flow, flow2, flow3, flow4, flow5, flow6, flow7, flow8) { args: Array<*> ->
     @Suppress("UNCHECKED_CAST")
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/NextStepViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/NextStepViewModel.kt
index d9155b6..3acedb1 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/NextStepViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/NextStepViewModel.kt
@@ -29,10 +29,8 @@
   val challengeToken: ByteArray?,
 ) : NextStepViewModel()
 
-data class EnrollAdditionalFingerprint(
-  val userId: Int,
-  val challengeToken: ByteArray?,
-) : NextStepViewModel()
+data class EnrollAdditionalFingerprint(val userId: Int, val challengeToken: ByteArray?) :
+  NextStepViewModel()
 
 data class FinishSettings(val reason: String) : NextStepViewModel()
 
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/PreferenceViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/PreferenceViewModel.kt
index 181da4e..2a1d9c6 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/PreferenceViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/settings/viewmodel/PreferenceViewModel.kt
@@ -16,15 +16,11 @@
 
 package com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel
 
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 
 /** Classed use to represent a Dialogs state. */
 sealed class PreferenceViewModel {
-  data class RenameDialog(
-      val fingerprintViewModel: FingerprintData,
-  ) : PreferenceViewModel()
+  data class RenameDialog(val fingerprintViewModel: FingerprintData) : PreferenceViewModel()
 
-  data class DeleteDialog(
-      val fingerprintViewModel: FingerprintData,
-  ) : PreferenceViewModel()
+  data class DeleteDialog(val fingerprintViewModel: FingerprintData) : PreferenceViewModel()
 }
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint2/fragment/FingerprintEnrollIntroFragmentTest.kt b/tests/robotests/src/com/android/settings/biometrics/fingerprint2/fragment/FingerprintEnrollIntroFragmentTest.kt
index 024f346..cea72aa 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint2/fragment/FingerprintEnrollIntroFragmentTest.kt
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint2/fragment/FingerprintEnrollIntroFragmentTest.kt
@@ -33,16 +33,20 @@
 import androidx.test.espresso.matcher.ViewMatchers.withText
 import androidx.test.runner.AndroidJUnit4
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.Default
+import com.android.settings.biometrics.fingerprint2.lib.model.Default
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Introduction
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.NavigationState
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollIntroV2Fragment
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollIntroViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintFlowViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Intro
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.NavState
 import com.android.settings.testutils2.FakeFingerprintManagerInteractor
+import com.android.systemui.biometrics.shared.model.FingerprintSensor
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
 import com.google.android.setupdesign.GlifLayout
 import com.google.android.setupdesign.template.RequireScrollMixin
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -62,18 +66,27 @@
     )
   private val backgroundDispatcher = StandardTestDispatcher()
   private lateinit var fragmentScenario: FragmentScenario<FingerprintEnrollIntroV2Fragment>
+  private val fingerprintSensor =
+    FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
+
+  var enrollFlow = Default
+  val flowViewModel = FingerprintFlowViewModel(enrollFlow)
 
   private val navigationViewModel =
-    FingerprintEnrollNavigationViewModel(
-      backgroundDispatcher,
-      interactor,
-      gatekeeperViewModel,
-      Intro,
-      NavState(true),
-      Default,
+    FingerprintNavigationViewModel(
+      Introduction,
+      false,
+      flowViewModel,
+      interactor
     )
+
   private var fingerprintViewModel =
-    FingerprintEnrollViewModel(interactor, gatekeeperViewModel, navigationViewModel)
+    FingerprintEnrollIntroViewModel(
+      navigationViewModel,
+      flowViewModel,
+      interactor,
+    )
+
   private var fingerprintScrollViewModel = FingerprintScrollViewModel()
 
   @Before
@@ -85,9 +98,9 @@
           modelClass: Class<T>,
         ): T {
           return when (modelClass) {
-            FingerprintEnrollViewModel::class.java -> fingerprintViewModel
+            FingerprintEnrollIntroViewModel::class.java -> fingerprintViewModel
             FingerprintScrollViewModel::class.java -> fingerprintScrollViewModel
-            FingerprintEnrollNavigationViewModel::class.java -> navigationViewModel
+            FingerprintNavigationViewModel::class.java -> navigationViewModel
             FingerprintGatekeeperViewModel::class.java -> gatekeeperViewModel
             else -> null
           }
diff --git a/tests/screenshot/src/com/android/settings/tests/screenshot/BasicScreenshotTest.kt b/tests/screenshot/src/com/android/settings/tests/screenshot/BasicScreenshotTest.kt
index bf28b54..493a669 100644
--- a/tests/screenshot/src/com/android/settings/tests/screenshot/BasicScreenshotTest.kt
+++ b/tests/screenshot/src/com/android/settings/tests/screenshot/BasicScreenshotTest.kt
@@ -30,16 +30,19 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.settings.R
-import com.android.settings.biometrics.fingerprint2.shared.model.Default
+import com.android.settings.biometrics.fingerprint2.lib.model.Default
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollIntroV2Fragment
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollIntroViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintFlowViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.NavState
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Start
 import com.android.settings.testutils2.FakeFingerprintManagerInteractor
+import com.android.systemui.biometrics.shared.model.FingerprintSensor
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
 import kotlinx.coroutines.test.StandardTestDispatcher
 import org.junit.Before
 import org.junit.Rule
@@ -60,7 +63,7 @@
         InstrumentationRegistry.getInstrumentation()
           .getTargetContext()
           .getFilesDir()
-          .getAbsolutePath() + "/settings_screenshots"
+          .getAbsolutePath() + "/settings_screenshots",
       )
     )
 
@@ -70,24 +73,27 @@
   private val gatekeeperViewModel =
     FingerprintGatekeeperViewModel(
       GatekeeperInfo.GatekeeperPasswordInfo(byteArrayOf(1, 2, 3), 100L),
-      interactor
+      interactor,
     )
 
   private val backgroundDispatcher = StandardTestDispatcher()
   private lateinit var fragmentScenario: FragmentScenario<FingerprintEnrollIntroV2Fragment>
-  val navState = NavState(true)
+  private val fingerprintSensor =
+    FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
 
-  private val navigationViewModel = FingerprintEnrollNavigationViewModel(
-      backgroundDispatcher,
+  var enrollFlow = Default
+  val flowViewModel = FingerprintFlowViewModel(enrollFlow)
+
+  private val navigationViewModel =
+    FingerprintNavigationViewModel(
+      FingerprintNavigationStep.Introduction,
+      false,
+      flowViewModel,
       interactor,
-      gatekeeperViewModel,
-      Start.next(navState),
-      navState,
-      Default,
     )
-  private var fingerprintViewModel = FingerprintEnrollViewModel(
-      interactor, gatekeeperViewModel, navigationViewModel,
-    )
+
+  private var fingerprintViewModel =
+    FingerprintEnrollIntroViewModel(navigationViewModel, flowViewModel, interactor)
   private var fingerprintScrollViewModel = FingerprintScrollViewModel()
 
   @Before
@@ -95,13 +101,11 @@
     val factory =
       object : ViewModelProvider.Factory {
         @Suppress("UNCHECKED_CAST")
-        override fun <T : ViewModel> create(
-          modelClass: Class<T>,
-        ): T {
+        override fun <T : ViewModel> create(modelClass: Class<T>): T {
           return when (modelClass) {
-            FingerprintEnrollViewModel::class.java -> fingerprintViewModel
+            FingerprintEnrollIntroViewModel::class.java -> fingerprintViewModel
             FingerprintScrollViewModel::class.java -> fingerprintScrollViewModel
-            FingerprintEnrollNavigationViewModel::class.java -> navigationViewModel
+            FingerprintNavigationViewModel::class.java -> navigationViewModel
             FingerprintGatekeeperViewModel::class.java -> gatekeeperViewModel
             else -> null
           }
@@ -118,11 +122,7 @@
   /** Renders a [view] into a [Bitmap]. */
   private fun viewToBitmap(view: View): Bitmap {
     val bitmap =
-      Bitmap.createBitmap(
-        view.measuredWidth,
-        view.measuredHeight,
-        Bitmap.Config.ARGB_8888,
-      )
+      Bitmap.createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888)
     val canvas = Canvas(bitmap)
     view.draw(canvas)
     return bitmap
@@ -136,12 +136,7 @@
     }
     fragmentScenario.onFragment { fragment ->
       val view = fragment.requireView().findViewById<View>(R.id.enroll_intro_content_view)!!
-      rule.assertBitmapAgainstGolden(
-        viewToBitmap(view),
-        "fp_enroll_intro",
-        MSSIMMatcher()
-      )
+      rule.assertBitmapAgainstGolden(viewToBitmap(view), "fp_enroll_intro", MSSIMMatcher())
     }
-
   }
 }
diff --git a/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt b/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
index dd8658c..7991ff1 100644
--- a/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
+++ b/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
@@ -16,11 +16,11 @@
 
 package com.android.settings.testutils2
 
-import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
-import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptModel
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.systemui.biometrics.shared.model.FingerprintSensor
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import com.android.systemui.biometrics.shared.model.SensorStrength
diff --git a/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FingerprintManagerInteractorTest.kt b/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FingerprintManagerInteractorTest.kt
index 3440d2a..f1808e3 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FingerprintManagerInteractorTest.kt
+++ b/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FingerprintManagerInteractorTest.kt
@@ -26,17 +26,23 @@
 import android.os.Handler
 import androidx.test.core.app.ApplicationProvider
 import com.android.settings.biometrics.GatekeeperPasswordProvider
+import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepo
 import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
-import com.android.settings.biometrics.fingerprint2.shared.data.repository.PressToAuthProvider
-import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
-import com.android.settings.biometrics.fingerprint2.shared.model.Default
-import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollState
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptModel
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.data.repository.PressToAuthRepo
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.model.Default
+import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.settings.password.ChooseLockSettingsHelper
+import com.android.systemui.biometrics.shared.model.FingerprintSensor
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.cancelAndJoin
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.last
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -71,21 +77,28 @@
   @Mock private lateinit var gateKeeperPasswordProvider: GatekeeperPasswordProvider
 
   private var testScope = TestScope(backgroundDispatcher)
-  private var pressToAuthProvider =
-    object : PressToAuthProvider {
+  private var pressToAuthRepo =
+    object : PressToAuthRepo {
       override val isEnabled: Boolean
         get() = false
     }
 
   @Before
   fun setup() {
+    val sensor = FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
+    val fingerprintSensorRepo =
+      object : FingerprintSensorRepo {
+        override val fingerprintSensor: Flow<FingerprintSensor> = flowOf(sensor)
+      }
+
     underTest =
       FingerprintManagerInteractorImpl(
         context,
         backgroundDispatcher,
         fingerprintManager,
+        fingerprintSensorRepo,
         gateKeeperPasswordProvider,
-        pressToAuthProvider,
+        pressToAuthRepo,
         Default,
       )
   }
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 bd94cba..3b02d49 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
@@ -21,16 +21,17 @@
 import android.view.accessibility.AccessibilityManager
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
 import androidx.test.core.app.ApplicationProvider
-import com.android.settings.biometrics.fingerprint2.shared.model.Default
+import com.android.settings.biometrics.fingerprint2.lib.model.Default
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.AccessibilityViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Education
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintFlowViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Education
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FoldStateViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.NextStepViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.NavigationState
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.OrientationStateViewModel
 import com.android.settings.testutils2.FakeFingerprintManagerInteractor
 import com.android.systemui.biometrics.shared.model.FingerprintSensor
@@ -38,7 +39,6 @@
 import com.android.systemui.biometrics.shared.model.SensorStrength
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
@@ -67,7 +67,7 @@
   private lateinit var fakeFingerprintManagerInteractor: FakeFingerprintManagerInteractor
   private lateinit var gatekeeperViewModel: FingerprintGatekeeperViewModel
   private lateinit var enrollViewModel: FingerprintEnrollViewModel
-  private lateinit var navigationViewModel: FingerprintEnrollNavigationViewModel
+  private lateinit var navigationViewModel: FingerprintNavigationViewModel
   private lateinit var accessibilityViewModel: AccessibilityViewModel
   private lateinit var foldStateViewModel: FoldStateViewModel
   private lateinit var orientationStateViewModel: OrientationStateViewModel
@@ -87,18 +87,19 @@
     gatekeeperViewModel =
       FingerprintGatekeeperViewModel.FingerprintGatekeeperViewModelFactory(
           null,
-          fakeFingerprintManagerInteractor
+          fakeFingerprintManagerInteractor,
         )
         .create(FingerprintGatekeeperViewModel::class.java)
+
+    val sensor = FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
+    val fingerprintFlowViewModel = FingerprintFlowViewModel(Default)
     navigationViewModel =
-      FingerprintEnrollNavigationViewModel.FingerprintEnrollNavigationViewModelFactory(
-          backgroundDispatcher,
-          fakeFingerprintManagerInteractor,
-          gatekeeperViewModel,
-          canSkipConfirm = true,
-          Default,
-        )
-        .create(FingerprintEnrollNavigationViewModel::class.java)
+      FingerprintNavigationViewModel(
+        Education(sensor),
+        false,
+        fingerprintFlowViewModel,
+        fakeFingerprintManagerInteractor,
+      )
 
     backgroundViewModel =
       BackgroundViewModel.BackgroundViewModelFactory().create(BackgroundViewModel::class.java)
@@ -126,12 +127,10 @@
           backgroundViewModel,
           accessibilityViewModel,
           foldStateViewModel,
-          orientationStateViewModel
+          orientationStateViewModel,
+          fingerprintFlowViewModel,
         )
         .create(FingerprintEnrollFindSensorViewModel::class.java)
-
-    // Navigate to Education page
-    navigationViewModel.nextStep()
   }
 
   @After
@@ -142,18 +141,6 @@
   // TODO(b/305094585): test enroll() logic
 
   @Test
-  fun currentStepIsEducation() =
-    testScope.runTest {
-      var step: NextStepViewModel? = null
-      val job = launch {
-        navigationViewModel.navigationViewModel.collectLatest { step = it.currStep }
-      }
-      advanceUntilIdle()
-      assertThat(step).isEqualTo(Education)
-      job.cancel()
-    }
-
-  @Test
   fun udfpsLottieInfo() =
     testScope.runTest {
       fakeFingerprintManagerInteractor.sensorProp =
@@ -161,7 +148,7 @@
           0 /* sensorId */,
           SensorStrength.STRONG,
           5,
-          FingerprintSensorType.UDFPS_OPTICAL
+          FingerprintSensorType.UDFPS_OPTICAL,
         )
 
       var udfpsLottieInfo: Boolean? = null
@@ -234,7 +221,7 @@
           0 /* sensorId */,
           SensorStrength.STRONG,
           5,
-          FingerprintSensorType.UDFPS_OPTICAL
+          FingerprintSensorType.UDFPS_OPTICAL,
         )
 
       var showPrimaryButton: Boolean? = null
diff --git a/tests/unit/src/com/android/settings/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollEnrollingViewModelTest.kt b/tests/unit/src/com/android/settings/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollEnrollingViewModelTest.kt
index efb4a07..4678da1 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollEnrollingViewModelTest.kt
+++ b/tests/unit/src/com/android/settings/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollEnrollingViewModelTest.kt
@@ -17,16 +17,20 @@
 package com.android.settings.fingerprint2.ui.enrollment.viewmodel
 
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.android.settings.biometrics.fingerprint2.shared.model.Default
+import com.android.settings.biometrics.fingerprint2.lib.model.Default
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Enrollment
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollEnrollingViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintFlowViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Enrollment
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.NavState
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.NavigationState
 import com.android.settings.testutils2.FakeFingerprintManagerInteractor
+import com.android.systemui.biometrics.shared.model.FingerprintSensor
+import com.android.systemui.biometrics.shared.model.FingerprintSensorType
+import com.android.systemui.biometrics.shared.model.SensorStrength
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -54,7 +58,7 @@
   private lateinit var enrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel
   private lateinit var backgroundViewModel: BackgroundViewModel
   private lateinit var gateKeeperViewModel: FingerprintGatekeeperViewModel
-  private lateinit var navigationViewModel: FingerprintEnrollNavigationViewModel
+  private lateinit var navigationViewModel: FingerprintNavigationViewModel
   private val defaultGatekeeperInfo = GatekeeperInfo.GatekeeperPasswordInfo(byteArrayOf(1, 3), 3)
   private var testScope = TestScope(backgroundDispatcher)
 
@@ -65,18 +69,18 @@
     gateKeeperViewModel =
       FingerprintGatekeeperViewModel.FingerprintGatekeeperViewModelFactory(
           gatekeeperInfo,
-          fakeFingerprintManagerInteractor
+          fakeFingerprintManagerInteractor,
         )
         .create(FingerprintGatekeeperViewModel::class.java)
+    val sensor = FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
+    val fingerprintFlowViewModel = FingerprintFlowViewModel(Default)
 
     navigationViewModel =
-      FingerprintEnrollNavigationViewModel(
-        backgroundDispatcher,
+      FingerprintNavigationViewModel(
+        Enrollment(sensor),
+        false,
+        fingerprintFlowViewModel,
         fakeFingerprintManagerInteractor,
-        gateKeeperViewModel,
-        Enrollment,
-        NavState(true),
-        Default,
       )
 
     backgroundViewModel =
diff --git a/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsNavigationViewModelTest.kt b/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsNavigationViewModelTest.kt
index 064e087..201fffa 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsNavigationViewModelTest.kt
+++ b/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsNavigationViewModelTest.kt
@@ -18,7 +18,7 @@
 
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
 import com.android.settings.biometrics.BiometricEnrollBase
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.EnrollFirstFingerprint
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.FingerprintSettingsNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.FinishSettings
diff --git a/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsViewModelTest.kt b/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsViewModelTest.kt
index 4bd9121..6577c95 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsViewModelTest.kt
+++ b/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsViewModelTest.kt
@@ -17,8 +17,8 @@
 package com.android.settings.fingerprint2.ui.settings
 
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptModel
-import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintData
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
+import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.FingerprintSettingsNavigationViewModel
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.FingerprintSettingsViewModel
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.PreferenceViewModel