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