Create endpoints for tracing and stashing on Bridgeless Android ReactHost (#53416)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53416

# Changelog: [Internal]

Creates methods on Bridgeless Android Host for starting / stopping tracing and implements logic for storing the recording that will be transferred to `jsinspector-modern` stack via HostTargetDelegate when CDP session is created.

Reviewed By: sbuggay

Differential Revision: D79725161

fbshipit-source-id: f3e3b39f6d94a6548cf227394f7328f6913c33e4
This commit is contained in:
Ruslan Lesiutin
2025-08-22 04:12:22 -07:00
committed by Facebook GitHub Bot
parent 80f340e81c
commit 8d8245123e
3 changed files with 101 additions and 9 deletions
@@ -34,6 +34,12 @@ internal class ReactHostInspectorTarget(reactHostImpl: ReactHostImpl) :
external fun sendDebuggerResumeCommand()
external fun startBackgroundTrace(): Boolean
external fun stopAndStashBackgroundTrace()
external fun stopAndDiscardBackgroundTrace()
override fun addPerfMonitorListener(listener: PerfMonitorUpdateListener) {
perfMonitorListeners.add(listener)
}
@@ -80,15 +80,6 @@ void JReactHostInspectorTarget::sendDebuggerResumeCommand() {
}
}
void JReactHostInspectorTarget::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", JReactHostInspectorTarget::initHybrid),
makeNativeMethod(
"sendDebuggerResumeCommand",
JReactHostInspectorTarget::sendDebuggerResumeCommand),
});
}
jsinspector_modern::HostTargetMetadata
JReactHostInspectorTarget::getMetadata() {
jsinspector_modern::HostTargetMetadata metadata = {
@@ -157,4 +148,63 @@ HostTarget* JReactHostInspectorTarget::getInspectorTarget() {
return inspectorTarget_ ? inspectorTarget_.get() : nullptr;
}
bool JReactHostInspectorTarget::startBackgroundTrace() {
if (inspectorTarget_) {
return inspectorTarget_->startTracing(tracing::Mode::Background);
} else {
jni::throwNewJavaException(
"java/lang/IllegalStateException",
"Cannot start Tracing session while the Fusebox backend is not enabled.");
}
}
tracing::TraceRecordingState JReactHostInspectorTarget::stopTracing() {
if (inspectorTarget_) {
return inspectorTarget_->stopTracing();
} else {
jni::throwNewJavaException(
"java/lang/IllegalStateException",
"Cannot stop Tracing session while the Fusebox backend is not enabled.");
}
}
void JReactHostInspectorTarget::stopAndStashBackgroundTrace() {
auto capturedTrace = inspectorTarget_->stopTracing();
stashTraceRecordingState(std::move(capturedTrace));
}
void JReactHostInspectorTarget::stopAndDiscardBackgroundTrace() {
inspectorTarget_->stopTracing();
}
void JReactHostInspectorTarget::stashTraceRecordingState(
tracing::TraceRecordingState&& state) {
stashedTraceRecordingState_ = std::move(state);
}
std::optional<tracing::TraceRecordingState> JReactHostInspectorTarget::
unstable_getTraceRecordingThatWillBeEmittedOnInitialization() {
auto state = std::move(stashedTraceRecordingState_);
stashedTraceRecordingState_.reset();
return state;
}
void JReactHostInspectorTarget::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", JReactHostInspectorTarget::initHybrid),
makeNativeMethod(
"sendDebuggerResumeCommand",
JReactHostInspectorTarget::sendDebuggerResumeCommand),
makeNativeMethod(
"startBackgroundTrace",
JReactHostInspectorTarget::startBackgroundTrace),
makeNativeMethod(
"stopAndStashBackgroundTrace",
JReactHostInspectorTarget::stopAndStashBackgroundTrace),
makeNativeMethod(
"stopAndDiscardBackgroundTrace",
JReactHostInspectorTarget::stopAndDiscardBackgroundTrace),
});
}
} // namespace facebook::react
@@ -77,6 +77,22 @@ class JReactHostInspectorTarget
static void registerNatives();
void sendDebuggerResumeCommand();
/**
* Starts a background trace recording for this HostTarget.
*
* \return false if already tracing, true otherwise.
*/
bool startBackgroundTrace();
/**
* Stops previously started trace recording and stashes the captured trace,
* which will be emitted the next time CDP session is created.
*/
void stopAndStashBackgroundTrace();
/**
* Stops previously started trace recording and discards the captured trace.
*/
void stopAndDiscardBackgroundTrace();
jsinspector_modern::HostTarget* getInspectorTarget();
// HostTargetDelegate methods
@@ -90,6 +106,8 @@ class JReactHostInspectorTarget
const jsinspector_modern::LoadNetworkResourceRequest& params,
jsinspector_modern::ScopedExecutor<
jsinspector_modern::NetworkRequestListener> executor) override;
std::optional<jsinspector_modern::tracing::TraceRecordingState>
unstable_getTraceRecordingThatWillBeEmittedOnInitialization() override;
private:
JReactHostInspectorTarget(
@@ -106,6 +124,24 @@ class JReactHostInspectorTarget
std::shared_ptr<jsinspector_modern::HostTarget> inspectorTarget_;
std::optional<int> inspectorPageId_;
/**
* Stops previously started trace recording and returns the captured trace.
*/
jsinspector_modern::tracing::TraceRecordingState stopTracing();
/**
* Stashes previously recorded trace recording state that will be emitted when
* CDP session is created. Once emitted, the value will be cleared from this
* instance.
*/
void stashTraceRecordingState(
jsinspector_modern::tracing::TraceRecordingState&& state);
/**
* Previously recorded trace recording state that will be emitted when
* CDP session is created.
*/
std::optional<jsinspector_modern::tracing::TraceRecordingState>
stashedTraceRecordingState_;
friend HybridBase;
};
} // namespace facebook::react