1 /*
2  * Copyright (C) 2024 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 package com.android.settings.biometrics.fingerprint2.data.repository
18 
19 import android.hardware.biometrics.ComponentInfoInternal
20 import android.hardware.biometrics.SensorLocationInternal
21 import android.hardware.biometrics.SensorProperties
22 import android.hardware.fingerprint.FingerprintManager
23 import android.hardware.fingerprint.FingerprintSensorProperties
24 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
25 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
26 import com.android.systemui.biometrics.shared.model.FingerprintSensor
27 import com.android.systemui.biometrics.shared.model.toFingerprintSensor
28 import kotlinx.coroutines.CoroutineDispatcher
29 import kotlinx.coroutines.CoroutineScope
30 import kotlinx.coroutines.channels.awaitClose
31 import kotlinx.coroutines.flow.Flow
32 import kotlinx.coroutines.flow.SharingStarted
33 import kotlinx.coroutines.flow.callbackFlow
34 import kotlinx.coroutines.flow.stateIn
35 import kotlinx.coroutines.flow.transform
36 import kotlinx.coroutines.withContext
37 
38 /**
39  * Provides the [FingerprintSensor]
40  *
41  * TODO(b/313493336): Move this to systemui
42  */
43 interface FingerprintSensorRepository {
44   /** Get the [FingerprintSensor] */
45   val fingerprintSensor: Flow<FingerprintSensor>
46 }
47 
48 class FingerprintSensorRepositoryImpl(
49   fingerprintManager: FingerprintManager?,
50   backgroundDispatcher: CoroutineDispatcher,
51   activityScope: CoroutineScope,
52 ) : FingerprintSensorRepository {
53 
54   private val fingerprintPropsInternal: Flow<FingerprintSensorPropertiesInternal> =
<lambda>null55     callbackFlow {
56         val callback =
57           object : IFingerprintAuthenticatorsRegisteredCallback.Stub() {
58             override fun onAllAuthenticatorsRegistered(
59               sensors: List<FingerprintSensorPropertiesInternal>
60             ) {
61               if (sensors.isEmpty()) {
62                 trySend(DEFAULT_PROPS)
63               } else {
64                 trySend(sensors[0])
65               }
66             }
67           }
68         withContext(backgroundDispatcher) {
69           fingerprintManager?.addAuthenticatorsRegisteredCallback(callback)
70         }
71         awaitClose {}
72       }
73       .stateIn(activityScope, started = SharingStarted.Eagerly, initialValue = DEFAULT_PROPS)
74 
75   override val fingerprintSensor: Flow<FingerprintSensor> =
<lambda>null76     fingerprintPropsInternal.transform { emit(it.toFingerprintSensor()) }
77 
78   companion object {
79 
80     private val DEFAULT_PROPS =
81       FingerprintSensorPropertiesInternal(
82         -1 /* sensorId */,
83         SensorProperties.STRENGTH_CONVENIENCE,
84         0 /* maxEnrollmentsPerUser */,
85         listOf<ComponentInfoInternal>(),
86         FingerprintSensorProperties.TYPE_UNKNOWN,
87         false /* halControlsIllumination */,
88         true /* resetLockoutRequiresHardwareAuthToken */,
89         listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
90       )
91   }
92 }
93