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 {View, Viewer, ViewType} from 'viewers/viewer'; 22 23export enum WinscopeEventType { 24 APP_INITIALIZED, 25 APP_FILES_COLLECTED, 26 APP_FILES_UPLOADED, 27 APP_RESET_REQUEST, 28 APP_TRACE_VIEW_REQUEST, 29 APP_REFRESH_DUMPS_REQUEST, 30 REMOTE_TOOL_DOWNLOAD_START, 31 REMOTE_TOOL_FILES_RECEIVED, 32 REMOTE_TOOL_TIMESTAMP_RECEIVED, 33 TABBED_VIEW_SWITCHED, 34 TABBED_VIEW_SWITCH_REQUEST, 35 TRACE_POSITION_UPDATE, 36 VIEWERS_LOADED, 37 VIEWERS_UNLOADED, 38 EXPANDED_TIMELINE_TOGGLED, 39 ACTIVE_TRACE_CHANGED, 40 DARK_MODE_TOGGLED, 41} 42 43interface TypeMap { 44 [WinscopeEventType.APP_INITIALIZED]: AppInitialized; 45 [WinscopeEventType.APP_FILES_COLLECTED]: AppFilesCollected; 46 [WinscopeEventType.APP_FILES_UPLOADED]: AppFilesUploaded; 47 [WinscopeEventType.APP_RESET_REQUEST]: AppResetRequest; 48 [WinscopeEventType.APP_TRACE_VIEW_REQUEST]: AppTraceViewRequest; 49 [WinscopeEventType.APP_REFRESH_DUMPS_REQUEST]: AppRefreshDumpsRequest; 50 [WinscopeEventType.REMOTE_TOOL_DOWNLOAD_START]: RemoteToolDownloadStart; 51 [WinscopeEventType.REMOTE_TOOL_FILES_RECEIVED]: RemoteToolFilesReceived; 52 [WinscopeEventType.REMOTE_TOOL_TIMESTAMP_RECEIVED]: RemoteToolTimestampReceived; 53 [WinscopeEventType.TABBED_VIEW_SWITCHED]: TabbedViewSwitched; 54 [WinscopeEventType.TABBED_VIEW_SWITCH_REQUEST]: TabbedViewSwitchRequest; 55 [WinscopeEventType.TRACE_POSITION_UPDATE]: TracePositionUpdate; 56 [WinscopeEventType.VIEWERS_LOADED]: ViewersLoaded; 57 [WinscopeEventType.VIEWERS_UNLOADED]: ViewersUnloaded; 58 [WinscopeEventType.EXPANDED_TIMELINE_TOGGLED]: ExpandedTimelineToggled; 59 [WinscopeEventType.ACTIVE_TRACE_CHANGED]: ActiveTraceChanged; 60 [WinscopeEventType.DARK_MODE_TOGGLED]: DarkModeToggled; 61} 62 63export abstract class WinscopeEvent { 64 abstract readonly type: WinscopeEventType; 65 66 async visit<T extends WinscopeEventType>( 67 type: T, 68 callback: (event: TypeMap[T]) => Promise<void>, 69 ) { 70 if (this.type === type) { 71 const event = this as unknown as TypeMap[T]; 72 await callback(event); 73 } 74 } 75} 76 77export class AppInitialized extends WinscopeEvent { 78 override readonly type = WinscopeEventType.APP_INITIALIZED; 79} 80 81export class AppFilesCollected extends WinscopeEvent { 82 override readonly type = WinscopeEventType.APP_FILES_COLLECTED; 83 84 constructor(readonly files: File[]) { 85 super(); 86 } 87} 88 89export class AppFilesUploaded extends WinscopeEvent { 90 override readonly type = WinscopeEventType.APP_FILES_UPLOADED; 91 92 constructor(readonly files: File[]) { 93 super(); 94 } 95} 96 97export class AppResetRequest extends WinscopeEvent { 98 override readonly type = WinscopeEventType.APP_RESET_REQUEST; 99} 100 101export class AppTraceViewRequest extends WinscopeEvent { 102 override readonly type = WinscopeEventType.APP_TRACE_VIEW_REQUEST; 103} 104 105export class AppRefreshDumpsRequest extends WinscopeEvent { 106 override readonly type = WinscopeEventType.APP_REFRESH_DUMPS_REQUEST; 107} 108 109export class RemoteToolDownloadStart extends WinscopeEvent { 110 override readonly type = WinscopeEventType.REMOTE_TOOL_DOWNLOAD_START; 111} 112 113export class RemoteToolFilesReceived extends WinscopeEvent { 114 override readonly type = WinscopeEventType.REMOTE_TOOL_FILES_RECEIVED; 115 116 constructor( 117 readonly files: File[], 118 readonly deferredTimestamp?: () => Timestamp | undefined, 119 ) { 120 super(); 121 } 122} 123 124export class RemoteToolTimestampReceived extends WinscopeEvent { 125 override readonly type = WinscopeEventType.REMOTE_TOOL_TIMESTAMP_RECEIVED; 126 127 constructor(readonly deferredTimestamp: () => Timestamp | undefined) { 128 super(); 129 } 130} 131 132export class TabbedViewSwitched extends WinscopeEvent { 133 override readonly type = WinscopeEventType.TABBED_VIEW_SWITCHED; 134 readonly newFocusedView: View; 135 136 constructor(view: View) { 137 super(); 138 assertTrue(view.type === ViewType.TAB); 139 this.newFocusedView = view; 140 } 141} 142 143export class TabbedViewSwitchRequest extends WinscopeEvent { 144 override readonly type = WinscopeEventType.TABBED_VIEW_SWITCH_REQUEST; 145 146 readonly newActiveTrace: Trace<object>; 147 148 constructor(newActiveTrace: Trace<object>) { 149 super(); 150 this.newActiveTrace = newActiveTrace; 151 } 152} 153 154export class TracePositionUpdate extends WinscopeEvent { 155 override readonly type = WinscopeEventType.TRACE_POSITION_UPDATE; 156 readonly position: TracePosition; 157 readonly updateTimeline: boolean; 158 159 constructor(position: TracePosition, updateTimeline = false) { 160 super(); 161 this.position = position; 162 this.updateTimeline = updateTimeline; 163 } 164 165 static fromTimestamp( 166 timestamp: Timestamp, 167 updateTimeline = false, 168 ): TracePositionUpdate { 169 const position = TracePosition.fromTimestamp(timestamp); 170 return new TracePositionUpdate(position, updateTimeline); 171 } 172 173 static fromTraceEntry( 174 entry: TraceEntry<object>, 175 updateTimeline = false, 176 ): TracePositionUpdate { 177 const position = TracePosition.fromTraceEntry(entry); 178 return new TracePositionUpdate(position, updateTimeline); 179 } 180} 181 182export class ViewersLoaded extends WinscopeEvent { 183 override readonly type = WinscopeEventType.VIEWERS_LOADED; 184 185 constructor(readonly viewers: Viewer[]) { 186 super(); 187 } 188} 189 190export class ViewersUnloaded extends WinscopeEvent { 191 override readonly type = WinscopeEventType.VIEWERS_UNLOADED; 192} 193 194export class ExpandedTimelineToggled extends WinscopeEvent { 195 override readonly type = WinscopeEventType.EXPANDED_TIMELINE_TOGGLED; 196 constructor(readonly isTimelineExpanded: boolean) { 197 super(); 198 } 199} 200 201export class ActiveTraceChanged extends WinscopeEvent { 202 override readonly type = WinscopeEventType.ACTIVE_TRACE_CHANGED; 203 constructor(readonly trace: Trace<object>) { 204 super(); 205 } 206} 207 208export class DarkModeToggled extends WinscopeEvent { 209 override readonly type = WinscopeEventType.DARK_MODE_TOGGLED; 210 constructor(readonly isDarkMode: boolean) { 211 super(); 212 } 213} 214