xref: /aosp_15_r20/development/tools/winscope/src/messaging/user_warnings.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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