Skip to content

Commit 5b2883b

Browse files
committed
Add a hook to get early access to trace object before loading
Perfetto plugins in host apps need to be able to access contextual information associated with the trace during loading of the trace and initialization of the plugin instance. This requires that a host app be able to associate information with the trace before the AppImpl's promise result from its various trace loading APIs is resolved at the completion of loading. Accordingly, add an optinoal call-back function parameter to the AppImpl load method implementations to provide this trace early access hook. For android-graphics/sokatoa#4633 Signed-off-by: Christian W. Damus <cdamus@eclipsesource.com>
1 parent 061c738 commit 5b2883b

File tree

2 files changed

+120
-15
lines changed

2 files changed

+120
-15
lines changed

ui/src/core/app_impl.ts

Lines changed: 111 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ import {CommandInvocation, CommandManagerImpl} from './command_manager';
3131
import {embedderContext} from './embedder';
3232
import {featureFlags} from './feature_flags';
3333
import {loadTrace} from './load_trace';
34-
import {HierarchicalOmniboxManager, OmniboxManagerImpl} from './omnibox_manager';
34+
import {
35+
HierarchicalOmniboxManager,
36+
OmniboxManagerImpl,
37+
} from './omnibox_manager';
3538
import {PageManagerImpl} from './page_manager';
3639
import {PerfManager} from './perf_manager';
3740
import {PluginManagerImpl} from './plugin_manager';
@@ -282,34 +285,128 @@ export class AppImpl implements App {
282285
};
283286
}
284287

