Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 913b2cf8 authored by Juan Sebastian Martinez's avatar Juan Sebastian Martinez Committed by Android (Google) Code Review
Browse files

Merge "Ignoring user touch feedback settings for biometric prompt UDFPS authentication." into main

parents ec6ff848 6355af29
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -438,9 +438,20 @@ object BiometricViewBinder {

                // Play haptics
                launch {
                    viewModel.hapticsToPlay.collect { hapticFeedbackConstant ->
                        if (hapticFeedbackConstant != HapticFeedbackConstants.NO_HAPTICS) {
                            vibratorHelper.performHapticFeedback(view, hapticFeedbackConstant)
                    viewModel.hapticsToPlay.collect { haptics ->
                        if (haptics.hapticFeedbackConstant != HapticFeedbackConstants.NO_HAPTICS) {
                            if (haptics.flag != null) {
                                vibratorHelper.performHapticFeedback(
                                    view,
                                    haptics.hapticFeedbackConstant,
                                    haptics.flag,
                                )
                            } else {
                                vibratorHelper.performHapticFeedback(
                                    view,
                                    haptics.hapticFeedbackConstant,
                                )
                            }
                            viewModel.clearHaptics()
                        }
                    }
+24 −6
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

/** ViewModel for BiometricPrompt. */
@@ -144,9 +145,10 @@ constructor(
    private val _forceLargeSize = MutableStateFlow(false)
    private val _forceMediumSize = MutableStateFlow(false)

    private val _hapticsToPlay = MutableStateFlow(HapticFeedbackConstants.NO_HAPTICS)
    private val _hapticsToPlay =
        MutableStateFlow(HapticsToPlay(HapticFeedbackConstants.NO_HAPTICS, /* flag= */ null))

    /** Event fired to the view indicating a [HapticFeedbackConstants] to be played */
    /** Event fired to the view indicating a [HapticsToPlay] */
    val hapticsToPlay = _hapticsToPlay.asStateFlow()

    /** The current position of the prompt */
@@ -686,16 +688,26 @@ constructor(
    }

    private fun vibrateOnSuccess() {
        _hapticsToPlay.value = HapticFeedbackConstants.CONFIRM
        _hapticsToPlay.value =
            HapticsToPlay(
                HapticFeedbackConstants.CONFIRM,
                HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING,
            )
    }

    private fun vibrateOnError() {
        _hapticsToPlay.value = HapticFeedbackConstants.REJECT
        _hapticsToPlay.value =
            HapticsToPlay(
                HapticFeedbackConstants.REJECT,
                HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING,
            )
    }

    /** Clears the [hapticsToPlay] variable by setting it to the NO_HAPTICS default. */
    /** Clears the [hapticsToPlay] variable by setting its constant to the NO_HAPTICS default. */
    fun clearHaptics() {
        _hapticsToPlay.value = HapticFeedbackConstants.NO_HAPTICS
        _hapticsToPlay.update { previous ->
            HapticsToPlay(HapticFeedbackConstants.NO_HAPTICS, previous.flag)
        }
    }

    companion object {
@@ -724,3 +736,9 @@ enum class FingerprintStartMode {
    val isStarted: Boolean
        get() = this == Normal || this == Delayed
}

/**
 * The state of haptic feedback to play. It is composed by a [HapticFeedbackConstants] and a
 * [HapticFeedbackConstants] flag.
 */
data class HapticsToPlay(val hapticFeedbackConstant: Int, val flag: Int?)
+26 −12
Original line number Diff line number Diff line
@@ -241,19 +241,27 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa

            viewModel.showAuthenticated(testCase.authenticatedModality, 1_000L)

            val confirmConstant by collectLastValue(viewModel.hapticsToPlay)
            assertThat(confirmConstant)
            val confirmHaptics by collectLastValue(viewModel.hapticsToPlay)
            assertThat(confirmHaptics?.hapticFeedbackConstant)
                .isEqualTo(
                    if (expectConfirmation) HapticFeedbackConstants.NO_HAPTICS
                    else HapticFeedbackConstants.CONFIRM
                )
            assertThat(confirmHaptics?.flag)
                .isEqualTo(
                    if (expectConfirmation) null
                    else HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING
                )

            if (expectConfirmation) {
                viewModel.confirmAuthenticated()
            }

            val confirmedConstant by collectLastValue(viewModel.hapticsToPlay)
            assertThat(confirmedConstant).isEqualTo(HapticFeedbackConstants.CONFIRM)
            val confirmedHaptics by collectLastValue(viewModel.hapticsToPlay)
            assertThat(confirmedHaptics?.hapticFeedbackConstant)
                .isEqualTo(HapticFeedbackConstants.CONFIRM)
            assertThat(confirmedHaptics?.flag)
                .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
        }

    @Test
@@ -265,16 +273,21 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
            viewModel.confirmAuthenticated()
        }

        val currentConstant by collectLastValue(viewModel.hapticsToPlay)
        assertThat(currentConstant).isEqualTo(HapticFeedbackConstants.CONFIRM)
        val currentHaptics by collectLastValue(viewModel.hapticsToPlay)
        assertThat(currentHaptics?.hapticFeedbackConstant)
            .isEqualTo(HapticFeedbackConstants.CONFIRM)
        assertThat(currentHaptics?.flag)
            .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
    }

    @Test
    fun playErrorHaptic_SetsRejectConstant() = runGenericTest {
        viewModel.showTemporaryError("test", "messageAfterError", false)

        val currentConstant by collectLastValue(viewModel.hapticsToPlay)
        assertThat(currentConstant).isEqualTo(HapticFeedbackConstants.REJECT)
        val currentHaptics by collectLastValue(viewModel.hapticsToPlay)
        assertThat(currentHaptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.REJECT)
        assertThat(currentHaptics?.flag)
            .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
    }

    @Test
@@ -800,8 +813,9 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
            hapticFeedback = true,
        )

        val constant by collectLastValue(viewModel.hapticsToPlay)
        assertThat(constant).isEqualTo(HapticFeedbackConstants.REJECT)
        val haptics by collectLastValue(viewModel.hapticsToPlay)
        assertThat(haptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.REJECT)
        assertThat(haptics?.flag).isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
    }

    @Test
@@ -813,8 +827,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
            hapticFeedback = false,
        )

        val constant by collectLastValue(viewModel.hapticsToPlay)
        assertThat(constant).isEqualTo(HapticFeedbackConstants.NO_HAPTICS)
        val haptics by collectLastValue(viewModel.hapticsToPlay)
        assertThat(haptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.NO_HAPTICS)
    }

    private suspend fun TestScope.showTemporaryErrors(