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   override val hasSideFps: Flow<Boolean>
101     get() = flowOf(false)
102 
pointToLeftOfSensornull103   private fun pointToLeftOfSensor(sensorLocation: Rect): MotionEvent =
104     MotionEvent.obtain(
105       100,
106       100,
107       ACTION_HOVER_MOVE,
108       sensorLocation.right + 5.0f,
109       sensorLocation.centerY().toFloat(),
110       0,
111     )
112 
113   private fun pointToRightOfSensor(sensorLocation: Rect): MotionEvent =
114     MotionEvent.obtain(
115       100,
116       100,
117       ACTION_HOVER_MOVE,
118       sensorLocation.right - 5.0f,
119       sensorLocation.centerY().toFloat(),
120       0,
121     )
122 
123   private fun pointBelowSensor(sensorLocation: Rect): MotionEvent =
124     MotionEvent.obtain(
125       100,
126       100,
127       ACTION_HOVER_MOVE,
128       sensorLocation.centerX().toFloat(),
129       sensorLocation.bottom + 5.0f,
130       0,
131     )
132 
133   private fun pointAboveSensor(sensorLocation: Rect): MotionEvent =
134     MotionEvent.obtain(
135       100,
136       100,
137       ACTION_HOVER_MOVE,
138       sensorLocation.centerX().toFloat(),
139       sensorLocation.top - 5.0f,
140       0,
141     )
142 
143   companion object {
144 
145     private val helpMsgId: Int = 1
146     private val sensorLocationInternal = Pair(540, 1713)
147     private val sensorRadius = 100
148     private val sensorRect =
149       Rect(
150         sensorLocationInternal.first - sensorRadius,
151         sensorLocationInternal.second - sensorRadius,
152         sensorLocationInternal.first + sensorRadius,
153         sensorLocationInternal.second + sensorRadius,
154       )
155     val sensorProps =
156       FingerprintSensor(
157         1,
158         SensorStrength.STRONG,
159         5,
160         FingerprintSensorType.UDFPS_OPTICAL,
161         sensorRect,
162         sensorRadius,
163       )
164   }
165 }
166