From 6c8bd65c605831b691cfedeeccaaed1f19725bf8 Mon Sep 17 00:00:00 2001
From: Pascal Muetschard <pmuetschard@google.com>
Date: Tue, 21 Nov 2023 17:25:56 +0100
Subject: [PATCH] Some code cleanup of InteractionJankMonitor.

- Move the CUJ constant related stuff to its own class
- Remove the Session class
- Separation of IJM and FT via event listener, breaking the dep loop
- Fix (unlikely) race problems in begin/cancel/end
- Trim out some unused stuff
- Remove some duplicated stuff (like config validation)
- Remove checks ensured by tests
- Fix a bunch of warnings
- Fix missing locks in debug overlay
- Remove the outdated DEBUG mechanism

Test: atest com.android.internal.jank
Flag: NA
Change-Id: I29b9da107313d4c07777ce50ce907c7516258807
---
 .../android/view/inputmethod/ImeTracker.java  |    6 +-
 core/java/com/android/internal/jank/Cuj.java  |  503 ++++++++
 .../android/internal/jank/FrameTracker.java   |  151 +--
 .../internal/jank/InteractionJankMonitor.java | 1112 ++++-------------
 .../jank/InteractionMonitorDebugOverlay.java  |   87 +-
 .../com/android/internal/jank/CujTest.java    |  156 +++
 .../internal/jank/FrameTrackerTest.java       |  128 +-
 .../jank/InteractionJankMonitorTest.java      |  230 +---
 .../wm/shell/back/BackAnimationRunner.java    |    6 +-
 .../common/InteractionJankMonitorUtils.java   |   17 +-
 .../OneHandedDisplayAreaOrganizer.java        |   11 +-
 .../SettingsJankMonitorTest.java              |    4 +-
 .../animation/DialogLaunchAnimator.kt         |    2 +-
 .../GhostedViewLaunchAnimatorController.kt    |    3 +-
 .../system/InteractionJankMonitorWrapper.java |   58 +-
 15 files changed, 1171 insertions(+), 1303 deletions(-)
 create mode 100644 core/java/com/android/internal/jank/Cuj.java
 create mode 100644 core/tests/coretests/src/com/android/internal/jank/CujTest.java

diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index d4cfd63492fc..661815853470 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -20,8 +20,8 @@ import static android.view.InsetsController.ANIMATION_TYPE_HIDE;
 import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
 
 import static com.android.internal.inputmethod.InputMethodDebug.softInputDisplayReasonToString;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_IME_INSETS_HIDE_ANIMATION;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_IME_INSETS_SHOW_ANIMATION;
+import static com.android.internal.jank.Cuj.CUJ_IME_INSETS_HIDE_ANIMATION;
+import static com.android.internal.jank.Cuj.CUJ_IME_INSETS_SHOW_ANIMATION;
 import static com.android.internal.util.LatencyTracker.ACTION_REQUEST_IME_HIDDEN;
 import static com.android.internal.util.LatencyTracker.ACTION_REQUEST_IME_SHOWN;
 
@@ -758,7 +758,7 @@ public interface ImeTracker {
          * A helper method to translate animation type to CUJ type for IME animations.
          *
          * @param animType the animation type.
-         * @return the integer in {@link com.android.internal.jank.InteractionJankMonitor.CujType},
+         * @return the integer in {@link com.android.internal.jank.Cuj.CujType},
          * or {@code -1} if the animation type is not supported for tracking yet.
          */
         private static int getImeInsetsCujFromAnimation(@AnimationType int animType) {
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
new file mode 100644
index 000000000000..f460233f0edd
--- /dev/null
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2023 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.internal.jank;
+
+import android.annotation.IntDef;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+
+/** @hide */
+public class Cuj {
+    @VisibleForTesting
+    public static final int MAX_LENGTH_OF_CUJ_NAME = 80;
+
+    // Every value must have a corresponding entry in CUJ_STATSD_INTERACTION_TYPE.
+    public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE = 0;
+    public static final int CUJ_NOTIFICATION_SHADE_SCROLL_FLING = 2;
+    public static final int CUJ_NOTIFICATION_SHADE_ROW_EXPAND = 3;
+    public static final int CUJ_NOTIFICATION_SHADE_ROW_SWIPE = 4;
+    public static final int CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE = 5;
+    public static final int CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE = 6;
+    public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS = 7;
+    public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON = 8;
+    public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME = 9;
+    public static final int CUJ_LAUNCHER_APP_CLOSE_TO_PIP = 10;
+    public static final int CUJ_LAUNCHER_QUICK_SWITCH = 11;
+    public static final int CUJ_NOTIFICATION_HEADS_UP_APPEAR = 12;
+    public static final int CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR = 13;
+    public static final int CUJ_NOTIFICATION_ADD = 14;
+    public static final int CUJ_NOTIFICATION_REMOVE = 15;
+    public static final int CUJ_NOTIFICATION_APP_START = 16;
+    public static final int CUJ_LOCKSCREEN_PASSWORD_APPEAR = 17;
+    public static final int CUJ_LOCKSCREEN_PATTERN_APPEAR = 18;
+    public static final int CUJ_LOCKSCREEN_PIN_APPEAR = 19;
+    public static final int CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR = 20;
+    public static final int CUJ_LOCKSCREEN_PATTERN_DISAPPEAR = 21;
+    public static final int CUJ_LOCKSCREEN_PIN_DISAPPEAR = 22;
+    public static final int CUJ_LOCKSCREEN_TRANSITION_FROM_AOD = 23;
+    public static final int CUJ_LOCKSCREEN_TRANSITION_TO_AOD = 24;
+    public static final int CUJ_LAUNCHER_OPEN_ALL_APPS = 25;
+    public static final int CUJ_LAUNCHER_ALL_APPS_SCROLL = 26;
+    public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET = 27;
+    public static final int CUJ_SETTINGS_PAGE_SCROLL = 28;
+    public static final int CUJ_LOCKSCREEN_UNLOCK_ANIMATION = 29;
+    public static final int CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON = 30;
+    public static final int CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER = 31;
+    public static final int CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE = 32;
+    public static final int CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON = 33;
+    public static final int CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP = 34;
+    public static final int CUJ_PIP_TRANSITION = 35;
+    public static final int CUJ_WALLPAPER_TRANSITION = 36;
+    public static final int CUJ_USER_SWITCH = 37;
+    public static final int CUJ_SPLASHSCREEN_AVD = 38;
+    public static final int CUJ_SPLASHSCREEN_EXIT_ANIM = 39;
+    public static final int CUJ_SCREEN_OFF = 40;
+    public static final int CUJ_SCREEN_OFF_SHOW_AOD = 41;
+    public static final int CUJ_ONE_HANDED_ENTER_TRANSITION = 42;
+    public static final int CUJ_ONE_HANDED_EXIT_TRANSITION = 43;
+    public static final int CUJ_UNFOLD_ANIM = 44;
+    public static final int CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS = 45;
+    public static final int CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS = 46;
+    public static final int CUJ_SUW_LOADING_TO_NEXT_FLOW = 47;
+    public static final int CUJ_SUW_LOADING_SCREEN_FOR_STATUS = 48;
+    public static final int CUJ_SPLIT_SCREEN_ENTER = 49;
+    public static final int CUJ_SPLIT_SCREEN_EXIT = 50;
+    public static final int CUJ_LOCKSCREEN_LAUNCH_CAMERA = 51; // reserved.
+    public static final int CUJ_SPLIT_SCREEN_RESIZE = 52;
+    public static final int CUJ_SETTINGS_SLIDER = 53;
+    public static final int CUJ_TAKE_SCREENSHOT = 54;
+    public static final int CUJ_VOLUME_CONTROL = 55;
+    public static final int CUJ_BIOMETRIC_PROMPT_TRANSITION = 56;
+    public static final int CUJ_SETTINGS_TOGGLE = 57;
+    public static final int CUJ_SHADE_DIALOG_OPEN = 58;
+    public static final int CUJ_USER_DIALOG_OPEN = 59;
+    public static final int CUJ_TASKBAR_EXPAND = 60;
+    public static final int CUJ_TASKBAR_COLLAPSE = 61;
+    public static final int CUJ_SHADE_CLEAR_ALL = 62;
+    public static final int CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION = 63;
+    public static final int CUJ_LOCKSCREEN_OCCLUSION = 64;
+    public static final int CUJ_RECENTS_SCROLLING = 65;
+    public static final int CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS = 66;
+    public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE = 67;
+    public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME = 68;
+    public static final int CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION = 70;
+    public static final int CUJ_LAUNCHER_OPEN_SEARCH_RESULT = 71;
+    // 72 - 77 are reserved for b/281564325.
+
+    /**
+     * In some cases when we do not have any end-target, we play a simple slide-down animation.
+     * eg: Open an app from Overview/Task switcher such that there is no home-screen icon.
+     * eg: Exit the app using back gesture.
+     */
+    public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK = 78;
+    public static final int CUJ_IME_INSETS_SHOW_ANIMATION = 80;
+    public static final int CUJ_IME_INSETS_HIDE_ANIMATION = 81;
+
+    public static final int CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER = 82;
+
+    public static final int CUJ_LAUNCHER_UNFOLD_ANIM = 83;
+
+    public static final int CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY = 84;
+    public static final int CUJ_PREDICTIVE_BACK_CROSS_TASK = 85;
+    public static final int CUJ_PREDICTIVE_BACK_HOME = 86;
+
+    // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
+    @VisibleForTesting
+    static final int LAST_CUJ = CUJ_PREDICTIVE_BACK_HOME;
+
+    /** @hide */
+    @IntDef({
+            CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
+            CUJ_NOTIFICATION_SHADE_SCROLL_FLING,
+            CUJ_NOTIFICATION_SHADE_ROW_EXPAND,
+            CUJ_NOTIFICATION_SHADE_ROW_SWIPE,
+            CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
+            CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE,
+            CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS,
+            CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON,
+            CUJ_LAUNCHER_APP_CLOSE_TO_HOME,
+            CUJ_LAUNCHER_APP_CLOSE_TO_PIP,
+            CUJ_LAUNCHER_QUICK_SWITCH,
+            CUJ_NOTIFICATION_HEADS_UP_APPEAR,
+            CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR,
+            CUJ_NOTIFICATION_ADD,
+            CUJ_NOTIFICATION_REMOVE,
+            CUJ_NOTIFICATION_APP_START,
+            CUJ_LOCKSCREEN_PASSWORD_APPEAR,
+            CUJ_LOCKSCREEN_PATTERN_APPEAR,
+            CUJ_LOCKSCREEN_PIN_APPEAR,
+            CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR,
+            CUJ_LOCKSCREEN_PATTERN_DISAPPEAR,
+            CUJ_LOCKSCREEN_PIN_DISAPPEAR,
+            CUJ_LOCKSCREEN_TRANSITION_FROM_AOD,
+            CUJ_LOCKSCREEN_TRANSITION_TO_AOD,
+            CUJ_LAUNCHER_OPEN_ALL_APPS,
+            CUJ_LAUNCHER_ALL_APPS_SCROLL,
+            CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET,
+            CUJ_SETTINGS_PAGE_SCROLL,
+            CUJ_LOCKSCREEN_UNLOCK_ANIMATION,
+            CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON,
+            CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER,
+            CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE,
+            CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON,
+            CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
+            CUJ_PIP_TRANSITION,
+            CUJ_WALLPAPER_TRANSITION,
+            CUJ_USER_SWITCH,
+            CUJ_SPLASHSCREEN_AVD,
+            CUJ_SPLASHSCREEN_EXIT_ANIM,
+            CUJ_SCREEN_OFF,
+            CUJ_SCREEN_OFF_SHOW_AOD,
+            CUJ_ONE_HANDED_ENTER_TRANSITION,
+            CUJ_ONE_HANDED_EXIT_TRANSITION,
+            CUJ_UNFOLD_ANIM,
+            CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS,
+            CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS,
+            CUJ_SUW_LOADING_TO_NEXT_FLOW,
+            CUJ_SUW_LOADING_SCREEN_FOR_STATUS,
+            CUJ_SPLIT_SCREEN_ENTER,
+            CUJ_SPLIT_SCREEN_EXIT,
+            CUJ_LOCKSCREEN_LAUNCH_CAMERA,
+            CUJ_SPLIT_SCREEN_RESIZE,
+            CUJ_SETTINGS_SLIDER,
+            CUJ_TAKE_SCREENSHOT,
+            CUJ_VOLUME_CONTROL,
+            CUJ_BIOMETRIC_PROMPT_TRANSITION,
+            CUJ_SETTINGS_TOGGLE,
+            CUJ_SHADE_DIALOG_OPEN,
+            CUJ_USER_DIALOG_OPEN,
+            CUJ_TASKBAR_EXPAND,
+            CUJ_TASKBAR_COLLAPSE,
+            CUJ_SHADE_CLEAR_ALL,
+            CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION,
+            CUJ_LOCKSCREEN_OCCLUSION,
+            CUJ_RECENTS_SCROLLING,
+            CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS,
+            CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE,
+            CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
+            CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION,
+            CUJ_LAUNCHER_OPEN_SEARCH_RESULT,
+            CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK,
+            CUJ_IME_INSETS_SHOW_ANIMATION,
+            CUJ_IME_INSETS_HIDE_ANIMATION,
+            CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER,
+            CUJ_LAUNCHER_UNFOLD_ANIM,
+            CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY,
+            CUJ_PREDICTIVE_BACK_CROSS_TASK,
+            CUJ_PREDICTIVE_BACK_HOME,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CujType {
+    }
+
+    private static final int NO_STATSD_LOGGING = -1;
+
+    // Used to convert CujType to InteractionType enum value for statsd logging.
+    // Use NO_STATSD_LOGGING in case the measurement for a given CUJ should not be logged to statsd.
+    private static final int[] CUJ_TO_STATSD_INTERACTION_TYPE = new int[LAST_CUJ + 1];
+    static {
+        Arrays.fill(CUJ_TO_STATSD_INTERACTION_TYPE, NO_STATSD_LOGGING);
+
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_SCROLL_FLING] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_SCROLL_FLING;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_ROW_EXPAND] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_EXPAND;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_ROW_SWIPE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_SWIPE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_QS_EXPAND_COLLAPSE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_QS_SCROLL_SWIPE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_RECENTS;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_ICON;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_HOME] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_PIP] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_PIP;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_QUICK_SWITCH] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_HEADS_UP_APPEAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_DISAPPEAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_ADD] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_ADD;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_REMOVE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_REMOVE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_APP_START] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PASSWORD_APPEAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_APPEAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PATTERN_APPEAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PATTERN_APPEAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PIN_APPEAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PIN_APPEAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_DISAPPEAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PATTERN_DISAPPEAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PATTERN_DISAPPEAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PIN_DISAPPEAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PIN_DISAPPEAR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_TRANSITION_FROM_AOD] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_TRANSITION_FROM_AOD;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_TRANSITION_TO_AOD] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_TRANSITION_TO_AOD;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_OPEN_ALL_APPS] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_ALL_APPS;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_ALL_APPS_SCROLL] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_WIDGET;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SETTINGS_PAGE_SCROLL] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_PAGE_SCROLL;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_UNLOCK_ANIMATION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_UNLOCK_ANIMATION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PIP_TRANSITION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PIP_TRANSITION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_USER_SWITCH] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLASHSCREEN_AVD] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_AVD;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLASHSCREEN_EXIT_ANIM] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_EXIT_ANIM;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SCREEN_OFF] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SCREEN_OFF_SHOW_AOD] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF_SHOW_AOD;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_ONE_HANDED_ENTER_TRANSITION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_ENTER_TRANSITION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_ONE_HANDED_EXIT_TRANSITION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_EXIT_TRANSITION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_UNFOLD_ANIM] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__UNFOLD_ANIM;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SUW_LOADING_TO_NEXT_FLOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_NEXT_FLOW;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SUW_LOADING_SCREEN_FOR_STATUS] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_SCREEN_FOR_STATUS;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_ENTER] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_ENTER;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_EXIT] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_EXIT;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_LAUNCH_CAMERA] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_RESIZE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_RESIZE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SETTINGS_SLIDER] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_SLIDER;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_TAKE_SCREENSHOT] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TAKE_SCREENSHOT;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_VOLUME_CONTROL] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__VOLUME_CONTROL;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_BIOMETRIC_PROMPT_TRANSITION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BIOMETRIC_PROMPT_TRANSITION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SETTINGS_TOGGLE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_TOGGLE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_DIALOG_OPEN] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_USER_DIALOG_OPEN] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_TASKBAR_EXPAND] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_TASKBAR_COLLAPSE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_CLEAR_ALL] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNLOCK_ENTRANCE_ANIMATION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_OCCLUSION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_OCCLUSION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_RECENTS_SCROLLING] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__RECENTS_SCROLLING;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_CLOCK_MOVE_ANIMATION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_OPEN_SEARCH_RESULT] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_SEARCH_RESULT;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_SHOW_ANIMATION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_SHOW_ANIMATION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_HIDE_ANIMATION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_HIDE_ANIMATION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_DOUBLE_TAP_DIVIDER;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_UNFOLD_ANIM] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNFOLD_ANIM;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_ACTIVITY;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_CROSS_TASK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_TASK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_HOME] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_HOME;
+    }
+
+    private Cuj() {
+    }
+
+    /**
+     * A helper method to translate CUJ type to CUJ name.
+     *
+     * @param cujType the cuj type defined in this file
+     * @return the name of the cuj type
+     */
+    public static String getNameOfCuj(int cujType) {
+        // Please note:
+        // 1. The length of the returned string shouldn't exceed MAX_LENGTH_OF_CUJ_NAME.
+        // 2. The returned string should be the same with the name defined in atoms.proto.
+        switch (cujType) {
+            case CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE:
+                return "NOTIFICATION_SHADE_EXPAND_COLLAPSE";
+            case CUJ_NOTIFICATION_SHADE_SCROLL_FLING:
+                return "NOTIFICATION_SHADE_SCROLL_FLING";
+            case CUJ_NOTIFICATION_SHADE_ROW_EXPAND:
+                return "NOTIFICATION_SHADE_ROW_EXPAND";
+            case CUJ_NOTIFICATION_SHADE_ROW_SWIPE:
+                return "NOTIFICATION_SHADE_ROW_SWIPE";
+            case CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE:
+                return "NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE";
+            case CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE:
+                return "NOTIFICATION_SHADE_QS_SCROLL_SWIPE";
+            case CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS:
+                return "LAUNCHER_APP_LAUNCH_FROM_RECENTS";
+            case CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON:
+                return "LAUNCHER_APP_LAUNCH_FROM_ICON";
+            case CUJ_LAUNCHER_APP_CLOSE_TO_HOME:
+                return "LAUNCHER_APP_CLOSE_TO_HOME";
+            case CUJ_LAUNCHER_APP_CLOSE_TO_PIP:
+                return "LAUNCHER_APP_CLOSE_TO_PIP";
+            case CUJ_LAUNCHER_QUICK_SWITCH:
+                return "LAUNCHER_QUICK_SWITCH";
+            case CUJ_NOTIFICATION_HEADS_UP_APPEAR:
+                return "NOTIFICATION_HEADS_UP_APPEAR";
+            case CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR:
+                return "NOTIFICATION_HEADS_UP_DISAPPEAR";
+            case CUJ_NOTIFICATION_ADD:
+                return "NOTIFICATION_ADD";
+            case CUJ_NOTIFICATION_REMOVE:
+                return "NOTIFICATION_REMOVE";
+            case CUJ_NOTIFICATION_APP_START:
+                return "NOTIFICATION_APP_START";
+            case CUJ_LOCKSCREEN_PASSWORD_APPEAR:
+                return "LOCKSCREEN_PASSWORD_APPEAR";
+            case CUJ_LOCKSCREEN_PATTERN_APPEAR:
+                return "LOCKSCREEN_PATTERN_APPEAR";
+            case CUJ_LOCKSCREEN_PIN_APPEAR:
+                return "LOCKSCREEN_PIN_APPEAR";
+            case CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR:
+                return "LOCKSCREEN_PASSWORD_DISAPPEAR";
+            case CUJ_LOCKSCREEN_PATTERN_DISAPPEAR:
+                return "LOCKSCREEN_PATTERN_DISAPPEAR";
+            case CUJ_LOCKSCREEN_PIN_DISAPPEAR:
+                return "LOCKSCREEN_PIN_DISAPPEAR";
+            case CUJ_LOCKSCREEN_TRANSITION_FROM_AOD:
+                return "LOCKSCREEN_TRANSITION_FROM_AOD";
+            case CUJ_LOCKSCREEN_TRANSITION_TO_AOD:
+                return "LOCKSCREEN_TRANSITION_TO_AOD";
+            case CUJ_LAUNCHER_OPEN_ALL_APPS :
+                return "LAUNCHER_OPEN_ALL_APPS";
+            case CUJ_LAUNCHER_ALL_APPS_SCROLL:
+                return "LAUNCHER_ALL_APPS_SCROLL";
+            case CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET:
+                return "LAUNCHER_APP_LAUNCH_FROM_WIDGET";
+            case CUJ_SETTINGS_PAGE_SCROLL:
+                return "SETTINGS_PAGE_SCROLL";
+            case CUJ_LOCKSCREEN_UNLOCK_ANIMATION:
+                return "LOCKSCREEN_UNLOCK_ANIMATION";
+            case CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON:
+                return "SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON";
+            case CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER:
+                return "SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER";
+            case CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE:
+                return "SHADE_APP_LAUNCH_FROM_QS_TILE";
+            case CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON:
+                return "SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON";
+            case CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP:
+                return "STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP";
+            case CUJ_PIP_TRANSITION:
+                return "PIP_TRANSITION";
+            case CUJ_WALLPAPER_TRANSITION:
+                return "WALLPAPER_TRANSITION";
+            case CUJ_USER_SWITCH:
+                return "USER_SWITCH";
+            case CUJ_SPLASHSCREEN_AVD:
+                return "SPLASHSCREEN_AVD";
+            case CUJ_SPLASHSCREEN_EXIT_ANIM:
+                return "SPLASHSCREEN_EXIT_ANIM";
+            case CUJ_SCREEN_OFF:
+                return "SCREEN_OFF";
+            case CUJ_SCREEN_OFF_SHOW_AOD:
+                return "SCREEN_OFF_SHOW_AOD";
+            case CUJ_ONE_HANDED_ENTER_TRANSITION:
+                return "ONE_HANDED_ENTER_TRANSITION";
+            case CUJ_ONE_HANDED_EXIT_TRANSITION:
+                return "ONE_HANDED_EXIT_TRANSITION";
+            case CUJ_UNFOLD_ANIM:
+                return "UNFOLD_ANIM";
+            case CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS:
+                return "SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS";
+            case CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS:
+                return "SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS";
+            case CUJ_SUW_LOADING_TO_NEXT_FLOW:
+                return "SUW_LOADING_TO_NEXT_FLOW";
+            case CUJ_SUW_LOADING_SCREEN_FOR_STATUS:
+                return "SUW_LOADING_SCREEN_FOR_STATUS";
+            case CUJ_SPLIT_SCREEN_ENTER:
+                return "SPLIT_SCREEN_ENTER";
+            case CUJ_SPLIT_SCREEN_EXIT:
+                return "SPLIT_SCREEN_EXIT";
+            case CUJ_LOCKSCREEN_LAUNCH_CAMERA:
+                return "LOCKSCREEN_LAUNCH_CAMERA";
+            case CUJ_SPLIT_SCREEN_RESIZE:
+                return "SPLIT_SCREEN_RESIZE";
+            case CUJ_SETTINGS_SLIDER:
+                return "SETTINGS_SLIDER";
+            case CUJ_TAKE_SCREENSHOT:
+                return "TAKE_SCREENSHOT";
+            case CUJ_VOLUME_CONTROL:
+                return "VOLUME_CONTROL";
+            case CUJ_BIOMETRIC_PROMPT_TRANSITION:
+                return "BIOMETRIC_PROMPT_TRANSITION";
+            case CUJ_SETTINGS_TOGGLE:
+                return "SETTINGS_TOGGLE";
+            case CUJ_SHADE_DIALOG_OPEN:
+                return "SHADE_DIALOG_OPEN";
+            case CUJ_USER_DIALOG_OPEN:
+                return "USER_DIALOG_OPEN";
+            case CUJ_TASKBAR_EXPAND:
+                return "TASKBAR_EXPAND";
+            case CUJ_TASKBAR_COLLAPSE:
+                return "TASKBAR_COLLAPSE";
+            case CUJ_SHADE_CLEAR_ALL:
+                return "SHADE_CLEAR_ALL";
+            case CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION:
+                return "LAUNCHER_UNLOCK_ENTRANCE_ANIMATION";
+            case CUJ_LOCKSCREEN_OCCLUSION:
+                return "LOCKSCREEN_OCCLUSION";
+            case CUJ_RECENTS_SCROLLING:
+                return "RECENTS_SCROLLING";
+            case CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS:
+                return "LAUNCHER_APP_SWIPE_TO_RECENTS";
+            case CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE:
+                return "LAUNCHER_CLOSE_ALL_APPS_SWIPE";
+            case CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME:
+                return "LAUNCHER_CLOSE_ALL_APPS_TO_HOME";
+            case CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION:
+                return "LOCKSCREEN_CLOCK_MOVE_ANIMATION";
+            case CUJ_LAUNCHER_OPEN_SEARCH_RESULT:
+                return "LAUNCHER_OPEN_SEARCH_RESULT";
+            case CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK:
+                return "LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK";
+            case CUJ_IME_INSETS_SHOW_ANIMATION:
+                return "IME_INSETS_SHOW_ANIMATION";
+            case CUJ_IME_INSETS_HIDE_ANIMATION:
+                return "IME_INSETS_HIDE_ANIMATION";
+            case CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER:
+                return "SPLIT_SCREEN_DOUBLE_TAP_DIVIDER";
+            case CUJ_LAUNCHER_UNFOLD_ANIM:
+                return "LAUNCHER_UNFOLD_ANIM";
+            case CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY:
+                return "PREDICTIVE_BACK_CROSS_ACTIVITY";
+            case CUJ_PREDICTIVE_BACK_CROSS_TASK:
+                return "PREDICTIVE_BACK_CROSS_TASK";
+            case CUJ_PREDICTIVE_BACK_HOME:
+                return "PREDICTIVE_BACK_HOME";
+        }
+        return "UNKNOWN";
+    }
+
+    public static int getStatsdInteractionType(@CujType int cujType) {
+        return CUJ_TO_STATSD_INTERACTION_TYPE[cujType];
+    }
+
+    /** Returns whether the measurements for the given CUJ should be written to statsd. */
+    public static boolean logToStatsd(@CujType int cujType) {
+        return getStatsdInteractionType(cujType) != NO_STATSD_LOGGING;
+    }
+
+    /**
+     * A helper method to translate interaction type to CUJ name.
+     *
+     * @param interactionType the interaction type defined in AtomsProto.java
+     * @return the name of the interaction type
+     */
+    public static String getNameOfInteraction(int interactionType) {
+        // There is an offset amount of 1 between cujType and interactionType.
+        return Cuj.getNameOfCuj(getCujTypeFromInteraction(interactionType));
+    }
+
+    /**
+     * A helper method to translate interaction type to CUJ type.
+     *
+     * @param interactionType the interaction type defined in AtomsProto.java
+     * @return the integer in {@link Cuj.CujType}
+     */
+    private static int getCujTypeFromInteraction(int interactionType) {
+        return interactionType - 1;
+    }
+}
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index c83452d88290..86729f74cd85 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -53,7 +53,6 @@ import android.view.WindowCallbacks;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.DisplayRefreshRate.RefreshRate;
 import com.android.internal.jank.InteractionJankMonitor.Configuration;
