1// Copyright (C) 2018 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 {RecordConfig} from '../controller/record_config_types'; 16import { 17 Aggregation, 18 PivotTree, 19 TableColumn, 20} from '../frontend/pivot_table_types'; 21import {TopLevelScrollSelection} from '../tracks/scroll_jank/scroll_track'; 22 23import {Direction} from './event_set'; 24import {TPDuration, TPTime} from './time'; 25 26/** 27 * A plain js object, holding objects of type |Class| keyed by string id. 28 * We use this instead of using |Map| object since it is simpler and faster to 29 * serialize for use in postMessage. 30 */ 31export interface ObjectById<Class extends{id: string}> { [id: string]: Class; } 32 33export interface Timestamped { 34 lastUpdate: number; 35} 36 37export type OmniboxMode = 'SEARCH'|'COMMAND'; 38 39export interface OmniboxState { 40 omnibox: string; 41 mode: OmniboxMode; 42} 43 44export interface VisibleState extends Timestamped { 45 start: TPTime; 46 end: TPTime; 47 resolution: TPDuration; 48} 49 50export interface AreaSelection { 51 kind: 'AREA'; 52 areaId: string; 53 // When an area is marked it will be assigned a unique note id and saved as 54 // an AreaNote for the user to return to later. id = 0 is the special id that 55 // is overwritten when a new area is marked. Any other id is a persistent 56 // marking that will not be overwritten. 57 // When not set, the area selection will be replaced with any 58 // new area selection (i.e. not saved anywhere). 59 noteId?: string; 60} 61 62export type AreaById = Area&{id: string}; 63 64export interface Area { 65 start: TPTime; 66 end: TPTime; 67 tracks: string[]; 68} 69 70export const MAX_TIME = 180; 71 72// 3: TrackKindPriority and related sorting changes. 73// 5: Move a large number of items off frontendLocalState and onto state. 74// 6: Common PivotTableConfig and pivot table specific PivotTableState. 75// 7: Split Chrome categories in two and add 'symbolize ksyms' flag. 76// 8: Rename several variables 77// "[...]HeapProfileFlamegraph[...]" -> "[...]Flamegraph[...]". 78// 9: Add a field to track last loaded recording profile name 79// 10: Change last loaded profile tracking type to accommodate auto-save. 80// 11: Rename updateChromeCategories to fetchChromeCategories. 81// 12: Add a field to cache mapping from UI track ID to trace track ID in order 82// to speed up flow arrows rendering. 83// 13: FlamegraphState changed to support area selection. 84// 14: Changed the type of uiTrackIdByTraceTrackId from `Map` to an object with 85// typed key/value because a `Map` does not preserve type during 86// serialisation+deserialisation. 87// 15: Added state for Pivot Table V2 88// 16: Added boolean tracking if the flamegraph modal was dismissed 89// 17: 90// - add currentEngineId to track the id of the current engine 91// - remove nextNoteId, nextAreaId and use nextId as a unique counter for all 92// indexing except the indexing of the engines 93// 18: areaSelection change see b/235869542 94// 19: Added visualisedArgs state. 95// 20: Refactored thread sorting order. 96// 21: Updated perf sample selection to include a ts range instead of single ts 97// 22: Add log selection kind. 98// 23: Add log filtering criteria for Android log entries. 99// 24: Store only a single Engine. 100// 25: Move omnibox state off VisibleState. 101// 26: Add tags for filtering Android log entries. 102// 27. Add a text entry for filtering Android log entries. 103// 28. Add a boolean indicating if non matching log entries are hidden. 104// 29. Add ftrace state. <-- Borked, state contains a non-serializable object. 105// 30. Convert ftraceFilter.excludedNames from Set<string> to string[]. 106// 31. Convert all timestamps to bigints. 107export const STATE_VERSION = 31; 108 109export const SCROLLING_TRACK_GROUP = 'ScrollingTracks'; 110 111export type EngineMode = 'WASM'|'HTTP_RPC'; 112 113export type NewEngineMode = 'USE_HTTP_RPC_IF_AVAILABLE'|'FORCE_BUILTIN_WASM'; 114 115// Tracks within track groups (usually corresponding to processes) are sorted. 116// As we want to group all tracks related to a given thread together, we use 117// two keys: 118// - Primary key corresponds to a priority of a track block (all tracks related 119// to a given thread or a single track if it's not thread-associated). 120// - Secondary key corresponds to a priority of a given thread-associated track 121// within its thread track block. 122// Each track will have a sort key, which either a primary sort key 123// (for non-thread tracks) or a tid and secondary sort key (mapping of tid to 124// primary sort key is done independently). 125export enum PrimaryTrackSortKey { 126 DEBUG_SLICE_TRACK, 127 NULL_TRACK, 128 PROCESS_SCHEDULING_TRACK, 129 PROCESS_SUMMARY_TRACK, 130 EXPECTED_FRAMES_SLICE_TRACK, 131 ACTUAL_FRAMES_SLICE_TRACK, 132 PERF_SAMPLES_PROFILE_TRACK, 133 HEAP_PROFILE_TRACK, 134 MAIN_THREAD, 135 RENDER_THREAD, 136 GPU_COMPLETION_THREAD, 137 CHROME_IO_THREAD, 138 CHROME_COMPOSITOR_THREAD, 139 ORDINARY_THREAD, 140 COUNTER_TRACK, 141 ASYNC_SLICE_TRACK, 142 ORDINARY_TRACK, 143} 144 145// Key that is used to sort tracks within a block of tracks associated with a 146// given thread. 147export enum InThreadTrackSortKey { 148 THREAD_COUNTER_TRACK, 149 THREAD_SCHEDULING_STATE_TRACK, 150 CPU_STACK_SAMPLES_TRACK, 151 VISUALISED_ARGS_TRACK, 152 ORDINARY, 153 DEFAULT_TRACK, 154} 155 156// Sort key used for sorting tracks associated with a thread. 157export type ThreadTrackSortKey = { 158 utid: number, 159 priority: InThreadTrackSortKey, 160} 161 162// Sort key for all tracks: both thread-associated and non-thread associated. 163export type TrackSortKey = PrimaryTrackSortKey|ThreadTrackSortKey; 164 165// Mapping which defines order for threads within a given process. 166export type UtidToTrackSortKey = { 167 [utid: number]: { 168 tid?: number, sortKey: PrimaryTrackSortKey, 169 } 170} 171 172export enum ProfileType { 173 HEAP_PROFILE = 'heap_profile', 174 NATIVE_HEAP_PROFILE = 'heap_profile:libc.malloc', 175 JAVA_HEAP_SAMPLES = 'heap_profile:com.android.art', 176 JAVA_HEAP_GRAPH = 'graph', 177 PERF_SAMPLE = 'perf', 178} 179 180export type FlamegraphStateViewingOption = 181 'SPACE'|'ALLOC_SPACE'|'OBJECTS'|'ALLOC_OBJECTS'|'PERF_SAMPLES'; 182 183export interface CallsiteInfo { 184 id: number; 185 parentId: number; 186 depth: number; 187 name?: string; 188 totalSize: number; 189 selfSize: number; 190 mapping: string; 191 merged: boolean; 192 highlighted: boolean; 193 location?: string; 194} 195 196export interface TraceFileSource { 197 type: 'FILE'; 198 file: File; 199} 200 201export interface TraceArrayBufferSource { 202 type: 'ARRAY_BUFFER'; 203 buffer: ArrayBuffer; 204 title: string; 205 url?: string; 206 fileName?: string; 207 208 // |uuid| is set only when loading via ?local_cache_key=1234. When set, 209 // this matches global.state.traceUuid, with the exception of the following 210 // time window: When a trace T1 is loaded and the user loads another trace T2, 211 // this |uuid| will be == T2, but the globals.state.traceUuid will be 212 // temporarily == T1 until T2 has been loaded (consistently to what happens 213 // with all other state fields). 214 uuid?: string; 215 // if |localOnly| is true then the trace should not be shared or downloaded. 216 localOnly?: boolean; 217} 218 219export interface TraceUrlSource { 220 type: 'URL'; 221 url: string; 222} 223 224export interface TraceHttpRpcSource { 225 type: 'HTTP_RPC'; 226} 227 228export type TraceSource = 229 TraceFileSource|TraceArrayBufferSource|TraceUrlSource|TraceHttpRpcSource; 230 231export interface TrackState { 232 id: string; 233 engineId: string; 234 kind: string; 235 name: string; 236 labels?: string[]; 237 trackSortKey: TrackSortKey; 238 trackGroup?: string; 239 config: { 240 trackId?: number; 241 trackIds?: number[]; 242 }; 243} 244 245export interface TrackGroupState { 246 id: string; 247 engineId: string; 248 name: string; 249 collapsed: boolean; 250 tracks: string[]; // Child track ids. 251} 252 253export interface EngineConfig { 254 id: string; 255 mode?: EngineMode; // Is undefined until |ready| is true. 256 ready: boolean; 257 failed?: string; // If defined the engine has crashed with the given message. 258 source: TraceSource; 259} 260 261export interface QueryConfig { 262 id: string; 263 engineId?: string; 264 query: string; 265} 266 267export interface PermalinkConfig { 268 requestId?: string; // Set by the frontend to request a new permalink. 269 hash?: string; // Set by the controller when the link has been created. 270 isRecordingConfig?: 271 boolean; // this permalink request is for a recording config only 272} 273 274export interface TraceTime { 275 start: TPTime; 276 end: TPTime; 277} 278 279export interface FrontendLocalState { 280 visibleState: VisibleState; 281} 282 283export interface Status { 284 msg: string; 285 timestamp: number; // Epoch in seconds (Date.now() / 1000). 286} 287 288export interface Note { 289 noteType: 'DEFAULT'; 290 id: string; 291 timestamp: TPTime; 292 color: string; 293 text: string; 294} 295 296export interface AreaNote { 297 noteType: 'AREA'; 298 id: string; 299 areaId: string; 300 color: string; 301 text: string; 302} 303 304export interface NoteSelection { 305 kind: 'NOTE'; 306 id: string; 307} 308 309export interface SliceSelection { 310 kind: 'SLICE'; 311 id: number; 312} 313 314export interface DebugSliceSelection { 315 kind: 'DEBUG_SLICE'; 316 id: number; 317 sqlTableName: string; 318 start: TPTime; 319 duration: TPDuration; 320} 321 322export interface CounterSelection { 323 kind: 'COUNTER'; 324 leftTs: TPTime; 325 rightTs: TPTime; 326 id: number; 327} 328 329export interface HeapProfileSelection { 330 kind: 'HEAP_PROFILE'; 331 id: number; 332 upid: number; 333 ts: TPTime; 334 type: ProfileType; 335} 336 337export interface PerfSamplesSelection { 338 kind: 'PERF_SAMPLES'; 339 id: number; 340 upid: number; 341 leftTs: TPTime; 342 rightTs: TPTime; 343 type: ProfileType; 344} 345 346export interface FlamegraphState { 347 kind: 'FLAMEGRAPH_STATE'; 348 upids: number[]; 349 start: TPTime; 350 end: TPTime; 351 type: ProfileType; 352 viewingOption: FlamegraphStateViewingOption; 353 focusRegex: string; 354 expandedCallsite?: CallsiteInfo; 355} 356 357export interface CpuProfileSampleSelection { 358 kind: 'CPU_PROFILE_SAMPLE'; 359 id: number; 360 utid: number; 361 ts: number; 362} 363 364export interface ChromeSliceSelection { 365 kind: 'CHROME_SLICE'; 366 id: number; 367 table: string; 368} 369 370export interface ThreadStateSelection { 371 kind: 'THREAD_STATE'; 372 id: number; 373} 374 375export interface LogSelection { 376 kind: 'LOG'; 377 id: number; 378 trackId: string; 379} 380 381export type Selection = 382 (NoteSelection|SliceSelection|CounterSelection|HeapProfileSelection| 383 CpuProfileSampleSelection|ChromeSliceSelection|ThreadStateSelection| 384 AreaSelection|PerfSamplesSelection|LogSelection|DebugSliceSelection| 385 TopLevelScrollSelection)&{trackId?: string}; 386export type SelectionKind = Selection['kind']; // 'THREAD_STATE' | 'SLICE' ... 387 388export interface Pagination { 389 offset: number; 390 count: number; 391} 392 393export type StringListPatch = ['add' | 'remove', string]; 394 395export interface FtraceFilterPatch { 396 excludedNames: StringListPatch[]; 397} 398 399export interface RecordingTarget { 400 name: string; 401 os: TargetOs; 402} 403 404export interface AdbRecordingTarget extends RecordingTarget { 405 serial: string; 406} 407 408export interface Sorting { 409 column: string; 410 direction: 'DESC'|'ASC'; 411} 412 413export interface AggregationState { 414 id: string; 415 sorting?: Sorting; 416} 417 418export interface MetricsState { 419 availableMetrics?: string[]; // Undefined until list is loaded. 420 selectedIndex?: number; 421 requestedMetric?: string; // Unset after metric request is handled. 422} 423 424// Auxiliary metadata needed to parse the query result, as well as to render it 425// correctly. Generated together with the text of query and passed without the 426// change to the query response. 427export interface PivotTableQueryMetadata { 428 pivotColumns: TableColumn[]; 429 aggregationColumns: Aggregation[]; 430 countIndex: number; 431} 432 433// Everything that's necessary to run the query for pivot table 434export interface PivotTableQuery { 435 text: string; 436 metadata: PivotTableQueryMetadata; 437} 438 439// Pivot table query result 440export interface PivotTableResult { 441 // Hierarchical pivot structure on top of rows 442 tree: PivotTree; 443 // Copy of the query metadata from the request, bundled up with the query 444 // result to ensure the correct rendering. 445 metadata: PivotTableQueryMetadata; 446} 447 448// Input parameters to check whether the pivot table needs to be re-queried. 449export interface PivotTableAreaState { 450 areaId: string; 451 tracks: string[]; 452} 453 454export type SortDirection = keyof typeof Direction; 455 456export interface PivotTableState { 457 // Currently selected area, if null, pivot table is not going to be visible. 458 selectionArea?: PivotTableAreaState; 459 460 // Query response 461 queryResult: PivotTableResult|null; 462 463 // Selected pivots for tables other than slice. 464 // Because of the query generation, pivoting happens first on non-slice 465 // pivots; therefore, those can't be put after slice pivots. In order to 466 // maintain the separation more clearly, slice and non-slice pivots are 467 // located in separate arrays. 468 selectedPivots: TableColumn[]; 469 470 // Selected aggregation columns. Stored same way as pivots. 471 selectedAggregations: Aggregation[]; 472 473 // Whether the pivot table results should be constrained to the selected area. 474 constrainToArea: boolean; 475 476 // Set to true by frontend to request controller to perform the query to 477 // acquire the necessary data from the engine. 478 queryRequested: boolean; 479 480 // Argument names in the current trace, used for autocompletion purposes. 481 argumentNames: string[]; 482} 483 484export interface LoadedConfigNone { 485 type: 'NONE'; 486} 487 488export interface LoadedConfigAutomatic { 489 type: 'AUTOMATIC'; 490} 491 492export interface LoadedConfigNamed { 493 type: 'NAMED'; 494 name: string; 495} 496 497export type LoadedConfig = 498 LoadedConfigNone|LoadedConfigAutomatic|LoadedConfigNamed; 499 500export interface NonSerializableState { 501 pivotTable: PivotTableState; 502} 503 504export interface LogFilteringCriteria { 505 minimumLevel: number; 506 tags: string[]; 507 textEntry: string; 508 hideNonMatching: boolean; 509} 510 511export interface FtraceFilterState { 512 // We use an exclude list rather than include list for filtering events, as we 513 // want to include all events by default but we won't know what names are 514 // present initially. 515 excludedNames: string[]; 516} 517 518export interface State { 519 version: number; 520 nextId: string; 521 522 /** 523 * State of the ConfigEditor. 524 */ 525 recordConfig: RecordConfig; 526 displayConfigAsPbtxt: boolean; 527 lastLoadedConfig: LoadedConfig; 528 529 /** 530 * Open traces. 531 */ 532 newEngineMode: NewEngineMode; 533 engine?: EngineConfig; 534 traceTime: TraceTime; 535 traceUuid?: string; 536 trackGroups: ObjectById<TrackGroupState>; 537 tracks: ObjectById<TrackState>; 538 uiTrackIdByTraceTrackId: {[key: number]: string;}; 539 utidToThreadSortKey: UtidToTrackSortKey; 540 areas: ObjectById<AreaById>; 541 aggregatePreferences: ObjectById<AggregationState>; 542 visibleTracks: string[]; 543 scrollingTracks: string[]; 544 pinnedTracks: string[]; 545 debugTrackId?: string; 546 lastTrackReloadRequest?: number; 547 queries: ObjectById<QueryConfig>; 548 metrics: MetricsState; 549 permalink: PermalinkConfig; 550 notes: ObjectById<Note|AreaNote>; 551 status: Status; 552 currentSelection: Selection|null; 553 currentFlamegraphState: FlamegraphState|null; 554 logsPagination: Pagination; 555 ftracePagination: Pagination; 556 ftraceFilter: FtraceFilterState; 557 traceConversionInProgress: boolean; 558 visualisedArgs: string[]; 559 560 /** 561 * This state is updated on the frontend at 60Hz and eventually syncronised to 562 * the controller at 10Hz. When the controller sends state updates to the 563 * frontend the frontend has special logic to pick whichever version of this 564 * key is most up to date. 565 */ 566 frontendLocalState: FrontendLocalState; 567 568 // Show track perf debugging overlay 569 perfDebug: boolean; 570 571 // Show the sidebar extended 572 sidebarVisible: boolean; 573 574 // Hovered and focused events 575 hoveredUtid: number; 576 hoveredPid: number; 577 hoverCursorTimestamp: TPTime; 578 hoveredNoteTimestamp: TPTime; 579 highlightedSliceId: number; 580 focusedFlowIdLeft: number; 581 focusedFlowIdRight: number; 582 pendingScrollId?: number; 583 584 searchIndex: number; 585 currentTab?: string; 586 587 /** 588 * Trace recording 589 */ 590 recordingInProgress: boolean; 591 recordingCancelled: boolean; 592 extensionInstalled: boolean; 593 flamegraphModalDismissed: boolean; 594 recordingTarget: RecordingTarget; 595 availableAdbDevices: AdbRecordingTarget[]; 596 lastRecordingError?: string; 597 recordingStatus?: string; 598 599 fetchChromeCategories: boolean; 600 chromeCategories: string[]|undefined; 601 602 // Special key: this part of the state is not going to be serialized when 603 // using permalink. Can be used to store those parts of the state that can't 604 // be serialized at the moment, such as ES6 Set and Map. 605 nonSerializableState: NonSerializableState; 606 607 // Android logs filtering state. 608 logFilteringCriteria: LogFilteringCriteria; 609 610 // Omnibox info. 611 omniboxState: OmniboxState; 612} 613 614export const defaultTraceTime = { 615 start: 0n, 616 end: BigInt(10e9), 617}; 618 619export declare type RecordMode = 620 'STOP_WHEN_FULL' | 'RING_BUFFER' | 'LONG_TRACE'; 621 622// 'Q','P','O' for Android, 'L' for Linux, 'C' for Chrome. 623export declare type TargetOs = 'S' | 'R' | 'Q' | 'P' | 'O' | 'C' | 'L' | 'CrOS'; 624 625export function isAndroidP(target: RecordingTarget) { 626 return target.os === 'P'; 627} 628 629export function isAndroidTarget(target: RecordingTarget) { 630 return ['Q', 'P', 'O'].includes(target.os); 631} 632 633export function isChromeTarget(target: RecordingTarget) { 634 return ['C', 'CrOS'].includes(target.os); 635} 636 637export function isCrOSTarget(target: RecordingTarget) { 638 return target.os === 'CrOS'; 639} 640 641export function isLinuxTarget(target: RecordingTarget) { 642 return target.os === 'L'; 643} 644 645export function isAdbTarget(target: RecordingTarget): 646 target is AdbRecordingTarget { 647 return !!(target as AdbRecordingTarget).serial; 648} 649 650export function hasActiveProbes(config: RecordConfig) { 651 const fieldsWithEmptyResult = new Set<string>( 652 ['hpBlockClient', 'allAtraceApps', 'chromePrivacyFiltering']); 653 let key: keyof RecordConfig; 654 for (key in config) { 655 if (typeof (config[key]) === 'boolean' && config[key] === true && 656 !fieldsWithEmptyResult.has(key)) { 657 return true; 658 } 659 } 660 if (config.chromeCategoriesSelected.length > 0) { 661 return true; 662 } 663 return config.chromeHighOverheadCategoriesSelected.length > 0; 664} 665 666export function getDefaultRecordingTargets(): RecordingTarget[] { 667 return [ 668 {os: 'Q', name: 'Android Q+ / 10+'}, 669 {os: 'P', name: 'Android P / 9'}, 670 {os: 'O', name: 'Android O- / 8-'}, 671 {os: 'C', name: 'Chrome'}, 672 {os: 'CrOS', name: 'Chrome OS (system trace)'}, 673 {os: 'L', name: 'Linux desktop'}, 674 ]; 675} 676 677export function getBuiltinChromeCategoryList(): string[] { 678 // List of static Chrome categories, last updated at 2023-04-04 from HEAD of 679 // Chromium's //base/trace_event/builtin_categories.h. 680 return [ 681 'accessibility', 682 'AccountFetcherService', 683 'android_webview', 684 'aogh', 685 'audio', 686 'base', 687 'benchmark', 688 'blink', 689 'blink.animations', 690 'blink.bindings', 691 'blink.console', 692 'blink.net', 693 'blink.resource', 694 'blink.user_timing', 695 'blink.worker', 696 'blink_style', 697 'Blob', 698 'browser', 699 'browsing_data', 700 'CacheStorage', 701 'Calculators', 702 'CameraStream', 703 'cppgc', 704 'camera', 705 'cast_app', 706 'cast_perf_test', 707 'cast.mdns', 708 'cast.mdns.socket', 709 'cast.stream', 710 'cc', 711 'cc.debug', 712 'cdp.perf', 713 'chromeos', 714 'cma', 715 'compositor', 716 'content', 717 'content_capture', 718 'delegated_ink_trails', 719 'device', 720 'devtools', 721 'devtools.contrast', 722 'devtools.timeline', 723 'disk_cache', 724 'download', 725 'download_service', 726 'drm', 727 'drmcursor', 728 'dwrite', 729 'DXVA_Decoding', 730 'evdev', 731 'event', 732 'event_latency', 733 'exo', 734 'extensions', 735 'explore_sites', 736 'FileSystem', 737 'file_system_provider', 738 'fledge', 739 'fonts', 740 'GAMEPAD', 741 'gpu', 742 'gpu.angle', 743 'gpu.angle.texture_metrics', 744 'gpu.capture', 745 'headless', 746 'history', 747 'hwoverlays', 748 'identity', 749 'ime', 750 'IndexedDB', 751 'input', 752 'io', 753 'ipc', 754 'Java', 755 'jni', 756 'jpeg', 757 'latency', 758 'latencyInfo', 759 'leveldb', 760 'loading', 761 'log', 762 'login', 763 'media', 764 'media_router', 765 'memory', 766 'midi', 767 'mojom', 768 'mus', 769 'native', 770 'navigation', 771 'net', 772 'netlog', 773 'offline_pages', 774 'omnibox', 775 'oobe', 776 'openscreen', 777 'ozone', 778 'partition_alloc', 779 'passwords', 780 'p2p', 781 'page-serialization', 782 'paint_preview', 783 'pepper', 784 'PlatformMalloc', 785 'power', 786 'ppapi', 787 'ppapi_proxy', 788 'print', 789 'raf_investigation', 790 'rail', 791 'renderer', 792 'renderer_host', 793 'renderer.scheduler', 794 'resources', 795 'RLZ', 796 'ServiceWorker', 797 'SiteEngagement', 798 'safe_browsing', 799 'scheduler', 800 'scheduler.long_tasks', 801 'screenlock_monitor', 802 'segmentation_platform', 803 'sequence_manager', 804 'service_manager', 805 'sharing', 806 'shell', 807 'shortcut_viewer', 808 'shutdown', 809 'skia', 810 'sql', 811 'stadia_media', 812 'stadia_rtc', 813 'startup', 814 'sync', 815 'system_apps', 816 'test_gpu', 817 'toplevel', 818 'toplevel.flow', 819 'ui', 820 'v8', 821 'v8.execute', 822 'v8.wasm', 823 'ValueStoreFrontend::Backend', 824 'views', 825 'views.frame', 826 'viz', 827 'vk', 828 'wakeup.flow', 829 'wayland', 830 'webaudio', 831 'webengine.fidl', 832 'weblayer', 833 'WebCore', 834 'webrtc', 835 'webrtc_stats', 836 'xr', 837 'disabled-by-default-android_view_hierarchy', 838 'disabled-by-default-animation-worklet', 839 'disabled-by-default-audio', 840 'disabled-by-default-audio-worklet', 841 'disabled-by-default-audio.latency', 842 'disabled-by-default-base', 843 'disabled-by-default-blink.debug', 844 'disabled-by-default-blink.debug.display_lock', 845 'disabled-by-default-blink.debug.layout', 846 'disabled-by-default-blink.debug.layout.scrollbars', 847 'disabled-by-default-blink.debug.layout.trees', 848 'disabled-by-default-blink.feature_usage', 849 'disabled-by-default-blink.image_decoding', 850 'disabled-by-default-blink.invalidation', 851 'disabled-by-default-identifiability', 852 'disabled-by-default-identifiability.high_entropy_api', 853 'disabled-by-default-cc', 854 'disabled-by-default-cc.debug', 855 'disabled-by-default-cc.debug.cdp-perf', 856 'disabled-by-default-cc.debug.display_items', 857 'disabled-by-default-cc.debug.lcd_text', 858 'disabled-by-default-cc.debug.picture', 859 'disabled-by-default-cc.debug.scheduler', 860 'disabled-by-default-cc.debug.scheduler.frames', 861 'disabled-by-default-cc.debug.scheduler.now', 862 'disabled-by-default-content.verbose', 863 'disabled-by-default-cpu_profiler', 864 'disabled-by-default-cppgc', 865 'disabled-by-default-cpu_profiler.debug', 866 'disabled-by-default-devtools.screenshot', 867 'disabled-by-default-devtools.timeline', 868 'disabled-by-default-devtools.timeline.frame', 869 'disabled-by-default-devtools.timeline.inputs', 870 'disabled-by-default-devtools.timeline.invalidationTracking', 871 'disabled-by-default-devtools.timeline.layers', 872 'disabled-by-default-devtools.timeline.picture', 873 'disabled-by-default-devtools.timeline.stack', 874 'disabled-by-default-file', 875 'disabled-by-default-fonts', 876 'disabled-by-default-gpu_cmd_queue', 877 'disabled-by-default-gpu.dawn', 878 'disabled-by-default-gpu.debug', 879 'disabled-by-default-gpu.decoder', 880 'disabled-by-default-gpu.device', 881 'disabled-by-default-gpu.service', 882 'disabled-by-default-gpu.vulkan.vma', 883 'disabled-by-default-histogram_samples', 884 'disabled-by-default-java-heap-profiler', 885 'disabled-by-default-layer-element', 886 'disabled-by-default-layout_shift.debug', 887 'disabled-by-default-lifecycles', 888 'disabled-by-default-loading', 889 'disabled-by-default-mediastream', 890 'disabled-by-default-memory-infra', 891 'disabled-by-default-memory-infra.v8.code_stats', 892 'disabled-by-default-mojom', 893 'disabled-by-default-net', 894 'disabled-by-default-network', 895 'disabled-by-default-paint-worklet', 896 'disabled-by-default-power', 897 'disabled-by-default-renderer.scheduler', 898 'disabled-by-default-renderer.scheduler.debug', 899 'disabled-by-default-sequence_manager', 900 'disabled-by-default-sequence_manager.debug', 901 'disabled-by-default-sequence_manager.verbose_snapshots', 902 'disabled-by-default-skia', 903 'disabled-by-default-skia.gpu', 904 'disabled-by-default-skia.gpu.cache', 905 'disabled-by-default-skia.shaders', 906 'disabled-by-default-SyncFileSystem', 907 'disabled-by-default-system_stats', 908 'disabled-by-default-thread_pool_diagnostics', 909 'disabled-by-default-toplevel.ipc', 910 'disabled-by-default-user_action_samples', 911 'disabled-by-default-v8.compile', 912 'disabled-by-default-v8.cpu_profiler', 913 'disabled-by-default-v8.gc', 914 'disabled-by-default-v8.gc_stats', 915 'disabled-by-default-v8.ic_stats', 916 'disabled-by-default-v8.inspector', 917 'disabled-by-default-v8.runtime', 918 'disabled-by-default-v8.runtime_stats', 919 'disabled-by-default-v8.runtime_stats_sampling', 920 'disabled-by-default-v8.stack_trace', 921 'disabled-by-default-v8.turbofan', 922 'disabled-by-default-v8.wasm.detailed', 923 'disabled-by-default-v8.wasm.turbofan', 924 'disabled-by-default-video_and_image_capture', 925 'disabled-by-default-viz.gpu_composite_time', 926 'disabled-by-default-viz.debug.overlay_planes', 927 'disabled-by-default-viz.hit_testing_flow', 928 'disabled-by-default-viz.overdraw', 929 'disabled-by-default-viz.quads', 930 'disabled-by-default-viz.surface_id_flow', 931 'disabled-by-default-viz.surface_lifetime', 932 'disabled-by-default-viz.triangles', 933 'disabled-by-default-webaudio.audionode', 934 'disabled-by-default-webgpu', 935 'disabled-by-default-webrtc', 936 'disabled-by-default-worker.scheduler', 937 'disabled-by-default-xr.debug', 938 ]; 939} 940 941export function getContainingTrackId(state: State, trackId: string): null| 942 string { 943 const track = state.tracks[trackId]; 944 if (!track) { 945 return null; 946 } 947 const parentId = track.trackGroup; 948 if (!parentId) { 949 return null; 950 } 951 return parentId; 952} 953