xref: /aosp_15_r20/external/perfetto/ui/src/public/selection.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2024 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 {time, duration, TimeSpan} from '../base/time';
16*6dbdd20aSAndroid Build Coastguard Workerimport {Engine} from '../trace_processor/engine';
17*6dbdd20aSAndroid Build Coastguard Workerimport {ColumnDef, Sorting, ThreadStateExtra} from './aggregation';
18*6dbdd20aSAndroid Build Coastguard Workerimport {TrackDescriptor} from './track';
19*6dbdd20aSAndroid Build Coastguard Worker
20*6dbdd20aSAndroid Build Coastguard Workerexport interface SelectionManager {
21*6dbdd20aSAndroid Build Coastguard Worker  readonly selection: Selection;
22*6dbdd20aSAndroid Build Coastguard Worker
23*6dbdd20aSAndroid Build Coastguard Worker  findTimeRangeOfSelection(): TimeSpan | undefined;
24*6dbdd20aSAndroid Build Coastguard Worker  clear(): void;
25*6dbdd20aSAndroid Build Coastguard Worker
26*6dbdd20aSAndroid Build Coastguard Worker  /**
27*6dbdd20aSAndroid Build Coastguard Worker   * Select a track event.
28*6dbdd20aSAndroid Build Coastguard Worker   *
29*6dbdd20aSAndroid Build Coastguard Worker   * @param trackUri - The URI of the track to select.
30*6dbdd20aSAndroid Build Coastguard Worker   * @param eventId - The value of the events ID column.
31*6dbdd20aSAndroid Build Coastguard Worker   * @param opts - Additional options.
32*6dbdd20aSAndroid Build Coastguard Worker   */
33*6dbdd20aSAndroid Build Coastguard Worker  selectTrackEvent(
34*6dbdd20aSAndroid Build Coastguard Worker    trackUri: string,
35*6dbdd20aSAndroid Build Coastguard Worker    eventId: number,
36*6dbdd20aSAndroid Build Coastguard Worker    opts?: SelectionOpts,
37*6dbdd20aSAndroid Build Coastguard Worker  ): void;
38*6dbdd20aSAndroid Build Coastguard Worker
39*6dbdd20aSAndroid Build Coastguard Worker  /**
40*6dbdd20aSAndroid Build Coastguard Worker   * Select a track.
41*6dbdd20aSAndroid Build Coastguard Worker   *
42*6dbdd20aSAndroid Build Coastguard Worker   * @param trackUri - The URI for the track to select.
43*6dbdd20aSAndroid Build Coastguard Worker   * @param opts - Additional options.
44*6dbdd20aSAndroid Build Coastguard Worker   */
45*6dbdd20aSAndroid Build Coastguard Worker  selectTrack(trackUri: string, opts?: SelectionOpts): void;
46*6dbdd20aSAndroid Build Coastguard Worker
47*6dbdd20aSAndroid Build Coastguard Worker  /**
48*6dbdd20aSAndroid Build Coastguard Worker   * Select a track event via a sql table name + id.
49*6dbdd20aSAndroid Build Coastguard Worker   *
50*6dbdd20aSAndroid Build Coastguard Worker   * @param sqlTableName - The name of the SQL table to resolve.
51*6dbdd20aSAndroid Build Coastguard Worker   * @param id - The ID of the event in that table.
52*6dbdd20aSAndroid Build Coastguard Worker   * @param opts - Additional options.
53*6dbdd20aSAndroid Build Coastguard Worker   */
54*6dbdd20aSAndroid Build Coastguard Worker  selectSqlEvent(sqlTableName: string, id: number, opts?: SelectionOpts): void;
55*6dbdd20aSAndroid Build Coastguard Worker
56*6dbdd20aSAndroid Build Coastguard Worker  /**
57*6dbdd20aSAndroid Build Coastguard Worker   * Create an area selection for the purposes of aggregation.
58*6dbdd20aSAndroid Build Coastguard Worker   *
59*6dbdd20aSAndroid Build Coastguard Worker   * @param args - The area to select.
60*6dbdd20aSAndroid Build Coastguard Worker   * @param opts - Additional options.
61*6dbdd20aSAndroid Build Coastguard Worker   */
62*6dbdd20aSAndroid Build Coastguard Worker  selectArea(args: Area, opts?: SelectionOpts): void;
63*6dbdd20aSAndroid Build Coastguard Worker
64*6dbdd20aSAndroid Build Coastguard Worker  scrollToCurrentSelection(): void;
65*6dbdd20aSAndroid Build Coastguard Worker  registerAreaSelectionAggregator(aggr: AreaSelectionAggregator): void;
66*6dbdd20aSAndroid Build Coastguard Worker
67*6dbdd20aSAndroid Build Coastguard Worker  /**
68*6dbdd20aSAndroid Build Coastguard Worker   * Register a new SQL selection resolver.
69*6dbdd20aSAndroid Build Coastguard Worker   *
70*6dbdd20aSAndroid Build Coastguard Worker   * A resolver consists of a SQL table name and a callback. When someone
71*6dbdd20aSAndroid Build Coastguard Worker   * expresses an interest in selecting a slice on a matching table, the
72*6dbdd20aSAndroid Build Coastguard Worker   * callback is called which can return a selection object or undefined.
73*6dbdd20aSAndroid Build Coastguard Worker   */
74*6dbdd20aSAndroid Build Coastguard Worker  registerSqlSelectionResolver(resolver: SqlSelectionResolver): void;
75*6dbdd20aSAndroid Build Coastguard Worker}
76*6dbdd20aSAndroid Build Coastguard Worker
77*6dbdd20aSAndroid Build Coastguard Workerexport interface AreaSelectionAggregator {
78*6dbdd20aSAndroid Build Coastguard Worker  readonly id: string;
79*6dbdd20aSAndroid Build Coastguard Worker  createAggregateView(engine: Engine, area: AreaSelection): Promise<boolean>;
80*6dbdd20aSAndroid Build Coastguard Worker  getExtra(
81*6dbdd20aSAndroid Build Coastguard Worker    engine: Engine,
82*6dbdd20aSAndroid Build Coastguard Worker    area: AreaSelection,
83*6dbdd20aSAndroid Build Coastguard Worker  ): Promise<ThreadStateExtra | void>;
84*6dbdd20aSAndroid Build Coastguard Worker  getTabName(): string;
85*6dbdd20aSAndroid Build Coastguard Worker  getDefaultSorting(): Sorting;
86*6dbdd20aSAndroid Build Coastguard Worker  getColumnDefinitions(): ColumnDef[];
87*6dbdd20aSAndroid Build Coastguard Worker}
88*6dbdd20aSAndroid Build Coastguard Worker
89*6dbdd20aSAndroid Build Coastguard Workerexport type Selection =
90*6dbdd20aSAndroid Build Coastguard Worker  | TrackEventSelection
91*6dbdd20aSAndroid Build Coastguard Worker  | TrackSelection
92*6dbdd20aSAndroid Build Coastguard Worker  | AreaSelection
93*6dbdd20aSAndroid Build Coastguard Worker  | NoteSelection
94*6dbdd20aSAndroid Build Coastguard Worker  | EmptySelection;
95*6dbdd20aSAndroid Build Coastguard Worker
96*6dbdd20aSAndroid Build Coastguard Worker/** Defines how changes to selection affect the rest of the UI state */
97*6dbdd20aSAndroid Build Coastguard Workerexport interface SelectionOpts {
98*6dbdd20aSAndroid Build Coastguard Worker  clearSearch?: boolean; // Default: true.
99*6dbdd20aSAndroid Build Coastguard Worker  switchToCurrentSelectionTab?: boolean; // Default: true.
100*6dbdd20aSAndroid Build Coastguard Worker  scrollToSelection?: boolean; // Default: false.
101*6dbdd20aSAndroid Build Coastguard Worker}
102*6dbdd20aSAndroid Build Coastguard Worker
103*6dbdd20aSAndroid Build Coastguard Workerexport interface TrackEventSelection extends TrackEventDetails {
104*6dbdd20aSAndroid Build Coastguard Worker  readonly kind: 'track_event';
105*6dbdd20aSAndroid Build Coastguard Worker  readonly trackUri: string;
106*6dbdd20aSAndroid Build Coastguard Worker  readonly eventId: number;
107*6dbdd20aSAndroid Build Coastguard Worker}
108*6dbdd20aSAndroid Build Coastguard Worker
109*6dbdd20aSAndroid Build Coastguard Workerexport interface TrackSelection {
110*6dbdd20aSAndroid Build Coastguard Worker  readonly kind: 'track';
111*6dbdd20aSAndroid Build Coastguard Worker  readonly trackUri: string;
112*6dbdd20aSAndroid Build Coastguard Worker}
113*6dbdd20aSAndroid Build Coastguard Worker
114*6dbdd20aSAndroid Build Coastguard Workerexport interface TrackEventDetails {
115*6dbdd20aSAndroid Build Coastguard Worker  // ts and dur are required by the core, and must be provided.
116*6dbdd20aSAndroid Build Coastguard Worker  readonly ts: time;
117*6dbdd20aSAndroid Build Coastguard Worker  // Note: dur can be -1 for instant events.
118*6dbdd20aSAndroid Build Coastguard Worker  readonly dur: duration;
119*6dbdd20aSAndroid Build Coastguard Worker
120*6dbdd20aSAndroid Build Coastguard Worker  // Optional additional information.
121*6dbdd20aSAndroid Build Coastguard Worker  // TODO(stevegolton): Find an elegant way of moving this information out of
122*6dbdd20aSAndroid Build Coastguard Worker  // the core.
123*6dbdd20aSAndroid Build Coastguard Worker  readonly wakeupTs?: time;
124*6dbdd20aSAndroid Build Coastguard Worker  readonly wakerCpu?: number;
125*6dbdd20aSAndroid Build Coastguard Worker  readonly upid?: number;
126*6dbdd20aSAndroid Build Coastguard Worker  readonly utid?: number;
127*6dbdd20aSAndroid Build Coastguard Worker  readonly tableName?: string;
128*6dbdd20aSAndroid Build Coastguard Worker  readonly profileType?: ProfileType;
129*6dbdd20aSAndroid Build Coastguard Worker  readonly interactionType?: string;
130*6dbdd20aSAndroid Build Coastguard Worker}
131*6dbdd20aSAndroid Build Coastguard Worker
132*6dbdd20aSAndroid Build Coastguard Workerexport interface Area {
133*6dbdd20aSAndroid Build Coastguard Worker  readonly start: time;
134*6dbdd20aSAndroid Build Coastguard Worker  readonly end: time;
135*6dbdd20aSAndroid Build Coastguard Worker  // TODO(primiano): this should be ReadonlyArray<> after the pivot table state
136*6dbdd20aSAndroid Build Coastguard Worker  // doesn't use State/Immer anymore.
137*6dbdd20aSAndroid Build Coastguard Worker  readonly trackUris: string[];
138*6dbdd20aSAndroid Build Coastguard Worker}
139*6dbdd20aSAndroid Build Coastguard Worker
140*6dbdd20aSAndroid Build Coastguard Workerexport interface AreaSelection extends Area {
141*6dbdd20aSAndroid Build Coastguard Worker  readonly kind: 'area';
142*6dbdd20aSAndroid Build Coastguard Worker
143*6dbdd20aSAndroid Build Coastguard Worker  // This array contains the resolved TrackDescriptor from Area.trackUris.
144*6dbdd20aSAndroid Build Coastguard Worker  // The resolution is done by SelectionManager whenever a kind='area' selection
145*6dbdd20aSAndroid Build Coastguard Worker  // is performed.
146*6dbdd20aSAndroid Build Coastguard Worker  readonly tracks: ReadonlyArray<TrackDescriptor>;
147*6dbdd20aSAndroid Build Coastguard Worker}
148*6dbdd20aSAndroid Build Coastguard Worker
149*6dbdd20aSAndroid Build Coastguard Workerexport interface NoteSelection {
150*6dbdd20aSAndroid Build Coastguard Worker  readonly kind: 'note';
151*6dbdd20aSAndroid Build Coastguard Worker  readonly id: string;
152*6dbdd20aSAndroid Build Coastguard Worker}
153*6dbdd20aSAndroid Build Coastguard Worker
154*6dbdd20aSAndroid Build Coastguard Workerexport interface EmptySelection {
155*6dbdd20aSAndroid Build Coastguard Worker  readonly kind: 'empty';
156*6dbdd20aSAndroid Build Coastguard Worker}
157*6dbdd20aSAndroid Build Coastguard Worker
158*6dbdd20aSAndroid Build Coastguard Workerexport enum ProfileType {
159*6dbdd20aSAndroid Build Coastguard Worker  HEAP_PROFILE = 'heap_profile',
160*6dbdd20aSAndroid Build Coastguard Worker  MIXED_HEAP_PROFILE = 'heap_profile:com.android.art,libc.malloc',
161*6dbdd20aSAndroid Build Coastguard Worker  NATIVE_HEAP_PROFILE = 'heap_profile:libc.malloc',
162*6dbdd20aSAndroid Build Coastguard Worker  JAVA_HEAP_SAMPLES = 'heap_profile:com.android.art',
163*6dbdd20aSAndroid Build Coastguard Worker  JAVA_HEAP_GRAPH = 'graph',
164*6dbdd20aSAndroid Build Coastguard Worker  PERF_SAMPLE = 'perf',
165*6dbdd20aSAndroid Build Coastguard Worker}
166*6dbdd20aSAndroid Build Coastguard Worker
167*6dbdd20aSAndroid Build Coastguard Workerexport function profileType(s: string): ProfileType {
168*6dbdd20aSAndroid Build Coastguard Worker  if (s === 'heap_profile:libc.malloc,com.android.art') {
169*6dbdd20aSAndroid Build Coastguard Worker    s = 'heap_profile:com.android.art,libc.malloc';
170*6dbdd20aSAndroid Build Coastguard Worker  }
171*6dbdd20aSAndroid Build Coastguard Worker  if (Object.values(ProfileType).includes(s as ProfileType)) {
172*6dbdd20aSAndroid Build Coastguard Worker    return s as ProfileType;
173*6dbdd20aSAndroid Build Coastguard Worker  }
174*6dbdd20aSAndroid Build Coastguard Worker  if (s.startsWith('heap_profile')) {
175*6dbdd20aSAndroid Build Coastguard Worker    return ProfileType.HEAP_PROFILE;
176*6dbdd20aSAndroid Build Coastguard Worker  }
177*6dbdd20aSAndroid Build Coastguard Worker  throw new Error('Unknown type ${s}');
178*6dbdd20aSAndroid Build Coastguard Worker}
179*6dbdd20aSAndroid Build Coastguard Worker
180*6dbdd20aSAndroid Build Coastguard Workerexport interface SqlSelectionResolver {
181*6dbdd20aSAndroid Build Coastguard Worker  readonly sqlTableName: string;
182*6dbdd20aSAndroid Build Coastguard Worker  readonly callback: (
183*6dbdd20aSAndroid Build Coastguard Worker    id: number,
184*6dbdd20aSAndroid Build Coastguard Worker    sqlTable: string,
185*6dbdd20aSAndroid Build Coastguard Worker  ) => Promise<{trackUri: string; eventId: number} | undefined>;
186*6dbdd20aSAndroid Build Coastguard Worker}
187