1// Copyright (C) 2024 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import {BigintMath as BIMath} from '../base/bigint_math'; 16import {clamp} from '../base/math_utils'; 17import {OnSliceClickArgs} from './base_slice_track'; 18import {globals} from './globals'; 19import { 20 NAMED_ROW, 21 NamedSliceTrack, 22 NamedSliceTrackTypes, 23} from './named_slice_track'; 24import {SLICE_LAYOUT_FIT_CONTENT_DEFAULTS} from './slice_layout'; 25import {NewTrackArgs} from './track'; 26import {LONG_NULL} from '../trace_processor/query_result'; 27 28export const THREAD_SLICE_ROW = { 29 // Base columns (tsq, ts, dur, id, depth). 30 ...NAMED_ROW, 31 32 // Thread-specific columns. 33 threadDur: LONG_NULL, 34}; 35export type ThreadSliceRow = typeof THREAD_SLICE_ROW; 36 37export interface ThreadSliceTrackTypes extends NamedSliceTrackTypes { 38 row: ThreadSliceRow; 39} 40 41export class ThreadSliceTrack extends NamedSliceTrack<ThreadSliceTrackTypes> { 42 constructor( 43 args: NewTrackArgs, 44 private trackId: number, 45 maxDepth: number, 46 private tableName: string = 'slice', 47 ) { 48 super(args); 49 this.sliceLayout = { 50 ...SLICE_LAYOUT_FIT_CONTENT_DEFAULTS, 51 depthGuess: maxDepth, 52 }; 53 } 54 55 // This is used by the base class to call iter(). 56 getRowSpec() { 57 return THREAD_SLICE_ROW; 58 } 59 60 getSqlSource(): string { 61 return ` 62 select 63 ts, 64 dur, 65 id, 66 depth, 67 ifnull(name, '') as name, 68 thread_dur as threadDur 69 from ${this.tableName} 70 where track_id = ${this.trackId} 71 `; 72 } 73 74 // Converts a SQL result row to an "Impl" Slice. 75 rowToSlice( 76 row: ThreadSliceTrackTypes['row'], 77 ): ThreadSliceTrackTypes['slice'] { 78 const namedSlice = super.rowToSlice(row); 79 80 if (row.dur > 0n && row.threadDur !== null) { 81 const fillRatio = clamp(BIMath.ratio(row.threadDur, row.dur), 0, 1); 82 return {...namedSlice, fillRatio}; 83 } else { 84 return namedSlice; 85 } 86 } 87 88 onUpdatedSlices(slices: ThreadSliceTrackTypes['slice'][]) { 89 for (const slice of slices) { 90 slice.isHighlighted = slice === this.hoveredSlice; 91 } 92 } 93 94 onSliceClick(args: OnSliceClickArgs<ThreadSliceTrackTypes['slice']>) { 95 globals.setLegacySelection( 96 { 97 kind: 'SLICE', 98 id: args.slice.id, 99 trackKey: this.trackKey, 100 table: this.tableName, 101 }, 102 { 103 clearSearch: true, 104 pendingScrollId: undefined, 105 switchToCurrentSelectionTab: true, 106 }, 107 ); 108 } 109} 110