xref: /aosp_15_r20/external/perfetto/ui/src/plugins/dev.perfetto.AndroidCujs/index.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2023 The Android Open Source Project
2*6dbdd20aSAndroid Build Coastguard Worker//
3*6dbdd20aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*6dbdd20aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*6dbdd20aSAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*6dbdd20aSAndroid Build Coastguard Worker//
7*6dbdd20aSAndroid Build Coastguard Worker//      http://www.apache.org/licenses/LICENSE-2.0
8*6dbdd20aSAndroid Build Coastguard Worker//
9*6dbdd20aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*6dbdd20aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*6dbdd20aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6dbdd20aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*6dbdd20aSAndroid Build Coastguard Worker// limitations under the License.
14*6dbdd20aSAndroid Build Coastguard Worker
15*6dbdd20aSAndroid Build Coastguard Workerimport {addDebugSliceTrack} from '../../components/tracks/debug_tracks';
16*6dbdd20aSAndroid Build Coastguard Workerimport {Trace} from '../../public/trace';
17*6dbdd20aSAndroid Build Coastguard Workerimport {PerfettoPlugin} from '../../public/plugin';
18*6dbdd20aSAndroid Build Coastguard Workerimport {addQueryResultsTab} from '../../components/query_table/query_result_tab';
19*6dbdd20aSAndroid Build Coastguard Worker
20*6dbdd20aSAndroid Build Coastguard Worker/**
21*6dbdd20aSAndroid Build Coastguard Worker * Adds the Debug Slice Track for given Jank CUJ name
22*6dbdd20aSAndroid Build Coastguard Worker *
23*6dbdd20aSAndroid Build Coastguard Worker * @param {Trace} ctx For properties and methods of trace viewer
24*6dbdd20aSAndroid Build Coastguard Worker * @param {string} trackName Display Name of the track
25*6dbdd20aSAndroid Build Coastguard Worker * @param {string | string[]} cujNames List of Jank CUJs to pin
26*6dbdd20aSAndroid Build Coastguard Worker */
27*6dbdd20aSAndroid Build Coastguard Workerexport function addJankCUJDebugTrack(
28*6dbdd20aSAndroid Build Coastguard Worker  ctx: Trace,
29*6dbdd20aSAndroid Build Coastguard Worker  trackName: string,
30*6dbdd20aSAndroid Build Coastguard Worker  cujNames?: string | string[],
31*6dbdd20aSAndroid Build Coastguard Worker) {
32*6dbdd20aSAndroid Build Coastguard Worker  const jankCujTrackConfig = generateJankCujTrackConfig(cujNames);
33*6dbdd20aSAndroid Build Coastguard Worker  addDebugSliceTrack({trace: ctx, title: trackName, ...jankCujTrackConfig});
34*6dbdd20aSAndroid Build Coastguard Worker}
35*6dbdd20aSAndroid Build Coastguard Worker
36*6dbdd20aSAndroid Build Coastguard Workerconst JANK_CUJ_QUERY_PRECONDITIONS = `
37*6dbdd20aSAndroid Build Coastguard Worker  SELECT RUN_METRIC('android/android_jank_cuj.sql');
38*6dbdd20aSAndroid Build Coastguard Worker  INCLUDE PERFETTO MODULE android.critical_blocking_calls;
39*6dbdd20aSAndroid Build Coastguard Worker`;
40*6dbdd20aSAndroid Build Coastguard Worker
41*6dbdd20aSAndroid Build Coastguard Worker/**
42*6dbdd20aSAndroid Build Coastguard Worker * Generate the Track config for a multiple Jank CUJ slices
43*6dbdd20aSAndroid Build Coastguard Worker *
44*6dbdd20aSAndroid Build Coastguard Worker * @param {string | string[]} cujNames List of Jank CUJs to pin, default empty
45*6dbdd20aSAndroid Build Coastguard Worker * @returns Returns the track config for given CUJs
46*6dbdd20aSAndroid Build Coastguard Worker */
47*6dbdd20aSAndroid Build Coastguard Workerfunction generateJankCujTrackConfig(cujNames: string | string[] = []) {
48*6dbdd20aSAndroid Build Coastguard Worker  // This method expects the caller to have run JANK_CUJ_QUERY_PRECONDITIONS
49*6dbdd20aSAndroid Build Coastguard Worker  // Not running the precondition query here to save time in case already run
50*6dbdd20aSAndroid Build Coastguard Worker  const jankCujQuery = JANK_CUJ_QUERY;
51*6dbdd20aSAndroid Build Coastguard Worker  const jankCujColumns = JANK_COLUMNS;
52*6dbdd20aSAndroid Build Coastguard Worker  const cujNamesList = typeof cujNames === 'string' ? [cujNames] : cujNames;
53*6dbdd20aSAndroid Build Coastguard Worker  const filterCuj =
54*6dbdd20aSAndroid Build Coastguard Worker    cujNamesList?.length > 0
55*6dbdd20aSAndroid Build Coastguard Worker      ? ` AND cuj.name IN (${cujNamesList
56*6dbdd20aSAndroid Build Coastguard Worker          .map((name) => `'J<${name}>'`)
57*6dbdd20aSAndroid Build Coastguard Worker          .join(',')})`
58*6dbdd20aSAndroid Build Coastguard Worker      : '';
59*6dbdd20aSAndroid Build Coastguard Worker
60*6dbdd20aSAndroid Build Coastguard Worker  return {
61*6dbdd20aSAndroid Build Coastguard Worker    data: {
62*6dbdd20aSAndroid Build Coastguard Worker      sqlSource: `${jankCujQuery}${filterCuj}`,
63*6dbdd20aSAndroid Build Coastguard Worker      columns: jankCujColumns,
64*6dbdd20aSAndroid Build Coastguard Worker    },
65*6dbdd20aSAndroid Build Coastguard Worker    argColumns: jankCujColumns,
66*6dbdd20aSAndroid Build Coastguard Worker  };
67*6dbdd20aSAndroid Build Coastguard Worker}
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Workerconst JANK_CUJ_QUERY = `
70*6dbdd20aSAndroid Build Coastguard Worker    SELECT
71*6dbdd20aSAndroid Build Coastguard Worker      CASE
72*6dbdd20aSAndroid Build Coastguard Worker        WHEN
73*6dbdd20aSAndroid Build Coastguard Worker          EXISTS(
74*6dbdd20aSAndroid Build Coastguard Worker              SELECT 1
75*6dbdd20aSAndroid Build Coastguard Worker              FROM slice AS cuj_state_marker
76*6dbdd20aSAndroid Build Coastguard Worker                     JOIN track marker_track
77*6dbdd20aSAndroid Build Coastguard Worker                          ON marker_track.id = cuj_state_marker.track_id
78*6dbdd20aSAndroid Build Coastguard Worker              WHERE
79*6dbdd20aSAndroid Build Coastguard Worker                cuj_state_marker.ts >= cuj.ts
80*6dbdd20aSAndroid Build Coastguard Worker                AND cuj_state_marker.ts + cuj_state_marker.dur <= cuj.ts + cuj.dur
81*6dbdd20aSAndroid Build Coastguard Worker                AND
82*6dbdd20aSAndroid Build Coastguard Worker                ( /* e.g. J<CUJ_NAME>#FT#cancel#0 this for backward compatibility */
83*6dbdd20aSAndroid Build Coastguard Worker                      cuj_state_marker.name GLOB(cuj.name || '#FT#cancel*')
84*6dbdd20aSAndroid Build Coastguard Worker                    OR (marker_track.name = cuj.name AND cuj_state_marker.name GLOB 'FT#cancel*')
85*6dbdd20aSAndroid Build Coastguard Worker                  )
86*6dbdd20aSAndroid Build Coastguard Worker            )
87*6dbdd20aSAndroid Build Coastguard Worker          THEN ' ❌ '
88*6dbdd20aSAndroid Build Coastguard Worker        WHEN
89*6dbdd20aSAndroid Build Coastguard Worker          EXISTS(
90*6dbdd20aSAndroid Build Coastguard Worker              SELECT 1
91*6dbdd20aSAndroid Build Coastguard Worker              FROM slice AS cuj_state_marker
92*6dbdd20aSAndroid Build Coastguard Worker                     JOIN track marker_track
93*6dbdd20aSAndroid Build Coastguard Worker                          ON marker_track.id = cuj_state_marker.track_id
94*6dbdd20aSAndroid Build Coastguard Worker              WHERE
95*6dbdd20aSAndroid Build Coastguard Worker                cuj_state_marker.ts >= cuj.ts
96*6dbdd20aSAndroid Build Coastguard Worker                AND cuj_state_marker.ts + cuj_state_marker.dur <= cuj.ts + cuj.dur
97*6dbdd20aSAndroid Build Coastguard Worker                AND
98*6dbdd20aSAndroid Build Coastguard Worker                ( /* e.g. J<CUJ_NAME>#FT#end#0 this for backward compatibility */
99*6dbdd20aSAndroid Build Coastguard Worker                      cuj_state_marker.name GLOB(cuj.name || '#FT#end*')
100*6dbdd20aSAndroid Build Coastguard Worker                    OR (marker_track.name = cuj.name AND cuj_state_marker.name GLOB 'FT#end*')
101*6dbdd20aSAndroid Build Coastguard Worker                  )
102*6dbdd20aSAndroid Build Coastguard Worker            )
103*6dbdd20aSAndroid Build Coastguard Worker          THEN ' ✅ '
104*6dbdd20aSAndroid Build Coastguard Worker        ELSE ' ❓ '
105*6dbdd20aSAndroid Build Coastguard Worker        END || cuj.name AS name,
106*6dbdd20aSAndroid Build Coastguard Worker      total_frames,
107*6dbdd20aSAndroid Build Coastguard Worker      missed_app_frames,
108*6dbdd20aSAndroid Build Coastguard Worker      missed_sf_frames,
109*6dbdd20aSAndroid Build Coastguard Worker      sf_callback_missed_frames,
110*6dbdd20aSAndroid Build Coastguard Worker      hwui_callback_missed_frames,
111*6dbdd20aSAndroid Build Coastguard Worker      cuj_layer.layer_name,
112*6dbdd20aSAndroid Build Coastguard Worker      /* Boundaries table doesn't contain ts and dur when a CUJ didn't complete successfully.
113*6dbdd20aSAndroid Build Coastguard Worker        In that case we still want to show that it was canceled, so let's take the slice timestamps. */
114*6dbdd20aSAndroid Build Coastguard Worker      CASE WHEN boundaries.ts IS NOT NULL THEN boundaries.ts ELSE cuj.ts END AS ts,
115*6dbdd20aSAndroid Build Coastguard Worker      CASE WHEN boundaries.dur IS NOT NULL THEN boundaries.dur ELSE cuj.dur END AS dur,
116*6dbdd20aSAndroid Build Coastguard Worker      cuj.track_id,
117*6dbdd20aSAndroid Build Coastguard Worker      cuj.slice_id
118*6dbdd20aSAndroid Build Coastguard Worker    FROM slice AS cuj
119*6dbdd20aSAndroid Build Coastguard Worker           JOIN process_track AS pt ON cuj.track_id = pt.id
120*6dbdd20aSAndroid Build Coastguard Worker           LEFT JOIN android_jank_cuj jc
121*6dbdd20aSAndroid Build Coastguard Worker                     ON pt.upid = jc.upid AND cuj.name = jc.cuj_slice_name AND cuj.ts = jc.ts
122*6dbdd20aSAndroid Build Coastguard Worker           LEFT JOIN android_jank_cuj_main_thread_cuj_boundary boundaries using (cuj_id)
123*6dbdd20aSAndroid Build Coastguard Worker           LEFT JOIN android_jank_cuj_layer_name cuj_layer USING (cuj_id)
124*6dbdd20aSAndroid Build Coastguard Worker           LEFT JOIN android_jank_cuj_counter_metrics USING (cuj_id)
125*6dbdd20aSAndroid Build Coastguard Worker    WHERE cuj.name GLOB 'J<*>'
126*6dbdd20aSAndroid Build Coastguard Worker      AND cuj.dur > 0
127*6dbdd20aSAndroid Build Coastguard Worker`;
128*6dbdd20aSAndroid Build Coastguard Worker
129*6dbdd20aSAndroid Build Coastguard Workerconst JANK_COLUMNS = [
130*6dbdd20aSAndroid Build Coastguard Worker  'name',
131*6dbdd20aSAndroid Build Coastguard Worker  'total_frames',
132*6dbdd20aSAndroid Build Coastguard Worker  'missed_app_frames',
133*6dbdd20aSAndroid Build Coastguard Worker  'missed_sf_frames',
134*6dbdd20aSAndroid Build Coastguard Worker  'sf_callback_missed_frames',
135*6dbdd20aSAndroid Build Coastguard Worker  'hwui_callback_missed_frames',
136*6dbdd20aSAndroid Build Coastguard Worker  'layer_name',
137*6dbdd20aSAndroid Build Coastguard Worker  'ts',
138*6dbdd20aSAndroid Build Coastguard Worker  'dur',
139*6dbdd20aSAndroid Build Coastguard Worker  'track_id',
140*6dbdd20aSAndroid Build Coastguard Worker  'slice_id',
141*6dbdd20aSAndroid Build Coastguard Worker];
142*6dbdd20aSAndroid Build Coastguard Worker
143*6dbdd20aSAndroid Build Coastguard Workerconst LATENCY_CUJ_QUERY = `
144*6dbdd20aSAndroid Build Coastguard Worker    SELECT
145*6dbdd20aSAndroid Build Coastguard Worker      CASE
146*6dbdd20aSAndroid Build Coastguard Worker        WHEN
147*6dbdd20aSAndroid Build Coastguard Worker          EXISTS(
148*6dbdd20aSAndroid Build Coastguard Worker              SELECT 1
149*6dbdd20aSAndroid Build Coastguard Worker              FROM slice AS cuj_state_marker
150*6dbdd20aSAndroid Build Coastguard Worker                     JOIN track marker_track
151*6dbdd20aSAndroid Build Coastguard Worker                          ON marker_track.id = cuj_state_marker.track_id
152*6dbdd20aSAndroid Build Coastguard Worker              WHERE
153*6dbdd20aSAndroid Build Coastguard Worker                cuj_state_marker.ts >= cuj.ts
154*6dbdd20aSAndroid Build Coastguard Worker                AND cuj_state_marker.ts + cuj_state_marker.dur <= cuj.ts + cuj.dur
155*6dbdd20aSAndroid Build Coastguard Worker                AND marker_track.name = cuj.name AND (
156*6dbdd20aSAndroid Build Coastguard Worker                    cuj_state_marker.name GLOB 'cancel'
157*6dbdd20aSAndroid Build Coastguard Worker                    OR cuj_state_marker.name GLOB 'timeout')
158*6dbdd20aSAndroid Build Coastguard Worker            )
159*6dbdd20aSAndroid Build Coastguard Worker          THEN ' ❌ '
160*6dbdd20aSAndroid Build Coastguard Worker        ELSE ' ✅ '
161*6dbdd20aSAndroid Build Coastguard Worker        END || cuj.name AS name,
162*6dbdd20aSAndroid Build Coastguard Worker      cuj.dur / 1e6 as dur_ms,
163*6dbdd20aSAndroid Build Coastguard Worker      cuj.ts,
164*6dbdd20aSAndroid Build Coastguard Worker      cuj.dur,
165*6dbdd20aSAndroid Build Coastguard Worker      cuj.track_id,
166*6dbdd20aSAndroid Build Coastguard Worker      cuj.slice_id
167*6dbdd20aSAndroid Build Coastguard Worker    FROM slice AS cuj
168*6dbdd20aSAndroid Build Coastguard Worker           JOIN process_track AS pt
169*6dbdd20aSAndroid Build Coastguard Worker                ON cuj.track_id = pt.id
170*6dbdd20aSAndroid Build Coastguard Worker    WHERE cuj.name GLOB 'L<*>'
171*6dbdd20aSAndroid Build Coastguard Worker      AND cuj.dur > 0
172*6dbdd20aSAndroid Build Coastguard Worker`;
173*6dbdd20aSAndroid Build Coastguard Worker
174*6dbdd20aSAndroid Build Coastguard Workerconst LATENCY_COLUMNS = ['name', 'dur_ms', 'ts', 'dur', 'track_id', 'slice_id'];
175*6dbdd20aSAndroid Build Coastguard Worker
176*6dbdd20aSAndroid Build Coastguard Workerconst BLOCKING_CALLS_DURING_CUJS_QUERY = `
177*6dbdd20aSAndroid Build Coastguard Worker    SELECT
178*6dbdd20aSAndroid Build Coastguard Worker      s.id AS slice_id,
179*6dbdd20aSAndroid Build Coastguard Worker      s.name,
180*6dbdd20aSAndroid Build Coastguard Worker      max(s.ts, cuj.ts) AS ts,
181*6dbdd20aSAndroid Build Coastguard Worker      min(s.ts + s.dur, cuj.ts_end) as ts_end,
182*6dbdd20aSAndroid Build Coastguard Worker      min(s.ts + s.dur, cuj.ts_end) - max(s.ts, cuj.ts) AS dur,
183*6dbdd20aSAndroid Build Coastguard Worker      cuj.cuj_id,
184*6dbdd20aSAndroid Build Coastguard Worker      cuj.cuj_name,
185*6dbdd20aSAndroid Build Coastguard Worker      s.process_name,
186*6dbdd20aSAndroid Build Coastguard Worker      s.upid,
187*6dbdd20aSAndroid Build Coastguard Worker      s.utid,
188*6dbdd20aSAndroid Build Coastguard Worker      'slice' AS table_name
189*6dbdd20aSAndroid Build Coastguard Worker    FROM _android_critical_blocking_calls s
190*6dbdd20aSAndroid Build Coastguard Worker      JOIN  android_jank_cuj cuj
191*6dbdd20aSAndroid Build Coastguard Worker      -- only when there is an overlap
192*6dbdd20aSAndroid Build Coastguard Worker      ON s.ts + s.dur > cuj.ts AND s.ts < cuj.ts_end
193*6dbdd20aSAndroid Build Coastguard Worker          -- and are from the same process
194*6dbdd20aSAndroid Build Coastguard Worker          AND s.upid = cuj.upid
195*6dbdd20aSAndroid Build Coastguard Worker`;
196*6dbdd20aSAndroid Build Coastguard Worker
197*6dbdd20aSAndroid Build Coastguard Workerconst BLOCKING_CALLS_DURING_CUJS_COLUMNS = [
198*6dbdd20aSAndroid Build Coastguard Worker  'slice_id',
199*6dbdd20aSAndroid Build Coastguard Worker  'name',
200*6dbdd20aSAndroid Build Coastguard Worker  'ts',
201*6dbdd20aSAndroid Build Coastguard Worker  'cuj_ts',
202*6dbdd20aSAndroid Build Coastguard Worker  'dur',
203*6dbdd20aSAndroid Build Coastguard Worker  'cuj_id',
204*6dbdd20aSAndroid Build Coastguard Worker  'cuj_name',
205*6dbdd20aSAndroid Build Coastguard Worker  'process_name',
206*6dbdd20aSAndroid Build Coastguard Worker  'upid',
207*6dbdd20aSAndroid Build Coastguard Worker  'utid',
208*6dbdd20aSAndroid Build Coastguard Worker  'table_name',
209*6dbdd20aSAndroid Build Coastguard Worker];
210*6dbdd20aSAndroid Build Coastguard Worker
211*6dbdd20aSAndroid Build Coastguard Workerexport default class implements PerfettoPlugin {
212*6dbdd20aSAndroid Build Coastguard Worker  static readonly id = 'dev.perfetto.AndroidCujs';
213*6dbdd20aSAndroid Build Coastguard Worker  async onTraceLoad(ctx: Trace): Promise<void> {
214*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
215*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidCujs#PinJankCUJs',
216*6dbdd20aSAndroid Build Coastguard Worker      name: 'Add track: Android jank CUJs',
217*6dbdd20aSAndroid Build Coastguard Worker      callback: () => {
218*6dbdd20aSAndroid Build Coastguard Worker        ctx.engine.query(JANK_CUJ_QUERY_PRECONDITIONS).then(() => {
219*6dbdd20aSAndroid Build Coastguard Worker          addJankCUJDebugTrack(ctx, 'Jank CUJs');
220*6dbdd20aSAndroid Build Coastguard Worker        });
221*6dbdd20aSAndroid Build Coastguard Worker      },
222*6dbdd20aSAndroid Build Coastguard Worker    });
223*6dbdd20aSAndroid Build Coastguard Worker
224*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
225*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidCujs#ListJankCUJs',
226*6dbdd20aSAndroid Build Coastguard Worker      name: 'Run query: Android jank CUJs',
227*6dbdd20aSAndroid Build Coastguard Worker      callback: () => {
228*6dbdd20aSAndroid Build Coastguard Worker        ctx.engine.query(JANK_CUJ_QUERY_PRECONDITIONS).then(() =>
229*6dbdd20aSAndroid Build Coastguard Worker          addQueryResultsTab(ctx, {
230*6dbdd20aSAndroid Build Coastguard Worker            query: JANK_CUJ_QUERY,
231*6dbdd20aSAndroid Build Coastguard Worker            title: 'Android Jank CUJs',
232*6dbdd20aSAndroid Build Coastguard Worker          }),
233*6dbdd20aSAndroid Build Coastguard Worker        );
234*6dbdd20aSAndroid Build Coastguard Worker      },
235*6dbdd20aSAndroid Build Coastguard Worker    });
236*6dbdd20aSAndroid Build Coastguard Worker
237*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
238*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidCujs#PinLatencyCUJs',
239*6dbdd20aSAndroid Build Coastguard Worker      name: 'Add track: Android latency CUJs',
240*6dbdd20aSAndroid Build Coastguard Worker      callback: () => {
241*6dbdd20aSAndroid Build Coastguard Worker        addDebugSliceTrack({
242*6dbdd20aSAndroid Build Coastguard Worker          trace: ctx,
243*6dbdd20aSAndroid Build Coastguard Worker          data: {
244*6dbdd20aSAndroid Build Coastguard Worker            sqlSource: LATENCY_CUJ_QUERY,
245*6dbdd20aSAndroid Build Coastguard Worker            columns: LATENCY_COLUMNS,
246*6dbdd20aSAndroid Build Coastguard Worker          },
247*6dbdd20aSAndroid Build Coastguard Worker          title: 'Latency CUJs',
248*6dbdd20aSAndroid Build Coastguard Worker        });
249*6dbdd20aSAndroid Build Coastguard Worker      },
250*6dbdd20aSAndroid Build Coastguard Worker    });
251*6dbdd20aSAndroid Build Coastguard Worker
252*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
253*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidCujs#ListLatencyCUJs',
254*6dbdd20aSAndroid Build Coastguard Worker      name: 'Run query: Android Latency CUJs',
255*6dbdd20aSAndroid Build Coastguard Worker      callback: () =>
256*6dbdd20aSAndroid Build Coastguard Worker        addQueryResultsTab(ctx, {
257*6dbdd20aSAndroid Build Coastguard Worker          query: LATENCY_CUJ_QUERY,
258*6dbdd20aSAndroid Build Coastguard Worker          title: 'Android Latency CUJs',
259*6dbdd20aSAndroid Build Coastguard Worker        }),
260*6dbdd20aSAndroid Build Coastguard Worker    });
261*6dbdd20aSAndroid Build Coastguard Worker
262*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
263*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidCujs#PinBlockingCalls',
264*6dbdd20aSAndroid Build Coastguard Worker      name: 'Add track: Android Blocking calls during CUJs',
265*6dbdd20aSAndroid Build Coastguard Worker      callback: () => {
266*6dbdd20aSAndroid Build Coastguard Worker        ctx.engine.query(JANK_CUJ_QUERY_PRECONDITIONS).then(() =>
267*6dbdd20aSAndroid Build Coastguard Worker          addDebugSliceTrack({
268*6dbdd20aSAndroid Build Coastguard Worker            trace: ctx,
269*6dbdd20aSAndroid Build Coastguard Worker            data: {
270*6dbdd20aSAndroid Build Coastguard Worker              sqlSource: BLOCKING_CALLS_DURING_CUJS_QUERY,
271*6dbdd20aSAndroid Build Coastguard Worker              columns: BLOCKING_CALLS_DURING_CUJS_COLUMNS,
272*6dbdd20aSAndroid Build Coastguard Worker            },
273*6dbdd20aSAndroid Build Coastguard Worker            title: 'Blocking calls during CUJs',
274*6dbdd20aSAndroid Build Coastguard Worker            argColumns: BLOCKING_CALLS_DURING_CUJS_COLUMNS,
275*6dbdd20aSAndroid Build Coastguard Worker          }),
276*6dbdd20aSAndroid Build Coastguard Worker        );
277*6dbdd20aSAndroid Build Coastguard Worker      },
278*6dbdd20aSAndroid Build Coastguard Worker    });
279*6dbdd20aSAndroid Build Coastguard Worker  }
280*6dbdd20aSAndroid Build Coastguard Worker}
281