1// Copyright (C) 2020 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 {ColumnDef} from '../../common/aggregation_data'; 16import {Engine} from '../../common/engine'; 17import {Area, Sorting} from '../../common/state'; 18import {globals} from '../../frontend/globals'; 19import { 20 ASYNC_SLICE_TRACK_KIND, 21 Config as AsyncSliceConfig, 22} from '../../tracks/async_slices'; 23import { 24 Config as SliceConfig, 25 SLICE_TRACK_KIND, 26} from '../../tracks/chrome_slices'; 27 28import {AggregationController} from './aggregation_controller'; 29 30export function getSelectedTrackIds(area: Area): number[] { 31 const selectedTrackIds = []; 32 for (const trackId of area.tracks) { 33 const track = globals.state.tracks[trackId]; 34 // Track will be undefined for track groups. 35 if (track !== undefined) { 36 if (track.kind === SLICE_TRACK_KIND) { 37 selectedTrackIds.push((track.config as SliceConfig).trackId); 38 } 39 if (track.kind === ASYNC_SLICE_TRACK_KIND) { 40 const config = track.config as AsyncSliceConfig; 41 for (const id of config.trackIds) { 42 selectedTrackIds.push(id); 43 } 44 } 45 } 46 } 47 return selectedTrackIds; 48} 49 50export class SliceAggregationController extends AggregationController { 51 async createAggregateView(engine: Engine, area: Area) { 52 await engine.query(`drop view if exists ${this.kind};`); 53 54 const selectedTrackIds = getSelectedTrackIds(area); 55 56 if (selectedTrackIds.length === 0) return false; 57 58 const query = `create view ${this.kind} as 59 SELECT 60 name, 61 sum(dur) AS total_dur, 62 sum(dur)/count(1) as avg_dur, 63 count(1) as occurrences 64 FROM slices 65 WHERE track_id IN (${selectedTrackIds}) AND 66 ts + dur > ${area.start} AND 67 ts < ${area.end} group by name`; 68 69 await engine.query(query); 70 return true; 71 } 72 73 getTabName() { 74 return 'Slices'; 75 } 76 77 async getExtra() {} 78 79 getDefaultSorting(): Sorting { 80 return {column: 'total_dur', direction: 'DESC'}; 81 } 82 83 getColumnDefinitions(): ColumnDef[] { 84 return [ 85 { 86 title: 'Name', 87 kind: 'STRING', 88 columnConstructor: Uint32Array, 89 columnId: 'name', 90 }, 91 { 92 title: 'Wall duration (ms)', 93 kind: 'TIMESTAMP_NS', 94 columnConstructor: Float64Array, 95 columnId: 'total_dur', 96 sum: true, 97 }, 98 { 99 title: 'Avg Wall duration (ms)', 100 kind: 'TIMESTAMP_NS', 101 columnConstructor: Float64Array, 102 columnId: 'avg_dur', 103 }, 104 { 105 title: 'Occurrences', 106 kind: 'NUMBER', 107 columnConstructor: Uint32Array, 108 columnId: 'occurrences', 109 sum: true, 110 }, 111 ]; 112 } 113} 114