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 {TimeRange} from 'common/time'; 18import {TimeDuration} from 'common/time_duration'; 19import {TRACE_INFO} from 'trace/trace_info'; 20import {TraceType} from 'trace/trace_type'; 21import {UserWarning} from './user_warning'; 22 23export class CorruptedArchive extends UserWarning { 24 constructor(private readonly file: File) { 25 super(); 26 } 27 28 getDescriptor(): string { 29 return 'corrupted archive'; 30 } 31 32 getMessage(): string { 33 return `${this.file.name}: corrupted archive`; 34 } 35} 36 37export class NoValidFiles extends UserWarning { 38 constructor(private traces?: string[]) { 39 super(); 40 } 41 getDescriptor(): string { 42 return 'no valid files'; 43 } 44 45 getMessage(): string { 46 return ( 47 'No valid trace files found' + 48 (this.traces ? ` for ${this.traces.join(', ')}` : '') 49 ); 50 } 51} 52 53export class TraceHasOldData extends UserWarning { 54 constructor( 55 private readonly descriptor: string, 56 private readonly timeGap?: TimeRange, 57 ) { 58 super(); 59 } 60 61 getDescriptor(): string { 62 return 'old trace'; 63 } 64 65 getMessage(): string { 66 const elapsedTime = this.timeGap 67 ? new TimeDuration( 68 this.timeGap.to.getValueNs() - this.timeGap.from.getValueNs(), 69 ) 70 : undefined; 71 return ( 72 `${this.descriptor}: discarded because data is old` + 73 (this.timeGap ? `er than ${elapsedTime?.format()}` : '') 74 ); 75 } 76} 77 78export class TraceOverridden extends UserWarning { 79 constructor( 80 private readonly descriptor: string, 81 private readonly overridingType?: TraceType, 82 ) { 83 super(); 84 } 85 86 getDescriptor(): string { 87 return 'trace overridden'; 88 } 89 90 getMessage(): string { 91 if (this.overridingType !== undefined) { 92 return `${this.descriptor}: overridden by another trace of type ${ 93 TraceType[this.overridingType] 94 }`; 95 } 96 return `${this.descriptor}: overridden by another trace of same type`; 97 } 98} 99 100export class UnsupportedFileFormat extends UserWarning { 101 constructor(private readonly descriptor: string) { 102 super(); 103 } 104 105 getDescriptor(): string { 106 return 'unsupported format'; 107 } 108 109 getMessage(): string { 110 return `${this.descriptor}: unsupported format`; 111 } 112} 113 114export class InvalidLegacyTrace extends UserWarning { 115 constructor( 116 private readonly descriptor: string, 117 private readonly errorMessage: string, 118 ) { 119 super(); 120 } 121 122 getDescriptor(): string { 123 return 'invalid legacy trace'; 124 } 125 126 getMessage(): string { 127 return `${this.descriptor}: ${this.errorMessage}`; 128 } 129} 130 131export class InvalidPerfettoTrace extends UserWarning { 132 constructor( 133 private readonly descriptor: string, 134 private readonly errorMessages: string[], 135 ) { 136 super(); 137 } 138 139 getDescriptor(): string { 140 return 'invalid perfetto trace'; 141 } 142 143 getMessage(): string { 144 return `${this.descriptor}: ${this.errorMessages.join(', ')}`; 145 } 146} 147 148export class FailedToCreateTracesParser extends UserWarning { 149 constructor( 150 private readonly traceType: TraceType, 151 private readonly errorMessage: string, 152 ) { 153 super(); 154 } 155 156 getDescriptor(): string { 157 return 'failed to create traces parser'; 158 } 159 160 getMessage(): string { 161 return `Failed to create ${TRACE_INFO[this.traceType].name} parser: ${ 162 this.errorMessage 163 }`; 164 } 165} 166 167export class CannotVisualizeTraceEntry extends UserWarning { 168 constructor(private readonly errorMessage: string) { 169 super(); 170 } 171 172 getDescriptor(): string { 173 return 'cannot visualize trace entry'; 174 } 175 176 getMessage(): string { 177 return this.errorMessage; 178 } 179} 180 181export class FailedToInitializeTimelineData extends UserWarning { 182 getDescriptor(): string { 183 return 'failed to initialize timeline data'; 184 } 185 186 getMessage(): string { 187 return 'Cannot visualize all traces: Failed to initialize timeline data.\nTry removing some traces.'; 188 } 189} 190 191export class IncompleteFrameMapping extends UserWarning { 192 constructor(private readonly errorMessage: string) { 193 super(); 194 } 195 196 getDescriptor(): string { 197 return 'incomplete frame mapping'; 198 } 199 200 getMessage(): string { 201 return `Error occurred in frame mapping: ${this.errorMessage}`; 202 } 203} 204 205export class NoTraceTargetsSelected extends UserWarning { 206 getDescriptor(): string { 207 return 'No trace targets selected'; 208 } 209 210 getMessage(): string { 211 return 'No trace targets selected.'; 212 } 213} 214 215export class MissingVsyncId extends UserWarning { 216 constructor(private readonly tableName: string) { 217 super(); 218 } 219 220 getDescriptor(): string { 221 return 'missing vsync id'; 222 } 223 224 getMessage(): string { 225 return `missing vsync_id value for one or more entries in ${this.tableName}`; 226 } 227} 228 229export class ProxyTraceTimeout extends UserWarning { 230 getDescriptor(): string { 231 return 'proxy trace timeout'; 232 } 233 234 getMessage(): string { 235 return 'Errors occurred during tracing: trace timed out'; 236 } 237} 238 239export class ProxyTracingWarnings extends UserWarning { 240 constructor(private readonly warnings: string[]) { 241 super(); 242 } 243 244 getDescriptor(): string { 245 return 'proxy tracing warnings'; 246 } 247 248 getMessage(): string { 249 return `Trace collection warning: ${this.warnings.join(', ')}`; 250 } 251} 252 253export class ProxyTracingErrors extends UserWarning { 254 constructor(private readonly errorMessages: string[]) { 255 super(); 256 } 257 258 getDescriptor(): string { 259 return 'proxy tracing errors'; 260 } 261 262 getMessage(): string { 263 return `Trace collection errors: ${this.errorMessages.join(', ')}`; 264 } 265} 266 267export class MissingLayerIds extends UserWarning { 268 getDescriptor(): string { 269 return 'missing layer ids'; 270 } 271 272 getMessage(): string { 273 return 'Cannot parse some layers due to null or undefined layer id'; 274 } 275} 276 277export class DuplicateLayerIds extends UserWarning { 278 constructor(private readonly layerIds: number[]) { 279 super(); 280 } 281 282 getDescriptor(): string { 283 return 'duplicate layer id'; 284 } 285 286 getMessage(): string { 287 const optionalPlural = this.layerIds.length > 1 ? 's' : ''; 288 const layerIds = this.layerIds.join(', '); 289 return `Duplicate SF layer id${optionalPlural} ${layerIds} found - adding as "Duplicate" to the hierarchy`; 290 } 291} 292 293export class MonotonicScreenRecording extends UserWarning { 294 getDescriptor(): string { 295 return 'monotonic screen recording'; 296 } 297 298 getMessage(): string { 299 return `Screen recording may not be synchronized with the 300 other traces. Metadata contains monotonic time instead of elapsed.`; 301 } 302} 303 304export class CannotParseAllTransitions extends UserWarning { 305 getDescriptor(): string { 306 return 'cannot parse all transitions'; 307 } 308 309 getMessage(): string { 310 return 'Cannot parse all transitions. Some may be missing in Transitions viewer.'; 311 } 312} 313 314export class TraceSearchQueryFailed extends UserWarning { 315 constructor(private readonly errorMessage: string) { 316 super(); 317 } 318 319 getDescriptor(): string { 320 return 'trace search query failed'; 321 } 322 323 getMessage(): string { 324 return `Search query failed: ${this.errorMessage}`; 325 } 326} 327