Merge "DO NOT MERGE: Enable presubmit for com.android.internal.jank" into tm-qpr-dev
diff --git a/core/java/com/android/internal/jank/TEST_MAPPING b/core/java/com/android/internal/jank/TEST_MAPPING
new file mode 100644
index 0000000..4e00ff1
--- /dev/null
+++ b/core/java/com/android/internal/jank/TEST_MAPPING
@@ -0,0 +1,22 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "com.android.internal.jank"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ],
+      "file_patterns": [
+        "core/java/com/android/internal/jank/.*",
+        "core/tests/coretests/src/com/android/internal/jank/.*"
+      ]
+    }
+  ]
+}
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 14a6d5e..d3f9e0a 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -16,6 +16,27 @@
 
 import static android.os.Trace.TRACE_TAG_APP;
 
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SWITCH_DISPLAY_UNFOLD;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TOGGLE_RECENTS;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__UNKNOWN_ACTION;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -30,6 +51,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.EventLogTags;
 import com.android.internal.os.BackgroundThread;
 
@@ -103,14 +125,14 @@
     public static final int ACTION_START_RECENTS_ANIMATION = 8;
 
     /**
-     * Time it takes the sensor to detect rotation.
-     */
-    public static final int ACTION_ROTATE_SCREEN_SENSOR = 9;
-
-    /**
      * Time it takes to for the camera based algorithm to rotate the screen.
      */
-    public static final int ACTION_ROTATE_SCREEN_CAMERA_CHECK = 10;
+    public static final int ACTION_ROTATE_SCREEN_CAMERA_CHECK = 9;
+
+    /**
+     * Time it takes the sensor to detect rotation.
+     */
+    public static final int ACTION_ROTATE_SCREEN_SENSOR = 10;
 
     /**
      * Time it takes to start unlock animation .
@@ -143,9 +165,14 @@
     public static final int ACTION_LOAD_SHARE_SHEET = 16;
 
     /**
+     * Time it takes for showing the selection toolbar.
+     */
+    public static final int ACTION_SHOW_SELECTION_TOOLBAR = 17;
+
+    /**
      * Time it takes to show AOD display after folding the device.
      */
-    public static final int ACTION_FOLD_TO_AOD = 17;
+    public static final int ACTION_FOLD_TO_AOD = 18;
 
     private static final int[] ACTIONS_ALL = {
         ACTION_EXPAND_PANEL,
@@ -157,14 +184,15 @@
         ACTION_ROTATE_SCREEN,
         ACTION_FACE_WAKE_AND_UNLOCK,
         ACTION_START_RECENTS_ANIMATION,
-        ACTION_ROTATE_SCREEN_SENSOR,
         ACTION_ROTATE_SCREEN_CAMERA_CHECK,
+        ACTION_ROTATE_SCREEN_SENSOR,
         ACTION_LOCKSCREEN_UNLOCK,
         ACTION_USER_SWITCH,
         ACTION_SWITCH_DISPLAY_UNFOLD,
         ACTION_UDFPS_ILLUMINATE,
         ACTION_SHOW_BACK_ARROW,
         ACTION_LOAD_SHARE_SHEET,
+        ACTION_SHOW_SELECTION_TOOLBAR,
         ACTION_FOLD_TO_AOD,
     };
 
@@ -179,39 +207,42 @@
         ACTION_ROTATE_SCREEN,
         ACTION_FACE_WAKE_AND_UNLOCK,
         ACTION_START_RECENTS_ANIMATION,
-        ACTION_ROTATE_SCREEN_SENSOR,
         ACTION_ROTATE_SCREEN_CAMERA_CHECK,
+        ACTION_ROTATE_SCREEN_SENSOR,
         ACTION_LOCKSCREEN_UNLOCK,
         ACTION_USER_SWITCH,
         ACTION_SWITCH_DISPLAY_UNFOLD,
         ACTION_UDFPS_ILLUMINATE,
         ACTION_SHOW_BACK_ARROW,
         ACTION_LOAD_SHARE_SHEET,
-        ACTION_FOLD_TO_AOD
+        ACTION_SHOW_SELECTION_TOOLBAR,
+        ACTION_FOLD_TO_AOD,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Action {
     }
 
