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