• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 m from 'mithril';
16import {Button} from '../../widgets/button';
17import {Icons} from '../../base/semantic_icons';
18import {uuidv4Sql} from '../../base/uuid';
19import {createView} from '../../trace_processor/sql_utils';
20import {Trace} from '../../public/trace';
21import {DatasetSliceTrack} from './dataset_slice_track';
22import {SourceDataset} from '../../trace_processor/dataset';
23import {LONG, LONG_NULL, NUM, STR} from '../../trace_processor/query_result';
24import {ThreadSliceDetailsPanel} from '../details/thread_slice_details_tab';
25import {BigintMath} from '../../base/bigint_math';
26import {clamp} from '../../base/math_utils';
27
28export interface VisualizedArgsTrackAttrs {
29  readonly uri: string;
30  readonly trace: Trace;
31  readonly trackId: number;
32  readonly maxDepth: number;
33  readonly argName: string;
34  readonly onClose: () => void;
35}
36
37export async function createVisualizedArgsTrack({
38  uri,
39  trace,
40  trackId,
41  maxDepth,
42  argName,
43  onClose,
44}: VisualizedArgsTrackAttrs) {
45  const uuid = uuidv4Sql();
46  const escapedArgName = argName.replace(/[^a-zA-Z]/g, '_');
47  const viewName = `__arg_visualisation_helper_${escapedArgName}_${uuid}_slice`;
48
49  await createView(
50    trace.engine,
51    viewName,
52    `
53      with slice_with_arg as (
54        select
55          slice.id,
56          slice.track_id,
57          slice.ts,
58          slice.dur,
59          slice.thread_dur,
60          NULL as cat,
61          args.display_value as name
62        from slice
63        join args using (arg_set_id)
64        where args.key='${argName}'
65      )
66      select
67        *,
68        (select count()
69        from ancestor_slice(s1.id) s2
70        join slice_with_arg s3 on s2.id=s3.id
71        ) as depth
72      from slice_with_arg s1
73      order by id
74    `,
75  );
76
77  return new DatasetSliceTrack({
78    trace,
79    uri,
80    dataset: new SourceDataset({
81      schema: {
82        id: NUM,
83        ts: LONG,
84        dur: LONG,
85        depth: NUM,
86        name: STR,
87        thread_dur: LONG_NULL,
88      },
89      src: viewName,
90      filter: {
91        col: 'track_id',
92        eq: trackId,
93      },
94    }),
95    initialMaxDepth: maxDepth,
96    detailsPanel: () => new ThreadSliceDetailsPanel(trace),
97    fillRatio: (row) => {
98      if (row.dur > 0n && row.thread_dur !== null) {
99        return clamp(BigintMath.ratio(row.thread_dur, row.dur), 0, 1);
100      } else {
101        return 1;
102      }
103    },
104    shellButtons: () => {
105      return m(Button, {
106        onclick: onClose,
107        icon: Icons.Close,
108        title: 'Close all visualised args tracks for this arg',
109        compact: true,
110      });
111    },
112  });
113}
114