Moved FakeFingerprintManagerInteractor

Test: atest
Bug: 295206367
Change-Id: If9f3b9dc88260c0725f70d3444c4f9a4b6ee5c2f
diff --git a/Android.bp b/Android.bp
index 0271b2f..a62aa11 100644
--- a/Android.bp
+++ b/Android.bp
@@ -55,6 +55,9 @@
     ],
 
     srcs: ["src/**/*.java", "src/**/*.kt"],
+    exclude_srcs: [
+        "src/com/android/settings/biometrics/fingerprint2/shared/**/*.kt",
+    ],
     use_resource_processor: true,
     resource_dirs: [
         "res",
@@ -113,6 +116,7 @@
         "SystemUIUnfoldLib",
         "aconfig_settings_flags_lib",
         "android.content.pm.flags-aconfig-java",
+        "FingerprintManagerInteractor",
     ],
 
     plugins: [
diff --git a/src/com/android/settings/biometrics/fingerprint2/conversion/Util.kt b/src/com/android/settings/biometrics/fingerprint2/conversion/Util.kt
new file mode 100644
index 0000000..b2767c3
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/conversion/Util.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.conversion
+
+import android.hardware.fingerprint.FingerprintManager
+import android.hardware.fingerprint.FingerprintSensorProperties
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintSensorPropertyViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorStrength
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorType
+
+class Util {
+  companion object {
+    fun sensorPropsToViewModel(
+      props: FingerprintSensorPropertiesInternal
+    ): FingerprintSensorPropertyViewModel {
+      val sensorStrength: SensorStrength =
+        when (props.sensorStrength) {
+          FingerprintSensorProperties.STRENGTH_CONVENIENCE -> SensorStrength.Convenient
+          FingerprintSensorProperties.STRENGTH_WEAK -> SensorStrength.Weak
+          FingerprintSensorProperties.STRENGTH_STRONG -> SensorStrength.Strong
+          else -> SensorStrength.Unknown
+        }
+      val sensorType: SensorType =
+        when (props.sensorType) {
+          FingerprintSensorProperties.TYPE_UDFPS_OPTICAL -> SensorType.Optical
+          FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC -> SensorType.Ultrasonic
+          FingerprintSensorProperties.TYPE_REAR -> SensorType.RFPS
+          FingerprintSensorProperties.TYPE_POWER_BUTTON -> SensorType.SFPS
+          else -> SensorType.Unknown
+        }
+      return FingerprintSensorPropertyViewModel(
+        props.sensorId,
+        sensorStrength,
+        props.maxEnrollmentsPerUser,
+        sensorType
+      )
+    }
+  }
+
+}
+fun EnrollReason.toOriginalReason(): Int {
+  return when (this) {
+    EnrollReason.EnrollEnrolling -> FingerprintManager.ENROLL_ENROLL
+    EnrollReason.FindSensor -> FingerprintManager.ENROLL_FIND_SENSOR
+  }
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt
similarity index 75%
rename from src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractor.kt
rename to src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt
index 2c8ee8f..41da247 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt
@@ -21,15 +21,16 @@
 import android.hardware.fingerprint.FingerprintManager
 import android.hardware.fingerprint.FingerprintManager.GenerateChallengeCallback
 import android.hardware.fingerprint.FingerprintManager.RemovalCallback
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
 import android.os.CancellationSignal
 import android.util.Log
 import com.android.settings.biometrics.GatekeeperPasswordProvider
+import com.android.settings.biometrics.fingerprint2.conversion.Util
+import com.android.settings.biometrics.fingerprint2.conversion.toOriginalReason
+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.FingerprintAuthAttemptViewModel
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.EnrollReason
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerEnrollStateViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.toOriginalReason
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollStateViewModel
 import com.android.settings.password.ChooseLockSettingsHelper
 import kotlin.coroutines.resume
 import kotlin.coroutines.suspendCoroutine
@@ -45,59 +46,6 @@
 
 private const val TAG = "FingerprintManagerInteractor"
 
-/** Encapsulates business logic related to managing fingerprints. */
-interface FingerprintManagerInteractor {
-  /** Returns the list of current fingerprints. */
-  val enrolledFingerprints: Flow<List<FingerprintViewModel>>
-
-  /** Returns the max enrollable fingerprints, note during SUW this might be 1 */
-  val maxEnrollableFingerprints: Flow<Int>
-
-  /** Returns true if a user can enroll a fingerprint false otherwise. */
-  val canEnrollFingerprints: Flow<Boolean>
-
-  /** Retrieves the sensor properties of a device */
-  val sensorPropertiesInternal: Flow<FingerprintSensorPropertiesInternal?>
-
-  /** Runs [FingerprintManager.authenticate] */
-  suspend fun authenticate(): FingerprintAuthAttemptViewModel
-
-  /**
-   * Generates a challenge with the provided [gateKeeperPasswordHandle] and on success returns a
-   * challenge and challenge token. This info can be used for secure operations such as
-   * [FingerprintManager.enroll]
-   *
-   * @param gateKeeperPasswordHandle GateKeeper password handle generated by a Confirm
-   * @return A [Pair] of the challenge and challenge token
-   */
-  suspend fun generateChallenge(gateKeeperPasswordHandle: Long): Pair<Long, ByteArray>
-
-  /**
-   * Runs [FingerprintManager.enroll] with the [hardwareAuthToken] and [EnrollReason] for this
-   * enrollment. Returning the [FingerEnrollStateViewModel] that represents this fingerprint
-   * enrollment state.
-   */
-  suspend fun enroll(
-    hardwareAuthToken: ByteArray?,
-    enrollReason: EnrollReason,
-  ): Flow<FingerEnrollStateViewModel>
-
-  /**
-   * Removes the given fingerprint, returning true if it was successfully removed and false
-   * otherwise
-   */
-  suspend fun removeFingerprint(fp: FingerprintViewModel): Boolean
-
-  /** Renames the given fingerprint if one exists */
-  suspend fun renameFingerprint(fp: FingerprintViewModel, newName: String)
-
-  /** Indicates if the device has side fingerprint */
-  suspend fun hasSideFps(): Boolean
-
-  /** Indicates if the press to auth feature has been enabled */
-  suspend fun pressToAuthEnabled(): Boolean
-}
-
 class FingerprintManagerInteractorImpl(
   applicationContext: Context,
   private val backgroundDispatcher: CoroutineDispatcher,
@@ -144,7 +92,10 @@
 
   override val sensorPropertiesInternal = flow {
     val sensorPropertiesInternal = fingerprintManager.sensorPropertiesInternal
-    emit(if (sensorPropertiesInternal.isEmpty()) null else sensorPropertiesInternal.first())
+    emit(
+      if (sensorPropertiesInternal.isEmpty()) null
+      else Util.sensorPropsToViewModel(sensorPropertiesInternal.first())
+    )
   }
 
   override val maxEnrollableFingerprints = flow { emit(maxFingerprints) }
@@ -183,7 +134,7 @@
       cancellationSignal,
       applicationContext.userId,
       enrollmentCallback,
-      enrollReason.toOriginalReason()
+      enrollReason.toOriginalReason(),
     )
     awaitClose {
       // If the stream has not been ended, and the user has stopped collecting the flow
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/Android.bp b/src/com/android/settings/biometrics/fingerprint2/shared/Android.bp
new file mode 100644
index 0000000..8873fd8
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/shared/Android.bp
@@ -0,0 +1,13 @@
+// This  library is mainly used for fakes which will be shared across are various types of tests
+// unit/robo/screenshot etc.
+//
+// This library shouldn't have many dependencies.
+android_library {
+    name: "FingerprintManagerInteractor",
+    srcs: [
+      "**/*.kt"
+    ],
+    static_libs: [
+      "kotlinx-coroutines-android",
+    ],
+}
\ No newline at end of file
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/AndroidManifest.xml b/src/com/android/settings/biometrics/fingerprint2/shared/AndroidManifest.xml
new file mode 100644
index 0000000..e2c97fc
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/shared/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<!--
+  ~ 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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.settings.biometrics.fingerprint2.shared">
+</manifest>
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/domain/interactor/FingerprintManagerInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/shared/domain/interactor/FingerprintManagerInteractor.kt
new file mode 100644
index 0000000..5353bb2
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/shared/domain/interactor/FingerprintManagerInteractor.kt
@@ -0,0 +1,82 @@
+/*
+ * 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.domain.interactor
+
+import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintSensorPropertyViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollStateViewModel
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Interface to obtain the necessary data for FingerprintEnrollment/Settings
+ *
+ * Note that this interface should not have dependencies on heavyweight libraries such as the
+ * framework, hidl/aidl, etc. This makes it much easier to test and create fakes for.
+ */
+interface FingerprintManagerInteractor {
+  /** Returns the list of current fingerprints. */
+  val enrolledFingerprints: Flow<List<FingerprintViewModel>>
+
+  /** Returns the max enrollable fingerprints, note during SUW this might be 1 */
+  val maxEnrollableFingerprints: Flow<Int>
+
+  /** Returns true if a user can enroll a fingerprint false otherwise. */
+  val canEnrollFingerprints: Flow<Boolean>
+
+  /** Retrieves the sensor properties of a device */
+  val sensorPropertiesInternal: Flow<FingerprintSensorPropertyViewModel?>
+
+  /** Runs the authenticate flow */
+  suspend fun authenticate(): FingerprintAuthAttemptViewModel
+
+  /**
+   * Generates a challenge with the provided [gateKeeperPasswordHandle] and on success returns a
+   * challenge and challenge token. This info can be used for secure operations such as enrollment
+   *
+   * @param gateKeeperPasswordHandle GateKeeper password handle generated by a Confirm
+   * @return A [Pair] of the challenge and challenge token
+   */
+  suspend fun generateChallenge(gateKeeperPasswordHandle: Long): Pair<Long, ByteArray>
+
+  /**
+   * Runs [FingerprintManager.enroll] with the [hardwareAuthToken] and [EnrollReason] for this
+   * enrollment. Returning the [FingerEnrollStateViewModel] that represents this fingerprint
+   * enrollment state.
+   */
+  suspend fun enroll(
+    hardwareAuthToken: ByteArray?,
+    enrollReason: EnrollReason,
+  ): Flow<FingerEnrollStateViewModel>
+
+  /**
+   * Removes the given fingerprint, returning true if it was successfully removed and false
+   * otherwise
+   */
+  suspend fun removeFingerprint(fp: FingerprintViewModel): Boolean
+
+  /** Renames the given fingerprint if one exists */
+  suspend fun renameFingerprint(fp: FingerprintViewModel, newName: String)
+
+  /** Indicates if the device has side fingerprint */
+  suspend fun hasSideFps(): Boolean
+
+  /** 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/EnrollReasonViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/shared/model/EnrollReasonViewModel.kt
new file mode 100644
index 0000000..47a0af0
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/shared/model/EnrollReasonViewModel.kt
@@ -0,0 +1,28 @@
+/*
+ * 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
+
+/** The reason for enrollment */
+enum class EnrollReason {
+  /**
+   * The enroll happens on education screen. This is to support legacy flows where we require the
+   * user to touch the sensor before going ahead to the EnrollEnrolling flow
+   */
+  FindSensor,
+  /** The enroll happens on enrolling screen. */
+  EnrollEnrolling
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerEnrollStateViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerEnrollStateViewModel.kt
similarity index 94%
rename from src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerEnrollStateViewModel.kt
rename to src/com/android/settings/biometrics/fingerprint2/shared/model/FingerEnrollStateViewModel.kt
index 73343bd..179ac60 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerEnrollStateViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerEnrollStateViewModel.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel
+package com.android.settings.biometrics.fingerprint2.shared.model
 
 import android.annotation.StringRes
 
diff --git a/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintViewModel.kt
index db28e79..fc9539c 100644
--- a/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/shared/model/FingerprintViewModel.kt
@@ -32,3 +32,36 @@
     val message: String,
   ) : FingerprintAuthAttemptViewModel()
 }
+
+/** The various types of fingerprint sensors */
+sealed class SensorType {
+  /** Rear fingerprint sensor */
+  data object RFPS : SensorType()
+
+  /** Optical under display sensor */
+  data object Optical : SensorType()
+
+  /** Ultrasonic under display sensor */
+  data object Ultrasonic : SensorType()
+
+  /** Side fingerprint sensor */
+  data object SFPS : SensorType()
+
+  /** Unkonwn fingerprint sensor */
+  data object Unknown : SensorType()
+}
+
+/** The strength of a given sensor */
+sealed class SensorStrength {
+  data object Convenient : SensorStrength()
+  data object Weak : SensorStrength()
+  data object Strong : SensorStrength()
+  data object Unknown : SensorStrength()
+}
+
+data class FingerprintSensorPropertyViewModel(
+  val sensorId: Int,
+  val sensorStrength: SensorStrength,
+  val maxEnrollmentsPerUser: Int,
+  val sensorType: SensorType
+)
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 dcdcccf..e4ac00f 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
@@ -29,6 +29,7 @@
 import com.android.settings.R
 import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog
 import com.android.settings.biometrics.fingerprint.FingerprintFindSensorAnimation
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorType
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import com.google.android.setupcompat.template.FooterBarMixin
@@ -65,9 +66,9 @@
       viewModel.sensorType.collect {
         contentLayoutId =
           when (it) {
-            FingerprintSensorType.UDFPS_OPTICAL,
-            FingerprintSensorType.UDFPS_ULTRASONIC -> R.layout.udfps_enroll_find_sensor_layout
-            FingerprintSensorType.POWER_BUTTON -> R.layout.sfps_enroll_find_sensor_layout
+            SensorType.Optical,
+            SensorType.Ultrasonic -> R.layout.udfps_enroll_find_sensor_layout
+            SensorType.SFPS -> R.layout.sfps_enroll_find_sensor_layout
             else -> R.layout.fingerprint_v2_enroll_find_sensor
           }
       }
@@ -170,14 +171,14 @@
     illustrationLottie?.visibility = View.VISIBLE
   }
 
-  private fun setTexts(sensorType: FingerprintSensorType, view: GlifLayout) {
+  private fun setTexts(sensorType: SensorType, view: GlifLayout) {
     when (sensorType) {
-      FingerprintSensorType.UDFPS_OPTICAL,
-      FingerprintSensorType.UDFPS_ULTRASONIC -> {
+      SensorType.Optical,
+      SensorType.Ultrasonic -> {
         view.setHeaderText(R.string.security_settings_udfps_enroll_find_sensor_title)
         view.setDescriptionText(R.string.security_settings_udfps_enroll_find_sensor_message)
       }
-      FingerprintSensorType.POWER_BUTTON -> {
+      SensorType.SFPS -> {
         view.setHeaderText(R.string.security_settings_sfps_enroll_find_sensor_title)
         view.setDescriptionText(R.string.security_settings_sfps_enroll_find_sensor_message)
       }
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 dbf6d12..2ebc5d5 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
@@ -35,10 +35,10 @@
 import com.android.settings.R
 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.shared.model.SensorType
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
 import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Unicorn
-import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import com.google.android.setupcompat.template.FooterBarMixin
 import com.google.android.setupcompat.template.FooterButton
 import com.google.android.setupdesign.GlifLayout
@@ -144,8 +144,8 @@
             val iconShield: ImageView = view.requireViewById(R.id.icon_shield)
             val footerMessage6: TextView = view.requireViewById(R.id.footer_message_6)
             when (sensorType) {
-              FingerprintSensorType.UDFPS_ULTRASONIC,
-              FingerprintSensorType.UDFPS_OPTICAL -> {
+              SensorType.Ultrasonic,
+              SensorType.Optical -> {
                 footerMessage6.visibility = View.VISIBLE
                 iconShield.visibility = View.VISIBLE
               }
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/EnrollReason.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/EnrollReason.kt
deleted file mode 100644
index 87deeb3..0000000
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/EnrollReason.kt
+++ /dev/null
@@ -1,36 +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.hardware.fingerprint.FingerprintManager
-
-/**
- * The reason for enrollment. Represents [FingerprintManager.EnrollReason]
- */
-enum class EnrollReason {
-  /** The enroll happens on education screen. */
-  FindSensor,
-  /** The enroll happens on enrolling screen. */
-  EnrollEnrolling
-}
-
-/** Convert EnrollReason to original [FingerprintManager.EnrollReason]. */
-fun EnrollReason.toOriginalReason(): Int {
-  return when (this) {
-    EnrollReason.EnrollEnrolling -> FingerprintManager.ENROLL_ENROLL
-    EnrollReason.FindSensor -> FingerprintManager.ENROLL_FIND_SENSOR
-  }
-}
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 dbf6b33..c877d67 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
@@ -20,6 +20,9 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
+import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollStateViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorType
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -42,13 +45,13 @@
   orientationStateViewModel: OrientationStateViewModel
 ) : ViewModel() {
   /** Represents the stream of sensor type. */
-  val sensorType: Flow<FingerprintSensorType> =
+  val sensorType: Flow<SensorType> =
     fingerprintEnrollViewModel.sensorType.filterWhenEducationIsShown()
   private val _isUdfps: Flow<Boolean> =
     sensorType.map {
-      it == FingerprintSensorType.UDFPS_OPTICAL || it == FingerprintSensorType.UDFPS_ULTRASONIC
+      it == SensorType.Optical || it == SensorType.Ultrasonic
     }
-  private val _isSfps: Flow<Boolean> = sensorType.map { it == FingerprintSensorType.POWER_BUTTON }
+  private val _isSfps: Flow<Boolean> = sensorType.map { it == SensorType.RFPS }
   private val _isRearSfps: Flow<Boolean> =
     combineTransform(_isSfps, _isUdfps) { v1, v2 -> !v1 && !v2 }
 
@@ -92,8 +95,8 @@
         ) { sensorType, hasValidGatekeeperInfo, gatekeeperInfo, navigationViewModel ->
           val shouldStartEnroll =
             navigationViewModel.currStep == Education &&
-              sensorType != FingerprintSensorType.UDFPS_OPTICAL &&
-              sensorType != FingerprintSensorType.UDFPS_ULTRASONIC &&
+              sensorType != SensorType.Optical &&
+              sensorType != SensorType.Ultrasonic &&
               hasValidGatekeeperInfo
           if (shouldStartEnroll) (gatekeeperInfo as GatekeeperInfo.GatekeeperPasswordInfo).token
           else null
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 cb1beb9..b2c51db 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
@@ -17,13 +17,14 @@
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
-import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractor
+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.FingerEnrollStateViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorType
 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
-import com.android.systemui.biometrics.shared.model.toSensorType
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.flowOn
@@ -39,17 +40,15 @@
   backgroundDispatcher: CoroutineDispatcher,
 ) : ViewModel() {
 
-  /** Represents the stream of [FingerprintSensorType] */
-  val sensorType: Flow<FingerprintSensorType> =
-    fingerprintManagerInteractor.sensorPropertiesInternal.filterNotNull().map {
-      it.sensorType.toSensorType()
-    }
-
   private var _enrollReason: MutableStateFlow<EnrollReason> =
     MutableStateFlow(EnrollReason.FindSensor)
   private var _hardwareAuthToken: MutableStateFlow<ByteArray?> = MutableStateFlow(null)
   private var _consumerShouldEnroll: MutableStateFlow<Boolean> = MutableStateFlow(false)
 
+  /** Represents the stream of [FingerprintSensorType] */
+  val sensorType: Flow<SensorType> =
+    fingerprintManagerInteractor.sensorPropertiesInternal.filterNotNull().map { it.sensorType }
+
   /**
    * A flow that contains a [FingerprintEnrollViewModel] which contains the relevant information for
    * an enrollment process
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
index dafe545..d2bb321 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrolllNavigationViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrolllNavigationViewModel.kt
@@ -20,7 +20,7 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
-import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -39,7 +39,7 @@
 /**
  * The [EnrollType] for fingerprint enrollment indicates information on how the flow should behave.
  */
-sealed class EnrollType()
+sealed class EnrollType
 
 /** The default enrollment experience, typically called from Settings */
 object Default : EnrollType()
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 fa4463a..db93d02 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.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
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 d79d9c0..989d4d3 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
@@ -27,6 +27,7 @@
 class FingerprintScrollViewModel : ViewModel() {
 
   private val _hasReadConsentScreen: MutableStateFlow<Boolean> = MutableStateFlow(false)
+
   /** Indicates if a user has consented to FingerprintEnrollment */
   val hasReadConsentScreen: Flow<Boolean> = _hasReadConsentScreen.asStateFlow()
 
@@ -35,7 +36,7 @@
     _hasReadConsentScreen.update { true }
   }
 
-  class FingerprintScrollViewModelFactory() : ViewModelProvider.Factory {
+  class FingerprintScrollViewModelFactory : ViewModelProvider.Factory {
 
     @Suppress("UNCHECKED_CAST")
     override fun <T : ViewModel> create(
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 9f42d81..e66b4cd 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
@@ -34,7 +34,6 @@
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.ShowSettings
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.launch
@@ -55,7 +54,6 @@
       challenge: Long?,
       challengeToken: ByteArray?
     )
-
     /** Helper to launch an add fingerprint request */
     fun launchAddFingerprint(userId: Int, challengeToken: ByteArray?)
     /**
@@ -63,10 +61,8 @@
      * choose a PIN/PATTERN/PASS.
      */
     fun launchConfirmOrChooseLock(userId: Int)
-
     /** Used to indicate that FingerprintSettings is finished. */
     fun finish()
-
     /** Indicates what result should be set for the returning callee */
     fun setResultExternal(resultCode: Int)
     /** Indicates the settings UI should be shown */
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 84f33ff..9bde0b0 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
@@ -106,8 +106,9 @@
         val dialog = FingerprintSettingsRenameDialog()
         val onClick =
           DialogInterface.OnClickListener { _, _ ->
-            val dialogTextField = dialog.requireDialog()
-                .requireViewById(R.id.fingerprint_rename_field) as ImeAwareEditText
+            val dialogTextField =
+              dialog.requireDialog().requireViewById(R.id.fingerprint_rename_field)
+                as ImeAwareEditText
             val newName = dialogTextField.text.toString()
             if (!TextUtils.equals(newName, fp.name)) {
               Log.d(TAG, "rename $fp.name to $newName for $dialog")
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 538bb6d..22a25e1 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.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
@@ -32,17 +32,18 @@
 
 /** 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
   private var challenge = challengeInit
 
   private val _nextStep: MutableStateFlow<NextStepViewModel?> = MutableStateFlow(null)
+
   /** This flow represents the high level state for the FingerprintSettingsV2Fragment. */
   val nextStep: StateFlow<NextStepViewModel?> = _nextStep.asStateFlow()
 
@@ -118,8 +119,8 @@
       launchFinishSettings("Error, empty keyChallenge")
       return
     }
-    token = theToken!!
-    challenge = theChallenge!!
+    token = theToken
+    challenge = theChallenge
 
     showSettingsHelper()
   }
@@ -170,12 +171,13 @@
   private fun launchFinishSettings(reason: String, errorCode: Int) {
     _nextStep.update { FinishSettingsWithResult(errorCode, reason) }
   }
+
   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")
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 5770d09..d2691b4 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,11 +21,10 @@
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
-import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptViewModel
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintViewModel
-import com.android.systemui.biometrics.shared.model.FingerprintSensorType
-import com.android.systemui.biometrics.shared.model.toSensorType
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorType
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
@@ -90,10 +89,8 @@
 
   private val _consumerShouldAuthenticate: MutableStateFlow<Boolean> = MutableStateFlow(false)
 
-  private val _fingerprintSensorType: Flow<FingerprintSensorType> =
-    fingerprintManagerInteractor.sensorPropertiesInternal.filterNotNull().map {
-      it.sensorType.toSensorType()
-    }
+  private val _fingerprintSensorType: Flow<SensorType> =
+    fingerprintManagerInteractor.sensorPropertiesInternal.filterNotNull().map { it.sensorType }
 
   private val _sensorNullOrEmpty: Flow<Boolean> =
     fingerprintManagerInteractor.sensorPropertiesInternal.map { it == null }
@@ -149,10 +146,7 @@
         if (sensorNullOrEmpty) {
           return@combine false
         }
-        if (
-          listOf(FingerprintSensorType.UDFPS_ULTRASONIC, FingerprintSensorType.UDFPS_OPTICAL)
-            .contains(sensorType)
-        ) {
+        if (listOf(SensorType.Ultrasonic, SensorType.Optical).contains(sensorType)) {
           return@combine false
         }
 
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index 910bbbd..fbfd888 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -61,6 +61,7 @@
         "flag-junit",
         "aconfig_settings_flags_lib",
         "platform-test-annotations",
+        "Settings-testutils2",
     ],
 
     libs: [
diff --git a/tests/shared/Android.bp b/tests/shared/Android.bp
new file mode 100644
index 0000000..fca24b6
--- /dev/null
+++ b/tests/shared/Android.bp
@@ -0,0 +1,9 @@
+android_library {
+    name: "Settings-testutils2",
+    srcs: [
+        "src/**/*.kt"
+    ],
+    libs: [
+        "FingerprintManagerInteractor",
+    ],
+}
diff --git a/tests/shared/AndroidManifest.xml b/tests/shared/AndroidManifest.xml
new file mode 100644
index 0000000..7e1842c
--- /dev/null
+++ b/tests/shared/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2022 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.settings.testutils2">
+</manifest>
diff --git a/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FakeFingerprintManagerInteractor.kt b/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
similarity index 71%
rename from tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FakeFingerprintManagerInteractor.kt
rename to tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
index f807f70..05c3e3c 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/domain/interactor/FakeFingerprintManagerInteractor.kt
+++ b/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
@@ -14,18 +14,19 @@
  * limitations under the License.
  */
 
-package com.android.settings.fingerprint2.domain.interactor
+package com.android.settings.testutils2
 
-import android.hardware.biometrics.SensorProperties
-import android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
-import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintSensorPropertyViewModel
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.EnrollReason
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerEnrollStateViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollStateViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorStrength
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorType
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOf
 
 /** Fake to be used by other classes to easily fake the FingerprintManager implementation. */
 class FakeFingerprintManagerInteractor : FingerprintManagerInteractor {
@@ -37,17 +38,8 @@
   val enrollStateViewModel = FingerEnrollStateViewModel.EnrollProgress(1)
   var pressToAuthEnabled = true
 
-  var sensorProps =
-    listOf(
-      FingerprintSensorPropertiesInternal(
-        0 /* sensorId */,
-        SensorProperties.STRENGTH_STRONG,
-        5 /* maxEnrollmentsPerUser */,
-        emptyList() /* ComponentInfoInternal */,
-        TYPE_POWER_BUTTON,
-        true /* resetLockoutRequiresHardwareAuthToken */
-      )
-    )
+  var sensorProp =
+    FingerprintSensorPropertyViewModel(0 /* sensorId */, SensorStrength.Strong, 5, SensorType.SFPS)
 
   override suspend fun authenticate(): FingerprintAuthAttemptViewModel {
     return authenticateAttempt
@@ -65,8 +57,8 @@
     emit(enrolledFingerprintsInternal.size < enrollableFingerprints)
   }
 
-  override val sensorPropertiesInternal: Flow<FingerprintSensorPropertiesInternal?> = flow {
-    emit(sensorProps.first())
+  override val sensorPropertiesInternal: Flow<FingerprintSensorPropertyViewModel?> = flow {
+    emit(sensorProp)
   }
 
   override val maxEnrollableFingerprints: Flow<Int> = flow { emit(enrollableFingerprints) }
@@ -74,7 +66,7 @@
   override suspend fun enroll(
     hardwareAuthToken: ByteArray?,
     enrollReason: EnrollReason
-  ): Flow<FingerEnrollStateViewModel> = flow { emit(enrollStateViewModel) }
+  ): Flow<FingerEnrollStateViewModel> = flowOf(enrollStateViewModel)
 
   override suspend fun removeFingerprint(fp: FingerprintViewModel): Boolean {
     return enrolledFingerprintsInternal.remove(fp)
@@ -87,7 +79,7 @@
   }
 
   override suspend fun hasSideFps(): Boolean {
-    return sensorProps.any { it.isAnySidefpsType }
+    return sensorProp.sensorType == SensorType.SFPS
   }
 
   override suspend fun pressToAuthEnabled(): Boolean {
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index 196b809..4f044c7 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -28,6 +28,7 @@
         "truth-prebuilt",
         "kotlinx_coroutines_test",
         "flag-junit",
+        "Settings-testutils2",
         // Don't add SettingsLib libraries here - you can use them directly as they are in the
         // instrumented Settings app.
     ],
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 de2c494..f0d0a0a 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,12 +26,12 @@
 import android.os.Handler
 import androidx.test.core.app.ApplicationProvider
 import com.android.settings.biometrics.GatekeeperPasswordProvider
-import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.shared.domain.interactor.FingerprintManagerInteractor
 import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
+import com.android.settings.biometrics.fingerprint2.shared.model.EnrollReason
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptViewModel
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.EnrollReason.FindSensor
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerEnrollStateViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerEnrollStateViewModel
 import com.android.settings.password.ChooseLockSettingsHelper
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.cancelAndJoin
@@ -283,7 +283,7 @@
     testScope.runTest {
       val token = byteArrayOf(5, 3, 2)
       var result: FingerEnrollStateViewModel? = null
-      val job = launch { underTest.enroll(token, FindSensor).collect { result = it } }
+      val job = launch { underTest.enroll(token, EnrollReason.FindSensor).collect { result = it } }
       val enrollCallback: ArgumentCaptor<FingerprintManager.EnrollmentCallback> = argumentCaptor()
       runCurrent()
 
@@ -307,7 +307,7 @@
     testScope.runTest {
       val token = byteArrayOf(5, 3, 2)
       var result: FingerEnrollStateViewModel? = null
-      val job = launch { underTest.enroll(token, FindSensor).collect { result = it } }
+      val job = launch { underTest.enroll(token, EnrollReason.FindSensor).collect { result = it } }
       val enrollCallback: ArgumentCaptor<FingerprintManager.EnrollmentCallback> = argumentCaptor()
       runCurrent()
 
@@ -331,7 +331,7 @@
     testScope.runTest {
       val token = byteArrayOf(5, 3, 2)
       var result: FingerEnrollStateViewModel? = null
-      val job = launch { underTest.enroll(token, FindSensor).collect { result = it } }
+      val job = launch { underTest.enroll(token, EnrollReason.FindSensor).collect { result = it } }
       val enrollCallback: ArgumentCaptor<FingerprintManager.EnrollmentCallback> = argumentCaptor()
       runCurrent()
 
diff --git a/tests/unit/src/com/android/settings/fingerprint2/settings/viewmodel/FingerprintSettingsNavigationViewModelTest.kt b/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsNavigationViewModelTest.kt
similarity index 94%
rename from tests/unit/src/com/android/settings/fingerprint2/settings/viewmodel/FingerprintSettingsNavigationViewModelTest.kt
rename to tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsNavigationViewModelTest.kt
index 6bb8a16..d4dbec5 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/settings/viewmodel/FingerprintSettingsNavigationViewModelTest.kt
+++ b/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsNavigationViewModelTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.fingerprint2.settings.viewmodel
+package com.android.settings.fingerprint2.ui.settings
 
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
 import com.android.settings.biometrics.BiometricEnrollBase
@@ -26,7 +26,7 @@
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.LaunchConfirmDeviceCredential
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.NextStepViewModel
 import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.ShowSettings
-import com.android.settings.fingerprint2.domain.interactor.FakeFingerprintManagerInteractor
+import com.android.settings.testutils2.FakeFingerprintManagerInteractor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -133,22 +133,6 @@
     }
 
   @Test
-  fun firstEnrollment_fails() =
-    testScope.runTest {
-      fakeFingerprintManagerInteractor.enrolledFingerprintsInternal = mutableListOf()
-
-      var nextStep: NextStepViewModel? = null
-      val job = launch { underTest.nextStep.collect { nextStep = it } }
-
-      underTest.onConfirmDevice(true, 10L)
-      underTest.onEnrollFirstFailure("We failed!!")
-      runCurrent()
-
-      assertThat(nextStep).isInstanceOf(FinishSettings::class.java)
-      job.cancel()
-    }
-
-  @Test
   fun firstEnrollment_failsWithReason() =
     testScope.runTest {
       fakeFingerprintManagerInteractor.enrolledFingerprintsInternal = mutableListOf()
diff --git a/tests/unit/src/com/android/settings/fingerprint2/settings/viewmodel/FingerprintSettingsViewModelTest.kt b/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsViewModelTest.kt
similarity index 86%
rename from tests/unit/src/com/android/settings/fingerprint2/settings/viewmodel/FingerprintSettingsViewModelTest.kt
rename to tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsViewModelTest.kt
index e8a4d55..fb1d05a 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/settings/viewmodel/FingerprintSettingsViewModelTest.kt
+++ b/tests/unit/src/com/android/settings/fingerprint2/ui/settings/FingerprintSettingsViewModelTest.kt
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.settings.fingerprint2.settings.viewmodel
+package com.android.settings.fingerprint2.ui.settings
 
-import android.hardware.biometrics.SensorProperties
-import android.hardware.fingerprint.FingerprintSensorProperties
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
 import androidx.arch.core.executor.testing.InstantTaskExecutorRule
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintAuthAttemptViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintSensorPropertyViewModel
 import com.android.settings.biometrics.fingerprint2.shared.model.FingerprintViewModel
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorStrength
+import com.android.settings.biometrics.fingerprint2.shared.model.SensorType
 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
-import com.android.settings.fingerprint2.domain.interactor.FakeFingerprintManagerInteractor
+import com.android.settings.testutils2.FakeFingerprintManagerInteractor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.collectLatest
@@ -95,16 +95,12 @@
   @Test
   fun authenticate_DoesNotRun_ifOptical() =
     testScope.runTest {
-      fakeFingerprintManagerInteractor.sensorProps =
-        listOf(
-          FingerprintSensorPropertiesInternal(
-            0 /* sensorId */,
-            SensorProperties.STRENGTH_STRONG,
-            5 /* maxEnrollmentsPerUser */,
-            emptyList() /* ComponentInfoInternal */,
-            FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
-            true /* resetLockoutRequiresHardwareAuthToken */
-          )
+      fakeFingerprintManagerInteractor.sensorProp =
+        FingerprintSensorPropertyViewModel(
+          0 /* sensorId */,
+          SensorStrength.Strong,
+          5 /* maxEnrollmentsPerUser */,
+          SensorType.Optical,
         )
       fakeFingerprintManagerInteractor.enrolledFingerprintsInternal =
         mutableListOf(FingerprintViewModel("a", 1, 3L))
@@ -135,16 +131,12 @@
   @Test
   fun authenticate_DoesNotRun_ifUltrasonic() =
     testScope.runTest {
-      fakeFingerprintManagerInteractor.sensorProps =
-        listOf(
-          FingerprintSensorPropertiesInternal(
-            0 /* sensorId */,
-            SensorProperties.STRENGTH_STRONG,
-            5 /* maxEnrollmentsPerUser */,
-            emptyList() /* ComponentInfoInternal */,
-            FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC,
-            true /* resetLockoutRequiresHardwareAuthToken */
-          )
+      fakeFingerprintManagerInteractor.sensorProp =
+        FingerprintSensorPropertyViewModel(
+          0 /* sensorId */,
+          SensorStrength.Strong,
+          5 /* maxEnrollmentsPerUser */,
+          SensorType.Ultrasonic,
         )
       fakeFingerprintManagerInteractor.enrolledFingerprintsInternal =
         mutableListOf(FingerprintViewModel("a", 1, 3L))
@@ -173,16 +165,12 @@
   @Test
   fun authenticate_DoesRun_ifNotUdfps() =
     testScope.runTest {
-      fakeFingerprintManagerInteractor.sensorProps =
-        listOf(
-          FingerprintSensorPropertiesInternal(
-            0 /* sensorId */,
-            SensorProperties.STRENGTH_STRONG,
-            5 /* maxEnrollmentsPerUser */,
-            emptyList() /* ComponentInfoInternal */,
-            FingerprintSensorProperties.TYPE_POWER_BUTTON,
-            true /* resetLockoutRequiresHardwareAuthToken */
-          )
+      fakeFingerprintManagerInteractor.sensorProp =
+        FingerprintSensorPropertyViewModel(
+          0 /* sensorId */,
+          SensorStrength.Strong,
+          5 /* maxEnrollmentsPerUser */,
+          SensorType.SFPS
         )
       fakeFingerprintManagerInteractor.enrolledFingerprintsInternal =
         mutableListOf(FingerprintViewModel("a", 1, 3L))
@@ -383,16 +371,12 @@
     }
 
   private fun setupAuth(): MutableList<FingerprintViewModel> {
-    fakeFingerprintManagerInteractor.sensorProps =
-      listOf(
-        FingerprintSensorPropertiesInternal(
-          0 /* sensorId */,
-          SensorProperties.STRENGTH_STRONG,
-          5 /* maxEnrollmentsPerUser */,
-          emptyList() /* ComponentInfoInternal */,
-          FingerprintSensorProperties.TYPE_POWER_BUTTON,
-          true /* resetLockoutRequiresHardwareAuthToken */
-        )
+    fakeFingerprintManagerInteractor.sensorProp =
+      FingerprintSensorPropertyViewModel(
+        0 /* sensorId */,
+        SensorStrength.Strong,
+        5 /* maxEnrollmentsPerUser */,
+        SensorType.SFPS
       )
     val fingerprints =
       mutableListOf(FingerprintViewModel("a", 1, 3L), FingerprintViewModel("b", 2, 5L))