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

Commit 175c7cef authored by Chandru S's avatar Chandru S Committed by Automerger Merge Worker
Browse files

Merge changes I1a0a4767,I261a3f3e into udc-qpr-dev am: f155938d

parents fc3eb944 f155938d
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.systemui.biometrics.dagger

import com.android.settingslib.udfps.UdfpsUtils
import com.android.systemui.biometrics.data.repository.FacePropertyRepository
import com.android.systemui.biometrics.data.repository.FacePropertyRepositoryImpl
import com.android.systemui.biometrics.data.repository.FaceSettingsRepository
import com.android.systemui.biometrics.data.repository.FaceSettingsRepositoryImpl
import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
@@ -51,6 +53,10 @@ interface BiometricsModule {
    @SysUISingleton
    fun faceSettings(impl: FaceSettingsRepositoryImpl): FaceSettingsRepository

    @Binds
    @SysUISingleton
    fun faceSensors(impl: FacePropertyRepositoryImpl): FacePropertyRepository

    @Binds
    @SysUISingleton
    fun biometricPromptRepository(impl: PromptRepositoryImpl): PromptRepository
+81 −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.biometrics.data.repository

import android.hardware.face.FaceManager
import android.hardware.face.FaceSensorPropertiesInternal
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback
import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.biometrics.shared.model.toSensorStrength
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn

/** A repository for the global state of Face sensor. */
interface FacePropertyRepository {
    /** Face sensor information, null if it is not available. */
    val sensorInfo: Flow<FaceSensorInfo?>
}

/** Describes a biometric sensor */
data class FaceSensorInfo(val id: Int, val strength: SensorStrength)

private const val TAG = "FaceSensorPropertyRepositoryImpl"

@SysUISingleton
class FacePropertyRepositoryImpl
@Inject
constructor(@Application private val applicationScope: CoroutineScope, faceManager: FaceManager?) :
    FacePropertyRepository {

    private val sensorProps: Flow<List<FaceSensorPropertiesInternal>> =
        faceManager?.let {
            ConflatedCallbackFlow.conflatedCallbackFlow {
                    val callback =
                        object : IFaceAuthenticatorsRegisteredCallback.Stub() {
                            override fun onAllAuthenticatorsRegistered(
                                sensors: List<FaceSensorPropertiesInternal>
                            ) {
                                trySendWithFailureLogging(
                                    sensors,
                                    TAG,
                                    "onAllAuthenticatorsRegistered"
                                )
                            }
                        }
                    it.addAuthenticatorsRegisteredCallback(callback)
                    awaitClose {}
                }
                .shareIn(applicationScope, SharingStarted.Eagerly)
        }
            ?: flowOf(emptyList())

    override val sensorInfo: Flow<FaceSensorInfo?> =
        sensorProps
            .map { it.firstOrNull() }
            .map { it?.let { FaceSensorInfo(it.sensorId, it.sensorStrength.toSensorStrength()) } }
}
+2 −10
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.biometrics.shared.model.toSensorStrength
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
@@ -106,7 +107,7 @@ constructor(

    private fun setProperties(prop: FingerprintSensorPropertiesInternal) {
        _sensorId.value = prop.sensorId
        _strength.value = sensorStrengthIntToObject(prop.sensorStrength)
        _strength.value = prop.sensorStrength.toSensorStrength()
        _sensorType.value = sensorTypeIntToObject(prop.sensorType)
        _sensorLocations.value =
            prop.allLocations.associateBy { sensorLocationInternal ->
@@ -119,15 +120,6 @@ constructor(
    }
}

private fun sensorStrengthIntToObject(value: Int): SensorStrength {
    return when (value) {
        0 -> SensorStrength.CONVENIENCE
        1 -> SensorStrength.WEAK
        2 -> SensorStrength.STRONG
        else -> throw IllegalArgumentException("Invalid SensorStrength value: $value")
    }
}

private fun sensorTypeIntToObject(value: Int): FingerprintSensorType {
    return when (value) {
        0 -> FingerprintSensorType.UNKNOWN
+10 −1
Original line number Diff line number Diff line
@@ -18,9 +18,18 @@ package com.android.systemui.biometrics.shared.model

import android.hardware.biometrics.SensorProperties

/** Fingerprint sensor security strength. Represents [SensorProperties.Strength]. */
/** Sensor security strength. Represents [SensorProperties.Strength]. */
enum class SensorStrength {
    CONVENIENCE,
    WEAK,
    STRONG,
}

/** Convert [this] to corresponding [SensorStrength] */
fun Int.toSensorStrength(): SensorStrength =
    when (this) {
        0 -> SensorStrength.CONVENIENCE
        1 -> SensorStrength.WEAK
        2 -> SensorStrength.STRONG
        else -> throw IllegalArgumentException("Invalid SensorStrength value: $this")
    }
+17 −15
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import com.android.internal.logging.UiEventLogger
import com.android.keyguard.FaceAuthUiEvent
import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.biometrics.data.repository.FacePropertyRepository
import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -58,6 +60,7 @@ import java.util.stream.Collectors
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
@@ -68,6 +71,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
@@ -120,6 +124,7 @@ interface DeviceEntryFaceAuthRepository {
    fun cancel()
}

@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class DeviceEntryFaceAuthRepositoryImpl
@Inject
@@ -143,7 +148,8 @@ constructor(
    @FaceDetectTableLog private val faceDetectLog: TableLogBuffer,
    @FaceAuthTableLog private val faceAuthLog: TableLogBuffer,
    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
    private val featureFlags: FeatureFlags,
    featureFlags: FeatureFlags,
    facePropertyRepository: FacePropertyRepository,
    dumpManager: DumpManager,
) : DeviceEntryFaceAuthRepository, Dumpable {
    private var authCancellationSignal: CancellationSignal? = null
@@ -163,6 +169,13 @@ constructor(
    override val detectionStatus: Flow<FaceDetectionStatus>
        get() = _detectionStatus.filterNotNull()

    private val isFaceBiometricsAllowed: Flow<Boolean> =
        facePropertyRepository.sensorInfo.flatMapLatest {
            if (it?.strength == SensorStrength.STRONG)
                biometricSettingsRepository.isStrongBiometricAllowed
            else biometricSettingsRepository.isNonStrongBiometricAllowed
        }

    private val _isLockedOut = MutableStateFlow(false)
    override val isLockedOut: StateFlow<Boolean> = _isLockedOut

@@ -274,10 +287,8 @@ constructor(
                canFaceAuthOrDetectRun(faceDetectLog),
                logAndObserve(isBypassEnabled, "isBypassEnabled", faceDetectLog),
                logAndObserve(
                    biometricSettingsRepository.isNonStrongBiometricAllowed
                        .isFalse()
                        .or(trustRepository.isCurrentUserTrusted),
                    "nonStrongBiometricIsNotAllowedOrCurrentUserIsTrusted",
                    isFaceBiometricsAllowed.isFalse().or(trustRepository.isCurrentUserTrusted),
                    "biometricIsNotAllowedOrCurrentUserIsTrusted",
                    faceDetectLog
                ),
                // We don't want to run face detect if fingerprint can be used to unlock the device
@@ -368,21 +379,12 @@ constructor(
        listOf(
                canFaceAuthOrDetectRun(faceAuthLog),
                logAndObserve(isLockedOut.isFalse(), "isNotInLockOutState", faceAuthLog),
                logAndObserve(
                    deviceEntryFingerprintAuthRepository.isLockedOut.isFalse(),
                    "fpIsNotLockedOut",
                    faceAuthLog
                ),
                logAndObserve(
                    trustRepository.isCurrentUserTrusted.isFalse(),
                    "currentUserIsNotTrusted",
                    faceAuthLog
                ),
                logAndObserve(
                    biometricSettingsRepository.isNonStrongBiometricAllowed,
                    "nonStrongBiometricIsAllowed",
                    faceAuthLog
                ),
                logAndObserve(isFaceBiometricsAllowed, "isFaceBiometricsAllowed", faceAuthLog),
                logAndObserve(isAuthenticated.isFalse(), "faceNotAuthenticated", faceAuthLog),
            )
            .reduce(::and)
Loading