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