xref: /aosp_15_r20/development/tools/winscope/src/logging/analytics.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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 BUGANIZER_OPENED = 'buganizer_opened';
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 EXPANDED_TIMELINE_OPENED = 'expanded_timeline_opened';
29  private static GLOBAL_EXCEPTION = 'global_exception';
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 PROXY_ERROR = 'proxy_error';
34  private static PROXY_SERVER_NOT_FOUND = 'proxy_server_not_found';
35  private static PROXY_NO_FILES_FOUND = 'proxy_no_files_found';
36  private static TP_QUERY_EXECUTION_TIME = 'tp_query_execution_time';
37  private static TP_QUERY_REQUESTED = 'tp_query_requested';
38  private static TP_QUERY_FAILED = 'tp_query_failed';
39  private static TP_QUERY_SAVED = 'tp_query_saved';
40  private static RECT_SETTINGS = 'rect_settings';
41  private static REFRESH_DUMPS = 'refresh_dumps';
42  private static TIME_BOOKMARK = 'time_bookmark';
43  private static TIME_COPIED = 'time_copied';
44  private static TIME_INPUT = 'time_input';
45  private static TRACE_TAB_SWITCHED = 'trace_tab_switched';
46  private static TRACE_TIMELINE_DESELECTED = 'trace_timeline_deselected';
47  private static TRACING_LOADED_EVENT = 'tracing_trace_loaded';
48  private static TRACING_COLLECT_DUMP = 'tracing_collect_dump';
49  private static TRACING_COLLECT_TRACE = 'tracing_collect_trace';
50  private static TRACING_OPEN_FROM_ABT = 'tracing_from_abt';
51  private static USER_WARNING = 'user_warning';
52
53  static Error = class {
54    static logGlobalException(description: string) {
55      Analytics.doLogEvent(Analytics.GLOBAL_EXCEPTION, {
56        description,
57      } as Gtag.CustomParams);
58    }
59    static logProxyError(description: string) {
60      Analytics.doLogEvent(Analytics.PROXY_ERROR, {
61        description,
62      } as Gtag.CustomParams);
63    }
64  };
65
66  static Help = class {
67    static logDocumentationOpened() {
68      Analytics.doLogEvent(Analytics.DOCUMENTATION_OPENED);
69    }
70
71    static logBuganizerOpened() {
72      Analytics.doLogEvent(Analytics.BUGANIZER_OPENED);
73    }
74  };
75
76  static Navigation = class {
77    static logExpandedTimelineOpened() {
78      Analytics.doLogEvent(Analytics.EXPANDED_TIMELINE_OPENED);
79    }
80
81    static logHierarchySettingsChanged(
82      option: string,
83      value: boolean,
84      traceType: string,
85    ) {
86      Analytics.doLogEvent(Analytics.HIERARCHY_SETTINGS, {
87        option,
88        value,
89        traceType,
90      } as Gtag.CustomParams);
91    }
92
93    static logPropertiesSettingsChanged(
94      option: string,
95      value: boolean,
96      traceType: string,
97    ) {
98      Analytics.doLogEvent(Analytics.PROPERTIES_SETTINGS, {
99        option,
100        value,
101        traceType,
102      } as Gtag.CustomParams);
103    }
104
105    static logRectSettingsChanged(
106      option: string,
107      value: string | number | boolean,
108      traceType: string,
109    ) {
110      Analytics.doLogEvent(Analytics.RECT_SETTINGS, {
111        option,
112        value,
113        traceType,
114      } as Gtag.CustomParams);
115    }
116
117    static logTabSwitched(tabTraceType: string) {
118      Analytics.doLogEvent(Analytics.TRACE_TAB_SWITCHED, {
119        type: tabTraceType,
120      } as Gtag.CustomParams);
121    }
122
123    static logTimeCopied(type: 'ns' | 'human') {
124      Analytics.doLogEvent(Analytics.TIME_COPIED, {
125        type,
126      } as Gtag.CustomParams);
127    }
128
129    static logTimeInput(type: 'ns' | 'human') {
130      Analytics.doLogEvent(Analytics.TIME_INPUT, {
131        type,
132      } as Gtag.CustomParams);
133    }
134
135    static logTimeBookmark() {
136      Analytics.doLogEvent(Analytics.TIME_BOOKMARK);
137    }
138
139    static logTraceTimelineDeselected(type: string) {
140      Analytics.doLogEvent(Analytics.TRACE_TIMELINE_DESELECTED, {
141        type,
142      } as Gtag.CustomParams);
143    }
144
145    static logZoom(
146      type: 'scroll' | 'button' | 'reset' | 'key',
147      component: 'rects' | 'timeline',
148      direction?: 'in' | 'out',
149    ) {
150      Analytics.doLogEvent(Analytics.NAVIGATION_ZOOM_EVENT, {
151        direction,
152        component,
153        type,
154      } as Gtag.CustomParams);
155    }
156  };
157
158  static Proxy = class {
159    static logServerNotFound() {
160      Analytics.doLogEvent(Analytics.PROXY_SERVER_NOT_FOUND);
161    }
162
163    static logNoFilesFound() {
164      Analytics.doLogEvent(Analytics.PROXY_NO_FILES_FOUND);
165    }
166  };
167
168  static Settings = class {
169    static logDarkModeEnabled() {
170      Analytics.doLogEvent(Analytics.DARK_MODE_ENABLED);
171    }
172    static logCrossToolSync(value: boolean) {
173      Analytics.doLogEvent(Analytics.CROSS_TOOL_SYNC, {
174        value,
175      } as Gtag.CustomParams);
176    }
177  };
178
179  static TraceSearch = class {
180    static logQueryExecutionTime(value: number) {
181      Analytics.doLogEvent(Analytics.TP_QUERY_EXECUTION_TIME, {
182        value,
183      } as Gtag.CustomParams);
184    }
185    static logQueryFailure() {
186      Analytics.doLogEvent(Analytics.TP_QUERY_FAILED);
187    }
188    static logQueryRequested(type: 'new' | 'saved' | 'recent') {
189      Analytics.doLogEvent(Analytics.TP_QUERY_REQUESTED, {
190        type,
191      } as Gtag.CustomParams);
192    }
193    static logQuerySaved() {
194      Analytics.doLogEvent(Analytics.TP_QUERY_SAVED);
195    }
196  };
197
198  static Tracing = class {
199    static logTraceLoaded(parser: Parser<object>) {
200      Analytics.doLogEvent(Analytics.TRACING_LOADED_EVENT, {
201        type: TraceType[parser.getTraceType()],
202        coarse_version: CoarseVersion[parser.getCoarseVersion()],
203      } as Gtag.CustomParams);
204    }
205
206    static logCollectDumps(requestedDumps: string[]) {
207      requestedDumps.forEach((dumpType) => {
208        Analytics.doLogEvent(Analytics.TRACING_COLLECT_DUMP, {
209          type: dumpType,
210        } as Gtag.CustomParams);
211      });
212    }
213
214    static logCollectTraces(requestedTraces: string[]) {
215      requestedTraces.forEach((traceType) => {
216        Analytics.doLogEvent(Analytics.TRACING_COLLECT_TRACE, {
217          type: traceType,
218        } as Gtag.CustomParams);
219      });
220    }
221
222    static logOpenFromABT() {
223      Analytics.doLogEvent(Analytics.TRACING_OPEN_FROM_ABT);
224    }
225
226    static logRefreshDumps() {
227      Analytics.doLogEvent(Analytics.REFRESH_DUMPS);
228    }
229  };
230
231  static UserNotification = class {
232    static logUserWarning(description: string, message: string) {
233      Analytics.doLogEvent(Analytics.USER_WARNING, {
234        description,
235        message,
236      } as Gtag.CustomParams);
237    }
238  };
239
240  private static doLogEvent(
241    eventName: Gtag.EventNames | (string & {}),
242    eventParams?: Gtag.ControlParams | Gtag.EventParams | Gtag.CustomParams,
243  ) {
244    if (globalConfig.MODE === 'PROD') {
245      gtag('event', eventName, eventParams);
246    }
247  }
248}
249