1 package com.android.systemui.log
2 
3 import android.hardware.face.FaceManager
4 import android.hardware.face.FaceSensorPropertiesInternal
5 import com.android.keyguard.FaceAuthUiEvent
6 import com.android.systemui.dagger.SysUISingleton
7 import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus
8 import com.android.systemui.keyguard.shared.model.TransitionStep
9 import com.android.systemui.log.core.LogLevel.DEBUG
10 import com.android.systemui.log.dagger.FaceAuthLog
11 import com.google.errorprone.annotations.CompileTimeConstant
12 import javax.inject.Inject
13 
14 private const val TAG = "DeviceEntryFaceAuthRepositoryLog"
15 
16 /**
17  * Helper class for logging for
18  * [com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository]
19  *
20  * To enable logcat echoing for an entire buffer:
21  * ```
22  *   adb shell settings put global systemui/buffer/DeviceEntryFaceAuthRepositoryLog <logLevel>
23  *
24  * ```
25  */
26 @SysUISingleton
27 class FaceAuthenticationLogger
28 @Inject
29 constructor(
30     @FaceAuthLog private val logBuffer: LogBuffer,
31 ) {
32     fun ignoredFaceAuthTrigger(uiEvent: FaceAuthUiEvent, ignoredReason: String) {
33         logBuffer.log(
34             TAG,
35             DEBUG,
36             {
37                 str1 = uiEvent.reason
38                 str2 = ignoredReason
39             },
40             { "Ignoring trigger because $str2, Trigger reason: $str1" }
41         )
42     }
43 
44     fun queuingRequestWhileCancelling(
45         alreadyQueuedRequest: FaceAuthUiEvent?,
46         newRequest: FaceAuthUiEvent
47     ) {
48         logBuffer.log(
49             TAG,
50             DEBUG,
51             {
52                 str1 = alreadyQueuedRequest?.reason
53                 str2 = newRequest.reason
54             },
55             {
56                 "Face auth requested while previous request is being cancelled, " +
57                     "already queued request: $str1 queueing the new request: $str2"
58             }
59         )
60     }
61 
62     fun authenticating(uiEvent: FaceAuthUiEvent) {
63         logBuffer.log(TAG, DEBUG, { str1 = uiEvent.reason }, { "Running authenticate for $str1" })
64     }
65 
66     fun detectionNotSupported(
67         faceManager: FaceManager?,
68         sensorPropertiesInternal: MutableList<FaceSensorPropertiesInternal>?
69     ) {
70         logBuffer.log(
71             TAG,
72             DEBUG,
73             {
74                 bool1 = faceManager == null
75                 bool2 = sensorPropertiesInternal.isNullOrEmpty()
76                 bool2 = sensorPropertiesInternal?.firstOrNull()?.supportsFaceDetection ?: false
77             },
78             {
79                 "skipping detection request because it is not supported, " +
80                     "faceManager isNull: $bool1, " +
81                     "sensorPropertiesInternal isNullOrEmpty: $bool2, " +
82                     "supportsFaceDetection: $bool3"
83             }
84         )
85     }
86 
87     fun skippingDetection(isAuthRunning: Boolean, detectCancellationNotNull: Boolean) {
88         logBuffer.log(
89             TAG,
90             DEBUG,
91             {
92                 bool1 = isAuthRunning
93                 bool2 = detectCancellationNotNull
94             },
95             {
96                 "Skipping running detection: isAuthRunning: $bool1, " +
97                     "detectCancellationNotNull: $bool2"
98             }
99         )
100     }
101 
102     fun faceDetectionStarted() {
103         logBuffer.log(TAG, DEBUG, "Face detection started.")
104     }
105 
106     fun faceDetected() {
107         logBuffer.log(TAG, DEBUG, "Face detected")
108     }
109 
110     fun cancelSignalNotReceived(
111         isAuthRunning: Boolean,
112         isLockedOut: Boolean,
113         cancellationInProgress: Boolean,
114         faceAuthRequestedWhileCancellation: FaceAuthUiEvent?
115     ) {
116         logBuffer.log(
117             TAG,
118             DEBUG,
119             {
120                 bool1 = isAuthRunning
121                 bool2 = isLockedOut
122                 bool3 = cancellationInProgress
123                 str1 = "${faceAuthRequestedWhileCancellation?.reason}"
124             },
125             {
126                 "Cancel signal was not received, running timeout handler to reset state. " +
127                     "State before reset: " +
128                     "isAuthRunning: $bool1, " +
129                     "isLockedOut: $bool2, " +
130                     "cancellationInProgress: $bool3, " +
131                     "faceAuthRequestedWhileCancellation: $str1"
132             }
133         )
134     }
135 
136     fun authenticationFailed() {
137         logBuffer.log(TAG, DEBUG, "Face authentication failed")
138     }
139 
140     fun authenticationError(
141         errorCode: Int,
142         errString: CharSequence?,
143         lockoutError: Boolean,
144         cancellationError: Boolean
145     ) {
146         logBuffer.log(
147             TAG,
148             DEBUG,
149             {
150                 int1 = errorCode
151                 str1 = "$errString"
152                 bool1 = lockoutError
153                 bool2 = cancellationError
154             },
155             {
156                 "Received authentication error: errorCode: $int1, " +
157                     "errString: $str1, " +
158                     "isLockoutError: $bool1, " +
159                     "isCancellationError: $bool2"
160             }
161         )
162     }
163 
164     fun launchingQueuedFaceAuthRequest(faceAuthRequestedWhileCancellation: FaceAuthUiEvent?) {
165         logBuffer.log(
166             TAG,
167             DEBUG,
168             { str1 = "${faceAuthRequestedWhileCancellation?.reason}" },
169             { "Received cancellation error and starting queued face auth request: $str1" }
170         )
171     }
172 
173     fun faceAuthSuccess(result: FaceManager.AuthenticationResult) {
174         logBuffer.log(
175             TAG,
176             DEBUG,
177             {
178                 int1 = result.userId
179                 bool1 = result.isStrongBiometric
180             },
181             { "Face authenticated successfully: userId: $int1, isStrongBiometric: $bool1" }
182         )
183     }
184 
185     fun observedConditionChanged(newValue: Boolean, context: String) {
186         logBuffer.log(
187             TAG,
188             DEBUG,
189             {
190                 bool1 = newValue
191                 str1 = context
192             },
193             { "Observed condition changed: $str1, new value: $bool1" }
194         )
195     }
196 
197     fun canFaceAuthRunChanged(canRun: Boolean) {
198         logBuffer.log(TAG, DEBUG, { bool1 = canRun }, { "canFaceAuthRun value changed to $bool1" })
199     }
200 
201     fun canRunDetectionChanged(canRunDetection: Boolean) {
202         logBuffer.log(
203             TAG,
204             DEBUG,
205             { bool1 = canRunDetection },
206             { "canRunDetection value changed to $bool1" }
207         )
208     }
209 
210     fun cancellingFaceAuth() {
211         logBuffer.log(TAG, DEBUG, "cancelling face auth because a gating condition became false")
212     }
213 
214     fun interactorStarted() {
215         logBuffer.log(TAG, DEBUG, "KeyguardFaceAuthInteractor started")
216     }
217 
218     fun bouncerVisibilityChanged() {
219         logBuffer.log(TAG, DEBUG, "Triggering face auth because primary bouncer is visible")
220     }
221 
222     fun alternateBouncerVisibilityChanged() {
223         logBuffer.log(TAG, DEBUG, "Triggering face auth because alternate bouncer is visible")
224     }
225 
226     fun lockscreenBecameVisible(transitionStep: TransitionStep?) {
227         logBuffer.log(
228             TAG,
229             DEBUG,
230             { str1 = "$transitionStep" },
231             { "Triggering face auth because lockscreen became visible due to transition: $str1" }
232         )
233     }
234 
235     fun authRequested(uiEvent: FaceAuthUiEvent) {
236         logBuffer.log(
237             TAG,
238             DEBUG,
239             { str1 = "$uiEvent" },
240             { "Requesting face auth for trigger: $str1" }
241         )
242     }
243 
244     fun hardwareError(errorStatus: ErrorFaceAuthenticationStatus) {
245         logBuffer.log(
246             TAG,
247             DEBUG,
248             {
249                 str1 = "${errorStatus.msg}"
250                 int1 = errorStatus.msgId
251             },
252             { "Received face hardware error: $str1 , code: $int1" }
253         )
254     }
255 
256     fun attemptingRetryAfterHardwareError(retryCount: Int) {
257         logBuffer.log(
258             TAG,
259             DEBUG,
260             { int1 = retryCount },
261             { "Attempting face auth again because of HW error: retry attempt $int1" }
262         )
263     }
264 
265     fun watchdogScheduled() {
266         logBuffer.log(TAG, DEBUG, "FaceManager Biometric watchdog scheduled.")
267     }
268 
269     fun faceLockedOut(@CompileTimeConstant reason: String) {
270         logBuffer.log(TAG, DEBUG, "Face auth has been locked out: $reason")
271     }
272 }
273