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