From 1ec202576d903547b41c66d22e7d31fcfb1378cc Mon Sep 17 00:00:00 2001 From: Joshua McCloskey Date: Fri, 8 Sep 2023 16:04:25 +0000 Subject: [PATCH] Moved FakeFingerprintManagerInteractor Test: atest Bug: 295206367 Change-Id: If9f3b9dc88260c0725f70d3444c4f9a4b6ee5c2f --- Android.bp | 4 + .../fingerprint2/conversion/Util.kt | 62 ++++++++++++++ ...kt => FingerprintManagerInteractorImpl.kt} | 69 +++------------- .../biometrics/fingerprint2/shared/Android.bp | 13 +++ .../fingerprint2/shared/AndroidManifest.xml | 18 ++++ .../FingerprintManagerInteractor.kt | 82 +++++++++++++++++++ .../model/EnrollReasonViewModel.kt} | 20 ++--- .../model}/FingerEnrollStateViewModel.kt | 2 +- .../shared/model/FingerprintViewModel.kt | 33 ++++++++ .../FingerprintEnrollFindSensorV2Fragment.kt | 15 ++-- .../FingerprintEnrollIntroV2Fragment.kt | 6 +- .../FingerprintEnrollFindSensorViewModel.kt | 13 +-- .../viewmodel/FingerprintEnrollViewModel.kt | 17 ++-- .../FingerprintEnrolllNavigationViewModel.kt | 4 +- .../FingerprintGatekeeperViewModel.kt | 2 +- .../viewmodel/FingerprintScrollViewModel.kt | 3 +- .../binder/FingerprintSettingsViewBinder.kt | 4 - .../FingerprintSettingsRenameDialog.kt | 5 +- .../FingerprintSettingsNavigationViewModel.kt | 28 ++++--- .../viewmodel/FingerprintSettingsViewModel.kt | 16 ++-- tests/robotests/Android.bp | 1 + tests/shared/Android.bp | 9 ++ tests/shared/AndroidManifest.xml | 20 +++++ .../FakeFingerprintManagerInteractor.kt | 36 ++++---- tests/unit/Android.bp | 1 + .../FingerprintManagerInteractorTest.kt | 12 +-- ...gerprintSettingsNavigationViewModelTest.kt | 20 +---- .../FingerprintSettingsViewModelTest.kt | 74 +++++++---------- 28 files changed, 366 insertions(+), 223 deletions(-) create mode 100644 src/com/android/settings/biometrics/fingerprint2/conversion/Util.kt rename src/com/android/settings/biometrics/fingerprint2/domain/interactor/{FingerprintManagerInteractor.kt => FingerprintManagerInteractorImpl.kt} (75%) create mode 100644 src/com/android/settings/biometrics/fingerprint2/shared/Android.bp create mode 100644 src/com/android/settings/biometrics/fingerprint2/shared/AndroidManifest.xml create mode 100644 src/com/android/settings/biometrics/fingerprint2/shared/domain/interactor/FingerprintManagerInteractor.kt rename src/com/android/settings/biometrics/fingerprint2/{ui/enrollment/viewmodel/EnrollReason.kt => shared/model/EnrollReasonViewModel.kt} (57%) rename src/com/android/settings/biometrics/fingerprint2/{ui/enrollment/viewmodel => shared/model}/FingerEnrollStateViewModel.kt (94%) create mode 100644 tests/shared/Android.bp create mode 100644 tests/shared/AndroidManifest.xml rename tests/{unit/src/com/android/settings/fingerprint2/domain/interactor => shared/src/com/android/settings/testutils2}/FakeFingerprintManagerInteractor.kt (71%) rename tests/unit/src/com/android/settings/fingerprint2/{settings/viewmodel => ui/settings}/FingerprintSettingsNavigationViewModelTest.kt (94%) rename tests/unit/src/com/android/settings/fingerprint2/{settings/viewmodel => ui/settings}/FingerprintSettingsViewModelTest.kt (86%) diff --git a/Android.bp b/Android.bp index 0271b2f10fb..a62aa1101c0 100644 --- a/Android.bp +++ b/Android.bp @@ -55,6 +55,9 @@ android_library { ], 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 @@ android_library { "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 00000000000..b2767c3b3cc --- /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 2c8ee8f7a40..41da24773da 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.content.Intent 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 @@ import kotlinx.coroutines.withContext private const val TAG = "FingerprintManagerInteractor" -/** Encapsulates business logic related to managing fingerprints. */ -interface FingerprintManagerInteractor { - /** Returns the list of current fingerprints. */ - val enrolledFingerprints: Flow> - - /** Returns the max enrollable fingerprints, note during SUW this might be 1 */ - val maxEnrollableFingerprints: Flow - - /** Returns true if a user can enroll a fingerprint false otherwise. */ - val canEnrollFingerprints: Flow - - /** Retrieves the sensor properties of a device */ - val sensorPropertiesInternal: Flow - - /** 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 - - /** - * 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 - - /** - * 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 @@ class FingerprintManagerInteractorImpl( 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 @@ class FingerprintManagerInteractorImpl( 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 00000000000..8873fd8f1a2 --- /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 00000000000..e2c97fc1fac --- /dev/null +++ b/src/com/android/settings/biometrics/fingerprint2/shared/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + 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 00000000000..5353bb2015b --- /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> + + /** Returns the max enrollable fingerprints, note during SUW this might be 1 */ + val maxEnrollableFingerprints: Flow + + /** Returns true if a user can enroll a fingerprint false otherwise. */ + val canEnrollFingerprints: Flow + + /** Retrieves the sensor properties of a device */ + val sensorPropertiesInternal: Flow + + /** 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 + + /** + * 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 + + /** + * 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/ui/enrollment/viewmodel/EnrollReason.kt b/src/com/android/settings/biometrics/fingerprint2/shared/model/EnrollReasonViewModel.kt similarity index 57% rename from src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/EnrollReason.kt rename to src/com/android/settings/biometrics/fingerprint2/shared/model/EnrollReasonViewModel.kt index 87deeb3f54f..47a0af0de97 100644 --- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/EnrollReason.kt +++ b/src/com/android/settings/biometrics/fingerprint2/shared/model/EnrollReasonViewModel.kt @@ -13,24 +13,16 @@ * 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 +package com.android.settings.biometrics.fingerprint2.shared.model -/** - * The reason for enrollment. Represents [FingerprintManager.EnrollReason] - */ +/** The reason for enrollment */ enum class EnrollReason { - /** The enroll happens on education screen. */ + /** + * 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 } - -/** 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/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 73343bdd048..179ac603b72 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 db28e793533..fc9539c7e3d 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 @@ sealed class FingerprintAuthAttemptViewModel { 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 dcdcccfd7b4..e4ac00fd308 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.airbnb.lottie.LottieAnimationView 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 @@ class FingerprintEnrollFindSensorV2Fragment : Fragment() { 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 @@ class FingerprintEnrollFindSensorV2Fragment : Fragment() { 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 dbf6d128c0d..2ebc5d58c20 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 androidx.lifecycle.lifecycleScope 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 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll 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/FingerprintEnrollFindSensorViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollFindSensorViewModel.kt index dbf6b33de5a..c877d679a9e 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 android.hardware.fingerprint.FingerprintManager 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 @@ class FingerprintEnrollFindSensorViewModel( orientationStateViewModel: OrientationStateViewModel ) : ViewModel() { /** Represents the stream of sensor type. */ - val sensorType: Flow = + val sensorType: Flow = fingerprintEnrollViewModel.sensorType.filterWhenEducationIsShown() private val _isUdfps: Flow = sensorType.map { - it == FingerprintSensorType.UDFPS_OPTICAL || it == FingerprintSensorType.UDFPS_ULTRASONIC + it == SensorType.Optical || it == SensorType.Ultrasonic } - private val _isSfps: Flow = sensorType.map { it == FingerprintSensorType.POWER_BUTTON } + private val _isSfps: Flow = sensorType.map { it == SensorType.RFPS } private val _isRearSfps: Flow = combineTransform(_isSfps, _isUdfps) { v1, v2 -> !v1 && !v2 } @@ -92,8 +95,8 @@ class FingerprintEnrollFindSensorViewModel( ) { 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 cb1beb93cff..b2c51dbc1f5 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 @@ package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel 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 @@ class FingerprintEnrollViewModel( backgroundDispatcher: CoroutineDispatcher, ) : ViewModel() { - /** Represents the stream of [FingerprintSensorType] */ - val sensorType: Flow = - fingerprintManagerInteractor.sensorPropertiesInternal.filterNotNull().map { - it.sensorType.toSensorType() - } - private var _enrollReason: MutableStateFlow = MutableStateFlow(EnrollReason.FindSensor) private var _hardwareAuthToken: MutableStateFlow = MutableStateFlow(null) private var _consumerShouldEnroll: MutableStateFlow = MutableStateFlow(false) + /** Represents the stream of [FingerprintSensorType] */ + val sensorType: Flow = + 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 dafe545ed19..d2bb3212122 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 android.util.Log 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 @@ interface Validator { /** * 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 fa4463a0822..db93d022266 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 android.util.Log 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 d79d9c0e8bc..989d4d32372 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 @@ import kotlinx.coroutines.flow.update class FingerprintScrollViewModel : ViewModel() { private val _hasReadConsentScreen: MutableStateFlow = MutableStateFlow(false) + /** Indicates if a user has consented to FingerprintEnrollment */ val hasReadConsentScreen: Flow = _hasReadConsentScreen.asStateFlow() @@ -35,7 +36,7 @@ class FingerprintScrollViewModel : ViewModel() { _hasReadConsentScreen.update { true } } - class FingerprintScrollViewModelFactory() : ViewModelProvider.Factory { + class FingerprintScrollViewModelFactory : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun 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 9f42d819b56..e66b4cde4b8 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.Prefer 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 @@ object FingerprintSettingsViewBinder { challenge: Long?, challengeToken: ByteArray? ) - /** Helper to launch an add fingerprint request */ fun launchAddFingerprint(userId: Int, challengeToken: ByteArray?) /** @@ -63,10 +61,8 @@ object FingerprintSettingsViewBinder { * 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 84f33ff8d1c..9bde0b062b0 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 @@ class FingerprintSettingsRenameDialog : InstrumentedDialogFragment() { 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 538bb6d5540..22a25e1af36 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.ViewModel 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 @@ import kotlinx.coroutines.launch /** 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 = MutableStateFlow(null) + /** This flow represents the high level state for the FingerprintSettingsV2Fragment. */ val nextStep: StateFlow = _nextStep.asStateFlow() @@ -118,8 +119,8 @@ class FingerprintSettingsNavigationViewModel( launchFinishSettings("Error, empty keyChallenge") return } - token = theToken!! - challenge = theChallenge!! + token = theToken + challenge = theChallenge showSettingsHelper() } @@ -170,12 +171,13 @@ class FingerprintSettingsNavigationViewModel( 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 5770d09e4d9..d2691b4b2c5 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 android.util.Log 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 @@ class FingerprintSettingsViewModel( private val _consumerShouldAuthenticate: MutableStateFlow = MutableStateFlow(false) - private val _fingerprintSensorType: Flow = - fingerprintManagerInteractor.sensorPropertiesInternal.filterNotNull().map { - it.sensorType.toSensorType() - } + private val _fingerprintSensorType: Flow = + fingerprintManagerInteractor.sensorPropertiesInternal.filterNotNull().map { it.sensorType } private val _sensorNullOrEmpty: Flow = fingerprintManagerInteractor.sensorPropertiesInternal.map { it == null } @@ -149,10 +146,7 @@ class FingerprintSettingsViewModel( 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 910bbbd2abb..fbfd888ad51 100644 --- a/tests/robotests/Android.bp +++ b/tests/robotests/Android.bp @@ -61,6 +61,7 @@ android_robolectric_test { "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 00000000000..fca24b69f53 --- /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 00000000000..7e1842cbdf7 --- /dev/null +++ b/tests/shared/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + 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 f807f703014..05c3e3c27d4 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 @@ class FakeFingerprintManagerInteractor : FingerprintManagerInteractor { 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 @@ class FakeFingerprintManagerInteractor : FingerprintManagerInteractor { emit(enrolledFingerprintsInternal.size < enrollableFingerprints) } - override val sensorPropertiesInternal: Flow = flow { - emit(sensorProps.first()) + override val sensorPropertiesInternal: Flow = flow { + emit(sensorProp) } override val maxEnrollableFingerprints: Flow = flow { emit(enrollableFingerprints) } @@ -74,7 +66,7 @@ class FakeFingerprintManagerInteractor : FingerprintManagerInteractor { override suspend fun enroll( hardwareAuthToken: ByteArray?, enrollReason: EnrollReason - ): Flow = flow { emit(enrollStateViewModel) } + ): Flow = flowOf(enrollStateViewModel) override suspend fun removeFingerprint(fp: FingerprintViewModel): Boolean { return enrolledFingerprintsInternal.remove(fp) @@ -87,7 +79,7 @@ class FakeFingerprintManagerInteractor : FingerprintManagerInteractor { } 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 196b80914c7..4f044c78392 100644 --- a/tests/unit/Android.bp +++ b/tests/unit/Android.bp @@ -28,6 +28,7 @@ android_test { "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 de2c494523f..f0d0a0a4ca0 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.CancellationSignal 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 @@ class FingerprintManagerInteractorTest { 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 = argumentCaptor() runCurrent() @@ -307,7 +307,7 @@ class FingerprintManagerInteractorTest { 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 = argumentCaptor() runCurrent() @@ -331,7 +331,7 @@ class FingerprintManagerInteractorTest { 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 = 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 6bb8a165312..d4dbec5cdfd 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.Finish 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 @@ -132,22 +132,6 @@ class FingerprintSettingsNavigationViewModelTest { job.cancel() } - @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 { 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 e8a4d55274f..fb1d05a7be9 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 @@ class FingerprintSettingsViewModelTest { @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 @@ class FingerprintSettingsViewModelTest { @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 @@ class FingerprintSettingsViewModelTest { @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 @@ class FingerprintSettingsViewModelTest { } private fun setupAuth(): MutableList { - 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))