-    private static final int[] STATSD_ACTION = new int[]{
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TOGGLE_RECENTS,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SWITCH_DISPLAY_UNFOLD,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET,
-            FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD
+    @VisibleForTesting
+    public static final int[] STATSD_ACTION = new int[] {
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_TOGGLE_RECENTS,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_SWITCH_DISPLAY_UNFOLD,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD,
     };
 
     private static LatencyTracker sLatencyTracker;
@@ -269,43 +300,45 @@
     public static String getNameOfAction(int atomsProtoAction) {
         // Defined in AtomsProto.java
         switch (atomsProtoAction) {
-            case 0:
+            case UIACTION_LATENCY_REPORTED__ACTION__UNKNOWN_ACTION:
                 return "UNKNOWN";
-            case 1:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL:
                 return "ACTION_EXPAND_PANEL";
-            case 2:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_TOGGLE_RECENTS:
                 return "ACTION_TOGGLE_RECENTS";
-            case 3:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK:
                 return "ACTION_FINGERPRINT_WAKE_AND_UNLOCK";
-            case 4:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL:
                 return "ACTION_CHECK_CREDENTIAL";
-            case 5:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED:
                 return "ACTION_CHECK_CREDENTIAL_UNLOCKED";
-            case 6:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_TURN_ON_SCREEN:
                 return "ACTION_TURN_ON_SCREEN";
-            case 7:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN:
                 return "ACTION_ROTATE_SCREEN";
-            case 8:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK:
                 return "ACTION_FACE_WAKE_AND_UNLOCK";
-            case 9:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_START_RECENTS_ANIMATION:
                 return "ACTION_START_RECENTS_ANIMATION";
-            case 10:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK:
                 return "ACTION_ROTATE_SCREEN_CAMERA_CHECK";
-            case 11:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR:
                 return "ACTION_ROTATE_SCREEN_SENSOR";
-            case 12:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK:
                 return "ACTION_LOCKSCREEN_UNLOCK";
-            case 13:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_USER_SWITCH:
                 return "ACTION_USER_SWITCH";
-            case 14:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SWITCH_DISPLAY_UNFOLD:
                 return "ACTION_SWITCH_DISPLAY_UNFOLD";
-            case 15:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_UDFPS_ILLUMINATE:
                 return "ACTION_UDFPS_ILLUMINATE";
-            case 16:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW:
                 return "ACTION_SHOW_BACK_ARROW";
-            case 17:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET:
                 return "ACTION_LOAD_SHARE_SHEET";
-            case 19:
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR:
+                return "ACTION_SHOW_SELECTION_TOOLBAR";
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD:
                 return "ACTION_FOLD_TO_AOD";
             default:
                 throw new IllegalArgumentException("Invalid action");
diff --git a/core/java/com/android/internal/util/TEST_MAPPING b/core/java/com/android/internal/util/TEST_MAPPING
index 5881c51..7970dd8 100644
--- a/core/java/com/android/internal/util/TEST_MAPPING
+++ b/core/java/com/android/internal/util/TEST_MAPPING
@@ -1,7 +1,22 @@
 {
   "presubmit": [
     {
-       "name": "ScreenshotHelperTests"
+      "name": "ScreenshotHelperTests"
+    },
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "com.android.internal.util.LatencyTrackerTest"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ],
+      "file_patterns": ["LatencyTracker.java"]
     }
   ]
-}
\ No newline at end of file
+}
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 1519e48..ecb281b 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -262,6 +262,8 @@
                         && 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();
@@ -279,7 +281,9 @@
                     .that(expectedEnumName.equals(enumName))
                     .isTrue();
             mExpect
-                    .withMessage(formatSimple("getNameOfCuj(%d) not matches %s", cuj, cujName))
+                    .withMessage(
+                            formatSimple("getNameOfCuj(%d) not matches: %s, expected=%s",
+                                    cuj, cujName, expectedNameOfCuj))
                     .that(cujName.equals(expectedNameOfCuj))
                     .isTrue();
         });
diff --git a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
new file mode 100644
index 0000000..e384e69
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static android.text.TextUtils.formatSimple;
+
+import static com.android.internal.util.LatencyTracker.STATSD_ACTION;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import androidx.test.filters.SmallTest;
+
+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.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@SmallTest
+public class LatencyTrackerTest {
+    private static final String ENUM_NAME_PREFIX = "UIACTION_LATENCY_REPORTED__ACTION__";
+
+    @Rule
+    public final Expect mExpect = Expect.create();
+
+    @Test
+    public void testCujsMapToEnumsCorrectly() {
+        List<Field> actions = Arrays.stream(LatencyTracker.class.getDeclaredFields())
+                .filter(f -> f.getName().startsWith("ACTION_")
+                        && 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)
+                        && Modifier.isStatic(f.getModifiers())
+                        && f.getType() == int.class)
+                .collect(Collectors.toMap(this::getIntFieldChecked, Field::getName));
+
+        assertThat(enumsMap.size() - 1).isEqualTo(actions.size());
+
+        actions.forEach(f -> {
+            final int action = getIntFieldChecked(f);
+            final String actionName = f.getName();
+            final String expectedEnumName = formatSimple("%s%s", ENUM_NAME_PREFIX, actionName);
+            final int enumKey = STATSD_ACTION[action];
+            final String enumName = enumsMap.get(enumKey);
+            final String expectedActionName = LatencyTracker.getNameOfAction(enumKey);
+            mExpect
+                    .withMessage(formatSimple(
+                            "%s (%d) not matches %s (%d)", actionName, action, enumName, enumKey))
+                    .that(expectedEnumName.equals(enumName))
+                    .isTrue();
+            mExpect
+                    .withMessage(
+                            formatSimple("getNameOfAction(%d) not matches: %s, expected=%s",
+                                    enumKey, actionName, expectedActionName))
+                    .that(actionName.equals(expectedActionName))
+                    .isTrue();
+        });
+    }
+
+    @Test
+    public void testCujTypeEnumCorrectlyDefined() throws Exception {
+        List<Field> cujEnumFields =
+                Arrays.stream(LatencyTracker.class.getDeclaredFields())
+                        .filter(field -> field.getName().startsWith("ACTION_")
+                                && 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 STATSD_ACTION",
+                    field.getName())
+                    .that(fieldValue < STATSD_ACTION.length)
+                    .isTrue();
+            assertWithMessage("All CujType values must be unique. Field %s repeats existing value.",
+                    field.getName())
+                    .that(allValues.add(fieldValue))
+                    .isTrue();
+        }
+    }
+
+    private int getIntFieldChecked(Field field) {
+        try {
+            return field.getInt(null);
+        } catch (IllegalAccessException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}