Log UiEvents whenever FaceAuth is triggered.

Test: atest KeyguardUpdateMonitor passes
Test: $ANDROID_HOST_OUT/bin/statsd_testdrive -terse 90  shows the
Test: atest FaceAuthReaonTest passes
triggered face auth UI events.
Bug: 238809124

Change-Id: I6cb04f7cccdaf92e77b8e5691bf5ac458928ff86
Merged-In: I6cb04f7cccdaf92e77b8e5691bf5ac458928ff86
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 182f49c..f50dc74 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -212,6 +212,7 @@
         "kotlinx-coroutines-android",
         "kotlinx-coroutines-core",
         "kotlinx_coroutines_test",
+        "kotlin-reflect",
         "iconloader_base",
         "SystemUI-tags",
         "SystemUI-proto",
diff --git a/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
new file mode 100644
index 0000000..6fcb6f5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/FaceAuthReason.kt
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.annotation.StringDef
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.keyguard.FaceAuthApiRequestReason.Companion.NOTIFICATION_PANEL_CLICKED
+import com.android.keyguard.FaceAuthApiRequestReason.Companion.PICK_UP_GESTURE_TRIGGERED
+import com.android.keyguard.FaceAuthApiRequestReason.Companion.QS_EXPANDED
+import com.android.keyguard.FaceAuthApiRequestReason.Companion.SWIPE_UP_ON_BOUNCER
+import com.android.keyguard.FaceAuthApiRequestReason.Companion.UDFPS_POINTER_DOWN
+import com.android.keyguard.InternalFaceAuthReasons.ALL_AUTHENTICATORS_REGISTERED
+import com.android.keyguard.InternalFaceAuthReasons.ALTERNATE_BIOMETRIC_BOUNCER_SHOWN
+import com.android.keyguard.InternalFaceAuthReasons.ASSISTANT_VISIBILITY_CHANGED
+import com.android.keyguard.InternalFaceAuthReasons.AUTH_REQUEST_DURING_CANCELLATION
+import com.android.keyguard.InternalFaceAuthReasons.BIOMETRIC_ENABLED
+import com.android.keyguard.InternalFaceAuthReasons.CAMERA_LAUNCHED
+import com.android.keyguard.InternalFaceAuthReasons.DEVICE_WOKEN_UP_ON_REACH_GESTURE
+import com.android.keyguard.InternalFaceAuthReasons.DREAM_STARTED
+import com.android.keyguard.InternalFaceAuthReasons.DREAM_STOPPED
+import com.android.keyguard.InternalFaceAuthReasons.ENROLLMENTS_CHANGED
+import com.android.keyguard.InternalFaceAuthReasons.FACE_AUTHENTICATED
+import com.android.keyguard.InternalFaceAuthReasons.FACE_AUTH_STOPPED_ON_USER_INPUT
+import com.android.keyguard.InternalFaceAuthReasons.FACE_CANCEL_NOT_RECEIVED
+import com.android.keyguard.InternalFaceAuthReasons.FACE_LOCKOUT_RESET
+import com.android.keyguard.InternalFaceAuthReasons.FINISHED_GOING_TO_SLEEP
+import com.android.keyguard.InternalFaceAuthReasons.FP_AUTHENTICATED
+import com.android.keyguard.InternalFaceAuthReasons.FP_LOCKED_OUT
+import com.android.keyguard.InternalFaceAuthReasons.GOING_TO_SLEEP
+import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_GOING_AWAY
+import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_INIT
+import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_OCCLUSION_CHANGED
+import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_RESET
+import com.android.keyguard.InternalFaceAuthReasons.KEYGUARD_VISIBILITY_CHANGED
+import com.android.keyguard.InternalFaceAuthReasons.OCCLUDING_APP_REQUESTED
+import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN
+import com.android.keyguard.InternalFaceAuthReasons.PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
+import com.android.keyguard.InternalFaceAuthReasons.RETRY_AFTER_HW_UNAVAILABLE
+import com.android.keyguard.InternalFaceAuthReasons.STARTED_WAKING_UP
+import com.android.keyguard.InternalFaceAuthReasons.TRUST_DISABLED
+import com.android.keyguard.InternalFaceAuthReasons.TRUST_ENABLED
+import com.android.keyguard.InternalFaceAuthReasons.USER_SWITCHING
+
+/**
+ * List of reasons why face auth is requested by clients through
+ * [KeyguardUpdateMonitor.requestFaceAuth].
+ */
+@Retention(AnnotationRetention.SOURCE)
+@StringDef(
+    SWIPE_UP_ON_BOUNCER,
+    UDFPS_POINTER_DOWN,
+    NOTIFICATION_PANEL_CLICKED,
+    QS_EXPANDED,
+    PICK_UP_GESTURE_TRIGGERED,
+)
+annotation class FaceAuthApiRequestReason {
+    companion object {
+        const val SWIPE_UP_ON_BOUNCER = "Face auth due to swipe up on bouncer"
+        const val UDFPS_POINTER_DOWN = "Face auth triggered due to finger down on UDFPS"
+        const val NOTIFICATION_PANEL_CLICKED = "Face auth due to notification panel click."
+        const val QS_EXPANDED = "Face auth due to QS expansion."
+        const val PICK_UP_GESTURE_TRIGGERED =
+            "Face auth due to pickup gesture triggered when the device is awake and not from AOD."
+    }
+}
+
+/** List of events why face auth could be triggered by [KeyguardUpdateMonitor]. */
+private object InternalFaceAuthReasons {
+    const val OCCLUDING_APP_REQUESTED = "Face auth due to request from occluding app."
+    const val RETRY_AFTER_HW_UNAVAILABLE = "Face auth due to retry after hardware unavailable."
+    const val FACE_LOCKOUT_RESET = "Face auth due to face lockout reset."
+    const val DEVICE_WOKEN_UP_ON_REACH_GESTURE =
+        "Face auth requested when user reaches for the device on AoD."
+    const val ALTERNATE_BIOMETRIC_BOUNCER_SHOWN = "Face auth due to alternate bouncer shown."
+    const val PRIMARY_BOUNCER_SHOWN = "Face auth started/stopped due to primary bouncer shown."
+    const val PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN =
+        "Face auth started/stopped due to bouncer being shown or will be shown."
+    const val TRUST_DISABLED = "Face auth started due to trust disabled."
+    const val TRUST_ENABLED = "Face auth stopped due to trust enabled."
+    const val KEYGUARD_OCCLUSION_CHANGED =
+        "Face auth started/stopped due to keyguard occlusion change."
+    const val ASSISTANT_VISIBILITY_CHANGED =
+        "Face auth started/stopped due to assistant visibility change."
+    const val STARTED_WAKING_UP = "Face auth started/stopped due to device starting to wake up."
+    const val DREAM_STOPPED = "Face auth due to dream stopped."
+    const val ALL_AUTHENTICATORS_REGISTERED = "Face auth due to all authenticators registered."
+    const val ENROLLMENTS_CHANGED = "Face auth due to enrolments changed."
+    const val KEYGUARD_VISIBILITY_CHANGED =
+        "Face auth stopped or started due to keyguard visibility changed."
+    const val FACE_CANCEL_NOT_RECEIVED = "Face auth stopped due to face cancel signal not received."
+    const val AUTH_REQUEST_DURING_CANCELLATION =
+        "Another request to start face auth received while cancelling face auth"
+    const val DREAM_STARTED = "Face auth stopped because dreaming started"
+    const val FP_LOCKED_OUT = "Face auth stopped because fp locked out"
+    const val FACE_AUTH_STOPPED_ON_USER_INPUT =
+        "Face auth stopped because user started typing password/pin"
+    const val KEYGUARD_GOING_AWAY = "Face auth stopped because keyguard going away"
+    const val CAMERA_LAUNCHED = "Face auth started/stopped because camera launched"
+    const val FP_AUTHENTICATED = "Face auth started/stopped because fingerprint launched"
+    const val GOING_TO_SLEEP = "Face auth started/stopped because going to sleep"
+    const val FINISHED_GOING_TO_SLEEP = "Face auth stopped because finished going to sleep"
+    const val KEYGUARD_INIT = "Face auth started/stopped because Keyguard is initialized"
+    const val KEYGUARD_RESET = "Face auth started/stopped because Keyguard is reset"
+    const val USER_SWITCHING = "Face auth started/stopped because user is switching"
+    const val FACE_AUTHENTICATED = "Face auth started/stopped because face is authenticated"
+    const val BIOMETRIC_ENABLED =
+        "Face auth started/stopped because biometric is enabled on keyguard"
+}
+
+/** UiEvents that are logged to identify why face auth is being triggered. */
+enum class FaceAuthUiEvent constructor(private val id: Int, val reason: String) :
+    UiEventLogger.UiEventEnum {
+    @UiEvent(doc = OCCLUDING_APP_REQUESTED)
+    FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED(1146, OCCLUDING_APP_REQUESTED),
+
+    @UiEvent(doc = UDFPS_POINTER_DOWN)
+    FACE_AUTH_TRIGGERED_UDFPS_POINTER_DOWN(1147, UDFPS_POINTER_DOWN),
+
+    @UiEvent(doc = SWIPE_UP_ON_BOUNCER)
+    FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER(1148, SWIPE_UP_ON_BOUNCER),
+
+    @UiEvent(doc = DEVICE_WOKEN_UP_ON_REACH_GESTURE)
+    FACE_AUTH_TRIGGERED_ON_REACH_GESTURE_ON_AOD(1149, DEVICE_WOKEN_UP_ON_REACH_GESTURE),
+
+    @UiEvent(doc = FACE_LOCKOUT_RESET)
+    FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET(1150, FACE_LOCKOUT_RESET),
+
+    @UiEvent(doc = QS_EXPANDED)
+    FACE_AUTH_TRIGGERED_QS_EXPANDED(1151, QS_EXPANDED),
+
+    @UiEvent(doc = NOTIFICATION_PANEL_CLICKED)
+    FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED(1152, NOTIFICATION_PANEL_CLICKED),
+
+    @UiEvent(doc = PICK_UP_GESTURE_TRIGGERED)
+    FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED(1153, PICK_UP_GESTURE_TRIGGERED),
+
+    @UiEvent(doc = ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
+    FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN(1154,
+        ALTERNATE_BIOMETRIC_BOUNCER_SHOWN),
+
+    @UiEvent(doc = PRIMARY_BOUNCER_SHOWN)
+    FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN(1155, PRIMARY_BOUNCER_SHOWN),
+
+    @UiEvent(doc = PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN)
+    FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN(
+        1197,
+        PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
+    ),
+
+    @UiEvent(doc = RETRY_AFTER_HW_UNAVAILABLE)
+    FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE(1156, RETRY_AFTER_HW_UNAVAILABLE),
+
+    @UiEvent(doc = TRUST_DISABLED)
+    FACE_AUTH_TRIGGERED_TRUST_DISABLED(1158, TRUST_DISABLED),
+
+    @UiEvent(doc = TRUST_ENABLED)
+    FACE_AUTH_STOPPED_TRUST_ENABLED(1173, TRUST_ENABLED),
+
+    @UiEvent(doc = KEYGUARD_OCCLUSION_CHANGED)
+    FACE_AUTH_UPDATED_KEYGUARD_OCCLUSION_CHANGED(1159, KEYGUARD_OCCLUSION_CHANGED),
+
+    @UiEvent(doc = ASSISTANT_VISIBILITY_CHANGED)
+    FACE_AUTH_UPDATED_ASSISTANT_VISIBILITY_CHANGED(1160, ASSISTANT_VISIBILITY_CHANGED),
+
+    @UiEvent(doc = STARTED_WAKING_UP)
+    FACE_AUTH_UPDATED_STARTED_WAKING_UP(1161, STARTED_WAKING_UP),
+
+    @UiEvent(doc = DREAM_STOPPED)
+    FACE_AUTH_TRIGGERED_DREAM_STOPPED(1162, DREAM_STOPPED),
+
+    @UiEvent(doc = ALL_AUTHENTICATORS_REGISTERED)
+    FACE_AUTH_TRIGGERED_ALL_AUTHENTICATORS_REGISTERED(1163, ALL_AUTHENTICATORS_REGISTERED),
+
+    @UiEvent(doc = ENROLLMENTS_CHANGED)
+    FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED(1164, ENROLLMENTS_CHANGED),
+
+    @UiEvent(doc = KEYGUARD_VISIBILITY_CHANGED)
+    FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED(1165, KEYGUARD_VISIBILITY_CHANGED),
+
+    @UiEvent(doc = FACE_CANCEL_NOT_RECEIVED)
+    FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED(1174, FACE_CANCEL_NOT_RECEIVED),
+
+    @UiEvent(doc = AUTH_REQUEST_DURING_CANCELLATION)
+    FACE_AUTH_TRIGGERED_DURING_CANCELLATION(1175, AUTH_REQUEST_DURING_CANCELLATION),
+
+    @UiEvent(doc = DREAM_STARTED)
+    FACE_AUTH_STOPPED_DREAM_STARTED(1176, DREAM_STARTED),
+
+    @UiEvent(doc = FP_LOCKED_OUT)
+    FACE_AUTH_STOPPED_FP_LOCKED_OUT(1177, FP_LOCKED_OUT),
+
+    @UiEvent(doc = FACE_AUTH_STOPPED_ON_USER_INPUT)
+    FACE_AUTH_STOPPED_USER_INPUT_ON_BOUNCER(1178, FACE_AUTH_STOPPED_ON_USER_INPUT),
+
+    @UiEvent(doc = KEYGUARD_GOING_AWAY)
+    FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY(1179, KEYGUARD_GOING_AWAY),
+
+    @UiEvent(doc = CAMERA_LAUNCHED)
+    FACE_AUTH_UPDATED_CAMERA_LAUNCHED(1180, CAMERA_LAUNCHED),
+
+    @UiEvent(doc = FP_AUTHENTICATED)
+    FACE_AUTH_UPDATED_FP_AUTHENTICATED(1181, FP_AUTHENTICATED),
+
+    @UiEvent(doc = GOING_TO_SLEEP)
+    FACE_AUTH_UPDATED_GOING_TO_SLEEP(1182, GOING_TO_SLEEP),
+
+    @UiEvent(doc = FINISHED_GOING_TO_SLEEP)
+    FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP(1183, FINISHED_GOING_TO_SLEEP),
+
+    @UiEvent(doc = KEYGUARD_INIT)
+    FACE_AUTH_UPDATED_ON_KEYGUARD_INIT(1189, KEYGUARD_INIT),
+
+    @UiEvent(doc = KEYGUARD_RESET)
+    FACE_AUTH_UPDATED_KEYGUARD_RESET(1185, KEYGUARD_RESET),
+
+    @UiEvent(doc = USER_SWITCHING)
+    FACE_AUTH_UPDATED_USER_SWITCHING(1186, USER_SWITCHING),
+
+    @UiEvent(doc = FACE_AUTHENTICATED)
+    FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED(1187, FACE_AUTHENTICATED),
+
+    @UiEvent(doc = BIOMETRIC_ENABLED)
+    FACE_AUTH_UPDATED_BIOMETRIC_ENABLED_ON_KEYGUARD(1188, BIOMETRIC_ENABLED);
+
+    override fun getId(): Int = this.id
+}
+
+private val apiRequestReasonToUiEvent =
+    mapOf(
+        SWIPE_UP_ON_BOUNCER to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER,
+        UDFPS_POINTER_DOWN to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_UDFPS_POINTER_DOWN,
+        NOTIFICATION_PANEL_CLICKED to
+            FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED,
+        QS_EXPANDED to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_QS_EXPANDED,
+        PICK_UP_GESTURE_TRIGGERED to FaceAuthUiEvent.FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED,
+    )
+
+/** Converts the [reason] to the corresponding [FaceAuthUiEvent]. */
+fun apiRequestReasonToUiEvent(@FaceAuthApiRequestReason reason: String): FaceAuthUiEvent =
+    apiRequestReasonToUiEvent[reason]!!
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 93175e1..57058b7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -223,7 +223,7 @@
         @Override
         public void onSwipeUp() {
             if (!mUpdateMonitor.isFaceDetectionRunning()) {
-                mUpdateMonitor.requestFaceAuth(true);
+                mUpdateMonitor.requestFaceAuth(true, FaceAuthApiRequestReason.SWIPE_UP_ON_BOUNCER);
                 mKeyguardSecurityCallback.userActivity();
                 showMessage(null, null);
             }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index cb88f32..4984300 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import static android.app.StatusBarManager.SESSION_KEYGUARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.Intent.ACTION_USER_REMOVED;
@@ -32,11 +33,43 @@
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+import static com.android.keyguard.FaceAuthReasonKt.apiRequestReasonToUiEvent;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_DREAM_STARTED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_FP_LOCKED_OUT;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_TRUST_ENABLED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_USER_INPUT_ON_BOUNCER;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALL_AUTHENTICATORS_REGISTERED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_DREAM_STOPPED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_DURING_CANCELLATION;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ON_REACH_GESTURE_ON_AOD;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_TRUST_DISABLED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ASSISTANT_VISIBILITY_CHANGED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_BIOMETRIC_ENABLED_ON_KEYGUARD;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_CAMERA_LAUNCHED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_FP_AUTHENTICATED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_GOING_TO_SLEEP;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_OCCLUSION_CHANGED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_RESET;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_ON_KEYGUARD_INIT;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STARTED_WAKING_UP;
+import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING;
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 
 import android.annotation.AnyThread;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.ActivityTaskManager.RootTaskInfo;
@@ -92,6 +125,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.logging.InstanceId;
+import com.android.internal.logging.UiEventLogger;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
@@ -105,6 +140,7 @@
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.log.SessionTracker;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
@@ -130,6 +166,7 @@
 import java.util.function.Consumer;
 
 import javax.inject.Inject;
+import javax.inject.Provider;
 
 /**
  * Watches for updates that may be interesting to the keyguard, and provides
@@ -240,6 +277,7 @@
     private final boolean mIsPrimaryUser;
     private final AuthController mAuthController;
     private final StatusBarStateController mStatusBarStateController;
+    private final UiEventLogger mUiEventLogger;
     private int mStatusBarState;
     private final StatusBarStateController.StateListener mStatusBarStateControllerListener =
             new StatusBarStateController.StateListener() {
@@ -305,7 +343,6 @@
     private KeyguardBypassController mKeyguardBypassController;
     private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
     private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
-    private boolean mIsFaceAuthUserRequested;
     private LockPatternUtils mLockPatternUtils;
     private final IDreamManager mDreamManager;
     private boolean mIsDreaming;
@@ -337,6 +374,7 @@
     protected final Runnable mFpCancelNotReceived = this::onFingerprintCancelNotReceived;
 
     private final Runnable mFaceCancelNotReceived = this::onFaceCancelNotReceived;
+    private final Provider<SessionTracker> mSessionTrackerProvider;
 
     @VisibleForTesting
     protected Handler getHandler() {
@@ -352,7 +390,8 @@
                 public void onChanged(boolean enabled, int userId) throws RemoteException {
                     mHandler.post(() -> {
                         mBiometricEnabledForUser.put(userId, enabled);
-                        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+                        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                                FACE_AUTH_UPDATED_BIOMETRIC_ENABLED_ON_KEYGUARD);
                     });
                 }
             };
@@ -420,9 +459,11 @@
         // authenticating.  TrustManager sends an onTrustChanged whenever a user unlocks keyguard,
         // for this reason we need to make sure to not authenticate.
         if (wasTrusted == enabled || enabled) {
-            updateBiometricListeningState(BIOMETRIC_ACTION_STOP);
+            updateBiometricListeningState(BIOMETRIC_ACTION_STOP,
+                    FACE_AUTH_STOPPED_TRUST_ENABLED);
         } else {
-            updateBiometricListeningState(BIOMETRIC_ACTION_START);
+            updateBiometricListeningState(BIOMETRIC_ACTION_START,
+                    FACE_AUTH_TRIGGERED_TRUST_DISABLED);
         }
 
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -616,7 +657,7 @@
     public void setKeyguardGoingAway(boolean goingAway) {
         mKeyguardGoingAway = goingAway;
         // This is set specifically to stop face authentication from running.
-        updateBiometricListeningState(BIOMETRIC_ACTION_STOP);
+        updateBiometricListeningState(BIOMETRIC_ACTION_STOP, FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY);
     }
 
     /**
@@ -624,7 +665,8 @@
      */
     public void setKeyguardOccluded(boolean occluded) {
         mKeyguardOccluded = occluded;
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_UPDATED_KEYGUARD_OCCLUSION_CHANGED);
     }
 
 
@@ -636,7 +678,8 @@
      */
     public void requestFaceAuthOnOccludingApp(boolean request) {
         mOccludingAppRequestingFace = request;
-        updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED);
     }
 
     /**
@@ -655,7 +698,8 @@
      */
     public void onCameraLaunched() {
         mSecureCameraLaunched = true;
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_UPDATED_CAMERA_LAUNCHED);
     }
 
     /**
@@ -697,7 +741,8 @@
         }
         // Don't send cancel if authentication succeeds
         mFingerprintCancelSignal = null;
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_UPDATED_FP_AUTHENTICATED);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -860,7 +905,7 @@
             if (isUdfpsEnrolled()) {
                 updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
             }
-            stopListeningForFace();
+            stopListeningForFace(FACE_AUTH_STOPPED_FP_LOCKED_OUT);
         }
 
         for (int i = 0; i < mCallbacks.size(); i++) {
@@ -939,7 +984,8 @@
         }
         // Don't send cancel if authentication succeeds
         mFaceCancelSignal = null;
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -1028,14 +1074,16 @@
         @Override
         public void run() {
             mLogger.logRetryingAfterFaceHwUnavailable(mHardwareFaceUnavailableRetryCount);
-            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
+            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
+                    FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE);
         }
     };
 
     private void onFaceCancelNotReceived() {
         mLogger.e("Face cancellation not received, transitioning to STOPPED");
         mFaceRunningState = BIOMETRIC_STATE_STOPPED;
-        KeyguardUpdateMonitor.this.updateFaceListeningState(BIOMETRIC_ACTION_STOP);
+        KeyguardUpdateMonitor.this.updateFaceListeningState(BIOMETRIC_ACTION_STOP,
+                FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED);
     }
 
     private void handleFaceError(int msgId, final String originalErrMsg) {
@@ -1058,7 +1106,8 @@
         if (msgId == FaceManager.FACE_ERROR_CANCELED
                 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
             setFaceRunningState(BIOMETRIC_STATE_STOPPED);
-            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
+            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
+                    FACE_AUTH_TRIGGERED_DURING_CANCELLATION);
         } else {
             setFaceRunningState(BIOMETRIC_STATE_STOPPED);
         }
@@ -1104,7 +1153,8 @@
         final boolean changed = (mFaceLockedOutPermanent != wasLockoutPermanent);
 
         mHandler.postDelayed(() -> {
-            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
+            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
+                    FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET);
         }, getBiometricLockoutDelay());
 
         if (changed) {
@@ -1349,7 +1399,8 @@
     @VisibleForTesting
     void setAssistantVisible(boolean assistantVisible) {
         mAssistantVisible = assistantVisible;
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_UPDATED_ASSISTANT_VISIBILITY_CHANGED);
         if (mAssistantVisible) {
             requestActiveUnlock(
                     ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.ASSISTANT,
@@ -1527,7 +1578,7 @@
                 @Override
                 public void onUdfpsPointerDown(int sensorId) {
                     mLogger.logUdfpsPointerDown(sensorId);
-                    requestFaceAuth(true);
+                    requestFaceAuth(true, FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
                 }
 
                 /**
@@ -1711,7 +1762,7 @@
     protected void handleStartedWakingUp() {
         Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
         Assert.isMainThread();
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_STARTED_WAKING_UP);
         requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "wakingUp");
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1732,7 +1783,7 @@
             }
         }
         mGoingToSleep = true;
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_GOING_TO_SLEEP);
     }
 
     protected void handleFinishedGoingToSleep(int arg1) {
@@ -1745,7 +1796,8 @@
             }
         }
         // This is set specifically to stop face authentication from running.
-        updateBiometricListeningState(BIOMETRIC_ACTION_STOP);
+        updateBiometricListeningState(BIOMETRIC_ACTION_STOP,
+                FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP);
     }
 
     private void handleScreenTurnedOff() {
@@ -1765,9 +1817,10 @@
         }
         if (mIsDreaming) {
             updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
-            updateFaceListeningState(BIOMETRIC_ACTION_STOP);
+            updateFaceListeningState(BIOMETRIC_ACTION_STOP, FACE_AUTH_STOPPED_DREAM_STARTED);
         } else {
-            updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+            updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                    FACE_AUTH_TRIGGERED_DREAM_STOPPED);
         }
     }
 
@@ -1832,8 +1885,10 @@
             InteractionJankMonitor interactionJankMonitor,
             LatencyTracker latencyTracker,
             ActiveUnlockConfig activeUnlockConfiguration,
-            KeyguardUpdateMonitorLogger logger) {
-        mLogger = logger;
+            KeyguardUpdateMonitorLogger logger,
+            UiEventLogger uiEventLogger,
+            // This has to be a provider because SessionTracker depends on KeyguardUpdateMonitor :(
+            Provider<SessionTracker> sessionTrackerProvider) {
         mContext = context;
         mSubscriptionManager = SubscriptionManager.from(context);
         mTelephonyListenerManager = telephonyListenerManager;
@@ -1851,6 +1906,9 @@
         dumpManager.registerDumpable(getClass().getName(), this);
         mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
         mActiveUnlockConfig = activeUnlockConfiguration;
+        mLogger = logger;
+        mUiEventLogger = uiEventLogger;
+        mSessionTrackerProvider = sessionTrackerProvider;
         mActiveUnlockConfig.setKeyguardUpdateMonitor(this);
 
         mHandler = new Handler(mainLooper) {
@@ -1934,7 +1992,8 @@
                         setAssistantVisible((boolean) msg.obj);
                         break;
                     case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
-                        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+                        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                                FACE_AUTH_UPDATED_FP_AUTHENTICATED);
                         break;
                     case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
                         updateLogoutEnabled();
@@ -2036,15 +2095,17 @@
         mAuthController.addCallback(new AuthController.Callback() {
             @Override
             public void onAllAuthenticatorsRegistered() {
-                mainExecutor.execute(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE));
+                mainExecutor.execute(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                        FACE_AUTH_TRIGGERED_ALL_AUTHENTICATORS_REGISTERED));
             }
 
             @Override
             public void onEnrollmentsChanged() {
-                mainExecutor.execute(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE));
+                mainExecutor.execute(() -> updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                        FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED));
             }
         });
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_ON_KEYGUARD_INIT);
         if (mFpm != null) {
             mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
         }
@@ -2156,9 +2217,10 @@
         mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
     }
 
-    private void updateBiometricListeningState(int action) {
+    private void updateBiometricListeningState(int action,
+            @NonNull FaceAuthUiEvent faceAuthUiEvent) {
         updateFingerprintListeningState(action);
-        updateFaceListeningState(action);
+        updateFaceListeningState(action, faceAuthUiEvent);
     }
 
     private void updateFingerprintListeningState(int action) {
@@ -2214,7 +2276,8 @@
             return;
         }
         mAuthInterruptActive = active;
-        updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_TRIGGERED_ON_REACH_GESTURE_ON_AOD);
         requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "onReach");
     }
 
@@ -2222,25 +2285,27 @@
      * Requests face authentication if we're on a state where it's allowed.
      * This will re-trigger auth in case it fails.
      * @param userInitiatedRequest true if the user explicitly requested face auth
+     * @param reason One of the reasons {@link FaceAuthApiRequestReason} on why this API is being
+     * invoked.
      */
