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 package com.android.systemui.biometrics.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 androidx.test.filters.SmallTest
27 import com.android.systemui.SysuiTestCase
28 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
29 import com.android.systemui.biometrics.shared.model.SensorStrength
30 import com.android.systemui.coroutines.collectLastValue
31 import com.google.common.truth.Truth.assertThat
32 import kotlinx.coroutines.ExperimentalCoroutinesApi
33 import kotlinx.coroutines.test.StandardTestDispatcher
34 import kotlinx.coroutines.test.TestScope
35 import kotlinx.coroutines.test.runCurrent
36 import kotlinx.coroutines.test.runTest
37 import org.junit.Before
38 import org.junit.Rule
39 import org.junit.Test
40 import org.junit.runner.RunWith
41 import org.junit.runners.JUnit4
42 import org.mockito.ArgumentCaptor
43 import org.mockito.Captor
44 import org.mockito.Mock
45 import org.mockito.Mockito.verify
46 import org.mockito.junit.MockitoJUnit
47 
48 @OptIn(ExperimentalCoroutinesApi::class)
49 @SmallTest
50 @RunWith(JUnit4::class)
51 class FingerprintRepositoryImplTest : SysuiTestCase() {
52 
53     @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
54     private lateinit var testScope: TestScope
55 
56     @Mock private lateinit var fingerprintManager: FingerprintManager
57     private lateinit var repository: FingerprintPropertyRepositoryImpl
58 
59     @Captor
60     private lateinit var fingerprintAuthenticatorsCaptor:
61         ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback.Stub>
62 
63     @Before
64     fun setup() {
65         val dispatcher = StandardTestDispatcher()
66         testScope = TestScope(dispatcher)
67         repository =
68             FingerprintPropertyRepositoryImpl(testScope.backgroundScope, fingerprintManager)
69         testScope.runCurrent()
70 
71         verify(fingerprintManager)
72             .addAuthenticatorsRegisteredCallback(fingerprintAuthenticatorsCaptor.capture())
73     }
74 
75     @Test
76     fun initializeProperties() =
77         testScope.runTest {
78             val sensorId by collectLastValue(repository.sensorId)
79             val strength by collectLastValue(repository.strength)
80             val sensorType by collectLastValue(repository.sensorType)
81             val sensorLocations by collectLastValue(repository.sensorLocations)
82 
83             // Assert default properties.
84             assertThat(sensorId).isEqualTo(-1)
85             assertThat(strength).isEqualTo(SensorStrength.CONVENIENCE)
86             assertThat(sensorType).isEqualTo(FingerprintSensorType.UNKNOWN)
87 
88             val fingerprintProps =
89                 listOf(
90                     FingerprintSensorPropertiesInternal(
91                         1 /* sensorId */,
92                         SensorProperties.STRENGTH_STRONG,
93                         5 /* maxEnrollmentsPerUser */,
94                         listOf<ComponentInfoInternal>(
95                             ComponentInfoInternal(
96                                 "sensor" /* componentId */,
97                                 "vendor/model/revision" /* hardwareVersion */,
98                                 "1.01" /* firmwareVersion */,
99                                 "00000001" /* serialNumber */,
100                                 "" /* softwareVersion */
101                             )
102                         ),
103                         FingerprintSensorProperties.TYPE_REAR,
104                         false /* halControlsIllumination */,
105                         true /* resetLockoutRequiresHardwareAuthToken */,
106                         listOf<SensorLocationInternal>(
107                             SensorLocationInternal(
108                                 "" /* displayId */,
109                                 540 /* sensorLocationX */,
110                                 1636 /* sensorLocationY */,
111                                 130 /* sensorRadius */
112                             ),
113                             SensorLocationInternal(
114                                 "display_id_1" /* displayId */,
115                                 100 /* sensorLocationX */,
116                                 300 /* sensorLocationY */,
117                                 20 /* sensorRadius */
118                             )
119                         )
120                     )
121                 )
122 
123             fingerprintAuthenticatorsCaptor.value.onAllAuthenticatorsRegistered(fingerprintProps)
124 
125             assertThat(sensorId).isEqualTo(1)
126             assertThat(strength).isEqualTo(SensorStrength.STRONG)
127             assertThat(sensorType).isEqualTo(FingerprintSensorType.REAR)
128 
129             assertThat(sensorLocations?.size).isEqualTo(2)
130             assertThat(sensorLocations).containsKey("display_id_1")
131             with(sensorLocations?.get("display_id_1")!!) {
132                 assertThat(displayId).isEqualTo("display_id_1")
133                 assertThat(sensorLocationX).isEqualTo(100)
134                 assertThat(sensorLocationY).isEqualTo(300)
135                 assertThat(sensorRadius).isEqualTo(20)
136             }
137             assertThat(sensorLocations).containsKey("")
138             with(sensorLocations?.get("")!!) {
139                 assertThat(displayId).isEqualTo("")
140                 assertThat(sensorLocationX).isEqualTo(540)
141                 assertThat(sensorLocationY).isEqualTo(1636)
142                 assertThat(sensorRadius).isEqualTo(130)
143             }
144         }
145 }
146