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

Commit b41615f1 authored by Chandru S's avatar Chandru S Committed by Android (Google) Code Review
Browse files

Merge "Make KeyguardFaceAuthManager check all the gating conditions before...

Merge "Make KeyguardFaceAuthManager check all the gating conditions before running face auth" into udc-dev
parents ed1deb22 202d0dc7
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.data.quickaffordance.KeyguardDataQuickAffordanceModule;
import com.android.systemui.keyguard.data.repository.KeyguardFaceAuthModule;
import com.android.systemui.keyguard.data.repository.KeyguardRepositoryModule;
import com.android.systemui.keyguard.domain.interactor.StartKeyguardTransitionModule;
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceModule;
@@ -66,8 +67,6 @@ import java.util.concurrent.Executor;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
import kotlinx.coroutines.CoroutineDispatcher;
import kotlinx.coroutines.CoroutineScope;

/**
 * Dagger Module providing keyguard.
@@ -82,6 +81,7 @@ import kotlinx.coroutines.CoroutineScope;
            KeyguardDataQuickAffordanceModule.class,
            KeyguardQuickAffordanceModule.class,
            KeyguardRepositoryModule.class,
            KeyguardFaceAuthModule.class,
            StartKeyguardTransitionModule.class,
        })
public class KeyguardModule {
+50 −11
Original line number Diff line number Diff line
@@ -87,6 +87,13 @@ interface BiometricSettingsRepository {
     */
    val isStrongBiometricAllowed: StateFlow<Boolean>

    /**
     * Whether the current user is allowed to use a convenience biometric for device entry based on
     * Android Security policies. If false, the user may be able to use strong biometric or primary
     * authentication for device entry.
     */
    val isNonStrongBiometricAllowed: StateFlow<Boolean>

    /** Whether fingerprint feature is enabled for the current user by the DevicePolicy */
    val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean>

