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.systemui.deviceentry.shared
18 
19 import android.annotation.StringDef
20 import android.os.PowerManager
21 import com.android.internal.logging.UiEvent
22 import com.android.internal.logging.UiEventLogger
23 import com.android.systemui.deviceentry.shared.FaceAuthApiRequestReason.Companion.ACCESSIBILITY_ACTION
24 import com.android.systemui.deviceentry.shared.FaceAuthApiRequestReason.Companion.NOTIFICATION_PANEL_CLICKED
25 import com.android.systemui.deviceentry.shared.FaceAuthApiRequestReason.Companion.PICK_UP_GESTURE_TRIGGERED
26 import com.android.systemui.deviceentry.shared.FaceAuthApiRequestReason.Companion.QS_EXPANDED
27 import com.android.systemui.deviceentry.shared.FaceAuthApiRequestReason.Companion.SWIPE_UP_ON_BOUNCER
28 import com.android.systemui.deviceentry.shared.FaceAuthApiRequestReason.Companion.UDFPS_POINTER_DOWN
29 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.ALL_AUTHENTICATORS_REGISTERED
30 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.ALTERNATE_BIOMETRIC_BOUNCER_SHOWN
31 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.ASSISTANT_VISIBILITY_CHANGED
32 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.AUTH_REQUEST_DURING_CANCELLATION
33 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.BIOMETRIC_ENABLED
34 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.CAMERA_AVAILABLE_CHANGED
35 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.CAMERA_LAUNCHED
36 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.DEVICE_WOKEN_UP_ON_REACH_GESTURE
37 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.DISPLAY_OFF
38 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.DREAM_STARTED
39 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.DREAM_STOPPED
40 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.ENROLLMENTS_CHANGED
41 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.FACE_AUTHENTICATED
42 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.FACE_AUTH_STOPPED_ON_USER_INPUT
43 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.FACE_CANCEL_NOT_RECEIVED
44 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.FACE_LOCKOUT_RESET
45 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.FINISHED_GOING_TO_SLEEP
46 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.FP_AUTHENTICATED
47 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.FP_LOCKED_OUT
48 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.GOING_TO_SLEEP
49 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.KEYGUARD_GOING_AWAY
50 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.KEYGUARD_INIT
51 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.KEYGUARD_OCCLUSION_CHANGED
52 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.KEYGUARD_RESET
53 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.KEYGUARD_VISIBILITY_CHANGED
54 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.NON_STRONG_BIOMETRIC_ALLOWED_CHANGED
55 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.OCCLUDING_APP_REQUESTED
56 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.POSTURE_CHANGED
57 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN
58 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
59 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.RETRY_AFTER_HW_UNAVAILABLE
60 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.STARTED_WAKING_UP
61 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.STRONG_AUTH_ALLOWED_CHANGED
62 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.TRUST_DISABLED
63 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.TRUST_ENABLED
64 import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.USER_SWITCHING
65 
66 /** List of reasons why face auth is requested by clients. */
67 @Retention(AnnotationRetention.SOURCE)
68 @StringDef(
69     SWIPE_UP_ON_BOUNCER,
70     UDFPS_POINTER_DOWN,
71     NOTIFICATION_PANEL_CLICKED,
72     QS_EXPANDED,
73     PICK_UP_GESTURE_TRIGGERED,
74     ACCESSIBILITY_ACTION,
75 )
76 annotation class FaceAuthApiRequestReason {
77     companion object {
78         const val SWIPE_UP_ON_BOUNCER = "Face auth due to swipe up on bouncer"
79         const val UDFPS_POINTER_DOWN = "Face auth triggered due to finger down on UDFPS"
80         const val NOTIFICATION_PANEL_CLICKED = "Face auth due to notification panel click."
81         const val QS_EXPANDED = "Face auth due to QS expansion."
82         const val PICK_UP_GESTURE_TRIGGERED =
83             "Face auth due to pickup gesture triggered when the device is awake and not from AOD."
84         const val ACCESSIBILITY_ACTION = "Face auth due to an accessibility action."
85     }
86 }
87 
88 /** List of events why face auth could be triggered by [KeyguardUpdateMonitor]. */
89 private object InternalFaceAuthReasons {
90     const val OCCLUDING_APP_REQUESTED = "Face auth due to request from occluding app."
91     const val RETRY_AFTER_HW_UNAVAILABLE = "Face auth due to retry after hardware unavailable."
92     const val FACE_LOCKOUT_RESET = "Face auth due to face lockout reset."
93     const val DEVICE_WOKEN_UP_ON_REACH_GESTURE =
94         "Face auth requested when user reaches for the device on AoD."
95     const val ALTERNATE_BIOMETRIC_BOUNCER_SHOWN = "Face auth due to alternate bouncer shown."
96     const val PRIMARY_BOUNCER_SHOWN = "Face auth started/stopped due to primary bouncer shown."
97     const val PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN =
98         "Face auth started/stopped due to bouncer being shown or will be shown."
99     const val TRUST_DISABLED = "Face auth started due to trust disabled."
100     const val TRUST_ENABLED = "Face auth stopped due to trust enabled."
101     const val KEYGUARD_OCCLUSION_CHANGED =
102         "Face auth started/stopped due to keyguard occlusion change."
103     const val ASSISTANT_VISIBILITY_CHANGED =
104         "Face auth started/stopped due to assistant visibility change."
105     const val STARTED_WAKING_UP = "Face auth started/stopped due to device starting to wake up."
106     const val DREAM_STOPPED = "Face auth due to dream stopped."
107     const val ALL_AUTHENTICATORS_REGISTERED = "Face auth due to all authenticators registered."
108     const val ENROLLMENTS_CHANGED = "Face auth due to enrolments changed."
109     const val KEYGUARD_VISIBILITY_CHANGED =
110         "Face auth stopped or started due to keyguard visibility changed."
111     const val FACE_CANCEL_NOT_RECEIVED = "Face auth stopped due to face cancel signal not received."
112     const val AUTH_REQUEST_DURING_CANCELLATION =
113         "Another request to start face auth received while cancelling face auth"
114     const val DREAM_STARTED = "Face auth stopped because dreaming started"
115     const val FP_LOCKED_OUT = "Face auth stopped because fp locked out"
116     const val FACE_AUTH_STOPPED_ON_USER_INPUT =
117         "Face auth stopped because user started typing password/pin"
118     const val KEYGUARD_GOING_AWAY = "Face auth stopped because keyguard going away"
119     const val CAMERA_LAUNCHED = "Face auth started/stopped because camera launched"
120     const val FP_AUTHENTICATED = "Face auth started/stopped because fingerprint launched"
121     const val GOING_TO_SLEEP = "Face auth started/stopped because going to sleep"
122     const val FINISHED_GOING_TO_SLEEP = "Face auth stopped because finished going to sleep"
123     const val KEYGUARD_INIT = "Face auth started/stopped because Keyguard is initialized"
124     const val KEYGUARD_RESET = "Face auth started/stopped because Keyguard is reset"
125     const val USER_SWITCHING = "Face auth started/stopped because user is switching"
126     const val FACE_AUTHENTICATED = "Face auth started/stopped because face is authenticated"
127     const val BIOMETRIC_ENABLED =
128         "Face auth started/stopped because biometric is enabled on keyguard"
129     const val STRONG_AUTH_ALLOWED_CHANGED = "Face auth stopped because strong auth allowed changed"
130     const val NON_STRONG_BIOMETRIC_ALLOWED_CHANGED =
131         "Face auth stopped because non strong biometric allowed changed"
132     const val POSTURE_CHANGED = "Face auth started/stopped due to device posture changed."
133     const val DISPLAY_OFF = "Face auth stopped due to display state OFF."
134     const val CAMERA_AVAILABLE_CHANGED = "Face auth started due to the available camera changed"
135 }
136 
137 /**
138  * UiEvents that are logged to identify why face auth is being triggered.
139  *
140  * @param extraInfo is logged as the position. See [UiEventLogger#logWithInstanceIdAndPosition]
141  */
142 enum class FaceAuthUiEvent
143 constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
144     UiEventLogger.UiEventEnum {
145     @UiEvent(doc = OCCLUDING_APP_REQUESTED)
146     FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED(1146, OCCLUDING_APP_REQUESTED),
147     @UiEvent(doc = UDFPS_POINTER_DOWN)
148     FACE_AUTH_TRIGGERED_UDFPS_POINTER_DOWN(1147, UDFPS_POINTER_DOWN),
149     @UiEvent(doc = SWIPE_UP_ON_BOUNCER)
150     FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER(1148, SWIPE_UP_ON_BOUNCER),
151     @UiEvent(doc = DEVICE_WOKEN_UP_ON_REACH_GESTURE)
152     FACE_AUTH_TRIGGERED_ON_REACH_GESTURE_ON_AOD(1149, DEVICE_WOKEN_UP_ON_REACH_GESTURE),
153     @UiEvent(doc = FACE_LOCKOUT_RESET)
154     FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET(1150, FACE_LOCKOUT_RESET),
155     @UiEvent(doc = QS_EXPANDED) FACE_AUTH_TRIGGERED_QS_EXPANDED(1151, QS_EXPANDED),
156     @UiEvent(doc = NOTIFICATION_PANEL_CLICKED)
157     FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED(1152, NOTIFICATION_PANEL_CLICKED),
158     @UiEvent(doc = PICK_UP_GESTURE_TRIGGERED)
159     FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED(1153, PICK_UP_GESTURE_TRIGGERED),
160     @UiEvent(doc = ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
161     FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN(1154, ALTERNATE_BIOMETRIC_BOUNCER_SHOWN),
162     @UiEvent(doc = PRIMARY_BOUNCER_SHOWN)
163     FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN(1155, PRIMARY_BOUNCER_SHOWN),
164     @UiEvent(doc = PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN)
165     FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN(
166         1197,
167         PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
168     ),
169     @UiEvent(doc = RETRY_AFTER_HW_UNAVAILABLE)
170     FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE(1156, RETRY_AFTER_HW_UNAVAILABLE),
171     @UiEvent(doc = TRUST_DISABLED) FACE_AUTH_TRIGGERED_TRUST_DISABLED(1158, TRUST_DISABLED),
172     @UiEvent(doc = TRUST_ENABLED) FACE_AUTH_STOPPED_TRUST_ENABLED(1173, TRUST_ENABLED),
173     @UiEvent(doc = KEYGUARD_OCCLUSION_CHANGED)
174     FACE_AUTH_UPDATED_KEYGUARD_OCCLUSION_CHANGED(1159, KEYGUARD_OCCLUSION_CHANGED),
175     @UiEvent(doc = ASSISTANT_VISIBILITY_CHANGED)
176     FACE_AUTH_UPDATED_ASSISTANT_VISIBILITY_CHANGED(1160, ASSISTANT_VISIBILITY_CHANGED),
177     @UiEvent(doc = STARTED_WAKING_UP)
178     FACE_AUTH_UPDATED_STARTED_WAKING_UP(1161, STARTED_WAKING_UP) {
extraInfoToStringnull179         override fun extraInfoToString(): String {
180             return PowerManager.wakeReasonToString(extraInfo)
181         }
182     },
183     @UiEvent(doc = POSTURE_CHANGED) FACE_AUTH_UPDATED_POSTURE_CHANGED(1265, POSTURE_CHANGED),
184     @Deprecated(
185         "Not a face auth trigger.",
186         ReplaceWith(
187             "FACE_AUTH_UPDATED_STARTED_WAKING_UP, " +
188                 "extraInfo=PowerManager.WAKE_REASON_DREAM_FINISHED"
189         )
190     )
191     @UiEvent(doc = DREAM_STOPPED)
192     FACE_AUTH_TRIGGERED_DREAM_STOPPED(1162, DREAM_STOPPED),
193     @UiEvent(doc = ALL_AUTHENTICATORS_REGISTERED)
194     FACE_AUTH_TRIGGERED_ALL_AUTHENTICATORS_REGISTERED(1163, ALL_AUTHENTICATORS_REGISTERED),
195     @UiEvent(doc = ENROLLMENTS_CHANGED)
196     FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED(1164, ENROLLMENTS_CHANGED),
197     @UiEvent(doc = KEYGUARD_VISIBILITY_CHANGED)
198     FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED(1165, KEYGUARD_VISIBILITY_CHANGED),
199     @UiEvent(doc = FACE_CANCEL_NOT_RECEIVED)
200     FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED(1174, FACE_CANCEL_NOT_RECEIVED),
201     @UiEvent(doc = AUTH_REQUEST_DURING_CANCELLATION)
202     FACE_AUTH_TRIGGERED_DURING_CANCELLATION(1175, AUTH_REQUEST_DURING_CANCELLATION),
203     @UiEvent(doc = DREAM_STARTED) FACE_AUTH_STOPPED_DREAM_STARTED(1176, DREAM_STARTED),
204     @UiEvent(doc = FP_LOCKED_OUT) FACE_AUTH_STOPPED_FP_LOCKED_OUT(1177, FP_LOCKED_OUT),
205     @UiEvent(doc = FACE_AUTH_STOPPED_ON_USER_INPUT)
206     FACE_AUTH_STOPPED_USER_INPUT_ON_BOUNCER(1178, FACE_AUTH_STOPPED_ON_USER_INPUT),
207     @UiEvent(doc = KEYGUARD_GOING_AWAY)
208     FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY(1179, KEYGUARD_GOING_AWAY),
209     @UiEvent(doc = CAMERA_LAUNCHED) FACE_AUTH_UPDATED_CAMERA_LAUNCHED(1180, CAMERA_LAUNCHED),
210     @UiEvent(doc = FP_AUTHENTICATED) FACE_AUTH_UPDATED_FP_AUTHENTICATED(1181, FP_AUTHENTICATED),
211     @UiEvent(doc = GOING_TO_SLEEP) FACE_AUTH_UPDATED_GOING_TO_SLEEP(1182, GOING_TO_SLEEP),
212     @UiEvent(doc = FINISHED_GOING_TO_SLEEP)
213     FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP(1183, FINISHED_GOING_TO_SLEEP),
214     @UiEvent(doc = KEYGUARD_INIT) FACE_AUTH_UPDATED_ON_KEYGUARD_INIT(1189, KEYGUARD_INIT),
215     @UiEvent(doc = KEYGUARD_RESET) FACE_AUTH_UPDATED_KEYGUARD_RESET(1185, KEYGUARD_RESET),
216     @UiEvent(doc = USER_SWITCHING) FACE_AUTH_UPDATED_USER_SWITCHING(1186, USER_SWITCHING),
217     @UiEvent(doc = FACE_AUTHENTICATED)
218     FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED(1187, FACE_AUTHENTICATED),
219     @UiEvent(doc = BIOMETRIC_ENABLED)
220     FACE_AUTH_UPDATED_BIOMETRIC_ENABLED_ON_KEYGUARD(1188, BIOMETRIC_ENABLED),
221     @UiEvent(doc = STRONG_AUTH_ALLOWED_CHANGED)
222     FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED(1255, STRONG_AUTH_ALLOWED_CHANGED),
223     @UiEvent(doc = NON_STRONG_BIOMETRIC_ALLOWED_CHANGED)
224     FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED(1256, NON_STRONG_BIOMETRIC_ALLOWED_CHANGED),
225     @UiEvent(doc = ACCESSIBILITY_ACTION) FACE_AUTH_ACCESSIBILITY_ACTION(1454, ACCESSIBILITY_ACTION),
226     @UiEvent(doc = DISPLAY_OFF) FACE_AUTH_DISPLAY_OFF(1461, DISPLAY_OFF),
227     @UiEvent(doc = CAMERA_AVAILABLE_CHANGED)
228     FACE_AUTH_CAMERA_AVAILABLE_CHANGED(1623, CAMERA_AVAILABLE_CHANGED);
229 
getIdnull230     override fun getId(): Int = this.id
231 
232     /** Convert [extraInfo] to a human-readable string. By default, this is empty. */
233     open fun extraInfoToString(): String = ""
234 }
235 
236 private val apiRequestReasonToUiEvent =
237     mapOf(
238         SWIPE_UP_ON_BOUNCER to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER,
239         UDFPS_POINTER_DOWN to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_UDFPS_POINTER_DOWN,
240         NOTIFICATION_PANEL_CLICKED to
241             FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED,
242         QS_EXPANDED to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED,
243         PICK_UP_GESTURE_TRIGGERED to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED,
244         PICK_UP_GESTURE_TRIGGERED to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED,
245         ACCESSIBILITY_ACTION to FaceAuthUiEvent.FACE_AUTH_ACCESSIBILITY_ACTION,
246     )
247 
248 /** Converts the [reason] to the corresponding [FaceAuthUiEvent]. */
249 fun apiRequestReasonToUiEvent(@FaceAuthApiRequestReason reason: String): FaceAuthUiEvent =
250     apiRequestReasonToUiEvent[reason]!!
251