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

Commit b418bf5c authored by Beverly's avatar Beverly
Browse files

Include the biometricEnabled state in the fingerprintEnabled state

This fixes an issue where the sideFps alternate bouncer was showing
even when biometrics weren't enabled in settings for device entry.

Test: manually disable biometrics for phone unlock in Security
settings, enroll sideFPS and see that tapping on an affordance
on the lockscreen will not show the alternate bouncer
Test: atest BiometricSettingsRepositoryTest
Flag: NONE
Fixes: 309103066

Change-Id: I66e57893fdcffa9d1731fe3c9021e3ce010bbbc2
parent 3129fc5b
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ import kotlinx.coroutines.flow.transformLatest

/**
 * Acts as source of truth for biometric authentication related settings like enrollments, device
 * policy, etc.
 * policy specifically for device entry usage.
 *
 * Abstracts-away data sources and their schemas so the rest of the app doesn't need to worry about
 * upstream changes.
@@ -74,7 +74,8 @@ import kotlinx.coroutines.flow.transformLatest
interface BiometricSettingsRepository {
    /**
     * If the current user can enter the device using fingerprint. This is true if user has enrolled
     * fingerprints and fingerprint auth is not disabled through settings/device policy
     * fingerprints and fingerprint auth is not disabled for device entry through settings and
     * device policy
     */
    val isFingerprintEnrolledAndEnabled: StateFlow<Boolean>

@@ -247,9 +248,11 @@ constructor(
            }
        }

    private val isFaceEnabledByBiometricsManagerForCurrentUser: Flow<Boolean> =
    private val areBiometricsEnabledForCurrentUser: Flow<Boolean> =
        userRepository.selectedUserInfo.flatMapLatest { userInfo ->
            isFaceEnabledByBiometricsManager.map { biometricsEnabledForUser[userInfo.id] ?: false }
            areBiometricsEnabledForDeviceEntryFromUserSetting.map {
                biometricsEnabledForUser[userInfo.id] ?: false
            }
        }

    private val isFaceEnabledByDevicePolicy: Flow<Boolean> =
