diff options
5 files changed, 237 insertions, 47 deletions
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 000000000000..4e00ff19e9d9 --- /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 14a6d5e4d08c..d3f9e0a2729e 100644 --- a/core/java/com/android/internal/util/LatencyTracker.java +++ b/core/java/com/android/internal/util/LatencyTracker.java @@ -16,6 +16,27 @@ package com.android.internal.util; 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.Log; 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 class LatencyTracker { public static final int ACTION_START_RECENTS_ANIMATION = 8; /** - * Time it takes the sensor to detect rotation. + * Time it takes to for the camera based algorithm to rotate the screen. */ - public static final int ACTION_ROTATE_SCREEN_SENSOR = 9; + public static final int ACTION_ROTATE_SCREEN_CAMERA_CHECK = 9; /** - * Time it takes to for the camera based algorithm to rotate the screen. + * Time it takes the sensor to detect rotation. */ - public static final int ACTION_ROTATE_SCREEN_CAMERA_CHECK = 10; + public static final int ACTION_ROTATE_SCREEN_SENSOR = 10; /** * Time it takes to start unlock animation . @@ -143,9 +165,14 @@ public class LatencyTracker { 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 @@ public class LatencyTracker { 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 @@ public class LatencyTracker { 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 class LatencyTracker { 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 41d59bbeb801..00a8118c0e4b 100644 --- a/core/java/com/android/internal/util/TEST_MAPPING +++ b/core/java/com/android/internal/util/TEST_MAPPING @@ -15,6 +15,21 @@ } ], "file_patterns": ["Xml"] + }, + { + "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"] } ] } 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 1519e48adbe0..ecb281b58c24 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 @@ public class InteractionJankMonitorTest { && 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 @@ public class InteractionJankMonitorTest { .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 000000000000..e384e699333b --- /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); + } + } +} |