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

Commit ec4f1ac9 authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "Include the biometricEnabled state in the fingerprintEnabled state" into main

parents 562c24db b418bf5c
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)