1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 18 package com.android.systemui.biometrics.data.repository 19 20 import android.hardware.face.FaceManager 21 import android.hardware.face.FaceSensorPropertiesInternal 22 import android.hardware.face.IFaceAuthenticatorsRegisteredCallback 23 import com.android.systemui.biometrics.shared.model.SensorStrength 24 import com.android.systemui.biometrics.shared.model.toSensorStrength 25 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging 26 import com.android.systemui.common.coroutine.ConflatedCallbackFlow 27 import com.android.systemui.dagger.SysUISingleton 28 import com.android.systemui.dagger.qualifiers.Application 29 import javax.inject.Inject 30 import kotlinx.coroutines.CoroutineScope 31 import kotlinx.coroutines.channels.awaitClose 32 import kotlinx.coroutines.flow.Flow 33 import kotlinx.coroutines.flow.SharingStarted 34 import kotlinx.coroutines.flow.flowOf 35 import kotlinx.coroutines.flow.map 36 import kotlinx.coroutines.flow.shareIn 37 38 /** A repository for the global state of Face sensor. */ 39 interface FacePropertyRepository { 40 /** Face sensor information, null if it is not available. */ 41 val sensorInfo: Flow<FaceSensorInfo?> 42 } 43 44 /** Describes a biometric sensor */ 45 data class FaceSensorInfo(val id: Int, val strength: SensorStrength) 46 47 private const val TAG = "FaceSensorPropertyRepositoryImpl" 48 49 @SysUISingleton 50 class FacePropertyRepositoryImpl 51 @Inject 52 constructor(@Application private val applicationScope: CoroutineScope, faceManager: FaceManager?) : 53 FacePropertyRepository { 54 55 private val sensorProps: Flow<List<FaceSensorPropertiesInternal>> = 56 faceManager?.let { 57 ConflatedCallbackFlow.conflatedCallbackFlow { 58 val callback = 59 object : IFaceAuthenticatorsRegisteredCallback.Stub() { 60 override fun onAllAuthenticatorsRegistered( 61 sensors: List<FaceSensorPropertiesInternal> 62 ) { 63 trySendWithFailureLogging( 64 sensors, 65 TAG, 66 "onAllAuthenticatorsRegistered" 67 ) 68 } 69 } 70 it.addAuthenticatorsRegisteredCallback(callback) 71 awaitClose {} 72 } 73 .shareIn(applicationScope, SharingStarted.Eagerly) 74 } 75 ?: flowOf(emptyList()) 76 77 override val sensorInfo: Flow<FaceSensorInfo?> = 78 sensorProps 79 .map { it.firstOrNull() } 80 .map { it?.let { FaceSensorInfo(it.sensorId, it.sensorStrength.toSensorStrength()) } } 81 } 82