[BiometricsV2] Add retry button
Add retry button for FingerprintEnrollErrorDialog and make sure that this button works well in the whole enrollment flow. Bug: 287168522 Test: manually test this dialog with error and rotate devices Test: atest FingerprintEnrollEnrollingViewModelTest Test: atest FingerprintEnrollErrorDialogViewModelTest Test: atest FingerprintEnrollProgressViewModelTest Test: atest FingerprintEnrollmentActivityTest Test: atest biometrics-enrollment-test Change-Id: Ica1d91d077ca322caca5551068f2a3c23b544361
This commit is contained in:
@@ -77,6 +77,7 @@ android_library {
|
|||||||
"setupcompat",
|
"setupcompat",
|
||||||
"setupdesign",
|
"setupdesign",
|
||||||
"androidx.lifecycle_lifecycle-runtime",
|
"androidx.lifecycle_lifecycle-runtime",
|
||||||
|
"androidx.lifecycle_lifecycle-runtime-ktx",
|
||||||
"androidx.lifecycle_lifecycle-viewmodel",
|
"androidx.lifecycle_lifecycle-viewmodel",
|
||||||
"guava",
|
"guava",
|
||||||
"jsr305",
|
"jsr305",
|
||||||
|
|||||||
@@ -70,25 +70,7 @@
|
|||||||
app:lottie_loop="true"
|
app:lottie_loop="true"
|
||||||
app:lottie_speed=".85" />
|
app:lottie_speed=".85" />
|
||||||
|
|
||||||
<com.android.settings.biometrics2.ui.widget.UdfpsEnrollView
|
<include layout="@layout/udfps_enroll_enrolling_v2_udfps_view"/>
|
||||||
android:id="@+id/udfps_animation_view"
|
|
||||||
android:layout_width="218.42dp"
|
|
||||||
android:layout_height="216dp"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginTop="553dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/udfps_enroll_animation_fp_progress_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
|
|
||||||
<!-- Fingerprint -->
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/udfps_enroll_animation_fp_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" />
|
|
||||||
</com.android.settings.biometrics2.ui.widget.UdfpsEnrollView>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/SudGlifButton.Secondary"
|
style="@style/SudGlifButton.Secondary"
|
||||||
|
|||||||
36
res/layout/udfps_enroll_enrolling_v2_udfps_view.xml
Normal file
36
res/layout/udfps_enroll_enrolling_v2_udfps_view.xml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2023 The Android Open Source Project
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
<com.android.settings.biometrics2.ui.widget.UdfpsEnrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/udfps_animation_view"
|
||||||
|
android:layout_width="218.42dp"
|
||||||
|
android:layout_height="216dp"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="553dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/udfps_enroll_animation_fp_progress_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<!-- Fingerprint -->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/udfps_enroll_animation_fp_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</com.android.settings.biometrics2.ui.widget.UdfpsEnrollView>
|
||||||
@@ -34,6 +34,7 @@ import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.Cha
|
|||||||
import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel;
|
import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel;
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel;
|
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel;
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel;
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel;
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel;
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel;
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel;
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel;
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel;
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel;
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel;
|
||||||
@@ -47,7 +48,7 @@ import com.android.systemui.unfold.compat.ScreenSizeFoldProvider;
|
|||||||
*/
|
*/
|
||||||
public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
|
public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
|
||||||
|
|
||||||
private static final String TAG = "BiometricsViewModelFact";
|
private static final String TAG = "BiometricsViewModelFactory";
|
||||||
|
|
||||||
public static final CreationExtras.Key<ChallengeGenerator> CHALLENGE_GENERATOR_KEY =
|
public static final CreationExtras.Key<ChallengeGenerator> CHALLENGE_GENERATOR_KEY =
|
||||||
new CreationExtras.Key<ChallengeGenerator>() {};
|
new CreationExtras.Key<ChallengeGenerator>() {};
|
||||||
@@ -113,7 +114,7 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
|
|||||||
final Integer userId = extras.get(USER_ID_KEY);
|
final Integer userId = extras.get(USER_ID_KEY);
|
||||||
final FingerprintRepository fingerprint = provider.getFingerprintRepository(
|
final FingerprintRepository fingerprint = provider.getFingerprintRepository(
|
||||||
application);
|
application);
|
||||||
if (fingerprint != null) {
|
if (fingerprint != null && userId != null) {
|
||||||
return (T) new FingerprintEnrollEnrollingViewModel(application, userId,
|
return (T) new FingerprintEnrollEnrollingViewModel(application, userId,
|
||||||
fingerprint);
|
fingerprint);
|
||||||
}
|
}
|
||||||
@@ -122,10 +123,15 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
|
|||||||
final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
|
final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
|
||||||
final FingerprintRepository fingerprint = provider.getFingerprintRepository(
|
final FingerprintRepository fingerprint = provider.getFingerprintRepository(
|
||||||
application);
|
application);
|
||||||
if (fingerprint != null && userId != null) {
|
if (fingerprint != null && userId != null && request != null) {
|
||||||
return (T) new FingerprintEnrollFinishViewModel(application, userId, request,
|
return (T) new FingerprintEnrollFinishViewModel(application, userId, request,
|
||||||
fingerprint);
|
fingerprint);
|
||||||
}
|
}
|
||||||
|
} else if (modelClass.isAssignableFrom(FingerprintEnrollErrorDialogViewModel.class)) {
|
||||||
|
final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
|
||||||
|
if (request != null) {
|
||||||
|
return (T) new FingerprintEnrollErrorDialogViewModel(application, request.isSuw());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return create(modelClass);
|
return create(modelClass);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2023 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.android.settings.biometrics2.ui.view
|
|
||||||
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.hardware.biometrics.BiometricConstants
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import com.android.settings.R
|
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fingerprint error dialog, will be shown when an error occurs during fingerprint enrollment.
|
|
||||||
*/
|
|
||||||
class FingerprintEnrollEnrollingErrorDialog : DialogFragment() {
|
|
||||||
|
|
||||||
private var mViewModel: FingerprintEnrollEnrollingViewModel? = null
|
|
||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
|
||||||
val value = mViewModel!!.errorDialogLiveData.value!!
|
|
||||||
return requireActivity().bindFingerprintEnrollEnrollingErrorDialog(
|
|
||||||
title = value.errTitle,
|
|
||||||
message = value.errMsg,
|
|
||||||
positiveButtonClickListener = { dialog: DialogInterface?, _: Int ->
|
|
||||||
dialog?.dismiss()
|
|
||||||
mViewModel?.onErrorDialogAction(
|
|
||||||
if (value.errMsgId == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT)
|
|
||||||
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
|
||||||
else
|
|
||||||
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
|
||||||
mViewModel = ViewModelProvider(requireActivity())[
|
|
||||||
FingerprintEnrollEnrollingViewModel::class.java]
|
|
||||||
super.onAttach(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Context.bindFingerprintEnrollEnrollingErrorDialog(
|
|
||||||
title: CharSequence?,
|
|
||||||
message: CharSequence?,
|
|
||||||
positiveButtonClickListener: DialogInterface.OnClickListener
|
|
||||||
): AlertDialog = AlertDialog.Builder(this)
|
|
||||||
.setTitle(title)
|
|
||||||
.setMessage(message)
|
|
||||||
.setCancelable(false)
|
|
||||||
.setPositiveButton(
|
|
||||||
R.string.security_settings_fingerprint_enroll_dialog_ok,
|
|
||||||
positiveButtonClickListener
|
|
||||||
)
|
|
||||||
.create()
|
|
||||||
.apply { setCanceledOnTouchOutside(false) }
|
|
||||||
@@ -23,13 +23,14 @@ import android.graphics.drawable.Animatable2
|
|||||||
import android.graphics.drawable.AnimatedVectorDrawable
|
import android.graphics.drawable.AnimatedVectorDrawable
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.graphics.drawable.LayerDrawable
|
import android.graphics.drawable.LayerDrawable
|
||||||
import android.hardware.fingerprint.FingerprintManager
|
import android.hardware.biometrics.BiometricFingerprintConstants
|
||||||
import android.hardware.fingerprint.FingerprintManager.FINGERPRINT_ERROR_CANCELED
|
import android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
|
import android.view.Surface
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.animation.AnimationUtils.loadInterpolator
|
import android.view.animation.AnimationUtils.loadInterpolator
|
||||||
@@ -39,17 +40,22 @@ import android.widget.TextView
|
|||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog
|
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
||||||
import com.google.android.setupcompat.template.FooterBarMixin
|
import com.google.android.setupcompat.template.FooterBarMixin
|
||||||
import com.google.android.setupcompat.template.FooterButton
|
import com.google.android.setupcompat.template.FooterButton
|
||||||
import com.google.android.setupdesign.GlifLayout
|
import com.google.android.setupdesign.GlifLayout
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment is used to handle enrolling process for rfps
|
* Fragment is used to handle enrolling process for rfps
|
||||||
@@ -64,25 +70,24 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
private val progressViewModel: FingerprintEnrollProgressViewModel
|
private val progressViewModel: FingerprintEnrollProgressViewModel
|
||||||
get() = _progressViewModel!!
|
get() = _progressViewModel!!
|
||||||
|
|
||||||
private val fastOutSlowInInterpolator: Interpolator
|
private var _errorDialogViewModel: FingerprintEnrollErrorDialogViewModel? = null
|
||||||
get() = loadInterpolator(requireActivity(), android.R.interpolator.fast_out_slow_in)
|
private val errorDialogViewModel: FingerprintEnrollErrorDialogViewModel
|
||||||
|
get() = _errorDialogViewModel!!
|
||||||
|
|
||||||
private val linearOutSlowInInterpolator: Interpolator
|
private var fastOutSlowInInterpolator: Interpolator? = null
|
||||||
get() = loadInterpolator(requireActivity(), android.R.interpolator.linear_out_slow_in)
|
private var linearOutSlowInInterpolator: Interpolator? = null
|
||||||
|
private var fastOutLinearInInterpolator: Interpolator? = null
|
||||||
private val fastOutLinearInInterpolator: Interpolator
|
|
||||||
get() = loadInterpolator(requireActivity(), android.R.interpolator.fast_out_linear_in)
|
|
||||||
|
|
||||||
private var isAnimationCancelled = false
|
private var isAnimationCancelled = false
|
||||||
|
|
||||||
private var enrollingRfpsView: GlifLayout? = null
|
private var enrollingView: GlifLayout? = null
|
||||||
private val progressBar: ProgressBar
|
private val progressBar: ProgressBar
|
||||||
get() = enrollingRfpsView!!.findViewById<ProgressBar>(R.id.fingerprint_progress_bar)!!
|
get() = enrollingView!!.findViewById(R.id.fingerprint_progress_bar)!!
|
||||||
|
|
||||||
private var progressAnim: ObjectAnimator? = null
|
private var progressAnim: ObjectAnimator? = null
|
||||||
|
|
||||||
private val errorText: TextView
|
private val errorText: TextView
|
||||||
get() = enrollingRfpsView!!.findViewById<TextView>(R.id.error_text)!!
|
get() = enrollingView!!.findViewById(R.id.error_text)!!
|
||||||
|
|
||||||
private val iconAnimationDrawable: AnimatedVectorDrawable?
|
private val iconAnimationDrawable: AnimatedVectorDrawable?
|
||||||
get() = (progressBar.background as LayerDrawable)
|
get() = (progressBar.background as LayerDrawable)
|
||||||
@@ -94,53 +99,47 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
|
|
||||||
private var iconTouchCount = 0
|
private var iconTouchCount = 0
|
||||||
|
|
||||||
private val touchAgainRunnable =
|
private val touchAgainRunnable = Runnable {
|
||||||
Runnable {
|
showError(
|
||||||
showError(
|
// Use enrollingView to getString to prevent activity is missing during rotation
|
||||||
// Use enrollingRfpsView to getString to prevent activity is missing during rotation
|
enrollingView!!.context.getString(
|
||||||
enrollingRfpsView!!.context.getString(
|
R.string.security_settings_fingerprint_enroll_lift_touch_again
|
||||||
R.string.security_settings_fingerprint_enroll_lift_touch_again
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private val onSkipClickListener = View.OnClickListener { _: View? ->
|
private val onSkipClickListener = View.OnClickListener { _: View? ->
|
||||||
enrollingViewModel.setOnSkipPressed()
|
enrollingViewModel.setOnSkipPressed()
|
||||||
cancelEnrollment()
|
cancelEnrollment(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val progressObserver: Observer<EnrollmentProgress> =
|
private var enrollingCancelSignal: Any? = null
|
||||||
Observer<EnrollmentProgress> { progress: EnrollmentProgress? ->
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "progressObserver($progress)")
|
|
||||||
}
|
|
||||||
if (progress != null && progress.steps >= 0) {
|
|
||||||
onEnrollmentProgressChange(progress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val helpMessageObserver: Observer<EnrollmentStatusMessage> =
|
private val progressObserver = Observer { progress: EnrollmentProgress? ->
|
||||||
Observer<EnrollmentStatusMessage> { helpMessage: EnrollmentStatusMessage? ->
|
if (progress != null && progress.steps >= 0) {
|
||||||
if (DEBUG) {
|
onEnrollmentProgressChange(progress)
|
||||||
Log.d(TAG, "helpMessageObserver($helpMessage)")
|
|
||||||
}
|
|
||||||
helpMessage?.let { onEnrollmentHelp(it) }
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val errorMessageObserver: Observer<EnrollmentStatusMessage> =
|
private val helpMessageObserver = Observer { helpMessage: EnrollmentStatusMessage? ->
|
||||||
Observer<EnrollmentStatusMessage> { errorMessage: EnrollmentStatusMessage? ->
|
helpMessage?.let { onEnrollmentHelp(it) }
|
||||||
if (DEBUG) {
|
}
|
||||||
Log.d(TAG, "errorMessageObserver($errorMessage)")
|
|
||||||
}
|
private val errorMessageObserver = Observer { errorMessage: EnrollmentStatusMessage? ->
|
||||||
errorMessage?.let { onEnrollmentError(it) }
|
Log.d(TAG, "errorMessageObserver($errorMessage)")
|
||||||
}
|
errorMessage?.let { onEnrollmentError(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val canceledSignalObserver = Observer { canceledSignal: Any? ->
|
||||||
|
canceledSignal?.let { onEnrollmentCanceled(it) }
|
||||||
|
}
|
||||||
|
|
||||||
private val onBackPressedCallback: OnBackPressedCallback =
|
private val onBackPressedCallback: OnBackPressedCallback =
|
||||||
object : OnBackPressedCallback(true) {
|
object : OnBackPressedCallback(true) {
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
isEnabled = false
|
isEnabled = false
|
||||||
enrollingViewModel.setOnBackPressed()
|
enrollingViewModel.setOnBackPressed()
|
||||||
cancelEnrollment()
|
cancelEnrollment(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +147,7 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
ViewModelProvider(requireActivity()).let { provider ->
|
ViewModelProvider(requireActivity()).let { provider ->
|
||||||
_enrollingViewModel = provider[FingerprintEnrollEnrollingViewModel::class.java]
|
_enrollingViewModel = provider[FingerprintEnrollEnrollingViewModel::class.java]
|
||||||
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
||||||
|
_errorDialogViewModel = provider[FingerprintEnrollErrorDialogViewModel::class.java]
|
||||||
}
|
}
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(onBackPressedCallback)
|
requireActivity().onBackPressedDispatcher.addCallback(onBackPressedCallback)
|
||||||
@@ -162,10 +162,10 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View {
|
): View {
|
||||||
enrollingRfpsView = inflater.inflate(
|
enrollingView = inflater.inflate(
|
||||||
R.layout.fingerprint_enroll_enrolling, container, false
|
R.layout.fingerprint_enroll_enrolling, container, false
|
||||||
) as GlifLayout
|
) as GlifLayout
|
||||||
return enrollingRfpsView!!
|
return enrollingView!!
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
@@ -193,16 +193,46 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requireActivity().bindFingerprintEnrollEnrollingRfpsView(
|
requireActivity().bindFingerprintEnrollEnrollingRfpsView(
|
||||||
view = enrollingRfpsView!!,
|
view = enrollingView!!,
|
||||||
onSkipClickListener = onSkipClickListener
|
onSkipClickListener = onSkipClickListener
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fastOutSlowInInterpolator =
|
||||||
|
loadInterpolator(requireContext(), android.R.interpolator.fast_out_slow_in)
|
||||||
|
linearOutSlowInInterpolator =
|
||||||
|
loadInterpolator(requireContext(), android.R.interpolator.linear_out_slow_in)
|
||||||
|
fastOutLinearInInterpolator =
|
||||||
|
loadInterpolator(requireContext(), android.R.interpolator.fast_out_linear_in)
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
errorDialogViewModel.triggerRetryFlow.collect { retryEnrollment() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun retryEnrollment() {
|
||||||
|
isAnimationCancelled = false
|
||||||
|
startIconAnimation()
|
||||||
|
startEnrollment()
|
||||||
|
|
||||||
|
clearError()
|
||||||
|
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
||||||
|
updateTitleAndDescription()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
isAnimationCancelled = false
|
|
||||||
startIconAnimation()
|
val isEnrolling = progressViewModel.isEnrolling
|
||||||
startEnrollment()
|
val isErrorDialogShown = errorDialogViewModel.isDialogShown
|
||||||
|
Log.d(TAG, "onStart(), isEnrolling:$isEnrolling, isErrorDialog:$isErrorDialogShown")
|
||||||
|
if (!isErrorDialogShown) {
|
||||||
|
isAnimationCancelled = false
|
||||||
|
startIconAnimation()
|
||||||
|
startEnrollment()
|
||||||
|
}
|
||||||
|
|
||||||
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
||||||
updateTitleAndDescription()
|
updateTitleAndDescription()
|
||||||
}
|
}
|
||||||
@@ -219,32 +249,44 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
stopIconAnimation()
|
stopIconAnimation()
|
||||||
removeEnrollmentObservers()
|
removeEnrollmentObservers()
|
||||||
if (!activity!!.isChangingConfigurations && progressViewModel.isEnrolling) {
|
val isEnrolling = progressViewModel.isEnrolling
|
||||||
progressViewModel.cancelEnrollment()
|
val isConfigChange = requireActivity().isChangingConfigurations
|
||||||
|
Log.d(TAG, "onStop(), enrolling:$isEnrolling isConfigChange:$isConfigChange")
|
||||||
|
if (isEnrolling && !isConfigChange) {
|
||||||
|
cancelEnrollment(false)
|
||||||
}
|
}
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeEnrollmentObservers() {
|
private fun removeEnrollmentObservers() {
|
||||||
preRemoveEnrollmentObservers()
|
|
||||||
progressViewModel.errorMessageLiveData.removeObserver(errorMessageObserver)
|
progressViewModel.errorMessageLiveData.removeObserver(errorMessageObserver)
|
||||||
}
|
|
||||||
|
|
||||||
private fun preRemoveEnrollmentObservers() {
|
|
||||||
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
||||||
progressViewModel.helpMessageLiveData.removeObserver(helpMessageObserver)
|
progressViewModel.helpMessageLiveData.removeObserver(helpMessageObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelEnrollment() {
|
private fun cancelEnrollment(waitForLastCancelErrMsg: Boolean) {
|
||||||
preRemoveEnrollmentObservers()
|
if (!progressViewModel.isEnrolling) {
|
||||||
progressViewModel.cancelEnrollment()
|
Log.d(TAG, "cancelEnrollment(), failed because isEnrolling is false")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
removeEnrollmentObservers()
|
||||||
|
if (waitForLastCancelErrMsg) {
|
||||||
|
progressViewModel.canceledSignalLiveData.observe(this, canceledSignalObserver)
|
||||||
|
} else {
|
||||||
|
enrollingCancelSignal = null
|
||||||
|
}
|
||||||
|
val cancelResult: Boolean = progressViewModel.cancelEnrollment()
|
||||||
|
if (!cancelResult) {
|
||||||
|
Log.e(TAG, "cancelEnrollment(), failed to cancel enrollment")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startEnrollment() {
|
private fun startEnrollment() {
|
||||||
val startResult: Boolean =
|
enrollingCancelSignal = progressViewModel.startEnrollment(ENROLL_ENROLL)
|
||||||
progressViewModel.startEnrollment(FingerprintManager.ENROLL_ENROLL)
|
if (enrollingCancelSignal == null) {
|
||||||
if (!startResult) {
|
|
||||||
Log.e(TAG, "startEnrollment(), failed")
|
Log.e(TAG, "startEnrollment(), failed")
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "startEnrollment(), success")
|
||||||
}
|
}
|
||||||
progressViewModel.progressLiveData.observe(this, progressObserver)
|
progressViewModel.progressLiveData.observe(this, progressObserver)
|
||||||
progressViewModel.helpMessageLiveData.observe(this, helpMessageObserver)
|
progressViewModel.helpMessageLiveData.observe(this, helpMessageObserver)
|
||||||
@@ -252,6 +294,7 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onEnrollmentHelp(helpMessage: EnrollmentStatusMessage) {
|
private fun onEnrollmentHelp(helpMessage: EnrollmentStatusMessage) {
|
||||||
|
Log.d(TAG, "onEnrollmentHelp($helpMessage)")
|
||||||
val helpStr: CharSequence = helpMessage.str
|
val helpStr: CharSequence = helpMessage.str
|
||||||
if (!TextUtils.isEmpty(helpStr)) {
|
if (!TextUtils.isEmpty(helpStr)) {
|
||||||
errorText.removeCallbacks(touchAgainRunnable)
|
errorText.removeCallbacks(touchAgainRunnable)
|
||||||
@@ -261,29 +304,27 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
|
|
||||||
private fun onEnrollmentError(errorMessage: EnrollmentStatusMessage) {
|
private fun onEnrollmentError(errorMessage: EnrollmentStatusMessage) {
|
||||||
stopIconAnimation()
|
stopIconAnimation()
|
||||||
removeEnrollmentObservers()
|
|
||||||
if (enrollingViewModel.onBackPressed
|
cancelEnrollment(true)
|
||||||
&& errorMessage.msgId == FINGERPRINT_ERROR_CANCELED
|
lifecycleScope.launch {
|
||||||
) {
|
Log.d(TAG, "newDialog $errorMessage")
|
||||||
enrollingViewModel.onCancelledDueToOnBackPressed()
|
errorDialogViewModel.newDialog(errorMessage.msgId)
|
||||||
} else if (enrollingViewModel.onSkipPressed
|
}
|
||||||
&& errorMessage.msgId == FINGERPRINT_ERROR_CANCELED
|
}
|
||||||
) {
|
|
||||||
enrollingViewModel.onCancelledDueToOnSkipPressed()
|
private fun onEnrollmentCanceled(canceledSignal: Any) {
|
||||||
} else {
|
Log.d(
|
||||||
val errMsgId: Int = errorMessage.msgId
|
TAG,
|
||||||
enrollingViewModel.showErrorDialog(
|
"onEnrollmentCanceled enrolling:$enrollingCancelSignal, canceled:$canceledSignal"
|
||||||
FingerprintEnrollEnrollingViewModel.ErrorDialogData(
|
)
|
||||||
enrollingRfpsView!!.context.getString(
|
if (enrollingCancelSignal === canceledSignal) {
|
||||||
FingerprintErrorDialog.getErrorMessage(errMsgId)
|
progressViewModel.canceledSignalLiveData.removeObserver(canceledSignalObserver)
|
||||||
),
|
progressViewModel.clearProgressLiveData()
|
||||||
enrollingRfpsView!!.context.getString(
|
if (enrollingViewModel.onBackPressed) {
|
||||||
FingerprintErrorDialog.getErrorTitle(errMsgId)
|
enrollingViewModel.onCancelledDueToOnBackPressed()
|
||||||
),
|
} else if (enrollingViewModel.onSkipPressed) {
|
||||||
errMsgId
|
enrollingViewModel.onCancelledDueToOnSkipPressed()
|
||||||
)
|
}
|
||||||
)
|
|
||||||
progressViewModel.cancelEnrollment()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,11 +337,10 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateProgress(animate: Boolean, enrollmentProgress: EnrollmentProgress) {
|
private fun updateProgress(animate: Boolean, enrollmentProgress: EnrollmentProgress) {
|
||||||
if (!progressViewModel.isEnrolling) {
|
|
||||||
Log.d(TAG, "Enrollment not started yet")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val progress = getProgress(enrollmentProgress)
|
val progress = getProgress(enrollmentProgress)
|
||||||
|
Log.d(TAG, "updateProgress($animate, $enrollmentProgress), old:${progressBar.progress}"
|
||||||
|
+ ", new:$progress")
|
||||||
|
|
||||||
// Only clear the error when progress has been made.
|
// Only clear the error when progress has been made.
|
||||||
// TODO (b/234772728) Add tests.
|
// TODO (b/234772728) Add tests.
|
||||||
if (progressBar.progress < progress) {
|
if (progressBar.progress < progress) {
|
||||||
@@ -328,7 +368,7 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
errorText.text = error
|
errorText.text = error
|
||||||
if (errorText.visibility == View.INVISIBLE) {
|
if (errorText.visibility == View.INVISIBLE) {
|
||||||
errorText.visibility = View.VISIBLE
|
errorText.visibility = View.VISIBLE
|
||||||
errorText.translationY = enrollingRfpsView!!.context.resources.getDimensionPixelSize(
|
errorText.translationY = enrollingView!!.context.resources.getDimensionPixelSize(
|
||||||
R.dimen.fingerprint_error_text_appear_distance
|
R.dimen.fingerprint_error_text_appear_distance
|
||||||
).toFloat()
|
).toFloat()
|
||||||
errorText.alpha = 0f
|
errorText.alpha = 0f
|
||||||
@@ -359,7 +399,7 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
.setDuration(100)
|
.setDuration(100)
|
||||||
.setInterpolator(fastOutLinearInInterpolator)
|
.setInterpolator(fastOutLinearInInterpolator)
|
||||||
.withEndAction { errorText!!.visibility = View.INVISIBLE }
|
.withEndAction { errorText.visibility = View.INVISIBLE }
|
||||||
.start()
|
.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,8 +425,8 @@ class FingerprintEnrollEnrollingRfpsFragment : Fragment() {
|
|||||||
|
|
||||||
private fun updateTitleAndDescription() {
|
private fun updateTitleAndDescription() {
|
||||||
val progressLiveData: EnrollmentProgress = progressViewModel.progressLiveData.value!!
|
val progressLiveData: EnrollmentProgress = progressViewModel.progressLiveData.value!!
|
||||||
GlifLayoutHelper(activity!!, enrollingRfpsView!!).setDescriptionText(
|
GlifLayoutHelper(activity!!, enrollingView!!).setDescriptionText(
|
||||||
enrollingRfpsView!!.context.getString(
|
enrollingView!!.context.getString(
|
||||||
if (progressLiveData.steps == -1)
|
if (progressLiveData.steps == -1)
|
||||||
R.string.security_settings_fingerprint_enroll_start_message
|
R.string.security_settings_fingerprint_enroll_start_message
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -21,10 +21,11 @@ import android.annotation.RawRes
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.ColorFilter
|
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
import android.graphics.PorterDuffColorFilter
|
import android.graphics.PorterDuffColorFilter
|
||||||
import android.hardware.fingerprint.FingerprintManager
|
import android.hardware.biometrics.BiometricFingerprintConstants
|
||||||
|
import android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL
|
||||||
|
import android.hardware.fingerprint.FingerprintManager.FINGERPRINT_ERROR_CANCELED
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@@ -39,24 +40,29 @@ import android.widget.RelativeLayout
|
|||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.airbnb.lottie.LottieAnimationView
|
import com.airbnb.lottie.LottieAnimationView
|
||||||
import com.airbnb.lottie.LottieComposition
|
import com.airbnb.lottie.LottieComposition
|
||||||
import com.airbnb.lottie.LottieCompositionFactory
|
import com.airbnb.lottie.LottieCompositionFactory
|
||||||
import com.airbnb.lottie.LottieProperty
|
import com.airbnb.lottie.LottieProperty
|
||||||
import com.airbnb.lottie.model.KeyPath
|
import com.airbnb.lottie.model.KeyPath
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog
|
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
||||||
import com.google.android.setupcompat.template.FooterBarMixin
|
import com.google.android.setupcompat.template.FooterBarMixin
|
||||||
import com.google.android.setupcompat.template.FooterButton
|
import com.google.android.setupcompat.template.FooterButton
|
||||||
import com.google.android.setupdesign.GlifLayout
|
import com.google.android.setupdesign.GlifLayout
|
||||||
import com.google.android.setupdesign.template.DescriptionMixin
|
import com.google.android.setupdesign.template.DescriptionMixin
|
||||||
import com.google.android.setupdesign.template.HeaderMixin
|
import com.google.android.setupdesign.template.HeaderMixin
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,13 +78,17 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
private val progressViewModel: FingerprintEnrollProgressViewModel
|
private val progressViewModel: FingerprintEnrollProgressViewModel
|
||||||
get() = _progressViewModel!!
|
get() = _progressViewModel!!
|
||||||
|
|
||||||
|
private var _errorDialogViewModel: FingerprintEnrollErrorDialogViewModel? = null
|
||||||
|
private val errorDialogViewModel: FingerprintEnrollErrorDialogViewModel
|
||||||
|
get() = _errorDialogViewModel!!
|
||||||
|
|
||||||
private val fastOutSlowInInterpolator: Interpolator
|
private val fastOutSlowInInterpolator: Interpolator
|
||||||
get() = AnimationUtils.loadInterpolator(activity, R.interpolator.fast_out_slow_in)
|
get() = AnimationUtils.loadInterpolator(activity, R.interpolator.fast_out_slow_in)
|
||||||
|
|
||||||
private var enrollingSfpsView: GlifLayout? = null
|
private var enrollingView: GlifLayout? = null
|
||||||
|
|
||||||
private val progressBar: ProgressBar
|
private val progressBar: ProgressBar
|
||||||
get() = enrollingSfpsView!!.findViewById<ProgressBar>(R.id.fingerprint_progress_bar)!!
|
get() = enrollingView!!.findViewById(R.id.fingerprint_progress_bar)!!
|
||||||
|
|
||||||
private var progressAnim: ObjectAnimator? = null
|
private var progressAnim: ObjectAnimator? = null
|
||||||
|
|
||||||
@@ -96,7 +106,7 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val illustrationLottie: LottieAnimationView
|
private val illustrationLottie: LottieAnimationView
|
||||||
get() = enrollingSfpsView!!.findViewById<LottieAnimationView>(R.id.illustration_lottie)!!
|
get() = enrollingView!!.findViewById(R.id.illustration_lottie)!!
|
||||||
|
|
||||||
private var haveShownSfpsNoAnimationLottie = false
|
private var haveShownSfpsNoAnimationLottie = false
|
||||||
private var haveShownSfpsCenterLottie = false
|
private var haveShownSfpsCenterLottie = false
|
||||||
@@ -110,78 +120,82 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
|
|
||||||
private val showIconTouchDialogRunnable = Runnable { showIconTouchDialog() }
|
private val showIconTouchDialogRunnable = Runnable { showIconTouchDialog() }
|
||||||
|
|
||||||
|
private var enrollingCancelSignal: Any? = null
|
||||||
|
|
||||||
// Give the user a chance to see progress completed before jumping to the next stage.
|
// Give the user a chance to see progress completed before jumping to the next stage.
|
||||||
private val delayedFinishRunnable = Runnable { enrollingViewModel.onEnrollingDone() }
|
private val delayedFinishRunnable = Runnable { enrollingViewModel.onEnrollingDone() }
|
||||||
|
|
||||||
private val onSkipClickListener = View.OnClickListener { _: View? ->
|
private val onSkipClickListener = View.OnClickListener { _: View? ->
|
||||||
enrollingViewModel.setOnSkipPressed()
|
enrollingViewModel.setOnSkipPressed()
|
||||||
cancelEnrollment()
|
cancelEnrollment(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val progressObserver: Observer<EnrollmentProgress> =
|
private val progressObserver = Observer { progress: EnrollmentProgress? ->
|
||||||
Observer<EnrollmentProgress> { progress: EnrollmentProgress? ->
|
if (progress != null && progress.steps >= 0) {
|
||||||
if (DEBUG) {
|
onEnrollmentProgressChange(progress)
|
||||||
Log.d(TAG, "progressObserver($progress)")
|
|
||||||
}
|
|
||||||
if (progress != null && progress.steps >= 0) {
|
|
||||||
onEnrollmentProgressChange(progress)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val helpMessageObserver: Observer<EnrollmentStatusMessage> =
|
private val helpMessageObserver = Observer { helpMessage: EnrollmentStatusMessage? ->
|
||||||
Observer<EnrollmentStatusMessage> { helpMessage: EnrollmentStatusMessage? ->
|
helpMessage?.let { onEnrollmentHelp(it) }
|
||||||
if (DEBUG) {
|
}
|
||||||
Log.d(TAG, "helpMessageObserver($helpMessage)")
|
|
||||||
}
|
|
||||||
helpMessage?.let { onEnrollmentHelp(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private val errorMessageObserver: Observer<EnrollmentStatusMessage> =
|
private val errorMessageObserver = Observer { errorMessage: EnrollmentStatusMessage? ->
|
||||||
Observer<EnrollmentStatusMessage> { errorMessage: EnrollmentStatusMessage? ->
|
Log.d(TAG, "errorMessageObserver($errorMessage)")
|
||||||
if (DEBUG) {
|
errorMessage?.let { onEnrollmentError(it) }
|
||||||
Log.d(TAG, "errorMessageObserver($errorMessage)")
|
}
|
||||||
|
|
||||||
|
private val canceledSignalObserver = Observer { canceledSignal: Any? ->
|
||||||
|
Log.d(TAG, "canceledSignalObserver($canceledSignal)")
|
||||||
|
canceledSignal?.let { onEnrollmentCanceled(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val onBackPressedCallback: OnBackPressedCallback =
|
||||||
|
object : OnBackPressedCallback(true) {
|
||||||
|
override fun handleOnBackPressed() {
|
||||||
|
isEnabled = false
|
||||||
|
enrollingViewModel.setOnBackPressed()
|
||||||
|
cancelEnrollment(true)
|
||||||
}
|
}
|
||||||
errorMessage?.let { onEnrollmentError(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
override fun onAttach(context: Context) {
|
||||||
ViewModelProvider(requireActivity()).let { provider ->
|
ViewModelProvider(requireActivity()).let { provider ->
|
||||||
_enrollingViewModel = provider[FingerprintEnrollEnrollingViewModel::class.java]
|
_enrollingViewModel = provider[FingerprintEnrollEnrollingViewModel::class.java]
|
||||||
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
||||||
|
_errorDialogViewModel = provider[FingerprintEnrollErrorDialogViewModel::class.java]
|
||||||
}
|
}
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(
|
requireActivity().onBackPressedDispatcher.addCallback(onBackPressedCallback)
|
||||||
object : OnBackPressedCallback(true) {
|
}
|
||||||
override fun handleOnBackPressed() {
|
|
||||||
isEnabled = false
|
override fun onDetach() {
|
||||||
enrollingViewModel.setOnBackPressed()
|
onBackPressedCallback.isEnabled = false
|
||||||
cancelEnrollment()
|
super.onDetach()
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
enrollingSfpsView = inflater.inflate(
|
enrollingView = inflater.inflate(
|
||||||
R.layout.sfps_enroll_enrolling,
|
R.layout.sfps_enroll_enrolling,
|
||||||
container, false
|
container, false
|
||||||
) as GlifLayout
|
) as GlifLayout
|
||||||
return enrollingSfpsView
|
return enrollingView
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
requireActivity().bindFingerprintEnrollEnrollingSfpsView(
|
requireActivity().bindFingerprintEnrollEnrollingSfpsView(
|
||||||
view = enrollingSfpsView!!,
|
view = enrollingView!!,
|
||||||
onSkipClickListener = onSkipClickListener
|
onSkipClickListener = onSkipClickListener
|
||||||
)
|
)
|
||||||
|
|
||||||
// setHelpAnimation()
|
// setHelpAnimation()
|
||||||
helpAnimation = ObjectAnimator.ofFloat(
|
helpAnimation = ObjectAnimator.ofFloat(
|
||||||
enrollingSfpsView!!.findViewById<RelativeLayout>(R.id.progress_lottie)!!,
|
enrollingView!!.findViewById<RelativeLayout>(R.id.progress_lottie)!!,
|
||||||
"translationX" /* propertyName */,
|
"translationX" /* propertyName */,
|
||||||
0f,
|
0f,
|
||||||
HELP_ANIMATION_TRANSLATION_X,
|
HELP_ANIMATION_TRANSLATION_X,
|
||||||
@@ -212,48 +226,79 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
errorDialogViewModel.triggerRetryFlow.collect { retryEnrollment() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun retryEnrollment() {
|
||||||
|
startEnrollment()
|
||||||
|
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
startEnrollment()
|
val isEnrolling = progressViewModel.isEnrolling
|
||||||
|
val isErrorDialogShown = errorDialogViewModel.isDialogShown
|
||||||
|
Log.d(TAG, "onStart(), isEnrolling:$isEnrolling, isErrorDialog:$isErrorDialogShown")
|
||||||
|
if (!isErrorDialogShown) {
|
||||||
|
startEnrollment()
|
||||||
|
}
|
||||||
|
|
||||||
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
||||||
progressViewModel.helpMessageLiveData.value?.let {
|
progressViewModel.helpMessageLiveData.value.let {
|
||||||
onEnrollmentHelp(it)
|
if (it != null) {
|
||||||
} ?: run {
|
onEnrollmentHelp(it)
|
||||||
clearError()
|
} else {
|
||||||
updateTitleAndDescription()
|
clearError()
|
||||||
|
updateTitleAndDescription()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
removeEnrollmentObservers()
|
removeEnrollmentObservers()
|
||||||
if (!activity!!.isChangingConfigurations && progressViewModel.isEnrolling) {
|
val isEnrolling = progressViewModel.isEnrolling
|
||||||
progressViewModel.cancelEnrollment()
|
val isConfigChange = requireActivity().isChangingConfigurations
|
||||||
|
Log.d(TAG, "onStop(), enrolling:$isEnrolling isConfigChange:$isConfigChange")
|
||||||
|
if (isEnrolling && !isConfigChange) {
|
||||||
|
cancelEnrollment(false)
|
||||||
}
|
}
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeEnrollmentObservers() {
|
private fun removeEnrollmentObservers() {
|
||||||
preRemoveEnrollmentObservers()
|
|
||||||
progressViewModel.errorMessageLiveData.removeObserver(errorMessageObserver)
|
progressViewModel.errorMessageLiveData.removeObserver(errorMessageObserver)
|
||||||
}
|
|
||||||
|
|
||||||
private fun preRemoveEnrollmentObservers() {
|
|
||||||
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
||||||
progressViewModel.helpMessageLiveData.removeObserver(helpMessageObserver)
|
progressViewModel.helpMessageLiveData.removeObserver(helpMessageObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelEnrollment() {
|
private fun cancelEnrollment(waitForLastCancelErrMsg: Boolean) {
|
||||||
preRemoveEnrollmentObservers()
|
if (!progressViewModel.isEnrolling) {
|
||||||
progressViewModel.cancelEnrollment()
|
Log.d(TAG, "cancelEnrollment(), failed because isEnrolling is false")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
removeEnrollmentObservers()
|
||||||
|
if (waitForLastCancelErrMsg) {
|
||||||
|
progressViewModel.canceledSignalLiveData.observe(this, canceledSignalObserver)
|
||||||
|
} else {
|
||||||
|
enrollingCancelSignal = null
|
||||||
|
}
|
||||||
|
val cancelResult: Boolean = progressViewModel.cancelEnrollment()
|
||||||
|
if (!cancelResult) {
|
||||||
|
Log.e(TAG, "cancelEnrollment(), failed to cancel enrollment")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startEnrollment() {
|
private fun startEnrollment() {
|
||||||
val startResult: Boolean =
|
enrollingCancelSignal = progressViewModel.startEnrollment(ENROLL_ENROLL)
|
||||||
progressViewModel.startEnrollment(FingerprintManager.ENROLL_ENROLL)
|
if (enrollingCancelSignal == null) {
|
||||||
if (!startResult) {
|
|
||||||
Log.e(TAG, "startEnrollment(), failed")
|
Log.e(TAG, "startEnrollment(), failed")
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "startEnrollment(), success")
|
||||||
}
|
}
|
||||||
progressViewModel.progressLiveData.observe(this, progressObserver)
|
progressViewModel.progressLiveData.observe(this, progressObserver)
|
||||||
progressViewModel.helpMessageLiveData.observe(this, helpMessageObserver)
|
progressViewModel.helpMessageLiveData.observe(this, helpMessageObserver)
|
||||||
@@ -261,7 +306,7 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun configureEnrollmentStage(description: CharSequence, @RawRes lottie: Int) {
|
private fun configureEnrollmentStage(description: CharSequence, @RawRes lottie: Int) {
|
||||||
GlifLayoutHelper(requireActivity(), enrollingSfpsView!!).setDescriptionText(description)
|
GlifLayoutHelper(requireActivity(), enrollingView!!).setDescriptionText(description)
|
||||||
LottieCompositionFactory.fromRawRes(activity, lottie)
|
LottieCompositionFactory.fromRawRes(activity, lottie)
|
||||||
.addListener { c: LottieComposition ->
|
.addListener { c: LottieComposition ->
|
||||||
illustrationLottie.setComposition(c)
|
illustrationLottie.setComposition(c)
|
||||||
@@ -290,6 +335,7 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onEnrollmentHelp(helpMessage: EnrollmentStatusMessage) {
|
private fun onEnrollmentHelp(helpMessage: EnrollmentStatusMessage) {
|
||||||
|
Log.d(TAG, "onEnrollmentHelp($helpMessage)")
|
||||||
val helpStr: CharSequence = helpMessage.str
|
val helpStr: CharSequence = helpMessage.str
|
||||||
if (helpStr.isNotEmpty()) {
|
if (helpStr.isNotEmpty()) {
|
||||||
showError(helpStr)
|
showError(helpStr)
|
||||||
@@ -297,25 +343,26 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onEnrollmentError(errorMessage: EnrollmentStatusMessage) {
|
private fun onEnrollmentError(errorMessage: EnrollmentStatusMessage) {
|
||||||
removeEnrollmentObservers()
|
cancelEnrollment(true)
|
||||||
if (enrollingViewModel.onBackPressed
|
lifecycleScope.launch {
|
||||||
&& errorMessage.msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
|
Log.d(TAG, "newDialog $errorMessage")
|
||||||
) {
|
errorDialogViewModel.newDialog(errorMessage.msgId)
|
||||||
enrollingViewModel.onCancelledDueToOnBackPressed()
|
}
|
||||||
} else if (enrollingViewModel.onSkipPressed
|
}
|
||||||
&& errorMessage.msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
|
|
||||||
) {
|
private fun onEnrollmentCanceled(canceledSignal: Any) {
|
||||||
enrollingViewModel.onCancelledDueToOnSkipPressed()
|
Log.d(
|
||||||
} else {
|
TAG,
|
||||||
val errMsgId: Int = errorMessage.msgId
|
"onEnrollmentCanceled enrolling:$enrollingCancelSignal, canceled:$canceledSignal"
|
||||||
enrollingViewModel.showErrorDialog(
|
)
|
||||||
FingerprintEnrollEnrollingViewModel.ErrorDialogData(
|
if (enrollingCancelSignal === canceledSignal) {
|
||||||
getString(FingerprintErrorDialog.getErrorMessage(errMsgId)),
|
progressViewModel.canceledSignalLiveData.removeObserver(canceledSignalObserver)
|
||||||
getString(FingerprintErrorDialog.getErrorTitle(errMsgId)),
|
progressViewModel.clearProgressLiveData()
|
||||||
errMsgId
|
if (enrollingViewModel.onBackPressed) {
|
||||||
)
|
enrollingViewModel.onCancelledDueToOnBackPressed()
|
||||||
)
|
} else if (enrollingViewModel.onSkipPressed) {
|
||||||
progressViewModel.cancelEnrollment()
|
enrollingViewModel.onCancelledDueToOnSkipPressed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,6 +392,8 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val progress = getProgress(enrollmentProgress)
|
val progress = getProgress(enrollmentProgress)
|
||||||
|
Log.d(TAG, "updateProgress($animate, $enrollmentProgress), old:${progressBar.progress}"
|
||||||
|
+ ", new:$progress")
|
||||||
|
|
||||||
// Only clear the error when progress has been made.
|
// Only clear the error when progress has been made.
|
||||||
// TODO (b/234772728) Add tests.
|
// TODO (b/234772728) Add tests.
|
||||||
@@ -365,12 +414,12 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
if (progress.steps == -1) {
|
if (progress.steps == -1) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
val displayProgress = Math.max(0, progress.steps + 1 - progress.remaining)
|
val displayProgress = 0.coerceAtLeast(progress.steps + 1 - progress.remaining)
|
||||||
return PROGRESS_BAR_MAX * displayProgress / (progress.steps + 1)
|
return PROGRESS_BAR_MAX * displayProgress / (progress.steps + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showError(error: CharSequence) {
|
private fun showError(error: CharSequence) {
|
||||||
enrollingSfpsView!!.let {
|
enrollingView!!.let {
|
||||||
it.headerText = error
|
it.headerText = error
|
||||||
it.headerTextView.contentDescription = error
|
it.headerTextView.contentDescription = error
|
||||||
GlifLayoutHelper(requireActivity(), it).setDescriptionText("")
|
GlifLayoutHelper(requireActivity(), it).setDescriptionText("")
|
||||||
@@ -425,7 +474,7 @@ class FingerprintEnrollEnrollingSfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTitleAndDescription() {
|
private fun updateTitleAndDescription() {
|
||||||
val helper = GlifLayoutHelper(requireActivity(), enrollingSfpsView!!)
|
val helper = GlifLayoutHelper(requireActivity(), enrollingView!!)
|
||||||
if (enrollingViewModel.isAccessibilityEnabled) {
|
if (enrollingViewModel.isAccessibilityEnabled) {
|
||||||
enrollingViewModel.clearTalkback()
|
enrollingViewModel.clearTalkback()
|
||||||
helper.glifLayout.descriptionTextView.accessibilityLiveRegion =
|
helper.glifLayout.descriptionTextView.accessibilityLiveRegion =
|
||||||
@@ -584,7 +633,7 @@ private fun ProgressBar.applyProgressBarDynamicColor(context: Context, isError:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun LottieAnimationView.applyLottieDynamicColor(context: Context, isError: Boolean) {
|
fun LottieAnimationView.applyLottieDynamicColor(context: Context, isError: Boolean) {
|
||||||
addValueCallback<ColorFilter>(
|
addValueCallback(
|
||||||
KeyPath(".blue100", "**"),
|
KeyPath(".blue100", "**"),
|
||||||
LottieProperty.COLOR_FILTER
|
LottieProperty.COLOR_FILTER
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ package com.android.settings.biometrics2.ui.view
|
|||||||
|
|
||||||
import android.annotation.RawRes
|
import android.annotation.RawRes
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.hardware.biometrics.BiometricFingerprintConstants
|
||||||
import android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL
|
import android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL
|
||||||
import android.hardware.fingerprint.FingerprintManager.FINGERPRINT_ERROR_CANCELED
|
|
||||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -35,20 +35,25 @@ import android.widget.TextView
|
|||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.airbnb.lottie.LottieAnimationView
|
import com.airbnb.lottie.LottieAnimationView
|
||||||
import com.airbnb.lottie.LottieComposition
|
import com.airbnb.lottie.LottieComposition
|
||||||
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.fingerprint.FingerprintErrorDialog
|
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
||||||
import com.android.settings.biometrics2.ui.widget.UdfpsEnrollView
|
import com.android.settings.biometrics2.ui.widget.UdfpsEnrollView
|
||||||
import com.android.settingslib.display.DisplayDensityUtils
|
import com.android.settingslib.display.DisplayDensityUtils
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,6 +73,10 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
private val progressViewModel: FingerprintEnrollProgressViewModel
|
private val progressViewModel: FingerprintEnrollProgressViewModel
|
||||||
get() = _progressViewModel!!
|
get() = _progressViewModel!!
|
||||||
|
|
||||||
|
private var _errorDialogViewModel: FingerprintEnrollErrorDialogViewModel? = null
|
||||||
|
private val errorDialogViewModel: FingerprintEnrollErrorDialogViewModel
|
||||||
|
get() = _errorDialogViewModel!!
|
||||||
|
|
||||||
private var illustrationLottie: LottieAnimationView? = null
|
private var illustrationLottie: LottieAnimationView? = null
|
||||||
|
|
||||||
private var haveShownTipLottie = false
|
private var haveShownTipLottie = false
|
||||||
@@ -76,22 +85,22 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
private var haveShownCenterLottie = false
|
private var haveShownCenterLottie = false
|
||||||
private var haveShownGuideLottie = false
|
private var haveShownGuideLottie = false
|
||||||
|
|
||||||
private var enrollingUdfpsView: RelativeLayout? = null
|
private var enrollingView: RelativeLayout? = null
|
||||||
|
|
||||||
private val titleText: TextView
|
private val titleText: TextView
|
||||||
get() = enrollingUdfpsView!!.findViewById<TextView>(R.id.suc_layout_title)!!
|
get() = enrollingView!!.findViewById(R.id.suc_layout_title)!!
|
||||||
|
|
||||||
private val subTitleText: TextView
|
private val subTitleText: TextView
|
||||||
get() = enrollingUdfpsView!!.findViewById<TextView>(R.id.sud_layout_subtitle)!!
|
get() = enrollingView!!.findViewById(R.id.sud_layout_subtitle)!!
|
||||||
|
|
||||||
private val udfpsEnrollView: UdfpsEnrollView
|
private val udfpsEnrollView: UdfpsEnrollView
|
||||||
get() = enrollingUdfpsView!!.findViewById<UdfpsEnrollView>(R.id.udfps_animation_view)!!
|
get() = enrollingView!!.findViewById(R.id.udfps_animation_view)!!
|
||||||
|
|
||||||
private val skipBtn: Button
|
private val skipBtn: Button
|
||||||
get() = enrollingUdfpsView!!.findViewById<Button>(R.id.skip_btn)!!
|
get() = enrollingView!!.findViewById(R.id.skip_btn)!!
|
||||||
|
|
||||||
private val icon: ImageView
|
private val icon: ImageView
|
||||||
get() = enrollingUdfpsView!!.findViewById<ImageView>(R.id.sud_layout_icon)!!
|
get() = enrollingView!!.findViewById(R.id.sud_layout_icon)!!
|
||||||
|
|
||||||
private val shouldShowLottie: Boolean
|
private val shouldShowLottie: Boolean
|
||||||
get() {
|
get() {
|
||||||
@@ -108,24 +117,33 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
|
|
||||||
private var rotation = -1
|
private var rotation = -1
|
||||||
|
|
||||||
|
private var enrollingCancelSignal: Any? = null
|
||||||
|
|
||||||
private val onSkipClickListener = View.OnClickListener { _: View? ->
|
private val onSkipClickListener = View.OnClickListener { _: View? ->
|
||||||
enrollingViewModel.setOnSkipPressed()
|
enrollingViewModel.setOnSkipPressed()
|
||||||
cancelEnrollment()
|
cancelEnrollment(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val progressObserver: Observer<EnrollmentProgress> =
|
private val progressObserver = Observer { progress: EnrollmentProgress? ->
|
||||||
Observer<EnrollmentProgress> { progress: EnrollmentProgress? ->
|
if (progress != null && progress.steps >= 0) {
|
||||||
progress?.let { onEnrollmentProgressChange(it) }
|
onEnrollmentProgressChange(progress)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val helpMessageObserver: Observer<EnrollmentStatusMessage> =
|
private val helpMessageObserver = Observer { helpMessage: EnrollmentStatusMessage? ->
|
||||||
Observer<EnrollmentStatusMessage> { helpMessage: EnrollmentStatusMessage? ->
|
Log.d(TAG, "helpMessageObserver($helpMessage)")
|
||||||
helpMessage?.let { onEnrollmentHelp(it) }
|
helpMessage?.let { onEnrollmentHelp(it) }
|
||||||
}
|
}
|
||||||
private val errorMessageObserver: Observer<EnrollmentStatusMessage> =
|
|
||||||
Observer<EnrollmentStatusMessage> { errorMessage: EnrollmentStatusMessage? ->
|
private val errorMessageObserver = Observer { errorMessage: EnrollmentStatusMessage? ->
|
||||||
errorMessage?.let { onEnrollmentError(it) }
|
Log.d(TAG, "errorMessageObserver($errorMessage)")
|
||||||
}
|
errorMessage?.let { onEnrollmentError(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val canceledSignalObserver = Observer { canceledSignal: Any? ->
|
||||||
|
Log.d(TAG, "canceledSignalObserver($canceledSignal)")
|
||||||
|
canceledSignal?.let { onEnrollmentCanceled(it) }
|
||||||
|
}
|
||||||
|
|
||||||
private val acquireObserver =
|
private val acquireObserver =
|
||||||
Observer { isAcquiredGood: Boolean? -> isAcquiredGood?.let { onAcquired(it) } }
|
Observer { isAcquiredGood: Boolean? -> isAcquiredGood?.let { onAcquired(it) } }
|
||||||
@@ -144,7 +162,7 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
isEnabled = false
|
isEnabled = false
|
||||||
enrollingViewModel.setOnBackPressed()
|
enrollingViewModel.setOnBackPressed()
|
||||||
cancelEnrollment()
|
cancelEnrollment(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +174,7 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
_enrollingViewModel = provider[FingerprintEnrollEnrollingViewModel::class.java]
|
_enrollingViewModel = provider[FingerprintEnrollEnrollingViewModel::class.java]
|
||||||
_rotationViewModel = provider[DeviceRotationViewModel::class.java]
|
_rotationViewModel = provider[DeviceRotationViewModel::class.java]
|
||||||
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
||||||
|
_errorDialogViewModel = provider[FingerprintEnrollErrorDialogViewModel::class.java]
|
||||||
}
|
}
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
requireActivity().onBackPressedDispatcher.addCallback(onBackPressedCallback)
|
requireActivity().onBackPressedDispatcher.addCallback(onBackPressedCallback)
|
||||||
@@ -172,7 +191,7 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
): View = (inflater.inflate(
|
): View = (inflater.inflate(
|
||||||
R.layout.udfps_enroll_enrolling_v2, container, false
|
R.layout.udfps_enroll_enrolling_v2, container, false
|
||||||
) as RelativeLayout).also {
|
) as RelativeLayout).also {
|
||||||
enrollingUdfpsView = it
|
enrollingView = it
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
@@ -181,23 +200,78 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
updateIllustrationLottie(rotation)
|
updateIllustrationLottie(rotation)
|
||||||
|
|
||||||
requireActivity().bindFingerprintEnrollEnrollingUdfpsView(
|
requireActivity().bindFingerprintEnrollEnrollingUdfpsView(
|
||||||
view = enrollingUdfpsView!!,
|
view = enrollingView!!,
|
||||||
sensorProperties = enrollingViewModel.firstFingerprintSensorPropertiesInternal!!,
|
sensorProperties = enrollingViewModel.firstFingerprintSensorPropertiesInternal!!,
|
||||||
rotation = rotation,
|
rotation = rotation,
|
||||||
onSkipClickListener = onSkipClickListener,
|
onSkipClickListener = onSkipClickListener,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
errorDialogViewModel.triggerRetryFlow.collect { retryEnrollment() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun retryEnrollment() {
|
||||||
|
reattachUdfpsEnrollView()
|
||||||
|
|
||||||
|
startEnrollment()
|
||||||
|
|
||||||
|
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
||||||
|
progressViewModel.helpMessageLiveData.value.let {
|
||||||
|
if (it != null) {
|
||||||
|
onEnrollmentHelp(it)
|
||||||
|
} else {
|
||||||
|
updateTitleAndDescription()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
startEnrollment()
|
val isEnrolling = progressViewModel.isEnrolling
|
||||||
|
val isErrorDialogShown = errorDialogViewModel.isDialogShown
|
||||||
|
Log.d(TAG, "onStart(), isEnrolling:$isEnrolling, isErrorDialog:$isErrorDialogShown")
|
||||||
|
if (!isErrorDialogShown) {
|
||||||
|
startEnrollment()
|
||||||
|
}
|
||||||
|
|
||||||
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
updateProgress(false /* animate */, progressViewModel.progressLiveData.value!!)
|
||||||
val msg: EnrollmentStatusMessage? = progressViewModel.helpMessageLiveData.value
|
progressViewModel.helpMessageLiveData.value.let {
|
||||||
if (msg != null) {
|
if (it != null) {
|
||||||
onEnrollmentHelp(msg)
|
onEnrollmentHelp(it)
|
||||||
} else {
|
} else {
|
||||||
updateTitleAndDescription()
|
updateTitleAndDescription()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reattachUdfpsEnrollView() {
|
||||||
|
enrollingView!!.let {
|
||||||
|
val newUdfpsView = LayoutInflater.from(requireActivity()).inflate(
|
||||||
|
R.layout.udfps_enroll_enrolling_v2_udfps_view,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
val index = it.indexOfChild(udfpsEnrollView)
|
||||||
|
val lp = udfpsEnrollView.layoutParams
|
||||||
|
|
||||||
|
it.removeView(udfpsEnrollView)
|
||||||
|
it.addView(newUdfpsView, index, lp)
|
||||||
|
udfpsEnrollView.setSensorProperties(
|
||||||
|
enrollingViewModel.firstFingerprintSensorPropertiesInternal
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear lottie status
|
||||||
|
haveShownTipLottie = false
|
||||||
|
haveShownLeftEdgeLottie = false
|
||||||
|
haveShownRightEdgeLottie = false
|
||||||
|
haveShownCenterLottie = false
|
||||||
|
haveShownGuideLottie = false
|
||||||
|
illustrationLottie?.let {
|
||||||
|
it.contentDescription = ""
|
||||||
|
it.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,18 +287,17 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
removeEnrollmentObservers()
|
removeEnrollmentObservers()
|
||||||
if (!activity!!.isChangingConfigurations && progressViewModel.isEnrolling) {
|
val isEnrolling = progressViewModel.isEnrolling
|
||||||
progressViewModel.cancelEnrollment()
|
val isConfigChange = requireActivity().isChangingConfigurations
|
||||||
|
Log.d(TAG, "onStop(), enrolling:$isEnrolling isConfigChange:$isConfigChange")
|
||||||
|
if (isEnrolling && !isConfigChange) {
|
||||||
|
cancelEnrollment(false)
|
||||||
}
|
}
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeEnrollmentObservers() {
|
private fun removeEnrollmentObservers() {
|
||||||
preRemoveEnrollmentObservers()
|
|
||||||
progressViewModel.errorMessageLiveData.removeObserver(errorMessageObserver)
|
progressViewModel.errorMessageLiveData.removeObserver(errorMessageObserver)
|
||||||
}
|
|
||||||
|
|
||||||
private fun preRemoveEnrollmentObservers() {
|
|
||||||
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
||||||
progressViewModel.helpMessageLiveData.removeObserver(helpMessageObserver)
|
progressViewModel.helpMessageLiveData.removeObserver(helpMessageObserver)
|
||||||
progressViewModel.acquireLiveData.removeObserver(acquireObserver)
|
progressViewModel.acquireLiveData.removeObserver(acquireObserver)
|
||||||
@@ -232,16 +305,29 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
progressViewModel.pointerUpLiveData.removeObserver(pointerUpObserver)
|
progressViewModel.pointerUpLiveData.removeObserver(pointerUpObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelEnrollment() {
|
private fun cancelEnrollment(waitForLastCancelErrMsg: Boolean) {
|
||||||
preRemoveEnrollmentObservers()
|
if (!progressViewModel.isEnrolling) {
|
||||||
progressViewModel.cancelEnrollment()
|
Log.d(TAG, "cancelEnrollment(), failed because isEnrolling is false")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
removeEnrollmentObservers()
|
||||||
|
if (waitForLastCancelErrMsg) {
|
||||||
|
progressViewModel.canceledSignalLiveData.observe(this, canceledSignalObserver)
|
||||||
|
} else {
|
||||||
|
enrollingCancelSignal = null
|
||||||
|
}
|
||||||
|
val cancelResult: Boolean = progressViewModel.cancelEnrollment()
|
||||||
|
if (!cancelResult) {
|
||||||
|
Log.e(TAG, "cancelEnrollment(), failed to cancel enrollment")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startEnrollment() {
|
private fun startEnrollment() {
|
||||||
val startResult: Boolean =
|
enrollingCancelSignal = progressViewModel.startEnrollment(ENROLL_ENROLL)
|
||||||
progressViewModel.startEnrollment(ENROLL_ENROLL)
|
if (enrollingCancelSignal == null) {
|
||||||
if (!startResult) {
|
|
||||||
Log.e(TAG, "startEnrollment(), failed")
|
Log.e(TAG, "startEnrollment(), failed")
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "startEnrollment(), success")
|
||||||
}
|
}
|
||||||
progressViewModel.progressLiveData.observe(this, progressObserver)
|
progressViewModel.progressLiveData.observe(this, progressObserver)
|
||||||
progressViewModel.helpMessageLiveData.observe(this, helpMessageObserver)
|
progressViewModel.helpMessageLiveData.observe(this, helpMessageObserver)
|
||||||
@@ -256,17 +342,24 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
Log.d(TAG, "Enrollment not started yet")
|
Log.d(TAG, "Enrollment not started yet")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val progress = getProgress(enrollmentProgress)
|
val progress = getProgress(enrollmentProgress)
|
||||||
if (progressViewModel.progressLiveData.value!!.steps != -1) {
|
Log.d(TAG, "updateProgress($animate, $enrollmentProgress), progress:$progress")
|
||||||
|
|
||||||
|
if (enrollmentProgress.steps != -1) {
|
||||||
udfpsEnrollView.onEnrollmentProgress(
|
udfpsEnrollView.onEnrollmentProgress(
|
||||||
enrollmentProgress.remaining,
|
enrollmentProgress.remaining,
|
||||||
enrollmentProgress.steps
|
enrollmentProgress.steps
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (animate) {
|
|
||||||
animateProgress(progress)
|
if (progress >= PROGRESS_BAR_MAX) {
|
||||||
} else if (progress >= PROGRESS_BAR_MAX) {
|
if (animate) {
|
||||||
delayedFinishRunnable.run()
|
// Wait animations to finish, then proceed to next page
|
||||||
|
activity!!.mainThreadHandler.postDelayed(delayedFinishRunnable, 400L)
|
||||||
|
} else {
|
||||||
|
delayedFinishRunnable.run()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,15 +371,8 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
return PROGRESS_BAR_MAX * displayProgress / (progress.steps + 1)
|
return PROGRESS_BAR_MAX * displayProgress / (progress.steps + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun animateProgress(progress: Int) {
|
|
||||||
// UDFPS animations are owned by SystemUI
|
|
||||||
if (progress >= PROGRESS_BAR_MAX) {
|
|
||||||
// Wait for any animations in SysUI to finish, then proceed to next page
|
|
||||||
activity!!.mainThreadHandler.postDelayed(delayedFinishRunnable, 400L)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateTitleAndDescription() {
|
private fun updateTitleAndDescription() {
|
||||||
|
Log.d(TAG, "updateTitleAndDescription($currentStage)")
|
||||||
when (currentStage) {
|
when (currentStage) {
|
||||||
STAGE_CENTER -> {
|
STAGE_CENTER -> {
|
||||||
titleText.setText(R.string.security_settings_fingerprint_enroll_repeat_title)
|
titleText.setText(R.string.security_settings_fingerprint_enroll_repeat_title)
|
||||||
@@ -386,7 +472,7 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
illustrationLottie = null
|
illustrationLottie = null
|
||||||
} else if (shouldShowLottie) {
|
} else if (shouldShowLottie) {
|
||||||
illustrationLottie =
|
illustrationLottie =
|
||||||
enrollingUdfpsView!!.findViewById<LottieAnimationView>(R.id.illustration_lottie)
|
enrollingView!!.findViewById(R.id.illustration_lottie)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,6 +554,7 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onEnrollmentHelp(helpMessage: EnrollmentStatusMessage) {
|
private fun onEnrollmentHelp(helpMessage: EnrollmentStatusMessage) {
|
||||||
|
Log.d(TAG, "onEnrollmentHelp($helpMessage)")
|
||||||
val helpStr: CharSequence = helpMessage.str
|
val helpStr: CharSequence = helpMessage.str
|
||||||
if (helpStr.isNotEmpty()) {
|
if (helpStr.isNotEmpty()) {
|
||||||
showError(helpStr)
|
showError(helpStr)
|
||||||
@@ -476,25 +563,26 @@ class FingerprintEnrollEnrollingUdfpsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onEnrollmentError(errorMessage: EnrollmentStatusMessage) {
|
private fun onEnrollmentError(errorMessage: EnrollmentStatusMessage) {
|
||||||
removeEnrollmentObservers()
|
cancelEnrollment(true)
|
||||||
if (enrollingViewModel.onBackPressed
|
lifecycleScope.launch {
|
||||||
&& errorMessage.msgId == FINGERPRINT_ERROR_CANCELED
|
Log.d(TAG, "newDialog $errorMessage")
|
||||||
) {
|
errorDialogViewModel.newDialog(errorMessage.msgId)
|
||||||
enrollingViewModel.onCancelledDueToOnBackPressed()
|
}
|
||||||
} else if (enrollingViewModel.onSkipPressed
|
}
|
||||||
&& errorMessage.msgId == FINGERPRINT_ERROR_CANCELED
|
|
||||||
) {
|
private fun onEnrollmentCanceled(canceledSignal: Any) {
|
||||||
enrollingViewModel.onCancelledDueToOnSkipPressed()
|
Log.d(
|
||||||
} else {
|
TAG,
|
||||||
val errMsgId: Int = errorMessage.msgId
|
"onEnrollmentCanceled enrolling:$enrollingCancelSignal, canceled:$canceledSignal"
|
||||||
enrollingViewModel.showErrorDialog(
|
)
|
||||||
FingerprintEnrollEnrollingViewModel.ErrorDialogData(
|
if (enrollingCancelSignal === canceledSignal) {
|
||||||
getString(FingerprintErrorDialog.getErrorMessage(errMsgId)),
|
progressViewModel.canceledSignalLiveData.removeObserver(canceledSignalObserver)
|
||||||
getString(FingerprintErrorDialog.getErrorTitle(errMsgId)),
|
progressViewModel.clearProgressLiveData()
|
||||||
errMsgId
|
if (enrollingViewModel.onBackPressed) {
|
||||||
)
|
enrollingViewModel.onCancelledDueToOnBackPressed()
|
||||||
)
|
} else if (enrollingViewModel.onSkipPressed) {
|
||||||
progressViewModel.cancelEnrollment()
|
enrollingViewModel.onCancelledDueToOnSkipPressed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.settings.biometrics2.ui.view
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.hardware.biometrics.BiometricConstants
|
||||||
|
import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_UNABLE_TO_PROCESS
|
||||||
|
import android.hardware.fingerprint.FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.android.settings.R
|
||||||
|
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog.getErrorMessage
|
||||||
|
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog.getErrorTitle
|
||||||
|
import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog.getSetupErrorMessage
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintErrorDialogSetResultAction.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintErrorDialogSetResultAction.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fingerprint error dialog, will be shown when an error occurs during fingerprint enrollment.
|
||||||
|
*/
|
||||||
|
class FingerprintEnrollErrorDialog : DialogFragment() {
|
||||||
|
|
||||||
|
private val viewModel: FingerprintEnrollErrorDialogViewModel?
|
||||||
|
get() = activity?.let {
|
||||||
|
ViewModelProvider(it)[FingerprintEnrollErrorDialogViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
val errorMsgId: Int = requireArguments().getInt(KEY_ERROR_MSG_ID)
|
||||||
|
val okButtonSetResultAction =
|
||||||
|
if (errorMsgId == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT)
|
||||||
|
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
||||||
|
else
|
||||||
|
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
||||||
|
return requireActivity().bindFingerprintEnrollEnrollingErrorDialog(
|
||||||
|
errorMsgId = errorMsgId,
|
||||||
|
isSuw = viewModel!!.isSuw,
|
||||||
|
tryAgainButtonClickListener = { dialog: DialogInterface?, _: Int ->
|
||||||
|
activity?.lifecycleScope?.launch {
|
||||||
|
Log.d(TAG, "tryAgain flow")
|
||||||
|
viewModel?.triggerRetry()
|
||||||
|
dialog?.dismiss()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
okButtonClickListener = { dialog: DialogInterface?, _: Int ->
|
||||||
|
activity?.lifecycleScope?.launch {
|
||||||
|
Log.d(TAG, "ok flow as $okButtonSetResultAction")
|
||||||
|
viewModel?.setResultAndFinish(okButtonSetResultAction)
|
||||||
|
dialog?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "FingerprintEnrollErrorDialog"
|
||||||
|
private const val KEY_ERROR_MSG_ID = "error_msg_id"
|
||||||
|
|
||||||
|
fun newInstance(errorMsgId: Int): FingerprintEnrollErrorDialog {
|
||||||
|
val dialog = FingerprintEnrollErrorDialog()
|
||||||
|
val args = Bundle()
|
||||||
|
args.putInt(KEY_ERROR_MSG_ID, errorMsgId)
|
||||||
|
dialog.arguments = args
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.bindFingerprintEnrollEnrollingErrorDialog(
|
||||||
|
errorMsgId: Int,
|
||||||
|
isSuw: Boolean,
|
||||||
|
tryAgainButtonClickListener: DialogInterface.OnClickListener,
|
||||||
|
okButtonClickListener: DialogInterface.OnClickListener
|
||||||
|
): AlertDialog = AlertDialog.Builder(this)
|
||||||
|
.setTitle(getString(getErrorTitle(errorMsgId)))
|
||||||
|
.setMessage(
|
||||||
|
getString(
|
||||||
|
if (isSuw)
|
||||||
|
getSetupErrorMessage(errorMsgId)
|
||||||
|
else
|
||||||
|
getErrorMessage(errorMsgId)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.setCancelable(false).apply {
|
||||||
|
if (errorMsgId == FINGERPRINT_ERROR_UNABLE_TO_PROCESS) {
|
||||||
|
setPositiveButton(
|
||||||
|
R.string.security_settings_fingerprint_enroll_dialog_try_again,
|
||||||
|
tryAgainButtonClickListener
|
||||||
|
)
|
||||||
|
setNegativeButton(
|
||||||
|
R.string.security_settings_fingerprint_enroll_dialog_ok,
|
||||||
|
okButtonClickListener
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
setPositiveButton(
|
||||||
|
R.string.security_settings_fingerprint_enroll_dialog_ok,
|
||||||
|
okButtonClickListener
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.create()
|
||||||
|
.apply { setCanceledOnTouchOutside(false) }
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
package com.android.settings.biometrics2.ui.view
|
package com.android.settings.biometrics2.ui.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.hardware.fingerprint.FingerprintManager
|
import android.hardware.biometrics.BiometricFingerprintConstants
|
||||||
import android.hardware.fingerprint.FingerprintManager.ENROLL_FIND_SENSOR
|
import android.hardware.fingerprint.FingerprintManager.ENROLL_FIND_SENSOR
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -26,19 +26,25 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.biometrics.fingerprint.FingerprintFindSensorAnimation
|
import com.android.settings.biometrics.fingerprint.FingerprintFindSensorAnimation
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
||||||
import com.google.android.setupcompat.template.FooterBarMixin
|
import com.google.android.setupcompat.template.FooterBarMixin
|
||||||
import com.google.android.setupcompat.template.FooterButton
|
import com.google.android.setupcompat.template.FooterButton
|
||||||
import com.google.android.setupdesign.GlifLayout
|
import com.google.android.setupdesign.GlifLayout
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment explaining the side fingerprint sensor location for fingerprint enrollment.
|
* Fragment explaining the side fingerprint sensor location for fingerprint enrollment.
|
||||||
@@ -68,6 +74,10 @@ class FingerprintEnrollFindRfpsFragment : Fragment() {
|
|||||||
private val rotationViewModel: DeviceRotationViewModel
|
private val rotationViewModel: DeviceRotationViewModel
|
||||||
get() = _rotationViewModel!!
|
get() = _rotationViewModel!!
|
||||||
|
|
||||||
|
private var _errorDialogViewModel: FingerprintEnrollErrorDialogViewModel? = null
|
||||||
|
private val errorDialogViewModel: FingerprintEnrollErrorDialogViewModel
|
||||||
|
get() = _errorDialogViewModel!!
|
||||||
|
|
||||||
private var findRfpsView: GlifLayout? = null
|
private var findRfpsView: GlifLayout? = null
|
||||||
|
|
||||||
private val onSkipClickListener =
|
private val onSkipClickListener =
|
||||||
@@ -75,33 +85,25 @@ class FingerprintEnrollFindRfpsFragment : Fragment() {
|
|||||||
|
|
||||||
private var animation: FingerprintFindSensorAnimation? = null
|
private var animation: FingerprintFindSensorAnimation? = null
|
||||||
|
|
||||||
|
private var enrollingCancelSignal: Any? = null
|
||||||
|
|
||||||
@Surface.Rotation
|
@Surface.Rotation
|
||||||
private var lastRotation = -1
|
private var lastRotation = -1
|
||||||
|
|
||||||
private val rotationObserver = Observer { rotation: Int? ->
|
private val progressObserver = Observer { progress: EnrollmentProgress? ->
|
||||||
if (DEBUG) {
|
if (progress != null && !progress.isInitialStep) {
|
||||||
Log.d(TAG, "rotationObserver $rotation")
|
cancelEnrollment(true)
|
||||||
}
|
}
|
||||||
rotation?.let { onRotationChanged(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val progressObserver: Observer<EnrollmentProgress> =
|
private val errorMessageObserver = Observer { errorMessage: EnrollmentStatusMessage? ->
|
||||||
Observer<EnrollmentProgress> { progress: EnrollmentProgress? ->
|
Log.d(TAG, "errorMessageObserver($errorMessage)")
|
||||||
if (DEBUG) {
|
errorMessage?.let { onEnrollmentError(it) }
|
||||||
Log.d(TAG, "progressObserver($progress)")
|
}
|
||||||
}
|
|
||||||
if (progress != null && !progress.isInitialStep) {
|
|
||||||
stopLookingForFingerprint(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val lastCancelMessageObserver: Observer<EnrollmentStatusMessage> =
|
private val canceledSignalObserver = Observer { canceledSignal: Any? ->
|
||||||
Observer<EnrollmentStatusMessage> { errorMessage: EnrollmentStatusMessage? ->
|
canceledSignal?.let { onEnrollmentCanceled(it) }
|
||||||
if (DEBUG) {
|
}
|
||||||
Log.d(TAG, "lastCancelMessageObserver($errorMessage)")
|
|
||||||
}
|
|
||||||
errorMessage?.let { onLastCancelMessage(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@@ -129,28 +131,40 @@ class FingerprintEnrollFindRfpsFragment : Fragment() {
|
|||||||
view = findRfpsView!!,
|
view = findRfpsView!!,
|
||||||
onSkipClickListener = onSkipClickListener
|
onSkipClickListener = onSkipClickListener
|
||||||
)
|
)
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
errorDialogViewModel.triggerRetryFlow.collect { retryLookingForFingerprint() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun retryLookingForFingerprint() {
|
||||||
|
startEnrollment()
|
||||||
|
animation?.let {
|
||||||
|
Log.d(TAG, "retry, start animation")
|
||||||
|
it.startAnimation()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
if (DEBUG) {
|
val isErrorDialogShown = errorDialogViewModel.isDialogShown
|
||||||
Log.d(
|
Log.d(TAG, "onStart(), isEnrolling:${progressViewModel.isEnrolling}"
|
||||||
TAG,
|
+ ", isErrorDialog:$isErrorDialogShown")
|
||||||
"onStart(), start looking for fingerprint, animation exist:${animation != null}"
|
if (!isErrorDialogShown) {
|
||||||
)
|
startEnrollment()
|
||||||
}
|
}
|
||||||
startLookingForFingerprint()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
val rotationLiveData: LiveData<Int> = rotationViewModel.liveData
|
val rotationLiveData: LiveData<Int> = rotationViewModel.liveData
|
||||||
lastRotation = rotationLiveData.value!!
|
lastRotation = rotationLiveData.value!!
|
||||||
rotationLiveData.observe(this, rotationObserver)
|
if (!errorDialogViewModel.isDialogShown) {
|
||||||
animation?.let {
|
animation?.let {
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "onResume(), start animation")
|
Log.d(TAG, "onResume(), start animation")
|
||||||
|
it.startAnimation()
|
||||||
}
|
}
|
||||||
it.startAnimation()
|
|
||||||
}
|
}
|
||||||
super.onResume()
|
super.onResume()
|
||||||
}
|
}
|
||||||
@@ -167,72 +181,68 @@ class FingerprintEnrollFindRfpsFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
super.onStop()
|
super.onStop()
|
||||||
val isEnrolling: Boolean = progressViewModel.isEnrolling
|
removeEnrollmentObservers()
|
||||||
if (DEBUG) {
|
val isEnrolling = progressViewModel.isEnrolling
|
||||||
Log.d(
|
val isConfigChange = requireActivity().isChangingConfigurations
|
||||||
TAG,
|
Log.d(TAG, "onStop(), enrolling:$isEnrolling isConfigChange:$isConfigChange")
|
||||||
"onStop(), current enrolling: ${isEnrolling}, animation exist:${animation != null}"
|
if (isEnrolling && !isConfigChange) {
|
||||||
)
|
cancelEnrollment(false)
|
||||||
}
|
|
||||||
if (isEnrolling) {
|
|
||||||
stopLookingForFingerprint(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startLookingForFingerprint() {
|
private fun removeEnrollmentObservers() {
|
||||||
if (progressViewModel.isEnrolling) {
|
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
||||||
Log.d(
|
progressViewModel.helpMessageLiveData.removeObserver(errorMessageObserver)
|
||||||
TAG,
|
}
|
||||||
"startLookingForFingerprint(), failed because isEnrolling is true before starting"
|
|
||||||
)
|
private fun startEnrollment() {
|
||||||
return
|
enrollingCancelSignal = progressViewModel.startEnrollment(ENROLL_FIND_SENSOR)
|
||||||
}
|
if (enrollingCancelSignal == null) {
|
||||||
val startResult: Boolean = progressViewModel.startEnrollment(ENROLL_FIND_SENSOR)
|
Log.e(TAG, "startEnrollment(), failed to start enrollment")
|
||||||
if (!startResult) {
|
} else {
|
||||||
Log.e(TAG, "startLookingForFingerprint(), failed to start enrollment")
|
Log.d(TAG, "startEnrollment(), success")
|
||||||
}
|
}
|
||||||
progressViewModel.progressLiveData.observe(this, progressObserver)
|
progressViewModel.progressLiveData.observe(this, progressObserver)
|
||||||
|
progressViewModel.errorMessageLiveData.observe(this, errorMessageObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stopLookingForFingerprint(waitForLastCancelErrMsg: Boolean) {
|
private fun cancelEnrollment(waitForLastCancelErrMsg: Boolean) {
|
||||||
if (!progressViewModel.isEnrolling) {
|
if (!progressViewModel.isEnrolling) {
|
||||||
Log.d(
|
Log.d(TAG, "cancelEnrollment(), failed because isEnrolling is false")
|
||||||
TAG,
|
|
||||||
"stopLookingForFingerprint(), failed because isEnrolling is false before stopping"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
removeEnrollmentObservers()
|
||||||
if (waitForLastCancelErrMsg) {
|
if (waitForLastCancelErrMsg) {
|
||||||
progressViewModel.clearErrorMessageLiveData() // Prevent got previous error message
|
progressViewModel.canceledSignalLiveData.observe(this, canceledSignalObserver)
|
||||||
progressViewModel.errorMessageLiveData.observe(this, lastCancelMessageObserver)
|
} else {
|
||||||
|
enrollingCancelSignal = null
|
||||||
}
|
}
|
||||||
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
|
||||||
val cancelResult: Boolean = progressViewModel.cancelEnrollment()
|
val cancelResult: Boolean = progressViewModel.cancelEnrollment()
|
||||||
if (!cancelResult) {
|
if (!cancelResult) {
|
||||||
Log.e(TAG, "stopLookingForFingerprint(), failed to cancel enrollment")
|
Log.e(TAG, "cancelEnrollment(), failed to cancel enrollment")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onRotationChanged(@Surface.Rotation newRotation: Int) {
|
private fun onEnrollmentError(errorMessage: EnrollmentStatusMessage) {
|
||||||
if (DEBUG) {
|
cancelEnrollment(false)
|
||||||
Log.d(TAG, "onRotationChanged() from $lastRotation to $newRotation")
|
lifecycleScope.launch {
|
||||||
}
|
Log.d(TAG, "newDialogFlow as $errorMessage")
|
||||||
if (newRotation % 2 != lastRotation % 2) {
|
errorDialogViewModel.newDialog(errorMessage.msgId)
|
||||||
// Fragment is going to be recreated, just stopLookingForFingerprint() here.
|
|
||||||
stopLookingForFingerprint(true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onLastCancelMessage(errorMessage: EnrollmentStatusMessage) {
|
private fun onEnrollmentCanceled(canceledSignal: Any) {
|
||||||
if (errorMessage.msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
|
Log.d(
|
||||||
|
TAG,
|
||||||
|
"onEnrollmentCanceled enrolling:$enrollingCancelSignal, canceled:$canceledSignal"
|
||||||
|
)
|
||||||
|
if (enrollingCancelSignal === canceledSignal) {
|
||||||
val progress: EnrollmentProgress? = progressViewModel.progressLiveData.value
|
val progress: EnrollmentProgress? = progressViewModel.progressLiveData.value
|
||||||
|
progressViewModel.canceledSignalLiveData.removeObserver(canceledSignalObserver)
|
||||||
progressViewModel.clearProgressLiveData()
|
progressViewModel.clearProgressLiveData()
|
||||||
progressViewModel.errorMessageLiveData.removeObserver(lastCancelMessageObserver)
|
|
||||||
if (progress != null && !progress.isInitialStep) {
|
if (progress != null && !progress.isInitialStep) {
|
||||||
viewModel.onStartButtonClick()
|
viewModel.onStartButtonClick()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Log.e(TAG, "errorMessageObserver($errorMessage)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +261,7 @@ class FingerprintEnrollFindRfpsFragment : Fragment() {
|
|||||||
_viewModel = provider[FingerprintEnrollFindSensorViewModel::class.java]
|
_viewModel = provider[FingerprintEnrollFindSensorViewModel::class.java]
|
||||||
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
||||||
_rotationViewModel = provider[DeviceRotationViewModel::class.java]
|
_rotationViewModel = provider[DeviceRotationViewModel::class.java]
|
||||||
|
_errorDialogViewModel = provider[FingerprintEnrollErrorDialogViewModel::class.java]
|
||||||
}
|
}
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
package com.android.settings.biometrics2.ui.view
|
package com.android.settings.biometrics2.ui.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.hardware.fingerprint.FingerprintManager
|
import android.hardware.biometrics.BiometricFingerprintConstants
|
||||||
|
import android.hardware.fingerprint.FingerprintManager.ENROLL_FIND_SENSOR
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@@ -26,21 +27,27 @@ import android.view.ViewGroup
|
|||||||
import androidx.annotation.RawRes
|
import androidx.annotation.RawRes
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.airbnb.lottie.LottieAnimationView
|
import com.airbnb.lottie.LottieAnimationView
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
import com.android.settings.biometrics2.ui.model.EnrollmentProgress
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
||||||
import com.android.settingslib.widget.LottieColorUtils
|
import com.android.settingslib.widget.LottieColorUtils
|
||||||
import com.google.android.setupcompat.template.FooterBarMixin
|
import com.google.android.setupcompat.template.FooterBarMixin
|
||||||
import com.google.android.setupcompat.template.FooterButton
|
import com.google.android.setupcompat.template.FooterButton
|
||||||
import com.google.android.setupdesign.GlifLayout
|
import com.google.android.setupdesign.GlifLayout
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment explaining the side fingerprint sensor location for fingerprint enrollment.
|
* Fragment explaining the side fingerprint sensor location for fingerprint enrollment.
|
||||||
@@ -75,41 +82,41 @@ class FingerprintEnrollFindSfpsFragment : Fragment() {
|
|||||||
private val foldedViewModel: DeviceFoldedViewModel
|
private val foldedViewModel: DeviceFoldedViewModel
|
||||||
get() = _foldedViewModel!!
|
get() = _foldedViewModel!!
|
||||||
|
|
||||||
|
private var _errorDialogViewModel: FingerprintEnrollErrorDialogViewModel? = null
|
||||||
|
private val errorDialogViewModel: FingerprintEnrollErrorDialogViewModel
|
||||||
|
get() = _errorDialogViewModel!!
|
||||||
|
|
||||||
private var findSfpsView: GlifLayout? = null
|
private var findSfpsView: GlifLayout? = null
|
||||||
|
|
||||||
private val onSkipClickListener =
|
private val onSkipClickListener =
|
||||||
View.OnClickListener { _: View? -> viewModel.onSkipButtonClick() }
|
View.OnClickListener { _: View? -> viewModel.onSkipButtonClick() }
|
||||||
|
|
||||||
private val illustrationLottie: LottieAnimationView
|
private val illustrationLottie: LottieAnimationView
|
||||||
get() = findSfpsView!!.findViewById<LottieAnimationView>(R.id.illustration_lottie)!!
|
get() = findSfpsView!!.findViewById(R.id.illustration_lottie)!!
|
||||||
|
|
||||||
|
private var enrollingCancelSignal: Any? = null
|
||||||
|
|
||||||
@Surface.Rotation
|
@Surface.Rotation
|
||||||
private var animationRotation = -1
|
private var animationRotation = -1
|
||||||
|
|
||||||
private val rotationObserver = Observer { rotation: Int? ->
|
private val rotationObserver = Observer { rotation: Int? ->
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "rotationObserver $rotation")
|
|
||||||
}
|
|
||||||
rotation?.let { onRotationChanged(it) }
|
rotation?.let { onRotationChanged(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val progressObserver: Observer<EnrollmentProgress> =
|
private val progressObserver = Observer { progress: EnrollmentProgress? ->
|
||||||
Observer<EnrollmentProgress> { progress: EnrollmentProgress? ->
|
if (progress != null && !progress.isInitialStep) {
|
||||||
if (DEBUG) {
|
cancelEnrollment(true)
|
||||||
Log.d(TAG, "progressObserver($progress)")
|
|
||||||
}
|
|
||||||
if (progress != null && !progress.isInitialStep) {
|
|
||||||
stopLookingForFingerprint(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val lastCancelMessageObserver: Observer<EnrollmentStatusMessage> =
|
private val errorMessageObserver = Observer{ errorMessage: EnrollmentStatusMessage? ->
|
||||||
Observer<EnrollmentStatusMessage> { errorMessage: EnrollmentStatusMessage? ->
|
Log.d(TAG, "errorMessageObserver($errorMessage)")
|
||||||
if (DEBUG) {
|
errorMessage?.let { onEnrollmentError(it) }
|
||||||
Log.d(TAG, "lastCancelMessageObserver($errorMessage)")
|
}
|
||||||
}
|
|
||||||
errorMessage?.let { onLastCancelMessage(it) }
|
private val canceledSignalObserver = Observer { canceledSignal: Any? ->
|
||||||
}
|
canceledSignal?.let { onEnrollmentCanceled(it) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@@ -128,16 +135,21 @@ class FingerprintEnrollFindSfpsFragment : Fragment() {
|
|||||||
view = findSfpsView!!,
|
view = findSfpsView!!,
|
||||||
onSkipClickListener = onSkipClickListener
|
onSkipClickListener = onSkipClickListener
|
||||||
)
|
)
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
errorDialogViewModel.triggerRetryFlow.collect { startEnrollment() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
val isEnrolling: Boolean = progressViewModel.isEnrolling
|
val isErrorDialogShown = errorDialogViewModel.isDialogShown
|
||||||
if (DEBUG) {
|
Log.d(TAG, "onStart(), isEnrolling:${progressViewModel.isEnrolling}"
|
||||||
Log.d(TAG, "onStart(), isEnrolling:$isEnrolling")
|
+ ", isErrorDialog:$isErrorDialogShown")
|
||||||
}
|
if (!isErrorDialogShown) {
|
||||||
if (!isEnrolling) {
|
startEnrollment()
|
||||||
startLookingForFingerprint()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,51 +167,44 @@ class FingerprintEnrollFindSfpsFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
super.onStop()
|
super.onStop()
|
||||||
val isEnrolling: Boolean = progressViewModel.isEnrolling
|
val isEnrolling = progressViewModel.isEnrolling
|
||||||
if (DEBUG) {
|
val isConfigChange = requireActivity().isChangingConfigurations
|
||||||
Log.d(TAG, "onStop(), isEnrolling:$isEnrolling")
|
Log.d(TAG, "onStop(), enrolling:$isEnrolling isConfigChange:$isConfigChange")
|
||||||
}
|
if (isEnrolling && !isConfigChange) {
|
||||||
if (isEnrolling) {
|
cancelEnrollment(false)
|
||||||
stopLookingForFingerprint(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startLookingForFingerprint() {
|
private fun removeEnrollmentObservers() {
|
||||||
if (progressViewModel.isEnrolling) {
|
progressViewModel.errorMessageLiveData.removeObserver(errorMessageObserver)
|
||||||
Log.d(
|
|
||||||
TAG,
|
|
||||||
"startLookingForFingerprint(), failed because isEnrolling is true before starting"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
progressViewModel.clearProgressLiveData()
|
|
||||||
progressViewModel.progressLiveData.observe(this, progressObserver)
|
|
||||||
val startResult: Boolean =
|
|
||||||
progressViewModel.startEnrollment(FingerprintManager.ENROLL_FIND_SENSOR)
|
|
||||||
if (!startResult) {
|
|
||||||
Log.e(TAG, "startLookingForFingerprint(), failed to start enrollment")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun stopLookingForFingerprint(waitForLastCancelErrMsg: Boolean) {
|
|
||||||
if (!progressViewModel.isEnrolling) {
|
|
||||||
Log.d(
|
|
||||||
TAG, "stopLookingForFingerprint(), failed because isEnrolling is false before"
|
|
||||||
+ " stopping"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (waitForLastCancelErrMsg) {
|
|
||||||
progressViewModel.clearErrorMessageLiveData() // Prevent got previous error message
|
|
||||||
progressViewModel.errorMessageLiveData.observe(
|
|
||||||
this,
|
|
||||||
lastCancelMessageObserver
|
|
||||||
)
|
|
||||||
}
|
|
||||||
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
progressViewModel.progressLiveData.removeObserver(progressObserver)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startEnrollment() {
|
||||||
|
enrollingCancelSignal = progressViewModel.startEnrollment(ENROLL_FIND_SENSOR)
|
||||||
|
if (enrollingCancelSignal == null) {
|
||||||
|
Log.e(TAG, "startEnrollment(), failed to start enrollment")
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "startEnrollment(), success")
|
||||||
|
}
|
||||||
|
progressViewModel.progressLiveData.observe(this, progressObserver)
|
||||||
|
progressViewModel.errorMessageLiveData.observe(this, errorMessageObserver)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cancelEnrollment(waitForLastCancelErrMsg: Boolean) {
|
||||||
|
if (!progressViewModel.isEnrolling) {
|
||||||
|
Log.d(TAG, "cancelEnrollment(), failed because isEnrolling is false")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
removeEnrollmentObservers()
|
||||||
|
if (waitForLastCancelErrMsg) {
|
||||||
|
progressViewModel.canceledSignalLiveData.observe(this, canceledSignalObserver)
|
||||||
|
} else {
|
||||||
|
enrollingCancelSignal = null
|
||||||
|
}
|
||||||
val cancelResult: Boolean = progressViewModel.cancelEnrollment()
|
val cancelResult: Boolean = progressViewModel.cancelEnrollment()
|
||||||
if (!cancelResult) {
|
if (!cancelResult) {
|
||||||
Log.e(TAG, "stopLookingForFingerprint(), failed to cancel enrollment")
|
Log.e(TAG, "cancelEnrollment(), failed to cancel enrollment")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,34 +215,39 @@ class FingerprintEnrollFindSfpsFragment : Fragment() {
|
|||||||
if ((newRotation + 2) % 4 == animationRotation) {
|
if ((newRotation + 2) % 4 == animationRotation) {
|
||||||
// Fragment not changed, we just need to play correct rotation animation
|
// Fragment not changed, we just need to play correct rotation animation
|
||||||
playLottieAnimation(newRotation)
|
playLottieAnimation(newRotation)
|
||||||
} else if (newRotation % 2 != animationRotation % 2) {
|
|
||||||
// Fragment is going to be recreated, just stopLookingForFingerprint() here.
|
|
||||||
stopLookingForFingerprint(true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onLastCancelMessage(errorMessage: EnrollmentStatusMessage) {
|
private fun onEnrollmentError(errorMessage: EnrollmentStatusMessage) {
|
||||||
if (errorMessage.msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
|
progressViewModel.cancelEnrollment()
|
||||||
|
lifecycleScope.launch {
|
||||||
|
Log.d(TAG, "newDialogFlow as $errorMessage")
|
||||||
|
errorDialogViewModel.newDialog(errorMessage.msgId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onEnrollmentCanceled(canceledSignal: Any) {
|
||||||
|
Log.d(
|
||||||
|
TAG,
|
||||||
|
"onEnrollmentCanceled enrolling:$enrollingCancelSignal, canceled:$canceledSignal"
|
||||||
|
)
|
||||||
|
if (enrollingCancelSignal === canceledSignal) {
|
||||||
val progress: EnrollmentProgress? = progressViewModel.progressLiveData.value
|
val progress: EnrollmentProgress? = progressViewModel.progressLiveData.value
|
||||||
|
progressViewModel.canceledSignalLiveData.removeObserver(canceledSignalObserver)
|
||||||
progressViewModel.clearProgressLiveData()
|
progressViewModel.clearProgressLiveData()
|
||||||
progressViewModel.errorMessageLiveData.removeObserver(lastCancelMessageObserver)
|
|
||||||
if (progress != null && !progress.isInitialStep) {
|
if (progress != null && !progress.isInitialStep) {
|
||||||
viewModel.onStartButtonClick()
|
viewModel.onStartButtonClick()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Log.e(TAG, "errorMessageObserver($errorMessage)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun playLottieAnimation(@Surface.Rotation rotation: Int) {
|
private fun playLottieAnimation(@Surface.Rotation rotation: Int) {
|
||||||
@RawRes val animationRawRes = getSfpsLottieAnimationRawRes(rotation)
|
@RawRes val animationRawRes = getSfpsLottieAnimationRawRes(rotation)
|
||||||
if (DEBUG) {
|
Log.d(
|
||||||
Log.d(
|
TAG,
|
||||||
TAG,
|
"play lottie animation $animationRawRes, previous rotation:$animationRotation"
|
||||||
"play lottie animation $animationRawRes, previous rotation:$animationRotation"
|
+ ", new rotation:" + rotation
|
||||||
+ ", new rotation:" + rotation
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
animationRotation = rotation
|
animationRotation = rotation
|
||||||
illustrationLottie.setAnimation(animationRawRes)
|
illustrationLottie.setAnimation(animationRawRes)
|
||||||
LottieColorUtils.applyDynamicColors(activity, illustrationLottie)
|
LottieColorUtils.applyDynamicColors(activity, illustrationLottie)
|
||||||
@@ -247,7 +257,7 @@ class FingerprintEnrollFindSfpsFragment : Fragment() {
|
|||||||
|
|
||||||
@RawRes
|
@RawRes
|
||||||
private fun getSfpsLottieAnimationRawRes(@Surface.Rotation rotation: Int): Int {
|
private fun getSfpsLottieAnimationRawRes(@Surface.Rotation rotation: Int): Int {
|
||||||
val isFolded = java.lang.Boolean.FALSE != foldedViewModel.getLiveData().getValue()
|
val isFolded = java.lang.Boolean.FALSE != foldedViewModel.liveData.value
|
||||||
return when (rotation) {
|
return when (rotation) {
|
||||||
Surface.ROTATION_90 ->
|
Surface.ROTATION_90 ->
|
||||||
if (isFolded)
|
if (isFolded)
|
||||||
@@ -278,6 +288,7 @@ class FingerprintEnrollFindSfpsFragment : Fragment() {
|
|||||||
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
_progressViewModel = provider[FingerprintEnrollProgressViewModel::class.java]
|
||||||
_rotationViewModel = provider[DeviceRotationViewModel::class.java]
|
_rotationViewModel = provider[DeviceRotationViewModel::class.java]
|
||||||
_foldedViewModel = provider[DeviceFoldedViewModel::class.java]
|
_foldedViewModel = provider[DeviceFoldedViewModel::class.java]
|
||||||
|
_errorDialogViewModel = provider[FingerprintEnrollErrorDialogViewModel::class.java]
|
||||||
}
|
}
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,11 @@ import androidx.annotation.ColorInt
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE
|
import androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.lifecycle.viewmodel.CreationExtras
|
import androidx.lifecycle.viewmodel.CreationExtras
|
||||||
import androidx.lifecycle.viewmodel.MutableCreationExtras
|
import androidx.lifecycle.viewmodel.MutableCreationExtras
|
||||||
import com.android.settings.R
|
import com.android.settings.R
|
||||||
@@ -53,15 +56,12 @@ import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CRE
|
|||||||
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.FingerprintChallengeGenerator
|
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.FingerprintChallengeGenerator
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData
|
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingAction
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingAction
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintErrorDialogAction
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP
|
||||||
@@ -78,8 +78,11 @@ import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewM
|
|||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FingerprintEnrollIntroAction
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FingerprintEnrollIntroAction
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel
|
||||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollmentViewModel
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollmentViewModel
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintErrorDialogSetResultAction.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintErrorDialogSetResultAction.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
||||||
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
|
import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
|
||||||
import com.google.android.setupdesign.util.ThemeHelper
|
import com.google.android.setupdesign.util.ThemeHelper
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fingerprint enrollment activity implementation
|
* Fingerprint enrollment activity implementation
|
||||||
@@ -103,6 +106,30 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
viewModelProvider[AutoCredentialViewModel::class.java]
|
viewModelProvider[AutoCredentialViewModel::class.java]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val introViewModel: FingerprintEnrollIntroViewModel by lazy {
|
||||||
|
viewModelProvider[FingerprintEnrollIntroViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
private val findSensorViewModel: FingerprintEnrollFindSensorViewModel by lazy {
|
||||||
|
viewModelProvider[FingerprintEnrollFindSensorViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
private val progressViewModel: FingerprintEnrollProgressViewModel by lazy {
|
||||||
|
viewModelProvider[FingerprintEnrollProgressViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
private val enrollingViewModel: FingerprintEnrollEnrollingViewModel by lazy {
|
||||||
|
viewModelProvider[FingerprintEnrollEnrollingViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
private val finishViewModel: FingerprintEnrollFinishViewModel by lazy {
|
||||||
|
viewModelProvider[FingerprintEnrollFinishViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
|
private val errorDialogViewModel: FingerprintEnrollErrorDialogViewModel by lazy {
|
||||||
|
viewModelProvider[FingerprintEnrollErrorDialogViewModel::class.java]
|
||||||
|
}
|
||||||
|
|
||||||
private val introActionObserver: Observer<Int> = Observer<Int> { action ->
|
private val introActionObserver: Observer<Int> = Observer<Int> { action ->
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "introActionObserver($action)")
|
Log.d(TAG, "introActionObserver($action)")
|
||||||
@@ -124,26 +151,6 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
action?.let { onEnrollingAction(it) }
|
action?.let { onEnrollingAction(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val enrollingErrorDialogObserver: Observer<ErrorDialogData> =
|
|
||||||
Observer<ErrorDialogData> { data ->
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "enrollingErrorDialogObserver($data)")
|
|
||||||
}
|
|
||||||
data?.let {
|
|
||||||
FingerprintEnrollEnrollingErrorDialog().show(
|
|
||||||
supportFragmentManager,
|
|
||||||
ENROLLING_ERROR_DIALOG_TAG
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val enrollingErrorDialogActionObserver: Observer<Int> = Observer<Int> { action ->
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "enrollingErrorDialogActionObserver($action)")
|
|
||||||
}
|
|
||||||
action?.let { onEnrollingErrorDialogAction(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private val finishActionObserver: Observer<Int> = Observer<Int> { action ->
|
private val finishActionObserver: Observer<Int> = Observer<Int> { action ->
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "finishActionObserver($action)")
|
Log.d(TAG, "finishActionObserver($action)")
|
||||||
@@ -218,6 +225,33 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
autoCredentialViewModel.generateChallengeFailedLiveData.observe(this) {
|
autoCredentialViewModel.generateChallengeFailedLiveData.observe(this) {
|
||||||
_: Boolean -> onGenerateChallengeFailed()
|
_: Boolean -> onGenerateChallengeFailed()
|
||||||
}
|
}
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
errorDialogViewModel.newDialogFlow.collect {
|
||||||
|
Log.d(TAG, "newErrorDialogFlow($it)")
|
||||||
|
FingerprintEnrollErrorDialog.newInstance(it).show(
|
||||||
|
supportFragmentManager,
|
||||||
|
ERROR_DIALOG_TAG
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
errorDialogViewModel.setResultFlow.collect {
|
||||||
|
Log.d(TAG, "errorDialogSetResultFlow($it)")
|
||||||
|
when (it) {
|
||||||
|
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH -> onSetActivityResult(
|
||||||
|
ActivityResult(BiometricEnrollBase.RESULT_FINISHED, null)
|
||||||
|
)
|
||||||
|
|
||||||
|
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT -> onSetActivityResult(
|
||||||
|
ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startFragment(fragmentClass: Class<out Fragment>, tag: String) {
|
private fun startFragment(fragmentClass: Class<out Fragment>, tag: String) {
|
||||||
@@ -252,7 +286,7 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
if (request.isSkipIntro || request.isSkipFindSensor) {
|
if (request.isSkipIntro || request.isSkipFindSensor) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
viewModelProvider[FingerprintEnrollIntroViewModel::class.java].let {
|
introViewModel.let {
|
||||||
// Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
|
// Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
|
||||||
// recreate, like press 'Agree' then press 'back' in FingerprintEnrollFindSensor
|
// recreate, like press 'Agree' then press 'back' in FingerprintEnrollFindSensor
|
||||||
// activity.
|
// activity.
|
||||||
@@ -264,8 +298,7 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
// We need to make sure token is valid before entering find sensor page
|
// We need to make sure token is valid before entering find sensor page
|
||||||
private fun startFindSensorFragment() {
|
private fun startFindSensorFragment() {
|
||||||
// Always setToken into progressViewModel even it is not necessary action for UDFPS
|
// Always setToken into progressViewModel even it is not necessary action for UDFPS
|
||||||
viewModelProvider[FingerprintEnrollProgressViewModel::class.java]
|
progressViewModel.setToken(autoCredentialViewModel.token)
|
||||||
.setToken(autoCredentialViewModel.token)
|
|
||||||
attachFindSensorViewModel()
|
attachFindSensorViewModel()
|
||||||
val fragmentClass: Class<out Fragment> = if (viewModel.canAssumeUdfps()) {
|
val fragmentClass: Class<out Fragment> = if (viewModel.canAssumeUdfps()) {
|
||||||
FingerprintEnrollFindUdfpsFragment::class.java
|
FingerprintEnrollFindUdfpsFragment::class.java
|
||||||
@@ -281,7 +314,7 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
if (viewModel.request.isSkipFindSensor) {
|
if (viewModel.request.isSkipFindSensor) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
viewModelProvider[FingerprintEnrollFindSensorViewModel::class.java].let {
|
findSensorViewModel.let {
|
||||||
// Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
|
// Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
|
||||||
// recreate, like press 'Start' then press 'back' in FingerprintEnrollEnrolling
|
// recreate, like press 'Start' then press 'back' in FingerprintEnrollEnrolling
|
||||||
// activity.
|
// activity.
|
||||||
@@ -292,8 +325,7 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
|
|
||||||
private fun startEnrollingFragment() {
|
private fun startEnrollingFragment() {
|
||||||
// Always setToken into progressViewModel even it is not necessary action for SFPS or RFPS
|
// Always setToken into progressViewModel even it is not necessary action for SFPS or RFPS
|
||||||
viewModelProvider[FingerprintEnrollProgressViewModel::class.java]
|
progressViewModel.setToken(autoCredentialViewModel.token)
|
||||||
.setToken(autoCredentialViewModel.token)
|
|
||||||
attachEnrollingViewModel()
|
attachEnrollingViewModel()
|
||||||
val fragmentClass: Class<out Fragment> = if (viewModel.canAssumeUdfps()) {
|
val fragmentClass: Class<out Fragment> = if (viewModel.canAssumeUdfps()) {
|
||||||
FingerprintEnrollEnrollingUdfpsFragment::class.java
|
FingerprintEnrollEnrollingUdfpsFragment::class.java
|
||||||
@@ -306,14 +338,9 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun attachEnrollingViewModel() {
|
private fun attachEnrollingViewModel() {
|
||||||
viewModelProvider[FingerprintEnrollEnrollingViewModel::class.java].let {
|
enrollingViewModel.let {
|
||||||
it.clearActionLiveData()
|
it.clearActionLiveData()
|
||||||
it.actionLiveData.observe(this, enrollingActionObserver)
|
it.actionLiveData.observe(this, enrollingActionObserver)
|
||||||
it.errorDialogLiveData.observe(this, enrollingErrorDialogObserver)
|
|
||||||
it.errorDialogActionLiveData.observe(
|
|
||||||
this,
|
|
||||||
enrollingErrorDialogActionObserver
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +401,7 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun attachFinishViewModel() {
|
private fun attachFinishViewModel() {
|
||||||
viewModelProvider[FingerprintEnrollFinishViewModel::class.java].let {
|
finishViewModel.let {
|
||||||
it.clearActionLiveData()
|
it.clearActionLiveData()
|
||||||
it.actionLiveData.observe(this, finishActionObserver)
|
it.actionLiveData.observe(this, finishActionObserver)
|
||||||
}
|
}
|
||||||
@@ -520,18 +547,6 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onEnrollingErrorDialogAction(@FingerprintErrorDialogAction action: Int) {
|
|
||||||
when (action) {
|
|
||||||
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH -> onSetActivityResult(
|
|
||||||
ActivityResult(BiometricEnrollBase.RESULT_FINISHED, null)
|
|
||||||
)
|
|
||||||
|
|
||||||
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT -> onSetActivityResult(
|
|
||||||
ActivityResult(BiometricEnrollBase.RESULT_TIMEOUT, null)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onFinishAction(@FingerprintEnrollFinishAction action: Int) {
|
private fun onFinishAction(@FingerprintEnrollFinishAction action: Int) {
|
||||||
when (action) {
|
when (action) {
|
||||||
FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK -> {
|
FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK -> {
|
||||||
@@ -623,12 +638,13 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
|
|||||||
companion object {
|
companion object {
|
||||||
private const val DEBUG = false
|
private const val DEBUG = false
|
||||||
private const val TAG = "FingerprintEnrollmentActivity"
|
private const val TAG = "FingerprintEnrollmentActivity"
|
||||||
|
protected const val LAUNCH_CONFIRM_LOCK_ACTIVITY = 1
|
||||||
|
|
||||||
private const val INTRO_TAG = "intro"
|
private const val INTRO_TAG = "intro"
|
||||||
private const val FIND_SENSOR_TAG = "find-sensor"
|
private const val FIND_SENSOR_TAG = "find-sensor"
|
||||||
private const val ENROLLING_TAG = "enrolling"
|
private const val ENROLLING_TAG = "enrolling"
|
||||||
private const val FINISH_TAG = "finish"
|
private const val FINISH_TAG = "finish"
|
||||||
private const val SKIP_SETUP_FIND_FPS_DIALOG_TAG = "skip-setup-dialog"
|
private const val SKIP_SETUP_FIND_FPS_DIALOG_TAG = "skip-setup-dialog"
|
||||||
private const val ENROLLING_ERROR_DIALOG_TAG = "enrolling-error-dialog"
|
private const val ERROR_DIALOG_TAG = "error-dialog"
|
||||||
protected const val LAUNCH_CONFIRM_LOCK_ACTIVITY = 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,9 +59,7 @@ public class DeviceRotationViewModel extends AndroidViewModel {
|
|||||||
@Override
|
@Override
|
||||||
public void onDisplayChanged(int displayId) {
|
public void onDisplayChanged(int displayId) {
|
||||||
final int rotation = getRotation();
|
final int rotation = getRotation();
|
||||||
if (DEBUG) {
|
Log.d(TAG, "onDisplayChanged(" + displayId + "), rotation:" + rotation);
|
||||||
Log.d(TAG, "onDisplayChanged(" + displayId + "), rotation:" + rotation);
|
|
||||||
}
|
|
||||||
mLiveData.postValue(rotation);
|
mLiveData.postValue(rotation);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -98,10 +96,11 @@ public class DeviceRotationViewModel extends AndroidViewModel {
|
|||||||
* Returns RotationLiveData
|
* Returns RotationLiveData
|
||||||
*/
|
*/
|
||||||
public LiveData<Integer> getLiveData() {
|
public LiveData<Integer> getLiveData() {
|
||||||
if (mLiveData.getValue() == null) {
|
final Integer lastRotation = mLiveData.getValue();
|
||||||
// Init data here because if we set it through getDisplay().getRotation() or through
|
@Surface.Rotation int newRotation = getRotation();
|
||||||
// getDisplay().getDisplayInfo() in constructor(), we always get incorrect value.
|
if (lastRotation == null || lastRotation != newRotation) {
|
||||||
mLiveData.setValue(getRotation());
|
Log.d(TAG, "getLiveData, update rotation from " + lastRotation + " to " + newRotation);
|
||||||
|
mLiveData.setValue(newRotation);
|
||||||
}
|
}
|
||||||
return mLiveData;
|
return mLiveData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,29 +73,11 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
|
|||||||
@IntDef(prefix = { "FINGERPRINT_ENROLL_ENROLLING_ACTION_" }, value = {
|
@IntDef(prefix = { "FINGERPRINT_ENROLL_ENROLLING_ACTION_" }, value = {
|
||||||
FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE,
|
FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE,
|
||||||
FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG,
|
FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG,
|
||||||
FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP,
|
FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP
|
||||||
FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED
|
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface FingerprintEnrollEnrollingAction {}
|
public @interface FingerprintEnrollEnrollingAction {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Enrolling skipped
|
|
||||||
*/
|
|
||||||
public static final int FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enrolling finished
|
|
||||||
*/
|
|
||||||
public static final int FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT = 1;
|
|
||||||
|
|
||||||
@IntDef(prefix = { "FINGERPRINT_ERROR_DIALOG_ACTION_" }, value = {
|
|
||||||
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH,
|
|
||||||
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
|
||||||
})
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
|
||||||
public @interface FingerprintErrorDialogAction {}
|
|
||||||
|
|
||||||
private final int mUserId;
|
private final int mUserId;
|
||||||
private boolean mOnBackPressed;
|
private boolean mOnBackPressed;
|
||||||
private boolean mOnSkipPressed;
|
private boolean mOnSkipPressed;
|
||||||
@@ -104,11 +86,12 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
|
|||||||
private final Vibrator mVibrator;
|
private final Vibrator mVibrator;
|
||||||
|
|
||||||
private final MutableLiveData<Integer> mActionLiveData = new MutableLiveData<>();
|
private final MutableLiveData<Integer> mActionLiveData = new MutableLiveData<>();
|
||||||
private final MutableLiveData<ErrorDialogData> mErrorDialogLiveData = new MutableLiveData<>();
|
|
||||||
private final MutableLiveData<Integer> mErrorDialogActionLiveData = new MutableLiveData<>();
|
|
||||||
|
|
||||||
public FingerprintEnrollEnrollingViewModel(@NonNull Application application,
|
public FingerprintEnrollEnrollingViewModel(
|
||||||
int userId, @NonNull FingerprintRepository fingerprintRepository) {
|
@NonNull Application application,
|
||||||
|
int userId,
|
||||||
|
@NonNull FingerprintRepository fingerprintRepository
|
||||||
|
) {
|
||||||
super(application);
|
super(application);
|
||||||
mUserId = userId;
|
mUserId = userId;
|
||||||
mFingerprintRepository = fingerprintRepository;
|
mFingerprintRepository = fingerprintRepository;
|
||||||
@@ -116,21 +99,6 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
|
|||||||
mVibrator = application.getSystemService(Vibrator.class);
|
mVibrator = application.getSystemService(Vibrator.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies activity to show error dialog
|
|
||||||
*/
|
|
||||||
public void showErrorDialog(@NonNull ErrorDialogData errorDialogData) {
|
|
||||||
mErrorDialogLiveData.postValue(errorDialogData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<ErrorDialogData> getErrorDialogLiveData() {
|
|
||||||
return mErrorDialogLiveData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<Integer> getErrorDialogActionLiveData() {
|
|
||||||
return mErrorDialogActionLiveData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<Integer> getActionLiveData() {
|
public LiveData<Integer> getActionLiveData() {
|
||||||
return mActionLiveData;
|
return mActionLiveData;
|
||||||
}
|
}
|
||||||
@@ -142,16 +110,6 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
|
|||||||
mActionLiveData.setValue(null);
|
mActionLiveData.setValue(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves new user dialog action to mErrorDialogActionLiveData
|
|
||||||
*/
|
|
||||||
public void onErrorDialogAction(@FingerprintErrorDialogAction int action) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "onErrorDialogAction(" + action + ")");
|
|
||||||
}
|
|
||||||
mErrorDialogActionLiveData.postValue(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getOnSkipPressed() {
|
public boolean getOnSkipPressed() {
|
||||||
return mOnSkipPressed;
|
return mOnSkipPressed;
|
||||||
}
|
}
|
||||||
@@ -164,7 +122,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enrolling is cacelled because user clicks skip
|
* Enrolling is cancelled because user clicks skip
|
||||||
*/
|
*/
|
||||||
public void onCancelledDueToOnSkipPressed() {
|
public void onCancelledDueToOnSkipPressed() {
|
||||||
final int action = FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP;
|
final int action = FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP;
|
||||||
@@ -287,38 +245,4 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel {
|
|||||||
public FingerprintSensorPropertiesInternal getFirstFingerprintSensorPropertiesInternal() {
|
public FingerprintSensorPropertiesInternal getFirstFingerprintSensorPropertiesInternal() {
|
||||||
return mFingerprintRepository.getFirstFingerprintSensorPropertiesInternal();
|
return mFingerprintRepository.getFirstFingerprintSensorPropertiesInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Data for passing to FingerprintEnrollEnrollingErrorDialog
|
|
||||||
*/
|
|
||||||
public static class ErrorDialogData {
|
|
||||||
@NonNull private final CharSequence mErrMsg;
|
|
||||||
@NonNull private final CharSequence mErrTitle;
|
|
||||||
@NonNull private final int mErrMsgId;
|
|
||||||
|
|
||||||
public ErrorDialogData(@NonNull CharSequence errMsg, @NonNull CharSequence errTitle,
|
|
||||||
int errMsgId) {
|
|
||||||
mErrMsg = errMsg;
|
|
||||||
mErrTitle = errTitle;
|
|
||||||
mErrMsgId = errMsgId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharSequence getErrMsg() {
|
|
||||||
return mErrMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharSequence getErrTitle() {
|
|
||||||
return mErrTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getErrMsgId() {
|
|
||||||
return mErrMsgId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode())
|
|
||||||
+ "{id:" + mErrMsgId + "}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.android.settings.biometrics2.ui.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import kotlinx.atomicfu.AtomicBoolean
|
||||||
|
import kotlinx.atomicfu.atomic
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
|
|
||||||
|
class FingerprintEnrollErrorDialogViewModel(
|
||||||
|
application: Application,
|
||||||
|
val isSuw: Boolean
|
||||||
|
): AndroidViewModel(application) {
|
||||||
|
|
||||||
|
private val _isDialogShown: AtomicBoolean = atomic(false)
|
||||||
|
val isDialogShown: Boolean
|
||||||
|
get() = _isDialogShown.value
|
||||||
|
|
||||||
|
private val _newDialogFlow = MutableSharedFlow<Int>()
|
||||||
|
val newDialogFlow: SharedFlow<Int>
|
||||||
|
get() = _newDialogFlow.asSharedFlow()
|
||||||
|
|
||||||
|
private val _triggerRetryFlow = MutableSharedFlow<Any>()
|
||||||
|
val triggerRetryFlow: SharedFlow<Any>
|
||||||
|
get() = _triggerRetryFlow.asSharedFlow()
|
||||||
|
|
||||||
|
private val _setResultFlow = MutableSharedFlow<FingerprintErrorDialogSetResultAction>()
|
||||||
|
val setResultFlow: SharedFlow<FingerprintErrorDialogSetResultAction>
|
||||||
|
get() = _setResultFlow.asSharedFlow()
|
||||||
|
|
||||||
|
suspend fun newDialog(errorMsgId: Int) {
|
||||||
|
_isDialogShown.compareAndSet(expect = false, update = true)
|
||||||
|
_newDialogFlow.emit(errorMsgId)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun triggerRetry() {
|
||||||
|
_isDialogShown.compareAndSet(expect = true, update = false)
|
||||||
|
_triggerRetryFlow.emit(Any())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun setResultAndFinish(action: FingerprintErrorDialogSetResultAction) {
|
||||||
|
_isDialogShown.compareAndSet(expect = true, update = false)
|
||||||
|
_setResultFlow.emit(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class FingerprintErrorDialogSetResultAction {
|
||||||
|
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH,
|
||||||
|
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.settings.biometrics2.ui.viewmodel;
|
package com.android.settings.biometrics2.ui.viewmodel;
|
||||||
|
|
||||||
|
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_CANCELED;
|
||||||
import static android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL;
|
import static android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL;
|
||||||
|
|
||||||
import static com.android.settings.biometrics2.ui.model.EnrollmentProgress.INITIAL_REMAINING;
|
import static com.android.settings.biometrics2.ui.model.EnrollmentProgress.INITIAL_REMAINING;
|
||||||
@@ -41,6 +42,8 @@ import com.android.settings.biometrics.fingerprint.MessageDisplayController;
|
|||||||
import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
|
import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
|
||||||
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage;
|
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Progress ViewModel handles the state around biometric enrollment. It manages the state of
|
* Progress ViewModel handles the state around biometric enrollment. It manages the state of
|
||||||
* enrollment throughout the activity lifecycle so the app can continue after an event like
|
* enrollment throughout the activity lifecycle so the app can continue after an event like
|
||||||
@@ -57,6 +60,7 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
|
|||||||
new MutableLiveData<>();
|
new MutableLiveData<>();
|
||||||
private final MutableLiveData<EnrollmentStatusMessage> mErrorMessageLiveData =
|
private final MutableLiveData<EnrollmentStatusMessage> mErrorMessageLiveData =
|
||||||
new MutableLiveData<>();
|
new MutableLiveData<>();
|
||||||
|
private final MutableLiveData<Object> mCanceledSignalLiveData = new MutableLiveData<>();
|
||||||
private final MutableLiveData<Boolean> mAcquireLiveData = new MutableLiveData<>();
|
private final MutableLiveData<Boolean> mAcquireLiveData = new MutableLiveData<>();
|
||||||
private final MutableLiveData<Integer> mPointerDownLiveData = new MutableLiveData<>();
|
private final MutableLiveData<Integer> mPointerDownLiveData = new MutableLiveData<>();
|
||||||
private final MutableLiveData<Integer> mPointerUpLiveData = new MutableLiveData<>();
|
private final MutableLiveData<Integer> mPointerUpLiveData = new MutableLiveData<>();
|
||||||
@@ -66,6 +70,8 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
|
|||||||
|
|
||||||
private final FingerprintUpdater mFingerprintUpdater;
|
private final FingerprintUpdater mFingerprintUpdater;
|
||||||
@Nullable private CancellationSignal mCancellationSignal = null;
|
@Nullable private CancellationSignal mCancellationSignal = null;
|
||||||
|
@NonNull private final LinkedList<CancellationSignal> mCancelingSignalQueue =
|
||||||
|
new LinkedList<>();
|
||||||
private final EnrollmentCallback mEnrollmentCallback = new EnrollmentCallback() {
|
private final EnrollmentCallback mEnrollmentCallback = new EnrollmentCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -91,10 +97,13 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnrollmentError(int errMsgId, CharSequence errString) {
|
public void onEnrollmentError(int errMsgId, CharSequence errString) {
|
||||||
if (DEBUG) {
|
Log.d(TAG, "onEnrollmentError(" + errMsgId + ", " + errString
|
||||||
Log.d(TAG, "onEnrollmentError(" + errMsgId + ", " + errString + ")");
|
+ "), cancelingQueueSize:" + mCancelingSignalQueue.size());
|
||||||
|
if (FINGERPRINT_ERROR_CANCELED == errMsgId && mCancelingSignalQueue.size() > 0) {
|
||||||
|
mCanceledSignalLiveData.postValue(mCancelingSignalQueue.poll());
|
||||||
|
} else {
|
||||||
|
mErrorMessageLiveData.postValue(new EnrollmentStatusMessage(errMsgId, errString));
|
||||||
}
|
}
|
||||||
mErrorMessageLiveData.postValue(new EnrollmentStatusMessage(errMsgId, errString));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -152,6 +161,10 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
|
|||||||
return mErrorMessageLiveData;
|
return mErrorMessageLiveData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Object> getCanceledSignalLiveData() {
|
||||||
|
return mCanceledSignalLiveData;
|
||||||
|
}
|
||||||
|
|
||||||
public LiveData<Boolean> getAcquireLiveData() {
|
public LiveData<Boolean> getAcquireLiveData() {
|
||||||
return mAcquireLiveData;
|
return mAcquireLiveData;
|
||||||
}
|
}
|
||||||
@@ -167,14 +180,14 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
|
|||||||
/**
|
/**
|
||||||
* Starts enrollment and return latest isEnrolling() result
|
* Starts enrollment and return latest isEnrolling() result
|
||||||
*/
|
*/
|
||||||
public boolean startEnrollment(@EnrollReason int reason) {
|
public Object startEnrollment(@EnrollReason int reason) {
|
||||||
if (mToken == null) {
|
if (mToken == null) {
|
||||||
Log.e(TAG, "Null hardware auth token for enroll");
|
Log.e(TAG, "Null hardware auth token for enroll");
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
if (mCancellationSignal != null) {
|
if (mCancellationSignal != null) {
|
||||||
Log.w(TAG, "Enrolling has started, shall not start again");
|
Log.w(TAG, "Enrolling is running, shall not start again");
|
||||||
return true;
|
return mCancellationSignal;
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.e(TAG, "startEnrollment(" + reason + ")");
|
Log.e(TAG, "startEnrollment(" + reason + ")");
|
||||||
@@ -204,7 +217,7 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
|
|||||||
mFingerprintUpdater.enroll(mToken, mCancellationSignal, mUserId, mEnrollmentCallback,
|
mFingerprintUpdater.enroll(mToken, mCancellationSignal, mUserId, mEnrollmentCallback,
|
||||||
reason);
|
reason);
|
||||||
}
|
}
|
||||||
return true;
|
return mCancellationSignal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -212,13 +225,17 @@ public class FingerprintEnrollProgressViewModel extends AndroidViewModel {
|
|||||||
*/
|
*/
|
||||||
public boolean cancelEnrollment() {
|
public boolean cancelEnrollment() {
|
||||||
final CancellationSignal cancellationSignal = mCancellationSignal;
|
final CancellationSignal cancellationSignal = mCancellationSignal;
|
||||||
|
mCancellationSignal = null;
|
||||||
|
|
||||||
if (cancellationSignal == null) {
|
if (cancellationSignal == null) {
|
||||||
Log.e(TAG, "Fail to cancel enrollment, has cancelled or not start");
|
Log.e(TAG, "Fail to cancel enrollment, has cancelled or not start");
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "enrollment cancelled");
|
||||||
}
|
}
|
||||||
|
mCancelingSignalQueue.add(cancellationSignal);
|
||||||
mCancellationSignal = null;
|
|
||||||
cancellationSignal.cancel();
|
cancellationSignal.cancel();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.RotationUtils;
|
import android.util.RotationUtils;
|
||||||
import android.view.DisplayInfo;
|
import android.view.DisplayInfo;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
@@ -130,18 +131,26 @@ public class UdfpsEnrollView extends FrameLayout {
|
|||||||
onFingerUp();
|
onFingerUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ViewTreeObserver.OnDrawListener mOnDrawListener = this::updateOverlayParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setup SensorProperties
|
* setup SensorProperties
|
||||||
*/
|
*/
|
||||||
public void setSensorProperties(FingerprintSensorPropertiesInternal properties) {
|
public void setSensorProperties(FingerprintSensorPropertiesInternal properties) {
|
||||||
mSensorProperties = properties;
|
mSensorProperties = properties;
|
||||||
((ViewGroup) getParent()).getViewTreeObserver().addOnDrawListener(
|
((ViewGroup) getParent()).getViewTreeObserver().addOnDrawListener(mOnDrawListener);
|
||||||
new ViewTreeObserver.OnDrawListener() {
|
}
|
||||||
@Override
|
|
||||||
public void onDraw() {
|
@Override
|
||||||
updateOverlayParams();
|
protected void onDetachedFromWindow() {
|
||||||
}
|
final ViewGroup parent = (ViewGroup) getParent();
|
||||||
});
|
if (parent != null) {
|
||||||
|
final ViewTreeObserver observer = parent.getViewTreeObserver();
|
||||||
|
if (observer != null) {
|
||||||
|
observer.removeOnDrawListener(mOnDrawListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onDetachedFromWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSensorRectUpdated() {
|
private void onSensorRectUpdated() {
|
||||||
@@ -168,6 +177,10 @@ public class UdfpsEnrollView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RelativeLayout parent = ((RelativeLayout) getParent());
|
RelativeLayout parent = ((RelativeLayout) getParent());
|
||||||
|
if (parent == null) {
|
||||||
|
Log.e(TAG, "Fail to updateDimensions for " + this + ", parent null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
final int[] coords = parent.getLocationOnScreen();
|
final int[] coords = parent.getLocationOnScreen();
|
||||||
final int parentLeft = coords[0];
|
final int parentLeft = coords[0];
|
||||||
final int parentTop = coords[1];
|
final int parentTop = coords[1];
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroChooseLock_landscape() {
|
fun testIntroChooseLock_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroChooseLock()
|
testIntroChooseLock()
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroWithGkPwHandle_withUdfps_clickStart_landscape() {
|
fun testIntroWithGkPwHandle_withUdfps_clickStart_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroWithGkPwHandle_withUdfps_clickStart()
|
testIntroWithGkPwHandle_withUdfps_clickStart()
|
||||||
}
|
}
|
||||||
@@ -226,7 +226,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroWithGkPwHandle_withUdfps_clickLottie_landscape() {
|
fun testIntroWithGkPwHandle_withUdfps_clickLottie_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroWithGkPwHandle_withUdfps_clickLottie()
|
testIntroWithGkPwHandle_withUdfps_clickLottie()
|
||||||
}
|
}
|
||||||
@@ -256,7 +256,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroWithGkPwHandle_withSfps_landscape() {
|
fun testIntroWithGkPwHandle_withSfps_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroWithGkPwHandle_withSfps()
|
testIntroWithGkPwHandle_withSfps()
|
||||||
}
|
}
|
||||||
@@ -291,7 +291,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroWithGkPwHandle_withRfps_landscape() {
|
fun testIntroWithGkPwHandle_withRfps_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroWithGkPwHandle_withRfps()
|
testIntroWithGkPwHandle_withRfps()
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroWithGkPwHandle_clickNoThanksInIntroPage_landscape() {
|
fun testIntroWithGkPwHandle_clickNoThanksInIntroPage_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroWithGkPwHandle_clickNoThanksInIntroPage()
|
testIntroWithGkPwHandle_clickNoThanksInIntroPage()
|
||||||
}
|
}
|
||||||
@@ -344,7 +344,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroWithGkPwHandle_clickSkipInFindSensor_landscape() {
|
fun testIntroWithGkPwHandle_clickSkipInFindSensor_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroWithGkPwHandle_clickSkipInFindSensor()
|
testIntroWithGkPwHandle_clickSkipInFindSensor()
|
||||||
}
|
}
|
||||||
@@ -382,7 +382,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroWithGkPwHandle_clickSkipAnywayInFindFpsDialog_whenIsSuw_landscape() {
|
fun testIntroWithGkPwHandle_clickSkipAnywayInFindFpsDialog_whenIsSuw_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroWithGkPwHandle_clickSkipAnywayInFindFpsDialog_whenIsSuw()
|
testIntroWithGkPwHandle_clickSkipAnywayInFindFpsDialog_whenIsSuw()
|
||||||
}
|
}
|
||||||
@@ -418,7 +418,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIntroWithGkPwHandle_clickGoBackInFindFpsDialog_whenIsSuw_landscape() {
|
fun testIntroWithGkPwHandle_clickGoBackInFindFpsDialog_whenIsSuw_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testIntroWithGkPwHandle_clickGoBackInFindFpsDialog_whenIsSuw()
|
testIntroWithGkPwHandle_clickGoBackInFindFpsDialog_whenIsSuw()
|
||||||
}
|
}
|
||||||
@@ -449,7 +449,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testEnrollingWithGkPwHandle_landscape() {
|
fun testEnrollingWithGkPwHandle_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testEnrollingWithGkPwHandle()
|
testEnrollingWithGkPwHandle()
|
||||||
}
|
}
|
||||||
@@ -492,7 +492,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testEnrollingIconTouchDialog_withSfps_landscape() {
|
fun testEnrollingIconTouchDialog_withSfps_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testEnrollingIconTouchDialog_withSfps()
|
testEnrollingIconTouchDialog_withSfps()
|
||||||
}
|
}
|
||||||
@@ -534,7 +534,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testEnrollingIconTouchDialog_withRfps_landscape() {
|
fun testEnrollingIconTouchDialog_withRfps_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testEnrollingIconTouchDialog_withRfps()
|
testEnrollingIconTouchDialog_withRfps()
|
||||||
}
|
}
|
||||||
@@ -563,7 +563,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFindUdfpsWithGkPwHandle_clickStart_landscape() {
|
fun testFindUdfpsWithGkPwHandle_clickStart_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testFindUdfpsWithGkPwHandle_clickStart()
|
testFindUdfpsWithGkPwHandle_clickStart()
|
||||||
}
|
}
|
||||||
@@ -580,7 +580,11 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
|
assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
|
||||||
|
|
||||||
// rotate device
|
// rotate device
|
||||||
device.setOrientationLandscape()
|
if (runAsLandscape) {
|
||||||
|
device.setOrientationPortrait()
|
||||||
|
} else {
|
||||||
|
device.setOrientationLandscape()
|
||||||
|
}
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
|
|
||||||
// FindUdfps page (landscape)
|
// FindUdfps page (landscape)
|
||||||
@@ -605,6 +609,12 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
|
assertThat(device.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFindUdfpsLandscapeWithGkPwHandle_clickStartThenBack_runAslandscape() {
|
||||||
|
runAsLandscape = true
|
||||||
|
testFindUdfpsLandscapeWithGkPwHandle_clickStartThenBack()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFindUdfpsWithGkPwHandle_clickLottie() {
|
fun testFindUdfpsWithGkPwHandle_clickLottie() {
|
||||||
Assume.assumeTrue(canAssumeUdfps)
|
Assume.assumeTrue(canAssumeUdfps)
|
||||||
@@ -629,7 +639,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFindUdfpsWithGkPwHandle_clickLottie_landscape() {
|
fun testFindUdfpsWithGkPwHandle_clickLottie_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testFindUdfpsWithGkPwHandle_clickLottie()
|
testFindUdfpsWithGkPwHandle_clickLottie()
|
||||||
}
|
}
|
||||||
@@ -653,7 +663,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFindSfpsWithGkPwHandle_landscape() {
|
fun testFindSfpsWithGkPwHandle_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testFindSfpsWithGkPwHandle()
|
testFindSfpsWithGkPwHandle()
|
||||||
}
|
}
|
||||||
@@ -688,7 +698,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFindRfpsWithGkPwHandle_landscape() {
|
fun testFindRfpsWithGkPwHandle_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testFindRfpsWithGkPwHandle()
|
testFindRfpsWithGkPwHandle()
|
||||||
}
|
}
|
||||||
@@ -712,7 +722,7 @@ class FingerprintEnrollmentActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFindSensorWithGkPwHandle_clickSkipInFindSensor_landscape() {
|
fun testFindSensorWithGkPwHandle_clickSkipInFindSensor_runAslandscape() {
|
||||||
runAsLandscape = true
|
runAsLandscape = true
|
||||||
testFindSensorWithGkPwHandle_clickSkipInFindSensor()
|
testFindSensorWithGkPwHandle_clickSkipInFindSensor()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,9 @@ package com.android.settings.biometrics2.ui.viewmodel;
|
|||||||
|
|
||||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
|
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
|
||||||
|
|
||||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData;
|
|
||||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG;
|
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG;
|
||||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED;
|
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED;
|
||||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP;
|
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP;
|
||||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH;
|
|
||||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT;
|
|
||||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintErrorDialogAction;
|
|
||||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository;
|
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
@@ -78,19 +74,10 @@ public class FingerprintEnrollEnrollingViewModelTest {
|
|||||||
mViewModel = new FingerprintEnrollEnrollingViewModel(
|
mViewModel = new FingerprintEnrollEnrollingViewModel(
|
||||||
mApplication,
|
mApplication,
|
||||||
TEST_USER_ID,
|
TEST_USER_ID,
|
||||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)
|
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testShowErrorDialogLiveData() {
|
|
||||||
assertThat(mViewModel.getErrorDialogLiveData().getValue()).isEqualTo(null);
|
|
||||||
|
|
||||||
final ErrorDialogData data = new ErrorDialogData("errMsg", "errTitle", 0);
|
|
||||||
mViewModel.showErrorDialog(data);
|
|
||||||
assertThat(mViewModel.getErrorDialogLiveData().getValue()).isEqualTo(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIconTouchDialog() {
|
public void testIconTouchDialog() {
|
||||||
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
||||||
@@ -101,20 +88,6 @@ public class FingerprintEnrollEnrollingViewModelTest {
|
|||||||
FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG);
|
FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testErrorDialogActionLiveData() {
|
|
||||||
assertThat(mViewModel.getErrorDialogActionLiveData().getValue()).isEqualTo(null);
|
|
||||||
|
|
||||||
@FingerprintErrorDialogAction int action =
|
|
||||||
FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT;
|
|
||||||
mViewModel.onErrorDialogAction(action);
|
|
||||||
assertThat(mViewModel.getErrorDialogActionLiveData().getValue()).isEqualTo(action);
|
|
||||||
|
|
||||||
action = FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH;
|
|
||||||
mViewModel.onErrorDialogAction(action);
|
|
||||||
assertThat(mViewModel.getErrorDialogActionLiveData().getValue()).isEqualTo(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void tesBackPressedScenario() {
|
public void tesBackPressedScenario() {
|
||||||
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.settings.biometrics2.ui.viewmodel
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintErrorDialogSetResultAction.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
||||||
|
import com.android.settings.biometrics2.ui.viewmodel.FingerprintErrorDialogSetResultAction.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.toList
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class FingerprintEnrollErrorDialogViewModelTest {
|
||||||
|
|
||||||
|
private val application = ApplicationProvider.getApplicationContext<Application>()
|
||||||
|
private var viewModel: FingerprintEnrollErrorDialogViewModel =
|
||||||
|
FingerprintEnrollErrorDialogViewModel(application, false)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
// Make sure viewModel is new for each test
|
||||||
|
viewModel = FingerprintEnrollErrorDialogViewModel(application, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testIsDialogNotShownDefaultFalse() {
|
||||||
|
assertThat(viewModel.isDialogShown).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testIsSuw() {
|
||||||
|
assertThat(FingerprintEnrollErrorDialogViewModel(application, false).isSuw).isFalse()
|
||||||
|
assertThat(FingerprintEnrollErrorDialogViewModel(application, true).isSuw).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@Test
|
||||||
|
fun testNewDialog() = runTest {
|
||||||
|
backgroundScope.launch {
|
||||||
|
mutableListOf<Any>().let { list ->
|
||||||
|
viewModel.newDialogFlow.toList(list)
|
||||||
|
assertThat(list.size).isEqualTo(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
mutableListOf<FingerprintErrorDialogSetResultAction>().let { list ->
|
||||||
|
val testErrorMsgId = 3456
|
||||||
|
viewModel.newDialog(testErrorMsgId)
|
||||||
|
|
||||||
|
assertThat(viewModel.isDialogShown).isTrue()
|
||||||
|
viewModel.setResultFlow.toList(list)
|
||||||
|
assertThat(list.size).isEqualTo(1)
|
||||||
|
assertThat(list[0]).isEqualTo(testErrorMsgId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@Test
|
||||||
|
fun testTriggerRetry() = runTest {
|
||||||
|
backgroundScope.launch {
|
||||||
|
// triggerRetryFlow shall be empty on begin
|
||||||
|
mutableListOf<Any>().let { list ->
|
||||||
|
viewModel.triggerRetryFlow.toList(list)
|
||||||
|
assertThat(list.size).isEqualTo(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit newDialog
|
||||||
|
mutableListOf<FingerprintErrorDialogSetResultAction>().let { list ->
|
||||||
|
viewModel.newDialog(0)
|
||||||
|
viewModel.triggerRetry()
|
||||||
|
|
||||||
|
assertThat(viewModel.isDialogShown).isFalse()
|
||||||
|
viewModel.setResultFlow.toList(list)
|
||||||
|
assertThat(list.size).isEqualTo(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@Test
|
||||||
|
fun testSetResultFinish() = runTest {
|
||||||
|
backgroundScope.launch {
|
||||||
|
// setResultFlow shall be empty on begin
|
||||||
|
mutableListOf<FingerprintErrorDialogSetResultAction>().let { list ->
|
||||||
|
viewModel.setResultFlow.toList(list)
|
||||||
|
assertThat(list.size).isEqualTo(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
||||||
|
viewModel = FingerprintEnrollErrorDialogViewModel(application, false)
|
||||||
|
mutableListOf<FingerprintErrorDialogSetResultAction>().let { list ->
|
||||||
|
viewModel.newDialog(0)
|
||||||
|
viewModel.setResultAndFinish(FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH)
|
||||||
|
|
||||||
|
assertThat(viewModel.isDialogShown).isFalse()
|
||||||
|
viewModel.setResultFlow.toList(list)
|
||||||
|
assertThat(list.size).isEqualTo(1)
|
||||||
|
assertThat(list[0]).isEqualTo(FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH)
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT
|
||||||
|
viewModel = FingerprintEnrollErrorDialogViewModel(application, false)
|
||||||
|
mutableListOf<FingerprintErrorDialogSetResultAction>().let { list ->
|
||||||
|
viewModel.newDialog(0)
|
||||||
|
viewModel.setResultAndFinish(FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT)
|
||||||
|
|
||||||
|
assertThat(viewModel.isDialogShown).isFalse()
|
||||||
|
viewModel.setResultFlow.toList(list)
|
||||||
|
assertThat(list.size).isEqualTo(1)
|
||||||
|
assertThat(list[0]).isEqualTo(FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -108,9 +108,9 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
mViewModel.setToken(token);
|
mViewModel.setToken(token);
|
||||||
|
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
final boolean ret = mViewModel.startEnrollment(enrollReason);
|
final Object ret = mViewModel.startEnrollment(enrollReason);
|
||||||
|
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
||||||
eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason));
|
eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason));
|
||||||
assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isFalse();
|
assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isFalse();
|
||||||
@@ -123,9 +123,9 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
mViewModel.setToken(token);
|
mViewModel.setToken(token);
|
||||||
|
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
final boolean ret = mViewModel.startEnrollment(enrollReason);
|
final Object ret = mViewModel.startEnrollment(enrollReason);
|
||||||
|
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
||||||
eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason));
|
eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason));
|
||||||
assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isFalse();
|
assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isFalse();
|
||||||
@@ -142,9 +142,9 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
mViewModel.setToken(token);
|
mViewModel.setToken(token);
|
||||||
|
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
final boolean ret = mViewModel.startEnrollment(enrollReason);
|
final Object ret = mViewModel.startEnrollment(enrollReason);
|
||||||
|
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
||||||
eq(TEST_USER_ID), any(MessageDisplayController.class), eq(enrollReason));
|
eq(TEST_USER_ID), any(MessageDisplayController.class), eq(enrollReason));
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
@@ -166,9 +166,9 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testStartEnrollmentFailBecauseOfNoToken() {
|
public void testStartEnrollmentFailBecauseOfNoToken() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_FIND_SENSOR);
|
final Object ret = mViewModel.startEnrollment(ENROLL_FIND_SENSOR);
|
||||||
|
|
||||||
assertThat(ret).isFalse();
|
assertThat(ret).isNull();
|
||||||
verify(mFingerprintUpdater, never()).enroll(any(byte[].class),
|
verify(mFingerprintUpdater, never()).enroll(any(byte[].class),
|
||||||
any(CancellationSignal.class), anyInt(), any(EnrollmentCallback.class), anyInt());
|
any(CancellationSignal.class), anyInt(), any(EnrollmentCallback.class), anyInt());
|
||||||
}
|
}
|
||||||
@@ -177,8 +177,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
public void testCancelEnrollment() {
|
public void testCancelEnrollment() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCancellationSignalWrapper.mValue).isNotNull();
|
assertThat(mCancellationSignalWrapper.mValue).isNotNull();
|
||||||
|
|
||||||
// Cancel enrollment
|
// Cancel enrollment
|
||||||
@@ -191,8 +191,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
public void testProgressUpdate() {
|
public void testProgressUpdate() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
|
|
||||||
// Test default value
|
// Test default value
|
||||||
@@ -228,8 +228,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
public void testProgressUpdateClearHelpMessage() {
|
public void testProgressUpdateClearHelpMessage() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
final LiveData<EnrollmentProgress> progressLiveData = mViewModel.getProgressLiveData();
|
final LiveData<EnrollmentProgress> progressLiveData = mViewModel.getProgressLiveData();
|
||||||
final LiveData<EnrollmentStatusMessage> helpMsgLiveData =
|
final LiveData<EnrollmentStatusMessage> helpMsgLiveData =
|
||||||
@@ -271,8 +271,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
|
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
|
|
||||||
// Test default value
|
// Test default value
|
||||||
@@ -308,8 +308,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
public void testGetErrorMessageLiveData() {
|
public void testGetErrorMessageLiveData() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
|
|
||||||
// Check default value
|
// Check default value
|
||||||
@@ -330,8 +330,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
public void testGetHelpMessageLiveData() {
|
public void testGetHelpMessageLiveData() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
|
|
||||||
// Check default value
|
// Check default value
|
||||||
@@ -352,8 +352,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
public void testGetAcquireLiveData() {
|
public void testGetAcquireLiveData() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
|
|
||||||
// Check default value
|
// Check default value
|
||||||
@@ -369,8 +369,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
public void testGetPointerDownLiveData() {
|
public void testGetPointerDownLiveData() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
|
|
||||||
// Check default value
|
// Check default value
|
||||||
@@ -387,8 +387,8 @@ public class FingerprintEnrollProgressViewModelTest {
|
|||||||
public void testGetPointerUpLiveData() {
|
public void testGetPointerUpLiveData() {
|
||||||
// Start enrollment
|
// Start enrollment
|
||||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||||
final boolean ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||||
assertThat(ret).isTrue();
|
assertThat(ret).isNotNull();
|
||||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||||
|
|
||||||
// Check default value
|
// Check default value
|
||||||
|
|||||||
Reference in New Issue
Block a user