-    public void requestFaceAuth(boolean userInitiatedRequest) {
+    public void requestFaceAuth(boolean userInitiatedRequest,
+            @FaceAuthApiRequestReason String reason) {
         mLogger.logFaceAuthRequested(userInitiatedRequest);
-        mIsFaceAuthUserRequested |= userInitiatedRequest;
-        updateFaceListeningState(BIOMETRIC_ACTION_START);
+        updateFaceListeningState(BIOMETRIC_ACTION_START, apiRequestReasonToUiEvent(reason));
     }
 
     /**
      * In case face auth is running, cancel it.
      */
     public void cancelFaceAuth() {
-        stopListeningForFace();
+        stopListeningForFace(FACE_AUTH_STOPPED_USER_INPUT_ON_BOUNCER);
     }
 
     public boolean isFaceScanning() {
         return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
     }
 
-    private void updateFaceListeningState(int action) {
+    private void updateFaceListeningState(int action, @NonNull FaceAuthUiEvent faceAuthUiEvent) {
         // If this message exists, we should not authenticate again until this message is
         // consumed by the handler
         if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
@@ -2253,17 +2318,21 @@
                 mLogger.v("Ignoring stopListeningForFace()");
                 return;
             }
-            mIsFaceAuthUserRequested = false;
-            stopListeningForFace();
+            stopListeningForFace(faceAuthUiEvent);
         } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING && shouldListenForFace) {
             if (action == BIOMETRIC_ACTION_STOP) {
                 mLogger.v("Ignoring startListeningForFace()");
                 return;
             }
-            startListeningForFace();
+            startListeningForFace(faceAuthUiEvent);
         }
     }
 
