Biometrics Enrollment refactor (7/N)
This cl moves the creation of repos and interactors to the
SettingsApplication.
Bug: 297082837
Test: atest
Change-Id: I9049da6f03bb1dc18d4186961444bf613d773d0e
diff --git a/Android.bp b/Android.bp
index b96d0dc..cb898be 100644
--- a/Android.bp
+++ b/Android.bp
@@ -108,6 +108,8 @@
"telephony_flags_core_java_lib",
"setupdesign-lottie-loading-layout",
"device_policy_aconfig_flags_lib",
+ "kotlinx-coroutines-core",
+ "kotlinx-coroutines-android",
],
plugins: ["androidx.room_room-compiler-plugin"],
diff --git a/src/com/android/settings/SettingsApplication.java b/src/com/android/settings/SettingsApplication.java
index 169e046..7d5d2c7 100644
--- a/src/com/android/settings/SettingsApplication.java
+++ b/src/com/android/settings/SettingsApplication.java
@@ -24,9 +24,11 @@
import android.util.FeatureFlagUtils;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
+import com.android.settings.biometrics.fingerprint2.BiometricsEnvironment;
import com.android.settings.core.instrumentation.ElapsedTimeUtils;
import com.android.settings.development.DeveloperOptionsActivityLifecycle;
import com.android.settings.fuelgauge.BatterySettingsStorage;
@@ -47,6 +49,7 @@
public class SettingsApplication extends Application {
private WeakReference<SettingsHomepageActivity> mHomeActivity = new WeakReference<>(null);
+ private BiometricsEnvironment mBiometricsEnvironment;
@Override
protected void attachBaseContext(Context base) {
@@ -70,6 +73,7 @@
// Set Spa environment.
setSpaEnvironment();
+ mBiometricsEnvironment = new BiometricsEnvironment(this);
if (ActivityEmbeddingUtils.isSettingsSplitEnabled(this)
&& FeatureFlagUtils.isEnabled(this,
@@ -111,6 +115,11 @@
return mHomeActivity.get();
}
+ @Nullable
+ public BiometricsEnvironment getBiometricEnvironment() {
+ return mBiometricsEnvironment;
+ }
+
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
diff --git a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollHelper.java b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollHelper.java
index f292aae..8d1113e 100644
--- a/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollHelper.java
+++ b/src/com/android/settings/biometrics/fingerprint/UdfpsEnrollHelper.java
@@ -184,7 +184,6 @@
*/
public void onAcquired(boolean isAcquiredGood) {
if (mListener != null) {
- Log.e("JRM", "OnaCquired " + isAcquiredGood + " lastStepIsGood" + animateIfLastStep());
mListener.onAcquired(isAcquiredGood && animateIfLastStep());
}
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt b/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt
new file mode 100644
index 0000000..215692a
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/BiometricsEnvironment.kt
@@ -0,0 +1,144 @@
+/*
+ * 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
+
+import android.hardware.fingerprint.FingerprintManager
+import android.view.MotionEvent
+import android.view.accessibility.AccessibilityManager
+import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.ViewModelStore
+import androidx.lifecycle.ViewModelStoreOwner
+import com.android.internal.widget.LockPatternUtils
+import com.android.settings.SettingsApplication
+import com.android.settings.biometrics.GatekeeperPasswordProvider
+import com.android.settings.biometrics.fingerprint2.data.repository.DebuggingRepository
+import com.android.settings.biometrics.fingerprint2.data.repository.DebuggingRepositoryImpl
+import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
+import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepositoryImpl
+import com.android.settings.biometrics.fingerprint2.debug.data.repository.UdfpsEnrollDebugRepositoryImpl
+import com.android.settings.biometrics.fingerprint2.debug.domain.interactor.DebugTouchEventInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.AccessibilityInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.AccessibilityInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.DebuggingInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.DebuggingInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.DisplayDensityInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.DisplayDensityInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.EnrollStageInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.EnrollStageInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintEnrollInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintEnrollInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintSensorInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintSensorInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.TouchEventInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractorImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractorImpl
+import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
+import com.android.settings.biometrics.fingerprint2.lib.model.Settings
+import java.util.concurrent.Executors
+import kotlinx.coroutines.MainScope
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+
+/**
+ * This class should handle all repo & interactor creation needed by the ViewModels for the
+ * biometrics code.
+ *
+ * This code is instantiated within the [SettingsApplication], all repos should be private &
+ * immutable and all interactors should public and immutable
+ */
+class BiometricsEnvironment(context: SettingsApplication) : ViewModelStoreOwner {
+
+ private val executorService = Executors.newSingleThreadExecutor()
+ private val backgroundDispatcher = executorService.asCoroutineDispatcher()
+ private val applicationScope = MainScope()
+ private val gateKeeperPasswordProvider = GatekeeperPasswordProvider(LockPatternUtils(context))
+ private val fingerprintManager =
+ context.getSystemService(FragmentActivity.FINGERPRINT_SERVICE) as FingerprintManager?
+
+ private val fingerprintSensorRepository: FingerprintSensorRepository =
+ FingerprintSensorRepositoryImpl(fingerprintManager, backgroundDispatcher, applicationScope)
+ private val debuggingRepository: DebuggingRepository = DebuggingRepositoryImpl()
+ private val udfpsDebugRepo = UdfpsEnrollDebugRepositoryImpl()
+
+ /** For now, interactors are public to those with access to the [BiometricsEnvironment] class */
+ val fingerprintEnrollInteractor: FingerprintEnrollInteractor by lazy {
+ FingerprintEnrollInteractorImpl(context, fingerprintManager, Settings)
+ }
+
+ /** [FingerprintManagerInteractor] to be used to construct view models */
+ val fingerprintManagerInteractor: FingerprintManagerInteractor by lazy {
+ FingerprintManagerInteractorImpl(
+ context,
+ backgroundDispatcher,
+ fingerprintManager,
+ fingerprintSensorRepository,
+ gateKeeperPasswordProvider,
+ fingerprintEnrollInteractor,
+ )
+ }
+
+ val accessibilityInteractor: AccessibilityInteractor by lazy {
+ AccessibilityInteractorImpl(
+ context.getSystemService(AccessibilityManager::class.java)!!,
+ applicationScope,
+ )
+ }
+
+ val foldStateInteractor: FoldStateInteractor by lazy { FoldStateInteractorImpl(context) }
+
+ val orientationInteractor: OrientationInteractor by lazy { OrientationInteractorImpl(context) }
+
+ val vibrationInteractor: VibrationInteractor by lazy { VibrationInteractorImpl(context) }
+
+ val displayDensityInteractor: DisplayDensityInteractor by lazy {
+ DisplayDensityInteractorImpl(context, applicationScope)
+ }
+
+ val debuggingInteractor: DebuggingInteractor by lazy {
+ DebuggingInteractorImpl(debuggingRepository)
+ }
+
+ val enrollStageInteractor: EnrollStageInteractor by lazy { EnrollStageInteractorImpl() }
+
+ val udfpsEnrollInteractor: UdfpsEnrollInteractor by lazy {
+ UdfpsEnrollInteractorImpl(context, accessibilityInteractor)
+ }
+
+ val sensorInteractor: FingerprintSensorInteractor by lazy {
+ FingerprintSensorInteractorImpl(fingerprintSensorRepository)
+ }
+
+ val touchEventInteractor: TouchEventInteractor by lazy {
+ if (debuggingRepository.isDebuggingEnabled()) {
+ DebugTouchEventInteractorImpl(udfpsDebugRepo)
+ } else {
+ object : TouchEventInteractor {
+ override val touchEvent: Flow<MotionEvent> = flowOf()
+ }
+ }
+ }
+
+ override val viewModelStore: ViewModelStore = ViewModelStore()
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/data/repository/DebuggingRepository.kt b/src/com/android/settings/biometrics/fingerprint2/data/repository/DebuggingRepository.kt
index d007e1a..6083809 100644
--- a/src/com/android/settings/biometrics/fingerprint2/data/repository/DebuggingRepository.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/data/repository/DebuggingRepository.kt
@@ -23,6 +23,7 @@
/** A function that will return if a build is debuggable */
fun isDebuggingEnabled(): Boolean
+
/** A function that will return if udfps enrollment should be swapped with debug repos */
fun isUdfpsEnrollmentDebuggingEnabled(): Boolean
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/data/repository/FingerprintSensorRepository.kt b/src/com/android/settings/biometrics/fingerprint2/data/repository/FingerprintSensorRepository.kt
index b7616e4..516549e 100644
--- a/src/com/android/settings/biometrics/fingerprint2/data/repository/FingerprintSensorRepository.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/data/repository/FingerprintSensorRepository.kt
@@ -46,7 +46,7 @@
}
class FingerprintSensorRepositoryImpl(
- fingerprintManager: FingerprintManager,
+ fingerprintManager: FingerprintManager?,
backgroundDispatcher: CoroutineDispatcher,
activityScope: CoroutineScope,
) : FingerprintSensorRepository {
@@ -73,12 +73,9 @@
.stateIn(activityScope, started = SharingStarted.Eagerly, initialValue = DEFAULT_PROPS)
override val fingerprintSensor: Flow<FingerprintSensor> =
- fingerprintPropsInternal.transform {
- emit(it.toFingerprintSensor())
- }
+ fingerprintPropsInternal.transform { emit(it.toFingerprintSensor()) }
companion object {
- private const val TAG = "FingerprintSensorRepoImpl"
private val DEFAULT_PROPS =
FingerprintSensorPropertiesInternal(
diff --git a/src/com/android/settings/biometrics/fingerprint2/data/repository/SimulatedTouchEventsRepository.kt b/src/com/android/settings/biometrics/fingerprint2/data/repository/SimulatedTouchEventsRepository.kt
index a3bcb12..3c355e7 100644
--- a/src/com/android/settings/biometrics/fingerprint2/data/repository/SimulatedTouchEventsRepository.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/data/repository/SimulatedTouchEventsRepository.kt
@@ -17,6 +17,7 @@
package com.android.settings.biometrics.fingerprint2.data.repository
import android.graphics.Point
+import android.view.MotionEvent
import kotlinx.coroutines.flow.Flow
/**
@@ -24,8 +25,6 @@
* that talkback is correct.
*/
interface SimulatedTouchEventsRepository {
- /**
- * A flow simulating user touches.
- */
- val touchExplorationDebug: Flow<Point>
+ /** A flow simulating user touches. */
+ val touchExplorationDebug: Flow<MotionEvent>
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/data/repository/UdfpsEnrollDebugRepository.kt b/src/com/android/settings/biometrics/fingerprint2/debug/data/repository/UdfpsEnrollDebugRepository.kt
similarity index 66%
rename from src/com/android/settings/biometrics/fingerprint2/data/repository/UdfpsEnrollDebugRepository.kt
rename to src/com/android/settings/biometrics/fingerprint2/debug/data/repository/UdfpsEnrollDebugRepository.kt
index 9b74813..0c3152a 100644
--- a/src/com/android/settings/biometrics/fingerprint2/data/repository/UdfpsEnrollDebugRepository.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/debug/data/repository/UdfpsEnrollDebugRepository.kt
@@ -14,10 +14,14 @@
* limitations under the License.
*/
-package com.android.settings.biometrics.fingerprint2.data.repository
+package com.android.settings.biometrics.fingerprint2.debug.data.repository
-import android.graphics.Point
import android.graphics.Rect
+import android.hardware.fingerprint.FingerprintEnrollOptions
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_HOVER_MOVE
+import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
+import com.android.settings.biometrics.fingerprint2.data.repository.SimulatedTouchEventsRepository
import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintEnrollInteractor
import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
@@ -36,7 +40,11 @@
class UdfpsEnrollDebugRepositoryImpl :
FingerprintEnrollInteractor, FingerprintSensorRepository, SimulatedTouchEventsRepository {
- override suspend fun enroll(hardwareAuthToken: ByteArray?, enrollReason: EnrollReason) = flow {
+ override suspend fun enroll(
+ hardwareAuthToken: ByteArray?,
+ enrollReason: EnrollReason,
+ fingerprintEnrollOptions: FingerprintEnrollOptions,
+ ) = flow {
emit(FingerEnrollState.OverlayShown)
delay(200)
emit(FingerEnrollState.EnrollHelp(helpMsgId, "Hello world"))
@@ -77,7 +85,7 @@
}
/** Provides touch events to the UdfpsEnrollFragment */
- override val touchExplorationDebug: Flow<Point> = flow {
+ override val touchExplorationDebug: Flow<MotionEvent> = flow {
delay(2000)
emit(pointToLeftOfSensor(sensorRect))
delay(2000)
@@ -90,17 +98,45 @@
override val fingerprintSensor: Flow<FingerprintSensor> = flowOf(sensorProps)
- private fun pointToLeftOfSensor(sensorLocation: Rect) =
- Point(sensorLocation.right + 5, sensorLocation.centerY())
+ private fun pointToLeftOfSensor(sensorLocation: Rect): MotionEvent =
+ MotionEvent.obtain(
+ 100,
+ 100,
+ ACTION_HOVER_MOVE,
+ sensorLocation.right + 5.0f,
+ sensorLocation.centerY().toFloat(),
+ 0,
+ )
- private fun pointToRightOfSensor(sensorLocation: Rect) =
- Point(sensorLocation.left - 5, sensorLocation.centerY())
+ private fun pointToRightOfSensor(sensorLocation: Rect): MotionEvent =
+ MotionEvent.obtain(
+ 100,
+ 100,
+ ACTION_HOVER_MOVE,
+ sensorLocation.right - 5.0f,
+ sensorLocation.centerY().toFloat(),
+ 0,
+ )
- private fun pointBelowSensor(sensorLocation: Rect) =
- Point(sensorLocation.centerX(), sensorLocation.bottom + 5)
+ private fun pointBelowSensor(sensorLocation: Rect): MotionEvent =
+ MotionEvent.obtain(
+ 100,
+ 100,
+ ACTION_HOVER_MOVE,
+ sensorLocation.centerX().toFloat(),
+ sensorLocation.bottom + 5.0f,
+ 0,
+ )
- private fun pointAboveSensor(sensorLocation: Rect) =
- Point(sensorLocation.centerX(), sensorLocation.top - 5)
+ private fun pointAboveSensor(sensorLocation: Rect): MotionEvent =
+ MotionEvent.obtain(
+ 100,
+ 100,
+ ACTION_HOVER_MOVE,
+ sensorLocation.centerX().toFloat(),
+ sensorLocation.top - 5.0f,
+ 0,
+ )
companion object {
@@ -109,10 +145,10 @@
private val sensorRadius = 100
private val sensorRect =
Rect(
- this.sensorLocationInternal.first - sensorRadius,
- this.sensorLocationInternal.second - sensorRadius,
- this.sensorLocationInternal.first + sensorRadius,
- this.sensorLocationInternal.second + sensorRadius,
+ sensorLocationInternal.first - sensorRadius,
+ sensorLocationInternal.second - sensorRadius,
+ sensorLocationInternal.first + sensorRadius,
+ sensorLocationInternal.second + sensorRadius,
)
val sensorProps =
FingerprintSensor(
diff --git a/src/com/android/settings/biometrics/fingerprint2/debug/domain/interactor/DebugTouchEventInteractorImpl.kt b/src/com/android/settings/biometrics/fingerprint2/debug/domain/interactor/DebugTouchEventInteractorImpl.kt
new file mode 100644
index 0000000..fff6b66
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/debug/domain/interactor/DebugTouchEventInteractorImpl.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.debug.domain.interactor
+
+import android.view.MotionEvent
+import com.android.settings.biometrics.fingerprint2.data.repository.SimulatedTouchEventsRepository
+import com.android.settings.biometrics.fingerprint2.domain.interactor.TouchEventInteractor
+import kotlinx.coroutines.flow.Flow
+
+class DebugTouchEventInteractorImpl(
+ udfpsSimulatedTouchEventsRepository: SimulatedTouchEventsRepository
+) : TouchEventInteractor {
+ override val touchEvent: Flow<MotionEvent> =
+ udfpsSimulatedTouchEventsRepository.touchExplorationDebug
+}
\ No newline at end of file
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
index e769237..e1a08e6 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/AccessibilityInteractor.kt
@@ -17,7 +17,7 @@
package com.android.settings.biometrics.fingerprint2.domain.interactor
import android.view.accessibility.AccessibilityManager
-import androidx.lifecycle.LifecycleCoroutineScope
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
@@ -26,27 +26,27 @@
/** Represents all of the information on accessibility state. */
interface AccessibilityInteractor {
- /** A flow that contains whether or not accessibility is enabled */
- val isAccessibilityEnabled: Flow<Boolean>
+ /** A flow that contains whether or not accessibility is enabled */
+ val isAccessibilityEnabled: Flow<Boolean>
}
class AccessibilityInteractorImpl(
- accessibilityManager: AccessibilityManager,
- activityScope: LifecycleCoroutineScope
+ accessibilityManager: AccessibilityManager,
+ applicationScope: CoroutineScope,
) : AccessibilityInteractor {
/** A flow that contains whether or not accessibility is enabled */
override val isAccessibilityEnabled: Flow<Boolean> =
callbackFlow {
val listener =
- AccessibilityManager.AccessibilityStateChangeListener { enabled -> trySend(enabled) }
+ AccessibilityManager.AccessibilityStateChangeListener { enabled -> trySend(enabled) }
accessibilityManager.addAccessibilityStateChangeListener(listener)
// This clause will be called when no one is listening to the flow
awaitClose { accessibilityManager.removeAccessibilityStateChangeListener(listener) }
- }
+ }
.stateIn(
- activityScope, // This is going to tied to the activity scope
- SharingStarted.WhileSubscribed(), // When no longer subscribed, we removeTheListener
- false
+ applicationScope, // This is going to tied to the activity scope
+ SharingStarted.WhileSubscribed(), // When no longer subscribed, we removeTheListener
+ false,
)
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/DebuggingInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/DebuggingInteractor.kt
index 3edca96..d0a056d 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/DebuggingInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/DebuggingInteractor.kt
@@ -28,9 +28,7 @@
val udfpsEnrollmentDebuggingEnabled: Flow<Boolean>
}
-/**
- * This interactor essentially forwards the [DebuggingRepository]
- */
+/** This interactor essentially forwards the [DebuggingRepository] */
class DebuggingInteractorImpl(val debuggingRepository: DebuggingRepository) : DebuggingInteractor {
override val debuggingEnabled: Flow<Boolean> = flow {
emit(debuggingRepository.isDebuggingEnabled())
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/DisplayDensityInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/DisplayDensityInteractor.kt
index 67c0001..6dfb4c2 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/DisplayDensityInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/DisplayDensityInteractor.kt
@@ -16,6 +16,8 @@
package com.android.settings.biometrics.fingerprint2.domain.interactor
+import android.content.Context
+import com.android.settingslib.display.DisplayDensityUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -50,12 +52,11 @@
* Implementation of the [DisplayDensityInteractor]. This interactor is used to forward activity
* information to the rest of the application.
*/
-class DisplayDensityInteractorImpl(
- currentFontScale: Float,
- currentDisplayDensity: Int,
- defaultDisplayDensity: Int,
- scope: CoroutineScope,
-) : DisplayDensityInteractor {
+class DisplayDensityInteractorImpl(context: Context, scope: CoroutineScope) :
+ DisplayDensityInteractor {
+
+ val displayDensityUtils = DisplayDensityUtils(context)
+
override fun updateDisplayDensity(density: Int) {
_displayDensity.update { density }
}
@@ -64,13 +65,18 @@
_fontScale.update { fontScale }
}
- private val _fontScale = MutableStateFlow(currentFontScale)
- private val _displayDensity = MutableStateFlow(currentDisplayDensity)
+ private val _fontScale = MutableStateFlow(context.resources.configuration.fontScale)
+ private val _displayDensity =
+ MutableStateFlow(
+ displayDensityUtils.defaultDisplayDensityValues[
+ displayDensityUtils.currentIndexForDefaultDisplay]
+ )
override val fontScale: Flow<Float> = _fontScale.asStateFlow()
override val displayDensity: Flow<Int> = _displayDensity.asStateFlow()
override val defaultDisplayDensity: Flow<Int> =
- flowOf(defaultDisplayDensity).shareIn(scope, SharingStarted.Eagerly, 1)
+ flowOf(displayDensityUtils.defaultDensityForDefaultDisplay)
+ .shareIn(scope, SharingStarted.Eagerly, 1)
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintEnrollInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintEnrollInteractor.kt
index f967e04..a36832d 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintEnrollInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintEnrollInteractor.kt
@@ -33,7 +33,6 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.callbackFlow
-import kotlinx.coroutines.flow.transform
import kotlinx.coroutines.flow.update
/** This repository is responsible for collecting all state related to the enroll API. */
@@ -45,13 +44,13 @@
suspend fun enroll(
hardwareAuthToken: ByteArray?,
enrollReason: EnrollReason,
+ fingerprintEnrollOptions: FingerprintEnrollOptions,
): Flow<FingerEnrollState>
}
class FingerprintEnrollInteractorImpl(
private val applicationContext: Context,
- private val fingerprintEnrollOptions: FingerprintEnrollOptions,
- private val fingerprintManager: FingerprintManager,
+ private val fingerprintManager: FingerprintManager?,
private val fingerprintFlow: FingerprintFlow,
) : FingerprintEnrollInteractor {
private val enrollRequestOutstanding = MutableStateFlow(false)
@@ -59,6 +58,7 @@
override suspend fun enroll(
hardwareAuthToken: ByteArray?,
enrollReason: EnrollReason,
+ fingerprintEnrollOptions: FingerprintEnrollOptions,
): Flow<FingerEnrollState> = callbackFlow {
// TODO (b/308456120) Improve this logic
if (enrollRequestOutstanding.value) {
@@ -135,7 +135,7 @@
val cancellationSignal = CancellationSignal()
- fingerprintManager.enroll(
+ fingerprintManager?.enroll(
hardwareAuthToken,
cancellationSignal,
applicationContext.userId,
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 ca3665c..f03c94e 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintManagerInteractorImpl.kt
@@ -18,6 +18,7 @@
import android.content.Context
import android.content.Intent
+import android.hardware.fingerprint.FingerprintEnrollOptions
import android.hardware.fingerprint.FingerprintManager
import android.hardware.fingerprint.FingerprintManager.GenerateChallengeCallback
import android.hardware.fingerprint.FingerprintManager.RemovalCallback
@@ -45,7 +46,7 @@
class FingerprintManagerInteractorImpl(
applicationContext: Context,
private val backgroundDispatcher: CoroutineDispatcher,
- private val fingerprintManager: FingerprintManager,
+ private val fingerprintManager: FingerprintManager?,
fingerprintSensorRepository: FingerprintSensorRepository,
private val gatekeeperPasswordProvider: GatekeeperPasswordProvider,
private val fingerprintEnrollStateRepository: FingerprintEnrollInteractor,
@@ -57,7 +58,6 @@
)
private val applicationContext = applicationContext.applicationContext
-
override suspend fun generateChallenge(gateKeeperPasswordHandle: Long): Pair<Long, ByteArray> =
suspendCoroutine {
val callback = GenerateChallengeCallback { _, userId, challenge ->
@@ -70,21 +70,19 @@
val p = Pair(challenge, challengeToken)
it.resume(p)
}
- fingerprintManager.generateChallenge(applicationContext.userId, callback)
+ fingerprintManager?.generateChallenge(applicationContext.userId, callback)
}
- override val enrolledFingerprints: Flow<List<FingerprintData>> = flow {
+ override val enrolledFingerprints: Flow<List<FingerprintData>?> = flow {
emit(
- fingerprintManager
- .getEnrolledFingerprints(applicationContext.userId)
- .map { (FingerprintData(it.name.toString(), it.biometricId, it.deviceId)) }
- .toList()
+ fingerprintManager?.getEnrolledFingerprints(applicationContext.userId)
+ ?.map { (FingerprintData(it.name.toString(), it.biometricId, it.deviceId)) }?.toList()
)
}
override val canEnrollFingerprints: Flow<Boolean> = flow {
emit(
- fingerprintManager.getEnrolledFingerprints(applicationContext.userId).size < maxFingerprints
+ fingerprintManager?.getEnrolledFingerprints(applicationContext.userId)?.size ?: maxFingerprints < maxFingerprints
)
}
@@ -92,8 +90,16 @@
override val maxEnrollableFingerprints = flow { emit(maxFingerprints) }
- override suspend fun enroll(hardwareAuthToken: ByteArray?, enrollReason: EnrollReason): Flow<FingerEnrollState> =
- fingerprintEnrollStateRepository.enroll(hardwareAuthToken, enrollReason)
+ override suspend fun enroll(
+ hardwareAuthToken: ByteArray?,
+ enrollReason: EnrollReason,
+ fingerprintEnrollOptions: FingerprintEnrollOptions,
+ ): Flow<FingerEnrollState> =
+ fingerprintEnrollStateRepository.enroll(
+ hardwareAuthToken,
+ enrollReason,
+ fingerprintEnrollOptions,
+ )
override suspend fun removeFingerprint(fp: FingerprintData): Boolean = suspendCoroutine {
val callback =
@@ -113,7 +119,7 @@
it.resume(true)
}
}
- fingerprintManager.remove(
+ fingerprintManager?.remove(
android.hardware.fingerprint.Fingerprint(fp.name, fp.fingerId, fp.deviceId),
applicationContext.userId,
callback,
@@ -122,12 +128,12 @@
override suspend fun renameFingerprint(fp: FingerprintData, newName: String) {
withContext(backgroundDispatcher) {
- fingerprintManager.rename(fp.fingerId, applicationContext.userId, newName)
+ fingerprintManager?.rename(fp.fingerId, applicationContext.userId, newName)
}
}
- override suspend fun hasSideFps(): Boolean = suspendCancellableCoroutine {
- it.resume(fingerprintManager.isPowerbuttonFps)
+ override suspend fun hasSideFps(): Boolean? = suspendCancellableCoroutine {
+ it.resume(fingerprintManager?.isPowerbuttonFps)
}
override suspend fun authenticate(): FingerprintAuthAttemptModel =
@@ -156,7 +162,7 @@
val cancellationSignal = CancellationSignal()
c.invokeOnCancellation { cancellationSignal.cancel() }
- fingerprintManager.authenticate(
+ fingerprintManager?.authenticate(
null,
cancellationSignal,
authenticationCallback,
@@ -164,5 +170,4 @@
applicationContext.userId,
)
}
-
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintSensorInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintSensorInteractor.kt
new file mode 100644
index 0000000..073629c
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FingerprintSensorInteractor.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.domain.interactor
+
+import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
+import com.android.systemui.biometrics.shared.model.FingerprintSensor
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Interactor that propagates the type of [FingerprintSensor] this device supports.
+ */
+interface FingerprintSensorInteractor {
+ /** Get the [FingerprintSensor] */
+ val fingerprintSensor: Flow<FingerprintSensor>
+}
+
+class FingerprintSensorInteractorImpl(repo: FingerprintSensorRepository) :
+ FingerprintSensorInteractor {
+ override val fingerprintSensor: Flow<FingerprintSensor> = repo.fingerprintSensor
+}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FoldStateInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FoldStateInteractor.kt
index 0224aa2..51de882 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FoldStateInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/FoldStateInteractor.kt
@@ -25,34 +25,30 @@
import kotlinx.coroutines.flow.callbackFlow
interface FoldStateInteractor {
- /** A flow that contains the fold state info */
- val isFolded: Flow<Boolean>
+ /** A flow that contains the fold state info */
+ val isFolded: Flow<Boolean>
- /**
- * Indicates a configuration change has occurred, and the repo
- * should update the [isFolded] flow.
- */
- fun onConfigurationChange(newConfig: Configuration)
+ /**
+ * Indicates a configuration change has occurred, and the repo should update the [isFolded] flow.
+ */
+ fun onConfigurationChange(newConfig: Configuration)
}
-/**
- * Interactor which handles fold state
- */
+/** Interactor which handles fold state */
class FoldStateInteractorImpl(context: Context) : FoldStateInteractor {
- private val screenSizeFoldProvider = ScreenSizeFoldProvider(context)
- override val isFolded: Flow<Boolean> = callbackFlow {
- val foldStateListener = FoldProvider.FoldCallback { isFolded -> trySend(isFolded) }
- screenSizeFoldProvider.registerCallback(foldStateListener, context.mainExecutor)
- awaitClose { screenSizeFoldProvider.unregisterCallback(foldStateListener) }
- }
+ private val screenSizeFoldProvider = ScreenSizeFoldProvider(context)
+ override val isFolded: Flow<Boolean> = callbackFlow {
+ val foldStateListener = FoldProvider.FoldCallback { isFolded -> trySend(isFolded) }
+ screenSizeFoldProvider.registerCallback(foldStateListener, context.mainExecutor)
+ awaitClose { screenSizeFoldProvider.unregisterCallback(foldStateListener) }
+ }
- /**
- * This function is called by the root activity, indicating an orientation event has occurred.
- * When this happens, the [ScreenSizeFoldProvider] is notified and it will re-compute if the
- * device is folded or not, and notify the [FoldProvider.FoldCallback]
- */
- override fun onConfigurationChange(newConfig: Configuration) {
- screenSizeFoldProvider.onConfigurationChange(newConfig)
- }
-
+ /**
+ * This function is called by the root activity, indicating an orientation event has occurred.
+ * When this happens, the [ScreenSizeFoldProvider] is notified and it will re-compute if the
+ * device is folded or not, and notify the [FoldProvider.FoldCallback]
+ */
+ override fun onConfigurationChange(newConfig: Configuration) {
+ screenSizeFoldProvider.onConfigurationChange(newConfig)
+ }
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/OrientationInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/OrientationInteractor.kt
index 3ecf312..e55d6b8 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/OrientationInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/OrientationInteractor.kt
@@ -60,10 +60,7 @@
awaitClose { orientationEventListener.disable() }
}
- override val rotation: Flow<Int> =
- orientation.transform {
- emit(context.display!!.rotation)
- }
+ override val rotation: Flow<Int> = orientation.transform { emit(context.display.rotation) }
override val rotationFromDefault: Flow<Int> = rotation.map { getRotationFromDefault(it) }
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/PressToAuthInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/PressToAuthInteractor.kt
index ab7b5de..6fb7555 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/PressToAuthInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/PressToAuthInteractor.kt
@@ -28,77 +28,67 @@
/** Interface that indicates if press to auth is on or off. */
interface PressToAuthInteractor {
- /** Indicates true if the PressToAuth feature is enabled, false otherwise. */
- val isEnabled: Flow<Boolean>
+ /** Indicates true if the PressToAuth feature is enabled, false otherwise. */
+ val isEnabled: Flow<Boolean>
}
/** Indicates whether or not the press to auth feature is enabled. */
class PressToAuthInteractorImpl(
- private val context: Context,
- private val backgroundDispatcher: CoroutineDispatcher,
+ private val context: Context,
+ private val backgroundDispatcher: CoroutineDispatcher,
) : PressToAuthInteractor {
- /**
- * A flow that contains the status of the press to auth feature.
- */
- override val isEnabled: Flow<Boolean> =
-
- callbackFlow {
- val callback =
- object : ContentObserver(null) {
- override fun onChange(selfChange: Boolean) {
- Log.d(TAG, "SFPS_PERFORMANT_AUTH_ENABLED#onchange")
- trySend(
- getPressToAuth(),
- )
- }
- }
-
- context.contentResolver.registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED),
- false,
- callback,
- context.userId
- )
- trySend(getPressToAuth())
- awaitClose {
- context.contentResolver.unregisterContentObserver(callback)
+ /** A flow that contains the status of the press to auth feature. */
+ override val isEnabled: Flow<Boolean> =
+ callbackFlow {
+ val callback =
+ object : ContentObserver(null) {
+ override fun onChange(selfChange: Boolean) {
+ Log.d(TAG, "SFPS_PERFORMANT_AUTH_ENABLED#onchange")
+ trySend(getPressToAuth())
}
- }.flowOn(backgroundDispatcher)
+ }
+ context.contentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED),
+ false,
+ callback,
+ context.userId,
+ )
+ trySend(getPressToAuth())
+ awaitClose { context.contentResolver.unregisterContentObserver(callback) }
+ }
+ .flowOn(backgroundDispatcher)
- /**
- * Returns true if press to auth is enabled
- */
- private fun getPressToAuth(): Boolean {
- var toReturn: Int =
- Settings.Secure.getIntForUser(
- context.contentResolver,
- Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
- -1,
- context.userId,
- )
- if (toReturn == -1) {
- toReturn =
- if (
- context.resources.getBoolean(com.android.internal.R.bool.config_performantAuthDefault)
- ) {
- 1
- } else {
- 0
- }
- Settings.Secure.putIntForUser(
- context.contentResolver,
- Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
- toReturn,
- context.userId,
- )
+ /** Returns true if press to auth is enabled */
+ private fun getPressToAuth(): Boolean {
+ var toReturn: Int =
+ Settings.Secure.getIntForUser(
+ context.contentResolver,
+ Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
+ -1,
+ context.userId,
+ )
+ if (toReturn == -1) {
+ toReturn =
+ if (
+ context.resources.getBoolean(com.android.internal.R.bool.config_performantAuthDefault)
+ ) {
+ 1
+ } else {
+ 0
}
- return toReturn == 1
-
+ Settings.Secure.putIntForUser(
+ context.contentResolver,
+ Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
+ toReturn,
+ context.userId,
+ )
}
+ return toReturn == 1
+ }
- companion object {
- const val TAG = "PressToAuthInteractor"
- }
+ companion object {
+ const val TAG = "PressToAuthInteractor"
+ }
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/TouchEventInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/TouchEventInteractor.kt
new file mode 100644
index 0000000..4ef2afa
--- /dev/null
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/TouchEventInteractor.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.domain.interactor
+
+import android.view.MotionEvent
+import kotlinx.coroutines.flow.Flow
+
+interface TouchEventInteractor {
+
+ /** A flow simulating user touches. */
+ val touchEvent: Flow<MotionEvent>
+}
+
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/UdfpsEnrollInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/UdfpsEnrollInteractor.kt
index 107d1f6..006060a 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/UdfpsEnrollInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/UdfpsEnrollInteractor.kt
@@ -16,8 +16,9 @@
package com.android.settings.biometrics.fingerprint2.domain.interactor
+import android.content.Context
import android.graphics.PointF
-import android.util.Log
+import android.util.TypedValue
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
@@ -43,13 +44,18 @@
/** Keeps track of which guided enrollment point we should be using */
class UdfpsEnrollInteractorImpl(
- pixelsPerMillimeter: Float,
+ applicationContext: Context,
accessibilityInteractor: AccessibilityInteractor,
) : UdfpsEnrollInteractor {
private var isGuidedEnrollment = MutableStateFlow(false)
// Number of pixels per mm
- val px = pixelsPerMillimeter
+ val px =
+ TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_MM,
+ 1f,
+ applicationContext.resources.displayMetrics,
+ )
private val guidedEnrollmentPoints: MutableList<PointF> =
mutableListOf(
PointF(2.00f * px, 0.00f * px),
@@ -70,7 +76,6 @@
override fun onEnrollmentStep(stepsRemaining: Int, totalStep: Int) {
val index = (totalStep - stepsRemaining) % guidedEnrollmentPoints.size
- Log.e("JRM", "guided enroll step $index")
_guidedEnrollment.update { guidedEnrollmentPoints[index] }
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/VibrationInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/VibrationInteractor.kt
index 0f107cc..97a68f0 100644
--- a/src/com/android/settings/biometrics/fingerprint2/domain/interactor/VibrationInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/domain/interactor/VibrationInteractor.kt
@@ -36,6 +36,7 @@
/** This vibration typically occurs when a help message is shown during UDFPS enrollment */
data object UdfpsHelp : FingerprintVibrationEffects()
}
+
/** Interface for sending haptic feedback */
interface VibrationInteractor {
/** This will send a haptic vibration */
@@ -43,8 +44,9 @@
}
/** Implementation of the VibrationInteractor interface */
-class VibrationInteractorImpl(val vibrator: Vibrator, val applicationContext: Context) :
- VibrationInteractor {
+class VibrationInteractorImpl(val applicationContext: Context) : VibrationInteractor {
+ val vibrator = applicationContext.getSystemService(Vibrator::class.java)!!
+
override fun vibrate(effect: FingerprintVibrationEffects, caller: String) {
val callerString = "$caller::$effect"
val res =
diff --git a/src/com/android/settings/biometrics/fingerprint2/lib/domain/interactor/FingerprintManagerInteractor.kt b/src/com/android/settings/biometrics/fingerprint2/lib/domain/interactor/FingerprintManagerInteractor.kt
index d2f9f0a..5f4ceca 100644
--- a/src/com/android/settings/biometrics/fingerprint2/lib/domain/interactor/FingerprintManagerInteractor.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/domain/interactor/FingerprintManagerInteractor.kt
@@ -16,7 +16,7 @@
package com.android.settings.biometrics.fingerprint2.lib.domain.interactor
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.hardware.fingerprint.FingerprintEnrollOptions
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
@@ -32,7 +32,7 @@
*/
interface FingerprintManagerInteractor {
/** Returns the list of current fingerprints. */
- val enrolledFingerprints: Flow<List<FingerprintData>>
+ val enrolledFingerprints: Flow<List<FingerprintData>?>
/** Returns the max enrollable fingerprints, note during SUW this might be 1 */
val maxEnrollableFingerprints: Flow<Int>
@@ -62,6 +62,7 @@
suspend fun enroll(
hardwareAuthToken: ByteArray?,
enrollReason: EnrollReason,
+ fingerprintEnrollOptions: FingerprintEnrollOptions,
): Flow<FingerEnrollState>
/**
@@ -74,5 +75,5 @@
suspend fun renameFingerprint(fp: FingerprintData, newName: String)
/** Indicates if the device has side fingerprint */
- suspend fun hasSideFps(): Boolean
+ suspend fun hasSideFps(): Boolean?
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/lib/model/EnrollReason.kt b/src/com/android/settings/biometrics/fingerprint2/lib/model/EnrollReason.kt
index 3cc6497..02df834 100644
--- a/src/com/android/settings/biometrics/fingerprint2/lib/model/EnrollReason.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/lib/model/EnrollReason.kt
@@ -24,5 +24,5 @@
*/
FindSensor,
/** The enroll happens on enrolling screen. */
- EnrollEnrolling
+ EnrollEnrolling,
}
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 d25fcd0..421548f 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
@@ -22,16 +22,12 @@
import android.hardware.fingerprint.FingerprintEnrollOptions
import android.hardware.fingerprint.FingerprintManager
import android.os.Bundle
-import android.os.Vibrator
import android.util.Log
-import android.util.TypedValue
-import android.view.accessibility.AccessibilityManager
import androidx.activity.result.contract.ActivityResultContracts
+import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
-import com.android.internal.widget.LockPatternUtils
import com.android.settings.R
import com.android.settings.SetupWizardUtils
import com.android.settings.Utils.SETTINGS_PACKAGE_NAME
@@ -40,27 +36,9 @@
import com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED
import com.android.settings.biometrics.BiometricUtils
import com.android.settings.biometrics.GatekeeperPasswordProvider
-import com.android.settings.biometrics.fingerprint2.data.repository.DebuggingRepositoryImpl
-import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepositoryImpl
-import com.android.settings.biometrics.fingerprint2.data.repository.UdfpsEnrollDebugRepositoryImpl
-import com.android.settings.biometrics.fingerprint2.domain.interactor.AccessibilityInteractorImpl
-import com.android.settings.biometrics.fingerprint2.domain.interactor.DebuggingInteractorImpl
import com.android.settings.biometrics.fingerprint2.domain.interactor.DisplayDensityInteractor
-import com.android.settings.biometrics.fingerprint2.domain.interactor.DisplayDensityInteractorImpl
-import com.android.settings.biometrics.fingerprint2.domain.interactor.EnrollStageInteractor
-import com.android.settings.biometrics.fingerprint2.domain.interactor.EnrollStageInteractorImpl
-import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintEnrollInteractorImpl
-import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractor
-import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractorImpl
-import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor
-import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractorImpl
-import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractor
-import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractorImpl
-import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractor
-import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractorImpl
import com.android.settings.biometrics.fingerprint2.lib.model.Default
-import com.android.settings.biometrics.fingerprint2.lib.model.Settings
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
@@ -68,18 +46,12 @@
import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.education.RfpsEnrollFindSensorFragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.education.SfpsEnrollFindSensorFragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.education.UdfpsEnrollFindSensorFragment
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.util.toFingerprintEnrollOptions
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.fragment.RFPSEnrollFragment
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel.RFPSViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.fragment.UdfpsEnrollFragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.UdfpsLastStepViewModel
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.UdfpsViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintAction
-import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollConfirmationViewModel
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.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
@@ -91,7 +63,6 @@
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.GatekeeperInfo
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Transition
import com.android.settings.flags.Flags
@@ -113,23 +84,38 @@
* children fragments.
*/
class FingerprintEnrollmentV2Activity : FragmentActivity() {
- private lateinit var fingerprintEnrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel
- private lateinit var navigationViewModel: FingerprintNavigationViewModel
- private lateinit var gatekeeperViewModel: FingerprintGatekeeperViewModel
- private lateinit var fingerprintEnrollViewModel: FingerprintEnrollViewModel
- private lateinit var vibrationInteractor: VibrationInteractor
+ private val navigationViewModel: FingerprintNavigationViewModel by viewModels {
+ FingerprintNavigationViewModel.Factory
+ }
+ private val fingerprintFlowViewModel: FingerprintFlowViewModel by viewModels {
+ FingerprintFlowViewModel.Factory
+ }
+
+ private val gatekeeperViewModel: FingerprintGatekeeperViewModel by viewModels {
+ FingerprintGatekeeperViewModel.Factory
+ }
+
+ /**
+ * View models below this line are not used by this class but must be initialized
+ * in the activity view model store to be used by other view models.
+ */
+ private val fingerprintEnrollViewModel: FingerprintEnrollViewModel by viewModels {
+ FingerprintEnrollViewModel.Factory
+ }
+
+ private val fingerprintEnrollEnrollingViewModel:
+ FingerprintEnrollEnrollingViewModel by viewModels {
+ FingerprintEnrollEnrollingViewModel.Factory
+ }
+
+ private val udfpsLastStepViewModel: UdfpsLastStepViewModel by viewModels {
+ UdfpsLastStepViewModel.Factory
+ }
+
+ private val backgroundViewModel: BackgroundViewModel by viewModels { BackgroundViewModel.Factory }
+
private lateinit var foldStateInteractor: FoldStateInteractor
- private lateinit var orientationInteractor: OrientationInteractor
private lateinit var displayDensityInteractor: DisplayDensityInteractor
- private lateinit var udfpsEnrollInteractor: UdfpsEnrollInteractor
- private lateinit var fingerprintScrollViewModel: FingerprintScrollViewModel
- private lateinit var backgroundViewModel: BackgroundViewModel
- private lateinit var fingerprintFlowViewModel: FingerprintFlowViewModel
- private lateinit var fingerprintEnrollConfirmationViewModel:
- FingerprintEnrollConfirmationViewModel
- private lateinit var udfpsLastStepViewModel: UdfpsLastStepViewModel
- private lateinit var udfpsViewModel: UdfpsViewModel
- private lateinit var enrollStageInteractor: EnrollStageInteractor
private val coroutineDispatcher = Dispatchers.Default
/** Result listener for ChooseLock activity flow. */
@@ -172,7 +158,7 @@
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?
+ val gateKeeperPasswordHandle = data?.getExtra(EXTRA_KEY_GK_PW_HANDLE) as Long
lifecycleScope.launch {
val confirmDeviceResult =
@@ -204,6 +190,15 @@
finish()
}
+ // Ensure that these view models are actually created and in this order
+ navigationViewModel
+ fingerprintFlowViewModel
+ gatekeeperViewModel
+ fingerprintEnrollViewModel
+ backgroundViewModel
+ fingerprintEnrollEnrollingViewModel
+ udfpsLastStepViewModel
+
setTheme(SetupWizardUtils.getTheme(applicationContext, intent))
ThemeHelper.trySetDynamicColor(applicationContext)
@@ -219,31 +214,7 @@
Default
}
- backgroundViewModel =
- ViewModelProvider(this, BackgroundViewModel.BackgroundViewModelFactory())[
- BackgroundViewModel::class.java]
-
- fingerprintFlowViewModel =
- ViewModelProvider(this, FingerprintFlowViewModel.FingerprintFlowViewModelFactory(enrollType))[
- FingerprintFlowViewModel::class.java]
- val displayDensityUtils = DisplayDensityUtils(context)
- val currIndex = displayDensityUtils.currentIndexForDefaultDisplay
- val defaultDisplayDensity = displayDensityUtils.defaultDensityForDefaultDisplay
- displayDensityInteractor =
- DisplayDensityInteractorImpl(
- resources.configuration.fontScale,
- displayDensityUtils.defaultDisplayDensityValues[currIndex],
- defaultDisplayDensity,
- lifecycleScope,
- )
-
- val debuggingRepo = DebuggingRepositoryImpl()
- val debuggingInteractor = DebuggingInteractorImpl(debuggingRepo)
- val udfpsEnrollDebugRepositoryImpl = UdfpsEnrollDebugRepositoryImpl()
-
- val fingerprintSensorRepo =
- if (debuggingRepo.isUdfpsEnrollmentDebuggingEnabled()) udfpsEnrollDebugRepositoryImpl
- else FingerprintSensorRepositoryImpl(fingerprintManager, backgroundDispatcher, lifecycleScope)
+ fingerprintFlowViewModel.updateFlowType(enrollType)
if (intent.getIntExtra(BiometricUtils.EXTRA_ENROLL_REASON, -1) === -1) {
val isSuw: Boolean = WizardManagerHelper.isAnySetupWizard(intent)
@@ -254,170 +225,18 @@
)
}
- val fingerprintEnrollStateRepository =
- if (debuggingRepo.isUdfpsEnrollmentDebuggingEnabled()) udfpsEnrollDebugRepositoryImpl
- else
- FingerprintEnrollInteractorImpl(
- context.applicationContext,
- intent.toFingerprintEnrollOptions(),
- fingerprintManager,
- Settings,
- )
- val accessibilityInteractor =
- AccessibilityInteractorImpl(
- getSystemService(AccessibilityManager::class.java)!!,
- lifecycleScope,
- )
-
- val pixelsPerMillimeter =
- TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1f, context.resources.displayMetrics)
- udfpsEnrollInteractor = UdfpsEnrollInteractorImpl(pixelsPerMillimeter, accessibilityInteractor)
-
- val fingerprintManagerInteractor =
- FingerprintManagerInteractorImpl(
- context,
- backgroundDispatcher,
- fingerprintManager,
- fingerprintSensorRepo,
- GatekeeperPasswordProvider(LockPatternUtils(context)),
- fingerprintEnrollStateRepository,
- )
-
var challenge = intent.getExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE) as Long?
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,
- fingerprintManagerInteractor,
- ),
- )[FingerprintGatekeeperViewModel::class.java]
-
- // Initialize FoldStateViewModel
- foldStateInteractor = FoldStateInteractorImpl(context)
- foldStateInteractor.onConfigurationChange(resources.configuration)
-
- orientationInteractor = OrientationInteractorImpl(context)
- vibrationInteractor =
- VibrationInteractorImpl(context.getSystemService(Vibrator::class.java)!!, context)
-
- // Initialize FingerprintViewModel
- fingerprintEnrollViewModel =
- ViewModelProvider(
- this,
- FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory(
- fingerprintManagerInteractor,
- gatekeeperViewModel,
- navigationViewModel,
- ),
- )[FingerprintEnrollViewModel::class.java]
-
- // Initialize scroll view model
- fingerprintScrollViewModel =
- ViewModelProvider(this, FingerprintScrollViewModel.FingerprintScrollViewModelFactory())[
- FingerprintScrollViewModel::class.java]
-
- // Initialize FingerprintEnrollEnrollingViewModel
- fingerprintEnrollEnrollingViewModel =
- ViewModelProvider(
- this,
- FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingViewModelFactory(
- fingerprintEnrollViewModel,
- backgroundViewModel,
- ),
- )[FingerprintEnrollEnrollingViewModel::class.java]
-
- // Initialize FingerprintEnrollFindSensorViewModel
- ViewModelProvider(
- this,
- FingerprintEnrollFindSensorViewModel.FingerprintEnrollFindSensorViewModelFactory(
- navigationViewModel,
- fingerprintEnrollViewModel,
- gatekeeperViewModel,
- backgroundViewModel,
- accessibilityInteractor,
- foldStateInteractor,
- orientationInteractor,
- fingerprintFlowViewModel,
- fingerprintManagerInteractor,
- ),
- )[FingerprintEnrollFindSensorViewModel::class.java]
-
- // Initialize RFPS View Model
- ViewModelProvider(
- this,
- RFPSViewModel.RFPSViewModelFactory(
- fingerprintEnrollEnrollingViewModel,
- navigationViewModel,
- orientationInteractor,
- fingerprintManagerInteractor,
- ),
- )[RFPSViewModel::class.java]
-
- enrollStageInteractor = EnrollStageInteractorImpl()
-
- udfpsLastStepViewModel =
- UdfpsLastStepViewModel(fingerprintEnrollEnrollingViewModel, vibrationInteractor)
-
- udfpsViewModel =
- ViewModelProvider(
- this,
- UdfpsViewModel.UdfpsEnrollmentFactory(
- vibrationInteractor,
- displayDensityInteractor,
- navigationViewModel,
- debuggingInteractor,
- fingerprintEnrollEnrollingViewModel,
- udfpsEnrollDebugRepositoryImpl,
- enrollStageInteractor,
- orientationInteractor,
- backgroundViewModel,
- fingerprintSensorRepo,
- udfpsEnrollInteractor,
- fingerprintManagerInteractor,
- udfpsLastStepViewModel,
- accessibilityInteractor,
- ),
- )[UdfpsViewModel::class.java]
-
- fingerprintEnrollConfirmationViewModel =
- ViewModelProvider(
- this,
- FingerprintEnrollConfirmationViewModel.FingerprintEnrollConfirmationViewModelFactory(
- navigationViewModel,
- fingerprintManagerInteractor,
- ),
- )[FingerprintEnrollConfirmationViewModel::class.java]
+ navigationViewModel.updateFingerprintFlow(enrollType)
+ navigationViewModel.hasConfirmedDeviceCredential(hasConfirmedDeviceCredential)
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")
}
}
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 d8c1c93..00541f8 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
@@ -20,8 +20,8 @@
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@@ -39,31 +39,11 @@
* This page will display basic information about what a fingerprint can be used for and acts as the
* final step of enrollment.
*/
-class FingerprintEnrollConfirmationV2Fragment() :
+class FingerprintEnrollConfirmationV2Fragment(factory: ViewModelProvider.Factory? = null) :
Fragment(R.layout.fingerprint_enroll_finish_base) {
- companion object {
- const val TAG = "FingerprintEnrollConfirmationV2Fragment"
- }
-
- /** Used for testing purposes */
- private var factory: ViewModelProvider.Factory? = null
-
- @VisibleForTesting
- constructor(theFactory: ViewModelProvider.Factory) : this() {
- factory = theFactory
- }
-
- private val viewModelProvider: ViewModelProvider by lazy {
- if (factory != null) {
- ViewModelProvider(requireActivity(), factory!!)
- } else {
- ViewModelProvider(requireActivity())
- }
- }
-
- private val viewModel: FingerprintEnrollConfirmationViewModel by lazy {
- viewModelProvider[FingerprintEnrollConfirmationViewModel::class.java]
+ private val viewModel: FingerprintEnrollConfirmationViewModel by activityViewModels {
+ factory ?: FingerprintEnrollConfirmationViewModel.Factory
}
override fun onCreateView(
@@ -106,4 +86,8 @@
private fun onNextButtonClick(view: View?) {
viewModel.onNextButtonClicked()
}
+
+ companion object {
+ const val TAG = "FingerprintEnrollConfirmationV2Fragment"
+ }
}
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 53d0ddf..6c87dfd 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
@@ -30,8 +30,9 @@
import android.widget.ImageView
import android.widget.ScrollView
import android.widget.TextView
-import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.android.settings.R
@@ -74,37 +75,22 @@
* 2. How the data will be stored
* 3. How the user can access and remove their data
*/
-class FingerprintEnrollIntroV2Fragment() : Fragment(R.layout.fingerprint_v2_enroll_introduction) {
-
- /** Used for testing purposes */
- private var factory: ViewModelProvider.Factory? = null
-
- @VisibleForTesting
- constructor(theFactory: ViewModelProvider.Factory) : this() {
- factory = theFactory
- }
-
- private val viewModelProvider: ViewModelProvider by lazy {
- if (factory != null) {
- ViewModelProvider(requireActivity(), factory!!)
- } else {
- ViewModelProvider(requireActivity())
- }
- }
+class FingerprintEnrollIntroV2Fragment(testFactory: ViewModelProvider.Factory? = null) :
+ Fragment(R.layout.fingerprint_v2_enroll_introduction) {
private lateinit var footerBarMixin: FooterBarMixin
private lateinit var textModel: TextModel
- private val viewModel: FingerprintEnrollIntroViewModel by lazy {
- viewModelProvider[FingerprintEnrollIntroViewModel::class.java]
+ private val viewModel: FingerprintEnrollIntroViewModel by activityViewModels {
+ testFactory ?: FingerprintEnrollIntroViewModel.Factory
}
- private val fingerprintScrollViewModel: FingerprintScrollViewModel by lazy {
- viewModelProvider[FingerprintScrollViewModel::class.java]
+ private val fingerprintScrollViewModel: FingerprintScrollViewModel by viewModels {
+ testFactory ?: FingerprintScrollViewModel.Factory
}
- private val gateKeeperViewModel: FingerprintGatekeeperViewModel by lazy {
- viewModelProvider[FingerprintGatekeeperViewModel::class.java]
+ private val gateKeeperViewModel: FingerprintGatekeeperViewModel by activityViewModels {
+ testFactory ?: FingerprintGatekeeperViewModel.Factory
}
override fun onCreateView(
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/RfpsEnrollFindSensorFragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/RfpsEnrollFindSensorFragment.kt
index 5ef1770..f1c1e34 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/RfpsEnrollFindSensorFragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/RfpsEnrollFindSensorFragment.kt
@@ -23,11 +23,15 @@
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import com.android.settings.R
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog
import com.android.settings.biometrics.fingerprint.FingerprintFindSensorAnimation
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.util.toFingerprintEnrollOptions
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel
import com.google.android.setupcompat.template.FooterBarMixin
import com.google.android.setupcompat.template.FooterButton
@@ -51,18 +55,10 @@
factory = theFactory
}
- private val viewModelProvider: ViewModelProvider by lazy {
- if (factory != null) {
- ViewModelProvider(requireActivity(), factory!!)
- } else {
- ViewModelProvider(requireActivity())
- }
- }
-
private var animation: FingerprintFindSensorAnimation? = null
- private val viewModel: FingerprintEnrollFindSensorViewModel by lazy {
- viewModelProvider[FingerprintEnrollFindSensorViewModel::class.java]
+ private val viewModel: FingerprintEnrollFindSensorViewModel by activityViewModels {
+ factory ?: FingerprintEnrollFindSensorViewModel.Factory
}
override fun onCreateView(
@@ -78,6 +74,12 @@
// Set up footer bar
val footerBarMixin = view.getMixin(FooterBarMixin::class.java)
setupSecondaryButton(footerBarMixin)
+
+ viewLifecycleOwner.lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ viewModel.enroll(requireActivity().intent.toFingerprintEnrollOptions())
+ }
+ }
lifecycleScope.launch {
viewModel.showPrimaryButton.collect { setupPrimaryButton(footerBarMixin) }
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/SfpsEnrollFindSensorFragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/SfpsEnrollFindSensorFragment.kt
index 584824d..22705b5 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/SfpsEnrollFindSensorFragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/SfpsEnrollFindSensorFragment.kt
@@ -24,11 +24,15 @@
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import com.airbnb.lottie.LottieAnimationView
import com.android.settings.R
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.util.toFingerprintEnrollOptions
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel
import com.google.android.setupcompat.template.FooterBarMixin
import com.google.android.setupcompat.template.FooterButton
@@ -52,16 +56,8 @@
factory = theFactory
}
- private val viewModelProvider: ViewModelProvider by lazy {
- if (factory != null) {
- ViewModelProvider(requireActivity(), factory!!)
- } else {
- ViewModelProvider(requireActivity())
- }
- }
-
- private val viewModel: FingerprintEnrollFindSensorViewModel by lazy {
- viewModelProvider[FingerprintEnrollFindSensorViewModel::class.java]
+ private val viewModel: FingerprintEnrollFindSensorViewModel by activityViewModels {
+ factory ?: FingerprintEnrollFindSensorViewModel.Factory
}
override fun onCreateView(
@@ -78,6 +74,12 @@
val footerBarMixin = view.getMixin(FooterBarMixin::class.java)
setupSecondaryButton(footerBarMixin)
+ viewLifecycleOwner.lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ viewModel.enroll(requireActivity().intent.toFingerprintEnrollOptions())
+ }
+ }
+
// Set up lottie
lifecycleScope.launch {
viewModel.sfpsLottieInfo.collect { (isFolded, rotation) ->
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/UdfpsEnrollFindSensorFragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/UdfpsEnrollFindSensorFragment.kt
index 923a309..17bfaa3 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/UdfpsEnrollFindSensorFragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/education/UdfpsEnrollFindSensorFragment.kt
@@ -24,11 +24,15 @@
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import com.airbnb.lottie.LottieAnimationView
import com.android.settings.R
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.util.toFingerprintEnrollOptions
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel
import com.google.android.setupcompat.template.FooterBarMixin
import com.google.android.setupcompat.template.FooterButton
@@ -53,16 +57,8 @@
factory = theFactory
}
- private val viewModelProvider: ViewModelProvider by lazy {
- if (factory != null) {
- ViewModelProvider(requireActivity(), factory!!)
- } else {
- ViewModelProvider(requireActivity())
- }
- }
-
- private val viewModel: FingerprintEnrollFindSensorViewModel by lazy {
- viewModelProvider[FingerprintEnrollFindSensorViewModel::class.java]
+ private val viewModel: FingerprintEnrollFindSensorViewModel by activityViewModels {
+ factory ?: FingerprintEnrollFindSensorViewModel.Factory
}
override fun onCreateView(
@@ -79,6 +75,12 @@
val footerBarMixin = view.getMixin(FooterBarMixin::class.java)
setupSecondaryButton(footerBarMixin)
+ viewLifecycleOwner.lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ viewModel.enroll(requireActivity().intent.toFingerprintEnrollOptions())
+ }
+ }
+
lifecycleScope.launch {
viewModel.showPrimaryButton.collect { setupPrimaryButton(footerBarMixin) }
}
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 0ec0bdd..1da0eea 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
@@ -28,12 +28,15 @@
import android.widget.TextView
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.settings.R
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.util.toFingerprintEnrollOptions
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.widget.FingerprintErrorDialog
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
@@ -62,29 +65,21 @@
factory = theFactory
}
- private val viewModelProvider: ViewModelProvider by lazy {
- if (factory != null) {
- ViewModelProvider(requireActivity(), factory!!)
- } else {
- ViewModelProvider(requireActivity())
- }
- }
-
private lateinit var linearOutSlowInInterpolator: Interpolator
private lateinit var fastOutLinearInInterpolator: Interpolator
private lateinit var textView: TextView
private lateinit var progressBar: RFPSProgressBar
- private val iconTouchViewModel: RFPSIconTouchViewModel by lazy {
- viewModelProvider[RFPSIconTouchViewModel::class.java]
+ private val iconTouchViewModel: RFPSIconTouchViewModel by viewModels {
+ RFPSIconTouchViewModel.Factory
}
- private val rfpsViewModel: RFPSViewModel by lazy { viewModelProvider[RFPSViewModel::class.java] }
-
- private val backgroundViewModel: BackgroundViewModel by lazy {
- viewModelProvider[BackgroundViewModel::class.java]
+ private val rfpsViewModel: RFPSViewModel by activityViewModels {
+ factory ?: RFPSViewModel.Factory
}
+ private val backgroundViewModel: BackgroundViewModel by activityViewModels()
+
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -131,6 +126,7 @@
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ rfpsViewModel.enroll(requireActivity().intent.toFingerprintEnrollOptions())
// Icon animation update
viewLifecycleOwner.lifecycleScope.launch {
// TODO(b/324427704): Fix this delay
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 cbcb1d4..00af7ed 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
@@ -19,6 +19,8 @@
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -27,6 +29,7 @@
import kotlinx.coroutines.flow.update
private const val touchesToShowDialog = 3
+
/**
* This class is responsible for counting the number of touches on the fingerprint icon, and if this
* number reaches a threshold it will produce an action via [shouldShowDialog] to indicate the ui
@@ -52,10 +55,9 @@
_touches.update { _touches.value + 1 }
}
- class RFPSIconTouchViewModelFactory : ViewModelProvider.Factory {
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return RFPSIconTouchViewModel() as T
+ companion object {
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer { RFPSIconTouchViewModel() }
}
}
}
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 8abcf1a..c95020d 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
@@ -16,9 +16,14 @@
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.rfps.ui.viewmodel
+import android.hardware.fingerprint.FingerprintEnrollOptions
+import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
@@ -158,27 +163,27 @@
enrollFlow = fingerprintEnrollViewModel.enrollFlow
}
- class RFPSViewModelFactory(
- private val fingerprintEnrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel,
- private val navigationViewModel: FingerprintNavigationViewModel,
- private val orientationInteractor: OrientationInteractor,
- private val fingerprintManager: FingerprintManagerInteractor,
- ) : ViewModelProvider.Factory {
-
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return RFPSViewModel(
- fingerprintEnrollEnrollingViewModel,
- navigationViewModel,
- orientationInteractor,
- fingerprintManager,
- )
- as T
- }
+ /** Starts enrollment. */
+ fun enroll(enrollOptions: FingerprintEnrollOptions) {
+ fingerprintEnrollViewModel.enroll(enrollOptions)
}
companion object {
private val navStep = Enrollment::class
private const val TAG = "RFPSViewModel"
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication =
+ this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment!!
+ val provider = ViewModelProvider(this[VIEW_MODEL_STORE_OWNER_KEY]!!)
+ RFPSViewModel(
+ provider[FingerprintEnrollEnrollingViewModel::class],
+ provider[FingerprintNavigationViewModel::class],
+ biometricEnvironment.orientationInteractor,
+ biometricEnvironment.fingerprintManagerInteractor,
+ )
+ }
+ }
}
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/widget/RFPSProgressBar.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/widget/RFPSProgressBar.kt
index dd7d9f5..97900b7 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/widget/RFPSProgressBar.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/rfps/ui/widget/RFPSProgressBar.kt
@@ -82,6 +82,7 @@
shouldAnimateInternal = shouldAnimate
}
+
/** This function should only be called when actual progress has been made. */
fun updateProgress(percentComplete: Float) {
val progress = maxProgress - (percentComplete.coerceIn(0.0f, 100.0f) * maxProgress).toInt()
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/fragment/UdfpsEnrollFragment.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/fragment/UdfpsEnrollFragment.kt
index 4588a07..3015321 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/fragment/UdfpsEnrollFragment.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/fragment/UdfpsEnrollFragment.kt
@@ -18,8 +18,6 @@
import android.os.Bundle
import android.util.Log
-import android.view.MotionEvent
-import android.view.MotionEvent.ACTION_HOVER_MOVE
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
@@ -27,6 +25,7 @@
import android.widget.FrameLayout
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
@@ -36,6 +35,7 @@
import com.android.settings.R
import com.android.settings.biometrics.fingerprint2.data.model.EnrollStageModel
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.util.toFingerprintEnrollOptions
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.widget.FingerprintErrorDialog
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.model.DescriptionText
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.model.HeaderText
@@ -50,17 +50,10 @@
/** Used for testing purposes */
private var factory: ViewModelProvider.Factory? = null
- private val viewModel: UdfpsViewModel by lazy { viewModelProvider[UdfpsViewModel::class.java] }
private lateinit var udfpsEnrollView: UdfpsEnrollViewV2
private lateinit var lottie: LottieAnimationView
- private val viewModelProvider: ViewModelProvider by lazy {
- if (factory != null) {
- ViewModelProvider(requireActivity(), factory!!)
- } else {
- ViewModelProvider(requireActivity())
- }
- }
+ private val viewModel: UdfpsViewModel by activityViewModels { factory ?: UdfpsViewModel.Factory }
@VisibleForTesting
constructor(theFactory: ViewModelProvider.Factory) : this() {
@@ -90,6 +83,7 @@
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ viewModel.enroll(requireActivity().intent.toFingerprintEnrollOptions())
launch {
viewModel.sensorLocation.collect { sensor ->
udfpsEnrollView.setSensorRect(sensor.sensorBounds, sensor.sensorType)
@@ -204,12 +198,16 @@
}
viewLifecycleOwner.lifecycleScope.launch {
- viewModel.touchExplorationDebug.collect {
- udfpsEnrollView.sendDebugTouchExplorationEvent(
- MotionEvent.obtain(100, 100, ACTION_HOVER_MOVE, it.x.toFloat(), it.y.toFloat(), 0)
- )
+ view.setOnTouchListener { _, motionEvent ->
+ viewModel.onTouchEvent(motionEvent)
+ false
}
}
+
+ viewLifecycleOwner.lifecycleScope.launch {
+ viewModel.touchEvent.collect { udfpsEnrollView.onTouchEvent(it) }
+ }
+
viewModel.readyForEnrollment()
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsLastStepViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsLastStepViewModel.kt
index 6a45ec4..8f9e45e 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsLastStepViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsLastStepViewModel.kt
@@ -16,9 +16,13 @@
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
+import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintVibrationEffects
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractor
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
@@ -89,14 +93,18 @@
}
.filterNotNull()
- class UdfpsLastStepViewModelFactory(
- private val fingerprintEnrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel,
- private val vibrationInteractor: VibrationInteractor,
- ) : ViewModelProvider.Factory {
-
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return UdfpsLastStepViewModel(fingerprintEnrollEnrollingViewModel, vibrationInteractor) as T
+ companion object {
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication =
+ this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment
+ val provider = ViewModelProvider(this[VIEW_MODEL_STORE_OWNER_KEY]!!)
+ UdfpsLastStepViewModel(
+ provider[FingerprintEnrollEnrollingViewModel::class],
+ biometricEnvironment!!.vibrationInteractor,
+ )
+ }
}
}
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsViewModel.kt
index 508084e..3396cdc 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/viewmodel/UdfpsViewModel.kt
@@ -16,21 +16,26 @@
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
-import android.graphics.Point
import android.graphics.PointF
+import android.hardware.fingerprint.FingerprintEnrollOptions
+import android.view.MotionEvent
import android.view.Surface
+import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
import com.android.settings.biometrics.fingerprint2.data.model.EnrollStageModel
-import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
-import com.android.settings.biometrics.fingerprint2.data.repository.SimulatedTouchEventsRepository
import com.android.settings.biometrics.fingerprint2.domain.interactor.AccessibilityInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.DebuggingInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.DisplayDensityInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.EnrollStageInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintSensorInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintVibrationEffects
import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor
+import com.android.settings.biometrics.fingerprint2.domain.interactor.TouchEventInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractor
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
@@ -45,6 +50,7 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.combineTransform
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -60,20 +66,20 @@
/** ViewModel used to drive UDFPS Enrollment through [UdfpsEnrollFragment] */
class UdfpsViewModel(
+ val navigationViewModel: FingerprintNavigationViewModel,
+ val fingerprintEnrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel,
+ backgroundViewModel: BackgroundViewModel,
+ val udfpsLastStepViewModel: UdfpsLastStepViewModel,
val vibrationInteractor: VibrationInteractor,
displayDensityInteractor: DisplayDensityInteractor,
- val navigationViewModel: FingerprintNavigationViewModel,
debuggingInteractor: DebuggingInteractor,
- val fingerprintEnrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel,
- simulatedTouchEventsDebugRepository: SimulatedTouchEventsRepository,
enrollStageInteractor: EnrollStageInteractor,
orientationInteractor: OrientationInteractor,
- backgroundViewModel: BackgroundViewModel,
- sensorRepository: FingerprintSensorRepository,
udfpsEnrollInteractor: UdfpsEnrollInteractor,
fingerprintManager: FingerprintManagerInteractor,
- val udfpsLastStepViewModel: UdfpsLastStepViewModel,
accessibilityInteractor: AccessibilityInteractor,
+ sensorRepository: FingerprintSensorInteractor,
+ touchEventInteractor: TouchEventInteractor,
) : ViewModel() {
private val isSetupWizard = flowOf(false)
@@ -191,15 +197,9 @@
.transform { emit(it == Surface.ROTATION_90) }
.distinctUntilChanged()
- /** This sends touch exploration events only used for debugging purposes. */
- val touchExplorationDebug: Flow<Point> =
- debuggingInteractor.debuggingEnabled.combineTransform(
- simulatedTouchEventsDebugRepository.touchExplorationDebug
- ) { enabled, point ->
- if (enabled) {
- emit(point)
- }
- }
+ private val _touchEvent: MutableStateFlow<MotionEvent?> = MutableStateFlow(null)
+ val touchEvent =
+ _touchEvent.asStateFlow().filterNotNull()
/** Determines the current [EnrollStageModel] enrollment is in */
private val enrollStage: Flow<EnrollStageModel> =
@@ -266,6 +266,12 @@
viewModelScope.launch {
backgroundViewModel.background.filter { it }.collect { didGoToBackground() }
}
+
+ viewModelScope.launch {
+ touchEventInteractor.touchEvent.collect {
+ _touchEvent.update { it }
+ }
+ }
}
/** Indicates if we should show the lottie. */
@@ -393,47 +399,43 @@
)
}
- class UdfpsEnrollmentFactory(
- private val vibrationInteractor: VibrationInteractor,
- private val displayDensityInteractor: DisplayDensityInteractor,
- private val navigationViewModel: FingerprintNavigationViewModel,
- private val debuggingInteractor: DebuggingInteractor,
- private val fingerprintEnrollEnrollingViewModel: FingerprintEnrollEnrollingViewModel,
- private val simulatedTouchEventsRepository: SimulatedTouchEventsRepository,
- private val enrollStageInteractor: EnrollStageInteractor,
- private val orientationInteractor: OrientationInteractor,
- private val backgroundViewModel: BackgroundViewModel,
- private val sensorRepository: FingerprintSensorRepository,
- private val udfpsEnrollInteractor: UdfpsEnrollInteractor,
- private val fingerprintManager: FingerprintManagerInteractor,
- private val udfpsLastStepViewModel: UdfpsLastStepViewModel,
- private val accessibilityInteractor: AccessibilityInteractor,
- ) : ViewModelProvider.Factory {
+ /** Starts enrollment. */
+ fun enroll(enrollOptions: FingerprintEnrollOptions) {
+ fingerprintEnrollEnrollingViewModel.enroll(enrollOptions)
+ }
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return UdfpsViewModel(
- vibrationInteractor,
- displayDensityInteractor,
- navigationViewModel,
- debuggingInteractor,
- fingerprintEnrollEnrollingViewModel,
- simulatedTouchEventsRepository,
- enrollStageInteractor,
- orientationInteractor,
- backgroundViewModel,
- sensorRepository,
- udfpsEnrollInteractor,
- fingerprintManager,
- udfpsLastStepViewModel,
- accessibilityInteractor,
- )
- as T
- }
+ /** Indicates a touch event has occurred. */
+ fun onTouchEvent(event: MotionEvent) {
+ _touchEvent.update { event }
}
companion object {
private val navStep = FingerprintNavigationStep.Enrollment::class
private const val TAG = "UDFPSViewModel"
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication =
+ this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment!!
+ val provider = ViewModelProvider(this[VIEW_MODEL_STORE_OWNER_KEY]!!)
+
+ UdfpsViewModel(
+ provider[FingerprintNavigationViewModel::class],
+ provider[FingerprintEnrollEnrollingViewModel::class],
+ provider[BackgroundViewModel::class],
+ provider[UdfpsLastStepViewModel::class],
+ biometricEnvironment.vibrationInteractor,
+ biometricEnvironment.displayDensityInteractor,
+ biometricEnvironment.debuggingInteractor,
+ biometricEnvironment.enrollStageInteractor,
+ biometricEnvironment.orientationInteractor,
+ biometricEnvironment.udfpsEnrollInteractor,
+ biometricEnvironment.fingerprintManagerInteractor,
+ biometricEnvironment.accessibilityInteractor,
+ biometricEnvironment.sensorInteractor,
+ biometricEnvironment.touchEventInteractor,
+ )
+ }
+ }
}
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/widget/UdfpsEnrollProgressBarDrawableV2.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/widget/UdfpsEnrollProgressBarDrawableV2.kt
index c3adc87..05d25cd 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/widget/UdfpsEnrollProgressBarDrawableV2.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/widget/UdfpsEnrollProgressBarDrawableV2.kt
@@ -210,6 +210,7 @@
override fun getOpacity(): Int {
return PixelFormat.UNKNOWN
}
+
/**
* Draws the progress with locations [sensorLocationX] [sensorLocationY], note these must be with
* respect to the parent framelayout.
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/widget/UdfpsEnrollViewV2.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/widget/UdfpsEnrollViewV2.kt
index d9593c1..286d750 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/widget/UdfpsEnrollViewV2.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/modules/enrolling/udfps/ui/widget/UdfpsEnrollViewV2.kt
@@ -148,18 +148,10 @@
}
}
- /**
- * Sends a touch exploration event to the [onHoverListener] this should only be used for
- * debugging.
- */
- fun sendDebugTouchExplorationEvent(motionEvent: MotionEvent) {
- touchExplorationAnnouncer.onTouch(motionEvent)
- }
-
/** Sets the addHoverListener, this should happen when talkback is enabled. */
private fun addHoverListener() {
onHoverListener = OnHoverListener { _: View, event: MotionEvent ->
- sendDebugTouchExplorationEvent(event)
+ touchExplorationAnnouncer.onTouch(event)
false
}
this.setOnHoverListener(onHoverListener)
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/BackgroundViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/BackgroundViewModel.kt
index 2b53a53..75a22fc 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/BackgroundViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/BackgroundViewModel.kt
@@ -18,6 +18,8 @@
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
@@ -39,10 +41,9 @@
_background.update { false }
}
- class BackgroundViewModelFactory : ViewModelProvider.Factory {
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return BackgroundViewModel() as T
+ companion object {
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer { BackgroundViewModel() }
}
}
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollConfirmationViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollConfirmationViewModel.kt
index d9b31d7..5ce2ed7 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollConfirmationViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollConfirmationViewModel.kt
@@ -16,14 +16,17 @@
package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel
+import android.util.Log
+import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
import kotlinx.coroutines.flow.Flow
-/**
- * Models the UI state for [FingerprintEnrollConfirmationV2Fragment]
- */
+/** Models the UI state for [FingerprintEnrollConfirmationV2Fragment] */
class FingerprintEnrollConfirmationViewModel(
private val navigationViewModel: FingerprintNavigationViewModel,
fingerprintInteractor: FingerprintManagerInteractor,
@@ -50,18 +53,20 @@
navigationViewModel.update(FingerprintAction.ADD_ANOTHER, navStep, "onAddAnotherButtonClicked")
}
- class FingerprintEnrollConfirmationViewModelFactory(
- private val navigationViewModel: FingerprintNavigationViewModel,
- private val fingerprintInteractor: FingerprintManagerInteractor,
- ) : ViewModelProvider.Factory {
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return FingerprintEnrollConfirmationViewModel(navigationViewModel, fingerprintInteractor) as T
- }
- }
-
companion object {
private const val TAG = "FingerprintEnrollConfirmationViewModel"
private val navStep = FingerprintNavigationStep.Confirmation::class
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication =
+ this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment
+ val provider = ViewModelProvider(this[VIEW_MODEL_STORE_OWNER_KEY]!!)
+ FingerprintEnrollConfirmationViewModel(
+ provider[FingerprintNavigationViewModel::class],
+ biometricEnvironment!!.fingerprintManagerInteractor,
+ )
+ }
+ }
}
}
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 bbe3cfd..a2accb7 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
@@ -16,14 +16,15 @@
package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel
-import android.util.Log
+import android.hardware.fingerprint.FingerprintEnrollOptions
+import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
-import com.android.systemui.biometrics.shared.model.FingerprintSensor
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.transformLatest
import kotlinx.coroutines.flow.update
@@ -69,23 +70,24 @@
val enrollFlow =
enrollFlowShouldBeRunning.transformLatest {
if (it) {
- fingerprintEnrollViewModel.enrollFlow.collect { event ->
- emit(event) }
+ fingerprintEnrollViewModel.enrollFlow.collect { event -> emit(event) }
}
}
- class FingerprintEnrollEnrollingViewModelFactory(
- private val fingerprintEnrollViewModel: FingerprintEnrollViewModel,
- private val backgroundViewModel: BackgroundViewModel,
- ) : ViewModelProvider.Factory {
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return FingerprintEnrollEnrollingViewModel(fingerprintEnrollViewModel, backgroundViewModel)
- as T
- }
+ /** Indicates enrollment to start */
+ fun enroll(enrollOptions: FingerprintEnrollOptions) {
+ fingerprintEnrollViewModel.enroll(enrollOptions)
}
companion object {
- private val TAG = "FingerprintEnrollEnrollingViewModel"
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val provider = ViewModelProvider(this[VIEW_MODEL_STORE_OWNER_KEY]!!)
+ FingerprintEnrollEnrollingViewModel(
+ provider[FingerprintEnrollViewModel::class],
+ provider[BackgroundViewModel::class],
+ )
+ }
+ }
}
}
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 ddbf1cb..3568dbd 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
@@ -16,9 +16,14 @@
package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel
+import android.hardware.fingerprint.FingerprintEnrollOptions
+import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
import com.android.settings.biometrics.fingerprint2.domain.interactor.AccessibilityInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractor
import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractor
@@ -43,10 +48,10 @@
private val fingerprintEnrollViewModel: FingerprintEnrollViewModel,
private val gatekeeperViewModel: FingerprintGatekeeperViewModel,
backgroundViewModel: BackgroundViewModel,
+ fingerprintFlowViewModel: FingerprintFlowViewModel,
accessibilityInteractor: AccessibilityInteractor,
foldStateInteractor: FoldStateInteractor,
orientationInteractor: OrientationInteractor,
- fingerprintFlowViewModel: FingerprintFlowViewModel,
fingerprintManagerInteractor: FingerprintManagerInteractor,
) : ViewModel() {
@@ -64,6 +69,7 @@
val showPrimaryButton: Flow<Boolean> = _isUdfps.filter { it }
private val _showSfpsLottie = _isSfps.filter { it }
+
/** Represents the stream of showing sfps lottie and the information Pair(isFolded, rotation). */
val sfpsLottieInfo: Flow<Pair<Boolean, Int>> =
combineTransform(
@@ -75,6 +81,7 @@
}
private val _showUdfpsLottie = _isUdfps.filter { it }
+
/** Represents the stream of showing udfps lottie and whether accessibility is enabled. */
val udfpsLottieInfo: Flow<Boolean> =
_showUdfpsLottie.combine(accessibilityInteractor.isAccessibilityEnabled) {
@@ -87,11 +94,13 @@
val showRfpsAnimation: Flow<Boolean> = _isRearSfps.filter { it }
private val _showErrorDialog: MutableStateFlow<Pair<Int, Boolean>?> = MutableStateFlow(null)
+
/** Represents the stream of showing error dialog. */
val showErrorDialog = _showErrorDialog.filterNotNull()
private var _didTryEducation = false
private var _education: MutableStateFlow<Boolean> = MutableStateFlow(false)
+
/** Indicates if the education flow should be running. */
private val educationFlowShouldBeRunning: Flow<Boolean> =
_education.combine(backgroundViewModel.background) { shouldRunEducation, isInBackground ->
@@ -167,6 +176,11 @@
_education.update { false }
}
+ /** Indicates enrollment to start */
+ fun enroll(enrollOptions: FingerprintEnrollOptions) {
+ fingerprintEnrollViewModel.enroll(enrollOptions)
+ }
+
/** Proceed to EnrollEnrolling page. */
fun proceedToEnrolling() {
stopEducation()
@@ -182,36 +196,29 @@
)
}
- class FingerprintEnrollFindSensorViewModelFactory(
- private val navigationViewModel: FingerprintNavigationViewModel,
- private val fingerprintEnrollViewModel: FingerprintEnrollViewModel,
- private val gatekeeperViewModel: FingerprintGatekeeperViewModel,
- private val backgroundViewModel: BackgroundViewModel,
- private val accessibilityInteractor: AccessibilityInteractor,
- private val foldStateInteractor: FoldStateInteractor,
- private val orientationInteractor: OrientationInteractor,
- private val fingerprintFlowViewModel: FingerprintFlowViewModel,
- private val fingerprintManagerInteractor: FingerprintManagerInteractor,
- ) : ViewModelProvider.Factory {
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return FingerprintEnrollFindSensorViewModel(
- navigationViewModel,
- fingerprintEnrollViewModel,
- gatekeeperViewModel,
- backgroundViewModel,
- accessibilityInteractor,
- foldStateInteractor,
- orientationInteractor,
- fingerprintFlowViewModel,
- fingerprintManagerInteractor,
- )
- as T
- }
- }
-
companion object {
private const val TAG = "FingerprintEnrollFindSensorViewModel"
private val navStep = Education::class
+
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication =
+ this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment!!
+ val provider = ViewModelProvider(this[VIEW_MODEL_STORE_OWNER_KEY]!!)
+
+ FingerprintEnrollFindSensorViewModel(
+ provider[FingerprintNavigationViewModel::class],
+ provider[FingerprintEnrollViewModel::class],
+ provider[FingerprintGatekeeperViewModel::class],
+ provider[BackgroundViewModel::class],
+ provider[FingerprintFlowViewModel::class],
+ biometricEnvironment.accessibilityInteractor,
+ biometricEnvironment.foldStateInteractor,
+ biometricEnvironment.orientationInteractor,
+ biometricEnvironment.fingerprintManagerInteractor,
+ )
+ }
+ }
}
}
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
index 3bf003c..6ec2048 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollIntroViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollIntroViewModel.kt
@@ -16,8 +16,12 @@
package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel
+import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
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
@@ -27,8 +31,8 @@
/** A view model for fingerprint enroll introduction. */
class FingerprintEnrollIntroViewModel(
val navigationViewModel: FingerprintNavigationViewModel,
- private val fingerprintFlowViewModel: FingerprintFlowViewModel,
- private val fingerprintManagerInteractor: FingerprintManagerInteractor,
+ fingerprintFlowViewModel: FingerprintFlowViewModel,
+ fingerprintManagerInteractor: FingerprintManagerInteractor,
) : ViewModel() {
/** Represents a stream of [FingerprintSensor] */
@@ -51,25 +55,21 @@
)
}
- 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"
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication =
+ this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment
+ val provider = ViewModelProvider(this[VIEW_MODEL_STORE_OWNER_KEY]!!)
+ FingerprintEnrollIntroViewModel(
+ provider[FingerprintNavigationViewModel::class],
+ provider[FingerprintFlowViewModel::class],
+ biometricEnvironment!!.fingerprintManagerInteractor,
+ )
+ }
+ }
}
}
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 c27808d..2669b8b 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
@@ -15,9 +15,15 @@
*/
package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel
+import android.hardware.fingerprint.FingerprintEnrollOptions
+import androidx.lifecycle.VIEW_MODEL_STORE_OWNER_KEY
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
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
@@ -25,12 +31,14 @@
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.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.transformLatest
+import kotlinx.coroutines.flow.update
/** Represents all of the fingerprint information needed for a fingerprint enrollment process. */
class FingerprintEnrollViewModel(
@@ -55,6 +63,8 @@
}
}
+ private val enrollOptions: MutableStateFlow<FingerprintEnrollOptions?> = MutableStateFlow(null)
+
/** Represents the stream of [FingerprintSensorType] */
val sensorType: Flow<FingerprintSensorType?> =
fingerprintManagerInteractor.sensorPropertiesInternal.filterNotNull().map { it.sensorType }
@@ -66,16 +76,23 @@
* This flow should be the only flow which calls enroll().
*/
val _enrollFlow: Flow<FingerEnrollState> =
- combine(gatekeeperViewModel.gatekeeperInfo, _enrollReason) { hardwareAuthToken, enrollReason ->
- Pair(hardwareAuthToken, enrollReason)
+ combine(gatekeeperViewModel.gatekeeperInfo, _enrollReason, enrollOptions) {
+ hardwareAuthToken,
+ enrollReason,
+ enrollOptions ->
+ Triple(hardwareAuthToken, enrollReason, enrollOptions)
}
.transformLatest {
/** [transformLatest] is used as we want to make sure to cancel previous API call. */
- (hardwareAuthToken, enrollReason) ->
- if (hardwareAuthToken is GatekeeperInfo.GatekeeperPasswordInfo && enrollReason != null) {
- fingerprintManagerInteractor.enroll(hardwareAuthToken.token, enrollReason).collect {
- emit(it)
- }
+ (hardwareAuthToken, enrollReason, enrollOptions) ->
+ if (
+ hardwareAuthToken is GatekeeperInfo.GatekeeperPasswordInfo &&
+ enrollReason != null &&
+ enrollOptions != null
+ ) {
+ fingerprintManagerInteractor
+ .enroll(hardwareAuthToken.token, enrollReason, enrollOptions)
+ .collect { emit(it) }
}
}
.shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 0)
@@ -108,14 +125,23 @@
}
}
- class FingerprintEnrollViewModelFactory(
- val interactor: FingerprintManagerInteractor,
- val gatekeeperViewModel: FingerprintGatekeeperViewModel,
- val navigationViewModel: FingerprintNavigationViewModel,
- ) : ViewModelProvider.Factory {
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return FingerprintEnrollViewModel(interactor, gatekeeperViewModel, navigationViewModel) as T
+ /** Starts enrollment. */
+ fun enroll(options: FingerprintEnrollOptions) {
+ enrollOptions.update { options }
+ }
+
+ companion object {
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication = this[APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment
+ val provider = ViewModelProvider(this[VIEW_MODEL_STORE_OWNER_KEY]!!)
+ FingerprintEnrollViewModel(
+ biometricEnvironment!!.fingerprintManagerInteractor,
+ provider[FingerprintGatekeeperViewModel::class],
+ provider[FingerprintNavigationViewModel::class],
+ )
+ }
}
}
}
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
index f076524..394c272 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintFlowViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintFlowViewModel.kt
@@ -19,21 +19,28 @@
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintFlow
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.update
-class FingerprintFlowViewModel(private val fingerprintFlowType: FingerprintFlow) : ViewModel() {
- val fingerprintFlow: Flow<FingerprintFlow> =
- flowOf(fingerprintFlowType).shareIn(viewModelScope, SharingStarted.Eagerly, 1)
+class FingerprintFlowViewModel() : ViewModel() {
+ val _mutableFingerprintFlow: MutableStateFlow<FingerprintFlow?> = MutableStateFlow(null)
+ val fingerprintFlow: Flow<FingerprintFlow?> =
+ _mutableFingerprintFlow.shareIn(viewModelScope, SharingStarted.Eagerly, 1)
- class FingerprintFlowViewModelFactory(val flowType: FingerprintFlow) : ViewModelProvider.Factory {
+ /** Used to set the fingerprint flow type */
+ fun updateFlowType(fingerprintFlowType: FingerprintFlow) {
+ _mutableFingerprintFlow.update { fingerprintFlowType }
+ }
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return FingerprintFlowViewModel(flowType) as T
+ companion object {
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer { FingerprintFlowViewModel() }
}
}
}
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 322be6a..b5be165 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,6 +21,9 @@
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -47,12 +50,10 @@
* in as a parameter to this class.
*/
class FingerprintGatekeeperViewModel(
- theGatekeeperInfo: GatekeeperInfo?,
- private val fingerprintManagerInteractor: FingerprintManagerInteractor,
+ private val fingerprintManagerInteractor: FingerprintManagerInteractor
) : ViewModel() {
- private var _gatekeeperInfo: MutableStateFlow<GatekeeperInfo?> =
- MutableStateFlow(theGatekeeperInfo)
+ private var _gatekeeperInfo: MutableStateFlow<GatekeeperInfo?> = MutableStateFlow(null)
/** The gatekeeper info for fingerprint enrollment. */
val gatekeeperInfo: Flow<GatekeeperInfo?> = _gatekeeperInfo.asStateFlow()
@@ -61,26 +62,27 @@
val hasValidGatekeeperInfo: Flow<Boolean> =
gatekeeperInfo.map { it is GatekeeperInfo.GatekeeperPasswordInfo }
- private var _credentialConfirmed: MutableStateFlow<Boolean?> = MutableStateFlow(null)
- val credentialConfirmed: Flow<Boolean?> = _credentialConfirmed.asStateFlow()
-
private var countDownTimer: CountDownTimer? = null
/** Timeout of 15 minutes for a generated challenge */
private val TIMEOUT: Long = 15 * 60 * 1000
/** Called after a confirm device credential attempt has been made. */
- fun onConfirmDevice(wasSuccessful: Boolean, theGatekeeperPasswordHandle: Long?) {
+ fun onConfirmDevice(
+ wasSuccessful: Boolean,
+ theGatekeeperPasswordHandle: Long?,
+ shouldStartTimer: Boolean = true,
+ ) {
if (!wasSuccessful) {
Log.d(TAG, "confirmDevice failed")
_gatekeeperInfo.update { GatekeeperInfo.Invalid }
- _credentialConfirmed.update { false }
} else {
viewModelScope.launch {
val res = fingerprintManagerInteractor.generateChallenge(theGatekeeperPasswordHandle!!)
_gatekeeperInfo.update { GatekeeperInfo.GatekeeperPasswordInfo(res.second, res.first) }
- _credentialConfirmed.update { true }
- startTimeout()
+ if (shouldStartTimer) {
+ startTimeout()
+ }
}
}
}
@@ -97,19 +99,9 @@
}
}
- 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]
@@ -121,5 +113,14 @@
}
return GatekeeperInfo.GatekeeperPasswordInfo(token, challenge)
}
+
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication =
+ this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment
+ FingerprintGatekeeperViewModel(biometricEnvironment!!.fingerprintManagerInteractor)
+ }
+ }
}
}
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
index 131f5bb..caf7d2a 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintNavigationViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/FingerprintNavigationViewModel.kt
@@ -20,7 +20,11 @@
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import com.android.settings.SettingsApplication
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.Finish
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.TransitionStep
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.UiStep
@@ -28,39 +32,40 @@
import kotlin.reflect.KClass
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.combineTransform
import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.stateIn
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() {
+class FingerprintNavigationViewModel(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))
- }
+ private val _flowInternal: MutableStateFlow<FingerprintFlow?> = MutableStateFlow(null)
+ private val _hasConfirmedDeviceCredential: MutableStateFlow<Boolean> = MutableStateFlow(false)
+ private val _navStateInternal: StateFlow<NavigationState?> =
+ combine(
+ _flowInternal,
+ _hasConfirmedDeviceCredential,
+ fingerprintManagerInteractor.sensorPropertiesInternal,
+ ) { flow, hasConfirmed, sensorType ->
+ if (flow == null || sensorType == null) {
+ return@combine null
}
- .collect { navState -> _navStateInternal.update { navState } }
- }
- }
+ return@combine NavigationState(flow, hasConfirmed, sensorType)
+ }
+ .stateIn(viewModelScope, SharingStarted.Eagerly, null)
- private var _currentStep = MutableStateFlow<FingerprintNavigationStep?>(step)
+ private var _currentStep =
+ MutableStateFlow<FingerprintNavigationStep?>(FingerprintNavigationStep.Init)
private var _navigateTo: MutableStateFlow<UiStep?> = MutableStateFlow(null)
val navigateTo: Flow<UiStep?> = _navigateTo.asStateFlow()
@@ -85,6 +90,16 @@
/** This indicates what screen should currently be presenting to the user. */
val currentScreen: Flow<UiStep?> = _currentScreen.asStateFlow()
+ /** Updates the type of flow the navigation should begin */
+ fun updateFingerprintFlow(flow: FingerprintFlow) {
+ _flowInternal.update { flow }
+ }
+
+ /** Indicates if we have confirmed device credential */
+ fun hasConfirmedDeviceCredential(hasConfirmedDeviceCredential: Boolean) {
+ _hasConfirmedDeviceCredential.update { hasConfirmedDeviceCredential }
+ }
+
/** See [updateInternal] for more details */
fun update(action: FingerprintAction, caller: KClass<*>, debugStr: String) {
Log.d(TAG, "$caller.update($action) $debugStr")
@@ -122,26 +137,15 @@
}
}
- 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"
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ val settingsApplication =
+ this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as SettingsApplication
+ val biometricEnvironment = settingsApplication.biometricEnvironment
+ FingerprintNavigationViewModel(biometricEnvironment!!.fingerprintManagerInteractor)
+ }
+ }
}
}
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 bc9703d..ddef0df 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
@@ -18,6 +18,8 @@
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -36,11 +38,9 @@
_hasReadConsentScreen.update { true }
}
- class FingerprintScrollViewModelFactory : ViewModelProvider.Factory {
-
- @Suppress("UNCHECKED_CAST")
- override fun <T : ViewModel> create(modelClass: Class<T>): T {
- return FingerprintScrollViewModel() as T
+ companion object {
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer { FingerprintScrollViewModel() }
}
}
}
diff --git a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/TransitionViewModel.kt b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/TransitionViewModel.kt
index 8fb7291..d1a9326 100644
--- a/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/TransitionViewModel.kt
+++ b/src/com/android/settings/biometrics/fingerprint2/ui/enrollment/viewmodel/TransitionViewModel.kt
@@ -18,24 +18,15 @@
/** Indicates the type of transitions that can occur between fragments */
sealed class Transition {
- /**
- * Indicates the new fragment should slide in from the left side
- */
+ /** Indicates the new fragment should slide in from the left side */
data object EnterFromLeft : Transition()
- /**
- * Indicates the new fragment should slide in from the right side
- */
+ /** Indicates the new fragment should slide in from the right side */
data object EnterFromRight : Transition()
- /**
- * Indicates the old fragment should slide out to the left side
- */
+ /** Indicates the old fragment should slide out to the left side */
data object ExitToLeft : Transition()
- /**
- * Indicates the old fragment should slide out to the right side
- */
+ /** Indicates the old fragment should slide out to the right side */
data object ExitToRight : Transition()
}
-
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 540e5ee..c71062f 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
@@ -54,29 +54,40 @@
challenge: Long?,
challengeToken: ByteArray?,
)
+
/** Helper to launch an add fingerprint request */
fun launchAddFingerprint(userId: Int, challengeToken: ByteArray?)
+
/**
* Helper function that will try and launch confirm lock, if that fails we will prompt user to
* choose a PIN/PATTERN/PASS.
*/
fun launchConfirmOrChooseLock(userId: Int)
+
/** Used to indicate that FingerprintSettings is finished. */
fun finish()
+
/** Indicates what result should be set for the returning callee */
fun setResultExternal(resultCode: Int)
+
/** Indicates the settings UI should be shown */
fun showSettings(enrolledFingerprints: List<FingerprintData>)
+
/** Updates the add fingerprints preference */
fun updateAddFingerprintsPreference(canEnroll: Boolean, maxFingerprints: Int)
+
/** Updates the sfps fingerprints preference */
fun updateSfpsPreference(isSfpsPrefVisible: Boolean)
+
/** Indicates that a user has been locked out */
fun userLockout(authAttemptViewModel: FingerprintAuthAttemptModel.Error)
+
/** Indicates a fingerprint preference should be highlighted */
suspend fun highlightPref(fingerId: Int)
+
/** Indicates a user should be prompted to delete a fingerprint */
suspend fun askUserToDeleteDialog(fingerprintViewModel: FingerprintData): Boolean
+
/** Indicates a user should be asked to renae ma dialog */
suspend fun askUserToRenameDialog(
fingerprintViewModel: FingerprintData
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 7900ed7..4c3773b 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,14 +45,13 @@
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.domain.interactor.FingerprintEnrollInteractorImpl
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepositoryImpl
+import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintEnrollInteractorImpl
import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
import com.android.settings.biometrics.fingerprint2.domain.interactor.PressToAuthInteractorImpl
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.enrollment.modules.enrolling.common.util.toFingerprintEnrollOptions
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
@@ -227,7 +226,6 @@
val fingerprintEnrollStateRepository =
FingerprintEnrollInteractorImpl(
requireContext().applicationContext,
- intent.toFingerprintEnrollOptions(),
fingerprintManager,
Settings,
)
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 00b91a8..8a694ae 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
@@ -52,7 +52,7 @@
_nextStep.update { LaunchConfirmDeviceCredential(userId) }
} else {
viewModelScope.launch {
- if (fingerprintManagerInteractor.enrolledFingerprints.last().isEmpty()) {
+ if (fingerprintManagerInteractor.enrolledFingerprints.last()?.isEmpty() == true) {
_nextStep.update { EnrollFirstFingerprint(userId, null, challenge, token) }
} else {
showSettingsHelper()
@@ -149,7 +149,7 @@
private suspend fun launchEnrollNextStep(gateKeeperPasswordHandle: Long?) {
fingerprintManagerInteractor.enrolledFingerprints.collect {
- if (it.isEmpty()) {
+ if (it?.isEmpty() == true) {
_nextStep.update { EnrollFirstFingerprint(userId, gateKeeperPasswordHandle, null, null) }
} else {
viewModelScope.launch(backgroundDispatcher) {
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 80bbb43..cf8c527 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
@@ -74,7 +74,7 @@
/** Represents the stream of visibility of sfps preference. */
val isSfpsPrefVisible: Flow<Boolean> =
_enrolledFingerprints.filterOnlyWhenSettingsIsShown().transform {
- emit(fingerprintManagerInteractor.hasSideFps() && !it.isNullOrEmpty())
+ emit(fingerprintManagerInteractor.hasSideFps() == true && !it.isNullOrEmpty())
}
private val _isShowingDialog: MutableStateFlow<PreferenceViewModel?> = MutableStateFlow(null)
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 e30819b..9286880 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
@@ -67,7 +67,6 @@
private val gatekeeperViewModel =
FingerprintGatekeeperViewModel(
- GatekeeperInfo.GatekeeperPasswordInfo(byteArrayOf(1, 2, 3), 100L),
interactor
)
private val backgroundDispatcher = StandardTestDispatcher()
@@ -86,13 +85,10 @@
.toFingerprintSensor()
var enrollFlow = Default
- val flowViewModel = FingerprintFlowViewModel(enrollFlow)
+ val flowViewModel = FingerprintFlowViewModel()
private val navigationViewModel =
FingerprintNavigationViewModel(
- Introduction(),
- false,
- flowViewModel,
interactor
)
@@ -124,6 +120,11 @@
}
}
+ gatekeeperViewModel.onConfirmDevice(true, 100L, false)
+ flowViewModel.updateFlowType(enrollFlow)
+ navigationViewModel.hasConfirmedDeviceCredential(true)
+ navigationViewModel.updateFingerprintFlow(enrollFlow)
+
fragmentScenario =
launchFragmentInContainer(Bundle(), R.style.SudThemeGlif) {
FingerprintEnrollIntroV2Fragment(factory)
diff --git a/tests/screenshot/assets/robolectric/fp_enroll_confirmation.png b/tests/screenshot/assets/robolectric/rfps_enroll_confirmation.png
similarity index 100%
rename from tests/screenshot/assets/robolectric/fp_enroll_confirmation.png
rename to tests/screenshot/assets/robolectric/rfps_enroll_confirmation.png
Binary files differ
diff --git a/tests/screenshot/assets/robolectric/fp_enroll_enrolling.png b/tests/screenshot/assets/robolectric/rfps_enroll_enrolling.png
similarity index 100%
rename from tests/screenshot/assets/robolectric/fp_enroll_enrolling.png
rename to tests/screenshot/assets/robolectric/rfps_enroll_enrolling.png
Binary files differ
diff --git a/tests/screenshot/assets/robolectric/fp_enroll_find_sensor.png b/tests/screenshot/assets/robolectric/rfps_enroll_find_sensor.png
similarity index 100%
rename from tests/screenshot/assets/robolectric/fp_enroll_find_sensor.png
rename to tests/screenshot/assets/robolectric/rfps_enroll_find_sensor.png
Binary files differ
diff --git a/tests/screenshot/assets/robolectric/fp_enroll_intro.png b/tests/screenshot/assets/robolectric/rfps_enroll_intro.png
similarity index 100%
rename from tests/screenshot/assets/robolectric/fp_enroll_intro.png
rename to tests/screenshot/assets/robolectric/rfps_enroll_intro.png
Binary files differ
diff --git a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
index 652afa0..19433f3 100644
--- a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
+++ b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/Injector.kt
@@ -42,7 +42,6 @@
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.testutils2.FakeFingerprintManagerInteractor
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
import kotlinx.coroutines.flow.Flow
@@ -95,23 +94,27 @@
override fun getRotationFromDefault(rotation: Int): Int = rotation
}
- var gatekeeperViewModel =
- FingerprintGatekeeperViewModel(
- GatekeeperInfo.GatekeeperPasswordInfo(byteArrayOf(1, 2, 3), 100L),
- interactor,
- )
+ var gatekeeperViewModel = FingerprintGatekeeperViewModel(fingerprintManagerInteractor)
- val flowViewModel = FingerprintFlowViewModel(enrollFlow)
+ val flowViewModel = FingerprintFlowViewModel()
- var navigationViewModel = FingerprintNavigationViewModel(step, true, flowViewModel, interactor)
+ var navigationViewModel = FingerprintNavigationViewModel(fingerprintManagerInteractor)
var fingerprintViewModel =
- FingerprintEnrollIntroViewModel(navigationViewModel, flowViewModel, interactor)
+ FingerprintEnrollIntroViewModel(
+ navigationViewModel,
+ flowViewModel,
+ fingerprintManagerInteractor,
+ )
var fingerprintScrollViewModel = FingerprintScrollViewModel()
var backgroundViewModel = BackgroundViewModel()
var fingerprintEnrollViewModel =
- FingerprintEnrollViewModel(interactor, gatekeeperViewModel, navigationViewModel)
+ FingerprintEnrollViewModel(
+ fingerprintManagerInteractor,
+ gatekeeperViewModel,
+ navigationViewModel,
+ )
var fingerprintEnrollEnrollingViewModel =
FingerprintEnrollEnrollingViewModel(fingerprintEnrollViewModel, backgroundViewModel)
@@ -122,11 +125,11 @@
fingerprintEnrollEnrollingViewModel,
navigationViewModel,
orientationInteractor,
- interactor,
+ fingerprintManagerInteractor,
)
val fingerprintEnrollConfirmationViewModel =
- FingerprintEnrollConfirmationViewModel(navigationViewModel, interactor)
+ FingerprintEnrollConfirmationViewModel(navigationViewModel, fingerprintManagerInteractor)
var fingerprintFindSensorViewModel =
FingerprintEnrollFindSensorViewModel(
@@ -134,11 +137,11 @@
fingerprintEnrollViewModel,
gatekeeperViewModel,
backgroundViewModel,
+ flowViewModel,
accessibilityInteractor,
foldStateInteractor,
orientationInteractor,
- flowViewModel,
- interactor,
+ fingerprintManagerInteractor,
)
val factory =
@@ -166,12 +169,16 @@
init {
fingerprintEnrollViewModel.sensorTypeCached = fingerprintSensor.sensorType
+ gatekeeperViewModel.onConfirmDevice(true, 100L)
+ navigationViewModel.updateFingerprintFlow(enrollFlow)
+ navigationViewModel.hasConfirmedDeviceCredential(true)
+ flowViewModel.updateFlowType(enrollFlow)
}
companion object {
private val Phone = DisplaySpec("phone", width = 1080, height = 2340, densityDpi = 420)
private const val screenshotPath = "/settings_screenshots"
- val interactor = FakeFingerprintManagerInteractor()
+ val fingerprintManagerInteractor = FakeFingerprintManagerInteractor()
fun BiometricFragmentScreenShotRule() =
FragmentScreenshotTestRule(
diff --git a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollConfirmationScreenshotTest.kt b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollConfirmationScreenshotTest.kt
similarity index 86%
rename from tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollConfirmationScreenshotTest.kt
rename to tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollConfirmationScreenshotTest.kt
index 28f4fbe..6c49a0c 100644
--- a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollConfirmationScreenshotTest.kt
+++ b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollConfirmationScreenshotTest.kt
@@ -17,7 +17,6 @@
package com.android.settings.tests.screenshot.biometrics.fingerprint.fragment
import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.platform.app.InstrumentationRegistry
import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollConfirmationV2Fragment
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
import com.android.settings.tests.screenshot.biometrics.fingerprint.Injector
@@ -28,17 +27,15 @@
import platform.test.screenshot.ViewScreenshotTestRule.Mode
@RunWith(AndroidJUnit4::class)
-class FingerprintEnrollConfirmationScreenshotTest {
+class RfpsEnrollConfirmationScreenshotTest {
private val injector: Injector = Injector(FingerprintNavigationStep.Confirmation)
- @Rule
- @JvmField
- var rule: FragmentScreenshotTestRule = Injector.BiometricFragmentScreenShotRule()
+ @Rule @JvmField var rule: FragmentScreenshotTestRule = Injector.BiometricFragmentScreenShotRule()
@Test
fun testConfirmation() {
rule.screenshotTest(
- "fp_enroll_confirmation",
+ "rfps_enroll_confirmation",
Mode.MatchSize,
FingerprintEnrollConfirmationV2Fragment(injector.factory),
)
diff --git a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollEnrollingScreenshotTest.kt b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollEnrollingScreenshotTest.kt
similarity index 86%
rename from tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollEnrollingScreenshotTest.kt
rename to tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollEnrollingScreenshotTest.kt
index 215e76f..48ff59b 100644
--- a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollEnrollingScreenshotTest.kt
+++ b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollEnrollingScreenshotTest.kt
@@ -27,14 +27,14 @@
import platform.test.screenshot.ViewScreenshotTestRule.Mode
@RunWith(AndroidJUnit4::class)
-class FingerprintEnrollEnrollingScreenshotTest {
+class RfpsEnrollEnrollingScreenshotTest {
private val injector: Injector =
- Injector(FingerprintNavigationStep.Enrollment(Injector.interactor.sensorProp))
+ Injector(FingerprintNavigationStep.Enrollment(Injector.fingerprintManagerInteractor.sensorProp))
@Rule @JvmField var rule: FragmentScreenshotTestRule = BiometricFragmentScreenShotRule()
@Test
fun testEnrollEnrolling() {
- rule.screenshotTest("fp_enroll_enrolling", Mode.MatchSize, RFPSEnrollFragment(injector.factory))
+ rule.screenshotTest("rfps_enroll_enrolling", Mode.MatchSize, RFPSEnrollFragment(injector.factory))
}
}
diff --git a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollFindSensorScreenshotTest.kt b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollFindSensorScreenshotTest.kt
index 594aade..01cc0e6 100644
--- a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollFindSensorScreenshotTest.kt
+++ b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollFindSensorScreenshotTest.kt
@@ -31,10 +31,6 @@
@Test
fun testEnrollFindSensor() {
- rule.screenshotTest(
- "fp_enroll_find_sensor",
- Mode.MatchSize,
- RfpsEnrollFindSensorFragment(),
- )
+ rule.screenshotTest("rfps_enroll_find_sensor", Mode.MatchSize, RfpsEnrollFindSensorFragment())
}
}
diff --git a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollIntroScreenshotTest.kt b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollIntroScreenshotTest.kt
similarity index 89%
rename from tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollIntroScreenshotTest.kt
rename to tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollIntroScreenshotTest.kt
index 68d600b..128d540 100644
--- a/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/FingerprintEnrollIntroScreenshotTest.kt
+++ b/tests/screenshot/src/com/android/settings/tests/screenshot/biometrics/fingerprint/fragment/RfpsEnrollIntroScreenshotTest.kt
@@ -27,17 +27,15 @@
import platform.test.screenshot.ViewScreenshotTestRule.Mode
@RunWith(AndroidJUnit4::class)
-class FingerprintEnrollIntroScreenshotTest {
+class RfpsEnrollIntroScreenshotTest {
private val injector: Injector = Injector(FingerprintNavigationStep.Introduction())
- @Rule
- @JvmField
- var rule: FragmentScreenshotTestRule = Injector.BiometricFragmentScreenShotRule()
+ @Rule @JvmField var rule: FragmentScreenshotTestRule = Injector.BiometricFragmentScreenShotRule()
@Test
fun testEnrollIntro() {
rule.screenshotTest(
- "fp_enroll_intro",
+ "rfps_enroll_intro",
Mode.MatchSize,
FingerprintEnrollIntroV2Fragment(injector.factory),
)
diff --git a/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt b/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
index b39f0d1..52df724 100644
--- a/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
+++ b/tests/shared/src/com/android/settings/testutils2/FakeFingerprintManagerInteractor.kt
@@ -19,6 +19,7 @@
import android.hardware.biometrics.ComponentInfoInternal
import android.hardware.biometrics.SensorLocationInternal
import android.hardware.biometrics.SensorProperties
+import android.hardware.fingerprint.FingerprintEnrollOptions
import android.hardware.fingerprint.FingerprintSensorProperties
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
@@ -78,6 +79,7 @@
override suspend fun enroll(
hardwareAuthToken: ByteArray?,
enrollReason: EnrollReason,
+ fingerprintEnrollOptions: FingerprintEnrollOptions
): Flow<FingerEnrollState> = flowOf(*enrollStateViewModel.toTypedArray())
override suspend fun removeFingerprint(fp: FingerprintData): Boolean {
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 900afd1..67a5957 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
@@ -109,12 +109,7 @@
fingerprintManager,
fingerprintSensorRepository,
gateKeeperPasswordProvider,
- FingerprintEnrollInteractorImpl(
- context,
- FingerprintEnrollOptions.Builder().build(),
- fingerprintManager,
- Default,
- ),
+ FingerprintEnrollInteractorImpl(context, fingerprintManager, Default),
)
}
@@ -135,7 +130,7 @@
whenever(fingerprintManager.getEnrolledFingerprints(anyInt())).thenReturn(fingerprintList)
val list = underTest.enrolledFingerprints.last()
- assertThat(list.size).isEqualTo(fingerprintList.size)
+ assertThat(list!!.size).isEqualTo(fingerprintList.size)
val actual = list[0]
assertThat(actual.name).isEqualTo(expected.name)
assertThat(actual.fingerId).isEqualTo(expected.biometricId)
@@ -318,7 +313,11 @@
testScope.runTest {
val token = byteArrayOf(5, 3, 2)
var result: FingerEnrollState? = null
- val job = launch { underTest.enroll(token, EnrollReason.FindSensor).collect { result = it } }
+ val job = launch {
+ underTest
+ .enroll(token, EnrollReason.FindSensor, FingerprintEnrollOptions.Builder().build())
+ .collect { result = it }
+ }
val enrollCallback: ArgumentCaptor<FingerprintManager.EnrollmentCallback> = argumentCaptor()
runCurrent()
@@ -343,7 +342,11 @@
testScope.runTest {
val token = byteArrayOf(5, 3, 2)
var result: FingerEnrollState? = null
- val job = launch { underTest.enroll(token, EnrollReason.FindSensor).collect { result = it } }
+ val job = launch {
+ underTest
+ .enroll(token, EnrollReason.FindSensor, FingerprintEnrollOptions.Builder().build())
+ .collect { result = it }
+ }
val enrollCallback: ArgumentCaptor<FingerprintManager.EnrollmentCallback> = argumentCaptor()
runCurrent()
@@ -368,7 +371,11 @@
testScope.runTest {
val token = byteArrayOf(5, 3, 2)
var result: FingerEnrollState? = null
- val job = launch { underTest.enroll(token, EnrollReason.FindSensor).collect { result = it } }
+ val job = launch {
+ underTest
+ .enroll(token, EnrollReason.FindSensor, FingerprintEnrollOptions.Builder().build())
+ .collect { result = it }
+ }
val enrollCallback: ArgumentCaptor<FingerprintManager.EnrollmentCallback> = argumentCaptor()
runCurrent()
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 4906e84..9662c39 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
@@ -35,7 +35,6 @@
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
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
import com.android.settings.testutils2.FakeFingerprintManagerInteractor
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
@@ -90,45 +89,20 @@
Dispatchers.setMain(backgroundDispatcher)
fakeFingerprintManagerInteractor = FakeFingerprintManagerInteractor()
- gatekeeperViewModel =
- FingerprintGatekeeperViewModel.FingerprintGatekeeperViewModelFactory(
- null,
- fakeFingerprintManagerInteractor,
- )
- .create(FingerprintGatekeeperViewModel::class.java)
+ gatekeeperViewModel = FingerprintGatekeeperViewModel(fakeFingerprintManagerInteractor)
- val sensor =
- FingerprintSensorPropertiesInternal(
- 0 /* sensorId */,
- SensorProperties.STRENGTH_STRONG,
- 5 /* maxEnrollmentsPerUser */,
- listOf<ComponentInfoInternal>(),
- FingerprintSensorProperties.TYPE_POWER_BUTTON,
- false /* halControlsIllumination */,
- true /* resetLockoutRequiresHardwareAuthToken */,
- listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
- )
- .toFingerprintSensor()
+ val fingerprintFlowViewModel = FingerprintFlowViewModel()
+ fingerprintFlowViewModel.updateFlowType(Default)
+ navigationViewModel = FingerprintNavigationViewModel(fakeFingerprintManagerInteractor)
- val fingerprintFlowViewModel = FingerprintFlowViewModel(Default)
- navigationViewModel =
- FingerprintNavigationViewModel(
- FingerprintNavigationStep.Education(sensor),
- false,
- fingerprintFlowViewModel,
- fakeFingerprintManagerInteractor,
- )
-
- backgroundViewModel =
- BackgroundViewModel.BackgroundViewModelFactory().create(BackgroundViewModel::class.java)
+ backgroundViewModel = BackgroundViewModel()
backgroundViewModel.inForeground()
enrollViewModel =
- FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory(
- fakeFingerprintManagerInteractor,
- gatekeeperViewModel,
- navigationViewModel,
- )
- .create(FingerprintEnrollViewModel::class.java)
+ FingerprintEnrollViewModel(
+ fakeFingerprintManagerInteractor,
+ gatekeeperViewModel,
+ navigationViewModel,
+ )
accessibilityInteractor =
object : AccessibilityInteractor {
override val isAccessibilityEnabled: Flow<Boolean> = flowOf(false)
@@ -145,23 +119,23 @@
orientationInteractor =
object : OrientationInteractor {
override val orientation: Flow<Int> = flowOf(Configuration.ORIENTATION_LANDSCAPE)
- override val rotation: Flow<Int> = flowOf(Surface.ROTATION_0)
- override val rotationFromDefault: Flow<Int> = flowOf(Surface.ROTATION_0)
+ override val rotation: Flow<Int> = flowOf(Surface.ROTATION_0)
+ override val rotationFromDefault: Flow<Int> = flowOf(Surface.ROTATION_0)
+
override fun getRotationFromDefault(rotation: Int): Int = rotation
}
underTest =
- FingerprintEnrollFindSensorViewModel.FingerprintEnrollFindSensorViewModelFactory(
- navigationViewModel,
- enrollViewModel,
- gatekeeperViewModel,
- backgroundViewModel,
- accessibilityInteractor,
- foldStateInteractor,
- orientationInteractor,
- fingerprintFlowViewModel,
- fakeFingerprintManagerInteractor,
- )
- .create(FingerprintEnrollFindSensorViewModel::class.java)
+ FingerprintEnrollFindSensorViewModel(
+ navigationViewModel,
+ enrollViewModel,
+ gatekeeperViewModel,
+ backgroundViewModel,
+ fingerprintFlowViewModel,
+ accessibilityInteractor,
+ foldStateInteractor,
+ orientationInteractor,
+ fakeFingerprintManagerInteractor,
+ )
}
@After
diff --git a/tests/unit/src/com/android/settings/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollConfirmationViewModelTest.kt b/tests/unit/src/com/android/settings/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollConfirmationViewModelTest.kt
index ad025cf..f59d1fc 100644
--- a/tests/unit/src/com/android/settings/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollConfirmationViewModelTest.kt
+++ b/tests/unit/src/com/android/settings/fingerprint2/ui/enrollment/viewmodel/FingerprintEnrollConfirmationViewModelTest.kt
@@ -23,22 +23,23 @@
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.android.settings.biometrics.fingerprint2.lib.model.Default
+import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintAction
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollConfirmationViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintFlowViewModel
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
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.android.systemui.biometrics.shared.model.toFingerprintSensor
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
+import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -53,44 +54,70 @@
@get:Rule val instantTaskRule = InstantTaskExecutorRule()
private var backgroundDispatcher = StandardTestDispatcher()
private var testScope = TestScope(backgroundDispatcher)
- val fingerprintFlowViewModel = FingerprintFlowViewModel(Default)
+ val fingerprintFlowViewModel = FingerprintFlowViewModel()
val fakeFingerprintManagerInteractor = FakeFingerprintManagerInteractor()
lateinit var navigationViewModel: FingerprintNavigationViewModel
lateinit var underTest: FingerprintEnrollConfirmationViewModel
@Before
fun setup() {
- navigationViewModel =
- FingerprintNavigationViewModel(
- FingerprintNavigationStep.Confirmation,
- false,
- fingerprintFlowViewModel,
- fakeFingerprintManagerInteractor,
- )
+ Dispatchers.setMain(backgroundDispatcher)
+ fingerprintFlowViewModel.updateFlowType(Default)
+ navigationViewModel = FingerprintNavigationViewModel(fakeFingerprintManagerInteractor)
underTest =
FingerprintEnrollConfirmationViewModel(navigationViewModel, fakeFingerprintManagerInteractor)
+ navigationViewModel.updateFingerprintFlow(Default)
+ navigationViewModel.hasConfirmedDeviceCredential(true)
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ private fun bringToConfirmation() {
+ navigationViewModel.update(
+ FingerprintAction.NEXT,
+ FingerprintNavigationStep.Introduction::class,
+ "Intro.Test.NEXT",
+ )
+ navigationViewModel.update(
+ FingerprintAction.NEXT,
+ FingerprintNavigationStep.Education::class,
+ "Edu.Test.NEXT",
+ )
+ navigationViewModel.update(
+ FingerprintAction.NEXT,
+ FingerprintNavigationStep.Enrollment::class,
+ "Enrollment.Test.NEXT",
+ )
}
@Test
fun testCanEnrollFingerprints() =
testScope.runTest {
- fakeFingerprintManagerInteractor.sensorProp = FingerprintSensorPropertiesInternal(
- 0 /* sensorId */,
- SensorProperties.STRENGTH_STRONG,
- 5 /* maxEnrollmentsPerUser */,
- listOf<ComponentInfoInternal>(),
- FingerprintSensorProperties.TYPE_POWER_BUTTON,
- false /* halControlsIllumination */,
- true /* resetLockoutRequiresHardwareAuthToken */,
- listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
- )
- .toFingerprintSensor()
+ advanceUntilIdle()
+ bringToConfirmation()
+ fakeFingerprintManagerInteractor.sensorProp =
+ FingerprintSensorPropertiesInternal(
+ 0 /* sensorId */,
+ SensorProperties.STRENGTH_STRONG,
+ 5 /* maxEnrollmentsPerUser */,
+ listOf<ComponentInfoInternal>(),
+ FingerprintSensorProperties.TYPE_POWER_BUTTON,
+ false /* halControlsIllumination */,
+ true /* resetLockoutRequiresHardwareAuthToken */,
+ listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
+ )
+ .toFingerprintSensor()
fakeFingerprintManagerInteractor.enrolledFingerprintsInternal = mutableListOf()
fakeFingerprintManagerInteractor.enrollableFingerprints = 5
var canEnrollFingerprints: Boolean = false
- val job = launch { underTest.isAddAnotherButtonVisible.collect { canEnrollFingerprints = it } }
+ val job = launch {
+ underTest.isAddAnotherButtonVisible.collect { canEnrollFingerprints = it }
+ }
advanceUntilIdle()
assertThat(canEnrollFingerprints).isTrue()
@@ -100,12 +127,14 @@
@Test
fun testNextButtonSendsNextStep() =
testScope.runTest {
+ advanceUntilIdle()
+ bringToConfirmation()
var step: FingerprintNavigationStep.UiStep? = null
val job = launch { navigationViewModel.navigateTo.collect { step = it } }
underTest.onNextButtonClicked()
- runCurrent()
+ advanceUntilIdle()
assertThat(step).isNull()
job.cancel()
@@ -114,14 +143,18 @@
@Test
fun testAddAnotherSendsAction() =
testScope.runTest {
+ advanceUntilIdle()
+ bringToConfirmation()
+ advanceUntilIdle()
+
var step: FingerprintNavigationStep.UiStep? = null
val job = launch { navigationViewModel.navigateTo.collect { step = it } }
underTest.onAddAnotherButtonClicked()
- runCurrent()
+ advanceUntilIdle()
- assertThat(step).isInstanceOf(FingerprintNavigationStep.Enrollment::class.java)
+ assertThat(step).isNull()
job.cancel()
}
}
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 5a30433..c475cc4 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
@@ -28,9 +28,7 @@
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.testutils2.FakeFingerprintManagerInteractor
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
import com.google.common.truth.Truth.assertThat
@@ -61,20 +59,15 @@
private lateinit var backgroundViewModel: BackgroundViewModel
private lateinit var gateKeeperViewModel: FingerprintGatekeeperViewModel
private lateinit var navigationViewModel: FingerprintNavigationViewModel
- private val defaultGatekeeperInfo = GatekeeperInfo.GatekeeperPasswordInfo(byteArrayOf(1, 3), 3)
private var testScope = TestScope(backgroundDispatcher)
private lateinit var fakeFingerprintManagerInteractor: FakeFingerprintManagerInteractor
- private fun initialize(gatekeeperInfo: GatekeeperInfo = defaultGatekeeperInfo) {
+ private fun initialize() {
fakeFingerprintManagerInteractor = FakeFingerprintManagerInteractor()
- gateKeeperViewModel =
- FingerprintGatekeeperViewModel.FingerprintGatekeeperViewModelFactory(
- gatekeeperInfo,
- fakeFingerprintManagerInteractor,
- )
- .create(FingerprintGatekeeperViewModel::class.java)
- val sensor =
+
+ gateKeeperViewModel = FingerprintGatekeeperViewModel(fakeFingerprintManagerInteractor)
+ fakeFingerprintManagerInteractor.sensorProp =
FingerprintSensorPropertiesInternal(
1 /* sensorId */,
SensorProperties.STRENGTH_STRONG,
@@ -86,32 +79,21 @@
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
)
.toFingerprintSensor()
- val fingerprintFlowViewModel = FingerprintFlowViewModel(Default)
+ val fingerprintFlowViewModel = FingerprintFlowViewModel()
+ fingerprintFlowViewModel.updateFlowType(Default)
- navigationViewModel =
- FingerprintNavigationViewModel(
- Enrollment(sensor),
- false,
- fingerprintFlowViewModel,
- fakeFingerprintManagerInteractor,
- )
+ navigationViewModel = FingerprintNavigationViewModel(fakeFingerprintManagerInteractor)
- backgroundViewModel =
- BackgroundViewModel.BackgroundViewModelFactory().create(BackgroundViewModel::class.java)
+ backgroundViewModel = BackgroundViewModel()
backgroundViewModel.inForeground()
val fingerprintEnrollViewModel =
- FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory(
- fakeFingerprintManagerInteractor,
- gateKeeperViewModel,
- navigationViewModel,
- )
- .create(FingerprintEnrollViewModel::class.java)
+ FingerprintEnrollViewModel(
+ fakeFingerprintManagerInteractor,
+ gateKeeperViewModel,
+ navigationViewModel,
+ )
enrollEnrollingViewModel =
- FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingViewModelFactory(
- fingerprintEnrollViewModel,
- backgroundViewModel,
- )
- .create(FingerprintEnrollEnrollingViewModel::class.java)
+ FingerprintEnrollEnrollingViewModel(fingerprintEnrollViewModel, backgroundViewModel)
}
@Before
@@ -128,6 +110,7 @@
@Test
fun testEnrollShouldBeFalse() =
testScope.runTest {
+ gateKeeperViewModel.onConfirmDevice(true, 3L, false)
var shouldEnroll = false
val job = launch {
@@ -147,6 +130,7 @@
@Test
fun testEnrollShouldBeFalseWhenBackground() =
testScope.runTest {
+ gateKeeperViewModel.onConfirmDevice(true, 3L, false)
var shouldEnroll = false
val job = launch {