xref: /aosp_15_r20/external/perfetto/ui/src/public/utils.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1// Copyright (C) 2023 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 {exists} from '../base/utils';
16import {Trace} from './trace';
17import {TimeSpan} from '../base/time';
18
19export function getTrackName(
20  args: Partial<{
21    name: string | null;
22    utid: number | null;
23    processName: string | null;
24    pid: number | null;
25    threadName: string | null;
26    tid: number | null;
27    upid: number | null;
28    userName: string | null;
29    uid: number | null;
30    kind: string;
31    threadTrack: boolean;
32    uidTrack: boolean;
33  }>,
34) {
35  const {
36    name,
37    upid,
38    utid,
39    processName,
40    threadName,
41    pid,
42    tid,
43    userName,
44    uid,
45    kind,
46    threadTrack,
47    uidTrack,
48  } = args;
49
50  const hasName = name !== undefined && name !== null && name !== '[NULL]';
51  const hasUpid = upid !== undefined && upid !== null;
52  const hasUtid = utid !== undefined && utid !== null;
53  const hasProcessName = processName !== undefined && processName !== null;
54  const hasThreadName = threadName !== undefined && threadName !== null;
55  const hasUserName = userName !== undefined && userName !== null;
56  const hasTid = tid !== undefined && tid !== null;
57  const hasPid = pid !== undefined && pid !== null;
58  const hasUid = uid !== undefined && uid !== null;
59  const hasKind = kind !== undefined;
60  const isThreadTrack = threadTrack !== undefined && threadTrack;
61  const isUidTrack = uidTrack !== undefined && uidTrack;
62
63  // If we don't have any useful information (better than
64  // upid/utid) we show the track kind to help with tracking
65  // down where this is coming from.
66  const kindSuffix = hasKind ? ` (${kind})` : '';
67
68  if (isThreadTrack && hasName && hasTid) {
69    return `${name} (${tid})`;
70  } else if (isUidTrack && hasName && hasUserName) {
71    return `${name} (${userName})`;
72  } else if (isUidTrack && hasName && hasUid) {
73    return `${name} ${uid}`;
74  } else if (hasName) {
75    return `${name}`;
76  } else if (hasUpid && hasPid && hasProcessName) {
77    return `${processName} ${pid}`;
78  } else if (hasUpid && hasPid) {
79    return `Process ${pid}`;
80  } else if (hasThreadName && hasTid) {
81    return `${threadName} ${tid}`;
82  } else if (hasTid) {
83    return `Thread ${tid}`;
84  } else if (hasUpid) {
85    return `upid: ${upid}${kindSuffix}`;
86  } else if (hasUtid) {
87    return `utid: ${utid}${kindSuffix}`;
88  } else if (hasUid) {
89    return `uid: ${uid}${kindSuffix}`;
90  } else if (hasKind) {
91    return `Unnamed ${kind}`;
92  }
93  return 'Unknown';
94}
95
96export function getThreadOrProcUri(
97  upid: number | null,
98  utid: number | null,
99): string {
100  if (exists(upid)) {
101    return `/process_${upid}`;
102  } else if (exists(utid)) {
103    return `/thread_${utid}`;
104  } else {
105    throw new Error('No upid or utid defined...');
106  }
107}
108
109export function getThreadUriPrefix(upid: number | null, utid: number): string {
110  if (exists(upid)) {
111    return `/process_${upid}/thread_${utid}`;
112  } else {
113    return `/thread_${utid}`;
114  }
115}
116
117// Returns the time span of the current selection, or the visible window if
118// there is no current selection.
119export async function getTimeSpanOfSelectionOrVisibleWindow(
120  trace: Trace,
121): Promise<TimeSpan> {
122  const range = await trace.selection.findTimeRangeOfSelection();
123  if (exists(range)) {
124    return new TimeSpan(range.start, range.end);
125  } else {
126    return trace.timeline.visibleWindow.toTimeSpan();
127  }
128}
129