Skip to content

Commit d05c282

Browse files
committed
feat: add React Native-only event for pre-enabling multiple layers of Tracing
1 parent 7dcbddd commit d05c282

File tree

9 files changed

+78
-0
lines changed

9 files changed

+78
-0
lines changed

front_end/core/sdk/ReactNativeApplicationModel.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,18 @@ export class ReactNativeApplicationModel extends SDKModel<EventTypes> implements
5151
this.metadataCached = metadata;
5252
this.dispatchEventToListeners(Events.METADATA_UPDATED, metadata);
5353
}
54+
55+
traceRequested(): void {
56+
this.dispatchEventToListeners(Events.TRACE_REQUESTED);
57+
}
5458
}
5559

5660
export const enum Events {
5761
METADATA_UPDATED = 'MetadataUpdated',
62+
TRACE_REQUESTED = 'TraceRequested',
5863
}
5964

6065
export interface EventTypes {
6166
[Events.METADATA_UPDATED]: Protocol.ReactNativeApplication.MetadataUpdatedEvent;
67+
[Events.TRACE_REQUESTED]: void;
6268
}

front_end/generated/InspectorBackendCommands.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

front_end/generated/protocol-mapping.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ export namespace ProtocolMapping {
1717
* device, application, and debugger integration.
1818
*/
1919
'ReactNativeApplication.metadataUpdated': [Protocol.ReactNativeApplication.MetadataUpdatedEvent];
20+
/**
21+
* Fired when React Native requests Chrome DevTools to prepare for displaying the captured Trace.
22+
*/
23+
'ReactNativeApplication.traceRequested': [];
2024
/**
2125
* The loadComplete event mirrors the load complete event sent by the browser to assistive
2226
* technology when the web page has finished loading.

front_end/generated/protocol-proxy-api.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ declare namespace ProtocolProxyApi {
255255
*/
256256
metadataUpdated(params: Protocol.ReactNativeApplication.MetadataUpdatedEvent): void;
257257

258+
/**
259+
* Fired when React Native requests Chrome DevTools to prepare for displaying the captured Trace.
260+
*/
261+
traceRequested(): void;
262+
258263
}
259264

260265
export interface AccessibilityApi {

front_end/models/trace/TracingManager.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ export class TracingManager extends SDK.SDKModel.SDKModel<void> {
9999
this.#finishing = true;
100100
void this.#tracingAgent.invoke_end();
101101
}
102+
103+
rnPrepareForTraceCapturedInBackground(client: TracingManagerClient): void {
104+
this.#activeClient = client;
105+
this.#finishing = true;
106+
}
102107
}
103108

104109
export interface TracingManagerClient {

front_end/panels/timeline/TimelineController.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,18 @@ export class TimelineController implements Trace.TracingManager.TracingManagerCl
202202
await LiveMetrics.LiveMetrics.instance().enable();
203203
}
204204

205+
async rnPrepareForTraceCapturedInBackground(): Promise<void> {
206+
await LiveMetrics.LiveMetrics.instance().disable();
207+
208+
if (this.tracingManager) {
209+
this.tracingManager.rnPrepareForTraceCapturedInBackground(this);
210+
}
211+
212+
this.client.loadingStarted();
213+
await this.allSourcesFinished();
214+
await LiveMetrics.LiveMetrics.instance().enable();
215+
}
216+
205217
private async fetchFieldData(): Promise<CrUXManager.PageResult[]|null> {
206218
const cruxManager = CrUXManager.CrUXManager.instance();
207219
if (!cruxManager.isEnabled() || !navigator.onLine) {

front_end/panels/timeline/TimelinePanel.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,19 @@ export class TimelinePanel extends UI.Panel.Panel implements Client, TimelineMod
700700
this.#showLandingPage();
701701
this.updateTimelineControls();
702702

703+
if (isReactNative) {
704+
SDK.TargetManager.TargetManager.instance().observeModels(
705+
SDK.ReactNativeApplicationModel.ReactNativeApplicationModel,
706+
{
707+
modelAdded: (model: SDK.ReactNativeApplicationModel.ReactNativeApplicationModel) => {
708+
model.addEventListener(
709+
SDK.ReactNativeApplicationModel.Events.TRACE_REQUESTED, () => this.rnPrepareForTraceCapturedInBackground());
710+
},
711+
modelRemoved: (_model: SDK.ReactNativeApplicationModel.ReactNativeApplicationModel) => {},
712+
},
713+
);
714+
}
715+
703716
SDK.TargetManager.TargetManager.instance().addEventListener(
704717
SDK.TargetManager.Events.SUSPEND_STATE_CHANGED, this.onSuspendStateChanged, this);
705718
const profilerModels = SDK.TargetManager.TargetManager.instance().models(SDK.CPUProfilerModel.CPUProfilerModel);
@@ -731,6 +744,31 @@ export class TimelinePanel extends UI.Panel.Panel implements Client, TimelineMod
731744
});
732745
}
733746

747+
private async rnPrepareForTraceCapturedInBackground(): Promise<void> {
748+
this.setUIControlsEnabled(false);
749+
750+
if (this.statusPane) {
751+
this.statusPane.finish();
752+
this.statusPane.updateStatus(i18nString(UIStrings.stoppingTimeline));
753+
this.statusPane.updateProgressBar(i18nString(UIStrings.received), 0);
754+
}
755+
this.setState(State.STOP_PENDING);
756+
757+
const rootTarget = SDK.TargetManager.TargetManager.instance().rootTarget();
758+
const primaryPageTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
759+
if (!primaryPageTarget) {
760+
throw new Error('Could not load primary page target.');
761+
}
762+
if (!rootTarget) {
763+
throw new Error('Could not load root target.');
764+
}
765+
766+
this.controller = new TimelineController(rootTarget, primaryPageTarget, this);
767+
await this.controller.rnPrepareForTraceCapturedInBackground();
768+
769+
this.setUIControlsEnabled(true);
770+
}
771+
734772
#setActiveInsight(insight: TimelineComponents.Sidebar.ActiveInsight|null): void {
735773
// When an insight is selected, ensure that the 3P checkbox is disabled
736774
// to avoid dimming interference.

third_party/blink/public/devtools_protocol/browser_protocol.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@
7171
"type": "boolean"
7272
}
7373
]
74+
},
75+
{
76+
"name": "traceRequested",
77+
"description": "Fired when React Native requests Chrome DevTools to prepare for displaying the captured Trace."
7478
}
7579
]
7680
},

third_party/blink/public/devtools_protocol/react_native_domains.pdl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ experimental domain ReactNativeApplication
3030
optional boolean unstable_isProfilingBuild
3131
# Enables the Network Panel.
3232
optional boolean unstable_networkInspectionEnabled
33+
34+
# Fired when React Native requests Chrome DevTools to prepare for displaying the captured Trace.
35+
event traceRequested

0 commit comments

Comments
 (0)