@@ -263,13 +266,13 @@ constructor(
            .distinctUntilChanged()

    private val isFaceAuthenticationEnabled: Flow<Boolean> =
        combine(isFaceEnabledByBiometricsManagerForCurrentUser, isFaceEnabledByDevicePolicy) {
        combine(areBiometricsEnabledForCurrentUser, isFaceEnabledByDevicePolicy) {
            biometricsManagerSetting,
            devicePolicySetting ->
            biometricsManagerSetting && devicePolicySetting
        }

    private val isFaceEnabledByBiometricsManager: Flow<Pair<Int, Boolean>> =
    private val areBiometricsEnabledForDeviceEntryFromUserSetting: Flow<Pair<Int, Boolean>> =
        conflatedCallbackFlow {
                val callback =
                    object : IBiometricEnabledOnKeyguardCallback.Stub() {
@@ -340,6 +343,7 @@ constructor(

    override val isFingerprintEnrolledAndEnabled: StateFlow<Boolean> =
        isFingerprintEnrolled
            .and(areBiometricsEnabledForCurrentUser)
            .and(isFingerprintEnabledByDevicePolicy)
            .stateIn(scope, SharingStarted.Eagerly, false)

+42 −8
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
    fun fingerprintEnrollmentChange() =
        testScope.runTest {
            createBiometricSettingsRepository()
            biometricsAreEnabledBySettings()
            val fingerprintAllowed = collectLastValue(underTest.isFingerprintEnrolledAndEnabled)
            runCurrent()

@@ -169,12 +170,35 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            assertThat(fingerprintAllowed()).isFalse()
        }

    @Test
    fun fingerprintEnabledStateChange() =
        testScope.runTest {
            createBiometricSettingsRepository()
            biometricsAreEnabledBySettings()
            val fingerprintAllowed = collectLastValue(underTest.isFingerprintEnrolledAndEnabled)
            runCurrent()

            // start state
            whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(true)
            enrollmentChange(UNDER_DISPLAY_FINGERPRINT, PRIMARY_USER_ID, true)
            assertThat(fingerprintAllowed()).isTrue()

            // when biometrics are not enabled by settings
            biometricsAreNotEnabledBySettings()
            assertThat(fingerprintAllowed()).isFalse()

            // when biometrics are enabled by settings
            biometricsAreEnabledBySettings()
            assertThat(fingerprintAllowed()).isTrue()
        }

    @Test
    fun strongBiometricAllowedChange() =
        testScope.runTest {
            fingerprintIsEnrolled()
            doNotDisableKeyguardAuthFeatures()
            createBiometricSettingsRepository()
            biometricsAreEnabledBySettings()

            val strongBiometricAllowed by
                collectLastValue(underTest.isFingerprintAuthCurrentlyAllowed)
@@ -197,7 +221,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            createBiometricSettingsRepository()
            val convenienceFaceAuthAllowed by collectLastValue(underTest.isFaceAuthCurrentlyAllowed)
            doNotDisableKeyguardAuthFeatures()
            faceAuthIsEnabledByBiometricManager()
            biometricsAreEnabledBySettings()

            onStrongAuthChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID)
            onNonStrongAuthChanged(true, PRIMARY_USER_ID)
@@ -238,6 +262,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            faceAuthIsNonStrongBiometric()
            faceAuthIsEnrolled()
            doNotDisableKeyguardAuthFeatures()
            biometricsAreEnabledBySettings()

            val convenienceBiometricAllowed = collectLastValue(underTest.isFaceAuthCurrentlyAllowed)
            runCurrent()
@@ -258,7 +283,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            faceAuthIsEnrolled()
            createBiometricSettingsRepository()
            doNotDisableKeyguardAuthFeatures()
            faceAuthIsEnabledByBiometricManager()
            biometricsAreEnabledBySettings()
            runCurrent()

            val convenienceBiometricAllowed by
@@ -291,6 +316,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
        testScope.runTest {
            fingerprintIsEnrolled(PRIMARY_USER_ID)
            createBiometricSettingsRepository()
            biometricsAreEnabledBySettings()

            val fingerprintEnabledByDevicePolicy =
                collectLastValue(underTest.isFingerprintEnrolledAndEnabled)
@@ -316,7 +342,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            createBiometricSettingsRepository()
            val faceAuthAllowed = collectLastValue(underTest.isFaceAuthEnrolledAndEnabled)

            faceAuthIsEnabledByBiometricManager()
            biometricsAreEnabledBySettings()

            doNotDisableKeyguardAuthFeatures(PRIMARY_USER_ID)

@@ -351,12 +377,18 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            assertThat(faceAuthAllowed()).isTrue()
        }

    private fun faceAuthIsEnabledByBiometricManager(userId: Int = PRIMARY_USER_ID) {
    private fun biometricsAreEnabledBySettings(userId: Int = PRIMARY_USER_ID) {
        verify(biometricManager, atLeastOnce())
            .registerEnabledOnKeyguardCallback(biometricManagerCallback.capture())
        biometricManagerCallback.value.onChanged(true, userId)
    }

    private fun biometricsAreNotEnabledBySettings(userId: Int = PRIMARY_USER_ID) {
        verify(biometricManager, atLeastOnce())
            .registerEnabledOnKeyguardCallback(biometricManagerCallback.capture())
        biometricManagerCallback.value.onChanged(false, userId)
    }

    @Test
    fun faceEnrollmentStatusOfNewUserUponUserSwitch() =
        testScope.runTest {
@@ -427,7 +459,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            faceAuthIsEnrolled()
            createBiometricSettingsRepository()

            faceAuthIsEnabledByBiometricManager()
            biometricsAreEnabledBySettings()
            doNotDisableKeyguardAuthFeatures()
            mobileConnectionsRepository.isAnySimSecure.value = false
            runCurrent()
@@ -454,7 +486,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            deviceIsInPostureThatSupportsFaceAuth()
            doNotDisableKeyguardAuthFeatures()
            faceAuthIsStrongBiometric()
            faceAuthIsEnabledByBiometricManager()
            biometricsAreEnabledBySettings()
            mobileConnectionsRepository.isAnySimSecure.value = false

            onStrongAuthChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID)
@@ -636,7 +668,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            deviceIsInPostureThatSupportsFaceAuth()
            doNotDisableKeyguardAuthFeatures()
            faceAuthIsStrongBiometric()
            faceAuthIsEnabledByBiometricManager()
            biometricsAreEnabledBySettings()

            onStrongAuthChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID)
            onNonStrongAuthChanged(false, PRIMARY_USER_ID)
@@ -660,7 +692,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
            deviceIsInPostureThatSupportsFaceAuth()
            doNotDisableKeyguardAuthFeatures()
            faceAuthIsNonStrongBiometric()
            faceAuthIsEnabledByBiometricManager()
            biometricsAreEnabledBySettings()

            onStrongAuthChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID)
            onNonStrongAuthChanged(false, PRIMARY_USER_ID)
@@ -682,6 +714,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
    fun fpAuthCurrentlyAllowed_dependsOnNonStrongAuthBiometricSetting_ifFpIsNotStrong() =
        testScope.runTest {
            createBiometricSettingsRepository()
            biometricsAreEnabledBySettings()
            val isFingerprintCurrentlyAllowed by
                collectLastValue(underTest.isFingerprintAuthCurrentlyAllowed)

@@ -723,6 +756,7 @@ class BiometricSettingsRepositoryTest : SysuiTestCase() {
    fun fpAuthCurrentlyAllowed_dependsOnStrongAuthBiometricSetting_ifFpIsStrong() =
        testScope.runTest {
            createBiometricSettingsRepository()
            biometricsAreEnabledBySettings()
            val isFingerprintCurrentlyAllowed by
                collectLastValue(underTest.isFingerprintAuthCurrentlyAllowed)