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

Commit 15a07814 authored by Alexander Hendrich's avatar Alexander Hendrich Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Fix lost focus on PIN input" into main

parents c9bf76c9 da0859af
Loading
Loading
Loading
Loading
+55 −24
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.view.KeyEvent.KEYCODE_0
import android.view.KeyEvent.KEYCODE_4
import android.view.KeyEvent.KEYCODE_A
import android.view.KeyEvent.KEYCODE_DEL
import android.view.KeyEvent.KEYCODE_ENTER
import android.view.KeyEvent.KEYCODE_NUMPAD_0
import androidx.compose.ui.input.key.KeyEventType
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -46,8 +47,6 @@ import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.testKosmos
import com.google.android.msdl.data.model.MSDLToken
import com.google.common.truth.Truth.assertThat
import kotlin.random.Random
import kotlin.random.nextInt
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
import org.junit.Before
@@ -444,37 +443,64 @@ class PinBouncerViewModelTest : SysuiTestCase() {
        kosmos.runTest {
            val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
            lockDeviceAndOpenPinBouncer()
            val random = Random(System.currentTimeMillis())
            // Generate a random 4 digit PIN
            val expectedPin =
                with(random) { arrayOf(nextInt(0..9), nextInt(0..9), nextInt(0..9), nextInt(0..9)) }
            val expectedPin = FakeAuthenticationRepository.WRONG_PIN.take(4).toTypedArray()

            // Enter the PIN using NUM pad and normal number keyboard events
            underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_0 + expectedPin[0])
            underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_0 + expectedPin[0])
            pressKey(KEYCODE_0 + expectedPin[0])
            pressKey(KEYCODE_NUMPAD_0 + expectedPin[1])
            pressKey(KEYCODE_0 + expectedPin[2])

            underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_NUMPAD_0 + expectedPin[1])
            underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_NUMPAD_0 + expectedPin[1])
            // Enter an additional digit in between and delete it
            pressKey(KEYCODE_4)
            pressKey(KEYCODE_DEL)

            underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_0 + expectedPin[2])
            underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_0 + expectedPin[2])
            // Try entering a non digit character, this should be ignored.
            pressKey(KEYCODE_A)

            // Enter an additional digit in between and delete it
            underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_4)
            underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_4)
            pressKey(KEYCODE_NUMPAD_0 + expectedPin[3])

            // Delete that additional digit
            underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_DEL)
            underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_DEL)
            assertThat(pin).containsExactly(*expectedPin).inOrder()
        }

            // Try entering a non digit character, this should be ignored.
            underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_A)
            underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_A)
    @Test
    fun onKeyboardInput_submitOnEnter_wrongPin() =
        kosmos.runTest {
            val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
            val authResult by collectLastValue(authenticationInteractor.onAuthenticationResult)
            fakeAuthenticationRepository.setAutoConfirmFeatureEnabled(false)
            lockDeviceAndOpenPinBouncer()

            val wrongPin = FakeAuthenticationRepository.WRONG_PIN.toTypedArray()

            wrongPin.forEach { pressKey(KEYCODE_0 + it) }

            assertThat(pin).containsExactly(*wrongPin).inOrder()

            assertThat(underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_ENTER)).isTrue()
            assertThat(underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_ENTER)).isTrue()

            assertThat(authResult).isFalse()
            assertThat(pin).isEmpty()
        }

    @Test
    fun onKeyboardInput_submitOnEnter_correctPin() =
        kosmos.runTest {
            val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
            val authResult by collectLastValue(authenticationInteractor.onAuthenticationResult)
            fakeAuthenticationRepository.setAutoConfirmFeatureEnabled(false)
            lockDeviceAndOpenPinBouncer()

            val correctPin = FakeAuthenticationRepository.DEFAULT_PIN.toTypedArray()

            correctPin.forEach { pressKey(KEYCODE_0 + it) }

            underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_NUMPAD_0 + expectedPin[3])
            underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_NUMPAD_0 + expectedPin[3])
            assertThat(pin).containsExactly(*correctPin).inOrder()

            assertThat(pin).containsExactly(*expectedPin)
            assertThat(underTest.onKeyEvent(KeyEventType.KeyDown, KEYCODE_ENTER)).isTrue()
            assertThat(underTest.onKeyEvent(KeyEventType.KeyUp, KEYCODE_ENTER)).isTrue()

            assertThat(authResult).isTrue()
        }

    @Test
@@ -527,6 +553,11 @@ class PinBouncerViewModelTest : SysuiTestCase() {
        showBouncer()
    }

    private fun pressKey(keyCode: Int) {
        underTest.onKeyEvent(KeyEventType.KeyDown, keyCode)
        underTest.onKeyEvent(KeyEventType.KeyUp, keyCode)
    }

    companion object {
        private const val ENTER_YOUR_PIN = "Enter your pin"
        private const val WRONG_PIN = "Wrong pin"
+20 −26
Original line number Diff line number Diff line
@@ -248,17 +248,16 @@ constructor(
     * @return `true` when the [KeyEvent] was consumed as user input on bouncer; `false` otherwise.
     */
    override fun onKeyEvent(type: KeyEventType, keyCode: Int): Boolean {
        return when (type) {
            KeyEventType.KeyUp -> {
        if (isConfirmKey(keyCode)) {
            if (type == KeyEventType.KeyUp) {
                onAuthenticateButtonClicked()
                    true
                } else {
                    false
            }
            return true
        }
            KeyEventType.KeyDown -> {
                when (keyCode) {

        if (type != KeyEventType.KeyDown) return false

        return when (keyCode) {
            KEYCODE_DEL -> {
                onBackspaceButtonClicked()
                true
@@ -271,11 +270,6 @@ constructor(
                onPinButtonClicked(keyCode - KEYCODE_NUMPAD_0)
                true
            }
                    else -> {
                        false
                    }
                }
            }
            else -> false
        }
    }
+1 −0
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ class FakeAuthenticationRepository(private val currentTime: () -> Long) : Authen
        const val LOCKOUT_DURATION_MS = LOCKOUT_DURATION_SECONDS * 1000
        const val HINTING_PIN_LENGTH = 6
        val DEFAULT_PIN = buildList { repeat(HINTING_PIN_LENGTH) { add(it + 1) } }
        val WRONG_PIN = buildList { repeat(HINTING_PIN_LENGTH) { add(9 - it) } }

        private fun AuthenticationMethodModel.toSecurityMode(): SecurityMode {
            return when (this) {