-import com.android.internal.jank.InteractionJankMonitor.Session;
 import com.android.internal.util.FrameworkStatsLog;
 
 import java.lang.annotation.Retention;
@@ -67,7 +66,6 @@ import java.util.concurrent.TimeUnit;
 public class FrameTracker extends SurfaceControl.OnJankDataListener
         implements HardwareRendererObserver.OnFrameMetricsAvailableListener {
     private static final String TAG = "FrameTracker";
-    private static final boolean DEBUG = false;
 
     private static final long INVALID_ID = -1;
     public static final int NANOS_IN_MILLISECOND = 1_000_000;
@@ -93,20 +91,19 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
             REASON_CANCEL_NORMAL,
             REASON_CANCEL_NOT_BEGUN,
             REASON_CANCEL_SAME_VSYNC,
+            REASON_CANCEL_TIMEOUT,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Reasons {
     }
 
-    @VisibleForTesting
-    public final InteractionJankMonitor mMonitor;
     private final HardwareRendererObserver mObserver;
     private final int mTraceThresholdMissedFrames;
     private final int mTraceThresholdFrameTimeMillis;
     private final ThreadedRendererWrapper mRendererWrapper;
     private final FrameMetricsWrapper mMetricsWrapper;
     private final SparseArray<JankInfo> mJankInfos = new SparseArray<>();
-    private final Session mSession;
+    private final Configuration mConfig;
     private final ViewRootWrapper mViewRoot;
     private final SurfaceControlWrapper mSurfaceControlWrapper;
     private final int mDisplayId;
@@ -197,19 +194,18 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
         }
     }
 
-    public FrameTracker(@NonNull InteractionJankMonitor monitor, @NonNull Session session,
-            @NonNull Handler handler, @Nullable ThreadedRendererWrapper renderer,
+    public FrameTracker(@NonNull Configuration config,
+            @Nullable ThreadedRendererWrapper renderer,
             @Nullable ViewRootWrapper viewRootWrapper,
             @NonNull SurfaceControlWrapper surfaceControlWrapper,
             @NonNull ChoreographerWrapper choreographer,
             @Nullable FrameMetricsWrapper metrics,
             @NonNull StatsLogWrapper statsLog,
             int traceThresholdMissedFrames, int traceThresholdFrameTimeMillis,
-            @Nullable FrameTrackerListener listener, @NonNull Configuration config) {
-        mMonitor = monitor;
+            @Nullable FrameTrackerListener listener) {
         mSurfaceOnly = config.isSurfaceOnly();
-        mSession = session;
-        mHandler = handler;
+        mConfig = config;
+        mHandler = config.getHandler();
         mChoreographer = choreographer;
         mSurfaceControlWrapper = surfaceControlWrapper;
         mStatsLog = statsLog;
@@ -222,7 +218,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
         mObserver = mSurfaceOnly
                 ? null
                 : new HardwareRendererObserver(this, mMetricsWrapper.getTiming(),
-                        handler, /* waitForPresentTime= */ false);
+                        mHandler, /* waitForPresentTime= */ false);
 
         mTraceThresholdMissedFrames = traceThresholdMissedFrames;
         mTraceThresholdFrameTimeMillis = traceThresholdFrameTimeMillis;
@@ -242,7 +238,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
             mSurfaceChangedCallback = new ViewRootImpl.SurfaceChangedCallback() {
                 @Override
                 public void surfaceCreated(SurfaceControl.Transaction t) {
-                    getHandler().runWithScissors(() -> {
+                    mHandler.runWithScissors(() -> {
                         if (mSurfaceControl == null) {
                             mSurfaceControl = mViewRoot.getSurfaceControl();
                             if (mBeginVsyncId != INVALID_ID) {
@@ -262,13 +258,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
 
                     // Wait a while to give the system a chance for the remaining
                     // frames to arrive, then force finish the session.
-                    getHandler().postDelayed(() -> {
-                        if (DEBUG) {
-                            Log.d(TAG, "surfaceDestroyed: " + mSession.getName()
-                                    + ", finalized=" + mMetricsFinalized
-                                    + ", info=" + mJankInfos.size()
-                                    + ", vsync=" + mBeginVsyncId);
-                        }
+                    mHandler.postDelayed(() -> {
                         if (!mMetricsFinalized) {
                             end(REASON_END_SURFACE_DESTROYED);
                             finish();
@@ -282,11 +272,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
         }
     }
 
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public Handler getHandler() {
-        return mHandler;
-    }
-
     /**
      * Begin a trace session of the CUJ.
      */
@@ -300,10 +285,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
             mBeginVsyncId = mDeferMonitoring ? currentVsync + 1 : currentVsync;
         }
         if (mSurfaceControl != null) {
-            if (DEBUG) {
-                Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId
-                        + ", defer=" + mDeferMonitoring + ", current=" + currentVsync);
-            }
             if (mDeferMonitoring && currentVsync < mBeginVsyncId) {
                 markEvent("FT#deferMonitoring", 0);
                 // Normal case, we begin the instrument from the very beginning,
@@ -314,11 +295,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                 // there is no need to skip the frame where the begin invocation happens.
                 beginInternal();
             }
-        } else {
-            if (DEBUG) {
-                Log.d(TAG, "begin: defer beginning since the surface is not ready for CUJ="
-                        + mSession.getName());
-            }
         }
     }
 
@@ -336,8 +312,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
             return;
         }
         mTracingStarted = true;
-        Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, mSession.getName(), mSession.getName(),
-                (int) mBeginVsyncId);
+        String name = mConfig.getSessionName();
+        Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, name, name, (int) mBeginVsyncId);
         markEvent("FT#beginVsync", mBeginVsyncId);
         markEvent("FT#layerId", mSurfaceControl.getLayerId());
         mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
@@ -361,15 +337,10 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
         } else if (mEndVsyncId <= mBeginVsyncId) {
             return cancel(REASON_CANCEL_SAME_VSYNC);
         } else {
-            if (DEBUG) {
-                Log.d(TAG, "end: " + mSession.getName()
-                        + ", end=" + mEndVsyncId + ", reason=" + reason);
-            }
+            final String name = mConfig.getSessionName();
             markEvent("FT#end", reason);
             markEvent("FT#endVsync", mEndVsyncId);
-            Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, mSession.getName(),
-                    (int) mBeginVsyncId);
-            mSession.setReason(reason);
+            Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, name, (int) mBeginVsyncId);
 
             // We don't remove observer here,
             // will remove it when all the frame metrics in this duration are called back.
@@ -395,16 +366,16 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                         mFlushAttempts++;
                     } else {
                         mWaitForFinishTimedOut = () -> {
-                            Log.e(TAG, "force finish cuj, time out: " + mSession.getName());
+                            Log.e(TAG, "force finish cuj, time out: " + name);
                             finish();
                         };
                         delay = TimeUnit.SECONDS.toMillis(10);
                     }
-                    getHandler().postDelayed(mWaitForFinishTimedOut, delay);
+                    mHandler.postDelayed(mWaitForFinishTimedOut, delay);
                 }
             };
-            getHandler().postDelayed(mWaitForFinishTimedOut, FLUSH_DELAY_MILLISECOND);
-            notifyCujEvent(ACTION_SESSION_END);
+            mHandler.postDelayed(mWaitForFinishTimedOut, FLUSH_DELAY_MILLISECOND);
+            notifyCujEvent(ACTION_SESSION_END, reason);
             return true;
         }
     }
@@ -421,22 +392,16 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
         markEvent("FT#cancel", reason);
         // We don't need to end the trace section if it has never begun.
         if (mTracingStarted) {
-            Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, mSession.getName(),
-                    (int) mBeginVsyncId);
+            Trace.asyncTraceForTrackEnd(
+                    Trace.TRACE_TAG_APP, mConfig.getSessionName(), (int) mBeginVsyncId);
         }
 
         // Always remove the observers in cancel call to avoid leakage.
         removeObservers();
 
-        if (DEBUG) {
-            Log.d(TAG, "cancel: " + mSession.getName() + ", begin=" + mBeginVsyncId
-                    + ", end=" + mEndVsyncId + ", reason=" + reason);
-        }
-
-        mSession.setReason(reason);
         // Notify the listener the session has been cancelled.
         // We don't notify the listeners if the session never begun.
-        notifyCujEvent(ACTION_SESSION_CANCEL);
+        notifyCujEvent(ACTION_SESSION_CANCEL, reason);
         return true;
     }
 
@@ -455,13 +420,13 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                         "The length of the trace event description <%s> exceeds %d",
                         event, MAX_LENGTH_EVENT_DESC));
             }
-            Trace.instantForTrack(Trace.TRACE_TAG_APP, mSession.getName(), event);
+            Trace.instantForTrack(Trace.TRACE_TAG_APP, mConfig.getSessionName(), event);
         }
     }
 
-    private void notifyCujEvent(String action) {
+    private void notifyCujEvent(String action, @Reasons int reason) {
         if (mListener == null) return;
-        mListener.onCujEvents(mSession, action);
+        mListener.onCujEvents(this, action, reason);
     }
 
     @Override
@@ -496,7 +461,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
      */
     @VisibleForTesting
     public void postCallback(Runnable callback) {
-        getHandler().post(callback);
+        mHandler.post(callback);
     }
 
     @Nullable
@@ -587,13 +552,15 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
         if (mMetricsFinalized || mCancelled) return;
         mMetricsFinalized = true;
 
-        getHandler().removeCallbacks(mWaitForFinishTimedOut);
+        mHandler.removeCallbacks(mWaitForFinishTimedOut);
         mWaitForFinishTimedOut = null;
         markEvent("FT#finish", mJankInfos.size());
 
         // The tracing has been ended, remove the observer, see if need to trigger perfetto.
         removeObservers();
 
+        final String name = mConfig.getSessionName();
+
         int totalFramesCount = 0;
         long maxFrameTimeNanos = 0;
         int missedFramesCount = 0;
@@ -616,7 +583,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                 totalFramesCount++;
                 boolean missedFrame = false;
                 if ((info.jankType & JANK_APP_DEADLINE_MISSED) != 0) {
-                    Log.w(TAG, "Missed App frame:" + info + ", CUJ=" + mSession.getName());
+                    Log.w(TAG, "Missed App frame:" + info + ", CUJ=" + name);
                     missedAppFramesCount++;
                     missedFrame = true;
                 }
@@ -625,7 +592,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                         || (info.jankType & JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED) != 0
                         || (info.jankType & SURFACE_FLINGER_SCHEDULING) != 0
                         || (info.jankType & PREDICTION_ERROR) != 0) {
-                    Log.w(TAG, "Missed SF frame:" + info + ", CUJ=" + mSession.getName());
+                    Log.w(TAG, "Missed SF frame:" + info + ", CUJ=" + name);
                     missedSfFramesCount++;
                     missedFrame = true;
                 }
@@ -646,7 +613,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                 if (!mSurfaceOnly && !info.hwuiCallbackFired) {
                     markEvent("FT#MissedHWUICallback", info.frameVsyncId);
                     Log.w(TAG, "Missing HWUI jank callback for vsyncId: " + info.frameVsyncId
-                            + ", CUJ=" + mSession.getName());
+                            + ", CUJ=" + name);
                 }
             }
             if (!mSurfaceOnly && info.hwuiCallbackFired) {
@@ -654,7 +621,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                 if (!info.surfaceControlCallbackFired) {
                     markEvent("FT#MissedSFCallback", info.frameVsyncId);
                     Log.w(TAG, "Missing SF jank callback for vsyncId: " + info.frameVsyncId
-                            + ", CUJ=" + mSession.getName());
+                            + ", CUJ=" + name);
                 }
             }
         }
@@ -662,29 +629,26 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                 maxSuccessiveMissedFramesCount, successiveMissedFramesCount);
 
         // Log the frame stats as counters to make them easily accessible in traces.
-        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#missedFrames",
-                missedFramesCount);
-        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#missedAppFrames",
-                missedAppFramesCount);
-        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#missedSfFrames",
-                missedSfFramesCount);
-        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#totalFrames",
-                totalFramesCount);
-        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#maxFrameTimeMillis",
+        Trace.traceCounter(Trace.TRACE_TAG_APP, name + "#missedFrames", missedFramesCount);
+        Trace.traceCounter(Trace.TRACE_TAG_APP, name + "#missedAppFrames", missedAppFramesCount);
+        Trace.traceCounter(Trace.TRACE_TAG_APP, name + "#missedSfFrames", missedSfFramesCount);
+        Trace.traceCounter(Trace.TRACE_TAG_APP, name + "#totalFrames", totalFramesCount);
+        Trace.traceCounter(Trace.TRACE_TAG_APP, name + "#maxFrameTimeMillis",
                 (int) (maxFrameTimeNanos / NANOS_IN_MILLISECOND));
-        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#maxSuccessiveMissedFrames",
+        Trace.traceCounter(Trace.TRACE_TAG_APP, name + "#maxSuccessiveMissedFrames",
                 maxSuccessiveMissedFramesCount);
 
         // Trigger perfetto if necessary.
-        if (shouldTriggerPerfetto(missedFramesCount, (int) maxFrameTimeNanos)) {
-            triggerPerfetto();
+        if (mListener != null
+                && shouldTriggerPerfetto(missedFramesCount, (int) maxFrameTimeNanos)) {
+            mListener.triggerPerfetto(mConfig);
         }
-        if (mSession.logToStatsd()) {
+        if (mConfig.logToStatsd()) {
             mStatsLog.write(
                     FrameworkStatsLog.UI_INTERACTION_FRAME_INFO_REPORTED,
                     mDisplayId,
                     refreshRate,
-                    mSession.getStatsdInteractionType(),
+                    mConfig.getStatsdInteractionType(),
                     totalFramesCount,
                     missedFramesCount,
                     maxFrameTimeNanos, /* will be 0 if mSurfaceOnly == true */
@@ -692,16 +656,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                     missedAppFramesCount,
                     maxSuccessiveMissedFramesCount);
         }
-        if (DEBUG) {
-            Log.i(TAG, "finish: CUJ=" + mSession.getName()
-                    + " (" + mBeginVsyncId + "," + mEndVsyncId + ")"
-                    + " totalFrames=" + totalFramesCount
-                    + " missedAppFrames=" + missedAppFramesCount
-                    + " missedSfFrames=" + missedSfFramesCount
-                    + " missedFrames=" + missedFramesCount
-                    + " maxFrameTimeMillis=" + maxFrameTimeNanos / NANOS_IN_MILLISECOND
-                    + " maxSuccessiveMissedFramesCount=" + maxSuccessiveMissedFramesCount);
-        }
     }
 
     ThreadedRendererWrapper getThreadedRenderer() {
@@ -736,13 +690,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
         }
     }
 