@@ -276,6 +283,16 @@ constructor(
            )
        )

    override val isNonStrongBiometricAllowed: StateFlow<Boolean> =
        strongAuthTracker.isNonStrongBiometricAllowed.stateIn(
            scope,
            SharingStarted.Eagerly,
            strongAuthTracker.isBiometricAllowedForUser(
                false,
                userRepository.getSelectedUserInfo().id
            )
        )

    override val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> =
        selectedUserId
            .flatMapLatest { userId ->
@@ -297,40 +314,62 @@ constructor(
private class StrongAuthTracker(private val userRepository: UserRepository, context: Context?) :
    LockPatternUtils.StrongAuthTracker(context) {

    private val _authFlags =
    // Backing field for onStrongAuthRequiredChanged
    private val _strongAuthFlags =
        MutableStateFlow(
            StrongAuthenticationFlags(currentUserId, getStrongAuthForUser(currentUserId))
        )

    // Backing field for onIsNonStrongBiometricAllowedChanged
    private val _nonStrongBiometricAllowed =
        MutableStateFlow(
            Pair(currentUserId, isNonStrongBiometricAllowedAfterIdleTimeout(currentUserId))
        )

    val currentUserAuthFlags: Flow<StrongAuthenticationFlags> =
        userRepository.selectedUserInfo
            .map { it.id }
            .distinctUntilChanged()
            .flatMapLatest { currUserId ->
                _authFlags
                    .filter { it.userId == currUserId }
            .flatMapLatest { userId ->
                _strongAuthFlags
                    .filter { it.userId == userId }
                    .onEach { Log.d(TAG, "currentUser authFlags changed, new value: $it") }
                    .onStart {
                        emit(
                            StrongAuthenticationFlags(
                                currentUserId,
                                getStrongAuthForUser(currentUserId)
                            )
                        )
                        emit(StrongAuthenticationFlags(userId, getStrongAuthForUser(userId)))
                    }
            }

    /** isStrongBiometricAllowed for the current user. */
    val isStrongBiometricAllowed: Flow<Boolean> =
        currentUserAuthFlags.map { isBiometricAllowedForUser(true, it.userId) }

    /** isNonStrongBiometricAllowed for the current user. */
    val isNonStrongBiometricAllowed: Flow<Boolean> =
        userRepository.selectedUserInfo
            .map { it.id }
            .distinctUntilChanged()
            .flatMapLatest { userId ->
                _nonStrongBiometricAllowed
                    .filter { it.first == userId }
                    .map { it.second }
                    .onEach { Log.d(TAG, "isNonStrongBiometricAllowed changed for current user") }
                    .onStart { emit(isNonStrongBiometricAllowedAfterIdleTimeout(userId)) }
            }

    private val currentUserId
        get() = userRepository.getSelectedUserInfo().id

    override fun onStrongAuthRequiredChanged(userId: Int) {
        val newFlags = getStrongAuthForUser(userId)
        _authFlags.value = StrongAuthenticationFlags(userId, newFlags)
        _strongAuthFlags.value = StrongAuthenticationFlags(userId, newFlags)
        Log.d(TAG, "onStrongAuthRequiredChanged for userId: $userId, flag value: $newFlags")
    }

    override fun onIsNonStrongBiometricAllowedChanged(userId: Int) {
        val allowed = isNonStrongBiometricAllowedAfterIdleTimeout(userId)
        _nonStrongBiometricAllowed.value = Pair(userId, allowed)
        Log.d(TAG, "onIsNonStrongBiometricAllowedChanged for userId: $userId, $allowed")
    }
}

private fun DevicePolicyManager.isFaceDisabled(userId: Int): Boolean =
+37 −6
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.keyguard.data.repository

import android.hardware.biometrics.BiometricAuthenticator
import android.hardware.biometrics.BiometricAuthenticator.Modality
import android.hardware.biometrics.BiometricSourceType
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
@@ -33,6 +35,7 @@ import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn

/** Encapsulates state about device entry fingerprint auth mechanism. */
@@ -49,7 +52,7 @@ interface DeviceEntryFingerprintAuthRepository {
    /**
     * Fingerprint sensor type present on the device, null if fingerprint sensor is not available.
     */
    val availableFpSensorType: BiometricType?
    val availableFpSensorType: Flow<BiometricType?>
}

/**
@@ -77,11 +80,39 @@ constructor(
        pw.println("isLockedOut=${isLockedOut.value}")
    }

    override val availableFpSensorType: BiometricType?
        get() =
            if (authController.isUdfpsSupported) BiometricType.UNDER_DISPLAY_FINGERPRINT
    override val availableFpSensorType: Flow<BiometricType?>
        get() {
            return if (authController.areAllFingerprintAuthenticatorsRegistered()) {
                flowOf(getFpSensorType())
            } else {
                conflatedCallbackFlow {
                    val callback =
                        object : AuthController.Callback {
                            override fun onAllAuthenticatorsRegistered(@Modality modality: Int) {
                                if (modality == BiometricAuthenticator.TYPE_FINGERPRINT)
                                    trySendWithFailureLogging(
                                        getFpSensorType(),
                                        TAG,
                                        "onAllAuthenticatorsRegistered, emitting fpSensorType"
                                    )
                            }
                        }
                    authController.addCallback(callback)
                    trySendWithFailureLogging(
                        getFpSensorType(),
                        TAG,
                        "initial value for fpSensorType"
                    )
                    awaitClose { authController.removeCallback(callback) }
                }
            }
        }

    private fun getFpSensorType(): BiometricType? {
        return if (authController.isUdfpsSupported) BiometricType.UNDER_DISPLAY_FINGERPRINT
        else if (authController.isSfpsSupported) BiometricType.SIDE_FINGERPRINT
        else if (authController.isRearFpsSupported) BiometricType.REAR_FINGERPRINT else null
    }

    override val isLockedOut: StateFlow<Boolean> =
        conflatedCallbackFlow {
+269 −75

File changed.

Preview size limit exceeded, changes collapsed.

+28 −0
Original line number Diff line number Diff line
/*
 * 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.data.repository

import dagger.Binds
import dagger.Module

@Module
interface KeyguardFaceAuthModule {
    @Binds fun faceAuthManager(impl: KeyguardFaceAuthManagerImpl): KeyguardFaceAuthManager

    @Binds fun trustRepository(impl: TrustRepositoryImpl): TrustRepository
}
Loading