+    @Nullable
+    private InstanceId getKeyguardSessionId() {
+        return mSessionTrackerProvider.get().getSessionId(SESSION_KEYGUARD);
+    }
+
     /**
      * Initiates active unlock to get the unlock token ready.
      */
@@ -2332,7 +2401,8 @@
     public void setUdfpsBouncerShowing(boolean showing) {
         mUdfpsBouncerShowing = showing;
         if (mUdfpsBouncerShowing) {
-            updateFaceListeningState(BIOMETRIC_ACTION_START);
+            updateFaceListeningState(BIOMETRIC_ACTION_START,
+                    FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN);
             requestActiveUnlock(
                     ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
                     "udfpsBouncer");
@@ -2645,7 +2715,7 @@
         }
     }
 
-    private void startListeningForFace() {
+    private void startListeningForFace(@NonNull FaceAuthUiEvent faceAuthUiEvent) {
         final int userId = getCurrentUser();
         final boolean unlockPossible = isUnlockWithFacePossible(userId);
         if (mFaceCancelSignal != null) {
@@ -2659,7 +2729,8 @@
             // Waiting for ERROR_CANCELED before requesting auth again
             return;
         }
-        mLogger.logStartedListeningForFace(mFaceRunningState);
+        mLogger.logStartedListeningForFace(mFaceRunningState, faceAuthUiEvent.getReason());
+        mUiEventLogger.log(faceAuthUiEvent, getKeyguardSessionId());
 
         if (unlockPossible) {
             mFaceCancelSignal = new CancellationSignal();
@@ -2743,8 +2814,10 @@
         }
     }
 
-    private void stopListeningForFace() {
+    private void stopListeningForFace(@NonNull FaceAuthUiEvent faceAuthUiEvent) {
         mLogger.v("stopListeningForFace()");
+        mLogger.logStoppedListeningForFace(mFaceRunningState, faceAuthUiEvent.getReason());
+        mUiEventLogger.log(faceAuthUiEvent, getKeyguardSessionId());
         if (mFaceRunningState == BIOMETRIC_STATE_RUNNING) {
             if (mFaceCancelSignal != null) {
                 mFaceCancelSignal.cancel();
@@ -3073,7 +3146,8 @@
                 cb.onKeyguardVisibilityChangedRaw(showing);
             }
         }
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED);
     }
 
     /**
@@ -3081,7 +3155,8 @@
      */
     private void handleKeyguardReset() {
         mLogger.d("handleKeyguardReset");
-        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                FACE_AUTH_UPDATED_KEYGUARD_RESET);
         mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
     }
 
