Merge "ui: Remove logic to port chrome scroll jank plugin flag to plugin flag" into main
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 50b81bc..131332d 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -15322,6 +15322,8 @@
THREAD_MEMORY_INFRA = 50;
THREAD_SAMPLING_PROFILER = 51;
+
+ THREAD_COMPOSITOR_GPU = 52;
};
optional ThreadType thread_type = 1;
diff --git a/protos/perfetto/trace/track_event/chrome_thread_descriptor.proto b/protos/perfetto/trace/track_event/chrome_thread_descriptor.proto
index bd82b5a..5e2f119 100644
--- a/protos/perfetto/trace/track_event/chrome_thread_descriptor.proto
+++ b/protos/perfetto/trace/track_event/chrome_thread_descriptor.proto
@@ -77,6 +77,8 @@
THREAD_MEMORY_INFRA = 50;
THREAD_SAMPLING_PROFILER = 51;
+
+ THREAD_COMPOSITOR_GPU = 52;
};
optional ThreadType thread_type = 1;
diff --git a/src/trace_processor/importers/proto/chrome_string_lookup.cc b/src/trace_processor/importers/proto/chrome_string_lookup.cc
index f3e1125..f688510 100644
--- a/src/trace_processor/importers/proto/chrome_string_lookup.cc
+++ b/src/trace_processor/importers/proto/chrome_string_lookup.cc
@@ -170,6 +170,7 @@
"NetworkConfigWatcher"},
{ChromeThreadDescriptor::THREAD_WASAPI_RENDER, "wasapi_render_thread"},
{ChromeThreadDescriptor::THREAD_LOADER_LOCK_SAMPLER, "LoaderLockSampler"},
+ {ChromeThreadDescriptor::THREAD_COMPOSITOR_GPU, "CompositorGpuThread"},
};
} // namespace
diff --git a/ui/src/core/default_plugins.ts b/ui/src/core/default_plugins.ts
index 4791e8e..caba9f0 100644
--- a/ui/src/core/default_plugins.ts
+++ b/ui/src/core/default_plugins.ts
@@ -60,6 +60,7 @@
'dev.perfetto.RestorePinnedTrack',
'dev.perfetto.Sched',
'dev.perfetto.Screenshots',
+ 'dev.perfetto.SqlModules',
'dev.perfetto.Thread',
'dev.perfetto.ThreadState',
'dev.perfetto.TimelineSync',
diff --git a/ui/src/core/feature_flags.ts b/ui/src/core/feature_flags.ts
index b88f93b..7fa974d 100644
--- a/ui/src/core/feature_flags.ts
+++ b/ui/src/core/feature_flags.ts
@@ -16,6 +16,7 @@
// ~everywhere and the are "statically" initialized (i.e. files construct Flags
// at import time) if this file starts importing anything we will quickly run
// into issues with initialization order which will be a pain.
+import {z} from 'zod';
import {Flag, FlagSettings, OverrideState} from '../public/feature_flag';
export interface FlagStore {
@@ -28,22 +29,6 @@
[id: string]: OverrideState;
}
-// Check if the given object is a valid FlagOverrides.
-// This is necessary since someone could modify the persisted flags
-// behind our backs.
-function isFlagOverrides(o: object): o is FlagOverrides {
- const states = [
- OverrideState.TRUE.toString(),
- OverrideState.FALSE.toString(),
- ];
- for (const v of Object.values(o)) {
- if (typeof v !== 'string' || !states.includes(v)) {
- return false;
- }
- }
- return true;
-}
-
class Flags {
private store: FlagStore;
private flags: Map<string, FlagImpl>;
@@ -89,8 +74,17 @@
load(): void {
const o = this.store.load();
- if (isFlagOverrides(o)) {
- this.overrides = o;
+
+ // Check if the given object is a valid FlagOverrides.
+ // This is necessary since someone could modify the persisted flags
+ // behind our backs.
+ const flagsSchema = z.record(
+ z.string(),
+ z.union([z.literal(OverrideState.TRUE), z.literal(OverrideState.FALSE)]),
+ );
+ const {success, data} = flagsSchema.safeParse(o);
+ if (success) {
+ this.overrides = data;
}
}
diff --git a/ui/src/core_plugins/chrome_scroll_jank/event_latency_track.ts b/ui/src/core_plugins/chrome_scroll_jank/event_latency_track.ts
index 33b42b4..03ab372 100644
--- a/ui/src/core_plugins/chrome_scroll_jank/event_latency_track.ts
+++ b/ui/src/core_plugins/chrome_scroll_jank/event_latency_track.ts
@@ -13,7 +13,6 @@
// limitations under the License.
import {NamedRow} from '../../frontend/named_slice_track';
-import {NewTrackArgs} from '../../frontend/track';
import {Slice} from '../../public/track';
import {
CustomSqlTableDefConfig,
@@ -22,15 +21,17 @@
import {JANK_COLOR} from './jank_colors';
import {TrackEventSelection} from '../../public/selection';
import {EventLatencySliceDetailsPanel} from './event_latency_details_panel';
+import {Trace} from '../../public/trace';
export const JANKY_LATENCY_NAME = 'Janky EventLatency';
export class EventLatencyTrack extends CustomSqlTableSliceTrack {
constructor(
- args: NewTrackArgs,
+ trace: Trace,
+ uri: string,
private baseTable: string,
) {
- super(args);
+ super(trace, uri);
}
getSqlSource(): string {
diff --git a/ui/src/core_plugins/chrome_scroll_jank/index.ts b/ui/src/core_plugins/chrome_scroll_jank/index.ts
index a4ecca8..04feac4 100644
--- a/ui/src/core_plugins/chrome_scroll_jank/index.ts
+++ b/ui/src/core_plugins/chrome_scroll_jank/index.ts
@@ -54,10 +54,7 @@
ctx.tracks.registerTrack({
uri,
title,
- track: new TopLevelScrollTrack({
- trace: ctx,
- uri,
- }),
+ track: new TopLevelScrollTrack(ctx, uri),
});
const track = new TrackNode({uri, title});
@@ -166,7 +163,7 @@
ctx.tracks.registerTrack({
uri,
title,
- track: new EventLatencyTrack({trace: ctx, uri}, baseTable),
+ track: new EventLatencyTrack(ctx, uri, baseTable),
});
const track = new TrackNode({uri, title});
@@ -187,10 +184,7 @@
ctx.tracks.registerTrack({
uri,
title,
- track: new ScrollJankV3Track({
- trace: ctx,
- uri,
- }),
+ track: new ScrollJankV3Track(ctx, uri),
});
const track = new TrackNode({uri, title});
diff --git a/ui/src/frontend/base_counter_track.ts b/ui/src/frontend/base_counter_track.ts
index b5d57fa..2bea9d9 100644
--- a/ui/src/frontend/base_counter_track.ts
+++ b/ui/src/frontend/base_counter_track.ts
@@ -25,7 +25,6 @@
import {MenuDivider, MenuItem, PopupMenu2} from '../widgets/menu';
import {LONG, NUM} from '../trace_processor/query_result';
import {checkerboardExcept} from './checkerboard';
-import {NewTrackArgs} from './track';
import {AsyncDisposableStack} from '../base/disposable_stack';
import {Trace} from '../public/trace';
@@ -180,13 +179,7 @@
unit?: string;
}
-export type BaseCounterTrackArgs = NewTrackArgs & {
- options?: Partial<CounterOptions>;
-};
-
export abstract class BaseCounterTrack implements Track {
- protected trace: Trace;
- protected uri: string;
protected trackUuid = uuidv4Sql();
// This is the over-skirted cached bounds:
@@ -204,7 +197,6 @@
private mousePos = {x: 0, y: 0};
private hover?: CounterTooltipState;
- private defaultOptions: Partial<CounterOptions>;
private options?: CounterOptions;
private readonly trash: AsyncDisposableStack;
@@ -244,10 +236,11 @@
};
}
- constructor(args: BaseCounterTrackArgs) {
- this.trace = args.trace;
- this.uri = args.uri;
- this.defaultOptions = args.options ?? {};
+ constructor(
+ protected readonly trace: Trace,
+ protected readonly uri: string,
+ protected readonly defaultOptions: Partial<CounterOptions> = {},
+ ) {
this.trash = new AsyncDisposableStack();
}
diff --git a/ui/src/frontend/base_slice_track.ts b/ui/src/frontend/base_slice_track.ts
index 0c18970..83c9d73 100644
--- a/ui/src/frontend/base_slice_track.ts
+++ b/ui/src/frontend/base_slice_track.ts
@@ -28,7 +28,6 @@
import {LONG, NUM} from '../trace_processor/query_result';
import {checkerboardExcept} from './checkerboard';
import {DEFAULT_SLICE_LAYOUT, SliceLayout} from './slice_layout';
-import {NewTrackArgs} from './track';
import {BUCKETS_PER_PIXEL, CacheKey} from '../core/timeline_cache';
import {uuidv4Sql} from '../base/uuid';
import {AsyncDisposableStack} from '../base/disposable_stack';
@@ -163,8 +162,6 @@
> implements Track
{
protected sliceLayout: SliceLayout = {...DEFAULT_SLICE_LAYOUT};
- protected trace: Trace;
- protected uri: string;
protected trackUuid = uuidv4Sql();
// This is the over-skirted cached bounds:
@@ -240,9 +237,10 @@
_selectedSlice?: SliceT,
): void {}
- constructor(args: NewTrackArgs) {
- this.trace = args.trace;
- this.uri = args.uri;
+ constructor(
+ protected readonly trace: Trace,
+ protected readonly uri: string,
+ ) {
// Work out the extra columns.
// This is the union of the embedder-defined columns and the base columns
// we know about (ts, dur, ...).
diff --git a/ui/src/frontend/named_slice_track.ts b/ui/src/frontend/named_slice_track.ts
index 7a23285..07043e9 100644
--- a/ui/src/frontend/named_slice_track.ts
+++ b/ui/src/frontend/named_slice_track.ts
@@ -26,11 +26,11 @@
SLICE_FLAGS_INSTANT,
} from './base_slice_track';
import {ThreadSliceDetailsPanel} from './thread_slice_details_tab';
-import {NewTrackArgs} from './track';
import {renderDuration} from './widgets/duration';
import {TraceImpl} from '../core/trace_impl';
import {assertIsInstance} from '../base/logging';
import {SourceDataset, Dataset} from '../trace_processor/dataset';
+import {Trace} from '../public/trace';
export const NAMED_ROW = {
// Base columns (tsq, ts, dur, id, depth).
@@ -45,8 +45,8 @@
SliceType extends Slice = Slice,
RowType extends NamedRow = NamedRow,
> extends BaseSliceTrack<SliceType, RowType> {
- constructor(args: NewTrackArgs) {
- super(args);
+ constructor(trace: Trace, uri: string) {
+ super(trace, uri);
}
// Converts a SQL result row to an "Impl" Slice.
diff --git a/ui/src/frontend/thread_slice_track.ts b/ui/src/frontend/thread_slice_track.ts
index 6e47c8a..10a829f 100644
--- a/ui/src/frontend/thread_slice_track.ts
+++ b/ui/src/frontend/thread_slice_track.ts
@@ -16,13 +16,13 @@
import {clamp} from '../base/math_utils';
import {NAMED_ROW, NamedSliceTrack} from './named_slice_track';
import {SLICE_LAYOUT_FIT_CONTENT_DEFAULTS} from './slice_layout';
-import {NewTrackArgs} from './track';
import {LONG_NULL} from '../trace_processor/query_result';
import {Slice} from '../public/track';
import {TrackEventDetails} from '../public/selection';
import {ThreadSliceDetailsPanel} from './thread_slice_details_tab';
import {TraceImpl} from '../core/trace_impl';
import {assertIsInstance} from '../base/logging';
+import {Trace} from '../public/trace';
export const THREAD_SLICE_ROW = {
// Base columns (tsq, ts, dur, id, depth).
@@ -35,12 +35,13 @@
export class ThreadSliceTrack extends NamedSliceTrack<Slice, ThreadSliceRow> {
constructor(
- args: NewTrackArgs,
- private trackId: number,
+ trace: Trace,
+ uri: string,
+ private readonly trackId: number,
maxDepth: number,
- private tableName: string = 'slice',
+ private readonly tableName: string = 'slice',
) {
- super(args);
+ super(trace, uri);
this.sliceLayout = {
...SLICE_LAYOUT_FIT_CONTENT_DEFAULTS,
depthGuess: maxDepth,
diff --git a/ui/src/frontend/track.ts b/ui/src/frontend/track.ts
deleted file mode 100644
index f10e21e..0000000
--- a/ui/src/frontend/track.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {Trace} from '../public/trace';
-
-export interface NewTrackArgs {
- uri: string;
- trace: Trace;
-}
diff --git a/ui/src/frontend/tracks/custom_sql_table_slice_track.ts b/ui/src/frontend/tracks/custom_sql_table_slice_track.ts
index 7d3caa3..c157267 100644
--- a/ui/src/frontend/tracks/custom_sql_table_slice_track.ts
+++ b/ui/src/frontend/tracks/custom_sql_table_slice_track.ts
@@ -14,11 +14,11 @@
import {generateSqlWithInternalLayout} from '../../trace_processor/sql_utils/layout';
import {NAMED_ROW, NamedRow, NamedSliceTrack} from '../named_slice_track';
-import {NewTrackArgs} from '../track';
import {createView} from '../../trace_processor/sql_utils';
import {Slice} from '../../public/track';
import {AsyncDisposableStack} from '../../base/disposable_stack';
import {sqlNameSafe} from '../../base/string_utils';
+import {Trace} from '../../public/trace';
export interface CustomSqlImportConfig {
modules: string[];
@@ -39,9 +39,9 @@
> {
protected readonly tableName;
- constructor(args: NewTrackArgs) {
- super(args);
- this.tableName = `customsqltableslicetrack_${sqlNameSafe(args.uri)}`;
+ constructor(trace: Trace, uri: string) {
+ super(trace, uri);
+ this.tableName = `customsqltableslicetrack_${sqlNameSafe(uri)}`;
}
getRowSpec(): NamedRow {
diff --git a/ui/src/frontend/visualized_args_track.ts b/ui/src/frontend/visualized_args_track.ts
index fdea5b3..4b52b9d 100644
--- a/ui/src/frontend/visualized_args_track.ts
+++ b/ui/src/frontend/visualized_args_track.ts
@@ -46,7 +46,7 @@
const escapedArgName = argName.replace(/[^a-zA-Z]/g, '_');
const viewName = `__arg_visualisation_helper_${escapedArgName}_${uuid}_slice`;
- super({trace, uri}, trackId, maxDepth, viewName);
+ super(trace, uri, trackId, maxDepth, viewName);
this.viewName = viewName;
this.argName = argName;
this.onClose = onClose;
diff --git a/ui/src/plugins/dev.perfetto.AsyncSlices/async_slice_track.ts b/ui/src/plugins/dev.perfetto.AsyncSlices/async_slice_track.ts
index 0486e6e..0d55ff1 100644
--- a/ui/src/plugins/dev.perfetto.AsyncSlices/async_slice_track.ts
+++ b/ui/src/plugins/dev.perfetto.AsyncSlices/async_slice_track.ts
@@ -16,8 +16,8 @@
import {clamp} from '../../base/math_utils';
import {NAMED_ROW, NamedSliceTrack} from '../../frontend/named_slice_track';
import {SLICE_LAYOUT_FIT_CONTENT_DEFAULTS} from '../../frontend/slice_layout';
-import {NewTrackArgs} from '../../frontend/track';
import {TrackEventDetails} from '../../public/selection';
+import {Trace} from '../../public/trace';
import {Slice} from '../../public/track';
import {SourceDataset, Dataset} from '../../trace_processor/dataset';
import {
@@ -39,11 +39,12 @@
export class AsyncSliceTrack extends NamedSliceTrack<Slice, ThreadSliceRow> {
constructor(
- args: NewTrackArgs,
+ trace: Trace,
+ uri: string,
maxDepth: number,
private readonly trackIds: number[],
) {
- super(args);
+ super(trace, uri);
this.sliceLayout = {
...SLICE_LAYOUT_FIT_CONTENT_DEFAULTS,
depthGuess: maxDepth,
diff --git a/ui/src/plugins/dev.perfetto.AsyncSlices/index.ts b/ui/src/plugins/dev.perfetto.AsyncSlices/index.ts
index 9b0c6e7..ecd8dab 100644
--- a/ui/src/plugins/dev.perfetto.AsyncSlices/index.ts
+++ b/ui/src/plugins/dev.perfetto.AsyncSlices/index.ts
@@ -197,7 +197,7 @@
kind: SLICE_TRACK_KIND,
scope: 'global',
},
- track: new AsyncSliceTrack({trace: ctx, uri}, maxDepth, trackIds),
+ track: new AsyncSliceTrack(ctx, uri, maxDepth, trackIds),
});
const trackNode = new TrackNode({
uri,
@@ -283,7 +283,7 @@
scope: 'process',
upid,
},
- track: new AsyncSliceTrack({trace: ctx, uri}, maxDepth, trackIds),
+ track: new AsyncSliceTrack(ctx, uri, maxDepth, trackIds),
});
const track = new TrackNode({uri, title, sortOrder: 30});
trackIds.forEach((id) => {
@@ -384,7 +384,7 @@
chips: removeFalsyValues([
isKernelThread === 0 && isMainThread === 1 && 'main thread',
]),
- track: new AsyncSliceTrack({trace: ctx, uri}, maxDepth, trackIds),
+ track: new AsyncSliceTrack(ctx, uri, maxDepth, trackIds),
});
const track = new TrackNode({uri, title, sortOrder: 20});
trackIds.forEach((id) => {
diff --git a/ui/src/plugins/dev.perfetto.Counter/index.ts b/ui/src/plugins/dev.perfetto.Counter/index.ts
index 074e2c4..ef063ca 100644
--- a/ui/src/plugins/dev.perfetto.Counter/index.ts
+++ b/ui/src/plugins/dev.perfetto.Counter/index.ts
@@ -85,10 +85,6 @@
// options.yRangeSharingKey = 'mem';
// }
- if (name.startsWith('battery_stats.')) {
- options.yRangeSharingKey = 'battery_stats';
- }
-
// All 'Entity residency: foo bar1234' tracks should share a y-axis
// with 'Entity residency: foo baz5678' etc tracks:
{
@@ -163,16 +159,16 @@
kind: COUNTER_TRACK_KIND,
trackIds: [trackId],
},
- track: new TraceProcessorCounterTrack({
- trace: ctx,
+ track: new TraceProcessorCounterTrack(
+ ctx,
uri,
- trackId,
- trackName: title,
- options: {
+ {
...getDefaultCounterOptions(title),
unit,
},
- }),
+ trackId,
+ title,
+ ),
});
const track = new TrackNode({uri, title});
ctx.workspace.addChildInOrder(track);
@@ -242,13 +238,13 @@
trackIds: [trackId],
scope,
},
- track: new TraceProcessorCounterTrack({
- trace: ctx,
+ track: new TraceProcessorCounterTrack(
+ ctx,
uri,
- trackId: trackId,
- trackName: name,
- options: getDefaultCounterOptions(name),
- }),
+ getDefaultCounterOptions(name),
+ trackId,
+ name,
+ ),
});
const trackNode = new TrackNode({uri, title: name, sortOrder: -20});
ctx.workspace.addChildInOrder(trackNode);
@@ -309,13 +305,13 @@
upid: upid ?? undefined,
scope: 'thread',
},
- track: new TraceProcessorCounterTrack({
- trace: ctx,
+ track: new TraceProcessorCounterTrack(
+ ctx,
uri,
- trackId: trackId,
- trackName: name,
- options: getDefaultCounterOptions(name),
- }),
+ getDefaultCounterOptions(name),
+ trackId,
+ name,
+ ),
});
const group = getOrCreateGroupForThread(ctx.workspace, utid);
const track = new TrackNode({uri, title: name, sortOrder: 30});
@@ -367,13 +363,13 @@
upid,
scope: 'process',
},
- track: new TraceProcessorCounterTrack({
- trace: ctx,
+ track: new TraceProcessorCounterTrack(
+ ctx,
uri,
- trackId: trackId,
- trackName: name,
- options: getDefaultCounterOptions(name),
- }),
+ getDefaultCounterOptions(name),
+ trackId,
+ name,
+ ),
});
const group = getOrCreateGroupForProcess(ctx.workspace, upid);
const track = new TrackNode({uri, title: name, sortOrder: 20});
@@ -402,13 +398,13 @@
trackIds: [it.id],
scope: 'gpuFreq',
},
- track: new TraceProcessorCounterTrack({
- trace: ctx,
+ track: new TraceProcessorCounterTrack(
+ ctx,
uri,
- trackId: it.id,
- trackName: name,
- options: getDefaultCounterOptions(name),
- }),
+ getDefaultCounterOptions(name),
+ it.id,
+ name,
+ ),
});
const track = new TrackNode({uri, title: name, sortOrder: -20});
ctx.workspace.addChildInOrder(track);
diff --git a/ui/src/plugins/dev.perfetto.Counter/trace_processor_counter_track.ts b/ui/src/plugins/dev.perfetto.Counter/trace_processor_counter_track.ts
index ddbdbcb..a76fcef 100644
--- a/ui/src/plugins/dev.perfetto.Counter/trace_processor_counter_track.ts
+++ b/ui/src/plugins/dev.perfetto.Counter/trace_processor_counter_track.ts
@@ -12,33 +12,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import {LONG, LONG_NULL, NUM} from '../../trace_processor/query_result';
+import {Time} from '../../base/time';
import {
BaseCounterTrack,
- BaseCounterTrackArgs,
+ CounterOptions,
} from '../../frontend/base_counter_track';
-
-import {TrackMouseEvent} from '../../public/track';
import {TrackEventDetails} from '../../public/selection';
-import {Time} from '../../base/time';
+import {Trace} from '../../public/trace';
+import {TrackMouseEvent} from '../../public/track';
+import {LONG, LONG_NULL, NUM} from '../../trace_processor/query_result';
import {CounterDetailsPanel} from './counter_details_panel';
-interface TraceProcessorCounterTrackArgs extends BaseCounterTrackArgs {
- readonly trackId: number;
- readonly trackName: string;
- readonly rootTable?: string;
-}
-
export class TraceProcessorCounterTrack extends BaseCounterTrack {
- private readonly trackId: number;
- private readonly rootTable: string;
- private readonly trackName: string;
-
- constructor(args: TraceProcessorCounterTrackArgs) {
- super(args);
- this.trackId = args.trackId;
- this.rootTable = args.rootTable ?? 'counter';
- this.trackName = args.trackName;
+ constructor(
+ trace: Trace,
+ uri: string,
+ options: Partial<CounterOptions>,
+ private readonly trackId: number,
+ private readonly trackName: string,
+ private readonly rootTable: string = 'counter',
+ ) {
+ super(trace, uri, options);
}
getSqlSource() {
diff --git a/ui/src/plugins/dev.perfetto.CpuProfile/cpu_profile_track.ts b/ui/src/plugins/dev.perfetto.CpuProfile/cpu_profile_track.ts
index 4baeddf..0bd6fe8 100644
--- a/ui/src/plugins/dev.perfetto.CpuProfile/cpu_profile_track.ts
+++ b/ui/src/plugins/dev.perfetto.CpuProfile/cpu_profile_track.ts
@@ -20,10 +20,10 @@
OnSliceClickArgs,
} from '../../frontend/base_slice_track';
import {NAMED_ROW, NamedRow} from '../../frontend/named_slice_track';
-import {NewTrackArgs} from '../../frontend/track';
import {NUM} from '../../trace_processor/query_result';
import {Slice} from '../../public/track';
import {CpuProfileSampleFlamegraphDetailsPanel} from './cpu_profile_details_panel';
+import {Trace} from '../../public/trace';
interface CpuProfileRow extends NamedRow {
callsiteId: number;
@@ -31,10 +31,11 @@
export class CpuProfileTrack extends BaseSliceTrack<Slice, CpuProfileRow> {
constructor(
- args: NewTrackArgs,
+ trace: Trace,
+ uri: string,
private utid: number,
) {
- super(args);
+ super(trace, uri);
}
protected getRowSpec(): CpuProfileRow {
diff --git a/ui/src/plugins/dev.perfetto.CpuProfile/index.ts b/ui/src/plugins/dev.perfetto.CpuProfile/index.ts
index 31e49fe..e33e341 100644
--- a/ui/src/plugins/dev.perfetto.CpuProfile/index.ts
+++ b/ui/src/plugins/dev.perfetto.CpuProfile/index.ts
@@ -60,13 +60,7 @@
utid,
...(exists(upid) && {upid}),
},
- track: new CpuProfileTrack(
- {
- trace: ctx,
- uri,
- },
- utid,
- ),
+ track: new CpuProfileTrack(ctx, uri, utid),
});
const group = getOrCreateGroupForThread(ctx.workspace, utid);
const track = new TrackNode({uri, title, sortOrder: -40});
diff --git a/ui/src/plugins/dev.perfetto.Frames/actual_frames_track.ts b/ui/src/plugins/dev.perfetto.Frames/actual_frames_track.ts
index 2c19110..c6ef4b3 100644
--- a/ui/src/plugins/dev.perfetto.Frames/actual_frames_track.ts
+++ b/ui/src/plugins/dev.perfetto.Frames/actual_frames_track.ts
@@ -55,7 +55,7 @@
uri: string,
private trackIds: number[],
) {
- super({trace, uri});
+ super(trace, uri);
this.sliceLayout = {
...SLICE_LAYOUT_FIT_CONTENT_DEFAULTS,
depthGuess: maxDepth,
diff --git a/ui/src/plugins/dev.perfetto.Frames/expected_frames_track.ts b/ui/src/plugins/dev.perfetto.Frames/expected_frames_track.ts
index ff04311..27557fc 100644
--- a/ui/src/plugins/dev.perfetto.Frames/expected_frames_track.ts
+++ b/ui/src/plugins/dev.perfetto.Frames/expected_frames_track.ts
@@ -33,7 +33,7 @@
uri: string,
private trackIds: number[],
) {
- super({trace, uri});
+ super(trace, uri);
this.sliceLayout = {
...SLICE_LAYOUT_FIT_CONTENT_DEFAULTS,
depthGuess: maxDepth,
diff --git a/ui/src/plugins/dev.perfetto.GpuByProcess/index.ts b/ui/src/plugins/dev.perfetto.GpuByProcess/index.ts
index 9705156..b34717e 100644
--- a/ui/src/plugins/dev.perfetto.GpuByProcess/index.ts
+++ b/ui/src/plugins/dev.perfetto.GpuByProcess/index.ts
@@ -21,13 +21,14 @@
NamedRow,
NamedSliceTrack,
} from '../../frontend/named_slice_track';
-import {NewTrackArgs} from '../../frontend/track';
import {TrackNode} from '../../public/workspace';
class GpuPidTrack extends NamedSliceTrack {
- upid: number;
-
- constructor(args: NewTrackArgs, upid: number) {
- super(args);
+ constructor(
+ trace: Trace,
+ uri: string,
+ protected readonly upid: number,
+ ) {
+ super(trace, uri);
this.upid = upid;
}
@@ -84,7 +85,7 @@
ctx.tracks.registerTrack({
uri,
title,
- track: new GpuPidTrack({trace: ctx, uri}, upid),
+ track: new GpuPidTrack(ctx, uri, upid),
});
const track = new TrackNode({uri, title});
track.uri = uri;
diff --git a/ui/src/plugins/dev.perfetto.HeapProfile/heap_profile_track.ts b/ui/src/plugins/dev.perfetto.HeapProfile/heap_profile_track.ts
index d4effa4..45f1d0e 100644
--- a/ui/src/plugins/dev.perfetto.HeapProfile/heap_profile_track.ts
+++ b/ui/src/plugins/dev.perfetto.HeapProfile/heap_profile_track.ts
@@ -19,13 +19,13 @@
OnSliceClickArgs,
OnSliceOverArgs,
} from '../../frontend/base_slice_track';
-import {NewTrackArgs} from '../../frontend/track';
import {
ProfileType,
profileType,
TrackEventDetails,
TrackEventSelection,
} from '../../public/selection';
+import {Trace} from '../../public/trace';
import {Slice} from '../../public/track';
import {LONG, STR} from '../../trace_processor/query_result';
import {HeapProfileFlamegraphDetailsPanel} from './heap_profile_details_panel';
@@ -44,12 +44,13 @@
HeapProfileRow
> {
constructor(
- args: NewTrackArgs,
+ trace: Trace,
+ uri: string,
private readonly tableName: string,
private readonly upid: number,
private readonly heapProfileIsIncomplete: boolean,
) {
- super(args);
+ super(trace, uri);
}
getSqlSource(): string {
diff --git a/ui/src/plugins/dev.perfetto.HeapProfile/index.ts b/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
index f4f9121..2e0591f 100644
--- a/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
+++ b/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
@@ -92,15 +92,7 @@
kind: HEAP_PROFILE_TRACK_KIND,
upid,
},
- track: new HeapProfileTrack(
- {
- trace: ctx,
- uri,
- },
- tableName,
- upid,
- incomplete,
- ),
+ track: new HeapProfileTrack(ctx, uri, tableName, upid, incomplete),
});
const group = getOrCreateGroupForProcess(ctx.workspace, upid);
const track = new TrackNode({uri, title, sortOrder: -30});
diff --git a/ui/src/plugins/dev.perfetto.PerfSamplesProfile/index.ts b/ui/src/plugins/dev.perfetto.PerfSamplesProfile/index.ts
index 26ac305..04e8b13 100644
--- a/ui/src/plugins/dev.perfetto.PerfSamplesProfile/index.ts
+++ b/ui/src/plugins/dev.perfetto.PerfSamplesProfile/index.ts
@@ -57,13 +57,7 @@
kind: PERF_SAMPLES_PROFILE_TRACK_KIND,
upid,
},
- track: new ProcessPerfSamplesProfileTrack(
- {
- trace: ctx,
- uri,
- },
- upid,
- ),
+ track: new ProcessPerfSamplesProfileTrack(ctx, uri, upid),
});
const group = getOrCreateGroupForProcess(ctx.workspace, upid);
const track = new TrackNode({uri, title, sortOrder: -40});
@@ -103,13 +97,7 @@
utid,
upid: upid ?? undefined,
},
- track: new ThreadPerfSamplesProfileTrack(
- {
- trace: ctx,
- uri,
- },
- utid,
- ),
+ track: new ThreadPerfSamplesProfileTrack(ctx, uri, utid),
});
const group = getOrCreateGroupForThread(ctx.workspace, utid);
const track = new TrackNode({uri, title, sortOrder: -50});
diff --git a/ui/src/plugins/dev.perfetto.PerfSamplesProfile/perf_samples_profile_track.ts b/ui/src/plugins/dev.perfetto.PerfSamplesProfile/perf_samples_profile_track.ts
index 839d0d1..06f3244 100644
--- a/ui/src/plugins/dev.perfetto.PerfSamplesProfile/perf_samples_profile_track.ts
+++ b/ui/src/plugins/dev.perfetto.PerfSamplesProfile/perf_samples_profile_track.ts
@@ -19,7 +19,6 @@
BaseSliceTrack,
OnSliceClickArgs,
} from '../../frontend/base_slice_track';
-import {NewTrackArgs} from '../../frontend/track';
import {NAMED_ROW, NamedRow} from '../../frontend/named_slice_track';
import {getColorForSample} from '../../public/lib/colorizer';
import {
@@ -37,6 +36,7 @@
import {time} from '../../base/time';
import {TrackEventDetailsPanel} from '../../public/details_panel';
import {Flamegraph, FLAMEGRAPH_STATE_SCHEMA} from '../../widgets/flamegraph';
+import {Trace} from '../../public/trace';
interface PerfSampleRow extends NamedRow {
callsiteId: number;
@@ -46,8 +46,8 @@
Slice,
PerfSampleRow
> {
- constructor(args: NewTrackArgs) {
- super(args);
+ constructor(trace: Trace, uri: string) {
+ super(trace, uri);
}
protected getRowSpec(): PerfSampleRow {
@@ -75,10 +75,11 @@
export class ProcessPerfSamplesProfileTrack extends BasePerfSamplesProfileTrack {
constructor(
- args: NewTrackArgs,
- private upid: number,
+ trace: Trace,
+ uri: string,
+ private readonly upid: number,
) {
- super(args);
+ super(trace, uri);
}
getSqlSource(): string {
@@ -170,10 +171,11 @@
export class ThreadPerfSamplesProfileTrack extends BasePerfSamplesProfileTrack {
constructor(
- args: NewTrackArgs,
- private utid: number,
+ trace: Trace,
+ uri: string,
+ private readonly utid: number,
) {
- super(args);
+ super(trace, uri);
}
getSqlSource(): string {
diff --git a/ui/src/plugins/dev.perfetto.Sched/active_cpu_count.ts b/ui/src/plugins/dev.perfetto.Sched/active_cpu_count.ts
index 328d386..02ff0b2 100644
--- a/ui/src/plugins/dev.perfetto.Sched/active_cpu_count.ts
+++ b/ui/src/plugins/dev.perfetto.Sched/active_cpu_count.ts
@@ -33,10 +33,7 @@
private readonly cpuType?: CPUType;
constructor(ctx: TrackContext, trace: Trace, cpuType?: CPUType) {
- super({
- trace,
- uri: ctx.trackUri,
- });
+ super(trace, ctx.trackUri);
this.cpuType = cpuType;
}
diff --git a/ui/src/plugins/dev.perfetto.Sched/index.ts b/ui/src/plugins/dev.perfetto.Sched/index.ts
index 68d3d0b..8be599d 100644
--- a/ui/src/plugins/dev.perfetto.Sched/index.ts
+++ b/ui/src/plugins/dev.perfetto.Sched/index.ts
@@ -31,10 +31,7 @@
ctx.tracks.registerTrack({
uri: runnableThreadCountUri,
title: 'Runnable thread count',
- track: new RunnableThreadCountTrack({
- trace: ctx,
- uri: runnableThreadCountUri,
- }),
+ track: new RunnableThreadCountTrack(ctx, runnableThreadCountUri),
});
ctx.commands.registerCommand({
id: 'dev.perfetto.Sched.AddRunnableThreadCountTrackCommand',
@@ -47,10 +44,10 @@
ctx.tracks.registerTrack({
uri: uninterruptibleSleepThreadCountUri,
title: 'Uninterruptible Sleep thread count',
- track: new UninterruptibleSleepThreadCountTrack({
- trace: ctx,
- uri: uninterruptibleSleepThreadCountUri,
- }),
+ track: new UninterruptibleSleepThreadCountTrack(
+ ctx,
+ uninterruptibleSleepThreadCountUri,
+ ),
});
ctx.commands.registerCommand({
id: 'dev.perfetto.Sched.AddUninterruptibleSleepThreadCountTrackCommand',
diff --git a/ui/src/plugins/dev.perfetto.Sched/thread_count.ts b/ui/src/plugins/dev.perfetto.Sched/thread_count.ts
index 88fe892..73e7ee2 100644
--- a/ui/src/plugins/dev.perfetto.Sched/thread_count.ts
+++ b/ui/src/plugins/dev.perfetto.Sched/thread_count.ts
@@ -16,11 +16,11 @@
BaseCounterTrack,
CounterOptions,
} from '../../frontend/base_counter_track';
-import {NewTrackArgs} from '../../frontend/track';
+import {Trace} from '../../public/trace';
abstract class ThreadCountTrack extends BaseCounterTrack {
- constructor(args: NewTrackArgs) {
- super(args);
+ constructor(trace: Trace, uri: string) {
+ super(trace, uri);
}
protected getDefaultCounterOptions(): CounterOptions {
diff --git a/ui/src/plugins/dev.perfetto.Screenshots/index.ts b/ui/src/plugins/dev.perfetto.Screenshots/index.ts
index 68c7d64..7cadbf7 100644
--- a/ui/src/plugins/dev.perfetto.Screenshots/index.ts
+++ b/ui/src/plugins/dev.perfetto.Screenshots/index.ts
@@ -35,10 +35,7 @@
ctx.tracks.registerTrack({
uri,
title,
- track: new ScreenshotsTrack({
- trace: ctx,
- uri,
- }),
+ track: new ScreenshotsTrack(ctx, uri),
tags: {
kind: ScreenshotsTrack.kind,
},
diff --git a/ui/src/plugins/dev.perfetto.SqlModules/index.ts b/ui/src/plugins/dev.perfetto.SqlModules/index.ts
new file mode 100644
index 0000000..f2fde8d
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.SqlModules/index.ts
@@ -0,0 +1,35 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {assetSrc} from '../../base/assets';
+import {assertExists} from '../../base/logging';
+import {PerfettoPlugin} from '../../public/plugin';
+import {SqlModules} from './sql_modules';
+import {SQL_MODULES_DOCS_SCHEMA, SqlModulesImpl} from './sql_modules_impl';
+
+export default class implements PerfettoPlugin {
+ static readonly id = 'dev.perfetto.SqlModules';
+ private sqlModules?: SqlModules;
+
+ async onTraceLoad() {
+ const resp = await fetch(assetSrc('stdlib_docs.json'));
+ const json = await resp.json();
+ const docs = SQL_MODULES_DOCS_SCHEMA.parse(json);
+ this.sqlModules = new SqlModulesImpl(docs);
+ }
+
+ getSqlModules() {
+ return assertExists(this.sqlModules);
+ }
+}
diff --git a/ui/src/plugins/dev.perfetto.SqlModules/sql_modules.ts b/ui/src/plugins/dev.perfetto.SqlModules/sql_modules.ts
new file mode 100644
index 0000000..9f0503a
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.SqlModules/sql_modules.ts
@@ -0,0 +1,90 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Handles the access to all of the Perfetto SQL modules accessible to Trace
+// Processor.
+export interface SqlModules {
+ // Returns names of all tables/views between all loaded Perfetto SQL modules.
+ listTables(): string[];
+
+ // Returns Perfetto SQL table/view if it was loaded in one of the Perfetto
+ // SQL module.
+ getTable(tableName: string): SqlTable | undefined;
+}
+
+// Handles the access to a specific Perfetto SQL Package. Package consists of
+// Perfetto SQL modules.
+export interface SqlPackage {
+ readonly name: string;
+ readonly modules: SqlModule[];
+ listTables(): string[];
+ getTable(tableName: string): SqlTable | undefined;
+}
+
+// Handles the access to a specific Perfetto SQL module.
+export interface SqlModule {
+ readonly includeKey: string;
+ readonly dataObjects: SqlTable[];
+ readonly functions: SqlFunction[];
+ readonly tableFunctions: SqlTableFunction[];
+ readonly macros: SqlMacro[];
+}
+
+// The definition of Perfetto SQL table/view.
+export interface SqlTable {
+ readonly name: string;
+ readonly description: string;
+ readonly type: string;
+ readonly columns: SqlColumn[];
+}
+
+// The definition of Perfetto SQL function.
+export interface SqlFunction {
+ readonly name: string;
+ readonly description: string;
+ readonly args: SqlArgument[];
+ readonly returnType: string;
+ readonly returnDesc: string;
+}
+
+// The definition of Perfetto SQL table function.
+export interface SqlTableFunction {
+ readonly name: string;
+ readonly description: string;
+ readonly args: SqlArgument[];
+ readonly returnCols: SqlColumn[];
+}
+
+// The definition of Perfetto SQL macro.
+export interface SqlMacro {
+ readonly name: string;
+ readonly description: string;
+ readonly args: SqlArgument[];
+ readonly returnType: string;
+}
+
+// The definition of Perfetto SQL column.
+export interface SqlColumn {
+ readonly name: string;
+ readonly description: string;
+ readonly type: string;
+}
+
+// The definition of Perfetto SQL argument. Can be used for functions, table
+// functions or macros.
+export interface SqlArgument {
+ readonly name: string;
+ readonly description: string;
+ readonly type: string;
+}
diff --git a/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_impl.ts b/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_impl.ts
new file mode 100644
index 0000000..ee6fe79
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_impl.ts
@@ -0,0 +1,254 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {z} from 'zod';
+import {
+ SqlModules,
+ SqlColumn,
+ SqlFunction,
+ SqlArgument,
+ SqlMacro,
+ SqlModule,
+ SqlPackage,
+ SqlTable,
+ SqlTableFunction,
+} from './sql_modules';
+
+export class SqlModulesImpl implements SqlModules {
+ readonly packages: SqlPackage[];
+
+ constructor(docs: SqlModulesDocsSchema) {
+ this.packages = docs.map((json) => new StdlibPackageImpl(json));
+ }
+
+ listTables(): string[] {
+ const tables: string[] = [];
+ for (const stdlibPackage of this.packages) {
+ tables.concat(stdlibPackage.listTables());
+ }
+ return tables;
+ }
+
+ getTable(tableName: string): SqlTable | undefined {
+ for (const stdlibPackage of this.packages) {
+ const maybeTable = stdlibPackage.getTable(tableName);
+ if (maybeTable) {
+ return maybeTable;
+ }
+ }
+ return undefined;
+ }
+}
+
+export class StdlibPackageImpl implements SqlPackage {
+ readonly name: string;
+ readonly modules: SqlModule[];
+
+ constructor(docs: DocsPackageSchemaType) {
+ this.name = docs.name;
+ this.modules = [];
+ for (const moduleJson of docs.modules) {
+ this.modules.push(new StdlibModuleImpl(moduleJson));
+ }
+ }
+
+ getTable(tableName: string): SqlTable | undefined {
+ for (const module of this.modules) {
+ for (const dataObj of module.dataObjects) {
+ if (dataObj.name == tableName) {
+ return dataObj;
+ }
+ }
+ }
+ return undefined;
+ }
+
+ listTables(): string[] {
+ return this.modules.flatMap((module) =>
+ module.dataObjects.map((dataObj) => dataObj.name),
+ );
+ }
+}
+
+export class StdlibModuleImpl implements SqlModule {
+ readonly includeKey: string;
+ readonly dataObjects: SqlTable[];
+ readonly functions: SqlFunction[];
+ readonly tableFunctions: SqlTableFunction[];
+ readonly macros: SqlMacro[];
+
+ constructor(docs: DocsModuleSchemaType) {
+ this.includeKey = docs.module_name;
+ this.dataObjects = docs.data_objects.map(
+ (json) => new StdlibDataObjectImpl(json),
+ );
+ this.functions = docs.functions.map((json) => new StdlibFunctionImpl(json));
+ this.tableFunctions = docs.table_functions.map(
+ (json) => new StdlibTableFunctionImpl(json),
+ );
+ this.macros = docs.macros.map((json) => new StdlibMacroImpl(json));
+ }
+}
+
+class StdlibMacroImpl implements SqlMacro {
+ readonly name: string;
+ readonly summaryDesc: string;
+ readonly description: string;
+ readonly args: SqlArgument[];
+ readonly returnType: string;
+
+ constructor(docs: DocsMacroSchemaType) {
+ this.name = docs.name;
+ this.summaryDesc = docs.summary_desc;
+ this.description = docs.desc;
+ this.returnType = docs.return_type;
+ this.args = [];
+ this.args = docs.args.map((json) => new StdlibFunctionArgImpl(json));
+ }
+}
+
+class StdlibTableFunctionImpl implements SqlTableFunction {
+ readonly name: string;
+ readonly summaryDesc: string;
+ readonly description: string;
+ readonly args: SqlArgument[];
+ readonly returnCols: SqlColumn[];
+
+ constructor(docs: DocsTableFunctionSchemaType) {
+ this.name = docs.name;
+ this.summaryDesc = docs.summary_desc;
+ this.description = docs.desc;
+ this.args = docs.args.map((json) => new StdlibFunctionArgImpl(json));
+ this.returnCols = docs.cols.map((json) => new StdlibColumnImpl(json));
+ }
+}
+
+class StdlibFunctionImpl implements SqlFunction {
+ readonly name: string;
+ readonly summaryDesc: string;
+ readonly description: string;
+ readonly args: SqlArgument[];
+ readonly returnType: string;
+ readonly returnDesc: string;
+
+ constructor(docs: DocsFunctionSchemaType) {
+ this.name = docs.name;
+ this.summaryDesc = docs.summary_desc;
+ this.description = docs.desc;
+ this.returnType = docs.return_type;
+ this.returnDesc = docs.return_desc;
+ this.args = docs.args.map((json) => new StdlibFunctionArgImpl(json));
+ }
+}
+
+class StdlibDataObjectImpl implements SqlTable {
+ name: string;
+ description: string;
+ type: string;
+ columns: SqlColumn[];
+
+ constructor(docs: DocsDataObjectSchemaType) {
+ this.name = docs.name;
+ this.description = docs.desc;
+ this.type = docs.type;
+ this.columns = docs.cols.map((json) => new StdlibColumnImpl(json));
+ }
+}
+
+class StdlibColumnImpl implements SqlColumn {
+ name: string;
+ type: string;
+ description: string;
+
+ constructor(docs: DocsArgOrColSchemaType) {
+ this.type = docs.type;
+ this.description = docs.desc;
+ this.name = docs.name;
+ }
+}
+
+class StdlibFunctionArgImpl implements SqlArgument {
+ name: string;
+ description: string;
+ type: string;
+
+ constructor(docs: DocsArgOrColSchemaType) {
+ this.type = docs.type;
+ this.description = docs.desc;
+ this.name = docs.name;
+ }
+}
+
+const ARG_OR_COL_SCHEMA = z.object({
+ name: z.string(),
+ type: z.string(),
+ desc: z.string(),
+});
+type DocsArgOrColSchemaType = z.infer<typeof ARG_OR_COL_SCHEMA>;
+
+const DATA_OBJECT_SCHEMA = z.object({
+ name: z.string(),
+ desc: z.string(),
+ summary_desc: z.string(),
+ type: z.string(),
+ cols: z.array(ARG_OR_COL_SCHEMA),
+});
+type DocsDataObjectSchemaType = z.infer<typeof DATA_OBJECT_SCHEMA>;
+
+const FUNCTION_SCHEMA = z.object({
+ name: z.string(),
+ desc: z.string(),
+ summary_desc: z.string(),
+ args: z.array(ARG_OR_COL_SCHEMA),
+ return_type: z.string(),
+ return_desc: z.string(),
+});
+type DocsFunctionSchemaType = z.infer<typeof FUNCTION_SCHEMA>;
+
+const TABLE_FUNCTION_SCHEMA = z.object({
+ name: z.string(),
+ desc: z.string(),
+ summary_desc: z.string(),
+ args: z.array(ARG_OR_COL_SCHEMA),
+ cols: z.array(ARG_OR_COL_SCHEMA),
+});
+type DocsTableFunctionSchemaType = z.infer<typeof TABLE_FUNCTION_SCHEMA>;
+
+const MACRO_SCHEMA = z.object({
+ name: z.string(),
+ desc: z.string(),
+ summary_desc: z.string(),
+ return_desc: z.string(),
+ return_type: z.string(),
+ args: z.array(ARG_OR_COL_SCHEMA),
+});
+type DocsMacroSchemaType = z.infer<typeof MACRO_SCHEMA>;
+
+const MODULE_SCHEMA = z.object({
+ module_name: z.string(),
+ data_objects: z.array(DATA_OBJECT_SCHEMA),
+ functions: z.array(FUNCTION_SCHEMA),
+ table_functions: z.array(TABLE_FUNCTION_SCHEMA),
+ macros: z.array(MACRO_SCHEMA),
+});
+type DocsModuleSchemaType = z.infer<typeof MODULE_SCHEMA>;
+
+const PACKAGE_SCHEMA = z.object({
+ name: z.string(),
+ modules: z.array(MODULE_SCHEMA),
+});
+type DocsPackageSchemaType = z.infer<typeof PACKAGE_SCHEMA>;
+
+export const SQL_MODULES_DOCS_SCHEMA = z.array(PACKAGE_SCHEMA);
+export type SqlModulesDocsSchema = z.infer<typeof SQL_MODULES_DOCS_SCHEMA>;
diff --git a/ui/src/plugins/dev.perfetto.ThreadState/index.ts b/ui/src/plugins/dev.perfetto.ThreadState/index.ts
index a106654..155b35f 100644
--- a/ui/src/plugins/dev.perfetto.ThreadState/index.ts
+++ b/ui/src/plugins/dev.perfetto.ThreadState/index.ts
@@ -84,13 +84,7 @@
chips: removeFalsyValues([
isKernelThread === 0 && isMainThread === 1 && 'main thread',
]),
- track: new ThreadStateTrack(
- {
- trace: ctx,
- uri,
- },
- utid,
- ),
+ track: new ThreadStateTrack(ctx, uri, utid),
});
const group = getOrCreateGroupForThread(ctx.workspace, utid);
diff --git a/ui/src/plugins/dev.perfetto.ThreadState/thread_state_track.ts b/ui/src/plugins/dev.perfetto.ThreadState/thread_state_track.ts
index 3935465..4fdb791 100644
--- a/ui/src/plugins/dev.perfetto.ThreadState/thread_state_track.ts
+++ b/ui/src/plugins/dev.perfetto.ThreadState/thread_state_track.ts
@@ -22,12 +22,12 @@
SLICE_LAYOUT_FLAT_DEFAULTS,
SliceLayout,
} from '../../frontend/slice_layout';
-import {NewTrackArgs} from '../../frontend/track';
import {NUM_NULL, STR} from '../../trace_processor/query_result';
import {Slice} from '../../public/track';
import {translateState} from '../../trace_processor/sql_utils/thread_state';
import {TrackEventDetails, TrackEventSelection} from '../../public/selection';
import {ThreadStateDetailsPanel} from './thread_state_details_panel';
+import {Trace} from '../../public/trace';
export const THREAD_STATE_ROW = {
...BASE_ROW,
@@ -41,10 +41,11 @@
protected sliceLayout: SliceLayout = {...SLICE_LAYOUT_FLAT_DEFAULTS};
constructor(
- args: NewTrackArgs,
+ trace: Trace,
+ uri: string,
private utid: number,
) {
- super(args);
+ super(trace, uri);
}
// This is used by the base class to call iter().
diff --git a/ui/src/plugins/org.chromium.ChromeCriticalUserInteractions/index.ts b/ui/src/plugins/org.chromium.ChromeCriticalUserInteractions/index.ts
index 6b96209..a2b7981 100644
--- a/ui/src/plugins/org.chromium.ChromeCriticalUserInteractions/index.ts
+++ b/ui/src/plugins/org.chromium.ChromeCriticalUserInteractions/index.ts
@@ -39,10 +39,10 @@
kind: CriticalUserInteractionTrack.kind,
},
title: 'Chrome Interactions',
- track: new CriticalUserInteractionTrack({
- trace: ctx,
- uri: CriticalUserInteractionTrack.kind,
- }),
+ track: new CriticalUserInteractionTrack(
+ ctx,
+ CriticalUserInteractionTrack.kind,
+ ),
});
}
}
diff --git a/ui/src/plugins/org.chromium.ChromeTasks/track.ts b/ui/src/plugins/org.chromium.ChromeTasks/track.ts
index ff2f361..030af9e 100644
--- a/ui/src/plugins/org.chromium.ChromeTasks/track.ts
+++ b/ui/src/plugins/org.chromium.ChromeTasks/track.ts
@@ -25,9 +25,9 @@
constructor(
trace: Trace,
uri: string,
- private utid: Utid,
+ private readonly utid: Utid,
) {
- super({trace, uri});
+ super(trace, uri);
}
getSqlDataSource(): CustomSqlTableDefConfig {
diff --git a/ui/src/plugins/org.kernel.LinuxKernelSubsystems/index.ts b/ui/src/plugins/org.kernel.LinuxKernelSubsystems/index.ts
index 0bca424..8d7ff66 100644
--- a/ui/src/plugins/org.kernel.LinuxKernelSubsystems/index.ts
+++ b/ui/src/plugins/org.kernel.LinuxKernelSubsystems/index.ts
@@ -66,14 +66,7 @@
ctx.tracks.registerTrack({
uri,
title,
- track: new AsyncSliceTrack(
- {
- trace: ctx,
- uri,
- },
- 0,
- [trackId],
- ),
+ track: new AsyncSliceTrack(ctx, uri, 0, [trackId]),
tags: {
kind: SLICE_TRACK_KIND,
trackIds: [trackId],
diff --git a/ui/src/plugins/org.kernel.SuspendResumeLatency/index.ts b/ui/src/plugins/org.kernel.SuspendResumeLatency/index.ts
index 96b0ddb..973af15 100644
--- a/ui/src/plugins/org.kernel.SuspendResumeLatency/index.ts
+++ b/ui/src/plugins/org.kernel.SuspendResumeLatency/index.ts
@@ -14,7 +14,6 @@
import {NUM, STR_NULL} from '../../trace_processor/query_result';
import {AsyncSliceTrack} from '../dev.perfetto.AsyncSlices/async_slice_track';
-import {NewTrackArgs} from '../../frontend/track';
import {PerfettoPlugin} from '../../public/plugin';
import {Trace} from '../../public/trace';
import {TrackNode} from '../../public/workspace';
@@ -31,12 +30,13 @@
// TODO(stevegolton): Remove this?
class SuspendResumeSliceTrack extends AsyncSliceTrack {
constructor(
- args: NewTrackArgs,
+ trace: Trace,
+ uri: string,
maxDepth: number,
trackIds: number[],
private readonly threads: ThreadMap,
) {
- super(args, maxDepth, trackIds);
+ super(trace, uri, maxDepth, trackIds);
}
onSliceClick(args: OnSliceClickArgs<Slice>) {
@@ -96,12 +96,7 @@
trackIds,
kind: SLICE_TRACK_KIND,
},
- track: new SuspendResumeSliceTrack(
- {uri, trace: ctx},
- maxDepth,
- trackIds,
- threads,
- ),
+ track: new SuspendResumeSliceTrack(ctx, uri, maxDepth, trackIds, threads),
});
// Display the track in the UI.
diff --git a/ui/src/plugins/org.kernel.Wattson/index.ts b/ui/src/plugins/org.kernel.Wattson/index.ts
index 539366d..ebbe946 100644
--- a/ui/src/plugins/org.kernel.Wattson/index.ts
+++ b/ui/src/plugins/org.kernel.Wattson/index.ts
@@ -94,10 +94,7 @@
readonly queryKey: string;
constructor(trace: Trace, uri: string, queryKey: string) {
- super({
- trace,
- uri,
- });
+ super(trace, uri);
this.queryKey = queryKey;
}
diff --git a/ui/src/public/lib/stdlib_docs.ts b/ui/src/public/lib/stdlib_docs.ts
deleted file mode 100644
index fcdcf18..0000000
--- a/ui/src/public/lib/stdlib_docs.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (C) 2024 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-import {assetSrc} from '../../base/assets';
-
-// Fetch the stdlib docs
-export async function getStdlibDocs(): Promise<string> {
- const resp = await fetch(assetSrc('stdlib_docs.json'));
- const json = await resp.json();
- return JSON.parse(json);
-}
diff --git a/ui/src/public/lib/tracks/query_counter_track.ts b/ui/src/public/lib/tracks/query_counter_track.ts
index dc25d69..e412f7c 100644
--- a/ui/src/public/lib/tracks/query_counter_track.ts
+++ b/ui/src/public/lib/tracks/query_counter_track.ts
@@ -109,11 +109,7 @@
private readonly sqlTableName: string,
options?: Partial<CounterOptions>,
) {
- super({
- trace,
- uri,
- options,
- });
+ super(trace, uri, options);
}
getSqlSource(): string {
diff --git a/ui/src/public/lib/tracks/query_slice_track.ts b/ui/src/public/lib/tracks/query_slice_track.ts
index f7455a9..c8065fb 100644
--- a/ui/src/public/lib/tracks/query_slice_track.ts
+++ b/ui/src/public/lib/tracks/query_slice_track.ts
@@ -137,10 +137,7 @@
uri: string,
private readonly sqlTableName: string,
) {
- super({
- trace,
- uri,
- });
+ super(trace, uri);
}
override async getSqlDataSource(): Promise<CustomSqlTableDefConfig> {
diff --git a/ui/src/public/lib/tracks/slice_layout.ts b/ui/src/public/lib/tracks/slice_layout.ts
new file mode 100644
index 0000000..d328d1c
--- /dev/null
+++ b/ui/src/public/lib/tracks/slice_layout.ts
@@ -0,0 +1,81 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+export interface SliceLayoutBase {
+ readonly padding: number; // vertical pixel padding between slices and track.
+ readonly rowSpacing: number; // Spacing between rows.
+
+ // A *guess* at the depth
+ readonly depthGuess?: number;
+
+ // True iff the track is flat (all slices have the same depth
+ // we have an optimisation for this).
+ readonly isFlat?: boolean;
+
+ readonly titleSizePx?: number;
+ readonly subtitleSizePx?: number;
+}
+
+export const SLICE_LAYOUT_BASE_DEFAULTS: SliceLayoutBase = Object.freeze({
+ padding: 3,
+ rowSpacing: 0,
+});
+
+export interface SliceLayoutFixed extends SliceLayoutBase {
+ readonly heightMode: 'FIXED';
+ readonly fixedHeight: number; // Outer height of the track.
+}
+
+export const SLICE_LAYOUT_FIXED_DEFAULTS: SliceLayoutFixed = Object.freeze({
+ ...SLICE_LAYOUT_BASE_DEFAULTS,
+ heightMode: 'FIXED',
+ fixedHeight: 30,
+});
+
+export interface SliceLayoutFitContent extends SliceLayoutBase {
+ readonly heightMode: 'FIT_CONTENT';
+ readonly sliceHeight: number; // Only when heightMode = 'FIT_CONTENT'.
+}
+
+export const SLICE_LAYOUT_FIT_CONTENT_DEFAULTS: SliceLayoutFitContent =
+ Object.freeze({
+ ...SLICE_LAYOUT_BASE_DEFAULTS,
+ heightMode: 'FIT_CONTENT',
+ sliceHeight: 18,
+ });
+
+export interface SliceLayoutFlat extends SliceLayoutBase {
+ readonly heightMode: 'FIXED';
+ readonly fixedHeight: number; // Outer height of the track.
+ readonly depthGuess: 0;
+ readonly isFlat: true;
+}
+
+export const SLICE_LAYOUT_FLAT_DEFAULTS: SliceLayoutFlat = Object.freeze({
+ ...SLICE_LAYOUT_BASE_DEFAULTS,
+ depthGuess: 0,
+ isFlat: true,
+ heightMode: 'FIXED',
+ fixedHeight: 18,
+ titleSizePx: 10,
+ padding: 3,
+});
+
+export type SliceLayout =
+ | SliceLayoutFixed
+ | SliceLayoutFitContent
+ | SliceLayoutFlat;
+
+export const DEFAULT_SLICE_LAYOUT: SliceLayout =
+ SLICE_LAYOUT_FIT_CONTENT_DEFAULTS;