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