@@ -3132,7 +3207,8 @@
                     cb.onKeyguardBouncerStateChanged(mBouncerIsOrWillBeShowing);
                 }
             }
-            updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+            updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                    FaceAuthUiEvent.FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN);
         }
 
         if (wasBouncerFullyShown != mBouncerFullyShown) {
@@ -3147,7 +3223,8 @@
                     cb.onKeyguardBouncerFullyShowingChanged(mBouncerFullyShown);
                 }
             }
-            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
+            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
+                    FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN);
         }
     }
 
@@ -3275,7 +3352,8 @@
         mSwitchingUser = switching;
         // Since this comes in on a binder thread, we need to post if first
         mHandler.post(() -> {
-            updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
+            updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
+                    FACE_AUTH_UPDATED_USER_SWITCHING);
         });
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index d718a24..2bc98f1 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -262,10 +262,18 @@
         logBuffer.log(TAG, VERBOSE, { int1 = subId }, { "reportSimUnlocked(subId=$int1)" })
     }
 
-    fun logStartedListeningForFace(faceRunningState: Int) {
-        logBuffer.log(TAG, VERBOSE,
-                { int1 = faceRunningState },
-                { "startListeningForFace(): $int1" })
+    fun logStartedListeningForFace(faceRunningState: Int, faceAuthReason: String) {
+        logBuffer.log(TAG, VERBOSE, {
+            int1 = faceRunningState
+            str1 = faceAuthReason
+        }, { "startListeningForFace(): $int1, reason: $str1" })
+    }
+
+    fun logStoppedListeningForFace(faceRunningState: Int, faceAuthReason: String) {
+        logBuffer.log(TAG, VERBOSE, {
+            int1 = faceRunningState
+            str1 = faceAuthReason
+        }, { "stopListeningForFace(): currentFaceRunningState: $int1, reason: $str1" })
     }
 
     fun logSubInfo(subInfo: SubscriptionInfo?) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index d1589b2..7f2680b 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -52,6 +52,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.LatencyTracker;
+import com.android.keyguard.FaceAuthApiRequestReason;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.biometrics.dagger.BiometricsBackground;
@@ -852,7 +853,9 @@
             playStartHaptic();
 
             if (!mKeyguardUpdateMonitor.isFaceDetectionRunning()) {
-                mKeyguardUpdateMonitor.requestFaceAuth(/* userInitiatedRequest */ false);
+                mKeyguardUpdateMonitor.requestFaceAuth(
+                        /* userInitiatedRequest */ false,
+                        FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
             }
         }
         mOnFingerDown = true;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index d5ba07a..91c6a9c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -97,6 +97,7 @@
 import com.android.internal.policy.SystemBarUtils;
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.ActiveUnlockConfig;
+import com.android.keyguard.FaceAuthApiRequestReason;
 import com.android.keyguard.KeyguardClockSwitch.ClockSize;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardStatusViewController;
@@ -2351,7 +2352,7 @@
         // When expanding QS, let's authenticate the user if possible,
         // this will speed up notification actions.
         if (height == 0) {
-            mCentralSurfaces.requestFaceAuth(false);
+            mCentralSurfaces.requestFaceAuth(false, FaceAuthApiRequestReason.QS_EXPANDED);
         }
     }
 
