• 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 {Trace} from '../../public/trace';
16import {PerfettoPlugin} from '../../public/plugin';
17import {TrackNode} from '../../public/workspace';
18import {
19  DatasetSliceTrack,
20  DatasetSliceTrackAttrs,
21  ROW_SCHEMA,
22} from '../../components/tracks/dataset_slice_track';
23import {LONG, NUM, STR} from '../../trace_processor/query_result';
24import {SourceDataset} from '../../trace_processor/dataset';
25import {getColorForSlice, makeColorScheme} from '../../components/colorizer';
26import {HSLColor} from '../../base/color';
27
28export default class implements PerfettoPlugin {
29  // TODO(stevegolton): Call this plugins ExampleTracks or something, as it has
30  // turned into more of a generic plugin showcasing what you can do with
31  // tracks.
32  static readonly id = 'com.example.ExampleNestedTracks';
33  async onTraceLoad(ctx: Trace): Promise<void> {
34    const traceStartTime = ctx.traceInfo.start;
35    const traceDur = ctx.traceInfo.end - ctx.traceInfo.start;
36    await ctx.engine.query(`
37      create table example_events (
38        id INTEGER PRIMARY KEY AUTOINCREMENT,
39        name TEXT,
40        ts INTEGER,
41        dur INTEGER,
42        arg INTEGER
43      );
44
45      insert into example_events (name, ts, dur, arg)
46      values
47        ('Foo', ${traceStartTime}, ${traceDur}, 'aaa'),
48        ('Bar', ${traceStartTime}, ${traceDur / 2n}, 'bbb'),
49        ('Baz', ${traceStartTime}, ${traceDur / 3n}, 'aaa'),
50        ('Qux', ${traceStartTime + traceDur / 2n}, ${traceDur / 2n}, 'bbb')
51      ;
52    `);
53
54    const title = 'Test Track';
55    const uri = `com.example.ExampleNestedTracks#TestTrack`;
56    const track = new DatasetSliceTrack({
57      trace: ctx,
58      uri,
59      dataset: new SourceDataset({
60        src: 'select *, id as depth from example_events',
61        schema: {
62          ts: LONG,
63          name: STR,
64          dur: LONG,
65          id: NUM,
66          arg: STR,
67        },
68      }),
69      colorizer: (row) => {
70        // Example usage of colorizer
71        return getColorForSlice(`${row.arg}`);
72      },
73    });
74    ctx.tracks.registerTrack({
75      uri,
76      title,
77      track,
78    });
79
80    this.addNestedTracks(ctx, uri);
81
82    // The following are some examples of dataset tracks with different configurations.
83    this.addTrack(ctx, {
84      trace: ctx,
85      uri: 'Red track',
86      dataset: new SourceDataset({
87        src: 'example_events',
88        schema: {
89          id: NUM,
90          ts: LONG,
91          dur: LONG,
92          name: STR,
93        },
94      }),
95      colorizer: () => makeColorScheme(new HSLColor({h: 0, s: 50, l: 50})),
96    });
97
98    this.addTrack(ctx, {
99      trace: ctx,
100      uri: 'Instants',
101      dataset: new SourceDataset({
102        src: 'example_events',
103        schema: {
104          id: NUM,
105          ts: LONG,
106        },
107      }),
108      colorizer: () => makeColorScheme(new HSLColor({h: 90, s: 50, l: 50})),
109    });
110
111    this.addTrack(ctx, {
112      trace: ctx,
113      uri: 'Flat',
114      dataset: new SourceDataset({
115        src: 'select 0 as depth, * from example_events',
116        schema: {
117          id: NUM,
118          ts: LONG,
119          dur: LONG,
120          name: STR,
121          depth: NUM,
122        },
123      }),
124      colorizer: () => makeColorScheme(new HSLColor({h: 180, s: 50, l: 50})),
125    });
126  }
127
128  private addTrack<T extends ROW_SCHEMA>(
129    ctx: Trace,
130    attrs: DatasetSliceTrackAttrs<T>,
131  ) {
132    const title = attrs.uri;
133    const uri = attrs.uri;
134    const track = new DatasetSliceTrack(attrs);
135    ctx.tracks.registerTrack({
136      uri,
137      title,
138      track,
139    });
140    ctx.workspace.addChildInOrder(new TrackNode({title, uri, sortOrder: -100}));
141  }
142
143  private addNestedTracks(ctx: Trace, uri: string): void {
144    const trackRoot = new TrackNode({uri, title: 'Root'});
145    const track1 = new TrackNode({uri, title: '1'});
146    const track2 = new TrackNode({uri, title: '2'});
147    const track11 = new TrackNode({uri, title: '1.1'});
148    const track12 = new TrackNode({uri, title: '1.2'});
149    const track121 = new TrackNode({uri, title: '1.2.1'});
150    const track21 = new TrackNode({uri, title: '2.1'});
151
152    ctx.workspace.addChildInOrder(trackRoot);
153    trackRoot.addChildLast(track1);
154    trackRoot.addChildLast(track2);
155    track1.addChildLast(track11);
156    track1.addChildLast(track12);
157    track12.addChildLast(track121);
158    track2.addChildLast(track21);
159
160    ctx.commands.registerCommand({
161      id: 'com.example.ExampleNestedTracks#CloneTracksToNewWorkspace',
162      name: 'Clone track to new workspace',
163      callback: () => {
164        const ws = ctx.workspaces.createEmptyWorkspace('New workspace');
165        ws.addChildLast(trackRoot.clone());
166        ctx.workspaces.switchWorkspace(ws);
167      },
168    });
169
170    ctx.commands.registerCommand({
171      id: 'com.example.ExampleNestedTracks#DeepCloneTracksToNewWorkspace',
172      name: 'Clone all tracks to new workspace',
173      callback: () => {
174        const ws = ctx.workspaces.createEmptyWorkspace('Deep workspace');
175        ws.addChildLast(trackRoot.clone(true));
176        ctx.workspaces.switchWorkspace(ws);
177      },
178    });
179  }
180}
181