Merge "UDFPS Enrollment Refactor (5/N)" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
890eecf2e4
@@ -14,38 +14,38 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.biometrics.fingerprint2.lib.model
|
package com.android.settings.biometrics.fingerprint2.data.model
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A view model that describes the various stages of UDFPS Enrollment. This stages typically update
|
* A view model that describes the various stages of UDFPS Enrollment. This stages typically update
|
||||||
* the enrollment UI in a major way, such as changing the lottie animation or changing the location
|
* the enrollment UI in a major way, such as changing the lottie animation or changing the location
|
||||||
* of the where the user should press their fingerprint
|
* of the where the user should press their fingerprint
|
||||||
*/
|
*/
|
||||||
sealed class StageViewModel {
|
sealed class EnrollStageModel {
|
||||||
/** Unknown stage */
|
/** Unknown stage */
|
||||||
data object Unknown : StageViewModel()
|
data object Unknown : EnrollStageModel()
|
||||||
|
|
||||||
/** This is the stage that moves the fingerprint icon around during enrollment. */
|
/** This is the stage that moves the fingerprint icon around during enrollment. */
|
||||||
data object Guided : StageViewModel()
|
data object Guided : EnrollStageModel()
|
||||||
|
|
||||||
/** The center stage is the initial stage of enrollment. */
|
/** The center stage is the initial stage of enrollment. */
|
||||||
data object Center : StageViewModel()
|
data object Center : EnrollStageModel()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fingerprint stage of enrollment. Typically there is some sort of indication that a user should
|
* Fingerprint stage of enrollment. Typically there is some sort of indication that a user should
|
||||||
* be using their finger tip to enroll.
|
* be using their finger tip to enroll.
|
||||||
*/
|
*/
|
||||||
data object Fingertip : StageViewModel()
|
data object Fingertip : EnrollStageModel()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Left edge stage of enrollment. Typically there is an indication that a user should be using the
|
* Left edge stage of enrollment. Typically there is an indication that a user should be using the
|
||||||
* left edge of their fingerprint.
|
* left edge of their fingerprint.
|
||||||
*/
|
*/
|
||||||
data object LeftEdge : StageViewModel()
|
data object LeftEdge : EnrollStageModel()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Right edge stage of enrollment. Typically there is an indication that a user should be using
|
* Right edge stage of enrollment. Typically there is an indication that a user should be using
|
||||||
* the right edge of their fingerprint.
|
* the right edge of their fingerprint.
|
||||||
*/
|
*/
|
||||||
data object RightEdge : StageViewModel()
|
data object RightEdge : EnrollStageModel()
|
||||||
}
|
}
|
@@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
package com.android.settings.biometrics.fingerprint2.domain.interactor
|
package com.android.settings.biometrics.fingerprint2.domain.interactor
|
||||||
|
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
import com.android.settings.biometrics.fingerprint2.data.model.EnrollStageModel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
|
||||||
typealias EnrollStageThresholds = Map<Float, StageViewModel>
|
typealias EnrollStageThresholds = Map<Float, EnrollStageModel>
|
||||||
|
|
||||||
/** Interactor that provides enroll stages for enrollment. */
|
/** Interactor that provides enroll stages for enrollment. */
|
||||||
interface EnrollStageInteractor {
|
interface EnrollStageInteractor {
|
||||||
@@ -33,11 +33,11 @@ class EnrollStageInteractorImpl() : EnrollStageInteractor {
|
|||||||
override val enrollStageThresholds: Flow<EnrollStageThresholds> =
|
override val enrollStageThresholds: Flow<EnrollStageThresholds> =
|
||||||
flowOf(
|
flowOf(
|
||||||
mapOf(
|
mapOf(
|
||||||
0.0f to StageViewModel.Center,
|
0.0f to EnrollStageModel.Center,
|
||||||
0.25f to StageViewModel.Guided,
|
0.25f to EnrollStageModel.Guided,
|
||||||
0.5f to StageViewModel.Fingertip,
|
0.5f to EnrollStageModel.Fingertip,
|
||||||
0.75f to StageViewModel.LeftEdge,
|
0.75f to EnrollStageModel.LeftEdge,
|
||||||
0.875f to StageViewModel.RightEdge,
|
0.875f to EnrollStageModel.RightEdge,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,7 @@ interface OrientationInteractor {
|
|||||||
* A flow that contains the rotation info matched against the def [config_reverseDefaultRotation]
|
* A flow that contains the rotation info matched against the def [config_reverseDefaultRotation]
|
||||||
*/
|
*/
|
||||||
val rotationFromDefault: Flow<Int>
|
val rotationFromDefault: Flow<Int>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Helper function that computes rotation if device is in
|
* A Helper function that computes rotation if device is in
|
||||||
* [R.bool.config_reverseDefaultConfigRotation]
|
* [R.bool.config_reverseDefaultConfigRotation]
|
||||||
|
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* 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.graphics.PointF
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interactor provides information about the current offset of the sensor for guided enrollment
|
||||||
|
* on UDFPS devices.
|
||||||
|
*/
|
||||||
|
interface UdfpsEnrollInteractor {
|
||||||
|
/** Indicates at which step a UDFPS enrollment is in. */
|
||||||
|
fun onEnrollmentStep(stepsRemaining: Int, totalStep: Int)
|
||||||
|
|
||||||
|
/** Indicates if guided enrollment should be enabled or not. */
|
||||||
|
fun updateGuidedEnrollment(enabled: Boolean)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flow indicating how much the sensor image drawable should be offset for guided enrollment. A
|
||||||
|
* null point indicates that the icon should be in its default position.
|
||||||
|
*/
|
||||||
|
val guidedEnrollmentOffset: Flow<PointF>
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Keeps track of which guided enrollment point we should be using */
|
||||||
|
class UdfpsEnrollInteractorImpl(
|
||||||
|
pixelsPerMillimeter: Float,
|
||||||
|
accessibilityInteractor: AccessibilityInteractor,
|
||||||
|
) : UdfpsEnrollInteractor {
|
||||||
|
|
||||||
|
private var isGuidedEnrollment = MutableStateFlow(false)
|
||||||
|
// Number of pixels per mm
|
||||||
|
val px = pixelsPerMillimeter
|
||||||
|
private val guidedEnrollmentPoints: MutableList<PointF> =
|
||||||
|
mutableListOf(
|
||||||
|
PointF(2.00f * px, 0.00f * px),
|
||||||
|
PointF(0.87f * px, -2.70f * px),
|
||||||
|
PointF(-1.80f * px, -1.31f * px),
|
||||||
|
PointF(-1.80f * px, 1.31f * px),
|
||||||
|
PointF(0.88f * px, 2.70f * px),
|
||||||
|
PointF(3.94f * px, -1.06f * px),
|
||||||
|
PointF(2.90f * px, -4.14f * px),
|
||||||
|
PointF(-0.52f * px, -5.95f * px),
|
||||||
|
PointF(-3.33f * px, -3.33f * px),
|
||||||
|
PointF(-3.99f * px, -0.35f * px),
|
||||||
|
PointF(-3.62f * px, 2.54f * px),
|
||||||
|
PointF(-1.49f * px, 5.57f * px),
|
||||||
|
PointF(2.29f * px, 4.92f * px),
|
||||||
|
PointF(3.82f * px, 1.78f * px),
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun onEnrollmentStep(stepsRemaining: Int, totalStep: Int) {
|
||||||
|
val index = (totalStep - stepsRemaining) % guidedEnrollmentPoints.size
|
||||||
|
_guidedEnrollment.update { guidedEnrollmentPoints[index] }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateGuidedEnrollment(enabled: Boolean) {
|
||||||
|
isGuidedEnrollment.update { enabled }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _guidedEnrollment = MutableStateFlow(PointF(0f, 0f))
|
||||||
|
override val guidedEnrollmentOffset: Flow<PointF> =
|
||||||
|
combine(
|
||||||
|
_guidedEnrollment,
|
||||||
|
accessibilityInteractor.isAccessibilityEnabled,
|
||||||
|
isGuidedEnrollment,
|
||||||
|
) { point, accessibilityEnabled, guidedEnrollmentEnabled ->
|
||||||
|
if (accessibilityEnabled || !guidedEnrollmentEnabled) {
|
||||||
|
return@combine PointF(0f, 0f)
|
||||||
|
} else {
|
||||||
|
return@combine PointF(point.x * SCALE, point.y * SCALE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val SCALE = 0.5f
|
||||||
|
}
|
||||||
|
}
|
@@ -24,6 +24,7 @@ import android.hardware.fingerprint.FingerprintManager
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Vibrator
|
import android.os.Vibrator
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.accessibility.AccessibilityManager
|
import android.view.accessibility.AccessibilityManager
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
@@ -54,6 +55,8 @@ import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateI
|
|||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.FoldStateInteractorImpl
|
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.OrientationInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.OrientationInteractorImpl
|
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.VibrationInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractorImpl
|
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.Default
|
||||||
@@ -89,6 +92,7 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Fing
|
|||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
|
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.FingerprintScrollViewModel
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo
|
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
|
import com.android.settings.flags.Flags
|
||||||
import com.android.settings.password.ChooseLockGeneric
|
import com.android.settings.password.ChooseLockGeneric
|
||||||
import com.android.settings.password.ChooseLockSettingsHelper
|
import com.android.settings.password.ChooseLockSettingsHelper
|
||||||
@@ -116,6 +120,7 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
|
|||||||
private lateinit var foldStateInteractor: FoldStateInteractor
|
private lateinit var foldStateInteractor: FoldStateInteractor
|
||||||
private lateinit var orientationInteractor: OrientationInteractor
|
private lateinit var orientationInteractor: OrientationInteractor
|
||||||
private lateinit var displayDensityInteractor: DisplayDensityInteractor
|
private lateinit var displayDensityInteractor: DisplayDensityInteractor
|
||||||
|
private lateinit var udfpsEnrollInteractor: UdfpsEnrollInteractor
|
||||||
private lateinit var fingerprintScrollViewModel: FingerprintScrollViewModel
|
private lateinit var fingerprintScrollViewModel: FingerprintScrollViewModel
|
||||||
private lateinit var backgroundViewModel: BackgroundViewModel
|
private lateinit var backgroundViewModel: BackgroundViewModel
|
||||||
private lateinit var fingerprintFlowViewModel: FingerprintFlowViewModel
|
private lateinit var fingerprintFlowViewModel: FingerprintFlowViewModel
|
||||||
@@ -256,6 +261,15 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
|
|||||||
fingerprintManager,
|
fingerprintManager,
|
||||||
Settings,
|
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 =
|
val fingerprintManagerInteractor =
|
||||||
FingerprintManagerInteractorImpl(
|
FingerprintManagerInteractorImpl(
|
||||||
@@ -273,12 +287,6 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
|
|||||||
|
|
||||||
val hasConfirmedDeviceCredential = gatekeeperInfo is GatekeeperInfo.GatekeeperPasswordInfo
|
val hasConfirmedDeviceCredential = gatekeeperInfo is GatekeeperInfo.GatekeeperPasswordInfo
|
||||||
|
|
||||||
val accessibilityInteractor =
|
|
||||||
AccessibilityInteractorImpl(
|
|
||||||
getSystemService(AccessibilityManager::class.java)!!,
|
|
||||||
lifecycleScope,
|
|
||||||
)
|
|
||||||
|
|
||||||
navigationViewModel =
|
navigationViewModel =
|
||||||
ViewModelProvider(
|
ViewModelProvider(
|
||||||
this,
|
this,
|
||||||
@@ -384,6 +392,7 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
|
|||||||
orientationInteractor,
|
orientationInteractor,
|
||||||
backgroundViewModel,
|
backgroundViewModel,
|
||||||
fingerprintSensorRepo,
|
fingerprintSensorRepo,
|
||||||
|
udfpsEnrollInteractor,
|
||||||
),
|
),
|
||||||
)[UdfpsViewModel::class.java]
|
)[UdfpsViewModel::class.java]
|
||||||
|
|
||||||
@@ -435,17 +444,17 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
|
|||||||
else -> FingerprintEnrollEnrollingV2Fragment()
|
else -> FingerprintEnrollEnrollingV2Fragment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Introduction -> FingerprintEnrollIntroV2Fragment()
|
is Introduction -> FingerprintEnrollIntroV2Fragment()
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theClass != null) {
|
if (theClass != null) {
|
||||||
supportFragmentManager.fragments.onEach { fragment ->
|
|
||||||
supportFragmentManager.beginTransaction().remove(fragment).commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
supportFragmentManager
|
supportFragmentManager
|
||||||
.beginTransaction()
|
.beginTransaction()
|
||||||
|
.setCustomAnimations(
|
||||||
|
step.enterTransition.toAnimation(),
|
||||||
|
step.exitTransition.toAnimation(),
|
||||||
|
)
|
||||||
.setReorderingAllowed(true)
|
.setReorderingAllowed(true)
|
||||||
.add(R.id.fragment_container_view, theClass::class.java, null)
|
.add(R.id.fragment_container_view, theClass::class.java, null)
|
||||||
.commit()
|
.commit()
|
||||||
@@ -512,3 +521,12 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Transition.toAnimation(): Int {
|
||||||
|
return when (this) {
|
||||||
|
Transition.EnterFromLeft -> com.google.android.setupdesign.R.anim.sud_slide_back_in
|
||||||
|
Transition.EnterFromRight -> com.google.android.setupdesign.R.anim.sud_slide_next_in
|
||||||
|
Transition.ExitToLeft -> com.google.android.setupdesign.R.anim.sud_slide_next_out
|
||||||
|
Transition.ExitToRight -> com.google.android.setupdesign.R.anim.sud_slide_back_out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -32,12 +32,12 @@ import androidx.lifecycle.repeatOnLifecycle
|
|||||||
import com.airbnb.lottie.LottieAnimationView
|
import com.airbnb.lottie.LottieAnimationView
|
||||||
import com.airbnb.lottie.LottieCompositionFactory
|
import com.airbnb.lottie.LottieCompositionFactory
|
||||||
import com.android.settings.R
|
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.lib.model.FingerEnrollState
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.common.widget.FingerprintErrorDialog
|
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.viewmodel.DescriptionText
|
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
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.EducationAnimationModel
|
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.EducationAnimationModel
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.HeaderText
|
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.UdfpsViewModel
|
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel.UdfpsViewModel
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.widget.UdfpsEnrollViewV2
|
import com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.widget.UdfpsEnrollViewV2
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
|
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
|
||||||
@@ -83,6 +83,8 @@ class UdfpsEnrollFragment() : Fragment(R.layout.fingerprint_v2_udfps_enroll_enro
|
|||||||
window.statusBarColor = color
|
window.statusBarColor = color
|
||||||
view.setBackgroundColor(color)
|
view.setBackgroundColor(color)
|
||||||
|
|
||||||
|
udfpsEnrollView.setFinishAnimationCompleted { viewModel.finishedSuccessfully() }
|
||||||
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
launch {
|
launch {
|
||||||
@@ -159,7 +161,14 @@ class UdfpsEnrollFragment() : Fragment(R.layout.fingerprint_v2_udfps_enroll_enro
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
viewModel.enrollStage.collect { udfpsEnrollView.updateStage(it) }
|
viewModel.guidedEnrollment.collect {
|
||||||
|
glifLayout.post { udfpsEnrollView.updateGuidedEnrollment(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
viewModel.guidedEnrollmentSaved.collect {
|
||||||
|
glifLayout.post { udfpsEnrollView.onGuidedPointSaved(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,35 +184,35 @@ class UdfpsEnrollFragment() : Fragment(R.layout.fingerprint_v2_udfps_enroll_enro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun HeaderText.toResource(): Int {
|
private fun HeaderText.toResource(): Int {
|
||||||
return when (this.stageViewModel) {
|
return when (this.enrollStageModel) {
|
||||||
StageViewModel.Center,
|
EnrollStageModel.Center,
|
||||||
StageViewModel.Guided,
|
EnrollStageModel.Guided,
|
||||||
StageViewModel.Fingertip,
|
EnrollStageModel.Fingertip,
|
||||||
StageViewModel.Unknown -> R.string.security_settings_udfps_enroll_fingertip_title
|
EnrollStageModel.Unknown -> R.string.security_settings_udfps_enroll_fingertip_title
|
||||||
StageViewModel.LeftEdge -> R.string.security_settings_udfps_enroll_left_edge_title
|
EnrollStageModel.LeftEdge -> R.string.security_settings_udfps_enroll_left_edge_title
|
||||||
StageViewModel.RightEdge -> R.string.security_settings_udfps_enroll_right_edge_title
|
EnrollStageModel.RightEdge -> R.string.security_settings_udfps_enroll_right_edge_title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun DescriptionText.toResource(): Int? {
|
private fun DescriptionText.toResource(): Int? {
|
||||||
return when (this.stageViewModel) {
|
return when (this.enrollStageModel) {
|
||||||
StageViewModel.Center,
|
EnrollStageModel.Center,
|
||||||
StageViewModel.Guided,
|
EnrollStageModel.Guided,
|
||||||
StageViewModel.Fingertip,
|
EnrollStageModel.Fingertip,
|
||||||
StageViewModel.LeftEdge,
|
EnrollStageModel.LeftEdge,
|
||||||
StageViewModel.RightEdge -> null
|
EnrollStageModel.RightEdge -> null
|
||||||
StageViewModel.Unknown -> R.string.security_settings_udfps_enroll_start_message
|
EnrollStageModel.Unknown -> R.string.security_settings_udfps_enroll_start_message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun EducationAnimationModel.toResource(): Int? {
|
private fun EducationAnimationModel.toResource(): Int? {
|
||||||
return when (this.stageViewModel) {
|
return when (this.enrollStageModel) {
|
||||||
StageViewModel.Center,
|
EnrollStageModel.Center,
|
||||||
StageViewModel.Guided -> R.raw.udfps_center_hint_lottie
|
EnrollStageModel.Guided -> R.raw.udfps_center_hint_lottie
|
||||||
StageViewModel.Fingertip -> R.raw.udfps_tip_hint_lottie
|
EnrollStageModel.Fingertip -> R.raw.udfps_tip_hint_lottie
|
||||||
StageViewModel.LeftEdge -> R.raw.udfps_left_edge_hint_lottie
|
EnrollStageModel.LeftEdge -> R.raw.udfps_left_edge_hint_lottie
|
||||||
StageViewModel.RightEdge -> R.raw.udfps_right_edge_hint_lottie
|
EnrollStageModel.RightEdge -> R.raw.udfps_right_edge_hint_lottie
|
||||||
StageViewModel.Unknown -> null
|
EnrollStageModel.Unknown -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,13 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
|
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.model
|
||||||
|
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
import com.android.settings.biometrics.fingerprint2.data.model.EnrollStageModel
|
||||||
|
|
||||||
/** Represents the description text for UDFPS enrollment */
|
/** Represents the description text for UDFPS enrollment */
|
||||||
data class DescriptionText(
|
data class DescriptionText(
|
||||||
val isSuw: Boolean,
|
val isSuw: Boolean,
|
||||||
val isAccessibility: Boolean,
|
val isAccessibility: Boolean,
|
||||||
val stageViewModel: StageViewModel,
|
val enrollStageModel: EnrollStageModel,
|
||||||
)
|
)
|
@@ -14,13 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
|
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.model
|
||||||
|
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
import com.android.settings.biometrics.fingerprint2.data.model.EnrollStageModel
|
||||||
|
|
||||||
/** Represents the header text for UDFPS enrollment */
|
/** Represents the header text for UDFPS enrollment */
|
||||||
data class HeaderText(
|
data class HeaderText(
|
||||||
val isSuw: Boolean,
|
val isSuw: Boolean,
|
||||||
val isAccessibility: Boolean,
|
val isAccessibility: Boolean,
|
||||||
val stageViewModel: StageViewModel,
|
val enrollStageModel: EnrollStageModel,
|
||||||
)
|
)
|
@@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
|
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
|
||||||
|
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
import com.android.settings.biometrics.fingerprint2.data.model.EnrollStageModel
|
||||||
|
|
||||||
/** Represents the lottie for UDFPS enrollment */
|
/** Represents the lottie for UDFPS enrollment */
|
||||||
data class EducationAnimationModel(
|
data class EducationAnimationModel(
|
||||||
val isSuw: Boolean,
|
val isSuw: Boolean,
|
||||||
val isAccessibility: Boolean,
|
val isAccessibility: Boolean,
|
||||||
val stageViewModel: StageViewModel,
|
val enrollStageModel: EnrollStageModel,
|
||||||
)
|
)
|
||||||
|
@@ -17,20 +17,24 @@
|
|||||||
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
|
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.viewmodel
|
||||||
|
|
||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
|
import android.graphics.PointF
|
||||||
import android.view.Surface
|
import android.view.Surface
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
|
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
|
||||||
|
import com.android.settings.biometrics.fingerprint2.data.model.EnrollStageModel
|
||||||
import com.android.settings.biometrics.fingerprint2.data.repository.SimulatedTouchEventsRepository
|
import com.android.settings.biometrics.fingerprint2.data.repository.SimulatedTouchEventsRepository
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.DebuggingInteractor
|
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.DisplayDensityInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.EnrollStageInteractor
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.EnrollStageInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintVibrationEffects
|
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.OrientationInteractor
|
||||||
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.UdfpsEnrollInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractor
|
import com.android.settings.biometrics.fingerprint2.domain.interactor.VibrationInteractor
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
|
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
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
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
|
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.FingerprintAction
|
||||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollEnrollingViewModel
|
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollEnrollingViewModel
|
||||||
@@ -61,9 +65,11 @@ class UdfpsViewModel(
|
|||||||
orientationInteractor: OrientationInteractor,
|
orientationInteractor: OrientationInteractor,
|
||||||
backgroundViewModel: BackgroundViewModel,
|
backgroundViewModel: BackgroundViewModel,
|
||||||
sensorRepository: FingerprintSensorRepository,
|
sensorRepository: FingerprintSensorRepository,
|
||||||
|
udfpsEnrollInteractor: UdfpsEnrollInteractor,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val isSetupWizard = flowOf(false)
|
private val isSetupWizard = flowOf(false)
|
||||||
|
private var shouldResetErollment = false
|
||||||
|
|
||||||
private var _enrollState: Flow<FingerEnrollState?> =
|
private var _enrollState: Flow<FingerEnrollState?> =
|
||||||
fingerprintEnrollEnrollingViewModel.enrollFlow
|
fingerprintEnrollEnrollingViewModel.enrollFlow
|
||||||
@@ -112,6 +118,17 @@ class UdfpsViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This indicates at which point the UI should offset the fingerprint sensor icon for guided
|
||||||
|
* enrollment.
|
||||||
|
*/
|
||||||
|
val guidedEnrollment: Flow<PointF> =
|
||||||
|
udfpsEnrollInteractor.guidedEnrollmentOffset.distinctUntilChanged()
|
||||||
|
|
||||||
|
/** The saved version of [guidedEnrollment] */
|
||||||
|
val guidedEnrollmentSaved: Flow<PointF> =
|
||||||
|
guidedEnrollment.shareIn(this.viewModelScope, SharingStarted.Eagerly, replay = 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the saved progress, this is for when views are recreated and need saved state for the
|
* This is the saved progress, this is for when views are recreated and need saved state for the
|
||||||
* first time.
|
* first time.
|
||||||
@@ -132,13 +149,13 @@ class UdfpsViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determines the current [StageViewModel] enrollment is in */
|
/** Determines the current [EnrollStageModel] enrollment is in */
|
||||||
val enrollStage: Flow<StageViewModel> =
|
private val enrollStage: Flow<EnrollStageModel> =
|
||||||
combine(enrollStageInteractor.enrollStageThresholds, enrollState) { thresholds, event ->
|
combine(enrollStageInteractor.enrollStageThresholds, enrollState) { thresholds, event ->
|
||||||
if (event is FingerEnrollState.EnrollProgress) {
|
if (event is FingerEnrollState.EnrollProgress) {
|
||||||
val progress =
|
val progress =
|
||||||
(event.totalStepsRequired - event.remainingSteps).toFloat() / event.totalStepsRequired
|
(event.totalStepsRequired - event.remainingSteps).toFloat() / event.totalStepsRequired
|
||||||
var stageToReturn: StageViewModel = StageViewModel.Center
|
var stageToReturn: EnrollStageModel = EnrollStageModel.Center
|
||||||
thresholds.forEach { (threshold, stage) ->
|
thresholds.forEach { (threshold, stage) ->
|
||||||
if (progress < threshold) {
|
if (progress < threshold) {
|
||||||
return@forEach
|
return@forEach
|
||||||
@@ -153,6 +170,40 @@ class UdfpsViewModel(
|
|||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
.shareIn(this.viewModelScope, SharingStarted.Eagerly, replay = 1)
|
.shareIn(this.viewModelScope, SharingStarted.Eagerly, replay = 1)
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch {
|
||||||
|
enrollState
|
||||||
|
.combine(accessibilityEnabled) { event, isEnabled -> Pair(event, isEnabled) }
|
||||||
|
.collect {
|
||||||
|
if (
|
||||||
|
when (it.first) {
|
||||||
|
is FingerEnrollState.EnrollError -> true
|
||||||
|
is FingerEnrollState.EnrollHelp -> it.second
|
||||||
|
is FingerEnrollState.EnrollProgress -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
vibrate(it.first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
viewModelScope.launch {
|
||||||
|
enrollStage.collect {
|
||||||
|
udfpsEnrollInteractor.updateGuidedEnrollment(it is EnrollStageModel.Guided)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
|
enrollState.filterIsInstance<FingerEnrollState.EnrollProgress>().collect {
|
||||||
|
udfpsEnrollInteractor.onEnrollmentStep(it.remainingSteps, it.totalStepsRequired)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelScope.launch {
|
||||||
|
backgroundViewModel.background.filter { true }.collect { didGoToBackground() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Indicates if we should show the lottie. */
|
/** Indicates if we should show the lottie. */
|
||||||
val shouldShowLottie: Flow<Boolean> =
|
val shouldShowLottie: Flow<Boolean> =
|
||||||
combine(
|
combine(
|
||||||
@@ -183,7 +234,7 @@ class UdfpsViewModel(
|
|||||||
}
|
}
|
||||||
.shareIn(this.viewModelScope, SharingStarted.Eagerly, replay = 1)
|
.shareIn(this.viewModelScope, SharingStarted.Eagerly, replay = 1)
|
||||||
|
|
||||||
private val shouldClearDescriptionText = enrollStage.map { it is StageViewModel.Unknown }
|
private val shouldClearDescriptionText = enrollStage.map { it is EnrollStageModel.Unknown }
|
||||||
|
|
||||||
/** The description text for UDFPS enrollment */
|
/** The description text for UDFPS enrollment */
|
||||||
val descriptionText: Flow<DescriptionText?> =
|
val descriptionText: Flow<DescriptionText?> =
|
||||||
@@ -202,6 +253,10 @@ class UdfpsViewModel(
|
|||||||
|
|
||||||
/** Indicates if the consumer is ready for enrollment */
|
/** Indicates if the consumer is ready for enrollment */
|
||||||
fun readyForEnrollment() {
|
fun readyForEnrollment() {
|
||||||
|
if (shouldResetErollment) {
|
||||||
|
shouldResetErollment = false
|
||||||
|
_enrollState = fingerprintEnrollEnrollingViewModel.enrollFlow
|
||||||
|
}
|
||||||
fingerprintEnrollEnrollingViewModel.canEnroll()
|
fingerprintEnrollEnrollingViewModel.canEnroll()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,8 +292,12 @@ class UdfpsViewModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun doReset() {
|
private fun doReset() {
|
||||||
/** Indicates if the icon should be animating or not */
|
|
||||||
_enrollState = fingerprintEnrollEnrollingViewModel.enrollFlow
|
_enrollState = fingerprintEnrollEnrollingViewModel.enrollFlow
|
||||||
|
progressSaved =
|
||||||
|
enrollState
|
||||||
|
.filterIsInstance<FingerEnrollState.EnrollProgress>()
|
||||||
|
.filterNotNull()
|
||||||
|
.shareIn(this.viewModelScope, SharingStarted.Eagerly, replay = 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The lottie that should be shown for UDFPS Enrollment */
|
/** The lottie that should be shown for UDFPS Enrollment */
|
||||||
@@ -272,6 +331,7 @@ class UdfpsViewModel(
|
|||||||
private val orientationInteractor: OrientationInteractor,
|
private val orientationInteractor: OrientationInteractor,
|
||||||
private val backgroundViewModel: BackgroundViewModel,
|
private val backgroundViewModel: BackgroundViewModel,
|
||||||
private val sensorRepository: FingerprintSensorRepository,
|
private val sensorRepository: FingerprintSensorRepository,
|
||||||
|
private val udfpsEnrollInteractor: UdfpsEnrollInteractor,
|
||||||
) : ViewModelProvider.Factory {
|
) : ViewModelProvider.Factory {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -287,6 +347,7 @@ class UdfpsViewModel(
|
|||||||
orientationInteractor,
|
orientationInteractor,
|
||||||
backgroundViewModel,
|
backgroundViewModel,
|
||||||
sensorRepository,
|
sensorRepository,
|
||||||
|
udfpsEnrollInteractor,
|
||||||
)
|
)
|
||||||
as T
|
as T
|
||||||
}
|
}
|
||||||
|
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2024 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrolling.udfps.ui.widget
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.PointF
|
|
||||||
import android.util.TypedValue
|
|
||||||
import android.view.accessibility.AccessibilityManager
|
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
|
||||||
|
|
||||||
/** Keeps track of which guided enrollment point we should be using */
|
|
||||||
class UdfpsEnrollHelperV2(private val mContext: Context) {
|
|
||||||
|
|
||||||
private var isGuidedEnrollment: Boolean = false
|
|
||||||
private val accessibilityEnabled: Boolean
|
|
||||||
private val guidedEnrollmentPoints: MutableList<PointF>
|
|
||||||
/** The current index of [guidedEnrollmentPoints] for the guided enrollment. */
|
|
||||||
private var index = 0
|
|
||||||
|
|
||||||
init {
|
|
||||||
val am = mContext.getSystemService(AccessibilityManager::class.java)
|
|
||||||
accessibilityEnabled = am!!.isEnabled
|
|
||||||
guidedEnrollmentPoints = ArrayList()
|
|
||||||
|
|
||||||
// Number of pixels per mm
|
|
||||||
val px =
|
|
||||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1f, mContext.resources.displayMetrics)
|
|
||||||
guidedEnrollmentPoints.add(PointF(2.00f * px, 0.00f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(0.87f * px, -2.70f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(-1.80f * px, -1.31f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(-1.80f * px, 1.31f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(0.88f * px, 2.70f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(3.94f * px, -1.06f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(2.90f * px, -4.14f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(-0.52f * px, -5.95f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(-3.33f * px, -3.33f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(-3.99f * px, -0.35f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(-3.62f * px, 2.54f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(-1.49f * px, 5.57f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(2.29f * px, 4.92f * px))
|
|
||||||
guidedEnrollmentPoints.add(PointF(3.82f * px, 1.78f * px))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This indicates whether we should be offsetting the enrollment icon based on
|
|
||||||
* [guidedEnrollmentPoints]
|
|
||||||
*/
|
|
||||||
fun onUpdateStage(stage: StageViewModel) {
|
|
||||||
this.isGuidedEnrollment = stage is StageViewModel.Guided
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Updates [index] to be used by [guidedEnrollmentPoints] */
|
|
||||||
fun onEnrollmentProgress(remaining: Int, totalSteps: Int) {
|
|
||||||
index = totalSteps - remaining
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current guided enrollment point, or (0,0) if we are not in guided enrollment or are
|
|
||||||
* in accessibility.
|
|
||||||
*/
|
|
||||||
val guidedEnrollmentLocation: PointF?
|
|
||||||
get() {
|
|
||||||
if (accessibilityEnabled || !isGuidedEnrollment) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
val scale = SCALE
|
|
||||||
val originalPoint = guidedEnrollmentPoints[index % guidedEnrollmentPoints.size]
|
|
||||||
return PointF(originalPoint.x * scale, originalPoint.y * scale)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "UdfpsEnrollHelperV2"
|
|
||||||
private const val SCALE = 0.5f
|
|
||||||
}
|
|
||||||
}
|
|
@@ -24,6 +24,7 @@ import android.graphics.Canvas
|
|||||||
import android.graphics.ColorFilter
|
import android.graphics.ColorFilter
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.PixelFormat
|
import android.graphics.PixelFormat
|
||||||
|
import android.graphics.PointF
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.graphics.RectF
|
import android.graphics.RectF
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
@@ -37,7 +38,6 @@ import androidx.core.animation.addListener
|
|||||||
import androidx.core.graphics.toRect
|
import androidx.core.graphics.toRect
|
||||||
import androidx.core.graphics.toRectF
|
import androidx.core.graphics.toRectF
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,11 +51,11 @@ class UdfpsEnrollIconV2 internal constructor(context: Context, attrs: AttributeS
|
|||||||
private val fingerprintDrawable: ShapeDrawable
|
private val fingerprintDrawable: ShapeDrawable
|
||||||
private val sensorOutlinePaint: Paint
|
private val sensorOutlinePaint: Paint
|
||||||
private val blueFill: Paint
|
private val blueFill: Paint
|
||||||
private val helper = UdfpsEnrollHelperV2(context)
|
|
||||||
@ColorInt private var enrollIconColor = 0
|
@ColorInt private var enrollIconColor = 0
|
||||||
@ColorInt private var movingTargetFill = 0
|
@ColorInt private var movingTargetFill = 0
|
||||||
private var currentScale = 1.0f
|
private var currentScale = 1.0f
|
||||||
private var alpha = 0
|
private var alpha = 0
|
||||||
|
private var guidedEnrollmentOffset: PointF? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the physical location of the sensor. This rect will be updated by [drawSensorRectAt]
|
* This is the physical location of the sensor. This rect will be updated by [drawSensorRectAt]
|
||||||
@@ -143,45 +143,6 @@ class UdfpsEnrollIconV2 internal constructor(context: Context, attrs: AttributeS
|
|||||||
invalidateSelf()
|
invalidateSelf()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update the progress of the icon */
|
|
||||||
fun onEnrollmentProgress(remaining: Int, totalSteps: Int, isRecreating: Boolean = false) {
|
|
||||||
restoreAnimationTime()
|
|
||||||
// If we are restoring this view from a saved state, set animation duration to 0 to avoid
|
|
||||||
// animating progress that has already occurred.
|
|
||||||
if (isRecreating) {
|
|
||||||
setAnimationTimeToZero()
|
|
||||||
} else {
|
|
||||||
restoreAnimationTime()
|
|
||||||
}
|
|
||||||
|
|
||||||
helper.onEnrollmentProgress(remaining, totalSteps)
|
|
||||||
val offset = helper.guidedEnrollmentLocation
|
|
||||||
val currentBounds = getCurrLocation().toRect()
|
|
||||||
if (offset != null) {
|
|
||||||
// This is the desired location of the sensor rect, the [EnrollHelper]
|
|
||||||
// offsets the initial sensor rect by a bit to get the user to move their finger a bit more.
|
|
||||||
val targetRect = Rect(sensorRectBounds).toRectF()
|
|
||||||
targetRect.offset(offset.x, offset.y)
|
|
||||||
val shouldAnimateMovement =
|
|
||||||
!currentBounds.equals(targetRect) && offset.x != 0f && offset.y != 0f
|
|
||||||
if (shouldAnimateMovement) {
|
|
||||||
targetAnimatorSet?.cancel()
|
|
||||||
animateMovement(currentBounds, targetRect, true)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If we are not offsetting the sensor, move it back to its original place
|
|
||||||
animateMovement(currentBounds, sensorRectBounds.toRectF(), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
invalidateSelf()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Update the stage of the icon */
|
|
||||||
fun updateStage(it: StageViewModel) {
|
|
||||||
helper.onUpdateStage(it)
|
|
||||||
invalidateSelf()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Stop drawing the fingerprint icon. */
|
/** Stop drawing the fingerprint icon. */
|
||||||
fun stopDrawing() {
|
fun stopDrawing() {
|
||||||
alpha = 0
|
alpha = 0
|
||||||
@@ -211,6 +172,7 @@ class UdfpsEnrollIconV2 internal constructor(context: Context, attrs: AttributeS
|
|||||||
if (currentBounds.equals(offsetRect)) {
|
if (currentBounds.equals(offsetRect)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val xAnimator = ValueAnimator.ofFloat(currentBounds.left.toFloat(), offsetRect.left)
|
val xAnimator = ValueAnimator.ofFloat(currentBounds.left.toFloat(), offsetRect.left)
|
||||||
xAnimator.addUpdateListener {
|
xAnimator.addUpdateListener {
|
||||||
currX = it.animatedValue as Float
|
currX = it.animatedValue as Float
|
||||||
@@ -260,6 +222,40 @@ class UdfpsEnrollIconV2 internal constructor(context: Context, attrs: AttributeS
|
|||||||
targetAnimationDuration = TARGET_ANIM_DURATION_LONG
|
targetAnimationDuration = TARGET_ANIM_DURATION_LONG
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates a change to guided enrollment has occurred. Also indicates if we are recreating the
|
||||||
|
* view, in which case their is no need to animate the icon to whatever position it was in.
|
||||||
|
*/
|
||||||
|
fun updateGuidedEnrollment(point: PointF, isRecreating: Boolean) {
|
||||||
|
guidedEnrollmentOffset = point
|
||||||
|
if (isRecreating) {
|
||||||
|
setAnimationTimeToZero()
|
||||||
|
} else {
|
||||||
|
restoreAnimationTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
val currentBounds = getCurrLocation().toRect()
|
||||||
|
val offset = guidedEnrollmentOffset
|
||||||
|
if (offset?.x != 0f && offset?.y != 0f) {
|
||||||
|
val targetRect = Rect(sensorRectBounds).toRectF()
|
||||||
|
// This is the desired location of the sensor rect, the [EnrollHelper]
|
||||||
|
// offsets the initial sensor rect by a bit to get the user to move their finger a bit more.
|
||||||
|
targetRect.offset(offset!!.x, offset!!.y)
|
||||||
|
val shouldAnimateMovement = !currentBounds.equals(targetRect)
|
||||||
|
if (shouldAnimateMovement) {
|
||||||
|
targetAnimatorSet?.cancel()
|
||||||
|
animateMovement(currentBounds, targetRect, true)
|
||||||
|
} else {
|
||||||
|
// If we are not offsetting the sensor, move it back to its original place
|
||||||
|
animateMovement(currentBounds, sensorRectBounds.toRectF(), false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If we are not offsetting the sensor, move it back to its original place
|
||||||
|
animateMovement(currentBounds, sensorRectBounds.toRectF(), false)
|
||||||
|
}
|
||||||
|
invalidateSelf()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "UdfpsEnrollDrawableV2"
|
private const val TAG = "UdfpsEnrollDrawableV2"
|
||||||
private const val DEFAULT_STROKE_WIDTH = 3f
|
private const val DEFAULT_STROKE_WIDTH = 3f
|
||||||
|
@@ -27,10 +27,12 @@ import android.graphics.Rect
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
|
import android.util.Log
|
||||||
import android.view.animation.DecelerateInterpolator
|
import android.view.animation.DecelerateInterpolator
|
||||||
import android.view.animation.Interpolator
|
import android.view.animation.Interpolator
|
||||||
import android.view.animation.OvershootInterpolator
|
import android.view.animation.OvershootInterpolator
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
|
import androidx.core.animation.addListener
|
||||||
import androidx.core.animation.doOnEnd
|
import androidx.core.animation.doOnEnd
|
||||||
import androidx.core.graphics.toRectF
|
import androidx.core.graphics.toRectF
|
||||||
import com.android.internal.annotations.VisibleForTesting
|
import com.android.internal.annotations.VisibleForTesting
|
||||||
@@ -46,6 +48,7 @@ import kotlin.math.sin
|
|||||||
class UdfpsEnrollProgressBarDrawableV2(private val context: Context, attrs: AttributeSet?) :
|
class UdfpsEnrollProgressBarDrawableV2(private val context: Context, attrs: AttributeSet?) :
|
||||||
Drawable() {
|
Drawable() {
|
||||||
private val sensorRect: Rect = Rect()
|
private val sensorRect: Rect = Rect()
|
||||||
|
private var onFinishedCompletionAnimation: (() -> Unit)? = null
|
||||||
private var rotation: Int = 0
|
private var rotation: Int = 0
|
||||||
private val strokeWidthPx: Float
|
private val strokeWidthPx: Float
|
||||||
|
|
||||||
@@ -287,6 +290,12 @@ class UdfpsEnrollProgressBarDrawableV2(private val context: Context, attrs: Attr
|
|||||||
checkMarkDrawable.bounds = newBounds
|
checkMarkDrawable.bounds = newBounds
|
||||||
checkMarkDrawable.setVisible(true, false)
|
checkMarkDrawable.setVisible(true, false)
|
||||||
}
|
}
|
||||||
|
doOnEnd {
|
||||||
|
onFinishedCompletionAnimation?.let{
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
start()
|
start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -380,6 +389,13 @@ class UdfpsEnrollProgressBarDrawableV2(private val context: Context, attrs: Attr
|
|||||||
checkmarkAnimationDuration = CHECKMARK_ANIMATION_DURATION_MS
|
checkmarkAnimationDuration = CHECKMARK_ANIMATION_DURATION_MS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the finish animation has completed, and enrollment can proceed to the next stage
|
||||||
|
*/
|
||||||
|
fun setFinishAnimationCompleted(onFinishedAnimation: () -> Unit) {
|
||||||
|
this.onFinishedCompletionAnimation = onFinishedAnimation
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "UdfpsProgressBar"
|
private const val TAG = "UdfpsProgressBar"
|
||||||
private const val FILL_COLOR_ANIMATION_DURATION_MS = 350L
|
private const val FILL_COLOR_ANIMATION_DURATION_MS = 350L
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.biometrics.fingerprint2.ui.enrollment.modules.enrol
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
|
import android.graphics.PointF
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -31,7 +32,6 @@ import android.widget.FrameLayout
|
|||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
|
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
|
||||||
import com.android.settings.biometrics.fingerprint2.lib.model.StageViewModel
|
|
||||||
import com.android.systemui.biometrics.UdfpsUtils
|
import com.android.systemui.biometrics.UdfpsUtils
|
||||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||||
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
|
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
|
||||||
@@ -53,6 +53,13 @@ class UdfpsEnrollViewV2(context: Context, attrs: AttributeSet?) : FrameLayout(co
|
|||||||
private val udfpsUtils: UdfpsUtils = UdfpsUtils()
|
private val udfpsUtils: UdfpsUtils = UdfpsUtils()
|
||||||
private lateinit var touchExplorationAnnouncer: TouchExplorationAnnouncer
|
private lateinit var touchExplorationAnnouncer: TouchExplorationAnnouncer
|
||||||
private var isRecreating = false
|
private var isRecreating = false
|
||||||
|
private var onFinishedCompletionAnimation: (() -> Unit)? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
fingerprintProgressDrawable.setFinishAnimationCompleted {
|
||||||
|
onFinishedCompletionAnimation?.let { it() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function computes the center (x,y) location with respect to the parent [FrameLayout] for
|
* This function computes the center (x,y) location with respect to the parent [FrameLayout] for
|
||||||
@@ -112,11 +119,6 @@ class UdfpsEnrollViewV2(context: Context, attrs: AttributeSet?) : FrameLayout(co
|
|||||||
touchExplorationAnnouncer = TouchExplorationAnnouncer(context, this, overlayParams, udfpsUtils)
|
touchExplorationAnnouncer = TouchExplorationAnnouncer(context, this, overlayParams, udfpsUtils)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Updates the current enrollment stage. */
|
|
||||||
fun updateStage(it: StageViewModel) {
|
|
||||||
fingerprintIcon.updateStage(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Receive enroll progress event */
|
/** Receive enroll progress event */
|
||||||
fun onUdfpsEvent(event: FingerEnrollState) {
|
fun onUdfpsEvent(event: FingerEnrollState) {
|
||||||
when (event) {
|
when (event) {
|
||||||
@@ -174,7 +176,6 @@ class UdfpsEnrollViewV2(context: Context, attrs: AttributeSet?) : FrameLayout(co
|
|||||||
|
|
||||||
/** Receive enroll progress event */
|
/** Receive enroll progress event */
|
||||||
private fun onEnrollmentProgress(remaining: Int, totalSteps: Int) {
|
private fun onEnrollmentProgress(remaining: Int, totalSteps: Int) {
|
||||||
fingerprintIcon.onEnrollmentProgress(remaining, totalSteps)
|
|
||||||
fingerprintProgressDrawable.onEnrollmentProgress(remaining, totalSteps)
|
fingerprintProgressDrawable.onEnrollmentProgress(remaining, totalSteps)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,10 +242,25 @@ class UdfpsEnrollViewV2(context: Context, attrs: AttributeSet?) : FrameLayout(co
|
|||||||
|
|
||||||
/** Indicates we should should restore the views saved state. */
|
/** Indicates we should should restore the views saved state. */
|
||||||
fun onEnrollProgressSaved(it: FingerEnrollState.EnrollProgress) {
|
fun onEnrollProgressSaved(it: FingerEnrollState.EnrollProgress) {
|
||||||
fingerprintIcon.onEnrollmentProgress(it.remainingSteps, it.totalStepsRequired, true)
|
|
||||||
fingerprintProgressDrawable.onEnrollmentProgress(it.remainingSteps, it.totalStepsRequired, true)
|
fingerprintProgressDrawable.onEnrollmentProgress(it.remainingSteps, it.totalStepsRequired, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Indicates we are recreating the UI from a saved state. */
|
||||||
|
fun onGuidedPointSaved(it: PointF) {
|
||||||
|
fingerprintIcon.updateGuidedEnrollment(it, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the finish animation has completed, and enrollment can proceed to the next stage
|
||||||
|
*/
|
||||||
|
fun setFinishAnimationCompleted(onFinishedAnimation: () -> Unit) {
|
||||||
|
this.onFinishedCompletionAnimation = onFinishedAnimation
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateGuidedEnrollment(point: PointF) {
|
||||||
|
fingerprintIcon.updateGuidedEnrollment(point, false)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "UdfpsEnrollView"
|
private const val TAG = "UdfpsEnrollView"
|
||||||
}
|
}
|
||||||
|
@@ -88,7 +88,10 @@ sealed interface FingerprintNavigationStep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** UiSteps should have a 1 to 1 mapping between each screen of FingerprintEnrollment */
|
/** UiSteps should have a 1 to 1 mapping between each screen of FingerprintEnrollment */
|
||||||
sealed class UiStep : FingerprintNavigationStep
|
sealed class UiStep(
|
||||||
|
val enterTransition: Transition = Transition.EnterFromRight,
|
||||||
|
val exitTransition: Transition = Transition.ExitToLeft,
|
||||||
|
) : FingerprintNavigationStep
|
||||||
|
|
||||||
/** This is the landing page for enrollment, where no content is shown. */
|
/** This is the landing page for enrollment, where no content is shown. */
|
||||||
data object Init : UiStep() {
|
data object Init : UiStep() {
|
||||||
@@ -103,7 +106,7 @@ sealed interface FingerprintNavigationStep {
|
|||||||
} else if (state.flowType is FastEnroll) {
|
} else if (state.flowType is FastEnroll) {
|
||||||
TransitionStep(Enrollment(state.fingerprintSensor!!))
|
TransitionStep(Enrollment(state.fingerprintSensor!!))
|
||||||
} else {
|
} else {
|
||||||
TransitionStep(Introduction)
|
TransitionStep(Introduction())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
@@ -118,7 +121,7 @@ sealed interface FingerprintNavigationStep {
|
|||||||
action: FingerprintAction,
|
action: FingerprintAction,
|
||||||
): FingerprintNavigationStep? {
|
): FingerprintNavigationStep? {
|
||||||
return when (action) {
|
return when (action) {
|
||||||
FingerprintAction.CONFIRM_DEVICE_SUCCESS -> TransitionStep(Introduction)
|
FingerprintAction.CONFIRM_DEVICE_SUCCESS -> TransitionStep(Introduction())
|
||||||
FingerprintAction.CONFIRM_DEVICE_FAIL -> Finish(null)
|
FingerprintAction.CONFIRM_DEVICE_FAIL -> Finish(null)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -126,7 +129,10 @@ sealed interface FingerprintNavigationStep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Indicates the FingerprintIntroduction screen is being presented to the user */
|
/** Indicates the FingerprintIntroduction screen is being presented to the user */
|
||||||
data object Introduction : UiStep() {
|
class Introduction(
|
||||||
|
enterTransition: Transition = Transition.EnterFromRight,
|
||||||
|
exitTransition: Transition = Transition.ExitToLeft,
|
||||||
|
) : UiStep(enterTransition, exitTransition) {
|
||||||
override fun update(
|
override fun update(
|
||||||
state: NavigationState,
|
state: NavigationState,
|
||||||
action: FingerprintAction,
|
action: FingerprintAction,
|
||||||
@@ -141,7 +147,11 @@ sealed interface FingerprintNavigationStep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Indicates the FingerprintEducation screen is being presented to the user */
|
/** Indicates the FingerprintEducation screen is being presented to the user */
|
||||||
data class Education(val sensor: FingerprintSensor) : UiStep() {
|
class Education(
|
||||||
|
val sensor: FingerprintSensor,
|
||||||
|
enterTransition: Transition = Transition.EnterFromRight,
|
||||||
|
exitTransition: Transition = Transition.ExitToLeft,
|
||||||
|
) : UiStep(enterTransition, exitTransition) {
|
||||||
override fun update(
|
override fun update(
|
||||||
state: NavigationState,
|
state: NavigationState,
|
||||||
action: FingerprintAction,
|
action: FingerprintAction,
|
||||||
@@ -149,7 +159,8 @@ sealed interface FingerprintNavigationStep {
|
|||||||
return when (action) {
|
return when (action) {
|
||||||
FingerprintAction.NEXT -> TransitionStep(Enrollment(state.fingerprintSensor!!))
|
FingerprintAction.NEXT -> TransitionStep(Enrollment(state.fingerprintSensor!!))
|
||||||
FingerprintAction.NEGATIVE_BUTTON_PRESSED,
|
FingerprintAction.NEGATIVE_BUTTON_PRESSED,
|
||||||
FingerprintAction.PREV -> TransitionStep(Introduction)
|
FingerprintAction.PREV ->
|
||||||
|
TransitionStep(Introduction(Transition.EnterFromLeft, Transition.ExitToRight))
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +190,10 @@ sealed interface FingerprintNavigationStep {
|
|||||||
): FingerprintNavigationStep? {
|
): FingerprintNavigationStep? {
|
||||||
return when (action) {
|
return when (action) {
|
||||||
FingerprintAction.NEXT -> Finish(null)
|
FingerprintAction.NEXT -> Finish(null)
|
||||||
FingerprintAction.PREV -> TransitionStep(Education(state.fingerprintSensor!!))
|
FingerprintAction.PREV ->
|
||||||
|
TransitionStep(
|
||||||
|
Education(state.fingerprintSensor!!, Transition.EnterFromLeft, Transition.ExitToRight)
|
||||||
|
)
|
||||||
FingerprintAction.ADD_ANOTHER -> TransitionStep(Enrollment(state.fingerprintSensor!!))
|
FingerprintAction.ADD_ANOTHER -> TransitionStep(Enrollment(state.fingerprintSensor!!))
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel
|
||||||
|
|
||||||
|
/** Indicates the type of transitions that can occur between fragments */
|
||||||
|
sealed class Transition {
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
data object EnterFromRight : Transition()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
data object ExitToRight : Transition()
|
||||||
|
}
|
||||||
|
|
@@ -90,7 +90,7 @@ class FingerprintEnrollIntroFragmentTest {
|
|||||||
|
|
||||||
private val navigationViewModel =
|
private val navigationViewModel =
|
||||||
FingerprintNavigationViewModel(
|
FingerprintNavigationViewModel(
|
||||||
Introduction,
|
Introduction(),
|
||||||
false,
|
false,
|
||||||
flowViewModel,
|
flowViewModel,
|
||||||
interactor
|
interactor
|
||||||
|
@@ -28,7 +28,7 @@ import platform.test.screenshot.ViewScreenshotTestRule.Mode
|
|||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class FingerprintEnrollIntroScreenshotTest {
|
class FingerprintEnrollIntroScreenshotTest {
|
||||||
private val injector: Injector = Injector(FingerprintNavigationStep.Introduction)
|
private val injector: Injector = Injector(FingerprintNavigationStep.Introduction())
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
@JvmField
|
@JvmField
|
||||||
|
Reference in New Issue
Block a user