• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2024 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {BlockingCallMetricData} from './metricUtils';
16import {pinBlockingCallHandlerInstance} from './pinBlockingCall';
17
18const validMetricsTest: {
19  inputMetric: string;
20  expectedOutput: BlockingCallMetricData;
21}[] = [
22  {
23    inputMetric:
24      'perfetto_android_blocking_call-cuj-name-com.google.android.apps.nexuslauncher-name-TASKBAR_EXPAND-blocking_calls-name-animation-total_dur_ms-mean',
25    expectedOutput: {
26      process: 'com.google.android.apps.nexuslauncher',
27      cujName: 'TASKBAR_EXPAND',
28      blockingCallName: 'animation',
29      aggregation: 'total_dur_ms-mean',
30    },
31  },
32
33  {
34    inputMetric:
35      'perfetto_android_blocking_call-cuj-name-com.android.systemui-name-NOTIFICATION_SHADE_EXPAND_COLLAPSE::Collapse-blocking_calls-name-AIDL::java::IPackageManager::isProtectedBroadcast::server-cnt-mean',
36    expectedOutput: {
37      process: 'com.android.systemui',
38      cujName: 'NOTIFICATION_SHADE_EXPAND_COLLAPSE::Collapse',
39      blockingCallName:
40        'AIDL::java::IPackageManager::isProtectedBroadcast::server',
41      aggregation: 'cnt-mean',
42    },
43  },
44  {
45    inputMetric:
46      'perfetto_android_blocking_call-cuj-name-com.android.systemui-name-SPLASHSCREEN_EXIT_ANIM-blocking_calls-name-AIDL::java::IPackageManager::isProtectedBroadcast::server-cnt-mean',
47    expectedOutput: {
48      process: 'com.android.systemui',
49      cujName: 'SPLASHSCREEN_EXIT_ANIM',
50      blockingCallName:
51        'AIDL::java::IPackageManager::isProtectedBroadcast::server',
52      aggregation: 'cnt-mean',
53    },
54  },
55  // test cases for blocking call per-frame metrics.
56  {
57    inputMetric:
58      'perfetto_android_blocking_call_per_frame-cuj-name-com.android.systemui-name-LOCKSCREEN_TRANSITION_FROM_AOD::DEFAULT-blocking_calls-name-Handler: android.widget.DateTimeView-mean_cnt_per_frame-mean',
59    expectedOutput: {
60      process: 'com.android.systemui',
61      cujName: 'LOCKSCREEN_TRANSITION_FROM_AOD::DEFAULT',
62      blockingCallName: 'Handler: android.widget.DateTimeView',
63      aggregation: 'mean_cnt_per_frame-mean',
64    },
65  },
66  {
67    inputMetric:
68      'perfetto_android_blocking_call_per_frame-cuj-name-com.google.android.apps.nexuslauncher-name-TASKBAR_EXPAND::Manually unstashed-blocking_calls-name-Handler: android.view.View-max_dur_per_frame_ns-mean',
69    expectedOutput: {
70      process: 'com.google.android.apps.nexuslauncher',
71      cujName: 'TASKBAR_EXPAND::Manually unstashed',
72      blockingCallName:
73        'Handler: android.view.View',
74      aggregation: 'max_dur_per_frame_ns-mean',
75    },
76  },
77  {
78    inputMetric:
79      'perfetto_android_blocking_call_per_frame-cuj-name-com.android.systemui-name-NOTIFICATION_SHADE_EXPAND_COLLAPSE::Collapse-blocking_calls-name-input-mean_dur_per_frame_ns-max',
80    expectedOutput: {
81      process: 'com.android.systemui',
82      cujName: 'NOTIFICATION_SHADE_EXPAND_COLLAPSE::Collapse',
83      blockingCallName:
84        'input',
85      aggregation: 'mean_dur_per_frame_ns-max',
86    },
87  },
88];
89
90const invalidMetricsTest: string[] = [
91  'perfetto_ft_launcher-missed_sf_frames-mean',
92  'perfetto_cuj_launcher-RECENTS_SCROLLING-counter_metrics-missed_sf_frames-mean',
93];
94
95const tester = pinBlockingCallHandlerInstance;
96
97describe('testMetricParser_match', () => {
98  it('parses metrics and returns expected data', () => {
99    for (const testCase of validMetricsTest) {
100      const parsedData = tester.match(testCase.inputMetric);
101      // without this explicit check, undefined also passes the test
102      expect(parsedData).toBeDefined();
103      if (parsedData) {
104        expect(parsedData).toEqual(testCase.expectedOutput);
105      }
106    }
107  });
108  it('parses metrics and returns undefined', () => {
109    for (const testCase of invalidMetricsTest) {
110      const parsedData = tester.match(testCase);
111
112      expect(parsedData).toBeUndefined();
113    }
114  });
115});
116