Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,18 @@ class HostAgent::Impl final {
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
SessionState& sessionState,
VoidExecutor executor)
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
: frontendChannel_(frontendChannel),
targetController_(targetController),
hostMetadata_(std::move(hostMetadata)),
sessionState_(sessionState),
networkIOAgent_(NetworkIOAgent(frontendChannel, std::move(executor))),
tracingAgent_(
TracingAgent(frontendChannel, sessionState, targetController)) {}
tracingAgent_(TracingAgent(
frontendChannel,
sessionState,
targetController,
std::move(traceRecordingToEmit))) {}

~Impl() {
if (isPausedInDebuggerOverlayVisible_) {
Expand Down Expand Up @@ -428,7 +432,8 @@ class HostAgent::Impl final {
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
SessionState& sessionState,
VoidExecutor executor) {}
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit) {}

void handleRequest(const cdp::PreparsedRequest& req) {}
void setCurrentInstanceAgent(std::shared_ptr<InstanceAgent> agent) {}
Expand All @@ -441,14 +446,16 @@ HostAgent::HostAgent(
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
SessionState& sessionState,
VoidExecutor executor)
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
: impl_(std::make_unique<Impl>(
*this,
frontendChannel,
targetController,
std::move(hostMetadata),
sessionState,
std::move(executor))) {}
std::move(executor),
std::move(traceRecordingToEmit))) {}

HostAgent::~HostAgent() = default;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@ class HostAgent final {
* \param hostMetadata Metadata about the host that created this agent.
* \param sessionState The state of the session that created this agent.
* \param executor A void executor to be used by async-aware handlers.
* \param traceRecordingToEmit If set, this is the trace that Host has
* requested to display in the Frontend.
*/
HostAgent(
const FrontendChannel& frontendChannel,
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
SessionState& sessionState,
VoidExecutor executor);
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit);

HostAgent(const HostAgent&) = delete;
HostAgent(HostAgent&&) = delete;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class HostTargetSession {
std::unique_ptr<IRemoteConnection> remote,
HostTargetController& targetController,
HostTargetMetadata hostMetadata,
VoidExecutor executor)
VoidExecutor executor,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
: remote_(std::make_shared<RAIIRemoteConnection>(std::move(remote))),
frontendChannel_(
[remoteWeak = std::weak_ptr(remote_)](std::string_view message) {
Expand All @@ -47,7 +48,8 @@ class HostTargetSession {
targetController,
std::move(hostMetadata),
state_,
std::move(executor)) {}
std::move(executor),
std::move(traceRecordingToEmit)) {}

/**
* Called by CallbackLocalConnection to send a message to this Session's
Expand Down Expand Up @@ -206,7 +208,8 @@ std::unique_ptr<ILocalConnection> HostTarget::connect(
std::move(connectionToFrontend),
controller_,
delegate_.getMetadata(),
makeVoidExecutor(executorFromThis()));
makeVoidExecutor(executorFromThis()),
delegate_.unstable_getTraceRecordingThatWillBeEmittedOnInitialization());
session->setCurrentInstance(currentInstance_.get());
sessions_.insert(std::weak_ptr(session));
return std::make_unique<CallbackLocalConnection>(
Expand Down
13 changes: 13 additions & 0 deletions packages/react-native/ReactCommon/jsinspector-modern/HostTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@ class HostTargetDelegate : public LoadNetworkResourceDelegate {
throw NotImplementedException(
"LoadNetworkResourceDelegate.loadNetworkResource is not implemented by this host target delegate.");
}

/**
* [Experimental] Will be called at the CDP session initialization to get the
* trace recording that may have been stashed by the Host from the previous
* background session.
*
* \return the trace recording state if there is one that needs to be
* displayed, otherwise std::nullopt.
*/
virtual std::optional<tracing::TraceRecordingState>
unstable_getTraceRecordingThatWillBeEmittedOnInitialization() {
return std::nullopt;
}
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,17 @@ const uint16_t PROFILE_TRACE_EVENT_CHUNK_SIZE = 1;
TracingAgent::TracingAgent(
FrontendChannel frontendChannel,
SessionState& sessionState,
HostTargetController& hostTargetController)
HostTargetController& hostTargetController,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit)
: frontendChannel_(std::move(frontendChannel)),
sessionState_(sessionState),
hostTargetController_(hostTargetController) {}
hostTargetController_(hostTargetController) {
if (traceRecordingToEmit.has_value()) {
frontendChannel_(
cdp::jsonNotification("ReactNativeApplication.traceRequested"));
emitTraceRecording(std::move(traceRecordingToEmit.value()));
}
}

TracingAgent::~TracingAgent() {
// Agents are owned by the session. If the agent is destroyed, it means that
Expand Down Expand Up @@ -86,25 +93,29 @@ bool TracingAgent::handleRequest(const cdp::PreparsedRequest& req) {
// Send response to Tracing.end request.
frontendChannel_(cdp::jsonResult(req.id));

auto dataCollectedCallback = [this](folly::dynamic&& eventsChunk) {
frontendChannel_(cdp::jsonNotification(
"Tracing.dataCollected",
folly::dynamic::object("value", std::move(eventsChunk))));
};
tracing::TraceRecordingStateSerializer::emitAsDataCollectedChunks(
std::move(state),
dataCollectedCallback,
TRACE_EVENT_CHUNK_SIZE,
PROFILE_TRACE_EVENT_CHUNK_SIZE);

frontendChannel_(cdp::jsonNotification(
"Tracing.tracingComplete",
folly::dynamic::object("dataLossOccurred", false)));

emitTraceRecording(std::move(state));
return true;
}

return false;
}

void TracingAgent::emitTraceRecording(
tracing::TraceRecordingState state) const {
auto dataCollectedCallback = [this](folly::dynamic&& eventsChunk) {
frontendChannel_(cdp::jsonNotification(
"Tracing.dataCollected",
folly::dynamic::object("value", std::move(eventsChunk))));
};
tracing::TraceRecordingStateSerializer::emitAsDataCollectedChunks(
std::move(state),
dataCollectedCallback,
TRACE_EVENT_CHUNK_SIZE,
PROFILE_TRACE_EVENT_CHUNK_SIZE);

frontendChannel_(cdp::jsonNotification(
"Tracing.tracingComplete",
folly::dynamic::object("dataLossOccurred", false)));
}

} // namespace facebook::react::jsinspector_modern
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ class TracingAgent {
/**
* \param frontendChannel A channel used to send responses to the
* frontend.
* \param sessionState The state of the session that created this agent.
* \param hostTargetController An interface to the HostTarget that this agent
* is attached to. The caller is responsible for ensuring that the
* HostTargetDelegate and underlying HostTarget both outlive the agent.
* \param traceRecordingToEmit If set, this is the trace that Host has
* requested to display in the Frontend.
*/
TracingAgent(
FrontendChannel frontendChannel,
SessionState& sessionState,
HostTargetController& hostTargetController);
HostTargetController& hostTargetController,
std::optional<tracing::TraceRecordingState> traceRecordingToEmit);

~TracingAgent();

Expand All @@ -48,6 +55,12 @@ class TracingAgent {
SessionState& sessionState_;

HostTargetController& hostTargetController_;

/**
* Emits the captured Trace Recording state in a series of
* Tracing.dataCollected events, followed by a Tracing.tracingComplete event.
*/
void emitTraceRecording(tracing::TraceRecordingState state) const;
};

} // namespace facebook::react::jsinspector_modern
Loading