-    /**
-     * Trigger the prefetto daemon.
-     */
-    public void triggerPerfetto() {
-        mMonitor.trigger(mSession);
-    }
-
     /**
      * A wrapper class that we can spy FrameMetrics (a final class) in unit tests.
      */
@@ -895,9 +842,17 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
         /**
          * Notify that the CUJ session was created.
          *
-         * @param session the CUJ session
+         * @param tracker the tracker
          * @param action the specific action
+         * @param reason the reason for the action
+         */
+        void onCujEvents(FrameTracker tracker, String action, @Reasons int reason);
+
+        /**
+         * Notify that the Perfetto trace should be triggered.
+         *
+         * @param config the tracker configuration
          */
-        void onCujEvents(Session session, String action);
+        void triggerPerfetto(Configuration config);
     }
 }
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index e6b036cfaa19..8b1879f5225d 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -23,89 +23,9 @@ import static android.provider.DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR;
 import static com.android.internal.jank.FrameTracker.REASON_CANCEL_NORMAL;
 import static com.android.internal.jank.FrameTracker.REASON_CANCEL_TIMEOUT;
 import static com.android.internal.jank.FrameTracker.REASON_END_NORMAL;
-import static com.android.internal.jank.FrameTracker.REASON_END_UNKNOWN;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BIOMETRIC_PROMPT_TRANSITION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_HIDE_ANIMATION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_SHOW_ANIMATION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_PIP;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_ICON;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_RECENTS;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_WIDGET;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_ALL_APPS;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_SEARCH_RESULT;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNFOLD_ANIM;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNLOCK_ENTRANCE_ANIMATION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_CLOCK_MOVE_ANIMATION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_OCCLUSION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_APPEAR;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_DISAPPEAR;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PATTERN_APPEAR;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PATTERN_DISAPPEAR;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PIN_APPEAR;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PIN_DISAPPEAR;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_TRANSITION_FROM_AOD;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_TRANSITION_TO_AOD;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_UNLOCK_ANIMATION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_ENTER_TRANSITION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_EXIT_TRANSITION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PIP_TRANSITION;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_ACTIVITY;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_TASK;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_HOME;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__RECENTS_SCROLLING;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF_SHOW_AOD;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_PAGE_SCROLL;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_SLIDER;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_TOGGLE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_DISAPPEAR;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_ADD;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_REMOVE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_QS_EXPAND_COLLAPSE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_QS_SCROLL_SWIPE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_EXPAND;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_SWIPE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_SCROLL_FLING;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_AVD;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_EXIT_ANIM;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_DOUBLE_TAP_DIVIDER;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_ENTER;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_EXIT;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_RESIZE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_SCREEN_FOR_STATUS;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_NEXT_FLOW;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TAKE_SCREENSHOT;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__UNFOLD_ANIM;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__VOLUME_CONTROL;
-import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION;
 
 import android.Manifest;
 import android.annotation.ColorInt;
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.UiThread;
@@ -137,34 +57,31 @@ import com.android.internal.jank.FrameTracker.ThreadedRendererWrapper;
 import com.android.internal.jank.FrameTracker.ViewRootWrapper;
 import com.android.internal.util.PerfettoTrigger;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.time.Instant;
-import java.util.Locale;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
 
 /**
- * This class let users to begin and end the always on tracing mechanism.
+ * This class lets users begin and end the always on tracing mechanism.
  *
  * Enabling for local development:
- *
+ *<pre>
  * adb shell device_config put interaction_jank_monitor enabled true
  * adb shell device_config put interaction_jank_monitor sampling_interval 1
- *
+ * </pre>
  * On debuggable builds, an overlay can be used to display the name of the
  * currently running cuj using:
- *
+ * <pre>
  * adb shell device_config put interaction_jank_monitor debug_overlay_enabled true
- *
- * NOTE: The overlay will interfere with metrics, so it should only be used
- * for understanding which UI events correspeond to which CUJs.
+ * </pre>
+ * <b>NOTE</b>: The overlay will interfere with metrics, so it should only be used
+ * for understanding which UI events correspond to which CUJs.
  *
  * @hide
  */
 public class InteractionJankMonitor {
     private static final String TAG = InteractionJankMonitor.class.getSimpleName();
-    private static final boolean DEBUG = false;
     private static final String ACTION_PREFIX = InteractionJankMonitor.class.getCanonicalName();
 
     private static final String DEFAULT_WORKER_NAME = TAG + "-Worker";
@@ -186,218 +103,79 @@ public class InteractionJankMonitor {
     private static final int DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS = 64;
     private static final boolean DEFAULT_DEBUG_OVERLAY_ENABLED = false;
 
-    @VisibleForTesting
-    public static final int MAX_LENGTH_OF_CUJ_NAME = 80;
     private static final int MAX_LENGTH_SESSION_NAME = 100;
 
     public static final String ACTION_SESSION_END = ACTION_PREFIX + ".ACTION_SESSION_END";
     public static final String ACTION_SESSION_CANCEL = ACTION_PREFIX + ".ACTION_SESSION_CANCEL";
 
-    // Every value must have a corresponding entry in CUJ_STATSD_INTERACTION_TYPE.
-    public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE = 0;
-    public static final int CUJ_NOTIFICATION_SHADE_SCROLL_FLING = 2;
-    public static final int CUJ_NOTIFICATION_SHADE_ROW_EXPAND = 3;
-    public static final int CUJ_NOTIFICATION_SHADE_ROW_SWIPE = 4;
-    public static final int CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE = 5;
-    public static final int CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE = 6;
-    public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS = 7;
-    public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON = 8;
-    public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME = 9;
-    public static final int CUJ_LAUNCHER_APP_CLOSE_TO_PIP = 10;
-    public static final int CUJ_LAUNCHER_QUICK_SWITCH = 11;
-    public static final int CUJ_NOTIFICATION_HEADS_UP_APPEAR = 12;
-    public static final int CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR = 13;
-    public static final int CUJ_NOTIFICATION_ADD = 14;
-    public static final int CUJ_NOTIFICATION_REMOVE = 15;
-    public static final int CUJ_NOTIFICATION_APP_START = 16;
-    public static final int CUJ_LOCKSCREEN_PASSWORD_APPEAR = 17;
-    public static final int CUJ_LOCKSCREEN_PATTERN_APPEAR = 18;
-    public static final int CUJ_LOCKSCREEN_PIN_APPEAR = 19;
-    public static final int CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR = 20;
-    public static final int CUJ_LOCKSCREEN_PATTERN_DISAPPEAR = 21;
-    public static final int CUJ_LOCKSCREEN_PIN_DISAPPEAR = 22;
-    public static final int CUJ_LOCKSCREEN_TRANSITION_FROM_AOD = 23;
-    public static final int CUJ_LOCKSCREEN_TRANSITION_TO_AOD = 24;
-    public static final int CUJ_LAUNCHER_OPEN_ALL_APPS = 25;
-    public static final int CUJ_LAUNCHER_ALL_APPS_SCROLL = 26;
-    public static final int CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET = 27;
-    public static final int CUJ_SETTINGS_PAGE_SCROLL = 28;
-    public static final int CUJ_LOCKSCREEN_UNLOCK_ANIMATION = 29;
-    public static final int CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON = 30;
-    public static final int CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER = 31;
-    public static final int CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE = 32;
-    public static final int CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON = 33;
-    public static final int CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP = 34;
-    public static final int CUJ_PIP_TRANSITION = 35;
-    public static final int CUJ_WALLPAPER_TRANSITION = 36;
-    public static final int CUJ_USER_SWITCH = 37;
-    public static final int CUJ_SPLASHSCREEN_AVD = 38;
-    public static final int CUJ_SPLASHSCREEN_EXIT_ANIM = 39;
-    public static final int CUJ_SCREEN_OFF = 40;
-    public static final int CUJ_SCREEN_OFF_SHOW_AOD = 41;
-    public static final int CUJ_ONE_HANDED_ENTER_TRANSITION = 42;
-    public static final int CUJ_ONE_HANDED_EXIT_TRANSITION = 43;
-    public static final int CUJ_UNFOLD_ANIM = 44;
-    public static final int CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS = 45;
-    public static final int CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS = 46;
-    public static final int CUJ_SUW_LOADING_TO_NEXT_FLOW = 47;
-    public static final int CUJ_SUW_LOADING_SCREEN_FOR_STATUS = 48;
-    public static final int CUJ_SPLIT_SCREEN_ENTER = 49;
-    public static final int CUJ_SPLIT_SCREEN_EXIT = 50;
-    public static final int CUJ_LOCKSCREEN_LAUNCH_CAMERA = 51; // reserved.
-    public static final int CUJ_SPLIT_SCREEN_RESIZE = 52;
-    public static final int CUJ_SETTINGS_SLIDER = 53;
-    public static final int CUJ_TAKE_SCREENSHOT = 54;
-    public static final int CUJ_VOLUME_CONTROL = 55;
-    public static final int CUJ_BIOMETRIC_PROMPT_TRANSITION = 56;
-    public static final int CUJ_SETTINGS_TOGGLE = 57;
-    public static final int CUJ_SHADE_DIALOG_OPEN = 58;
-    public static final int CUJ_USER_DIALOG_OPEN = 59;
-    public static final int CUJ_TASKBAR_EXPAND = 60;
-    public static final int CUJ_TASKBAR_COLLAPSE = 61;
-    public static final int CUJ_SHADE_CLEAR_ALL = 62;
-    public static final int CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION = 63;
-    public static final int CUJ_LOCKSCREEN_OCCLUSION = 64;
-    public static final int CUJ_RECENTS_SCROLLING = 65;
-    public static final int CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS = 66;
-    public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE = 67;
-    public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME = 68;
-    public static final int CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION = 70;
-    public static final int CUJ_LAUNCHER_OPEN_SEARCH_RESULT = 71;
-    // 72 - 77 are reserved for b/281564325.
-
-    /**
-     * In some cases when we do not have any end-target, we play a simple slide-down animation.
-     * eg: Open an app from Overview/Task switcher such that there is no home-screen icon.
-     * eg: Exit the app using back gesture.
-     */
-    public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK = 78;
-    public static final int CUJ_IME_INSETS_SHOW_ANIMATION = 80;
-    public static final int CUJ_IME_INSETS_HIDE_ANIMATION = 81;
-
-    public static final int CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER = 82;
-
-    public static final int CUJ_LAUNCHER_UNFOLD_ANIM = 83;
-
-    public static final int CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY = 84;
-    public static final int CUJ_PREDICTIVE_BACK_CROSS_TASK = 85;
-    public static final int CUJ_PREDICTIVE_BACK_HOME = 86;
-
-    private static final int LAST_CUJ = CUJ_PREDICTIVE_BACK_HOME;
-    private static final int NO_STATSD_LOGGING = -1;
-
-    // Used to convert CujType to InteractionType enum value for statsd logging.
-    // Use NO_STATSD_LOGGING in case the measurement for a given CUJ should not be logged to statsd.
-    @VisibleForTesting
-    public static final int[] CUJ_TO_STATSD_INTERACTION_TYPE = new int[LAST_CUJ + 1];
-
-    static {
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[1] = NO_STATSD_LOGGING; // This is deprecated.
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_SCROLL_FLING] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_SCROLL_FLING;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_ROW_EXPAND] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_EXPAND;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_ROW_SWIPE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_SWIPE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_QS_EXPAND_COLLAPSE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_QS_SCROLL_SWIPE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_RECENTS;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_ICON;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_HOME] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_PIP] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_PIP;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_QUICK_SWITCH] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_QUICK_SWITCH;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_HEADS_UP_APPEAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_DISAPPEAR;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_ADD] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_ADD;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_REMOVE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_REMOVE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_APP_START] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PASSWORD_APPEAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_APPEAR;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PATTERN_APPEAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PATTERN_APPEAR;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PIN_APPEAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PIN_APPEAR;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PASSWORD_DISAPPEAR;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PATTERN_DISAPPEAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PATTERN_DISAPPEAR;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_PIN_DISAPPEAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_PIN_DISAPPEAR;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_TRANSITION_FROM_AOD] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_TRANSITION_FROM_AOD;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_TRANSITION_TO_AOD] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_TRANSITION_TO_AOD;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_OPEN_ALL_APPS] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_ALL_APPS;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_ALL_APPS_SCROLL] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_LAUNCH_FROM_WIDGET;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SETTINGS_PAGE_SCROLL] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_PAGE_SCROLL;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_UNLOCK_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_UNLOCK_ANIMATION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_QS_TILE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PIP_TRANSITION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PIP_TRANSITION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_USER_SWITCH] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLASHSCREEN_AVD] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_AVD;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLASHSCREEN_EXIT_ANIM] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_EXIT_ANIM;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SCREEN_OFF] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SCREEN_OFF_SHOW_AOD] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF_SHOW_AOD;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_ONE_HANDED_ENTER_TRANSITION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_ENTER_TRANSITION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_ONE_HANDED_EXIT_TRANSITION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_EXIT_TRANSITION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_UNFOLD_ANIM] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__UNFOLD_ANIM;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SUW_LOADING_TO_NEXT_FLOW] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_TO_NEXT_FLOW;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SUW_LOADING_SCREEN_FOR_STATUS] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SUW_LOADING_SCREEN_FOR_STATUS;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_ENTER] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_ENTER;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_EXIT] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_EXIT;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_LAUNCH_CAMERA] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_LAUNCH_CAMERA;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_RESIZE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_RESIZE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SETTINGS_SLIDER] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_SLIDER;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_TAKE_SCREENSHOT] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TAKE_SCREENSHOT;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_VOLUME_CONTROL] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__VOLUME_CONTROL;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_BIOMETRIC_PROMPT_TRANSITION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BIOMETRIC_PROMPT_TRANSITION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SETTINGS_TOGGLE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SETTINGS_TOGGLE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_DIALOG_OPEN] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_USER_DIALOG_OPEN] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_DIALOG_OPEN;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_TASKBAR_EXPAND] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_EXPAND;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_TASKBAR_COLLAPSE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__TASKBAR_COLLAPSE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_CLEAR_ALL] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNLOCK_ENTRANCE_ANIMATION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_OCCLUSION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_OCCLUSION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_RECENTS_SCROLLING] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__RECENTS_SCROLLING;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME;
-        CUJ_TO_STATSD_INTERACTION_TYPE[69] = NO_STATSD_LOGGING; // This is deprecated.
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_CLOCK_MOVE_ANIMATION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_OPEN_SEARCH_RESULT] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OPEN_SEARCH_RESULT;
-        // 72 - 77 are reserved for b/281564325.
-        CUJ_TO_STATSD_INTERACTION_TYPE[72] = NO_STATSD_LOGGING;
-        CUJ_TO_STATSD_INTERACTION_TYPE[73] = NO_STATSD_LOGGING;
-        CUJ_TO_STATSD_INTERACTION_TYPE[74] = NO_STATSD_LOGGING;
-        CUJ_TO_STATSD_INTERACTION_TYPE[75] = NO_STATSD_LOGGING;
-        CUJ_TO_STATSD_INTERACTION_TYPE[76] = NO_STATSD_LOGGING;
-        CUJ_TO_STATSD_INTERACTION_TYPE[77] = NO_STATSD_LOGGING;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
-        CUJ_TO_STATSD_INTERACTION_TYPE[79] = NO_STATSD_LOGGING; // This is deprecated.
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_SHOW_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_SHOW_ANIMATION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_IME_INSETS_HIDE_ANIMATION] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_HIDE_ANIMATION;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLIT_SCREEN_DOUBLE_TAP_DIVIDER;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_UNFOLD_ANIM] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_UNFOLD_ANIM;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY] =
-            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_ACTIVITY;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_CROSS_TASK] =
-            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_CROSS_TASK;
-        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_PREDICTIVE_BACK_HOME] =
-            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PREDICTIVE_BACK_HOME;
-    }
+    // These are not the CUJ constants you are looking for. These constants simply forward their
+    // definition from {@link Cuj}. They are here only as a transition measure until all references
+    // have been updated to the new location.
+    @Deprecated public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
+    @Deprecated public static final int CUJ_NOTIFICATION_SHADE_SCROLL_FLING = Cuj.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
+    @Deprecated public static final int CUJ_NOTIFICATION_SHADE_ROW_EXPAND = Cuj.CUJ_NOTIFICATION_SHADE_ROW_EXPAND;
+    @Deprecated public static final int CUJ_NOTIFICATION_SHADE_ROW_SWIPE = Cuj.CUJ_NOTIFICATION_SHADE_ROW_SWIPE;
+    @Deprecated public static final int CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE = Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
+    @Deprecated public static final int CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE = Cuj.CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE;
+    @Deprecated public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME = Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME;
+    @Deprecated public static final int CUJ_LAUNCHER_QUICK_SWITCH = Cuj.CUJ_LAUNCHER_QUICK_SWITCH;
+    @Deprecated public static final int CUJ_NOTIFICATION_HEADS_UP_APPEAR = Cuj.CUJ_NOTIFICATION_HEADS_UP_APPEAR;
+    @Deprecated public static final int CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR = Cuj.CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR;
+    @Deprecated public static final int CUJ_NOTIFICATION_ADD = Cuj.CUJ_NOTIFICATION_ADD;
+    @Deprecated public static final int CUJ_NOTIFICATION_REMOVE = Cuj.CUJ_NOTIFICATION_REMOVE;
+    @Deprecated public static final int CUJ_NOTIFICATION_APP_START = Cuj.CUJ_NOTIFICATION_APP_START;
+    @Deprecated public static final int CUJ_LOCKSCREEN_PASSWORD_APPEAR = Cuj.CUJ_LOCKSCREEN_PASSWORD_APPEAR;
+    @Deprecated public static final int CUJ_LOCKSCREEN_PATTERN_APPEAR = Cuj.CUJ_LOCKSCREEN_PATTERN_APPEAR;
+    @Deprecated public static final int CUJ_LOCKSCREEN_PIN_APPEAR = Cuj.CUJ_LOCKSCREEN_PIN_APPEAR;
+    @Deprecated public static final int CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR = Cuj.CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR;
+    @Deprecated public static final int CUJ_LOCKSCREEN_PATTERN_DISAPPEAR = Cuj.CUJ_LOCKSCREEN_PATTERN_DISAPPEAR;
+    @Deprecated public static final int CUJ_LOCKSCREEN_PIN_DISAPPEAR = Cuj.CUJ_LOCKSCREEN_PIN_DISAPPEAR;
+    @Deprecated public static final int CUJ_LOCKSCREEN_TRANSITION_FROM_AOD = Cuj.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD;
+    @Deprecated public static final int CUJ_LOCKSCREEN_TRANSITION_TO_AOD = Cuj.CUJ_LOCKSCREEN_TRANSITION_TO_AOD;
+    @Deprecated public static final int CUJ_SETTINGS_PAGE_SCROLL = Cuj.CUJ_SETTINGS_PAGE_SCROLL;
+    @Deprecated public static final int CUJ_LOCKSCREEN_UNLOCK_ANIMATION = Cuj.CUJ_LOCKSCREEN_UNLOCK_ANIMATION;
+    @Deprecated public static final int CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON = Cuj.CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON;
+    @Deprecated public static final int CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER = Cuj.CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER;
+    @Deprecated public static final int CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE = Cuj.CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE;
+    @Deprecated public static final int CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON = Cuj.CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
+    @Deprecated public static final int CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP = Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP;
+    @Deprecated public static final int CUJ_PIP_TRANSITION = Cuj.CUJ_PIP_TRANSITION;
+    @Deprecated public static final int CUJ_USER_SWITCH = Cuj.CUJ_USER_SWITCH;
+    @Deprecated public static final int CUJ_SPLASHSCREEN_AVD = Cuj.CUJ_SPLASHSCREEN_AVD;
+    @Deprecated public static final int CUJ_SPLASHSCREEN_EXIT_ANIM = Cuj.CUJ_SPLASHSCREEN_EXIT_ANIM;
+    @Deprecated public static final int CUJ_SCREEN_OFF = Cuj.CUJ_SCREEN_OFF;
+    @Deprecated public static final int CUJ_SCREEN_OFF_SHOW_AOD = Cuj.CUJ_SCREEN_OFF_SHOW_AOD;
+    @Deprecated public static final int CUJ_UNFOLD_ANIM = Cuj.CUJ_UNFOLD_ANIM;
+    @Deprecated public static final int CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS = Cuj.CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS;
+    @Deprecated public static final int CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS = Cuj.CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS;
+    @Deprecated public static final int CUJ_SUW_LOADING_TO_NEXT_FLOW = Cuj.CUJ_SUW_LOADING_TO_NEXT_FLOW;
+    @Deprecated public static final int CUJ_SUW_LOADING_SCREEN_FOR_STATUS = Cuj.CUJ_SUW_LOADING_SCREEN_FOR_STATUS;
+    @Deprecated public static final int CUJ_SPLIT_SCREEN_RESIZE = Cuj.CUJ_SPLIT_SCREEN_RESIZE;
+    @Deprecated public static final int CUJ_SETTINGS_SLIDER = Cuj.CUJ_SETTINGS_SLIDER;
+    @Deprecated public static final int CUJ_TAKE_SCREENSHOT = Cuj.CUJ_TAKE_SCREENSHOT;
+    @Deprecated public static final int CUJ_VOLUME_CONTROL = Cuj.CUJ_VOLUME_CONTROL;
+    @Deprecated public static final int CUJ_BIOMETRIC_PROMPT_TRANSITION = Cuj.CUJ_BIOMETRIC_PROMPT_TRANSITION;
+    @Deprecated public static final int CUJ_SETTINGS_TOGGLE = Cuj.CUJ_SETTINGS_TOGGLE;
+    @Deprecated public static final int CUJ_SHADE_DIALOG_OPEN = Cuj.CUJ_SHADE_DIALOG_OPEN;
+    @Deprecated public static final int CUJ_USER_DIALOG_OPEN = Cuj.CUJ_USER_DIALOG_OPEN;
+    @Deprecated public static final int CUJ_TASKBAR_EXPAND = Cuj.CUJ_TASKBAR_EXPAND;
+    @Deprecated public static final int CUJ_TASKBAR_COLLAPSE = Cuj.CUJ_TASKBAR_COLLAPSE;
+    @Deprecated public static final int CUJ_SHADE_CLEAR_ALL = Cuj.CUJ_SHADE_CLEAR_ALL;
+    @Deprecated public static final int CUJ_LOCKSCREEN_OCCLUSION = Cuj.CUJ_LOCKSCREEN_OCCLUSION;
+    @Deprecated public static final int CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION = Cuj.CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION;
+    @Deprecated public static final int CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER = Cuj.CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER;
+    @Deprecated public static final int CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY = Cuj.CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY;
+    @Deprecated public static final int CUJ_PREDICTIVE_BACK_CROSS_TASK = Cuj.CUJ_PREDICTIVE_BACK_CROSS_TASK;
+    @Deprecated public static final int CUJ_PREDICTIVE_BACK_HOME = Cuj.CUJ_PREDICTIVE_BACK_HOME;
 
     private static class InstanceHolder {
         public static final InteractionJankMonitor INSTANCE =
             new InteractionJankMonitor(new HandlerThread(DEFAULT_WORKER_NAME));
     }
 
