Merge "Add BiometricMessageInteractor for fingerprint msgs" into udc-qpr-dev
This commit is contained in:
@@ -28,7 +28,7 @@ import com.android.systemui.dagger.SysUISingleton
|
|||||||
import com.android.systemui.dagger.qualifiers.Application
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.FailedFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.FingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.FingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
|
||||||
@@ -214,7 +214,7 @@ constructor(
|
|||||||
) {
|
) {
|
||||||
sendUpdateIfFingerprint(
|
sendUpdateIfFingerprint(
|
||||||
biometricSourceType,
|
biometricSourceType,
|
||||||
FailedFingerprintAuthenticationStatus,
|
FailFingerprintAuthenticationStatus,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* 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.systemui.keyguard.domain.interactor
|
||||||
|
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.hardware.biometrics.BiometricSourceType
|
||||||
|
import android.hardware.biometrics.BiometricSourceType.FINGERPRINT
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED
|
||||||
|
import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
|
||||||
|
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
|
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
|
||||||
|
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
|
||||||
|
import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
|
||||||
|
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
|
||||||
|
import com.android.systemui.keyguard.util.IndicationHelper
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.filterNot
|
||||||
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BiometricMessage business logic. Filters biometric error/acquired/fail/success events for
|
||||||
|
* authentication events that should never surface a message to the user at the current device
|
||||||
|
* state.
|
||||||
|
*/
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
@SysUISingleton
|
||||||
|
class BiometricMessageInteractor
|
||||||
|
@Inject
|
||||||
|
constructor(
|
||||||
|
@Main private val resources: Resources,
|
||||||
|
private val fingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
|
||||||
|
private val fingerprintPropertyRepository: FingerprintPropertyRepository,
|
||||||
|
private val indicationHelper: IndicationHelper,
|
||||||
|
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
|
||||||
|
) {
|
||||||
|
val fingerprintErrorMessage: Flow<BiometricMessage> =
|
||||||
|
fingerprintAuthRepository.authenticationStatus
|
||||||
|
.filter {
|
||||||
|
it is ErrorFingerprintAuthenticationStatus &&
|
||||||
|
!indicationHelper.shouldSuppressErrorMsg(FINGERPRINT, it.msgId)
|
||||||
|
}
|
||||||
|
.map {
|
||||||
|
val errorStatus = it as ErrorFingerprintAuthenticationStatus
|
||||||
|
BiometricMessage(
|
||||||
|
FINGERPRINT,
|
||||||
|
BiometricMessageType.ERROR,
|
||||||
|
errorStatus.msgId,
|
||||||
|
errorStatus.msg,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val fingerprintHelpMessage: Flow<BiometricMessage> =
|
||||||
|
fingerprintAuthRepository.authenticationStatus
|
||||||
|
.filter { it is HelpFingerprintAuthenticationStatus }
|
||||||
|
.filterNot { isPrimaryAuthRequired() }
|
||||||
|
.map {
|
||||||
|
val helpStatus = it as HelpFingerprintAuthenticationStatus
|
||||||
|
BiometricMessage(
|
||||||
|
FINGERPRINT,
|
||||||
|
BiometricMessageType.HELP,
|
||||||
|
helpStatus.msgId,
|
||||||
|
helpStatus.msg,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val fingerprintFailMessage: Flow<BiometricMessage> =
|
||||||
|
isUdfps().flatMapLatest { isUdfps ->
|
||||||
|
fingerprintAuthRepository.authenticationStatus
|
||||||
|
.filter { it is FailFingerprintAuthenticationStatus }
|
||||||
|
.filterNot { isPrimaryAuthRequired() }
|
||||||
|
.map {
|
||||||
|
BiometricMessage(
|
||||||
|
FINGERPRINT,
|
||||||
|
BiometricMessageType.FAIL,
|
||||||
|
BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
|
||||||
|
if (isUdfps) {
|
||||||
|
resources.getString(
|
||||||
|
com.android.internal.R.string.fingerprint_udfps_error_not_match
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
resources.getString(
|
||||||
|
com.android.internal.R.string.fingerprint_error_not_match
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isUdfps() =
|
||||||
|
fingerprintPropertyRepository.sensorType.map {
|
||||||
|
it == FingerprintSensorType.UDFPS_OPTICAL ||
|
||||||
|
it == FingerprintSensorType.UDFPS_ULTRASONIC
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isPrimaryAuthRequired(): Boolean {
|
||||||
|
// Only checking if unlocking with Biometric is allowed (no matter strong or non-strong
|
||||||
|
// as long as primary auth, i.e. PIN/pattern/password, is required), so it's ok to
|
||||||
|
// pass true for isStrongBiometric to isUnlockingWithBiometricAllowed() to bypass the
|
||||||
|
// check of whether non-strong biometric is allowed since strong biometrics can still be
|
||||||
|
// used.
|
||||||
|
return !keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class BiometricMessage(
|
||||||
|
val source: BiometricSourceType,
|
||||||
|
val type: BiometricMessageType,
|
||||||
|
val id: Int,
|
||||||
|
val message: String?,
|
||||||
|
)
|
||||||
|
|
||||||
|
enum class BiometricMessageType {
|
||||||
|
HELP,
|
||||||
|
ERROR,
|
||||||
|
FAIL,
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ data class AcquiredFingerprintAuthenticationStatus(val acquiredInfo: Int) :
|
|||||||
FingerprintAuthenticationStatus()
|
FingerprintAuthenticationStatus()
|
||||||
|
|
||||||
/** Fingerprint authentication failed message. */
|
/** Fingerprint authentication failed message. */
|
||||||
object FailedFingerprintAuthenticationStatus : FingerprintAuthenticationStatus()
|
object FailFingerprintAuthenticationStatus : FingerprintAuthenticationStatus()
|
||||||
|
|
||||||
/** Fingerprint authentication error message */
|
/** Fingerprint authentication error message */
|
||||||
data class ErrorFingerprintAuthenticationStatus(
|
data class ErrorFingerprintAuthenticationStatus(
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import com.android.systemui.biometrics.AuthController
|
|||||||
import com.android.systemui.coroutines.collectLastValue
|
import com.android.systemui.coroutines.collectLastValue
|
||||||
import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.FailedFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
|
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
|
||||||
import com.android.systemui.util.mockito.whenever
|
import com.android.systemui.util.mockito.whenever
|
||||||
@@ -210,7 +210,7 @@ class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
assertThat(authenticationStatus)
|
assertThat(authenticationStatus)
|
||||||
.isInstanceOf(FailedFingerprintAuthenticationStatus::class.java)
|
.isInstanceOf(FailFingerprintAuthenticationStatus::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
* 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.systemui.keyguard.domain.interactor
|
||||||
|
|
||||||
|
import android.hardware.biometrics.BiometricSourceType.FINGERPRINT
|
||||||
|
import android.hardware.fingerprint.FingerprintManager
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor
|
||||||
|
import com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
|
||||||
|
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||||
|
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||||
|
import com.android.systemui.coroutines.collectLastValue
|
||||||
|
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
|
||||||
|
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
|
||||||
|
import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
|
||||||
|
import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
|
||||||
|
import com.android.systemui.keyguard.util.IndicationHelper
|
||||||
|
import com.android.systemui.util.mockito.whenever
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.TestScope
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.ArgumentMatchers.anyBoolean
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class BiometricMessageInteractorTest : SysuiTestCase() {
|
||||||
|
|
||||||
|
private lateinit var underTest: BiometricMessageInteractor
|
||||||
|
private lateinit var testScope: TestScope
|
||||||
|
private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository
|
||||||
|
private lateinit var fingerprintAuthRepository: FakeDeviceEntryFingerprintAuthRepository
|
||||||
|
|
||||||
|
@Mock private lateinit var indicationHelper: IndicationHelper
|
||||||
|
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
testScope = TestScope()
|
||||||
|
fingerprintPropertyRepository = FakeFingerprintPropertyRepository()
|
||||||
|
fingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository()
|
||||||
|
underTest =
|
||||||
|
BiometricMessageInteractor(
|
||||||
|
mContext.resources,
|
||||||
|
fingerprintAuthRepository,
|
||||||
|
fingerprintPropertyRepository,
|
||||||
|
indicationHelper,
|
||||||
|
keyguardUpdateMonitor,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fingerprintErrorMessage() =
|
||||||
|
testScope.runTest {
|
||||||
|
val fingerprintErrorMessage by collectLastValue(underTest.fingerprintErrorMessage)
|
||||||
|
|
||||||
|
// GIVEN FINGERPRINT_ERROR_HW_UNAVAILABLE should NOT be suppressed
|
||||||
|
whenever(
|
||||||
|
indicationHelper.shouldSuppressErrorMsg(
|
||||||
|
FINGERPRINT,
|
||||||
|
FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.thenReturn(false)
|
||||||
|
|
||||||
|
// WHEN authentication status error is FINGERPRINT_ERROR_HW_UNAVAILABLE
|
||||||
|
fingerprintAuthRepository.setAuthenticationStatus(
|
||||||
|
ErrorFingerprintAuthenticationStatus(
|
||||||
|
msgId = FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
|
||||||
|
msg = "test"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN fingerprintErrorMessage is updated
|
||||||
|
assertThat(fingerprintErrorMessage?.source).isEqualTo(FINGERPRINT)
|
||||||
|
assertThat(fingerprintErrorMessage?.type).isEqualTo(BiometricMessageType.ERROR)
|
||||||
|
assertThat(fingerprintErrorMessage?.id)
|
||||||
|
.isEqualTo(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE)
|
||||||
|
assertThat(fingerprintErrorMessage?.message).isEqualTo("test")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fingerprintErrorMessage_suppressedError() =
|
||||||
|
testScope.runTest {
|
||||||
|
val fingerprintErrorMessage by collectLastValue(underTest.fingerprintErrorMessage)
|
||||||
|
|
||||||
|
// GIVEN FINGERPRINT_ERROR_HW_UNAVAILABLE should be suppressed
|
||||||
|
whenever(
|
||||||
|
indicationHelper.shouldSuppressErrorMsg(
|
||||||
|
FINGERPRINT,
|
||||||
|
FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.thenReturn(true)
|
||||||
|
|
||||||
|
// WHEN authentication status error is FINGERPRINT_ERROR_HW_UNAVAILABLE
|
||||||
|
fingerprintAuthRepository.setAuthenticationStatus(
|
||||||
|
ErrorFingerprintAuthenticationStatus(
|
||||||
|
msgId = FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
|
||||||
|
msg = "test"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN fingerprintErrorMessage isn't update - it's still null
|
||||||
|
assertThat(fingerprintErrorMessage).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fingerprintHelpMessage() =
|
||||||
|
testScope.runTest {
|
||||||
|
val fingerprintHelpMessage by collectLastValue(underTest.fingerprintHelpMessage)
|
||||||
|
|
||||||
|
// GIVEN primary auth is NOT required
|
||||||
|
whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
|
||||||
|
.thenReturn(true)
|
||||||
|
|
||||||
|
// WHEN authentication status help is FINGERPRINT_ACQUIRED_IMAGER_DIRTY
|
||||||
|
fingerprintAuthRepository.setAuthenticationStatus(
|
||||||
|
HelpFingerprintAuthenticationStatus(
|
||||||
|
msgId = FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY,
|
||||||
|
msg = "test"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN fingerprintHelpMessage is updated
|
||||||
|
assertThat(fingerprintHelpMessage?.source).isEqualTo(FINGERPRINT)
|
||||||
|
assertThat(fingerprintHelpMessage?.type).isEqualTo(BiometricMessageType.HELP)
|
||||||
|
assertThat(fingerprintHelpMessage?.id)
|
||||||
|
.isEqualTo(FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY)
|
||||||
|
assertThat(fingerprintHelpMessage?.message).isEqualTo("test")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fingerprintHelpMessage_primaryAuthRequired() =
|
||||||
|
testScope.runTest {
|
||||||
|
val fingerprintHelpMessage by collectLastValue(underTest.fingerprintHelpMessage)
|
||||||
|
|
||||||
|
// GIVEN primary auth is required
|
||||||
|
whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
|
||||||
|
.thenReturn(false)
|
||||||
|
|
||||||
|
// WHEN authentication status help is FINGERPRINT_ACQUIRED_IMAGER_DIRTY
|
||||||
|
fingerprintAuthRepository.setAuthenticationStatus(
|
||||||
|
HelpFingerprintAuthenticationStatus(
|
||||||
|
msgId = FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY,
|
||||||
|
msg = "test"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN fingerprintHelpMessage isn't update - it's still null
|
||||||
|
assertThat(fingerprintHelpMessage).isNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fingerprintFailMessage_nonUdfps() =
|
||||||
|
testScope.runTest {
|
||||||
|
val fingerprintFailMessage by collectLastValue(underTest.fingerprintFailMessage)
|
||||||
|
|
||||||
|
// GIVEN primary auth is NOT required
|
||||||
|
whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
|
||||||
|
.thenReturn(true)
|
||||||
|
|
||||||
|
// GIVEN rear fingerprint (not UDFPS)
|
||||||
|
fingerprintPropertyRepository.setProperties(
|
||||||
|
0,
|
||||||
|
SensorStrength.STRONG,
|
||||||
|
FingerprintSensorType.REAR,
|
||||||
|
mapOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN authentication status fail
|
||||||
|
fingerprintAuthRepository.setAuthenticationStatus(FailFingerprintAuthenticationStatus)
|
||||||
|
|
||||||
|
// THEN fingerprintFailMessage is updated
|
||||||
|
assertThat(fingerprintFailMessage?.source).isEqualTo(FINGERPRINT)
|
||||||
|
assertThat(fingerprintFailMessage?.type).isEqualTo(BiometricMessageType.FAIL)
|
||||||
|
assertThat(fingerprintFailMessage?.id)
|
||||||
|
.isEqualTo(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED)
|
||||||
|
assertThat(fingerprintFailMessage?.message)
|
||||||
|
.isEqualTo(
|
||||||
|
mContext.resources.getString(
|
||||||
|
com.android.internal.R.string.fingerprint_error_not_match
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fingerprintFailMessage_udfps() =
|
||||||
|
testScope.runTest {
|
||||||
|
val fingerprintFailMessage by collectLastValue(underTest.fingerprintFailMessage)
|
||||||
|
|
||||||
|
// GIVEN primary auth is NOT required
|
||||||
|
whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
|
||||||
|
.thenReturn(true)
|
||||||
|
|
||||||
|
// GIVEN UDFPS
|
||||||
|
fingerprintPropertyRepository.setProperties(
|
||||||
|
0,
|
||||||
|
SensorStrength.STRONG,
|
||||||
|
FingerprintSensorType.UDFPS_OPTICAL,
|
||||||
|
mapOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN authentication status fail
|
||||||
|
fingerprintAuthRepository.setAuthenticationStatus(FailFingerprintAuthenticationStatus)
|
||||||
|
|
||||||
|
// THEN fingerprintFailMessage is updated to udfps message
|
||||||
|
assertThat(fingerprintFailMessage?.source).isEqualTo(FINGERPRINT)
|
||||||
|
assertThat(fingerprintFailMessage?.type).isEqualTo(BiometricMessageType.FAIL)
|
||||||
|
assertThat(fingerprintFailMessage?.id)
|
||||||
|
.isEqualTo(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED)
|
||||||
|
assertThat(fingerprintFailMessage?.message)
|
||||||
|
.isEqualTo(
|
||||||
|
mContext.resources.getString(
|
||||||
|
com.android.internal.R.string.fingerprint_udfps_error_not_match
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fingerprintFailedMessage_primaryAuthRequired() =
|
||||||
|
testScope.runTest {
|
||||||
|
val fingerprintFailedMessage by collectLastValue(underTest.fingerprintFailMessage)
|
||||||
|
|
||||||
|
// GIVEN primary auth is required
|
||||||
|
whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
|
||||||
|
.thenReturn(false)
|
||||||
|
|
||||||
|
// WHEN authentication status fail
|
||||||
|
fingerprintAuthRepository.setAuthenticationStatus(FailFingerprintAuthenticationStatus)
|
||||||
|
|
||||||
|
// THEN fingerprintFailedMessage isn't update - it's still null
|
||||||
|
assertThat(fingerprintFailedMessage).isNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user