1/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import {ScreenRecordingTraceEntry} from './screen_recording';
18import {HierarchyTreeNode} from './tree_node/hierarchy_tree_node';
19import {PropertyTreeNode} from './tree_node/property_tree_node';
20
21export enum TraceType {
22  WINDOW_MANAGER,
23  SURFACE_FLINGER,
24  SCREEN_RECORDING,
25  SCREENSHOT,
26  TRANSACTIONS,
27  TRANSACTIONS_LEGACY,
28  WAYLAND,
29  WAYLAND_DUMP,
30  PROTO_LOG,
31  SYSTEM_UI,
32  INPUT_METHOD_CLIENTS,
33  INPUT_METHOD_MANAGER_SERVICE,
34  INPUT_METHOD_SERVICE,
35  EVENT_LOG,
36  WM_TRANSITION,
37  SHELL_TRANSITION,
38  TRANSITION,
39  CUJS,
40  TEST_TRACE_STRING,
41  TEST_TRACE_NUMBER,
42  VIEW_CAPTURE,
43  INPUT_MOTION_EVENT,
44  INPUT_KEY_EVENT,
45}
46
47export type ImeTraceType =
48  | TraceType.INPUT_METHOD_CLIENTS
49  | TraceType.INPUT_METHOD_MANAGER_SERVICE
50  | TraceType.INPUT_METHOD_SERVICE;
51
52export interface TraceEntryTypeMap {
53  [TraceType.PROTO_LOG]: PropertyTreeNode;
54  [TraceType.SURFACE_FLINGER]: HierarchyTreeNode;
55  [TraceType.SCREEN_RECORDING]: ScreenRecordingTraceEntry;
56  [TraceType.SCREENSHOT]: ScreenRecordingTraceEntry;
57  [TraceType.SYSTEM_UI]: object;
58  [TraceType.TRANSACTIONS]: PropertyTreeNode;
59  [TraceType.TRANSACTIONS_LEGACY]: object;
60  [TraceType.WAYLAND]: object;
61  [TraceType.WAYLAND_DUMP]: object;
62  [TraceType.WINDOW_MANAGER]: HierarchyTreeNode;
63  [TraceType.INPUT_METHOD_CLIENTS]: HierarchyTreeNode;
64  [TraceType.INPUT_METHOD_MANAGER_SERVICE]: HierarchyTreeNode;
65  [TraceType.INPUT_METHOD_SERVICE]: HierarchyTreeNode;
66  [TraceType.EVENT_LOG]: PropertyTreeNode;
67  [TraceType.WM_TRANSITION]: PropertyTreeNode;
68  [TraceType.SHELL_TRANSITION]: PropertyTreeNode;
69  [TraceType.TRANSITION]: PropertyTreeNode;
70  [TraceType.CUJS]: PropertyTreeNode;
71  [TraceType.TEST_TRACE_STRING]: string;
72  [TraceType.TEST_TRACE_NUMBER]: number;
73  [TraceType.VIEW_CAPTURE]: HierarchyTreeNode;
74  [TraceType.INPUT_MOTION_EVENT]: PropertyTreeNode;
75  [TraceType.INPUT_KEY_EVENT]: PropertyTreeNode;
76}
77
78export class TraceTypeUtils {
79  private static UI_PIPELINE_ORDER = [
80    TraceType.INPUT_METHOD_CLIENTS,
81    TraceType.INPUT_METHOD_SERVICE,
82    TraceType.INPUT_METHOD_MANAGER_SERVICE,
83    TraceType.PROTO_LOG,
84    TraceType.WINDOW_MANAGER,
85    TraceType.TRANSACTIONS,
86    TraceType.SURFACE_FLINGER,
87    TraceType.SCREEN_RECORDING,
88  ];
89
90  private static TRACES_WITH_VIEWERS_DISPLAY_ORDER = [
91    TraceType.SCREEN_RECORDING,
92    TraceType.SURFACE_FLINGER,
93    TraceType.WINDOW_MANAGER,
94    TraceType.INPUT_METHOD_CLIENTS,
95    TraceType.INPUT_METHOD_MANAGER_SERVICE,
96    TraceType.INPUT_METHOD_SERVICE,
97    TraceType.TRANSACTIONS,
98    TraceType.TRANSACTIONS_LEGACY,
99    TraceType.PROTO_LOG,
100    TraceType.VIEW_CAPTURE,
101    TraceType.TRANSITION,
102  ];
103
104  static isTraceTypeWithViewer(t: TraceType): boolean {
105    return TraceTypeUtils.TRACES_WITH_VIEWERS_DISPLAY_ORDER.includes(t);
106  }
107
108  static compareByUiPipelineOrder(t: TraceType, u: TraceType) {
109    const tIndex = TraceTypeUtils.findIndexInOrder(
110      t,
111      TraceTypeUtils.UI_PIPELINE_ORDER,
112    );
113    const uIndex = TraceTypeUtils.findIndexInOrder(
114      u,
115      TraceTypeUtils.UI_PIPELINE_ORDER,
116    );
117    return tIndex >= 0 && uIndex >= 0 && tIndex < uIndex;
118  }
119
120  static compareByDisplayOrder(t: TraceType, u: TraceType) {
121    const tIndex = TraceTypeUtils.findIndexInOrder(
122      t,
123      TraceTypeUtils.TRACES_WITH_VIEWERS_DISPLAY_ORDER,
124    );
125    const uIndex = TraceTypeUtils.findIndexInOrder(
126      u,
127      TraceTypeUtils.TRACES_WITH_VIEWERS_DISPLAY_ORDER,
128    );
129    return tIndex - uIndex;
130  }
131
132  static canVisualizeTrace(t: TraceType): boolean {
133    return t !== TraceType.WM_TRANSITION && t !== TraceType.SHELL_TRANSITION;
134  }
135
136  static traceUploadInfo(t: TraceType): string | undefined {
137    switch (t) {
138      case TraceType.CUJS:
139        return 'Used to show CUJ boundaries in timeline';
140      default:
141        return undefined;
142    }
143  }
144
145  static getReasonForNoTraceVisualization(t: TraceType): string {
146    switch (t) {
147      case TraceType.WM_TRANSITION:
148        return 'Must also upload a shell transitions trace to visualize transitions';
149      case TraceType.SHELL_TRANSITION:
150        return 'Must also upload a wm transitions trace to visualize transitions';
151      default:
152        return 'Visualization for this trace is not supported in Winscope';
153    }
154  }
155
156  private static findIndexInOrder(
157    traceType: TraceType,
158    order: TraceType[],
159  ): number {
160    return order.findIndex((type) => {
161      return type === traceType;
162    });
163  }
164}
165