@@ -3528,7 +3529,8 @@
                             && !mUpdateMonitor.isFaceDetectionRunning()
                             && !mUpdateMonitor.getUserCanSkipBouncer(
                             KeyguardUpdateMonitor.getCurrentUser())) {
-                        mUpdateMonitor.requestFaceAuth(true);
+                        mUpdateMonitor.requestFaceAuth(true,
+                                FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED);
                     } else {
                         mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT,
                                 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index d1b2974..20b6d0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -40,6 +40,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.RegisterStatusBarResult;
+import com.android.keyguard.FaceAuthApiRequestReason;
 import com.android.systemui.Dumpable;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.animation.RemoteTransitionAdapter;
@@ -225,7 +226,12 @@
 
     boolean isShadeDisabled();
 
-    void requestFaceAuth(boolean userInitiatedRequest);
+    /**
+     * Request face auth to initiated
+     * @param userInitiatedRequest Whether this was a user initiated request
+     * @param reason Reason why face auth was triggered.
+     */
+    void requestFaceAuth(boolean userInitiatedRequest, @FaceAuthApiRequestReason String reason);
 
     @Override
     void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index df6e545..6426aef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -120,6 +120,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.RegisterStatusBarResult;
+import com.android.keyguard.FaceAuthApiRequestReason;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
@@ -1612,9 +1613,11 @@
      * Asks {@link KeyguardUpdateMonitor} to run face auth.
      */
     @Override
-    public void requestFaceAuth(boolean userInitiatedRequest) {
+    public void requestFaceAuth(boolean userInitiatedRequest,
+            @FaceAuthApiRequestReason String reason) {
         if (!mKeyguardStateController.canDismissLockScreen()) {
-            mKeyguardUpdateMonitor.requestFaceAuth(userInitiatedRequest);
+            mKeyguardUpdateMonitor.requestFaceAuth(
+                    userInitiatedRequest, reason);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
index 3f8e97f1..b58dbe2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -22,6 +22,7 @@
 import android.hardware.TriggerEvent
 import android.hardware.TriggerEventListener
 import com.android.keyguard.ActiveUnlockConfig
+import com.android.keyguard.FaceAuthApiRequestReason
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.CoreStartable
@@ -71,7 +72,10 @@
             // Not listening anymore since trigger events unregister themselves
             isListening = false
             updateListeningState()
-            keyguardUpdateMonitor.requestFaceAuth(true)
+            keyguardUpdateMonitor.requestFaceAuth(
+                true,
+                FaceAuthApiRequestReason.PICK_UP_GESTURE_TRIGGERED
+            )
             keyguardUpdateMonitor.requestActiveUnlock(
                 ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE,
                 "KeyguardLiftController")
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/FaceAuthReasonTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/FaceAuthReasonTest.kt
new file mode 100644
index 0000000..68d0f41
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/FaceAuthReasonTest.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import junit.framework.Assert
+import kotlin.reflect.full.declaredMembers
+import org.junit.Test
+
+@SmallTest
+class FaceAuthReasonTest : SysuiTestCase() {
+    @Test
+    fun testApiReasonToUiEvent_forAllReasons_isNotNull() {
+        val declaredMemberProperties = FaceAuthApiRequestReason.Companion::class.declaredMembers
+
+        declaredMemberProperties.forEach {
+            val reason = it.call()
+            try {
+                apiRequestReasonToUiEvent(reason as String)
+            } catch (e: Exception) {
+                Assert.fail(
+                    "Expected the reason: \"$reason\" to have a corresponding FaceAuthUiEvent"
+                )
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index f5b9503..763a63e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -16,6 +16,7 @@
 
 package com.android.keyguard;
 
+import static android.app.StatusBarManager.SESSION_KEYGUARD;
 import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
 import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
 import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
@@ -85,6 +86,8 @@
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.logging.InstanceId;
+import com.android.internal.logging.UiEventLogger;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.widget.ILockSettings;
@@ -95,6 +98,7 @@
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.log.SessionTracker;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -189,6 +193,10 @@
     private KeyguardUpdateMonitorLogger mKeyguardUpdateMonitorLogger;
     @Mock
     private IActivityManager mActivityService;
+    @Mock
+    private SessionTracker mSessionTracker;
+    @Mock
+    private UiEventLogger mUiEventLogger;
 
     private final int mCurrentUserId = 100;
     private final UserInfo mCurrentUserInfo = new UserInfo(mCurrentUserId, "Test user", 0);
@@ -211,6 +219,7 @@
     private MockitoSession mMockitoSession;
     private StatusBarStateController.StateListener mStatusBarStateListener;
     private IBiometricEnabledOnKeyguardCallback mBiometricEnabledOnKeyguardCallback;
+    private final InstanceId mKeyguardInstanceId = InstanceId.fakeInstanceId(999);
 
     @Before
     public void setup() throws RemoteException {
@@ -224,6 +233,7 @@
         when(mFaceManager.hasEnrolledTemplates()).thenReturn(true);
         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
         when(mFaceManager.getSensorPropertiesInternal()).thenReturn(mFaceSensorProperties);
+        when(mSessionTracker.getSessionId(SESSION_KEYGUARD)).thenReturn(mKeyguardInstanceId);
 
         // IBiometricsFace@1.0 does not support detection, only authentication.
         when(mFaceSensorProperties.isEmpty()).thenReturn(false);
@@ -655,7 +665,8 @@
         // Stop scanning when bouncer becomes visible
         setKeyguardBouncerVisibility(true);
         clearInvocations(mFaceManager);
-        mKeyguardUpdateMonitor.requestFaceAuth(true);
+        mKeyguardUpdateMonitor.requestFaceAuth(true,
+                FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
         verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
                 anyBoolean());
     }
@@ -1499,10 +1510,13 @@
         keyguardIsVisible();
 
         mTestableLooper.processAllMessages();
+        clearInvocations(mUiEventLogger);
 
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
 
-        mKeyguardUpdateMonitor.requestFaceAuth(true);
+        mKeyguardUpdateMonitor.requestFaceAuth(true,
+                FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
+
         verify(mFaceManager).authenticate(any(),
                 mCancellationSignalCaptor.capture(),
                 mAuthenticationCallbackCaptor.capture(),
@@ -1594,7 +1608,7 @@
     }
 
     private void triggerSuccessfulFaceAuth() {
-        mKeyguardUpdateMonitor.requestFaceAuth(true);
+        mKeyguardUpdateMonitor.requestFaceAuth(true, FaceAuthApiRequestReason.UDFPS_POINTER_DOWN);
         verify(mFaceManager).authenticate(any(),
                 any(),
                 mAuthenticationCallbackCaptor.capture(),
@@ -1714,7 +1728,7 @@
                     mStatusBarStateController, mLockPatternUtils,
                     mAuthController, mTelephonyListenerManager,
                     mInteractionJankMonitor, mLatencyTracker, mActiveUnlockConfig,
-                    mKeyguardUpdateMonitorLogger);
+                    mKeyguardUpdateMonitorLogger, mUiEventLogger, () -> mSessionTracker);
             setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
         }