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.debug.data.repository
18 
19 import android.graphics.Rect
20 import android.hardware.fingerprint.FingerprintEnrollOptions
21 import android.view.MotionEvent
22 import android.view.MotionEvent.ACTION_HOVER_MOVE
23 import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
24 import com.android.settings.biometrics.fingerprint2.data.repository.SimulatedTouchEventsRepository
25 import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintEnrollInteractor
26 import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
27 import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
28 import com.android.systemui.biometrics.shared.model.FingerprintSensor
29 import com.android.systemui.biometrics.shared.model.FingerprintSensorType
30 import com.android.systemui.biometrics.shared.model.SensorStrength
31 import kotlinx.coroutines.delay
32 import kotlinx.coroutines.flow.Flow
33 import kotlinx.coroutines.flow.flow
34 import kotlinx.coroutines.flow.flowOf
35 
36 /**
37  * This class is used to simulate enroll data. This has two major use cases. 1). Ease of Development
38  * 2). Bug Fixes
39  */
40 class UdfpsEnrollDebugRepositoryImpl :
41   FingerprintEnrollInteractor, FingerprintSensorRepository, SimulatedTouchEventsRepository {
42 
enrollnull43   override suspend fun enroll(
44     hardwareAuthToken: ByteArray?,
45     enrollReason: EnrollReason,
46     fingerprintEnrollOptions: FingerprintEnrollOptions,
47   ) = flow {
48     emit(FingerEnrollState.OverlayShown)
49     delay(200)
50     emit(FingerEnrollState.EnrollHelp(helpMsgId, "Hello world"))
51     delay(200)
52     emit(FingerEnrollState.EnrollProgress(15, 16))
53     delay(300)
54     emit(FingerEnrollState.EnrollHelp(helpMsgId, "Hello world"))
55     delay(1000)
56     emit(FingerEnrollState.EnrollProgress(14, 16))
57     delay(500)
58     emit(FingerEnrollState.EnrollProgress(13, 16))
59     delay(500)
60     emit(FingerEnrollState.EnrollProgress(12, 16))
61     delay(500)
62     emit(FingerEnrollState.EnrollProgress(11, 16))
63     delay(500)
64     emit(FingerEnrollState.EnrollProgress(10, 16))
65     delay(500)
66     emit(FingerEnrollState.EnrollProgress(9, 16))
67     delay(500)
68     emit(FingerEnrollState.EnrollProgress(8, 16))
69     delay(500)
70     emit(FingerEnrollState.EnrollProgress(7, 16))
71     delay(500)
72     emit(FingerEnrollState.EnrollProgress(6, 16))
73     delay(500)
74     emit(FingerEnrollState.EnrollProgress(5, 16))
75     delay(500)
76     emit(FingerEnrollState.EnrollProgress(4, 16))
77     delay(500)
78     emit(FingerEnrollState.EnrollProgress(3, 16))
79     delay(500)
80     emit(FingerEnrollState.EnrollProgress(2, 16))
81     delay(500)
82     emit(FingerEnrollState.EnrollProgress(1, 16))
83     delay(500)
84     emit(FingerEnrollState.EnrollProgress(0, 16))
85   }
86 
87   /** Provides touch events to the UdfpsEnrollFragment */
<lambda>null88   override val touchExplorationDebug: Flow<MotionEvent> = flow {
89     delay(2000)
90     emit(pointToLeftOfSensor(sensorRect))
91     delay(2000)
92     emit(pointBelowSensor(sensorRect))
93     delay(2000)
94     emit(pointToRightOfSensor(sensorRect))
95     delay(2000)
96     emit(pointAboveSensor(sensorRect))
97   }
98 
99   override val fingerprintSensor: Flow<FingerprintSensor> = flowOf(sensorProps)
100 
pointToLeftOfSensornull101   private fun pointToLeftOfSensor(sensorLocation: Rect): MotionEvent =
102     MotionEvent.obtain(
103       100,
104       100,
105       ACTION_HOVER_MOVE,
106       sensorLocation.right + 5.0f,
107       sensorLocation.centerY().toFloat(),
108       0,
109     )
110 
111   private fun pointToRightOfSensor(sensorLocation: Rect): MotionEvent =
112     MotionEvent.obtain(
113       100,
114       100,
115       ACTION_HOVER_MOVE,
116       sensorLocation.right - 5.0f,
117       sensorLocation.centerY().toFloat(),
118       0,
119     )
120 
121   private fun pointBelowSensor(sensorLocation: Rect): MotionEvent =
122     MotionEvent.obtain(
123       100,
124       100,
125       ACTION_HOVER_MOVE,
126       sensorLocation.centerX().toFloat(),
127       sensorLocation.bottom + 5.0f,
128       0,
129     )
130 
131   private fun pointAboveSensor(sensorLocation: Rect): MotionEvent =
132     MotionEvent.obtain(
133       100,
134       100,
135       ACTION_HOVER_MOVE,
136       sensorLocation.centerX().toFloat(),
137       sensorLocation.top - 5.0f,
138       0,
139     )
140 
141   companion object {
142 
143     private val helpMsgId: Int = 1
144     private val sensorLocationInternal = Pair(540, 1713)
145     private val sensorRadius = 100
146     private val sensorRect =
147       Rect(
148         sensorLocationInternal.first - sensorRadius,
149         sensorLocationInternal.second - sensorRadius,
150         sensorLocationInternal.first + sensorRadius,
151         sensorLocationInternal.second + sensorRadius,
152       )
153     val sensorProps =
154       FingerprintSensor(
155         1,
156         SensorStrength.STRONG,
157         5,
158         FingerprintSensorType.UDFPS_OPTICAL,
159         sensorRect,
160         sensorRadius,
161       )
162   }
163 }
164