xref: /aosp_15_r20/external/perfetto/ui/src/plugins/dev.perfetto.AndroidPerf/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 {Trace} from '../../public/trace';
16*6dbdd20aSAndroid Build Coastguard Workerimport {PerfettoPlugin} from '../../public/plugin';
17*6dbdd20aSAndroid Build Coastguard Workerimport {getTimeSpanOfSelectionOrVisibleWindow} from '../../public/utils';
18*6dbdd20aSAndroid Build Coastguard Workerimport {addQueryResultsTab} from '../../components/query_table/query_result_tab';
19*6dbdd20aSAndroid Build Coastguard Workerimport {
20*6dbdd20aSAndroid Build Coastguard Worker  addDebugCounterTrack,
21*6dbdd20aSAndroid Build Coastguard Worker  addDebugSliceTrack,
22*6dbdd20aSAndroid Build Coastguard Worker  addPivotedTracks,
23*6dbdd20aSAndroid Build Coastguard Worker} from '../../components/tracks/debug_tracks';
24*6dbdd20aSAndroid Build Coastguard Worker
25*6dbdd20aSAndroid Build Coastguard Workerexport default class implements PerfettoPlugin {
26*6dbdd20aSAndroid Build Coastguard Worker  static readonly id = 'dev.perfetto.AndroidPerf';
27*6dbdd20aSAndroid Build Coastguard Worker  async addAppProcessStartsDebugTrack(
28*6dbdd20aSAndroid Build Coastguard Worker    ctx: Trace,
29*6dbdd20aSAndroid Build Coastguard Worker    reason: string,
30*6dbdd20aSAndroid Build Coastguard Worker    sliceName: string,
31*6dbdd20aSAndroid Build Coastguard Worker  ): Promise<void> {
32*6dbdd20aSAndroid Build Coastguard Worker    const sliceColumns = [
33*6dbdd20aSAndroid Build Coastguard Worker      'id',
34*6dbdd20aSAndroid Build Coastguard Worker      'ts',
35*6dbdd20aSAndroid Build Coastguard Worker      'dur',
36*6dbdd20aSAndroid Build Coastguard Worker      'reason',
37*6dbdd20aSAndroid Build Coastguard Worker      'process_name',
38*6dbdd20aSAndroid Build Coastguard Worker      'intent',
39*6dbdd20aSAndroid Build Coastguard Worker      'table_name',
40*6dbdd20aSAndroid Build Coastguard Worker    ];
41*6dbdd20aSAndroid Build Coastguard Worker    await addDebugSliceTrack({
42*6dbdd20aSAndroid Build Coastguard Worker      trace: ctx,
43*6dbdd20aSAndroid Build Coastguard Worker      data: {
44*6dbdd20aSAndroid Build Coastguard Worker        sqlSource: `
45*6dbdd20aSAndroid Build Coastguard Worker                    SELECT
46*6dbdd20aSAndroid Build Coastguard Worker                      start_id AS id,
47*6dbdd20aSAndroid Build Coastguard Worker                      proc_start_ts AS ts,
48*6dbdd20aSAndroid Build Coastguard Worker                      total_dur AS dur,
49*6dbdd20aSAndroid Build Coastguard Worker                      reason,
50*6dbdd20aSAndroid Build Coastguard Worker                      process_name,
51*6dbdd20aSAndroid Build Coastguard Worker                      intent,
52*6dbdd20aSAndroid Build Coastguard Worker                      'slice' AS table_name
53*6dbdd20aSAndroid Build Coastguard Worker                    FROM android_app_process_starts
54*6dbdd20aSAndroid Build Coastguard Worker                    WHERE reason = '${reason}'
55*6dbdd20aSAndroid Build Coastguard Worker                 `,
56*6dbdd20aSAndroid Build Coastguard Worker        columns: sliceColumns,
57*6dbdd20aSAndroid Build Coastguard Worker      },
58*6dbdd20aSAndroid Build Coastguard Worker      title: 'app_' + sliceName + '_start reason: ' + reason,
59*6dbdd20aSAndroid Build Coastguard Worker      argColumns: sliceColumns,
60*6dbdd20aSAndroid Build Coastguard Worker    });
61*6dbdd20aSAndroid Build Coastguard Worker  }
62*6dbdd20aSAndroid Build Coastguard Worker
63*6dbdd20aSAndroid Build Coastguard Worker  async onTraceLoad(ctx: Trace): Promise<void> {
64*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
65*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#BinderSystemServerIncoming',
66*6dbdd20aSAndroid Build Coastguard Worker      name: 'Run query: system_server incoming binder graph',
67*6dbdd20aSAndroid Build Coastguard Worker      callback: () =>
68*6dbdd20aSAndroid Build Coastguard Worker        addQueryResultsTab(ctx, {
69*6dbdd20aSAndroid Build Coastguard Worker          query: `INCLUDE PERFETTO MODULE android.binder;
70*6dbdd20aSAndroid Build Coastguard Worker           SELECT * FROM android_binder_incoming_graph((SELECT upid FROM process WHERE name = 'system_server'))`,
71*6dbdd20aSAndroid Build Coastguard Worker          title: 'system_server incoming binder graph',
72*6dbdd20aSAndroid Build Coastguard Worker        }),
73*6dbdd20aSAndroid Build Coastguard Worker    });
74*6dbdd20aSAndroid Build Coastguard Worker
75*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
76*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#BinderSystemServerOutgoing',
77*6dbdd20aSAndroid Build Coastguard Worker      name: 'Run query: system_server outgoing binder graph',
78*6dbdd20aSAndroid Build Coastguard Worker      callback: () =>
79*6dbdd20aSAndroid Build Coastguard Worker        addQueryResultsTab(ctx, {
80*6dbdd20aSAndroid Build Coastguard Worker          query: `INCLUDE PERFETTO MODULE android.binder;
81*6dbdd20aSAndroid Build Coastguard Worker           SELECT * FROM android_binder_outgoing_graph((SELECT upid FROM process WHERE name = 'system_server'))`,
82*6dbdd20aSAndroid Build Coastguard Worker          title: 'system_server outgoing binder graph',
83*6dbdd20aSAndroid Build Coastguard Worker        }),
84*6dbdd20aSAndroid Build Coastguard Worker    });
85*6dbdd20aSAndroid Build Coastguard Worker
86*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
87*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#MonitorContentionSystemServer',
88*6dbdd20aSAndroid Build Coastguard Worker      name: 'Run query: system_server monitor_contention graph',
89*6dbdd20aSAndroid Build Coastguard Worker      callback: () =>
90*6dbdd20aSAndroid Build Coastguard Worker        addQueryResultsTab(ctx, {
91*6dbdd20aSAndroid Build Coastguard Worker          query: `INCLUDE PERFETTO MODULE android.monitor_contention;
92*6dbdd20aSAndroid Build Coastguard Worker           SELECT * FROM android_monitor_contention_graph((SELECT upid FROM process WHERE name = 'system_server'))`,
93*6dbdd20aSAndroid Build Coastguard Worker          title: 'system_server monitor_contention graph',
94*6dbdd20aSAndroid Build Coastguard Worker        }),
95*6dbdd20aSAndroid Build Coastguard Worker    });
96*6dbdd20aSAndroid Build Coastguard Worker
97*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
98*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#BinderAll',
99*6dbdd20aSAndroid Build Coastguard Worker      name: 'Run query: all process binder graph',
100*6dbdd20aSAndroid Build Coastguard Worker      callback: () =>
101*6dbdd20aSAndroid Build Coastguard Worker        addQueryResultsTab(ctx, {
102*6dbdd20aSAndroid Build Coastguard Worker          query: `INCLUDE PERFETTO MODULE android.binder;
103*6dbdd20aSAndroid Build Coastguard Worker           SELECT * FROM android_binder_graph(-1000, 1000, -1000, 1000)`,
104*6dbdd20aSAndroid Build Coastguard Worker          title: 'all process binder graph',
105*6dbdd20aSAndroid Build Coastguard Worker        }),
106*6dbdd20aSAndroid Build Coastguard Worker    });
107*6dbdd20aSAndroid Build Coastguard Worker
108*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
109*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#ThreadClusterDistribution',
110*6dbdd20aSAndroid Build Coastguard Worker      name: 'Run query: runtime cluster distribution for a thread',
111*6dbdd20aSAndroid Build Coastguard Worker      callback: async (tid) => {
112*6dbdd20aSAndroid Build Coastguard Worker        if (tid === undefined) {
113*6dbdd20aSAndroid Build Coastguard Worker          tid = prompt('Enter a thread tid', '');
114*6dbdd20aSAndroid Build Coastguard Worker          if (tid === null) return;
115*6dbdd20aSAndroid Build Coastguard Worker        }
116*6dbdd20aSAndroid Build Coastguard Worker        addQueryResultsTab(ctx, {
117*6dbdd20aSAndroid Build Coastguard Worker          query: `
118*6dbdd20aSAndroid Build Coastguard Worker          INCLUDE PERFETTO MODULE android.cpu.cluster_type;
119*6dbdd20aSAndroid Build Coastguard Worker          WITH
120*6dbdd20aSAndroid Build Coastguard Worker            total_runtime AS (
121*6dbdd20aSAndroid Build Coastguard Worker              SELECT sum(dur) AS total_runtime
122*6dbdd20aSAndroid Build Coastguard Worker              FROM sched s
123*6dbdd20aSAndroid Build Coastguard Worker              LEFT JOIN thread t
124*6dbdd20aSAndroid Build Coastguard Worker                USING (utid)
125*6dbdd20aSAndroid Build Coastguard Worker              WHERE t.tid = ${tid}
126*6dbdd20aSAndroid Build Coastguard Worker            )
127*6dbdd20aSAndroid Build Coastguard Worker            SELECT
128*6dbdd20aSAndroid Build Coastguard Worker              c.cluster_type AS cluster, sum(dur)/1e6 AS total_dur_ms,
129*6dbdd20aSAndroid Build Coastguard Worker              sum(dur) * 1.0 / (SELECT * FROM total_runtime) AS percentage
130*6dbdd20aSAndroid Build Coastguard Worker            FROM sched s
131*6dbdd20aSAndroid Build Coastguard Worker            LEFT JOIN thread t
132*6dbdd20aSAndroid Build Coastguard Worker              USING (utid)
133*6dbdd20aSAndroid Build Coastguard Worker            LEFT JOIN android_cpu_cluster_mapping c
134*6dbdd20aSAndroid Build Coastguard Worker              USING (cpu)
135*6dbdd20aSAndroid Build Coastguard Worker            WHERE t.tid = ${tid}
136*6dbdd20aSAndroid Build Coastguard Worker            GROUP BY 1`,
137*6dbdd20aSAndroid Build Coastguard Worker          title: `runtime cluster distrubtion for tid ${tid}`,
138*6dbdd20aSAndroid Build Coastguard Worker        });
139*6dbdd20aSAndroid Build Coastguard Worker      },
140*6dbdd20aSAndroid Build Coastguard Worker    });
141*6dbdd20aSAndroid Build Coastguard Worker
142*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
143*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#SchedLatency',
144*6dbdd20aSAndroid Build Coastguard Worker      name: 'Run query: top 50 sched latency for a thread',
145*6dbdd20aSAndroid Build Coastguard Worker      callback: async (tid) => {
146*6dbdd20aSAndroid Build Coastguard Worker        if (tid === undefined) {
147*6dbdd20aSAndroid Build Coastguard Worker          tid = prompt('Enter a thread tid', '');
148*6dbdd20aSAndroid Build Coastguard Worker          if (tid === null) return;
149*6dbdd20aSAndroid Build Coastguard Worker        }
150*6dbdd20aSAndroid Build Coastguard Worker        addQueryResultsTab(ctx, {
151*6dbdd20aSAndroid Build Coastguard Worker          query: `
152*6dbdd20aSAndroid Build Coastguard Worker          SELECT ts.*, t.tid, t.name, tt.id AS track_id
153*6dbdd20aSAndroid Build Coastguard Worker          FROM thread_state ts
154*6dbdd20aSAndroid Build Coastguard Worker          LEFT JOIN thread_track tt
155*6dbdd20aSAndroid Build Coastguard Worker           USING (utid)
156*6dbdd20aSAndroid Build Coastguard Worker          LEFT JOIN thread t
157*6dbdd20aSAndroid Build Coastguard Worker           USING (utid)
158*6dbdd20aSAndroid Build Coastguard Worker          WHERE ts.state IN ('R', 'R+') AND tid = ${tid}
159*6dbdd20aSAndroid Build Coastguard Worker           ORDER BY dur DESC
160*6dbdd20aSAndroid Build Coastguard Worker          LIMIT 50`,
161*6dbdd20aSAndroid Build Coastguard Worker          title: `top 50 sched latency slice for tid ${tid}`,
162*6dbdd20aSAndroid Build Coastguard Worker        });
163*6dbdd20aSAndroid Build Coastguard Worker      },
164*6dbdd20aSAndroid Build Coastguard Worker    });
165*6dbdd20aSAndroid Build Coastguard Worker
166*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
167*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#SchedLatencyInSelectedWindow',
168*6dbdd20aSAndroid Build Coastguard Worker      name: 'Top 50 sched latency in selected time window',
169*6dbdd20aSAndroid Build Coastguard Worker      callback: async () => {
170*6dbdd20aSAndroid Build Coastguard Worker        const window = await getTimeSpanOfSelectionOrVisibleWindow(ctx);
171*6dbdd20aSAndroid Build Coastguard Worker        addQueryResultsTab(ctx, {
172*6dbdd20aSAndroid Build Coastguard Worker          title: 'top 50 sched latency slice in selcted time window',
173*6dbdd20aSAndroid Build Coastguard Worker          query: `SELECT
174*6dbdd20aSAndroid Build Coastguard Worker            ts.*,
175*6dbdd20aSAndroid Build Coastguard Worker            t.tid,
176*6dbdd20aSAndroid Build Coastguard Worker            t.name AS thread_name,
177*6dbdd20aSAndroid Build Coastguard Worker            tt.id AS track_id,
178*6dbdd20aSAndroid Build Coastguard Worker            p.name AS process_name
179*6dbdd20aSAndroid Build Coastguard Worker          FROM thread_state ts
180*6dbdd20aSAndroid Build Coastguard Worker          LEFT JOIN thread_track tt
181*6dbdd20aSAndroid Build Coastguard Worker           USING (utid)
182*6dbdd20aSAndroid Build Coastguard Worker          LEFT JOIN thread t
183*6dbdd20aSAndroid Build Coastguard Worker           USING (utid)
184*6dbdd20aSAndroid Build Coastguard Worker          LEFT JOIN process p
185*6dbdd20aSAndroid Build Coastguard Worker           USING (upid)
186*6dbdd20aSAndroid Build Coastguard Worker          WHERE ts.state IN ('R', 'R+')
187*6dbdd20aSAndroid Build Coastguard Worker           AND ts.ts >= ${window.start} and ts.ts < ${window.end}
188*6dbdd20aSAndroid Build Coastguard Worker          ORDER BY dur DESC
189*6dbdd20aSAndroid Build Coastguard Worker          LIMIT 50`,
190*6dbdd20aSAndroid Build Coastguard Worker        });
191*6dbdd20aSAndroid Build Coastguard Worker      },
192*6dbdd20aSAndroid Build Coastguard Worker    });
193*6dbdd20aSAndroid Build Coastguard Worker
194*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
195*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#AppProcessStarts',
196*6dbdd20aSAndroid Build Coastguard Worker      name: 'Add tracks: app process starts',
197*6dbdd20aSAndroid Build Coastguard Worker      callback: async () => {
198*6dbdd20aSAndroid Build Coastguard Worker        await ctx.engine.query(
199*6dbdd20aSAndroid Build Coastguard Worker          `INCLUDE PERFETTO MODULE android.app_process_starts;`,
200*6dbdd20aSAndroid Build Coastguard Worker        );
201*6dbdd20aSAndroid Build Coastguard Worker
202*6dbdd20aSAndroid Build Coastguard Worker        const startReason = ['activity', 'service', 'broadcast', 'provider'];
203*6dbdd20aSAndroid Build Coastguard Worker        for (const reason of startReason) {
204*6dbdd20aSAndroid Build Coastguard Worker          await this.addAppProcessStartsDebugTrack(ctx, reason, 'process_name');
205*6dbdd20aSAndroid Build Coastguard Worker        }
206*6dbdd20aSAndroid Build Coastguard Worker      },
207*6dbdd20aSAndroid Build Coastguard Worker    });
208*6dbdd20aSAndroid Build Coastguard Worker
209*6dbdd20aSAndroid Build Coastguard Worker    ctx.commands.registerCommand({
210*6dbdd20aSAndroid Build Coastguard Worker      id: 'dev.perfetto.AndroidPerf#AppIntentStarts',
211*6dbdd20aSAndroid Build Coastguard Worker      name: 'Add tracks: app intent starts',
212*6dbdd20aSAndroid Build Coastguard Worker      callback: async () => {
213*6dbdd20aSAndroid Build Coastguard Worker        await ctx.engine.query(
214*6dbdd20aSAndroid Build Coastguard Worker          `INCLUDE PERFETTO MODULE android.app_process_starts;`,
215*6dbdd20aSAndroid Build Coastguard Worker        );
216*6dbdd20aSAndroid Build Coastguard Worker
217*6dbdd20aSAndroid Build Coastguard Worker        const startReason = ['activity', 'service', 'broadcast'];
218*6dbdd20aSAndroid Build Coastguard Worker        for (const reason of startReason) {
219*6dbdd20aSAndroid Build Coastguard Worker          await this.addAppProcessStartsDebugTrack(ctx, reason, 'intent');
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.AndroidPerf#CounterByFtraceEventArgs',
226*6dbdd20aSAndroid Build Coastguard Worker      name: 'Add counter tracks by ftrace event arguments',
227*6dbdd20aSAndroid Build Coastguard Worker      callback: async (event, value, filter, filterValue) => {
228*6dbdd20aSAndroid Build Coastguard Worker        if (event === undefined) {
229*6dbdd20aSAndroid Build Coastguard Worker          event = prompt('Enter the name of the targeted ftrace event', '');
230*6dbdd20aSAndroid Build Coastguard Worker          if (event === null) return;
231*6dbdd20aSAndroid Build Coastguard Worker          const resp = await ctx.engine.query(`
232*6dbdd20aSAndroid Build Coastguard Worker            SELECT * FROM ftrace_event WHERE name = '${event}' LIMIT 1
233*6dbdd20aSAndroid Build Coastguard Worker          `);
234*6dbdd20aSAndroid Build Coastguard Worker          if (resp.numRows() === 0) {
235*6dbdd20aSAndroid Build Coastguard Worker            alert(`Can not find ${event} ftrace event in this trace`);
236*6dbdd20aSAndroid Build Coastguard Worker            return;
237*6dbdd20aSAndroid Build Coastguard Worker          }
238*6dbdd20aSAndroid Build Coastguard Worker        }
239*6dbdd20aSAndroid Build Coastguard Worker        if (value === undefined) {
240*6dbdd20aSAndroid Build Coastguard Worker          value = prompt('Enter the name of arguments as counter value', '');
241*6dbdd20aSAndroid Build Coastguard Worker          if (value === null) return;
242*6dbdd20aSAndroid Build Coastguard Worker          const resp = await ctx.engine.query(`
243*6dbdd20aSAndroid Build Coastguard Worker            SELECT *
244*6dbdd20aSAndroid Build Coastguard Worker            FROM ftrace_event
245*6dbdd20aSAndroid Build Coastguard Worker            JOIN args
246*6dbdd20aSAndroid Build Coastguard Worker              USING (arg_set_id)
247*6dbdd20aSAndroid Build Coastguard Worker            WHERE name = '${event}' AND key = '${value}'
248*6dbdd20aSAndroid Build Coastguard Worker            LIMIT 1
249*6dbdd20aSAndroid Build Coastguard Worker          `);
250*6dbdd20aSAndroid Build Coastguard Worker          if (resp.numRows() === 0) {
251*6dbdd20aSAndroid Build Coastguard Worker            alert(`The ${event} ftrace event does not have argument ${value}`);
252*6dbdd20aSAndroid Build Coastguard Worker            return;
253*6dbdd20aSAndroid Build Coastguard Worker          }
254*6dbdd20aSAndroid Build Coastguard Worker        }
255*6dbdd20aSAndroid Build Coastguard Worker        if (filter === undefined) {
256*6dbdd20aSAndroid Build Coastguard Worker          filter = prompt('Enter the name of arguments to pivot', '');
257*6dbdd20aSAndroid Build Coastguard Worker          if (filter === null) return;
258*6dbdd20aSAndroid Build Coastguard Worker          const resp = await ctx.engine.query(`
259*6dbdd20aSAndroid Build Coastguard Worker            SELECT *
260*6dbdd20aSAndroid Build Coastguard Worker            FROM ftrace_event
261*6dbdd20aSAndroid Build Coastguard Worker            JOIN args
262*6dbdd20aSAndroid Build Coastguard Worker              USING (arg_set_id)
263*6dbdd20aSAndroid Build Coastguard Worker            WHERE name = '${event}' AND key = '${filter}'
264*6dbdd20aSAndroid Build Coastguard Worker            LIMIT 1
265*6dbdd20aSAndroid Build Coastguard Worker          `);
266*6dbdd20aSAndroid Build Coastguard Worker          if (resp.numRows() === 0) {
267*6dbdd20aSAndroid Build Coastguard Worker            alert(`The ${event} ftrace event does not have argument ${filter}`);
268*6dbdd20aSAndroid Build Coastguard Worker            return;
269*6dbdd20aSAndroid Build Coastguard Worker          }
270*6dbdd20aSAndroid Build Coastguard Worker        }
271*6dbdd20aSAndroid Build Coastguard Worker        if (filterValue === undefined) {
272*6dbdd20aSAndroid Build Coastguard Worker          filterValue = prompt(
273*6dbdd20aSAndroid Build Coastguard Worker            'List the target pivot values (separate by comma) to present\n' +
274*6dbdd20aSAndroid Build Coastguard Worker              'ex1: 123,456 \n' +
275*6dbdd20aSAndroid Build Coastguard Worker              'ex2: "task_name1","task_name2"\n',
276*6dbdd20aSAndroid Build Coastguard Worker            '',
277*6dbdd20aSAndroid Build Coastguard Worker          );
278*6dbdd20aSAndroid Build Coastguard Worker          if (filterValue === null) return;
279*6dbdd20aSAndroid Build Coastguard Worker        }
280*6dbdd20aSAndroid Build Coastguard Worker        await addPivotedTracks(
281*6dbdd20aSAndroid Build Coastguard Worker          ctx,
282*6dbdd20aSAndroid Build Coastguard Worker          {
283*6dbdd20aSAndroid Build Coastguard Worker            sqlSource: `
284*6dbdd20aSAndroid Build Coastguard Worker              SELECT
285*6dbdd20aSAndroid Build Coastguard Worker                ts,
286*6dbdd20aSAndroid Build Coastguard Worker                EXTRACT_ARG(arg_set_id, '${value}') AS value,
287*6dbdd20aSAndroid Build Coastguard Worker                EXTRACT_ARG(arg_set_id, '${filter}') AS pivot
288*6dbdd20aSAndroid Build Coastguard Worker              FROM ftrace_event
289*6dbdd20aSAndroid Build Coastguard Worker                WHERE name = '${event}' AND pivot IN (${filterValue})`,
290*6dbdd20aSAndroid Build Coastguard Worker          },
291*6dbdd20aSAndroid Build Coastguard Worker          event + '#' + value + '@' + filter,
292*6dbdd20aSAndroid Build Coastguard Worker          'pivot',
293*6dbdd20aSAndroid Build Coastguard Worker          async (ctx, data, trackName) =>
294*6dbdd20aSAndroid Build Coastguard Worker            addDebugCounterTrack({
295*6dbdd20aSAndroid Build Coastguard Worker              trace: ctx,
296*6dbdd20aSAndroid Build Coastguard Worker              data,
297*6dbdd20aSAndroid Build Coastguard Worker              title: trackName,
298*6dbdd20aSAndroid Build Coastguard Worker            }),
299*6dbdd20aSAndroid Build Coastguard Worker        );
300*6dbdd20aSAndroid Build Coastguard Worker      },
301*6dbdd20aSAndroid Build Coastguard Worker    });
302*6dbdd20aSAndroid Build Coastguard Worker  }
303*6dbdd20aSAndroid Build Coastguard Worker}
304