1/* 2 * Copyright (C) 2023 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 {assertTrue} from 'common/assert_utils'; 18import {Timestamp} from 'common/time/time'; 19import {Trace, TraceEntry} from 'trace/trace'; 20import {TracePosition} from 'trace/trace_position'; 21import {TraceType} from 'trace/trace_type'; 22import {AdbFiles} from 'trace_collection/adb_files'; 23import {View, Viewer, ViewType} from 'viewers/viewer'; 24 25export enum WinscopeEventType { 26 APP_INITIALIZED, 27 APP_FILES_COLLECTED, 28 APP_FILES_UPLOADED, 29 APP_RESET_REQUEST, 30 APP_TRACE_VIEW_REQUEST, 31 APP_TRACE_VIEW_REQUEST_HANDLED, 32 APP_REFRESH_DUMPS_REQUEST, 33 REMOTE_TOOL_DOWNLOAD_START, 34 REMOTE_TOOL_FILES_RECEIVED, 35 REMOTE_TOOL_TIMESTAMP_RECEIVED, 36 TABBED_VIEW_SWITCHED, 37 TABBED_VIEW_SWITCH_REQUEST, 38 TRACE_POSITION_UPDATE, 39 VIEWERS_LOADED, 40 VIEWERS_UNLOADED, 41 EXPANDED_TIMELINE_TOGGLED, 42 ACTIVE_TRACE_CHANGED, 43 DARK_MODE_TOGGLED, 44 NO_TRACE_TARGETS_SELECTED, 45 FILTER_PRESET_SAVE_REQUEST, 46 FILTER_PRESET_APPLY_REQUEST, 47 TRACE_SEARCH_REQUEST, 48 TRACE_SEARCH_FAILED, 49 TRACE_SEARCH_COMPLETED, 50 TRACE_ADD_REQUEST, 51 TRACE_REMOVE_REQUEST, 52 INITIALIZE_TRACE_SEARCH_REQUEST, 53 TRACE_SEARCH_INITIALIZED, 54} 55 56interface TypeMap { 57 [WinscopeEventType.APP_INITIALIZED]: AppInitialized; 58 [WinscopeEventType.APP_FILES_COLLECTED]: AppFilesCollected; 59 [WinscopeEventType.APP_FILES_UPLOADED]: AppFilesUploaded; 60 [WinscopeEventType.APP_RESET_REQUEST]: AppResetRequest; 61 [WinscopeEventType.APP_TRACE_VIEW_REQUEST]: AppTraceViewRequest; 62 [WinscopeEventType.APP_TRACE_VIEW_REQUEST_HANDLED]: AppTraceViewRequestHandled; 63 [WinscopeEventType.APP_REFRESH_DUMPS_REQUEST]: AppRefreshDumpsRequest; 64 [WinscopeEventType.REMOTE_TOOL_DOWNLOAD_START]: RemoteToolDownloadStart; 65 [WinscopeEventType.REMOTE_TOOL_FILES_RECEIVED]: RemoteToolFilesReceived; 66 [WinscopeEventType.REMOTE_TOOL_TIMESTAMP_RECEIVED]: RemoteToolTimestampReceived; 67 [WinscopeEventType.TABBED_VIEW_SWITCHED]: TabbedViewSwitched; 68 [WinscopeEventType.TABBED_VIEW_SWITCH_REQUEST]: TabbedViewSwitchRequest; 69 [WinscopeEventType.TRACE_POSITION_UPDATE]: TracePositionUpdate; 70 [WinscopeEventType.VIEWERS_LOADED]: ViewersLoaded; 71 [WinscopeEventType.VIEWERS_UNLOADED]: ViewersUnloaded; 72 [WinscopeEventType.EXPANDED_TIMELINE_TOGGLED]: ExpandedTimelineToggled; 73 [WinscopeEventType.ACTIVE_TRACE_CHANGED]: ActiveTraceChanged; 74 [WinscopeEventType.DARK_MODE_TOGGLED]: DarkModeToggled; 75 [WinscopeEventType.NO_TRACE_TARGETS_SELECTED]: NoTraceTargetsSelected; 76 [WinscopeEventType.FILTER_PRESET_SAVE_REQUEST]: FilterPresetSaveRequest; 77 [WinscopeEventType.FILTER_PRESET_APPLY_REQUEST]: FilterPresetApplyRequest; 78 [WinscopeEventType.TRACE_SEARCH_REQUEST]: TraceSearchRequest; 79 [WinscopeEventType.TRACE_SEARCH_FAILED]: TraceSearchFailed; 80 [WinscopeEventType.TRACE_ADD_REQUEST]: TraceAddRequest; 81 [WinscopeEventType.TRACE_REMOVE_REQUEST]: TraceRemoveRequest; 82 [WinscopeEventType.INITIALIZE_TRACE_SEARCH_REQUEST]: InitializeTraceSearchRequest; 83 [WinscopeEventType.TRACE_SEARCH_INITIALIZED]: TraceSearchInitialized; 84 [WinscopeEventType.TRACE_SEARCH_COMPLETED]: TraceSearchCompleted; 85} 86 87export abstract class WinscopeEvent { 88 abstract readonly type: WinscopeEventType; 89 90 async visit<T extends WinscopeEventType>( 91 type: T, 92 callback: (event: TypeMap[T]) => Promise<void>, 93 ) { 94 if (this.type === type) { 95 const event = this as unknown as TypeMap[T]; 96 await callback(event); 97 } 98 } 99} 100 101export class AppInitialized extends WinscopeEvent { 102 override readonly type = WinscopeEventType.APP_INITIALIZED; 103} 104 105export class AppFilesCollected extends WinscopeEvent { 106 override readonly type = WinscopeEventType.APP_FILES_COLLECTED; 107 108 constructor(readonly files: AdbFiles) { 109 super(); 110 } 111} 112 113export class AppFilesUploaded extends WinscopeEvent { 114 override readonly type = WinscopeEventType.APP_FILES_UPLOADED; 115 116 constructor(readonly files: File[]) { 117 super(); 118 } 119} 120 121export class AppResetRequest extends WinscopeEvent { 122 override readonly type = WinscopeEventType.APP_RESET_REQUEST; 123} 124 125export class AppTraceViewRequest extends WinscopeEvent { 126 override readonly type = WinscopeEventType.APP_TRACE_VIEW_REQUEST; 127} 128 129export class AppTraceViewRequestHandled extends WinscopeEvent { 130 override readonly type = WinscopeEventType.APP_TRACE_VIEW_REQUEST_HANDLED; 131} 132 133export class AppRefreshDumpsRequest extends WinscopeEvent { 134 override readonly type = WinscopeEventType.APP_REFRESH_DUMPS_REQUEST; 135} 136 137export class RemoteToolDownloadStart extends WinscopeEvent { 138 override readonly type = WinscopeEventType.REMOTE_TOOL_DOWNLOAD_START; 139} 140 141export class RemoteToolFilesReceived extends WinscopeEvent { 142 override readonly type = WinscopeEventType.REMOTE_TOOL_FILES_RECEIVED; 143 144 constructor( 145 readonly files: File[], 146 readonly deferredTimestamp?: () => Timestamp | undefined, 147 ) { 148 super(); 149 } 150} 151 152export class RemoteToolTimestampReceived extends WinscopeEvent { 153 override readonly type = WinscopeEventType.REMOTE_TOOL_TIMESTAMP_RECEIVED; 154 155 constructor(readonly deferredTimestamp: () => Timestamp | undefined) { 156 super(); 157 } 158} 159 160export class TabbedViewSwitched extends WinscopeEvent { 161 override readonly type = WinscopeEventType.TABBED_VIEW_SWITCHED; 162 readonly newFocusedView: View; 163 164 constructor(view: View) { 165 super(); 166 assertTrue( 167 view.type === ViewType.TRACE_TAB || view.type === ViewType.GLOBAL_SEARCH, 168 ); 169 this.newFocusedView = view; 170 } 171} 172 173export class TabbedViewSwitchRequest extends WinscopeEvent { 174 override readonly type = WinscopeEventType.TABBED_VIEW_SWITCH_REQUEST; 175 176 readonly newActiveTrace: Trace<object>; 177 178 constructor(newActiveTrace: Trace<object>) { 179 super(); 180 this.newActiveTrace = newActiveTrace; 181 } 182} 183 184export class TracePositionUpdate extends WinscopeEvent { 185 override readonly type = WinscopeEventType.TRACE_POSITION_UPDATE; 186 readonly position: TracePosition; 187 readonly updateTimeline: boolean; 188 189 constructor(position: TracePosition, updateTimeline = false) { 190 super(); 191 this.position = position; 192 this.updateTimeline = updateTimeline; 193 } 194 195 static fromTimestamp( 196 timestamp: Timestamp, 197 updateTimeline = false, 198 ): TracePositionUpdate { 199 const position = TracePosition.fromTimestamp(timestamp); 200 return new TracePositionUpdate(position, updateTimeline); 201 } 202 203 static fromTraceEntry( 204 entry: TraceEntry<{}>, 205 updateTimeline = false, 206 ): TracePositionUpdate { 207 const position = TracePosition.fromTraceEntry(entry); 208 return new TracePositionUpdate(position, updateTimeline); 209 } 210} 211 212export class ViewersLoaded extends WinscopeEvent { 213 override readonly type = WinscopeEventType.VIEWERS_LOADED; 214 215 constructor(readonly viewers: Viewer[]) { 216 super(); 217 } 218} 219 220export class ViewersUnloaded extends WinscopeEvent { 221 override readonly type = WinscopeEventType.VIEWERS_UNLOADED; 222} 223 224export class ExpandedTimelineToggled extends WinscopeEvent { 225 override readonly type = WinscopeEventType.EXPANDED_TIMELINE_TOGGLED; 226 constructor(readonly isTimelineExpanded: boolean) { 227 super(); 228 } 229} 230 231export class ActiveTraceChanged extends WinscopeEvent { 232 override readonly type = WinscopeEventType.ACTIVE_TRACE_CHANGED; 233 constructor(readonly trace: Trace<object>) { 234 super(); 235 } 236} 237 238export class DarkModeToggled extends WinscopeEvent { 239 override readonly type = WinscopeEventType.DARK_MODE_TOGGLED; 240 constructor(readonly isDarkMode: boolean) { 241 super(); 242 } 243} 244 245export class NoTraceTargetsSelected extends WinscopeEvent { 246 override readonly type = WinscopeEventType.NO_TRACE_TARGETS_SELECTED; 247} 248 249export class FilterPresetSaveRequest extends WinscopeEvent { 250 override readonly type = WinscopeEventType.FILTER_PRESET_SAVE_REQUEST; 251 constructor(readonly name: string, readonly traceType: TraceType) { 252 super(); 253 } 254} 255 256export class FilterPresetApplyRequest extends WinscopeEvent { 257 override readonly type = WinscopeEventType.FILTER_PRESET_APPLY_REQUEST; 258 constructor(readonly name: string, readonly traceType: TraceType) { 259 super(); 260 } 261} 262 263export class TraceSearchRequest extends WinscopeEvent { 264 override readonly type = WinscopeEventType.TRACE_SEARCH_REQUEST; 265 constructor(readonly query: string) { 266 super(); 267 } 268} 269 270export class TraceSearchFailed extends WinscopeEvent { 271 override readonly type = WinscopeEventType.TRACE_SEARCH_FAILED; 272} 273 274export class TraceAddRequest extends WinscopeEvent { 275 override readonly type = WinscopeEventType.TRACE_ADD_REQUEST; 276 constructor(readonly trace: Trace<object>) { 277 super(); 278 } 279} 280 281export class TraceRemoveRequest extends WinscopeEvent { 282 override readonly type = WinscopeEventType.TRACE_REMOVE_REQUEST; 283 constructor(readonly trace: Trace<object>) { 284 super(); 285 } 286} 287 288export class InitializeTraceSearchRequest extends WinscopeEvent { 289 override readonly type = WinscopeEventType.INITIALIZE_TRACE_SEARCH_REQUEST; 290} 291 292export class TraceSearchInitialized extends WinscopeEvent { 293 override readonly type = WinscopeEventType.TRACE_SEARCH_INITIALIZED; 294 295 constructor(readonly views: string[]) { 296 super(); 297 } 298} 299 300export class TraceSearchCompleted extends WinscopeEvent { 301 override readonly type = WinscopeEventType.TRACE_SEARCH_COMPLETED; 302} 303