Loading src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java +2 −2 Original line number Diff line number Diff line Loading @@ -30,10 +30,10 @@ import android.hardware.fingerprint.FingerprintManager; import android.os.Bundle; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import com.android.settings.R; import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; /** Fingerprint error dialog, will be shown when an error occurs during fingerprint enrollment. */ Loading Loading @@ -95,7 +95,7 @@ public class FingerprintErrorDialog extends InstrumentedDialogFragment { return dialog; } public static void showErrorDialog(BiometricEnrollBase host, int errMsgId, boolean isSetup) { public static void showErrorDialog(FragmentActivity host, int errMsgId, boolean isSetup) { if (host.isFinishing()) { return; } Loading src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt +56 −4 Original line number Diff line number Diff line Loading @@ -20,11 +20,13 @@ import android.annotation.ColorInt import android.app.Activity import android.content.Intent import android.content.res.ColorStateList import android.content.res.Configuration import android.graphics.Color import android.hardware.fingerprint.FingerprintManager import android.os.Bundle import android.provider.Settings import android.util.Log import android.view.accessibility.AccessibilityManager import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity Loading @@ -44,17 +46,21 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.Finge import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollEnrollingV2Fragment import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollFindSensorV2Fragment import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollIntroV2Fragment import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.AccessibilityViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Confirmation import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Education import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Enrollment import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Finish import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FoldStateViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Intro import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.LaunchConfirmDeviceCredential import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.OrientationStateViewModel import com.android.settings.password.ChooseLockGeneric import com.android.settings.password.ChooseLockSettingsHelper import com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE Loading @@ -72,6 +78,10 @@ private const val TAG = "FingerprintEnrollmentV2Activity" class FingerprintEnrollmentV2Activity : FragmentActivity() { private lateinit var navigationViewModel: FingerprintEnrollNavigationViewModel private lateinit var gatekeeperViewModel: FingerprintGatekeeperViewModel private lateinit var fingerprintEnrollViewModel: FingerprintEnrollViewModel private lateinit var accessibilityViewModel: AccessibilityViewModel private lateinit var foldStateViewModel: FoldStateViewModel private lateinit var orientationStateViewModel: OrientationStateViewModel private val coroutineDispatcher = Dispatchers.Default /** Result listener for ChooseLock activity flow. */ Loading @@ -94,6 +104,11 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() { super.onAttachedToWindow() } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) foldStateViewModel.onConfigurationChange(newConfig) } @ColorInt private fun getBackgroundColor(): Int { val stateList: ColorStateList? = Loading Loading @@ -178,16 +193,53 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() { ) )[FingerprintEnrollNavigationViewModel::class.java] // Initialize FoldStateViewModel foldStateViewModel = ViewModelProvider(this, FoldStateViewModel.FoldStateViewModelFactory(context))[ FoldStateViewModel::class.java] foldStateViewModel.onConfigurationChange(resources.configuration) // Initialize FingerprintViewModel fingerprintEnrollViewModel = ViewModelProvider( this, FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory(interactor, backgroundDispatcher) FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory( interactor, backgroundDispatcher ) )[FingerprintEnrollViewModel::class.java] // Initialize scroll view model ViewModelProvider(this, FingerprintScrollViewModel.FingerprintScrollViewModelFactory())[ FingerprintScrollViewModel::class.java] // Initialize AccessibilityViewModel accessibilityViewModel = ViewModelProvider( this, AccessibilityViewModel.AccessibilityViewModelFactory( getSystemService(AccessibilityManager::class.java)!! ) )[AccessibilityViewModel::class.java] // Initialize OrientationViewModel orientationStateViewModel = ViewModelProvider(this, OrientationStateViewModel.OrientationViewModelFactory(context))[ OrientationStateViewModel::class.java] // Initialize FingerprintEnrollFindSensorViewModel ViewModelProvider( this, FingerprintEnrollFindSensorViewModel.FingerprintEnrollFindSensorViewModelFactory( navigationViewModel, fingerprintEnrollViewModel, gatekeeperViewModel, accessibilityViewModel, foldStateViewModel, orientationStateViewModel ) )[FingerprintEnrollFindSensorViewModel::class.java] lifecycleScope.launch { navigationViewModel.navigationViewModel.filterNotNull().collect { Log.d(TAG, "navigationStep $it") Loading src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollEnrollingV2Fragment.kt +2 −1 Original line number Diff line number Diff line Loading @@ -19,10 +19,11 @@ package com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment import android.os.Bundle import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import com.android.settings.R import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel /** A fragment that is responsible for enrolling a users fingerprint. */ class FingerprintEnrollEnrollingV2Fragment : Fragment() { class FingerprintEnrollEnrollingV2Fragment : Fragment(R.layout.fingerprint_enroll_enrolling) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loading src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollFindSensorV2Fragment.kt +176 −5 Original line number Diff line number Diff line Loading @@ -17,26 +17,197 @@ package com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.Surface import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.airbnb.lottie.LottieAnimationView import com.android.settings.R import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog import com.android.settings.biometrics.fingerprint.FingerprintFindSensorAnimation import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel import com.android.systemui.biometrics.shared.model.FingerprintSensorType import com.google.android.setupcompat.template.FooterBarMixin import com.google.android.setupcompat.template.FooterButton import com.google.android.setupdesign.GlifLayout import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch private const val TAG = "FingerprintEnrollFindSensorV2Fragment" /** * A fragment that is used to educate the user about the fingerprint sensor on this device. * * If the sensor is not a udfps sensor, this fragment listens to fingerprint enrollment for * proceeding to the enroll enrolling. * * The main goals of this page are * 1. Inform the user where the fingerprint sensor is on their device * 2. Explain to the user how the enrollment process shown by [FingerprintEnrollEnrollingV2Fragment] * will work. */ class FingerprintEnrollFindSensorV2Fragment : Fragment(R.layout.fingerprint_v2_enroll_find_sensor) { class FingerprintEnrollFindSensorV2Fragment : Fragment() { // This is only for non-udfps or non-sfps sensor. For udfps and sfps, we show lottie. private var animation: FingerprintFindSensorAnimation? = null private var contentLayoutId: Int = -1 private lateinit var viewModel: FingerprintEnrollFindSensorViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) { val navigationViewModel = ViewModelProvider(requireActivity())[FingerprintEnrollNavigationViewModel::class.java] viewModel = ViewModelProvider(requireActivity())[FingerprintEnrollFindSensorViewModel::class.java] lifecycleScope.launch { viewModel.sensorType.collect { contentLayoutId = when (it) { FingerprintSensorType.UDFPS_OPTICAL, FingerprintSensorType.UDFPS_ULTRASONIC -> R.layout.udfps_enroll_find_sensor_layout FingerprintSensorType.POWER_BUTTON -> R.layout.sfps_enroll_find_sensor_layout else -> R.layout.fingerprint_v2_enroll_find_sensor } } } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(contentLayoutId, container, false).also { it -> val view = it!! as GlifLayout // Set up header and description lifecycleScope.launch { viewModel.sensorType.collect { setTexts(it, view) } } // Set up footer bar val footerBarMixin = view.getMixin(FooterBarMixin::class.java) setupSecondaryButton(footerBarMixin) lifecycleScope.launch { viewModel.showPrimaryButton.collect { setupPrimaryButton(footerBarMixin) } } // Set up lottie or animation lifecycleScope.launch { viewModel.showSfpsLottie.collect { (isFolded, rotation) -> setupLottie(view, getSfpsIllustrationLottieAnimation(isFolded, rotation)) } } lifecycleScope.launch { viewModel.showUdfpsLottie.collect { isAccessibilityEnabled -> val lottieAnimation = if (isAccessibilityEnabled) R.raw.udfps_edu_a11y_lottie else R.raw.udfps_edu_lottie setupLottie(view, lottieAnimation) { viewModel.proceedToEnrolling() } } } lifecycleScope.launch { viewModel.showRfpsAnimation.collect { animation = view.findViewById(R.id.fingerprint_sensor_location_animation) animation!!.startAnimation() } } lifecycleScope.launch { viewModel.showErrorDialog.collect { (errMsgId, isSetup) -> // TODO: Covert error dialog kotlin as well FingerprintErrorDialog.showErrorDialog(requireActivity(), errMsgId, isSetup) } } } } override fun onDestroy() { animation?.stopAnimation() super.onDestroy() } private fun setupSecondaryButton(footerBarMixin: FooterBarMixin) { footerBarMixin.secondaryButton = FooterButton.Builder(requireActivity()) .setText(R.string.security_settings_fingerprint_enroll_enrolling_skip) .setListener { run { // TODO: Show the dialog for suw Log.d(TAG, "onSkipClicked") // TODO: Finish activity in the root activity instead. requireActivity().finish() } } .setButtonType(FooterButton.ButtonType.SKIP) .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Secondary) .build() } private fun setupPrimaryButton(footerBarMixin: FooterBarMixin) { footerBarMixin.primaryButton = FooterButton.Builder(requireActivity()) .setText(R.string.security_settings_udfps_enroll_find_sensor_start_button) .setListener { run { Log.d(TAG, "onStartButtonClick") viewModel.proceedToEnrolling() } } .setButtonType(FooterButton.ButtonType.NEXT) .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary) .build() } private fun setupLottie( view: View, lottieAnimation: Int, lottieClickListener: View.OnClickListener? = null ) { val illustrationLottie: LottieAnimationView? = view.findViewById(R.id.illustration_lottie) illustrationLottie?.setAnimation(lottieAnimation) illustrationLottie?.playAnimation() illustrationLottie?.setOnClickListener(lottieClickListener) illustrationLottie?.visibility = View.VISIBLE } private fun setTexts(sensorType: FingerprintSensorType, view: GlifLayout) { when (sensorType) { FingerprintSensorType.UDFPS_OPTICAL, FingerprintSensorType.UDFPS_ULTRASONIC -> { view.setHeaderText(R.string.security_settings_udfps_enroll_find_sensor_title) view.setDescriptionText(R.string.security_settings_udfps_enroll_find_sensor_message) } FingerprintSensorType.POWER_BUTTON -> { view.setHeaderText(R.string.security_settings_sfps_enroll_find_sensor_title) view.setDescriptionText(R.string.security_settings_sfps_enroll_find_sensor_message) } else -> { view.setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title) view.setDescriptionText(R.string.security_settings_fingerprint_enroll_find_sensor_message) } } } private fun getSfpsIllustrationLottieAnimation(isFolded: Boolean, rotation: Int): Int { val animation: Int when (rotation) { Surface.ROTATION_90 -> animation = (if (isFolded) R.raw.fingerprint_edu_lottie_folded_top_left else R.raw.fingerprint_edu_lottie_portrait_top_left) Surface.ROTATION_180 -> animation = (if (isFolded) R.raw.fingerprint_edu_lottie_folded_bottom_left else R.raw.fingerprint_edu_lottie_landscape_bottom_left) Surface.ROTATION_270 -> animation = (if (isFolded) R.raw.fingerprint_edu_lottie_folded_bottom_right else R.raw.fingerprint_edu_lottie_portrait_bottom_right) else -> animation = (if (isFolded) R.raw.fingerprint_edu_lottie_folded_top_right else R.raw.fingerprint_edu_lottie_landscape_top_right) } return animation } } src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollIntroV2Fragment.kt +4 −1 Original line number Diff line number Diff line Loading @@ -180,7 +180,10 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll scrollView.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES // Next button responsible for starting the next fragment. val onNextButtonClick: View.OnClickListener = View.OnClickListener { Log.d(TAG, "OnNextClicked") } View.OnClickListener { Log.d(TAG, "OnNextClicked") navigationViewModel.nextStep() } val layout: GlifLayout = requireActivity().requireViewById(R.id.setup_wizard_layout) footerBarMixin = layout.getMixin(FooterBarMixin::class.java) Loading Loading
src/com/android/settings/biometrics/fingerprint/FingerprintErrorDialog.java +2 −2 Original line number Diff line number Diff line Loading @@ -30,10 +30,10 @@ import android.hardware.fingerprint.FingerprintManager; import android.os.Bundle; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import com.android.settings.R; import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; /** Fingerprint error dialog, will be shown when an error occurs during fingerprint enrollment. */ Loading Loading @@ -95,7 +95,7 @@ public class FingerprintErrorDialog extends InstrumentedDialogFragment { return dialog; } public static void showErrorDialog(BiometricEnrollBase host, int errMsgId, boolean isSetup) { public static void showErrorDialog(FragmentActivity host, int errMsgId, boolean isSetup) { if (host.isFinishing()) { return; } Loading
src/com/android/settings/biometrics/fingerprint2/ui/enrollment/activity/FingerprintEnrollmentV2Activity.kt +56 −4 Original line number Diff line number Diff line Loading @@ -20,11 +20,13 @@ import android.annotation.ColorInt import android.app.Activity import android.content.Intent import android.content.res.ColorStateList import android.content.res.Configuration import android.graphics.Color import android.hardware.fingerprint.FingerprintManager import android.os.Bundle import android.provider.Settings import android.util.Log import android.view.accessibility.AccessibilityManager import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity Loading @@ -44,17 +46,21 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.Finge import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollEnrollingV2Fragment import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollFindSensorV2Fragment import com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment.FingerprintEnrollIntroV2Fragment import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.AccessibilityViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Confirmation import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Education import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Enrollment import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintGatekeeperViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Finish import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FoldStateViewModel import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Intro import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.LaunchConfirmDeviceCredential import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.OrientationStateViewModel import com.android.settings.password.ChooseLockGeneric import com.android.settings.password.ChooseLockSettingsHelper import com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE Loading @@ -72,6 +78,10 @@ private const val TAG = "FingerprintEnrollmentV2Activity" class FingerprintEnrollmentV2Activity : FragmentActivity() { private lateinit var navigationViewModel: FingerprintEnrollNavigationViewModel private lateinit var gatekeeperViewModel: FingerprintGatekeeperViewModel private lateinit var fingerprintEnrollViewModel: FingerprintEnrollViewModel private lateinit var accessibilityViewModel: AccessibilityViewModel private lateinit var foldStateViewModel: FoldStateViewModel private lateinit var orientationStateViewModel: OrientationStateViewModel private val coroutineDispatcher = Dispatchers.Default /** Result listener for ChooseLock activity flow. */ Loading @@ -94,6 +104,11 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() { super.onAttachedToWindow() } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) foldStateViewModel.onConfigurationChange(newConfig) } @ColorInt private fun getBackgroundColor(): Int { val stateList: ColorStateList? = Loading Loading @@ -178,16 +193,53 @@ class FingerprintEnrollmentV2Activity : FragmentActivity() { ) )[FingerprintEnrollNavigationViewModel::class.java] // Initialize FoldStateViewModel foldStateViewModel = ViewModelProvider(this, FoldStateViewModel.FoldStateViewModelFactory(context))[ FoldStateViewModel::class.java] foldStateViewModel.onConfigurationChange(resources.configuration) // Initialize FingerprintViewModel fingerprintEnrollViewModel = ViewModelProvider( this, FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory(interactor, backgroundDispatcher) FingerprintEnrollViewModel.FingerprintEnrollViewModelFactory( interactor, backgroundDispatcher ) )[FingerprintEnrollViewModel::class.java] // Initialize scroll view model ViewModelProvider(this, FingerprintScrollViewModel.FingerprintScrollViewModelFactory())[ FingerprintScrollViewModel::class.java] // Initialize AccessibilityViewModel accessibilityViewModel = ViewModelProvider( this, AccessibilityViewModel.AccessibilityViewModelFactory( getSystemService(AccessibilityManager::class.java)!! ) )[AccessibilityViewModel::class.java] // Initialize OrientationViewModel orientationStateViewModel = ViewModelProvider(this, OrientationStateViewModel.OrientationViewModelFactory(context))[ OrientationStateViewModel::class.java] // Initialize FingerprintEnrollFindSensorViewModel ViewModelProvider( this, FingerprintEnrollFindSensorViewModel.FingerprintEnrollFindSensorViewModelFactory( navigationViewModel, fingerprintEnrollViewModel, gatekeeperViewModel, accessibilityViewModel, foldStateViewModel, orientationStateViewModel ) )[FingerprintEnrollFindSensorViewModel::class.java] lifecycleScope.launch { navigationViewModel.navigationViewModel.filterNotNull().collect { Log.d(TAG, "navigationStep $it") Loading
src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollEnrollingV2Fragment.kt +2 −1 Original line number Diff line number Diff line Loading @@ -19,10 +19,11 @@ package com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment import android.os.Bundle import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import com.android.settings.R import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel /** A fragment that is responsible for enrolling a users fingerprint. */ class FingerprintEnrollEnrollingV2Fragment : Fragment() { class FingerprintEnrollEnrollingV2Fragment : Fragment(R.layout.fingerprint_enroll_enrolling) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loading
src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollFindSensorV2Fragment.kt +176 −5 Original line number Diff line number Diff line Loading @@ -17,26 +17,197 @@ package com.android.settings.biometrics.fingerprint2.ui.enrollment.fragment import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.Surface import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.airbnb.lottie.LottieAnimationView import com.android.settings.R import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollNavigationViewModel import com.android.settings.biometrics.fingerprint.FingerprintErrorDialog import com.android.settings.biometrics.fingerprint.FingerprintFindSensorAnimation import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollFindSensorViewModel import com.android.systemui.biometrics.shared.model.FingerprintSensorType import com.google.android.setupcompat.template.FooterBarMixin import com.google.android.setupcompat.template.FooterButton import com.google.android.setupdesign.GlifLayout import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch private const val TAG = "FingerprintEnrollFindSensorV2Fragment" /** * A fragment that is used to educate the user about the fingerprint sensor on this device. * * If the sensor is not a udfps sensor, this fragment listens to fingerprint enrollment for * proceeding to the enroll enrolling. * * The main goals of this page are * 1. Inform the user where the fingerprint sensor is on their device * 2. Explain to the user how the enrollment process shown by [FingerprintEnrollEnrollingV2Fragment] * will work. */ class FingerprintEnrollFindSensorV2Fragment : Fragment(R.layout.fingerprint_v2_enroll_find_sensor) { class FingerprintEnrollFindSensorV2Fragment : Fragment() { // This is only for non-udfps or non-sfps sensor. For udfps and sfps, we show lottie. private var animation: FingerprintFindSensorAnimation? = null private var contentLayoutId: Int = -1 private lateinit var viewModel: FingerprintEnrollFindSensorViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) { val navigationViewModel = ViewModelProvider(requireActivity())[FingerprintEnrollNavigationViewModel::class.java] viewModel = ViewModelProvider(requireActivity())[FingerprintEnrollFindSensorViewModel::class.java] lifecycleScope.launch { viewModel.sensorType.collect { contentLayoutId = when (it) { FingerprintSensorType.UDFPS_OPTICAL, FingerprintSensorType.UDFPS_ULTRASONIC -> R.layout.udfps_enroll_find_sensor_layout FingerprintSensorType.POWER_BUTTON -> R.layout.sfps_enroll_find_sensor_layout else -> R.layout.fingerprint_v2_enroll_find_sensor } } } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(contentLayoutId, container, false).also { it -> val view = it!! as GlifLayout // Set up header and description lifecycleScope.launch { viewModel.sensorType.collect { setTexts(it, view) } } // Set up footer bar val footerBarMixin = view.getMixin(FooterBarMixin::class.java) setupSecondaryButton(footerBarMixin) lifecycleScope.launch { viewModel.showPrimaryButton.collect { setupPrimaryButton(footerBarMixin) } } // Set up lottie or animation lifecycleScope.launch { viewModel.showSfpsLottie.collect { (isFolded, rotation) -> setupLottie(view, getSfpsIllustrationLottieAnimation(isFolded, rotation)) } } lifecycleScope.launch { viewModel.showUdfpsLottie.collect { isAccessibilityEnabled -> val lottieAnimation = if (isAccessibilityEnabled) R.raw.udfps_edu_a11y_lottie else R.raw.udfps_edu_lottie setupLottie(view, lottieAnimation) { viewModel.proceedToEnrolling() } } } lifecycleScope.launch { viewModel.showRfpsAnimation.collect { animation = view.findViewById(R.id.fingerprint_sensor_location_animation) animation!!.startAnimation() } } lifecycleScope.launch { viewModel.showErrorDialog.collect { (errMsgId, isSetup) -> // TODO: Covert error dialog kotlin as well FingerprintErrorDialog.showErrorDialog(requireActivity(), errMsgId, isSetup) } } } } override fun onDestroy() { animation?.stopAnimation() super.onDestroy() } private fun setupSecondaryButton(footerBarMixin: FooterBarMixin) { footerBarMixin.secondaryButton = FooterButton.Builder(requireActivity()) .setText(R.string.security_settings_fingerprint_enroll_enrolling_skip) .setListener { run { // TODO: Show the dialog for suw Log.d(TAG, "onSkipClicked") // TODO: Finish activity in the root activity instead. requireActivity().finish() } } .setButtonType(FooterButton.ButtonType.SKIP) .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Secondary) .build() } private fun setupPrimaryButton(footerBarMixin: FooterBarMixin) { footerBarMixin.primaryButton = FooterButton.Builder(requireActivity()) .setText(R.string.security_settings_udfps_enroll_find_sensor_start_button) .setListener { run { Log.d(TAG, "onStartButtonClick") viewModel.proceedToEnrolling() } } .setButtonType(FooterButton.ButtonType.NEXT) .setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary) .build() } private fun setupLottie( view: View, lottieAnimation: Int, lottieClickListener: View.OnClickListener? = null ) { val illustrationLottie: LottieAnimationView? = view.findViewById(R.id.illustration_lottie) illustrationLottie?.setAnimation(lottieAnimation) illustrationLottie?.playAnimation() illustrationLottie?.setOnClickListener(lottieClickListener) illustrationLottie?.visibility = View.VISIBLE } private fun setTexts(sensorType: FingerprintSensorType, view: GlifLayout) { when (sensorType) { FingerprintSensorType.UDFPS_OPTICAL, FingerprintSensorType.UDFPS_ULTRASONIC -> { view.setHeaderText(R.string.security_settings_udfps_enroll_find_sensor_title) view.setDescriptionText(R.string.security_settings_udfps_enroll_find_sensor_message) } FingerprintSensorType.POWER_BUTTON -> { view.setHeaderText(R.string.security_settings_sfps_enroll_find_sensor_title) view.setDescriptionText(R.string.security_settings_sfps_enroll_find_sensor_message) } else -> { view.setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title) view.setDescriptionText(R.string.security_settings_fingerprint_enroll_find_sensor_message) } } } private fun getSfpsIllustrationLottieAnimation(isFolded: Boolean, rotation: Int): Int { val animation: Int when (rotation) { Surface.ROTATION_90 -> animation = (if (isFolded) R.raw.fingerprint_edu_lottie_folded_top_left else R.raw.fingerprint_edu_lottie_portrait_top_left) Surface.ROTATION_180 -> animation = (if (isFolded) R.raw.fingerprint_edu_lottie_folded_bottom_left else R.raw.fingerprint_edu_lottie_landscape_bottom_left) Surface.ROTATION_270 -> animation = (if (isFolded) R.raw.fingerprint_edu_lottie_folded_bottom_right else R.raw.fingerprint_edu_lottie_portrait_bottom_right) else -> animation = (if (isFolded) R.raw.fingerprint_edu_lottie_folded_top_right else R.raw.fingerprint_edu_lottie_landscape_top_right) } return animation } }
src/com/android/settings/biometrics/fingerprint2/ui/enrollment/fragment/FingerprintEnrollIntroV2Fragment.kt +4 −1 Original line number Diff line number Diff line Loading @@ -180,7 +180,10 @@ class FingerprintEnrollIntroV2Fragment : Fragment(R.layout.fingerprint_v2_enroll scrollView.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES // Next button responsible for starting the next fragment. val onNextButtonClick: View.OnClickListener = View.OnClickListener { Log.d(TAG, "OnNextClicked") } View.OnClickListener { Log.d(TAG, "OnNextClicked") navigationViewModel.nextStep() } val layout: GlifLayout = requireActivity().requireViewById(R.id.setup_wizard_layout) footerBarMixin = layout.getMixin(FooterBarMixin::class.java) Loading