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

Commit d459a367 authored by Beverly's avatar Beverly
Browse files

Don't show lockout messages over occluding apps

When fingerprint lockout occurs, the bouncer will show immediately,
so we filter out the fingerprint lockout messages from showing
over occluding apps so that we don't flicker the chipbar message.

Test: atest OccludingAppDeviceEntryInteractorTest
Fixes: 292545014
Change-Id: I229ce6dd55ff584a4579ee212b4dbad818ae67b3
parent b7d2d3e4
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.domain.interactor
import android.content.res.Resources
import android.hardware.biometrics.BiometricSourceType
import android.hardware.biometrics.BiometricSourceType.FINGERPRINT
import android.hardware.fingerprint.FingerprintManager
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED
import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
@@ -129,7 +130,14 @@ data class BiometricMessage(
    val type: BiometricMessageType,
    val id: Int,
    val message: String?,
)
) {
    fun isFingerprintLockoutMessage(): Boolean {
        return source == FINGERPRINT &&
            type == BiometricMessageType.ERROR &&
            (id == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT ||
                id == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT)
    }
}

enum class BiometricMessageType {
    HELP,
+5 −7
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.systemui.keyguard.domain.interactor

import android.content.Context
import android.content.Intent
import android.hardware.fingerprint.FingerprintManager
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.dagger.SysUISingleton
@@ -35,6 +34,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNot
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@@ -74,15 +74,13 @@ constructor(
    private val fingerprintLockoutEvents: Flow<Unit> =
        fingerprintAuthRepository.authenticationStatus
            .ifKeyguardOccludedByApp()
            .filter {
                it is ErrorFingerprintAuthenticationStatus &&
                    (it.msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT ||
                        it.msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT)
            }
            .filter { it is ErrorFingerprintAuthenticationStatus && it.isLockoutMessage() }
            .map {} // maps FingerprintAuthenticationStatus => Unit
    val message: Flow<BiometricMessage?> =
        merge(
                biometricMessageInteractor.fingerprintErrorMessage,
                biometricMessageInteractor.fingerprintErrorMessage.filterNot {
                    it.isFingerprintLockoutMessage()
                },
                biometricMessageInteractor.fingerprintFailMessage,
                biometricMessageInteractor.fingerprintHelpMessage,
            )
+7 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.keyguard.shared.model

import android.hardware.fingerprint.FingerprintManager
import android.os.SystemClock.elapsedRealtime

/**
@@ -49,4 +50,9 @@ data class ErrorFingerprintAuthenticationStatus(
    val msg: String? = null,
    // present to break equality check if the same error occurs repeatedly.
    val createdAt: Long = elapsedRealtime(),
) : FingerprintAuthenticationStatus()
) : FingerprintAuthenticationStatus() {
    fun isLockoutMessage(): Boolean {
        return msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT ||
            msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT
    }
}
+30 −2
Original line number Diff line number Diff line
@@ -233,12 +233,12 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() {
            // ERROR message
            fingerprintAuthRepository.setAuthenticationStatus(
                ErrorFingerprintAuthenticationStatus(
                    FingerprintManager.FINGERPRINT_ERROR_LOCKOUT,
                    FingerprintManager.FINGERPRINT_ERROR_CANCELED,
                    "testError",
                )
            )
            assertThat(message?.source).isEqualTo(BiometricSourceType.FINGERPRINT)
            assertThat(message?.id).isEqualTo(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)
            assertThat(message?.id).isEqualTo(FingerprintManager.FINGERPRINT_ERROR_CANCELED)
            assertThat(message?.message).isEqualTo("testError")
            assertThat(message?.type).isEqualTo(BiometricMessageType.ERROR)

@@ -262,6 +262,34 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() {
            assertThat(message?.type).isEqualTo(BiometricMessageType.FAIL)
        }

    @Test
    fun message_fpError_lockoutFilteredOut() =
        testScope.runTest {
            val message by collectLastValue(underTest.message)

            givenOnOccludingApp(true)
            givenPrimaryAuthRequired(false)
            runCurrent()

            // permanent lockout error message
            fingerprintAuthRepository.setAuthenticationStatus(
                ErrorFingerprintAuthenticationStatus(
                    FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT,
                    "testPermanentLockoutMessageFiltered",
                )
            )
            assertThat(message).isNull()

            // temporary lockout error message
            fingerprintAuthRepository.setAuthenticationStatus(
                ErrorFingerprintAuthenticationStatus(
                    FingerprintManager.FINGERPRINT_ERROR_LOCKOUT,
                    "testLockoutMessageFiltered",
                )
            )
            assertThat(message).isNull()
        }

    private fun givenOnOccludingApp(isOnOccludingApp: Boolean) {
        keyguardRepository.setKeyguardOccluded(isOnOccludingApp)
        keyguardRepository.setKeyguardShowing(isOnOccludingApp)