285-
openTraceFromFile(file: File) {
286-
return this.openTrace({type: 'FILE', file});
288+
openTraceFromFile(file: File): Promise<TraceImpl>;
289+
openTraceFromFile(
290+
file: File,
291+
/**
292+
* An optional call-back to be notified of the identity of the new trace as soon as it is created
293+
* and before loading begins. Be careful how this is used: it may only be used for its identity
294+
* because it is in an uninitialized state and loading it may yet fail.
295+
*/
296+
onTraceCreated?: (newTrace: TraceImpl) => void,
297+
): Promise<TraceImpl>;
298+
openTraceFromFile(
299+
file: File,
300+
onTraceCreated?: (newTrace: TraceImpl) => void,
301+
) {
302+
return this.openTrace({type: 'FILE', file}, onTraceCreated);
287303
}
288304

289-
openTraceFromMultipleFiles(files: ReadonlyArray<File>) {
290-
return this.openTrace({type: 'MULTIPLE_FILES', files});
305+
openTraceFromMultipleFiles(files: ReadonlyArray<File>): Promise<TraceImpl>;
306+
openTraceFromMultipleFiles(
307+
files: ReadonlyArray<File>,
308+
/**
309+
* An optional call-back to be notified of the identity of the new trace as soon as it is created
310+
* and before loading begins. Be careful how this is used: it may only be used for its identity
311+
* because it is in an uninitialized state and loading it may yet fail.
312+
*/
313+
onTraceCreated?: (newTrace: TraceImpl) => void,
314+
): Promise<TraceImpl>;
315+
openTraceFromMultipleFiles(
316+
files: ReadonlyArray<File>,
317+
onTraceCreated?: (newTrace: TraceImpl) => void,
318+
) {
319+
return this.openTrace({type: 'MULTIPLE_FILES', files}, onTraceCreated);
291320
}
292321

293-
openTraceFromUrl(url: string, serializedAppState?: SerializedAppState) {
294-
return this.openTrace({type: 'URL', url, serializedAppState});
322+
openTraceFromUrl(
323+
url: string,
324+
serializedAppState?: SerializedAppState,
325+
): Promise<TraceImpl>;
326+
openTraceFromUrl(
327+
url: string,
328+
serializedAppState?: SerializedAppState,
329+
/**
330+
* An optional call-back to be notified of the identity of the new trace as soon as it is created
331+
* and before loading begins. Be careful how this is used: it may only be used for its identity
332+
* because it is in an uninitialized state and loading it may yet fail.
333+
*/
334+
onTraceCreated?: (newTrace: TraceImpl) => void,
335+
): Promise<TraceImpl>;
336+
openTraceFromUrl(
337+
url: string,
338+
serializedAppState?: SerializedAppState,
339+
onTraceCreated?: (newTrace: TraceImpl) => void,
340+
) {
341+
return this.openTrace(
342+
{type: 'URL', url, serializedAppState},
343+
onTraceCreated,
344+
);
295345
}
296346

297-
openTraceFromStream(stream: TraceStream) {
298-
return this.openTrace({type: 'STREAM', stream});
347+
openTraceFromStream(stream: TraceStream): Promise<TraceImpl>;
348+
openTraceFromStream(
349+
stream: TraceStream,
350+
/**
351+
* An optional call-back to be notified of the identity of the new trace as soon as it is created
352+
* and before loading begins. Be careful how this is used: it may only be used for its identity
353+
* because it is in an uninitialized state and loading it may yet fail.
354+
*/
355+
onTraceCreated?: (newTrace: TraceImpl) => void,
356+
): Promise<TraceImpl>;
357+
openTraceFromStream(
358+
stream: TraceStream,
359+
onTraceCreated?: (newTrace: TraceImpl) => void,
360+
) {
361+
return this.openTrace({type: 'STREAM', stream}, onTraceCreated);
299362
}
300363

301364
openTraceFromBuffer(
302365
args: OpenTraceArrayBufArgs,
303366
serializedAppState?: SerializedAppState,
367+
): Promise<TraceImpl>;
368+
openTraceFromBuffer(
369+
args: OpenTraceArrayBufArgs,
370+
serializedAppState?: SerializedAppState,
371+
/**
372+
* An optional call-back to be notified of the identity of the new trace as soon as it is created
373+
* and before loading begins. Be careful how this is used: it may only be used for its identity
374+
* because it is in an uninitialized state and loading it may yet fail.
375+
*/
376+
onTraceCreated?: (newTrace: TraceImpl) => void,
377+
): Promise<TraceImpl>;
378+
openTraceFromBuffer(
379+
args: OpenTraceArrayBufArgs,
380+
serializedAppState?: SerializedAppState,
381+
onTraceCreated?: (newTrace: TraceImpl) => void,
304382
) {
305-
return this.openTrace({...args, type: 'ARRAY_BUFFER', serializedAppState});
383+
return this.openTrace(
384+
{...args, type: 'ARRAY_BUFFER', serializedAppState},
385+
onTraceCreated,
386+
);
306387
}
307388

308-
openTraceFromHttpRpc(port?: string) {
309-
return this.openTrace({type: 'HTTP_RPC', port});
389+
openTraceFromHttpRpc(port?: string): Promise<TraceImpl>;
390+
openTraceFromHttpRpc(
391+
port?: string,
392+
/**
393+
* An optional call-back to be notified of the identity of the new trace as soon as it is created
394+
* and before loading begins. Be careful how this is used: it may only be used for its identity
395+
* because it is in an uninitialized state and loading it may yet fail.
396+
*/
397+
onTraceCreated?: (newTrace: TraceImpl) => void,
398+
): Promise<TraceImpl>;
399+
openTraceFromHttpRpc(
400+
port?: string,
401+
onTraceCreated?: (newTrace: TraceImpl) => void,
402+
) {
403+
return this.openTrace({type: 'HTTP_RPC', port}, onTraceCreated);
310404
}
311405

312-
private async openTrace(src: TraceSource): Promise<TraceImpl> {
406+
private async openTrace(
407+
src: TraceSource,
408+
onTraceCreated?: (newTrace: TraceImpl) => void,
409+
): Promise<TraceImpl> {
313410
if (src.type === 'ARRAY_BUFFER' && src.buffer instanceof Uint8Array) {
314411
// Even though the type of `buffer` is ArrayBuffer, it's possible to
315412
// accidentally pass a Uint8Array here, because the interface of
@@ -351,7 +448,7 @@ export class AppImpl implements App {
351448
// - Call AppImpl.setActiveTrace(TraceImpl)
352449
// - Continue with the trace loading logic (track decider, plugins, etc)
353450
// - Resolve the promise when everything is done.
354-
const trace = await loadTrace(this, src);
451+
const trace = await loadTrace(this, src, onTraceCreated);
355452
this.omnibox.childFor(src).reset(/* focus= */ false);
356453
// loadTrace() internally will call setActiveTrace() and change our
357454
// _currentTrace in the middle of its execution. We cannot wait for

ui/src/core/load_trace.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,17 @@ let lastEngineId = 0;
127127
export async function loadTrace(
128128
app: AppImpl,
129129
traceSource: TraceSource,
130+
/**
131+
* An optional call-back to be notified of the identity of the new trace as soon as it is created
132+
* and before loading begins. Be careful how this is used: it may only be used for its identity
133+
* because it is in an uninitialized state and loading it may yet fail.
134+
*/
135+
onTraceCreated?: (newTrace: TraceImpl) => void,
130136
): Promise<TraceImpl> {
131137
updateStatus(traceSource, app, 'Opening trace');
132138
const engineId = `${++lastEngineId}`;
133139
const engine = await createEngine(app, engineId, traceSource);
134-
return await loadTraceIntoEngine(app, traceSource, engine);
140+
return await loadTraceIntoEngine(app, traceSource, engine, onTraceCreated);
135141
}
136142

137143
async function createEngine(
@@ -183,6 +189,7 @@ async function loadTraceIntoEngine(
183189
app: AppImpl,
184190
traceSource: TraceSource,
185191
engine: EngineBase,
192+
onTraceCreated?: (newTrace: TraceImpl) => void,
186193
): Promise<TraceImpl> {
187194
let traceStream: TraceStream | undefined;
188195
let serializedAppState = traceSource.serializedAppState;
@@ -238,6 +245,7 @@ async function loadTraceIntoEngine(
238245

239246
const traceDetails = await getTraceInfo(engine, app, traceSource);
240247
const trace = new TraceImpl(app, engine, traceDetails);
248+
onTraceCreated?.(trace);
241249
app.setActiveTrace(trace);
242250

243251
const visibleTimeSpan = await computeVisibleTime(

0 commit comments

Comments
 (0)