1/*
2 * Copyright (C) 2024 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 {globalConfig} from 'common/global_config';
18import {CoarseVersion} from 'trace/coarse_version';
19import {Parser} from 'trace/parser';
20import {TraceType} from 'trace/trace_type';
21
22/* eslint-disable no-undef */
23export class Analytics {
24  private static GLOBAL_EXCEPTION = 'global_exception';
25  private static CROSS_TOOL_SYNC = 'cross_tool_sync';
26  private static DARK_MODE_ENABLED = 'dark_mode_enabled';
27  private static DOCUMENTATION_OPENED = 'documentation_opened';
28  private static BUGANIZER_OPENED = 'buganizer_opened';
29  private static EXPANDED_TIMELINE_OPENED = 'expanded_timeline_opened';
30  private static HIERARCHY_SETTINGS = 'hierarchy_settings';
31  private static NAVIGATION_ZOOM_EVENT = 'navigation_zoom';
32  private static PROPERTIES_SETTINGS = 'properties_settings';
33  private static RECT_SETTINGS = 'rect_settings';
34  private static REFRESH_DUMPS = 'refresh_dumps';
35  private static TIME_COPIED = 'time_copied';
36  private static TIME_INPUT = 'time_input';
37  private static TRACE_TAB_SWITCHED = 'trace_tab_switched';
38  private static TRACE_TIMELINE_DESELECTED = 'trace_timeline_deselected';
39  private static TRACING_LOADED_EVENT = 'tracing_trace_loaded';
40  private static TRACING_COLLECT_DUMP = 'tracing_collect_dump';
41  private static TRACING_COLLECT_TRACE = 'tracing_collect_trace';
42  private static TRACING_OPEN_FROM_ABT = 'tracing_from_abt';
43  private static USER_WARNING = 'user_warning';
44
45  static Error = class {
46    static logGlobalException(description: string) {
47      Analytics.doLogEvent(Analytics.GLOBAL_EXCEPTION, {
48        description,
49      } as Gtag.CustomParams);
50    }
51  };
52
53  static Help = class {
54    static logDocumentationOpened() {
55      Analytics.doLogEvent(Analytics.DOCUMENTATION_OPENED);
56    }
57
58    static logBuganizerOpened() {
59      Analytics.doLogEvent(Analytics.BUGANIZER_OPENED);
60    }
61  };
62
63  static Settings = class {
64    static logDarkModeEnabled() {
65      Analytics.doLogEvent(Analytics.DARK_MODE_ENABLED);
66    }
67    static logCrossToolSync(value: boolean) {
68      Analytics.doLogEvent(Analytics.CROSS_TOOL_SYNC, {
69        value,
70      } as Gtag.CustomParams);
71    }
72  };
73
74  static Navigation = class {
75    static logExpandedTimelineOpened() {
76      Analytics.doLogEvent(Analytics.EXPANDED_TIMELINE_OPENED);
77    }
78
79    static logHierarchySettingsChanged(
80      option: string,
81      value: boolean,
82      traceType: string,
83    ) {
84      Analytics.doLogEvent(Analytics.HIERARCHY_SETTINGS, {
85        option,
86        value,
87        traceType,
88      } as Gtag.CustomParams);
89    }
90
91    static logPropertiesSettingsChanged(
92      option: string,
93      value: boolean,
94      traceType: string,
95    ) {
96      Analytics.doLogEvent(Analytics.PROPERTIES_SETTINGS, {
97        option,
98        value,
99        traceType,
100      } as Gtag.CustomParams);
101    }
102
103    static logRectSettingsChanged(
104      option: string,
105      value: string | number | boolean,
106      traceType: string,
107    ) {
108      Analytics.doLogEvent(Analytics.RECT_SETTINGS, {
109        option,
110        value,
111        traceType,
112      } as Gtag.CustomParams);
113    }
114
115    static logTabSwitched(tabTraceType: string) {
116      Analytics.doLogEvent(Analytics.TRACE_TAB_SWITCHED, {
117        type: tabTraceType,
118      } as Gtag.CustomParams);
119    }
120
121    static logTimeCopied(type: 'ns' | 'human') {
122      Analytics.doLogEvent(Analytics.TIME_COPIED, {
123        type,
124      } as Gtag.CustomParams);
125    }
126
127    static logTimeInput(type: 'ns' | 'human') {
128      Analytics.doLogEvent(Analytics.TIME_INPUT, {
129        type,
130      } as Gtag.CustomParams);
131    }
132
133    static logTraceTimelineDeselected(type: string) {
134      Analytics.doLogEvent(Analytics.TRACE_TIMELINE_DESELECTED, {
135        type,
136      } as Gtag.CustomParams);
137    }
138
139    static logZoom(
140      type: 'scroll' | 'button' | 'reset',
141      component: 'rects' | 'timeline',
142      direction?: 'in' | 'out',
143    ) {
144      Analytics.doLogEvent(Analytics.NAVIGATION_ZOOM_EVENT, {
145        direction,
146        component,
147        type,
148      } as Gtag.CustomParams);
149    }
150  };
151
152  static Tracing = class {
153    static logTraceLoaded(parser: Parser<object>) {
154      Analytics.doLogEvent(Analytics.TRACING_LOADED_EVENT, {
155        type: TraceType[parser.getTraceType()],
156        coarse_version: CoarseVersion[parser.getCoarseVersion()],
157      } as Gtag.CustomParams);
158    }
159
160    static logCollectDumps(requestedDumps: string[]) {
161      requestedDumps.forEach((dumpType) => {
162        Analytics.doLogEvent(Analytics.TRACING_COLLECT_DUMP, {
163          type: dumpType,
164        } as Gtag.CustomParams);
165      });
166    }
167
168    static logCollectTraces(requestedTraces: string[]) {
169      requestedTraces.forEach((traceType) => {
170        Analytics.doLogEvent(Analytics.TRACING_COLLECT_TRACE, {
171          type: traceType,
172        } as Gtag.CustomParams);
173      });
174    }
175
176    static logOpenFromABT() {
177      Analytics.doLogEvent(Analytics.TRACING_OPEN_FROM_ABT);
178    }
179
180    static logRefreshDumps() {
181      Analytics.doLogEvent(Analytics.REFRESH_DUMPS);
182    }
183  };
184
185  static UserNotification = class {
186    static logUserWarning(description: string) {
187      Analytics.doLogEvent(Analytics.USER_WARNING, {
188        description,
189      } as Gtag.CustomParams);
190    }
191  };
192
193  private static doLogEvent(
194    eventName: Gtag.EventNames | (string & {}),
195    eventParams?: Gtag.ControlParams | Gtag.EventParams | Gtag.CustomParams,
196  ) {
197    if (globalConfig.MODE === 'PROD') {
198      gtag('event', eventName, eventParams);
199    }
200  }
201}
202