-    private final DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener =
-            this::updateProperties;
-
     @GuardedBy("mLock")
-    private final SparseArray<FrameTracker> mRunningTrackers;
-    @GuardedBy("mLock")
-    private final SparseArray<Runnable> mTimeoutActions;
-    private final HandlerThread mWorker;
+    private final SparseArray<RunningTracker> mRunningTrackers = new SparseArray<>();
+    private final Handler mWorker;
     private final DisplayResolutionTracker mDisplayResolutionTracker;
     private final Object mLock = new Object();
     private @ColorInt int mDebugBgColor = Color.CYAN;
@@ -409,91 +187,6 @@ public class InteractionJankMonitor {
     private int mTraceThresholdMissedFrames = DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES;
     private int mTraceThresholdFrameTimeMillis = DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS;
 
-    /** @hide */
-    @IntDef({
-            CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
-            CUJ_NOTIFICATION_SHADE_SCROLL_FLING,
-            CUJ_NOTIFICATION_SHADE_ROW_EXPAND,
-            CUJ_NOTIFICATION_SHADE_ROW_SWIPE,
-            CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
-            CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE,
-            CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS,
-            CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON,
-            CUJ_LAUNCHER_APP_CLOSE_TO_HOME,
-            CUJ_LAUNCHER_APP_CLOSE_TO_PIP,
-            CUJ_LAUNCHER_QUICK_SWITCH,
-            CUJ_NOTIFICATION_HEADS_UP_APPEAR,
-            CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR,
-            CUJ_NOTIFICATION_ADD,
-            CUJ_NOTIFICATION_REMOVE,
-            CUJ_NOTIFICATION_APP_START,
-            CUJ_LOCKSCREEN_PASSWORD_APPEAR,
-            CUJ_LOCKSCREEN_PATTERN_APPEAR,
-            CUJ_LOCKSCREEN_PIN_APPEAR,
-            CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR,
-            CUJ_LOCKSCREEN_PATTERN_DISAPPEAR,
-            CUJ_LOCKSCREEN_PIN_DISAPPEAR,
-            CUJ_LOCKSCREEN_TRANSITION_FROM_AOD,
-            CUJ_LOCKSCREEN_TRANSITION_TO_AOD,
-            CUJ_LAUNCHER_OPEN_ALL_APPS,
-            CUJ_LAUNCHER_ALL_APPS_SCROLL,
-            CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET,
-            CUJ_SETTINGS_PAGE_SCROLL,
-            CUJ_LOCKSCREEN_UNLOCK_ANIMATION,
-            CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON,
-            CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER,
-            CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE,
-            CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON,
-            CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
-            CUJ_PIP_TRANSITION,
-            CUJ_WALLPAPER_TRANSITION,
-            CUJ_USER_SWITCH,
-            CUJ_SPLASHSCREEN_AVD,
-            CUJ_SPLASHSCREEN_EXIT_ANIM,
-            CUJ_SCREEN_OFF,
-            CUJ_SCREEN_OFF_SHOW_AOD,
-            CUJ_ONE_HANDED_ENTER_TRANSITION,
-            CUJ_ONE_HANDED_EXIT_TRANSITION,
-            CUJ_UNFOLD_ANIM,
-            CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS,
-            CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS,
-            CUJ_SUW_LOADING_TO_NEXT_FLOW,
-            CUJ_SUW_LOADING_SCREEN_FOR_STATUS,
-            CUJ_SPLIT_SCREEN_ENTER,
-            CUJ_SPLIT_SCREEN_EXIT,
-            CUJ_LOCKSCREEN_LAUNCH_CAMERA,
-            CUJ_SPLIT_SCREEN_RESIZE,
-            CUJ_SETTINGS_SLIDER,
-            CUJ_TAKE_SCREENSHOT,
-            CUJ_VOLUME_CONTROL,
-            CUJ_BIOMETRIC_PROMPT_TRANSITION,
-            CUJ_SETTINGS_TOGGLE,
-            CUJ_SHADE_DIALOG_OPEN,
-            CUJ_USER_DIALOG_OPEN,
-            CUJ_TASKBAR_EXPAND,
-            CUJ_TASKBAR_COLLAPSE,
-            CUJ_SHADE_CLEAR_ALL,
-            CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION,
-            CUJ_LOCKSCREEN_OCCLUSION,
-            CUJ_RECENTS_SCROLLING,
-            CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS,
-            CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE,
-            CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
-            CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION,
-            CUJ_LAUNCHER_OPEN_SEARCH_RESULT,
-            CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK,
-            CUJ_IME_INSETS_SHOW_ANIMATION,
-            CUJ_IME_INSETS_HIDE_ANIMATION,
-            CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER,
-            CUJ_LAUNCHER_UNFOLD_ANIM,
-            CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY,
-            CUJ_PREDICTIVE_BACK_CROSS_TASK,
-            CUJ_PREDICTIVE_BACK_HOME,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CujType {
-    }
-
     /**
      * Get the singleton of InteractionJankMonitor.
      *
@@ -511,71 +204,44 @@ public class InteractionJankMonitor {
     @VisibleForTesting
     @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
     public InteractionJankMonitor(@NonNull HandlerThread worker) {
-        mRunningTrackers = new SparseArray<>();
-        mTimeoutActions = new SparseArray<>();
-        mWorker = worker;
-        mWorker.start();
-        mDisplayResolutionTracker = new DisplayResolutionTracker(worker.getThreadHandler());
-        mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
-        mEnabled = DEFAULT_ENABLED;
+        worker.start();
+        mWorker = worker.getThreadHandler();
+        mDisplayResolutionTracker = new DisplayResolutionTracker(mWorker);
 
         final Context context = ActivityThread.currentApplication();
-        if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PERMISSION_GRANTED) {
-            if (DEBUG) {
-                Log.d(TAG, "Initialized the InteractionJankMonitor."
-                        + " (No READ_DEVICE_CONFIG permission to change configs)"
-                        + " enabled=" + mEnabled + ", interval=" + mSamplingInterval
-                        + ", missedFrameThreshold=" + mTraceThresholdMissedFrames
-                        + ", frameTimeThreshold=" + mTraceThresholdFrameTimeMillis
-                        + ", package=" + context.getPackageName());
-            }
+        if (context == null || context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PERMISSION_GRANTED) {
+            Log.w(TAG, "Initializing without READ_DEVICE_CONFIG permission."
+                    + " enabled=" + mEnabled + ", interval=" + mSamplingInterval
+                    + ", missedFrameThreshold=" + mTraceThresholdMissedFrames
+                    + ", frameTimeThreshold=" + mTraceThresholdFrameTimeMillis
+                    + ", package=" + (context == null ? "null" : context.getPackageName()));
             return;
         }
 
         // Post initialization to the background in case we're running on the main thread.
-        mWorker.getThreadHandler().post(
-                () -> {
-                    try {
-                        mPropertiesChangedListener.onPropertiesChanged(
-                                DeviceConfig.getProperties(NAMESPACE_INTERACTION_JANK_MONITOR));
-                        DeviceConfig.addOnPropertiesChangedListener(
-                                NAMESPACE_INTERACTION_JANK_MONITOR,
-                                new HandlerExecutor(mWorker.getThreadHandler()),
-                                mPropertiesChangedListener);
-                    } catch (SecurityException ex) {
-                        Log.d(TAG, "Can't get properties: READ_DEVICE_CONFIG granted="
-                                + context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG)
-                                + ", package=" + context.getPackageName());
-                    }
-                });
+        mWorker.post(() -> {
+            try {
+                updateProperties(DeviceConfig.getProperties(NAMESPACE_INTERACTION_JANK_MONITOR));
+                DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_INTERACTION_JANK_MONITOR,
+                        new HandlerExecutor(mWorker), this::updateProperties);
+            } catch (SecurityException ex) {
+                Log.d(TAG, "Can't get properties: READ_DEVICE_CONFIG granted="
+                        + context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG)
+                        + ", package=" + context.getPackageName());
+            }
+        });
     }
 
     /**
      * Creates a {@link FrameTracker} instance.
      *
-     * @param config the config used in instrumenting
-     * @param session the session associates with this tracker
+     * @param config the conifg associates with this tracker
      * @return instance of the FrameTracker
      */
     @VisibleForTesting
-    public FrameTracker createFrameTracker(Configuration config, Session session) {
+    public FrameTracker createFrameTracker(Configuration config) {
         final View view = config.mView;
 
-        if (!config.hasValidView()) {
-            boolean attached = false;
-            boolean hasViewRoot = false;
-            boolean hasRenderer = false;
-            if (view != null) {
-                attached = view.isAttachedToWindow();
-                hasViewRoot = view.getViewRootImpl() != null;
-                hasRenderer = view.getThreadedRenderer() != null;
-            }
-            Log.d(TAG, "create FrameTracker fails: view=" + view
-                    + ", attached=" + attached + ", hasViewRoot=" + hasViewRoot
-                    + ", hasRenderer=" + hasRenderer, new Throwable());
-            return null;
-        }
-
         final ThreadedRendererWrapper threadedRenderer =
                 view == null ? null : new ThreadedRendererWrapper(view.getThreadedRenderer());
         final ViewRootWrapper viewRoot =
@@ -583,52 +249,50 @@ public class InteractionJankMonitor {
         final SurfaceControlWrapper surfaceControl = new SurfaceControlWrapper();
         final ChoreographerWrapper choreographer =
                 new ChoreographerWrapper(Choreographer.getInstance());
-        final FrameTrackerListener eventsListener = (s, act) -> handleCujEvents(act, s);
+        final FrameTrackerListener eventsListener = new FrameTrackerListener() {
+            @Override
+            public void onCujEvents(FrameTracker tracker, String action, int reason) {
+                config.getHandler().runWithScissors(() ->
+                        handleCujEvents(config.mCujType, tracker, action, reason),
+                        EXECUTOR_TASK_TIMEOUT);
+            }
+
+            @Override
+            public void triggerPerfetto(Configuration config) {
+                mWorker.post(() -> PerfettoTrigger.trigger(config.getPerfettoTrigger()));
+            }
+        };
         final FrameMetricsWrapper frameMetrics = new FrameMetricsWrapper();
 
-        return new FrameTracker(this, session, config.getHandler(), threadedRenderer, viewRoot,
+        return new FrameTracker(config, threadedRenderer, viewRoot,
                 surfaceControl, choreographer, frameMetrics,
                 new FrameTracker.StatsLogWrapper(mDisplayResolutionTracker),
                 mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis,
-                eventsListener, config);
+                eventsListener);
     }
 
     @UiThread
-    private void handleCujEvents(String action, Session session) {
+    private void handleCujEvents(
+            @Cuj.CujType int cuj, FrameTracker tracker, String action, @Reasons int reason) {
         // Clear the running and timeout tasks if the end / cancel was fired within the tracker.
         // Or we might have memory leaks.
-        if (needRemoveTasks(action, session)) {
-            getTracker(session.getCuj()).getHandler().runWithScissors(() -> {
-                removeTimeout(session.getCuj());
-                removeTracker(session.getCuj(), session.getReason());
-            }, EXECUTOR_TASK_TIMEOUT);
+        if (needRemoveTasks(action, reason)) {
+            removeTrackerIfCurrent(cuj, tracker, reason);
         }
     }
 
-    private boolean needRemoveTasks(String action, Session session) {
-        final boolean badEnd = action.equals(ACTION_SESSION_END)
-                && session.getReason() != REASON_END_NORMAL;
+    private static boolean needRemoveTasks(String action, @Reasons int reason) {
+        final boolean badEnd = action.equals(ACTION_SESSION_END) && reason != REASON_END_NORMAL;
         final boolean badCancel = action.equals(ACTION_SESSION_CANCEL)
-                && !(session.getReason() == REASON_CANCEL_NORMAL
-                || session.getReason() == REASON_CANCEL_TIMEOUT);
+                && !(reason == REASON_CANCEL_NORMAL || reason == REASON_CANCEL_TIMEOUT);
         return badEnd || badCancel;
     }
 
-    private void removeTimeout(@CujType int cujType) {
-        synchronized (mLock) {
-            Runnable timeout = mTimeoutActions.get(cujType);
-            if (timeout != null) {
-                getTracker(cujType).getHandler().removeCallbacks(timeout);
-                mTimeoutActions.remove(cujType);
-            }
-        }
-    }
-
     /**
      * @param cujType cuj type
      * @return true if the cuj is under instrumenting, false otherwise.
      */
-    public boolean isInstrumenting(@CujType int cujType) {
+    public boolean isInstrumenting(@Cuj.CujType int cujType) {
         synchronized (mLock) {
             return mRunningTrackers.contains(cujType);
         }
@@ -638,10 +302,10 @@ public class InteractionJankMonitor {
      * Begins a trace session.
      *
      * @param v an attached view.
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link Cuj.CujType}.
      * @return boolean true if the tracker is started successfully, false otherwise.
      */
-    public boolean begin(View v, @CujType int cujType) {
+    public boolean begin(View v, @Cuj.CujType int cujType) {
         try {
             return begin(Configuration.Builder.withView(cujType, v));
         } catch (IllegalArgumentException ex) {
@@ -667,7 +331,7 @@ public class InteractionJankMonitor {
             final boolean success = config.getHandler().runWithScissors(
                     () -> result.mResult = beginInternal(config), EXECUTOR_TASK_TIMEOUT);
             if (!success) {
-                Log.d(TAG, "begin failed due to timeout, CUJ=" + getNameOfCuj(config.mCujType));
+                Log.d(TAG, "begin failed due to timeout, CUJ=" + Cuj.getNameOfCuj(config.mCujType));
                 return false;
             }
             return result.mResult;
@@ -680,75 +344,59 @@ public class InteractionJankMonitor {
     @UiThread
     private boolean beginInternal(@NonNull Configuration conf) {
         int cujType = conf.mCujType;
-        if (!shouldMonitor(cujType)) return false;
-        FrameTracker tracker = getTracker(cujType);
-        // Skip subsequent calls if we already have an ongoing tracing.
-        if (tracker != null) return false;
+        if (!shouldMonitor()) {
+            return false;
+        }
 
-        // begin a new trace session.
-        tracker = createFrameTracker(conf, new Session(cujType, conf.mTag));
-        if (tracker == null) return false;
-        putTracker(cujType, tracker);
-        tracker.begin();
+        RunningTracker tracker = putTrackerIfNoCurrent(cujType, () ->
+                new RunningTracker(
+                    conf, createFrameTracker(conf), () -> cancel(cujType, REASON_CANCEL_TIMEOUT)));
+        if (tracker == null) {
+            return false;
+        }
 
+        tracker.mTracker.begin();
         // Cancel the trace if we don't get an end() call in specified duration.
-        scheduleTimeoutAction(
-                cujType, conf.mTimeout, () -> cancel(cujType, REASON_CANCEL_TIMEOUT));
+        scheduleTimeoutAction(tracker.mConfig, tracker.mTimeoutAction);
+
         return true;
     }
 
     /**
      * Check if the monitoring is enabled and if it should be sampled.
      */
-    @SuppressWarnings("RandomModInteger")
     @VisibleForTesting
-    public boolean shouldMonitor(@CujType int cujType) {
-        boolean shouldSample = ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0;
-        if (!mEnabled || !shouldSample) {
-            if (DEBUG) {
-                Log.d(TAG, "Skip monitoring cuj: " + getNameOfCuj(cujType)
-                        + ", enable=" + mEnabled + ", debuggable=" + DEFAULT_ENABLED
-                        + ", sample=" + shouldSample + ", interval=" + mSamplingInterval);
-            }
-            return false;
-        }
-        return true;
+    public boolean shouldMonitor() {
+        return mEnabled && (ThreadLocalRandom.current().nextInt(mSamplingInterval) == 0);
     }
 
-    /**
-     * Schedules a timeout action.
-     * @param cuj cuj type
-     * @param timeout duration to timeout
-     * @param action action once timeout
-     */
     @VisibleForTesting
-    public void scheduleTimeoutAction(@CujType int cuj, long timeout, Runnable action) {
-        synchronized (mLock) {
-            mTimeoutActions.put(cuj, action);
-            getTracker(cuj).getHandler().postDelayed(action, timeout);
-        }
+    public void scheduleTimeoutAction(Configuration config, Runnable action) {
+        config.getHandler().postDelayed(action, config.mTimeout);
     }
 
     /**
      * Ends a trace session.
      *
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link Cuj.CujType}.
      * @return boolean true if the tracker is ended successfully, false otherwise.
      */
-    public boolean end(@CujType int cujType) {
+    public boolean end(@Cuj.CujType int cujType) {
         postEventLogToWorkerThread((unixNanos, elapsedNanos, realtimeNanos) -> {
             EventLogTags.writeJankCujEventsEndRequest(
                     cujType, unixNanos, elapsedNanos, realtimeNanos);
         });
-        FrameTracker tracker = getTracker(cujType);
+        RunningTracker tracker = getTracker(cujType);
         // Skip this call since we haven't started a trace yet.
-        if (tracker == null) return false;
+        if (tracker == null) {
+            return false;
+        }
         try {
             final TrackerResult result = new TrackerResult();
-            final boolean success = tracker.getHandler().runWithScissors(
-                    () -> result.mResult = endInternal(cujType), EXECUTOR_TASK_TIMEOUT);
+            final boolean success = tracker.mConfig.getHandler().runWithScissors(
+                    () -> result.mResult = endInternal(tracker), EXECUTOR_TASK_TIMEOUT);
             if (!success) {
-                Log.d(TAG, "end failed due to timeout, CUJ=" + getNameOfCuj(cujType));
+                Log.d(TAG, "end failed due to timeout, CUJ=" + Cuj.getNameOfCuj(cujType));
                 return false;
             }
             return result.mResult;
@@ -759,15 +407,11 @@ public class InteractionJankMonitor {
     }
 
     @UiThread
-    private boolean endInternal(@CujType int cujType) {
-        // remove the timeout action first.
-        removeTimeout(cujType);
-        FrameTracker tracker = getTracker(cujType);
-        if (tracker == null) return false;
-        // if the end call doesn't return true, another thread is handling end of the cuj.
-        if (tracker.end(REASON_END_NORMAL)) {
-            removeTracker(cujType, REASON_END_NORMAL);
+    private boolean endInternal(RunningTracker tracker) {
+        if (removeTrackerIfCurrent(tracker, REASON_END_NORMAL)) {
+            return false;
         }
+        tracker.mTracker.end(REASON_END_NORMAL);
         return true;
     }
 
@@ -776,7 +420,7 @@ public class InteractionJankMonitor {
      *
      * @return boolean true if the tracker is cancelled successfully, false otherwise.
      */
-    public boolean cancel(@CujType int cujType) {
+    public boolean cancel(@Cuj.CujType int cujType) {
         postEventLogToWorkerThread((unixNanos, elapsedNanos, realtimeNanos) -> {
             EventLogTags.writeJankCujEventsCancelRequest(
                     cujType, unixNanos, elapsedNanos, realtimeNanos);
@@ -790,16 +434,18 @@ public class InteractionJankMonitor {
      * @return boolean true if the tracker is cancelled successfully, false otherwise.
      */
     @VisibleForTesting
-    public boolean cancel(@CujType int cujType, @Reasons int reason) {
-        FrameTracker tracker = getTracker(cujType);
+    public boolean cancel(@Cuj.CujType int cujType, @Reasons int reason) {
+        RunningTracker tracker = getTracker(cujType);
         // Skip this call since we haven't started a trace yet.
-        if (tracker == null) return false;
+        if (tracker == null) {
+            return false;
+        }
         try {
             final TrackerResult result = new TrackerResult();
-            final boolean success = tracker.getHandler().runWithScissors(
-                    () -> result.mResult = cancelInternal(cujType, reason), EXECUTOR_TASK_TIMEOUT);
+            final boolean success = tracker.mConfig.getHandler().runWithScissors(
+                    () -> result.mResult = cancelInternal(tracker, reason), EXECUTOR_TASK_TIMEOUT);
             if (!success) {
-                Log.d(TAG, "cancel failed due to timeout, CUJ=" + getNameOfCuj(cujType));
+                Log.d(TAG, "cancel failed due to timeout, CUJ=" + Cuj.getNameOfCuj(cujType));
                 return false;
             }
             return result.mResult;
@@ -810,71 +456,86 @@ public class InteractionJankMonitor {
     }
 
     @UiThread
-    private boolean cancelInternal(@CujType int cujType, @Reasons int reason) {
-        // remove the timeout action first.
-        removeTimeout(cujType);
-        FrameTracker tracker = getTracker(cujType);
-        if (tracker == null) return false;
-        // if the cancel call doesn't return true, another thread is handling cancel of the cuj.
-        if (tracker.cancel(reason)) {
-            removeTracker(cujType, reason);
+    private boolean cancelInternal(RunningTracker tracker, @Reasons int reason) {
+        if (removeTrackerIfCurrent(tracker, reason)) {
+            return false;
         }
+        tracker.mTracker.cancel(reason);
         return true;
     }
 
     @UiThread
-    private void putTracker(@CujType int cuj, @NonNull FrameTracker tracker) {
+    private RunningTracker putTrackerIfNoCurrent(
+            @Cuj.CujType int cuj, Supplier<RunningTracker> supplier) {
         synchronized (mLock) {
+            if (mRunningTrackers.contains(cuj)) {
+                return null;
+            }
+
+            RunningTracker tracker = supplier.get();
+            if (tracker == null) {
+                return null;
+            }
+
             mRunningTrackers.put(cuj, tracker);
             if (mDebugOverlay != null) {
                 mDebugOverlay.onTrackerAdded(cuj, tracker);
             }
-            if (DEBUG) {
-                Log.d(TAG, "Added tracker for " + getNameOfCuj(cuj)
-                        + ". mRunningTrackers=" + listNamesOfCujs(mRunningTrackers));
-            }
+
+            return tracker;
         }
     }
 
-    private FrameTracker getTracker(@CujType int cuj) {
+    private RunningTracker getTracker(@Cuj.CujType int cuj) {
         synchronized (mLock) {
             return mRunningTrackers.get(cuj);
         }
     }
 
+    /**
+     * @return {@code true} if another tracker is current
+     */
+    @UiThread
+    private boolean removeTrackerIfCurrent(RunningTracker tracker, int reason) {
+        return removeTrackerIfCurrent(tracker.mConfig.mCujType, tracker.mTracker, reason);
+    }
+
+    /**
+     * @return {@code true} if another tracker is current
+     */
     @UiThread
-    private void removeTracker(@CujType int cuj, int reason) {
+    private boolean removeTrackerIfCurrent(@Cuj.CujType int cuj, FrameTracker tracker, int reason) {
         synchronized (mLock) {
+            RunningTracker running = mRunningTrackers.get(cuj);
+            if (running == null || running.mTracker != tracker) {
+                return true;
+            }
+
+            running.mConfig.getHandler().removeCallbacks(running.mTimeoutAction);
             mRunningTrackers.remove(cuj);
             if (mDebugOverlay != null) {
                 mDebugOverlay.onTrackerRemoved(cuj, reason, mRunningTrackers);
             }
-            if (DEBUG) {
-                Log.d(TAG, "Removed tracker for " + getNameOfCuj(cuj)
-                        + ". mRunningTrackers=" + listNamesOfCujs(mRunningTrackers));
-            }
+            return false;
         }
     }
 
     @WorkerThread
-    private void updateProperties(DeviceConfig.Properties properties) {
+    @VisibleForTesting
+    public void updateProperties(DeviceConfig.Properties properties) {
         for (String property : properties.getKeyset()) {
             switch (property) {
-                case SETTINGS_SAMPLING_INTERVAL_KEY:
-                    mSamplingInterval = properties.getInt(property, DEFAULT_SAMPLING_INTERVAL);
-                    break;
-                case SETTINGS_THRESHOLD_MISSED_FRAMES_KEY:
-                    mTraceThresholdMissedFrames =
-                            properties.getInt(property, DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES);
-                    break;
-                case SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY:
-                    mTraceThresholdFrameTimeMillis =
-                            properties.getInt(property, DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS);
-                    break;
-                case SETTINGS_ENABLED_KEY:
-                    mEnabled = properties.getBoolean(property, DEFAULT_ENABLED);
-                    break;
-                case SETTINGS_DEBUG_OVERLAY_ENABLED_KEY:
+                case SETTINGS_SAMPLING_INTERVAL_KEY ->
+                        mSamplingInterval = properties.getInt(property, DEFAULT_SAMPLING_INTERVAL);
+                case SETTINGS_THRESHOLD_MISSED_FRAMES_KEY ->
+                        mTraceThresholdMissedFrames =
+                                properties.getInt(property, DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES);
+                case SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY ->
+                        mTraceThresholdFrameTimeMillis =
+                                properties.getInt(property, DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS);
+                case SETTINGS_ENABLED_KEY ->
+                        mEnabled = properties.getBoolean(property, DEFAULT_ENABLED);
+                case SETTINGS_DEBUG_OVERLAY_ENABLED_KEY -> {
                     // Never allow the debug overlay to be used on user builds
                     boolean debugOverlayEnabled = Build.IS_DEBUGGABLE
                             && properties.getBoolean(property, DEFAULT_DEBUG_OVERLAY_ENABLED);
@@ -885,49 +546,35 @@ public class InteractionJankMonitor {
                         mDebugOverlay.dispose();
                         mDebugOverlay = null;
                     }
-                    break;
-                default:
-                    if (DEBUG) {
-                        Log.d(TAG, "Got a change event for an unknown property: "
-                                + property + " => " + properties.getString(property, ""));
-                    }
+                }
+                default -> Log.w(TAG, "Got a change event for an unknown property: "
+                        + property + " => " + properties.getString(property, ""));
             }
         }
     }
 
-    @VisibleForTesting
-    public DeviceConfig.OnPropertiesChangedListener getPropertiesChangedListener() {
-        return mPropertiesChangedListener;
-    }
-
-    /**
-     * Triggers the perfetto daemon to collect and upload data.
-     */
-    @VisibleForTesting
-    public void trigger(Session session) {
-        mWorker.getThreadHandler().post(
-                () -> PerfettoTrigger.trigger(session.getPerfettoTrigger()));
-    }
-
     /**
      * A helper method to translate interaction type to CUJ name.
      *
      * @param interactionType the interaction type defined in AtomsProto.java
      * @return the name of the interaction type
+     * @deprecated use {@link Cuj#getNameOfInteraction(int)}
      */
+    @Deprecated
     public static String getNameOfInteraction(int interactionType) {
-        // There is an offset amount of 1 between cujType and interactionType.
-        return getNameOfCuj(getCujTypeFromInteraction(interactionType));
+        return Cuj.getNameOfInteraction(interactionType);
     }
 
     /**
-     * A helper method to translate interaction type to CUJ type.
+     * A helper method to translate CUJ type to CUJ name.
      *
-     * @param interactionType the interaction type defined in AtomsProto.java
-     * @return the integer in {@link CujType}
+     * @param cujType the cuj type defined in this file
+     * @return the name of the cuj type
+     * @deprecated use {@link Cuj#getNameOfCuj(int)}
      */
-    private static int getCujTypeFromInteraction(int interactionType) {
-        return interactionType - 1;
+    @Deprecated
+    public static String getNameOfCuj(int cujType) {
+        return Cuj.getNameOfCuj(cujType);
     }
 
     /**
@@ -943,195 +590,14 @@ public class InteractionJankMonitor {
         mDebugYOffset = yOffset;
     }
 
-    /**
-     * A helper method for getting a string representation of all running CUJs. For example,
-     * "(LOCKSCREEN_TRANSITION_FROM_AOD, IME_INSETS_ANIMATION)"
-     */
-    private static String listNamesOfCujs(SparseArray<FrameTracker> trackers) {
-        if (!DEBUG) {
-            return null;
-        }
-        StringBuilder sb = new StringBuilder();
-        sb.append('(');
-        for (int i = 0; i < trackers.size(); i++) {
-            sb.append(getNameOfCuj(trackers.keyAt(i)));
-            if (i < trackers.size() - 1) {
-                sb.append(", ");
-            }
-        }
-        sb.append(')');
-        return sb.toString();
-    }
+    private void postEventLogToWorkerThread(TimeFunction logFunction) {
+        final Instant now = Instant.now();
+        final long unixNanos = TimeUnit.NANOSECONDS.convert(now.getEpochSecond(), TimeUnit.SECONDS)
+                + now.getNano();
+        final long elapsedNanos = SystemClock.elapsedRealtimeNanos();
+        final long realtimeNanos = SystemClock.uptimeNanos();
 
-    /**
-     * A helper method to translate CUJ type to CUJ name.
-     *
-     * @param cujType the cuj type defined in this file
-     * @return the name of the cuj type
-     */
-    public static String getNameOfCuj(int cujType) {
-        // Please note:
-        // 1. The length of the returned string shouldn't exceed MAX_LENGTH_OF_CUJ_NAME.
-        // 2. The returned string should be the same with the name defined in atoms.proto.
-        switch (cujType) {
-            case CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE:
-                return "NOTIFICATION_SHADE_EXPAND_COLLAPSE";
-            case CUJ_NOTIFICATION_SHADE_SCROLL_FLING:
-                return "NOTIFICATION_SHADE_SCROLL_FLING";
-            case CUJ_NOTIFICATION_SHADE_ROW_EXPAND:
-                return "NOTIFICATION_SHADE_ROW_EXPAND";
-            case CUJ_NOTIFICATION_SHADE_ROW_SWIPE:
-                return "NOTIFICATION_SHADE_ROW_SWIPE";
-            case CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE:
-                return "NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE";
-            case CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE:
-                return "NOTIFICATION_SHADE_QS_SCROLL_SWIPE";
-            case CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS:
-                return "LAUNCHER_APP_LAUNCH_FROM_RECENTS";
-            case CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON:
-                return "LAUNCHER_APP_LAUNCH_FROM_ICON";
-            case CUJ_LAUNCHER_APP_CLOSE_TO_HOME:
-                return "LAUNCHER_APP_CLOSE_TO_HOME";
-            case CUJ_LAUNCHER_APP_CLOSE_TO_PIP:
-                return "LAUNCHER_APP_CLOSE_TO_PIP";
-            case CUJ_LAUNCHER_QUICK_SWITCH:
-                return "LAUNCHER_QUICK_SWITCH";
-            case CUJ_NOTIFICATION_HEADS_UP_APPEAR:
-                return "NOTIFICATION_HEADS_UP_APPEAR";
-            case CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR:
-                return "NOTIFICATION_HEADS_UP_DISAPPEAR";
-            case CUJ_NOTIFICATION_ADD:
-                return "NOTIFICATION_ADD";
-            case CUJ_NOTIFICATION_REMOVE:
-                return "NOTIFICATION_REMOVE";
-            case CUJ_NOTIFICATION_APP_START:
-                return "NOTIFICATION_APP_START";
-            case CUJ_LOCKSCREEN_PASSWORD_APPEAR:
-                return "LOCKSCREEN_PASSWORD_APPEAR";
-            case CUJ_LOCKSCREEN_PATTERN_APPEAR:
-                return "LOCKSCREEN_PATTERN_APPEAR";
-            case CUJ_LOCKSCREEN_PIN_APPEAR:
-                return "LOCKSCREEN_PIN_APPEAR";
-            case CUJ_LOCKSCREEN_PASSWORD_DISAPPEAR:
-                return "LOCKSCREEN_PASSWORD_DISAPPEAR";
-            case CUJ_LOCKSCREEN_PATTERN_DISAPPEAR:
-                return "LOCKSCREEN_PATTERN_DISAPPEAR";
-            case CUJ_LOCKSCREEN_PIN_DISAPPEAR:
-                return "LOCKSCREEN_PIN_DISAPPEAR";
-            case CUJ_LOCKSCREEN_TRANSITION_FROM_AOD:
-                return "LOCKSCREEN_TRANSITION_FROM_AOD";
-            case CUJ_LOCKSCREEN_TRANSITION_TO_AOD:
-                return "LOCKSCREEN_TRANSITION_TO_AOD";
-            case CUJ_LAUNCHER_OPEN_ALL_APPS :
-                return "LAUNCHER_OPEN_ALL_APPS";
-            case CUJ_LAUNCHER_ALL_APPS_SCROLL:
-                return "LAUNCHER_ALL_APPS_SCROLL";
-            case CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET:
-                return "LAUNCHER_APP_LAUNCH_FROM_WIDGET";
-            case CUJ_SETTINGS_PAGE_SCROLL:
-                return "SETTINGS_PAGE_SCROLL";
-            case CUJ_LOCKSCREEN_UNLOCK_ANIMATION:
-                return "LOCKSCREEN_UNLOCK_ANIMATION";
-            case CUJ_SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON:
-                return "SHADE_APP_LAUNCH_FROM_HISTORY_BUTTON";
-            case CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER:
-                return "SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER";
-            case CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE:
-                return "SHADE_APP_LAUNCH_FROM_QS_TILE";
-            case CUJ_SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON:
-                return "SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON";
-            case CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP:
-                return "STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP";
-            case CUJ_PIP_TRANSITION:
-                return "PIP_TRANSITION";
-            case CUJ_WALLPAPER_TRANSITION:
-                return "WALLPAPER_TRANSITION";
-            case CUJ_USER_SWITCH:
-                return "USER_SWITCH";
-            case CUJ_SPLASHSCREEN_AVD:
-                return "SPLASHSCREEN_AVD";
-            case CUJ_SPLASHSCREEN_EXIT_ANIM:
-                return "SPLASHSCREEN_EXIT_ANIM";
-            case CUJ_SCREEN_OFF:
-                return "SCREEN_OFF";
-            case CUJ_SCREEN_OFF_SHOW_AOD:
-                return "SCREEN_OFF_SHOW_AOD";
-            case CUJ_ONE_HANDED_ENTER_TRANSITION:
-                return "ONE_HANDED_ENTER_TRANSITION";
-            case CUJ_ONE_HANDED_EXIT_TRANSITION:
-                return "ONE_HANDED_EXIT_TRANSITION";
-            case CUJ_UNFOLD_ANIM:
-                return "UNFOLD_ANIM";
-            case CUJ_SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS:
-                return "SUW_LOADING_TO_SHOW_INFO_WITH_ACTIONS";
-            case CUJ_SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS:
-                return "SUW_SHOW_FUNCTION_SCREEN_WITH_ACTIONS";
-            case CUJ_SUW_LOADING_TO_NEXT_FLOW:
-                return "SUW_LOADING_TO_NEXT_FLOW";
-            case CUJ_SUW_LOADING_SCREEN_FOR_STATUS:
-                return "SUW_LOADING_SCREEN_FOR_STATUS";
-            case CUJ_SPLIT_SCREEN_ENTER:
-                return "SPLIT_SCREEN_ENTER";
-            case CUJ_SPLIT_SCREEN_EXIT:
-                return "SPLIT_SCREEN_EXIT";
-            case CUJ_LOCKSCREEN_LAUNCH_CAMERA:
-                return "LOCKSCREEN_LAUNCH_CAMERA";
-            case CUJ_SPLIT_SCREEN_RESIZE:
-                return "SPLIT_SCREEN_RESIZE";
-            case CUJ_SETTINGS_SLIDER:
-                return "SETTINGS_SLIDER";
-            case CUJ_TAKE_SCREENSHOT:
-                return "TAKE_SCREENSHOT";
-            case CUJ_VOLUME_CONTROL:
-                return "VOLUME_CONTROL";
-            case CUJ_BIOMETRIC_PROMPT_TRANSITION:
-                return "BIOMETRIC_PROMPT_TRANSITION";
-            case CUJ_SETTINGS_TOGGLE:
-                return "SETTINGS_TOGGLE";
-            case CUJ_SHADE_DIALOG_OPEN:
-                return "SHADE_DIALOG_OPEN";
-            case CUJ_USER_DIALOG_OPEN:
-                return "USER_DIALOG_OPEN";
-            case CUJ_TASKBAR_EXPAND:
-                return "TASKBAR_EXPAND";
-            case CUJ_TASKBAR_COLLAPSE:
-                return "TASKBAR_COLLAPSE";
-            case CUJ_SHADE_CLEAR_ALL:
-                return "SHADE_CLEAR_ALL";
-            case CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION:
-                return "LAUNCHER_UNLOCK_ENTRANCE_ANIMATION";
-            case CUJ_LOCKSCREEN_OCCLUSION:
-                return "LOCKSCREEN_OCCLUSION";
-            case CUJ_RECENTS_SCROLLING:
-                return "RECENTS_SCROLLING";
-            case CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS:
-                return "LAUNCHER_APP_SWIPE_TO_RECENTS";
-            case CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE:
-                return "LAUNCHER_CLOSE_ALL_APPS_SWIPE";
-            case CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME:
-                return "LAUNCHER_CLOSE_ALL_APPS_TO_HOME";
-            case CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION:
-                return "LOCKSCREEN_CLOCK_MOVE_ANIMATION";
-            case CUJ_LAUNCHER_OPEN_SEARCH_RESULT:
-                return "LAUNCHER_OPEN_SEARCH_RESULT";
-            case CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK:
-                return "LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK";
-            case CUJ_IME_INSETS_SHOW_ANIMATION:
-                return "IME_INSETS_SHOW_ANIMATION";
-            case CUJ_IME_INSETS_HIDE_ANIMATION:
-                return "IME_INSETS_HIDE_ANIMATION";
-            case CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER:
-                return "SPLIT_SCREEN_DOUBLE_TAP_DIVIDER";
-            case CUJ_LAUNCHER_UNFOLD_ANIM:
-                return "LAUNCHER_UNFOLD_ANIM";
-            case CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY:
-                return "PREDICTIVE_BACK_CROSS_ACTIVITY";
-            case CUJ_PREDICTIVE_BACK_CROSS_TASK:
-                return "PREDICTIVE_BACK_CROSS_TASK";
-            case CUJ_PREDICTIVE_BACK_HOME:
-                return "PREDICTIVE_BACK_HOME";
-        }
-        return "UNKNOWN";
+        mWorker.post(() -> logFunction.invoke(unixNanos, elapsedNanos, realtimeNanos));
     }
 
     private static class TrackerResult {
@@ -1147,9 +613,10 @@ public class InteractionJankMonitor {
         private final Context mContext;
         private final long mTimeout;
         private final String mTag;
+        private final String mSessionName;
         private final boolean mSurfaceOnly;
         private final SurfaceControl mSurfaceControl;
-        private final @CujType int mCujType;
+        private final @Cuj.CujType int mCujType;
         private final boolean mDeferMonitor;
         private final Handler mHandler;
 
@@ -1167,17 +634,17 @@ public class InteractionJankMonitor {
             private String mAttrTag = "";
             private boolean mAttrSurfaceOnly;
             private SurfaceControl mAttrSurfaceControl;
-            private @CujType int mAttrCujType;
+            private final @Cuj.CujType int mAttrCujType;
             private boolean mAttrDeferMonitor = true;
 
             /**
              * Creates a builder which instruments only surface.
-             * @param cuj The enum defined in {@link InteractionJankMonitor.CujType}.
+             * @param cuj The enum defined in {@link Cuj.CujType}.
              * @param context context
              * @param surfaceControl surface control
              * @return builder
              */
-            public static Builder withSurface(@CujType int cuj, @NonNull Context context,
+            public static Builder withSurface(@Cuj.CujType int cuj, @NonNull Context context,
                     @NonNull SurfaceControl surfaceControl) {
                 return new Builder(cuj)
                         .setContext(context)
@@ -1187,16 +654,17 @@ public class InteractionJankMonitor {
 
             /**
              * Creates a builder which instruments both surface and view.
-             * @param cuj The enum defined in {@link InteractionJankMonitor.CujType}.
+             * @param cuj The enum defined in {@link Cuj.CujType}.
              * @param view view
              * @return builder
              */
-            public static Builder withView(@CujType int cuj, @NonNull View view) {
-                return new Builder(cuj).setView(view)
+            public static Builder withView(@Cuj.CujType int cuj, @NonNull View view) {
+                return new Builder(cuj)
+                        .setView(view)
                         .setContext(view.getContext());
             }
 
-            private Builder(@CujType int cuj) {
+            private Builder(@Cuj.CujType int cuj) {
                 mAttrCujType = cuj;
             }
 
@@ -1281,11 +749,12 @@ public class InteractionJankMonitor {
             }
         }
 
-        private Configuration(@CujType int cuj, View view, String tag, long timeout,
+        private Configuration(@Cuj.CujType int cuj, View view, @NonNull String tag, long timeout,
                 boolean surfaceOnly, Context context, SurfaceControl surfaceControl,
                 boolean deferMonitor) {
             mCujType = cuj;
             mTag = tag;
+            mSessionName = generateSessionName(Cuj.getNameOfCuj(cuj), tag);
             mTimeout = timeout;
             mView = view;
             mSurfaceOnly = surfaceOnly;
@@ -1298,6 +767,23 @@ public class InteractionJankMonitor {
             mHandler = mSurfaceOnly ? mContext.getMainThreadHandler() : mView.getHandler();
         }
 
+        @VisibleForTesting
+        public static String generateSessionName(
+                @NonNull String cujName, @NonNull String cujPostfix) {
+            final boolean hasPostfix = !TextUtils.isEmpty(cujPostfix);
+            if (hasPostfix) {
+                final int remaining = MAX_LENGTH_SESSION_NAME - cujName.length();
+                if (cujPostfix.length() > remaining) {
+                    cujPostfix = cujPostfix.substring(0, remaining - 3).concat("...");
+                }
+            }
+            // The max length of the whole string should be:
+            // 105 with postfix, 83 without postfix
+            return hasPostfix
+                    ? TextUtils.formatSimple("J<%s::%s>", cujName, cujPostfix)
+                    : TextUtils.formatSimple("J<%s>", cujName);
+        }
+
         private void validate() {
             boolean shouldThrow = false;
             final StringBuilder msg = new StringBuilder();
@@ -1360,10 +846,10 @@ public class InteractionJankMonitor {
             return mSurfaceControl;
         }
 
-        @VisibleForTesting
         /**
          * @return a view which is attached to the view tree.
          */
+        @VisibleForTesting
         public View getView() {
             return mView;
         }
@@ -1375,7 +861,7 @@ public class InteractionJankMonitor {
             return mDeferMonitor;
         }
 
-        @VisibleForTesting
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
         public Handler getHandler() {
             return mHandler;
         }
@@ -1387,79 +873,27 @@ public class InteractionJankMonitor {
         public int getDisplayId() {
             return (mSurfaceOnly ? mContext : mView.getContext()).getDisplayId();
         }
-    }
-
-    /**
-     * A class to represent a session.
-     */
-    public static class Session {
-        @CujType
-        private final int mCujType;
-        private final long mTimeStamp;
-        @Reasons
-        private int mReason = REASON_END_UNKNOWN;
-        private final String mName;
-
-        public Session(@CujType int cujType, @NonNull String postfix) {
-            mCujType = cujType;
-            mTimeStamp = System.nanoTime();
-            mName = generateSessionName(getNameOfCuj(cujType), postfix);
-        }
-
-        private String generateSessionName(@NonNull String cujName, @NonNull String cujPostfix) {
-            final boolean hasPostfix = !TextUtils.isEmpty(cujPostfix);
-            // We assert that the cujName shouldn't exceed MAX_LENGTH_OF_CUJ_NAME.
-            if (cujName.length() > MAX_LENGTH_OF_CUJ_NAME) {
-                throw new IllegalArgumentException(TextUtils.formatSimple(
-                        "The length of cuj name <%s> exceeds %d", cujName, MAX_LENGTH_OF_CUJ_NAME));
-            }
-            if (hasPostfix) {
-                final int remaining = MAX_LENGTH_SESSION_NAME - cujName.length();
-                if (cujPostfix.length() > remaining) {
-                    cujPostfix = cujPostfix.substring(0, remaining - 3).concat("...");
-                }
-            }
-            // The max length of the whole string should be:
-            // 105 with postfix, 83 without postfix
-            return hasPostfix
-                    ? TextUtils.formatSimple("J<%s::%s>", cujName, cujPostfix)
-                    : TextUtils.formatSimple("J<%s>", cujName);
-        }
 
-        @CujType
-        public int getCuj() {
-            return mCujType;
+        public String getSessionName() {
+            return mSessionName;
         }
 
         public int getStatsdInteractionType() {
-            return CUJ_TO_STATSD_INTERACTION_TYPE[mCujType];
+            return Cuj.getStatsdInteractionType(mCujType);
         }
 
         /** Describes whether the measurement from this session should be written to statsd. */
         public boolean logToStatsd() {
-            return getStatsdInteractionType() != NO_STATSD_LOGGING;
+            return Cuj.logToStatsd(mCujType);
         }
 
         public String getPerfettoTrigger() {
-            return String.format(Locale.US, "com.android.telemetry.interaction-jank-monitor-%d",
-                    mCujType);
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public long getTimeStamp() {
-            return mTimeStamp;
-        }
-
-        public void setReason(@Reasons int reason) {
-            mReason = reason;
+            return TextUtils.formatSimple(
+                    "com.android.telemetry.interaction-jank-monitor-%d", mCujType);
         }
 
-        @Reasons
-        public int getReason() {
-            return mReason;
+        public @Cuj.CujType int getCujType() {
+            return mCujType;
         }
     }
 
@@ -1468,15 +902,15 @@ public class InteractionJankMonitor {
         void invoke(long unixNanos, long elapsedNanos, long realtimeNanos);
     }
 
-    private void postEventLogToWorkerThread(TimeFunction logFunction) {
-        final Instant now = Instant.now();
-        final long unixNanos = TimeUnit.NANOSECONDS.convert(now.getEpochSecond(), TimeUnit.SECONDS)
-                + now.getNano();
-        final long elapsedNanos = SystemClock.elapsedRealtimeNanos();
-        final long realtimeNanos = SystemClock.uptimeNanos();
+    static class RunningTracker {
+        public final Configuration mConfig;
+        public final FrameTracker mTracker;
+        public final Runnable mTimeoutAction;
 
-        mWorker.getThreadHandler().post(() -> {
-            logFunction.invoke(unixNanos, elapsedNanos, realtimeNanos);
-        });
+        RunningTracker(Configuration config, FrameTracker tracker, Runnable timeoutAction) {
+            this.mConfig = config;
+            this.mTracker = tracker;
+            this.mTimeoutAction = timeoutAction;
+        }
     }
 }
diff --git a/core/java/com/android/internal/jank/InteractionMonitorDebugOverlay.java b/core/java/com/android/internal/jank/InteractionMonitorDebugOverlay.java
index ef7944c21ad2..f3f16a0c662d 100644
--- a/core/java/com/android/internal/jank/InteractionMonitorDebugOverlay.java
+++ b/core/java/com/android/internal/jank/InteractionMonitorDebugOverlay.java
@@ -34,7 +34,6 @@ import android.view.WindowCallbacks;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.jank.FrameTracker.Reasons;
-import com.android.internal.jank.InteractionJankMonitor.CujType;
 
 /**
  * An overlay that uses WindowCallbacks to draw the names of all running CUJs to the window
@@ -94,14 +93,14 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks {
     }
 
     @UiThread
-    private boolean attachViewRootIfNeeded(FrameTracker tracker) {
-        FrameTracker.ViewRootWrapper viewRoot = tracker.getViewRoot();
+    private boolean attachViewRootIfNeeded(InteractionJankMonitor.RunningTracker tracker) {
+        FrameTracker.ViewRootWrapper viewRoot = tracker.mTracker.getViewRoot();
         if (mViewRoot == null && viewRoot != null) {
             // Add a trace marker so we can identify traces that were captured while the debug
             // overlay was enabled. Traces that use the debug overlay should NOT be used for
             // performance analysis.
             Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, TRACK_NAME, "DEBUG_OVERLAY_DRAW", 0);
-            mHandler = tracker.getHandler();
+            mHandler = tracker.mConfig.getHandler();
             mViewRoot = viewRoot;
             mHandler.runWithScissors(() -> viewRoot.addWindowCallbacks(this),
                     InteractionJankMonitor.EXECUTOR_TASK_TIMEOUT);
@@ -111,11 +110,12 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks {
         return false;
     }
 
+    @GuardedBy("mLock")
     private float getWidthOfLongestCujName(int cujFontSize) {
         mDebugPaint.setTextSize(cujFontSize);
         float maxLength = 0;
         for (int i = 0; i < mRunningCujs.size(); i++) {
-            String cujName = InteractionJankMonitor.getNameOfCuj(mRunningCujs.keyAt(i));
+            String cujName = Cuj.getNameOfCuj(mRunningCujs.keyAt(i));
             float textLength = mDebugPaint.measureText(cujName);
             if (textLength > maxLength) {
                 maxLength = textLength;
@@ -149,8 +149,8 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks {
     }
 
     @UiThread
-    void onTrackerRemoved(@CujType int removedCuj, @Reasons int reason,
-                          SparseArray<FrameTracker> runningTrackers) {
+    void onTrackerRemoved(@Cuj.CujType int removedCuj, @Reasons int reason,
+                          SparseArray<InteractionJankMonitor.RunningTracker> runningTrackers) {
         synchronized (mLock) {
             mRunningCujs.put(removedCuj, reason);
             // If REASON_STILL_RUNNING is not in mRunningCujs, then all CUJs have ended
@@ -164,7 +164,7 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks {
                     // trackers
                     for (int i = 0; i < runningTrackers.size(); i++) {
                         if (mViewRoot.equals(
-                                runningTrackers.valueAt(i).getViewRoot())) {
+                                runningTrackers.valueAt(i).mTracker.getViewRoot())) {
                             needsNewViewRoot = false;
                             break;
                         }
@@ -185,7 +185,7 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks {
     }
 
     @UiThread
-    void onTrackerAdded(@CujType int addedCuj, FrameTracker tracker) {
+    void onTrackerAdded(@Cuj.CujType int addedCuj, InteractionJankMonitor.RunningTracker tracker) {
         synchronized (mLock) {
             // Use REASON_STILL_RUNNING (not technically one of the '@Reasons') to indicate the CUJ
             // is still running
@@ -230,41 +230,44 @@ class InteractionMonitorDebugOverlay implements WindowCallbacks {
         int cujFontSize = dipToPx(18);
         final float cujNameTextHeight = getTextHeight(cujFontSize);
         final float packageNameTextHeight = getTextHeight(packageNameFontSize);
-        float maxLength = getWidthOfLongestCujName(cujFontSize);
 
-        final int dx = (int) ((w - maxLength) / 2f);
-        canvas.translate(dx, dy);
-        // Draw background rectangle for displaying the text showing the CUJ name
-        mDebugPaint.setColor(mBgColor);
-        canvas.drawRect(
-                -padding * 2, // more padding on top so we can draw the package name
-                -padding,
-                padding * 2 + maxLength,
-                padding * 2 + packageNameTextHeight + cujNameTextHeight * mRunningCujs.size(),
-                mDebugPaint);
-        mDebugPaint.setTextSize(packageNameFontSize);
-        mDebugPaint.setColor(Color.BLACK);
-        mDebugPaint.setStrikeThruText(false);
-        canvas.translate(0, packageNameTextHeight);
-        canvas.drawText("package:" + mPackageName, 0, 0, mDebugPaint);
-        mDebugPaint.setTextSize(cujFontSize);
-        // Draw text for CUJ names
-        for (int i = 0; i < mRunningCujs.size(); i++) {
-            int status = mRunningCujs.valueAt(i);
-            if (status == REASON_STILL_RUNNING) {
-                mDebugPaint.setColor(Color.BLACK);
-                mDebugPaint.setStrikeThruText(false);
-            } else if (status == REASON_END_NORMAL) {
-                mDebugPaint.setColor(Color.GRAY);
-                mDebugPaint.setStrikeThruText(false);
-            } else {
-                // Cancelled, or otherwise ended for a bad reason
-                mDebugPaint.setColor(Color.RED);
-                mDebugPaint.setStrikeThruText(true);
+        synchronized (mLock) {
+            float maxLength = getWidthOfLongestCujName(cujFontSize);
+
+            final int dx = (int) ((w - maxLength) / 2f);
+            canvas.translate(dx, dy);
+            // Draw background rectangle for displaying the text showing the CUJ name
+            mDebugPaint.setColor(mBgColor);
+            canvas.drawRect(
+                    -padding * 2, // more padding on top so we can draw the package name
+                    -padding,
+                    padding * 2 + maxLength,
+                    padding * 2 + packageNameTextHeight + cujNameTextHeight * mRunningCujs.size(),
+                    mDebugPaint);
+            mDebugPaint.setTextSize(packageNameFontSize);
+            mDebugPaint.setColor(Color.BLACK);
+            mDebugPaint.setStrikeThruText(false);
+            canvas.translate(0, packageNameTextHeight);
+            canvas.drawText("package:" + mPackageName, 0, 0, mDebugPaint);
+            mDebugPaint.setTextSize(cujFontSize);
+            // Draw text for CUJ names
+            for (int i = 0; i < mRunningCujs.size(); i++) {
+                int status = mRunningCujs.valueAt(i);
+                if (status == REASON_STILL_RUNNING) {
+                    mDebugPaint.setColor(Color.BLACK);
+                    mDebugPaint.setStrikeThruText(false);
+                } else if (status == REASON_END_NORMAL) {
+                    mDebugPaint.setColor(Color.GRAY);
+                    mDebugPaint.setStrikeThruText(false);
+                } else {
+                    // Cancelled, or otherwise ended for a bad reason
+                    mDebugPaint.setColor(Color.RED);
+                    mDebugPaint.setStrikeThruText(true);
+                }
+                String cujName = Cuj.getNameOfCuj(mRunningCujs.keyAt(i));
+                canvas.translate(0, cujNameTextHeight);
+                canvas.drawText(cujName, 0, 0, mDebugPaint);
             }
-            String cujName = InteractionJankMonitor.getNameOfCuj(mRunningCujs.keyAt(i));
-            canvas.translate(0, cujNameTextHeight);
-            canvas.drawText(cujName, 0, 0, mDebugPaint);
         }
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/jank/CujTest.java b/core/tests/coretests/src/com/android/internal/jank/CujTest.java
new file mode 100644
index 000000000000..bf35ed0a1601
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/jank/CujTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2023 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.internal.jank;
+
+import static android.text.TextUtils.formatSimple;
+
+import static com.android.internal.jank.Cuj.getNameOfCuj;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@SmallTest
+public class CujTest {
+    private static final String ENUM_NAME_PREFIX =
+            "UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__";
+    private static final Set<String> DEPRECATED_VALUES = new HashSet<>() {
+        {
+            add(ENUM_NAME_PREFIX + "IME_INSETS_ANIMATION");
+        }
+    };
+    private static final Map<Integer, String> ENUM_NAME_EXCEPTION_MAP = new HashMap<>() {
+        {
+            put(Cuj.CUJ_NOTIFICATION_ADD, getEnumName("SHADE_NOTIFICATION_ADD"));
+            put(Cuj.CUJ_NOTIFICATION_HEADS_UP_APPEAR, getEnumName("SHADE_HEADS_UP_APPEAR"));
+            put(Cuj.CUJ_NOTIFICATION_APP_START, getEnumName("SHADE_APP_LAUNCH"));
+            put(Cuj.CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR, getEnumName("SHADE_HEADS_UP_DISAPPEAR"));
+            put(Cuj.CUJ_NOTIFICATION_REMOVE, getEnumName("SHADE_NOTIFICATION_REMOVE"));
+            put(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, getEnumName("NOTIFICATION_SHADE_SWIPE"));
+            put(Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, getEnumName("SHADE_QS_EXPAND_COLLAPSE"));
+            put(Cuj.CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE, getEnumName("SHADE_QS_SCROLL_SWIPE"));
+            put(Cuj.CUJ_NOTIFICATION_SHADE_ROW_EXPAND, getEnumName("SHADE_ROW_EXPAND"));
+            put(Cuj.CUJ_NOTIFICATION_SHADE_ROW_SWIPE, getEnumName("SHADE_ROW_SWIPE"));
+            put(Cuj.CUJ_NOTIFICATION_SHADE_SCROLL_FLING, getEnumName("SHADE_SCROLL_FLING"));
+        }
+    };
+
+    @Rule
+    public final Expect mExpect = Expect.create();
+
+    @Test
+    public void testCujNameLimit() {
+        getCujConstants().forEach(f -> {
+            final int cuj = getIntFieldChecked(f);
+            mExpect.withMessage(formatSimple("Too long CUJ(%d) name: %s", cuj, getNameOfCuj(cuj)))
+                    .that(getNameOfCuj(cuj).length())
+                    .isAtMost(Cuj.MAX_LENGTH_OF_CUJ_NAME);
+        });
+    }
+
+    @Test
+    public void testCujTypeEnumCorrectlyDefined() throws Exception {
+        List<Field> cujEnumFields = getCujConstants().toList();
+
+        HashSet<Integer> allValues = new HashSet<>();
+        for (Field field : cujEnumFields) {
+            int fieldValue = field.getInt(null);
+            assertWithMessage("All CujType values must be unique. Field %s repeats existing value.",
+                    field.getName())
+                    .that(allValues.add(fieldValue))
+                    .isTrue();
+            assertWithMessage("Field %s must have a value <= LAST_CUJ", field.getName())
+                    .that(fieldValue)
+                    .isAtMost(Cuj.LAST_CUJ);
+            assertWithMessage("Field %s must have a statsd mapping.", field.getName())
+                    .that(Cuj.logToStatsd(fieldValue))
+                    .isTrue();
+        }
+    }
+
+    @Test
+    public void testCujsMapToEnumsCorrectly() {
+        List<Field> cujs = getCujConstants().toList();
+
+        Map<Integer, String> enumsMap = Arrays.stream(FrameworkStatsLog.class.getDeclaredFields())
+                .filter(f -> f.getName().startsWith(ENUM_NAME_PREFIX)
+                        && !DEPRECATED_VALUES.contains(f.getName())
+                        && Modifier.isStatic(f.getModifiers())
+                        && f.getType() == int.class)
+                .collect(Collectors.toMap(CujTest::getIntFieldChecked, Field::getName));
+
+        assertThat(enumsMap.size() - 1).isEqualTo(cujs.size());
+
+        cujs.forEach(f -> {
+            final int cuj = getIntFieldChecked(f);
+            final String cujName = f.getName();
+            final String expectedEnumName =
+                    ENUM_NAME_EXCEPTION_MAP.getOrDefault(cuj, getEnumName(cujName.substring(4)));
+            final int enumKey = Cuj.getStatsdInteractionType(cuj);
+            final String enumName = enumsMap.get(enumKey);
+            final String expectedNameOfCuj = formatSimple("CUJ_%s", getNameOfCuj(cuj));
+
+            mExpect.withMessage(
+                    formatSimple("%s (%d) not matches %s (%d)", cujName, cuj, enumName, enumKey))
+                    .that(expectedEnumName.equals(enumName))
+                    .isTrue();
+            mExpect.withMessage(
+                    formatSimple("getNameOfCuj(%d) not matches: %s, expected=%s",
+                            cuj, cujName, expectedNameOfCuj))
+                    .that(cujName.equals(expectedNameOfCuj))
+                    .isTrue();
+        });
+    }
+
+    private static String getEnumName(String name) {
+        return formatSimple("%s%s", ENUM_NAME_PREFIX, name);
+    }
+
+    private static int getIntFieldChecked(Field field) {
+        try {
+            return field.getInt(null);
+        } catch (IllegalAccessException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private static Stream<Field> getCujConstants() {
+        return Arrays.stream(Cuj.class.getDeclaredFields())
+                .filter(f -> f.getName().startsWith("CUJ_")
+                        && Modifier.isStatic(f.getModifiers())
+                        && f.getType() == int.class);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 1b9717a6dfc5..1a7117e3b4a1 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -22,9 +22,8 @@ import static android.view.SurfaceControl.JankData.JANK_SURFACEFLINGER_DEADLINE_
 
 import static com.android.internal.jank.FrameTracker.SurfaceControlWrapper;
 import static com.android.internal.jank.FrameTracker.ViewRootWrapper;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_TO_STATSD_INTERACTION_TYPE;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_WALLPAPER_TRANSITION;
+import static com.android.internal.jank.Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
+import static com.android.internal.jank.Cuj.CUJ_WALLPAPER_TRANSITION;
 import static com.android.internal.util.FrameworkStatsLog.UI_INTERACTION_FRAME_INFO_REPORTED;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -49,15 +48,14 @@ import android.view.SurfaceControl.OnJankDataListener;
 import android.view.View;
 import android.view.ViewAttachTestActivity;
 
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
 import androidx.test.filters.SmallTest;
-import androidx.test.rule.ActivityTestRule;
 
 import com.android.internal.jank.FrameTracker.ChoreographerWrapper;
 import com.android.internal.jank.FrameTracker.FrameMetricsWrapper;
 import com.android.internal.jank.FrameTracker.StatsLogWrapper;
 import com.android.internal.jank.FrameTracker.ThreadedRendererWrapper;
 import com.android.internal.jank.InteractionJankMonitor.Configuration;
-import com.android.internal.jank.InteractionJankMonitor.Session;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -69,14 +67,14 @@ import java.util.concurrent.TimeUnit;
 
 @SmallTest
 public class FrameTrackerTest {
-    private static final String CUJ_POSTFIX = "";
+    private static final String SESSION_NAME = "SessionName";
     private static final long FRAME_TIME_60Hz = (long) 1e9 / 60;
 
     private ViewAttachTestActivity mActivity;
 
     @Rule
-    public ActivityTestRule<ViewAttachTestActivity> mRule =
-            new ActivityTestRule<>(ViewAttachTestActivity.class);
+    public ActivityScenarioRule<ViewAttachTestActivity> mRule =
+            new ActivityScenarioRule<>(ViewAttachTestActivity.class);
 
     private ThreadedRendererWrapper mRenderer;
     private FrameMetricsWrapper mWrapper;
@@ -86,12 +84,13 @@ public class FrameTrackerTest {
     private StatsLogWrapper mStatsLog;
     private ArgumentCaptor<OnJankDataListener> mListenerCapture;
     private SurfaceControl mSurfaceControl;
+    private FrameTracker.FrameTrackerListener mTrackerListener;
     private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
 
     @Before
     public void setup() {
         // Prepare an activity for getting ThreadedRenderer later.
-        mActivity = mRule.getActivity();
+        mRule.getScenario().onActivity(activity -> mActivity = activity);
         View view = mActivity.getWindow().getDecorView();
         assertThat(view.isAttachedToWindow()).isTrue();
 
@@ -116,36 +115,38 @@ public class FrameTrackerTest {
         mChoreographer = mock(ChoreographerWrapper.class);
         mStatsLog = mock(StatsLogWrapper.class);
         mRunnableArgumentCaptor = ArgumentCaptor.forClass(Runnable.class);
+        mTrackerListener = mock(FrameTracker.FrameTrackerListener.class);
     }
 
-    private FrameTracker spyFrameTracker(int cuj, String postfix, boolean surfaceOnly) {
-        InteractionJankMonitor monitor = mock(InteractionJankMonitor.class);
-        Handler handler = mRule.getActivity().getMainThreadHandler();
-        Session session = new Session(cuj, postfix);
+    private FrameTracker spyFrameTracker(boolean surfaceOnly) {
+        Handler handler = mActivity.getMainThreadHandler();
         Configuration config = mock(Configuration.class);
+        when(config.getSessionName()).thenReturn(SESSION_NAME);
         when(config.isSurfaceOnly()).thenReturn(surfaceOnly);
         when(config.getSurfaceControl()).thenReturn(mSurfaceControl);
         when(config.shouldDeferMonitor()).thenReturn(true);
         when(config.getDisplayId()).thenReturn(42);
-        View view = mRule.getActivity().getWindow().getDecorView();
+        View view = mActivity.getWindow().getDecorView();
         Handler spyHandler = spy(new Handler(handler.getLooper()));
         when(config.getView()).thenReturn(surfaceOnly ? null : view);
         when(config.getHandler()).thenReturn(spyHandler);
+        when(config.logToStatsd()).thenReturn(true);
+        when(config.getStatsdInteractionType()).thenReturn(surfaceOnly
+                ? Cuj.getStatsdInteractionType(CUJ_WALLPAPER_TRANSITION)
+                : Cuj.getStatsdInteractionType(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE));
         FrameTracker frameTracker = Mockito.spy(
-                new FrameTracker(monitor, session, spyHandler, mRenderer, mViewRootWrapper,
+                new FrameTracker(config, mRenderer, mViewRootWrapper,
                         mSurfaceControlWrapper, mChoreographer, mWrapper, mStatsLog,
                         /* traceThresholdMissedFrames= */ 1,
                         /* traceThresholdFrameTimeMillis= */ -1,
-                        /* FrameTrackerListener= */ null, config));
-        doNothing().when(frameTracker).triggerPerfetto();
+                        mTrackerListener));
         doNothing().when(frameTracker).postTraceStartMarker(mRunnableArgumentCaptor.capture());
         return frameTracker;
     }
 
     @Test
     public void testOnlyFirstWindowFrameOverThreshold() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         // Just provide current timestamp anytime mWrapper asked for VSYNC_TIMESTAMP
         when(mWrapper.getMetric(FrameMetrics.VSYNC_TIMESTAMP))
@@ -169,11 +170,11 @@ public class FrameTrackerTest {
         sendFrame(tracker, 500, JANK_APP_DEADLINE_MISSED, 103L);
 
         verify(tracker).removeObservers();
-        verify(tracker, never()).triggerPerfetto();
+        verify(mTrackerListener, never()).triggerPerfetto(any());
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]),
+                eq(Cuj.getStatsdInteractionType(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)),
                 eq(2L) /* totalFrames */,
                 eq(0L) /* missedFrames */,
                 eq(5000000L) /* maxFrameTimeNanos */,
@@ -184,8 +185,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testSfJank() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -206,12 +206,12 @@ public class FrameTrackerTest {
         verify(tracker).removeObservers();
 
         // We detected a janky frame - trigger Perfetto
-        verify(tracker).triggerPerfetto();
+        verify(mTrackerListener).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]),
+                eq(Cuj.getStatsdInteractionType(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)),
                 eq(2L) /* totalFrames */,
                 eq(1L) /* missedFrames */,
                 eq(40000000L) /* maxFrameTimeNanos */,
@@ -222,8 +222,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testFirstFrameJankyNoTrigger() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -243,13 +242,12 @@ public class FrameTrackerTest {
 
         verify(tracker).removeObservers();
 
-        // We detected a janky frame - trigger Perfetto
-        verify(tracker, never()).triggerPerfetto();
+        verify(mTrackerListener, never()).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]),
+                eq(Cuj.getStatsdInteractionType(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)),
                 eq(2L) /* totalFrames */,
                 eq(0L) /* missedFrames */,
                 eq(4000000L) /* maxFrameTimeNanos */,
@@ -260,8 +258,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testOtherFrameOverThreshold() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -282,12 +279,12 @@ public class FrameTrackerTest {
         verify(tracker).removeObservers();
 
         // We detected a janky frame - trigger Perfetto
-        verify(tracker).triggerPerfetto();
+        verify(mTrackerListener).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]),
+                eq(Cuj.getStatsdInteractionType(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)),
                 eq(2L) /* totalFrames */,
                 eq(1L) /* missedFrames */,
                 eq(40000000L) /* maxFrameTimeNanos */,
@@ -298,8 +295,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testLastFrameOverThresholdBeforeEnd() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -323,12 +319,12 @@ public class FrameTrackerTest {
         verify(tracker).removeObservers();
 
         // We detected a janky frame - trigger Perfetto
-        verify(tracker).triggerPerfetto();
+        verify(mTrackerListener).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]),
+                eq(Cuj.getStatsdInteractionType(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)),
                 eq(2L) /* totalFrames */,
                 eq(1L) /* missedFrames */,
                 eq(50000000L) /* maxFrameTimeNanos */,
@@ -342,8 +338,7 @@ public class FrameTrackerTest {
      */
     @Test
     public void testNoOvercountingAfterEnd() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -367,11 +362,11 @@ public class FrameTrackerTest {
         sendFrame(tracker, 50, JANK_APP_DEADLINE_MISSED, 103L);
 
         verify(tracker).removeObservers();
-        verify(tracker, never()).triggerPerfetto();
+        verify(mTrackerListener, never()).triggerPerfetto(any());
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]),
+                eq(Cuj.getStatsdInteractionType(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)),
                 eq(2L) /* totalFrames */,
                 eq(0L) /* missedFrames */,
                 eq(4000000L) /* maxFrameTimeNanos */,
@@ -382,8 +377,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testBeginCancel() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -402,13 +396,12 @@ public class FrameTrackerTest {
         tracker.cancel(FrameTracker.REASON_CANCEL_NORMAL);
         verify(tracker).removeObservers();
         // Since the tracker has been cancelled, shouldn't trigger perfetto.
-        verify(tracker, never()).triggerPerfetto();
+        verify(mTrackerListener, never()).triggerPerfetto(any());
     }
 
     @Test
     public void testCancelIfEndVsyncIdEqualsToBeginVsyncId() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -426,13 +419,12 @@ public class FrameTrackerTest {
         verify(tracker).removeObservers();
 
         // Should never trigger Perfetto since it is a cancel.
-        verify(tracker, never()).triggerPerfetto();
+        verify(mTrackerListener, never()).triggerPerfetto(any());
     }
 
     @Test
     public void testCancelIfEndVsyncIdLessThanBeginVsyncId() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -450,13 +442,12 @@ public class FrameTrackerTest {
         verify(tracker).removeObservers();
 
         // Should never trigger Perfetto since it is a cancel.
-        verify(tracker, never()).triggerPerfetto();
+        verify(mTrackerListener, never()).triggerPerfetto(any());
     }
 
     @Test
     public void testCancelWhenSessionNeverBegun() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         tracker.cancel(FrameTracker.REASON_CANCEL_NORMAL);
         verify(tracker).removeObservers();
@@ -464,8 +455,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testEndWhenSessionNeverBegun() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX, /* surfaceOnly= */ false);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ false);
 
         tracker.end(FrameTracker.REASON_END_NORMAL);
         verify(tracker).removeObservers();
@@ -473,8 +463,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testSurfaceOnlyOtherFrameJanky() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ true);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -495,12 +484,12 @@ public class FrameTrackerTest {
         sendFrame(tracker, JANK_NONE, 103L);
 
         verify(mSurfaceControlWrapper).removeJankStatsListener(any());
-        verify(tracker).triggerPerfetto();
+        verify(mTrackerListener).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]),
+                eq(Cuj.getStatsdInteractionType(CUJ_WALLPAPER_TRANSITION)),
                 eq(2L) /* totalFrames */,
                 eq(1L) /* missedFrames */,
                 eq(0L) /* maxFrameTimeNanos */,
@@ -511,8 +500,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testSurfaceOnlyFirstFrameJanky() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ true);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -533,12 +521,12 @@ public class FrameTrackerTest {
         sendFrame(tracker, JANK_NONE, 103L);
 
         verify(mSurfaceControlWrapper).removeJankStatsListener(any());
-        verify(tracker, never()).triggerPerfetto();
+        verify(mTrackerListener, never()).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]),
+                eq(Cuj.getStatsdInteractionType(CUJ_WALLPAPER_TRANSITION)),
                 eq(2L) /* totalFrames */,
                 eq(0L) /* missedFrames */,
                 eq(0L) /* maxFrameTimeNanos */,
@@ -549,8 +537,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testSurfaceOnlyLastFrameJanky() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ true);
 
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
@@ -571,12 +558,12 @@ public class FrameTrackerTest {
         sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 103L);
 
         verify(mSurfaceControlWrapper).removeJankStatsListener(any());
-        verify(tracker, never()).triggerPerfetto();
+        verify(mTrackerListener, never()).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]),
+                eq(Cuj.getStatsdInteractionType(CUJ_WALLPAPER_TRANSITION)),
                 eq(2L) /* totalFrames */,
                 eq(0L) /* missedFrames */,
                 eq(0L) /* maxFrameTimeNanos */,
@@ -587,8 +574,7 @@ public class FrameTrackerTest {
 
     @Test
     public void testMaxSuccessiveMissedFramesCount() {
-        FrameTracker tracker = spyFrameTracker(
-                CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true);
+        FrameTracker tracker = spyFrameTracker(/* surfaceOnly= */ true);
         when(mChoreographer.getVsyncId()).thenReturn(100L);
         tracker.begin();
         mRunnableArgumentCaptor.getValue().run();
@@ -604,11 +590,11 @@ public class FrameTrackerTest {
         sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 106L);
         sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 107L);
         verify(mSurfaceControlWrapper).removeJankStatsListener(any());
-        verify(tracker).triggerPerfetto();
+        verify(mTrackerListener).triggerPerfetto(any());
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
                 eq(DisplayRefreshRate.REFRESH_RATE_60_HZ),
-                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]),
+                eq(Cuj.getStatsdInteractionType(CUJ_WALLPAPER_TRANSITION)),
                 eq(6L) /* totalFrames */,
                 eq(5L) /* missedFrames */,
                 eq(0L) /* maxFrameTimeNanos */,
diff --git a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
index b61f995724e5..68095e5eb46c 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -20,23 +20,9 @@ import static android.text.TextUtils.formatSimple;
 
 import static com.android.internal.jank.FrameTracker.REASON_CANCEL_TIMEOUT;
 import static com.android.internal.jank.FrameTracker.REASON_END_NORMAL;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_ADD;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_APP_START;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_HEADS_UP_APPEAR;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_REMOVE;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_ROW_EXPAND;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_ROW_SWIPE;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_TO_STATSD_INTERACTION_TYPE;
-import static com.android.internal.jank.InteractionJankMonitor.MAX_LENGTH_OF_CUJ_NAME;
-import static com.android.internal.jank.InteractionJankMonitor.getNameOfCuj;
+import static com.android.internal.jank.InteractionJankMonitor.Configuration.generateSessionName;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -52,12 +38,11 @@ import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.SystemClock;
 import android.provider.DeviceConfig;
-import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewAttachTestActivity;
 
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
 import androidx.test.filters.SmallTest;
-import androidx.test.rule.ActivityTestRule;
 
 import com.android.internal.jank.FrameTracker.ChoreographerWrapper;
 import com.android.internal.jank.FrameTracker.FrameMetricsWrapper;
@@ -66,101 +51,54 @@ import com.android.internal.jank.FrameTracker.SurfaceControlWrapper;
 import com.android.internal.jank.FrameTracker.ThreadedRendererWrapper;
 import com.android.internal.jank.FrameTracker.ViewRootWrapper;
 import com.android.internal.jank.InteractionJankMonitor.Configuration;
-import com.android.internal.jank.InteractionJankMonitor.Session;
-import com.android.internal.util.FrameworkStatsLog;
 
 import com.google.common.truth.Expect;
 
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 @SmallTest
 public class InteractionJankMonitorTest {
-    private static final String CUJ_POSTFIX = "";
-    private static final SparseArray<String> ENUM_NAME_EXCEPTION_MAP = new SparseArray<>();
-    private static final String ENUM_NAME_PREFIX =
-            "UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__";
-
-    private static final ArrayList<String> DEPRECATED_VALUES = new ArrayList<>();
-
     private ViewAttachTestActivity mActivity;
     private View mView;
+    private Handler mHandler;
     private HandlerThread mWorker;
 
     @Rule
-    public ActivityTestRule<ViewAttachTestActivity> mRule =
-            new ActivityTestRule<>(ViewAttachTestActivity.class);
+    public ActivityScenarioRule<ViewAttachTestActivity> mRule =
+            new ActivityScenarioRule<>(ViewAttachTestActivity.class);
 
     @Rule
     public final Expect mExpect = Expect.create();
 
-    @BeforeClass
-    public static void initialize() {
-        ENUM_NAME_EXCEPTION_MAP.put(CUJ_NOTIFICATION_ADD, getEnumName("SHADE_NOTIFICATION_ADD"));
-        ENUM_NAME_EXCEPTION_MAP.put(CUJ_NOTIFICATION_APP_START, getEnumName("SHADE_APP_LAUNCH"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_HEADS_UP_APPEAR, getEnumName("SHADE_HEADS_UP_APPEAR"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR, getEnumName("SHADE_HEADS_UP_DISAPPEAR"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_REMOVE, getEnumName("SHADE_NOTIFICATION_REMOVE"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, getEnumName("NOTIFICATION_SHADE_SWIPE"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, getEnumName("SHADE_QS_EXPAND_COLLAPSE"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE, getEnumName("SHADE_QS_SCROLL_SWIPE"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_SHADE_ROW_EXPAND, getEnumName("SHADE_ROW_EXPAND"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_SHADE_ROW_SWIPE, getEnumName("SHADE_ROW_SWIPE"));
-        ENUM_NAME_EXCEPTION_MAP.put(
-                CUJ_NOTIFICATION_SHADE_SCROLL_FLING, getEnumName("SHADE_SCROLL_FLING"));
-        DEPRECATED_VALUES.add(ENUM_NAME_PREFIX + "IME_INSETS_ANIMATION");
-    }
-
-    private static String getEnumName(String name) {
-        return formatSimple("%s%s", ENUM_NAME_PREFIX, name);
-    }
-
     @Before
     public void setup() {
-        // Prepare an activity for getting ThreadedRenderer later.
-        mActivity = mRule.getActivity();
+        mRule.getScenario().onActivity(activity -> mActivity = activity);
         mView = mActivity.getWindow().getDecorView();
         assertThat(mView.isAttachedToWindow()).isTrue();
 
-        Handler handler = spy(new Handler(mActivity.getMainLooper()));
-        doReturn(true).when(handler).sendMessageAtTime(any(), anyLong());
+        mHandler = spy(new Handler(mActivity.getMainLooper()));
+        doReturn(true).when(mHandler).sendMessageAtTime(any(), anyLong());
         mWorker = mock(HandlerThread.class);
-        doReturn(handler).when(mWorker).getThreadHandler();
+        doReturn(mHandler).when(mWorker).getThreadHandler();
     }
 
     @Test
     public void testBeginEnd() {
         InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
-        FrameTracker tracker = createMockedFrameTracker(monitor, null);
-        doReturn(tracker).when(monitor).createFrameTracker(any(), any());
+        FrameTracker tracker = createMockedFrameTracker();
+        doReturn(tracker).when(monitor).createFrameTracker(any());
         doNothing().when(tracker).begin();
         doReturn(true).when(tracker).end(anyInt());
 
         // Simulate a trace session and see if begin / end are invoked.
-        assertThat(monitor.begin(mView, CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+        assertThat(monitor.begin(mView, Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
         verify(tracker).begin();
-        assertThat(monitor.end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+        assertThat(monitor.end(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
         verify(tracker).end(REASON_END_NORMAL);
     }
 
@@ -172,10 +110,10 @@ public class InteractionJankMonitorTest {
         propertiesValues.put("enabled", "false");
         DeviceConfig.Properties properties = new DeviceConfig.Properties(
                 DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR, propertiesValues);
-        monitor.getPropertiesChangedListener().onPropertiesChanged(properties);
+        monitor.updateProperties(properties);
 
-        assertThat(monitor.begin(mView, CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isFalse();
-        assertThat(monitor.end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isFalse();
+        assertThat(monitor.begin(mView, Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isFalse();
+        assertThat(monitor.end(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isFalse();
     }
 
     @Test
@@ -185,145 +123,57 @@ public class InteractionJankMonitorTest {
         assertThat(view.isAttachedToWindow()).isFalse();
 
         // Should return false if the view passed in is not attached to window yet.
-        assertThat(monitor.begin(view, CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isFalse();
-        assertThat(monitor.end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isFalse();
+        assertThat(monitor.begin(view, Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isFalse();
+        assertThat(monitor.end(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isFalse();
     }
 
     @Test
     public void testBeginTimeout() {
         ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
         InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
-        FrameTracker tracker = createMockedFrameTracker(monitor, null);
-        doReturn(tracker).when(monitor).createFrameTracker(any(), any());
+        FrameTracker tracker = createMockedFrameTracker();
+        doReturn(tracker).when(monitor).createFrameTracker(any());
         doNothing().when(tracker).begin();
         doReturn(true).when(tracker).cancel(anyInt());
 
-        assertThat(monitor.begin(mView, CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+        assertThat(monitor.begin(mView, Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
         verify(tracker).begin();
-        verify(monitor).scheduleTimeoutAction(anyInt(), anyLong(), captor.capture());
+        verify(monitor).scheduleTimeoutAction(any(), captor.capture());
         Runnable runnable = captor.getValue();
         assertThat(runnable).isNotNull();
-        mWorker.getThreadHandler().removeCallbacks(runnable);
         runnable.run();
-        verify(monitor).cancel(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, REASON_CANCEL_TIMEOUT);
+        verify(monitor).cancel(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, REASON_CANCEL_TIMEOUT);
         verify(tracker).cancel(REASON_CANCEL_TIMEOUT);
     }
 
-    @Test
-    public void testCujTypeEnumCorrectlyDefined() throws Exception {
-        List<Field> cujEnumFields =
-                Arrays.stream(InteractionJankMonitor.class.getDeclaredFields())
-                        .filter(field -> field.getName().startsWith("CUJ_")
-                                && Modifier.isStatic(field.getModifiers())
-                                && field.getType() == int.class)
-                        .collect(Collectors.toList());
-
-        HashSet<Integer> allValues = new HashSet<>();
-        for (Field field : cujEnumFields) {
-            int fieldValue = field.getInt(null);
-            assertWithMessage(
-                    "Field %s must have a mapping to a value in CUJ_TO_STATSD_INTERACTION_TYPE",
-                    field.getName())
-                    .that(fieldValue < CUJ_TO_STATSD_INTERACTION_TYPE.length)
-                    .isTrue();
-            assertWithMessage("All CujType values must be unique. Field %s repeats existing value.",
-                    field.getName())
-                    .that(allValues.add(fieldValue))
-                    .isTrue();
-        }
-    }
-
-    @Test
-    public void testCujsMapToEnumsCorrectly() {
-        List<Field> cujs = Arrays.stream(InteractionJankMonitor.class.getDeclaredFields())
-                .filter(f -> f.getName().startsWith("CUJ_")
-                        && Modifier.isStatic(f.getModifiers())
-                        && f.getType() == int.class)
-                .collect(Collectors.toList());
-
-        Map<Integer, String> enumsMap = Arrays.stream(FrameworkStatsLog.class.getDeclaredFields())
-                .filter(f -> f.getName().startsWith(ENUM_NAME_PREFIX)
-                        && !DEPRECATED_VALUES.contains(f.getName())
-                        && Modifier.isStatic(f.getModifiers())
-                        && f.getType() == int.class)
-                .collect(Collectors.toMap(this::getIntFieldChecked, Field::getName));
-
-        assertThat(enumsMap.size() - 1).isEqualTo(cujs.size());
-
-        cujs.forEach(f -> {
-            final int cuj = getIntFieldChecked(f);
-            final String cujName = f.getName();
-            final String expectedEnumName = ENUM_NAME_EXCEPTION_MAP.contains(cuj)
-                    ? ENUM_NAME_EXCEPTION_MAP.get(cuj)
-                    : formatSimple("%s%s", ENUM_NAME_PREFIX, cujName.substring(4));
-            final int enumKey = CUJ_TO_STATSD_INTERACTION_TYPE[cuj];
-            final String enumName = enumsMap.get(enumKey);
-            final String expectedNameOfCuj = formatSimple("CUJ_%s", getNameOfCuj(cuj));
-
-            mExpect
-                    .withMessage(formatSimple(
-                            "%s (%d) not matches %s (%d)", cujName, cuj, enumName, enumKey))
-                    .that(expectedEnumName.equals(enumName))
-                    .isTrue();
-            mExpect
-                    .withMessage(
-                            formatSimple("getNameOfCuj(%d) not matches: %s, expected=%s",
-                                    cuj, cujName, expectedNameOfCuj))
-                    .that(cujName.equals(expectedNameOfCuj))
-                    .isTrue();
-        });
-    }
-
-    @Test
-    public void testCujNameLimit() {
-        Arrays.stream(InteractionJankMonitor.class.getDeclaredFields())
-                .filter(f -> f.getName().startsWith("CUJ_")
-                        && Modifier.isStatic(f.getModifiers())
-                        && f.getType() == int.class)
-                .forEach(f -> {
-                    final int cuj = getIntFieldChecked(f);
-                    mExpect
-                            .withMessage(formatSimple(
-                                    "Too long CUJ(%d) name: %s", cuj, getNameOfCuj(cuj)))
-                            .that(getNameOfCuj(cuj).length())
-                            .isAtMost(MAX_LENGTH_OF_CUJ_NAME);
-                });
-    }
-
     @Test
     public void testSessionNameLengthLimit() {
-        final int cujType = CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
-        final String cujName = getNameOfCuj(cujType);
+        final int cujType = Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
+        final String cujName = Cuj.getNameOfCuj(cujType);
         final String cujTag = "ThisIsTheCujTag";
         final String tooLongTag = cujTag.repeat(10);
 
         // Normal case, no postfix.
-        Session noPostfix = new Session(cujType, "");
-        assertThat(noPostfix.getName()).isEqualTo(formatSimple("J<%s>", cujName));
+        assertThat(generateSessionName(cujName, "")).isEqualTo(formatSimple("J<%s>", cujName));
 
         // Normal case, with postfix.
-        Session withPostfix = new Session(cujType, cujTag);
-        assertThat(withPostfix.getName()).isEqualTo(formatSimple("J<%s::%s>", cujName, cujTag));
+        assertThat(generateSessionName(cujName, cujTag))
+                .isEqualTo(formatSimple("J<%s::%s>", cujName, cujTag));
 
         // Since the length of the cuj name is tested in another test, no need to test it here.
         // Too long postfix case, should trim the postfix and keep the cuj name completed.
         final String expectedTrimmedName = formatSimple("J<%s::%s>", cujName,
                 "ThisIsTheCujTagThisIsTheCujTagThisIsTheCujTagThisIsTheCujTagThi...");
-        Session longPostfix = new Session(cujType, tooLongTag);
-        assertThat(longPostfix.getName()).isEqualTo(expectedTrimmedName);
+        assertThat(generateSessionName(cujName, tooLongTag)).isEqualTo(expectedTrimmedName);
     }
 
     private InteractionJankMonitor createMockedInteractionJankMonitor() {
         InteractionJankMonitor monitor = spy(new InteractionJankMonitor(mWorker));
-        doReturn(true).when(monitor).shouldMonitor(anyInt());
+        doReturn(true).when(monitor).shouldMonitor();
         return monitor;
     }
 
-    private FrameTracker createMockedFrameTracker(InteractionJankMonitor monitor,
-            FrameTracker.FrameTrackerListener listener) {
-        Session session = spy(new Session(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, CUJ_POSTFIX));
-        doReturn(false).when(session).logToStatsd();
-
+    private FrameTracker createMockedFrameTracker() {
         ThreadedRendererWrapper threadedRenderer = mock(ThreadedRendererWrapper.class);
         doNothing().when(threadedRenderer).addObserver(any());
         doNothing().when(threadedRenderer).removeObserver(any());
@@ -342,27 +192,19 @@ public class InteractionJankMonitorTest {
         Configuration configuration = mock(Configuration.class);
         when(configuration.isSurfaceOnly()).thenReturn(false);
         when(configuration.getView()).thenReturn(mView);
-        when(configuration.getHandler()).thenReturn(mView.getHandler());
         when(configuration.getDisplayId()).thenReturn(42);
+        when(configuration.logToStatsd()).thenReturn(false);
+        when(configuration.getHandler()).thenReturn(mHandler);
 
-        FrameTracker tracker = spy(new FrameTracker(monitor, session, mWorker.getThreadHandler(),
+        FrameTracker tracker = spy(new FrameTracker(configuration,
                 threadedRenderer, viewRoot, surfaceControl, choreographer,
                 new FrameMetricsWrapper(), new StatsLogWrapper(null),
                 /* traceThresholdMissedFrames= */ 1,
-                /* traceThresholdFrameTimeMillis= */ -1, listener, configuration));
+                /* traceThresholdFrameTimeMillis= */ -1,
+                /* listener */ null));
 
         doNothing().when(tracker).postTraceStartMarker(any());
-        doNothing().when(tracker).triggerPerfetto();
-        doReturn(configuration.getHandler()).when(tracker).getHandler();
 
         return tracker;
     }
-
-    private int getIntFieldChecked(Field field) {
-        try {
-            return field.getInt(null);
-        } catch (IllegalAccessException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
index dc413b059fd7..a32b435ff99e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
@@ -28,7 +28,7 @@ import android.view.RemoteAnimationTarget;
 import android.window.IBackAnimationRunner;
 import android.window.IOnBackInvokedCallback;
 
-import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.jank.Cuj.CujType;
 import com.android.wm.shell.common.InteractionJankMonitorUtils;
 
 /**
@@ -42,7 +42,7 @@ public class BackAnimationRunner {
 
     private final IOnBackInvokedCallback mCallback;
     private final IRemoteAnimationRunner mRunner;
-    private final @InteractionJankMonitor.CujType int mCujType;
+    private final @CujType int mCujType;
     private final Context mContext;
 
     // Whether we are waiting to receive onAnimationStart
@@ -55,7 +55,7 @@ public class BackAnimationRunner {
             @NonNull IOnBackInvokedCallback callback,
             @NonNull IRemoteAnimationRunner runner,
             @NonNull Context context,
-            @InteractionJankMonitor.CujType int cujType) {
+            @CujType int cujType) {
         mCallback = callback;
         mRunner = runner;
         mCujType = cujType;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
index ec344d345139..86f00b83cadd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
@@ -23,6 +23,7 @@ import android.text.TextUtils;
 import android.view.SurfaceControl;
 import android.view.View;
 
+import com.android.internal.jank.Cuj.CujType;
 import com.android.internal.jank.InteractionJankMonitor;
 
 /** Utils class for simplfy InteractionJank trancing call */
@@ -31,11 +32,11 @@ public class InteractionJankMonitorUtils {
     /**
      * Begin a trace session.
      *
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link CujType}.
      * @param view the view to trace
      * @param tag the tag to distinguish different flow of same type CUJ.
      */
-    public static void beginTracing(@InteractionJankMonitor.CujType int cujType,
+    public static void beginTracing(@CujType int cujType,
             @NonNull View view, @Nullable String tag) {
         final InteractionJankMonitor.Configuration.Builder builder =
                 InteractionJankMonitor.Configuration.Builder.withView(cujType, view);
@@ -48,12 +49,12 @@ public class InteractionJankMonitorUtils {
     /**
      * Begin a trace session.
      *
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link CujType}.
      * @param context the context
      * @param surface the surface to trace
      * @param tag the tag to distinguish different flow of same type CUJ.
      */
-    public static void beginTracing(@InteractionJankMonitor.CujType int cujType,
+    public static void beginTracing(@CujType int cujType,
             @NonNull Context context, @NonNull SurfaceControl surface, @Nullable String tag) {
         final InteractionJankMonitor.Configuration.Builder builder =
                 InteractionJankMonitor.Configuration.Builder.withSurface(cujType, context, surface);
@@ -66,18 +67,18 @@ public class InteractionJankMonitorUtils {
     /**
      * End a trace session.
      *
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link CujType}.
      */
-    public static void endTracing(@InteractionJankMonitor.CujType int cujType) {
+    public static void endTracing(@CujType int cujType) {
         InteractionJankMonitor.getInstance().end(cujType);
     }
 
     /**
      * Cancel the trace session.
      *
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link CujType}.
      */
-    public static void cancelTracing(@InteractionJankMonitor.CujType int cujType) {
+    public static void cancelTracing(@CujType int cujType) {
         InteractionJankMonitor.getInstance().cancel(cujType);
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
index 38ce16489b06..d157ca837608 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -16,8 +16,8 @@
 
 package com.android.wm.shell.onehanded;
 
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_ONE_HANDED_ENTER_TRANSITION;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_ONE_HANDED_EXIT_TRANSITION;
+import static com.android.internal.jank.Cuj.CUJ_ONE_HANDED_ENTER_TRANSITION;
+import static com.android.internal.jank.Cuj.CUJ_ONE_HANDED_EXIT_TRANSITION;
 import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_EXIT;
 import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_TRIGGER;
 
@@ -37,6 +37,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.internal.jank.Cuj.CujType;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
@@ -327,7 +328,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
         mTransitionCallbacks.add(callback);
     }
 
-    void beginCUJTracing(@InteractionJankMonitor.CujType int cujType, @Nullable String tag) {
+    void beginCUJTracing(@CujType int cujType, @Nullable String tag) {
         final Map.Entry<WindowContainerToken, SurfaceControl> firstEntry =
                 getDisplayAreaTokenMap().entrySet().iterator().next();
         final InteractionJankMonitor.Configuration.Builder builder =
@@ -339,11 +340,11 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
         mJankMonitor.begin(builder);
     }
 
-    void endCUJTracing(@InteractionJankMonitor.CujType int cujType) {
+    void endCUJTracing(@CujType int cujType) {
         mJankMonitor.end(cujType);
     }
 
-    void cancelCUJTracing(@InteractionJankMonitor.CujType int cujType) {
+    void cancelCUJTracing(@CujType int cujType) {
         mJankMonitor.cancel(cujType);
     }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
index 25833b3ddbba..5aee8cdb8b9e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SettingsJankMonitorTest.java
@@ -16,7 +16,7 @@
 
 package com.android.settingslib.core.instrumentation;
 
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_SETTINGS_TOGGLE;
+import static com.android.internal.jank.Cuj.CUJ_SETTINGS_TOGGLE;
 import static com.android.settingslib.core.instrumentation.SettingsJankMonitor.MONITORED_ANIMATION_DURATION_MS;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -34,8 +34,8 @@ import androidx.preference.PreferenceGroupAdapter;
 import androidx.preference.SwitchPreference;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.android.internal.jank.Cuj.CujType;
 import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.jank.InteractionJankMonitor.CujType;
 import com.android.settingslib.testutils.OverpoweredReflectionHelper;
 import com.android.settingslib.testutils.shadow.ShadowInteractionJankMonitor;
 
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index 187d0739b734..168039ed5d3d 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -33,8 +33,8 @@ import android.view.WindowInsets
 import android.view.WindowManager
 import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
 import com.android.app.animation.Interpolators
+import com.android.internal.jank.Cuj.CujType
 import com.android.internal.jank.InteractionJankMonitor
-import com.android.internal.jank.InteractionJankMonitor.CujType
 import com.android.systemui.util.maybeForceFullscreen
 import com.android.systemui.util.registerAnimationOnBackInvoked
 import kotlin.math.roundToInt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index af35ea44322f..b738e2bc972b 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -33,6 +33,7 @@ import android.view.View
 import android.view.ViewGroup
 import android.view.ViewGroupOverlay
 import android.widget.FrameLayout
+import com.android.internal.jank.Cuj.CujType
 import com.android.internal.jank.InteractionJankMonitor
 import java.util.LinkedList
 import kotlin.math.min
@@ -58,7 +59,7 @@ constructor(
     /** The view that will be ghosted and from which the background will be extracted. */
     private val ghostedView: View,
 
-    /** The [InteractionJankMonitor.CujType] associated to this animation. */
+    /** The [CujType] associated to this animation. */
     private val cujType: Int? = null,
     private var interactionJankMonitor: InteractionJankMonitor =
         InteractionJankMonitor.getInstance(),
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
index c505bd502985..df7182b90f12 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
@@ -21,6 +21,7 @@ import android.os.Build;
 import android.text.TextUtils;
 import android.view.View;
 
+import com.android.internal.jank.Cuj;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.jank.InteractionJankMonitor.Configuration;
 
@@ -29,40 +30,25 @@ import java.lang.annotation.RetentionPolicy;
 
 public final class InteractionJankMonitorWrapper {
     // Launcher journeys.
-    public static final int CUJ_APP_LAUNCH_FROM_RECENTS =
-            InteractionJankMonitor.CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS;
-    public static final int CUJ_APP_LAUNCH_FROM_ICON =
-            InteractionJankMonitor.CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON;
-    public static final int CUJ_APP_CLOSE_TO_HOME =
-            InteractionJankMonitor.CUJ_LAUNCHER_APP_CLOSE_TO_HOME;
+    public static final int CUJ_APP_LAUNCH_FROM_RECENTS = Cuj.CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS;
+    public static final int CUJ_APP_LAUNCH_FROM_ICON = Cuj.CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON;
+    public static final int CUJ_APP_CLOSE_TO_HOME = Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME;
     public static final int CUJ_APP_CLOSE_TO_HOME_FALLBACK =
-            InteractionJankMonitor.CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
-    public static final int CUJ_APP_CLOSE_TO_PIP =
-            InteractionJankMonitor.CUJ_LAUNCHER_APP_CLOSE_TO_PIP;
-    public static final int CUJ_QUICK_SWITCH =
-            InteractionJankMonitor.CUJ_LAUNCHER_QUICK_SWITCH;
-    public static final int CUJ_OPEN_ALL_APPS =
-            InteractionJankMonitor.CUJ_LAUNCHER_OPEN_ALL_APPS;
-    public static final int CUJ_CLOSE_ALL_APPS_SWIPE =
-            InteractionJankMonitor.CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE;
-    public static final int CUJ_CLOSE_ALL_APPS_TO_HOME =
-            InteractionJankMonitor.CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME;
-    public static final int CUJ_ALL_APPS_SCROLL =
-            InteractionJankMonitor.CUJ_LAUNCHER_ALL_APPS_SCROLL;
-    public static final int CUJ_APP_LAUNCH_FROM_WIDGET =
-            InteractionJankMonitor.CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET;
-    public static final int CUJ_SPLIT_SCREEN_ENTER =
-            InteractionJankMonitor.CUJ_SPLIT_SCREEN_ENTER;
+            Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
+    public static final int CUJ_APP_CLOSE_TO_PIP = Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_PIP;
+    public static final int CUJ_QUICK_SWITCH = Cuj.CUJ_LAUNCHER_QUICK_SWITCH;
+    public static final int CUJ_OPEN_ALL_APPS = Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS;
+    public static final int CUJ_CLOSE_ALL_APPS_SWIPE = Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE;
+    public static final int CUJ_CLOSE_ALL_APPS_TO_HOME = Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME;
+    public static final int CUJ_ALL_APPS_SCROLL = Cuj.CUJ_LAUNCHER_ALL_APPS_SCROLL;
+    public static final int CUJ_APP_LAUNCH_FROM_WIDGET = Cuj.CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET;
+    public static final int CUJ_SPLIT_SCREEN_ENTER = Cuj.CUJ_SPLIT_SCREEN_ENTER;
     public static final int CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION =
-            InteractionJankMonitor.CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION;
-    public static final int CUJ_RECENTS_SCROLLING =
-            InteractionJankMonitor.CUJ_RECENTS_SCROLLING;
-    public static final int CUJ_APP_SWIPE_TO_RECENTS =
-            InteractionJankMonitor.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS;
-    public static final int CUJ_OPEN_SEARCH_RESULT =
-            InteractionJankMonitor.CUJ_LAUNCHER_OPEN_SEARCH_RESULT;
-    public static final int CUJ_LAUNCHER_UNFOLD_ANIM =
-            InteractionJankMonitor.CUJ_LAUNCHER_UNFOLD_ANIM;
+            Cuj.CUJ_LAUNCHER_UNLOCK_ENTRANCE_ANIMATION;
+    public static final int CUJ_RECENTS_SCROLLING = Cuj.CUJ_RECENTS_SCROLLING;
+    public static final int CUJ_APP_SWIPE_TO_RECENTS = Cuj.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS;
+    public static final int CUJ_OPEN_SEARCH_RESULT = Cuj.CUJ_LAUNCHER_OPEN_SEARCH_RESULT;
+    public static final int CUJ_LAUNCHER_UNFOLD_ANIM = Cuj.CUJ_LAUNCHER_UNFOLD_ANIM;
 
     @IntDef({
             CUJ_APP_LAUNCH_FROM_RECENTS,
@@ -89,7 +75,7 @@ public final class InteractionJankMonitorWrapper {
      * Begin a trace session.
      *
      * @param v       an attached view.
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link Cuj.CujType}.
      */
     public static void begin(View v, @CujType int cujType) {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return;
@@ -100,7 +86,7 @@ public final class InteractionJankMonitorWrapper {
      * Begin a trace session.
      *
      * @param v       an attached view.
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link Cuj.CujType}.
      * @param timeout duration to cancel the instrumentation in ms
      */
     public static void begin(View v, @CujType int cujType, long timeout) {
@@ -115,7 +101,7 @@ public final class InteractionJankMonitorWrapper {
      * Begin a trace session.
      *
      * @param v       an attached view.
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link Cuj.CujType}.
      * @param tag the tag to distinguish different flow of same type CUJ.
      */
     public static void begin(View v, @CujType int cujType, String tag) {
@@ -131,7 +117,7 @@ public final class InteractionJankMonitorWrapper {
     /**
      * End a trace session.
      *
-     * @param cujType the specific {@link InteractionJankMonitor.CujType}.
+     * @param cujType the specific {@link Cuj.CujType}.
      */
     public static void end(@CujType int cujType) {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return;
-- 
GitLab