PageTarget → HostTarget (#43113)

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

Changelog: [Internal]

Renames the "Page" concept in the modern CDP backend to "Host". Now all the Target types we have are named consistently after React Native concepts (ReactHost, ReactInstance, JSI Runtime) rather than CDP/browser concepts (Page).

Reviewed By: robhogan

Differential Revision: D53945333

fbshipit-source-id: 90e8b914ba8b4927806cbdd072ca36c78fd2093f
This commit is contained in:
Moti Zilberman
2024-02-20 10:39:44 -08:00
committed by Facebook GitHub Bot
parent d6bf51cad9
commit e9351f0f8a
27 changed files with 190 additions and 190 deletions
@@ -74,11 +74,11 @@ RCT_EXTERN void RCTRegisterModule(Class);
@property (nonatomic, strong, readonly) RCTModuleRegistry *moduleRegistry;
/**
* The page target for this bridge, if one has been created. Exposed for RCTCxxBridge only.
* The HostTarget for this bridge, if one has been created. Exposed for RCTCxxBridge only.
*/
@property (nonatomic, assign, readonly)
#ifdef __cplusplus
facebook::react::jsinspector_modern::PageTarget *
facebook::react::jsinspector_modern::HostTarget *
#else
// The inspector infrastructure cannot be used in C code.
void *
@@ -188,9 +188,9 @@ void RCTUIManagerSetDispatchAccessibilityManagerInitOntoMain(BOOL enabled)
kDispatchAccessibilityManagerInitOntoMain = enabled;
}
class RCTBridgePageTargetDelegate : public facebook::react::jsinspector_modern::PageTargetDelegate {
class RCTBridgeHostTargetDelegate : public facebook::react::jsinspector_modern::HostTargetDelegate {
public:
RCTBridgePageTargetDelegate(RCTBridge *bridge) : bridge_(bridge) {}
RCTBridgeHostTargetDelegate(RCTBridge *bridge) : bridge_(bridge) {}
void onReload(const PageReloadRequest &request) override
{
@@ -208,8 +208,8 @@ class RCTBridgePageTargetDelegate : public facebook::react::jsinspector_modern::
@implementation RCTBridge {
NSURL *_delegateBundleURL;
std::unique_ptr<RCTBridgePageTargetDelegate> _inspectorPageDelegate;
std::shared_ptr<facebook::react::jsinspector_modern::PageTarget> _inspectorTarget;
std::unique_ptr<RCTBridgeHostTargetDelegate> _inspectorHostDelegate;
std::shared_ptr<facebook::react::jsinspector_modern::HostTarget> _inspectorTarget;
std::optional<int> _inspectorPageId;
}
@@ -259,7 +259,7 @@ static RCTBridge *RCTCurrentBridgeInstance = nil;
_bundleURL = bundleURL;
_moduleProvider = block;
_launchOptions = [launchOptions copy];
_inspectorPageDelegate = std::make_unique<RCTBridgePageTargetDelegate>(self);
_inspectorHostDelegate = std::make_unique<RCTBridgeHostTargetDelegate>(self);
[self setUp];
}
@@ -413,7 +413,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
auto &inspectorFlags = facebook::react::jsinspector_modern::InspectorFlags::getInstance();
if (inspectorFlags.getEnableModernCDPRegistry() && !_inspectorPageId.has_value()) {
_inspectorTarget =
facebook::react::jsinspector_modern::PageTarget::create(*_inspectorPageDelegate, [](auto callback) {
facebook::react::jsinspector_modern::HostTarget::create(*_inspectorHostDelegate, [](auto callback) {
RCTExecuteOnMainQueue(^{
callback();
});
@@ -526,7 +526,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
[self.batchedBridge registerSegmentWithId:segmentId path:path];
}
- (facebook::react::jsinspector_modern::PageTarget *)inspectorTarget
- (facebook::react::jsinspector_modern::HostTarget *)inspectorTarget
{
return _inspectorTarget.get();
}
@@ -437,7 +437,7 @@ struct RCTInstanceCallback : public InstanceCallback {
// pointer into a member of RCTBridge! But we only use it while _reactInstance exists, meaning we
// haven't been invalidated, and therefore RCTBridge hasn't been deallocated yet.
RCTAssertMainQueue();
facebook::react::jsinspector_modern::PageTarget *parentInspectorTarget = _parentBridge.inspectorTarget;
facebook::react::jsinspector_modern::HostTarget *parentInspectorTarget = _parentBridge.inspectorTarget;
// Dispatch the instance initialization as soon as the initial module metadata has
// been collected (see initModules)
@@ -658,7 +658,7 @@ struct RCTInstanceCallback : public InstanceCallback {
}
- (void)_initializeBridge:(std::shared_ptr<JSExecutorFactory>)executorFactory
parentInspectorTarget:(facebook::react::jsinspector_modern::PageTarget *)parentInspectorTarget
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
{
if (!self.valid) {
return;
@@ -691,7 +691,7 @@ struct RCTInstanceCallback : public InstanceCallback {
}
- (void)_initializeBridgeLocked:(std::shared_ptr<JSExecutorFactory>)executorFactory
parentInspectorTarget:(facebook::react::jsinspector_modern::PageTarget *)parentInspectorTarget
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
{
std::lock_guard<std::mutex> guard(_moduleRegistryLock);
@@ -54,7 +54,7 @@ void Instance::initializeBridge(
std::shared_ptr<JSExecutorFactory> jsef,
std::shared_ptr<MessageQueueThread> jsQueue,
std::shared_ptr<ModuleRegistry> moduleRegistry,
jsinspector_modern::PageTarget* parentInspectorTarget) {
jsinspector_modern::HostTarget* parentInspectorTarget) {
callback_ = std::move(callback);
moduleRegistry_ = std::move(moduleRegistry);
parentInspectorTarget_ = parentInspectorTarget;
@@ -47,7 +47,7 @@ class RN_EXPORT Instance : private jsinspector_modern::InstanceTargetDelegate {
std::shared_ptr<JSExecutorFactory> jsef,
std::shared_ptr<MessageQueueThread> jsQueue,
std::shared_ptr<ModuleRegistry> moduleRegistry,
jsinspector_modern::PageTarget* inspectorTarget = nullptr);
jsinspector_modern::HostTarget* inspectorTarget = nullptr);
void initializeRuntime();
@@ -178,7 +178,7 @@ class RN_EXPORT Instance : private jsinspector_modern::InstanceTargetDelegate {
std::shared_ptr<JSCallInvoker> jsCallInvoker_ =
std::make_shared<JSCallInvoker>();
jsinspector_modern::PageTarget* parentInspectorTarget_{nullptr};
jsinspector_modern::HostTarget* parentInspectorTarget_{nullptr};
jsinspector_modern::InstanceTarget* inspectorTarget_{nullptr};
jsinspector_modern::RuntimeTarget* runtimeInspectorTarget_{nullptr};
};
@@ -102,7 +102,7 @@ class HermesRuntimeAgentDelegate::Impl final : public RuntimeAgentDelegate {
* \param executionContextDescription A description of the execution context
* represented by this runtime. This is used for disambiguating the
* source/destination of CDP messages when there are multiple runtimes
* (concurrently or over the life of a Page).
* (concurrently or over the life of a Host).
* \param runtime The HermesRuntime that this agent is attached to.
* \param runtimeExecutor A callback for scheduling work on the JS thread.
* \c runtimeExecutor may drop scheduled work if the runtime is destroyed
@@ -155,7 +155,7 @@ class HermesRuntimeAgentDelegate::Impl final : public RuntimeAgentDelegate {
// TODO: Change to string::starts_with when we're on C++20.
if (req.method.rfind("Log.", 0) == 0) {
// Since we know Hermes doesn't do anything useful with Log messages, but
// our containing PageAgent will, just bail out early.
// our containing HostAgent will, just bail out early.
// TODO: We need a way to negotiate this more dynamically with Hermes
// through the API.
return false;
@@ -33,7 +33,7 @@ class HermesRuntimeAgentDelegate : public RuntimeAgentDelegate {
* \param executionContextDescription A description of the execution context
* represented by this runtime. This is used for disambiguating the
* source/destination of CDP messages when there are multiple runtimes
* (concurrently or over the life of a Page).
* (concurrently or over the life of a Host).
* \param runtime The HermesRuntime that this agent is attached to.
* \param runtimeExecutor A callback for scheduling work on the JS thread.
* \c runtimeExecutor may drop scheduled work if the runtime is destroyed
@@ -8,11 +8,11 @@ A debuggable entity that a debugger frontend can connect to.
### Target Delegate
An interface between a Target class and the underlying debuggable entity. For example, PageTargetDelegate is used by PageTarget to send page-related events to the native platform implementation.
An interface between a Target class and the underlying debuggable entity. For example, HostTargetDelegate is used by HostTarget to send host-related events to the native platform implementation.
### Target Controller
A private interface exposed by a Target class to its Sessions/Agents. For example, PageTargetController is used by PageAgent to safely access the page's PageTargetDelegate, without exposing PageTarget's other private state.
A private interface exposed by a Target class to its Sessions/Agents. For example, HostTargetController is used by HostAgent to safely access the host's HostTargetDelegate, without exposing HostTarget's other private state.
### Session
@@ -7,9 +7,9 @@
#include <folly/dynamic.h>
#include <folly/json.h>
#include <jsinspector-modern/HostAgent.h>
#include <jsinspector-modern/HostTarget.h>
#include <jsinspector-modern/InstanceAgent.h>
#include <jsinspector-modern/PageAgent.h>
#include <jsinspector-modern/PageTarget.h>
#include <chrono>
@@ -27,19 +27,19 @@ namespace facebook::react::jsinspector_modern {
static constexpr auto kModernCDPBackendNotice =
ANSI_COLOR_BG_YELLOW ANSI_WEIGHT_BOLD
"NOTE:" ANSI_WEIGHT_RESET " You are using the " ANSI_STYLE_ITALIC
"modern" ANSI_STYLE_RESET " CDP backend for React Native (PageTarget)."sv;
"modern" ANSI_STYLE_RESET " CDP backend for React Native (HostTarget)."sv;
PageAgent::PageAgent(
HostAgent::HostAgent(
FrontendChannel frontendChannel,
PageTargetController& targetController,
PageTarget::SessionMetadata sessionMetadata,
HostTargetController& targetController,
HostTarget::SessionMetadata sessionMetadata,
SessionState& sessionState)
: frontendChannel_(frontendChannel),
targetController_(targetController),
sessionMetadata_(std::move(sessionMetadata)),
sessionState_(sessionState) {}
void PageAgent::handleRequest(const cdp::PreparsedRequest& req) {
void HostAgent::handleRequest(const cdp::PreparsedRequest& req) {
bool shouldSendOKResponse = false;
bool isFinishedHandlingRequest = false;
@@ -113,7 +113,7 @@ void PageAgent::handleRequest(const cdp::PreparsedRequest& req) {
frontendChannel_(json);
}
void PageAgent::sendInfoLogEntry(std::string_view text) {
void HostAgent::sendInfoLogEntry(std::string_view text) {
frontendChannel_(
folly::toJson(folly::dynamic::object("method", "Log.entryAdded")(
"params",
@@ -127,7 +127,7 @@ void PageAgent::sendInfoLogEntry(std::string_view text) {
"level", "info")("text", text)))));
}
void PageAgent::setCurrentInstanceAgent(
void HostAgent::setCurrentInstanceAgent(
std::shared_ptr<InstanceAgent> instanceAgent) {
auto previousInstanceAgent = std::move(instanceAgent_);
instanceAgent_ = std::move(instanceAgent);
@@ -7,7 +7,7 @@
#pragma once
#include "PageTarget.h"
#include "HostTarget.h"
#include "SessionState.h"
#include <jsinspector-modern/InspectorInterfaces.h>
@@ -19,32 +19,32 @@
namespace facebook::react::jsinspector_modern {
class PageTarget;
class HostTarget;
class InstanceAgent;
class InstanceTarget;
/**
* An Agent that handles requests from the Chrome DevTools Protocol for the
* given page.
* given Host.
* The constructor, destructor and all public methods must be called on the
* same thread, which is also the thread where the associated PageTarget is
* same thread, which is also the thread where the associated HostTarget is
* constructed and managed.
*/
class PageAgent final {
class HostAgent final {
public:
/**
* \param frontendChannel A channel used to send responses and events to the
* frontend.
* \param targetController An interface to the PageTarget that this agent is
* \param targetController An interface to the HostTarget that this agent is
* attached to. The caller is responsible for ensuring that the
* PageTargetDelegate and underlying PageTarget both outlive the agent.
* HostTargetDelegate and underlying HostTarget both outlive the agent.
* \param sessionMetadata Metadata about the session that created this agent.
* \param sessionState The state of the session that created this agent.
*/
PageAgent(
HostAgent(
FrontendChannel frontendChannel,
PageTargetController& targetController,
PageTarget::SessionMetadata sessionMetadata,
HostTargetController& targetController,
HostTarget::SessionMetadata sessionMetadata,
SessionState& sessionState);
/**
@@ -70,13 +70,13 @@ class PageAgent final {
* DevTools, the message will appear in the Console tab along with regular
* console messages. The difference between Log.entryAdded and
* Runtime.consoleAPICalled is that the latter requires an execution context
* ID, which does not exist at the Page level.
* ID, which does not exist at the Host level.
*/
void sendInfoLogEntry(std::string_view text);
FrontendChannel frontendChannel_;
PageTargetController& targetController_;
const PageTarget::SessionMetadata sessionMetadata_;
HostTargetController& targetController_;
const HostTarget::SessionMetadata sessionMetadata_;
std::shared_ptr<InstanceAgent> instanceAgent_;
/**
@@ -5,11 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/
#include "PageTarget.h"
#include "HostTarget.h"
#include "HostAgent.h"
#include "InspectorInterfaces.h"
#include "InspectorUtilities.h"
#include "InstanceTarget.h"
#include "PageAgent.h"
#include "Parsing.h"
#include "SessionState.h"
@@ -21,15 +21,15 @@
namespace facebook::react::jsinspector_modern {
/**
* A Session connected to a PageTarget, passing CDP messages to and from a
* PageAgent which it owns.
* A Session connected to a HostTarget, passing CDP messages to and from a
* HostAgent which it owns.
*/
class PageTargetSession {
class HostTargetSession {
public:
explicit PageTargetSession(
explicit HostTargetSession(
std::unique_ptr<IRemoteConnection> remote,
PageTargetController& targetController,
PageTarget::SessionMetadata sessionMetadata)
HostTargetController& targetController,
HostTarget::SessionMetadata sessionMetadata)
: remote_(std::make_shared<RAIIRemoteConnection>(std::move(remote))),
frontendChannel_(
[remoteWeak = std::weak_ptr(remote_)](std::string_view message) {
@@ -37,7 +37,7 @@ class PageTargetSession {
remote->onMessage(std::string(message));
}
}),
pageAgent_(
hostAgent_(
frontendChannel_,
targetController,
std::move(sessionMetadata),
@@ -67,7 +67,7 @@ class PageTargetSession {
// Catch exceptions that may arise from accessing dynamic params during
// request handling.
try {
pageAgent_.handleRequest(request);
hostAgent_.handleRequest(request);
} catch (const cdp::TypeError& e) {
frontendChannel_(folly::toJson(folly::dynamic::object("id", request.id)(
"error",
@@ -77,17 +77,17 @@ class PageTargetSession {
}
/**
* Replace the current instance agent inside pageAgent_ with a new one
* Replace the current instance agent inside hostAgent_ with a new one
* connected to the new InstanceTarget.
* \param instance The new instance target. May be nullptr to indicate
* there's no current instance.
*/
void setCurrentInstance(InstanceTarget* instance) {
if (instance) {
pageAgent_.setCurrentInstanceAgent(
hostAgent_.setCurrentInstanceAgent(
instance->createAgent(frontendChannel_, state_));
} else {
pageAgent_.setCurrentInstanceAgent(nullptr);
hostAgent_.setCurrentInstanceAgent(nullptr);
}
}
@@ -95,26 +95,26 @@ class PageTargetSession {
// Owned by this instance, but shared (weakly) with the frontend channel
std::shared_ptr<RAIIRemoteConnection> remote_;
FrontendChannel frontendChannel_;
PageAgent pageAgent_;
HostAgent hostAgent_;
SessionState state_;
};
std::shared_ptr<PageTarget> PageTarget::create(
PageTargetDelegate& delegate,
std::shared_ptr<HostTarget> HostTarget::create(
HostTargetDelegate& delegate,
VoidExecutor executor) {
std::shared_ptr<PageTarget> pageTarget{new PageTarget(delegate)};
pageTarget->setExecutor(executor);
return pageTarget;
std::shared_ptr<HostTarget> hostTarget{new HostTarget(delegate)};
hostTarget->setExecutor(executor);
return hostTarget;
}
PageTarget::PageTarget(PageTargetDelegate& delegate)
HostTarget::HostTarget(HostTargetDelegate& delegate)
: delegate_(delegate),
executionContextManager_{std::make_shared<ExecutionContextManager>()} {}
std::unique_ptr<ILocalConnection> PageTarget::connect(
std::unique_ptr<ILocalConnection> HostTarget::connect(
std::unique_ptr<IRemoteConnection> connectionToFrontend,
SessionMetadata sessionMetadata) {
auto session = std::make_shared<PageTargetSession>(
auto session = std::make_shared<HostTargetSession>(
std::move(connectionToFrontend), controller_, std::move(sessionMetadata));
session->setCurrentInstance(currentInstance_.get());
sessions_.insert(std::weak_ptr(session));
@@ -122,44 +122,44 @@ std::unique_ptr<ILocalConnection> PageTarget::connect(
[session](std::string message) { (*session)(message); });
}
PageTarget::~PageTarget() {
// Sessions are owned by InspectorPackagerConnection, not by PageTarget, but
// they hold a PageTarget& that we must guarantee is valid.
HostTarget::~HostTarget() {
// Sessions are owned by InspectorPackagerConnection, not by HostTarget, but
// they hold a HostTarget& that we must guarantee is valid.
assert(
sessions_.empty() &&
"PageTargetSession objects must be destroyed before their PageTarget. Did you call getInspectorInstance().removePage()?");
"HostTargetSession objects must be destroyed before their HostTarget. Did you call getInspectorInstance().removePage()?");
}
PageTargetDelegate::~PageTargetDelegate() {}
HostTargetDelegate::~HostTargetDelegate() {}
InstanceTarget& PageTarget::registerInstance(InstanceTargetDelegate& delegate) {
InstanceTarget& HostTarget::registerInstance(InstanceTargetDelegate& delegate) {
assert(!currentInstance_ && "Only one instance allowed");
currentInstance_ = InstanceTarget::create(
executionContextManager_, delegate, makeVoidExecutor(executorFromThis()));
sessions_.forEach(
[currentInstance = &*currentInstance_](PageTargetSession& session) {
[currentInstance = &*currentInstance_](HostTargetSession& session) {
session.setCurrentInstance(currentInstance);
});
return *currentInstance_;
}
void PageTarget::unregisterInstance(InstanceTarget& instance) {
void HostTarget::unregisterInstance(InstanceTarget& instance) {
assert(
currentInstance_ && currentInstance_.get() == &instance &&
"Invalid unregistration");
sessions_.forEach(
[](PageTargetSession& session) { session.setCurrentInstance(nullptr); });
[](HostTargetSession& session) { session.setCurrentInstance(nullptr); });
currentInstance_.reset();
}
PageTargetController::PageTargetController(PageTarget& target)
HostTargetController::HostTargetController(HostTarget& target)
: target_(target) {}
PageTargetDelegate& PageTargetController::getDelegate() {
HostTargetDelegate& HostTargetController::getDelegate() {
return target_.getDelegate();
}
bool PageTargetController::hasInstance() const {
bool HostTargetController::hasInstance() const {
return target_.hasInstance();
}
@@ -31,22 +31,22 @@
namespace facebook::react::jsinspector_modern {
class PageTargetSession;
class PageAgent;
class PageTarget;
class HostTargetSession;
class HostAgent;
class HostTarget;
/**
* Receives events from a PageTarget. This is a shared interface that each
* Receives events from a HostTarget. This is a shared interface that each
* React Native platform needs to implement in order to integrate with the
* debugging stack.
*/
class PageTargetDelegate {
class HostTargetDelegate {
public:
PageTargetDelegate() = default;
PageTargetDelegate(const PageTargetDelegate&) = delete;
PageTargetDelegate(PageTargetDelegate&&) = default;
PageTargetDelegate& operator=(const PageTargetDelegate&) = delete;
PageTargetDelegate& operator=(PageTargetDelegate&&) = default;
HostTargetDelegate() = default;
HostTargetDelegate(const HostTargetDelegate&) = delete;
HostTargetDelegate(HostTargetDelegate&&) = default;
HostTargetDelegate& operator=(const HostTargetDelegate&) = delete;
HostTargetDelegate& operator=(HostTargetDelegate&&) = default;
// TODO(moti): This is 1:1 the shape of the corresponding CDP message -
// consider reusing typed/generated CDP interfaces when we have those.
@@ -67,7 +67,7 @@ class PageTargetDelegate {
}
};
virtual ~PageTargetDelegate();
virtual ~HostTargetDelegate();
/**
* Called when the debugger requests a reload of the page. This is called on
@@ -78,19 +78,19 @@ class PageTargetDelegate {
};
/**
* The limited interface that PageTarget exposes to its associated
* The limited interface that HostTarget exposes to its associated
* sessions/agents.
*/
class PageTargetController final {
class HostTargetController final {
public:
explicit PageTargetController(PageTarget& target);
explicit HostTargetController(HostTarget& target);
PageTargetDelegate& getDelegate();
HostTargetDelegate& getDelegate();
bool hasInstance() const;
private:
PageTarget& target_;
HostTarget& target_;
};
/**
@@ -98,37 +98,37 @@ class PageTargetController final {
* "Host" in React Native's architecture - the entity that manages the
* lifecycle of a React Instance.
*/
class JSINSPECTOR_EXPORT PageTarget
: public EnableExecutorFromThis<PageTarget> {
class JSINSPECTOR_EXPORT HostTarget
: public EnableExecutorFromThis<HostTarget> {
public:
struct SessionMetadata {
std::optional<std::string> integrationName;
};
/**
* Constructs a new PageTarget.
* \param delegate The PageTargetDelegate that will
* receive events from this PageTarget. The caller is responsible for ensuring
* that the PageTargetDelegate outlives this object.
* Constructs a new HostTarget.
* \param delegate The HostTargetDelegate that will
* receive events from this HostTarget. The caller is responsible for ensuring
* that the HostTargetDelegate outlives this object.
* \param executor An executor that may be used to call methods on this
* PageTarget while it exists. \c create additionally guarantees that the
* executor will not be called after the PageTarget is destroyed.
* HostTarget while it exists. \c create additionally guarantees that the
* executor will not be called after the HostTarget is destroyed.
*/
static std::shared_ptr<PageTarget> create(
PageTargetDelegate& delegate,
static std::shared_ptr<HostTarget> create(
HostTargetDelegate& delegate,
VoidExecutor executor);
PageTarget(const PageTarget&) = delete;
PageTarget(PageTarget&&) = delete;
PageTarget& operator=(const PageTarget&) = delete;
PageTarget& operator=(PageTarget&&) = delete;
~PageTarget();
HostTarget(const HostTarget&) = delete;
HostTarget(HostTarget&&) = delete;
HostTarget& operator=(const HostTarget&) = delete;
HostTarget& operator=(HostTarget&&) = delete;
~HostTarget();
/**
* Creates a new Session connected to this PageTarget, wrapped in an
* Creates a new Session connected to this HostTarget, wrapped in an
* interface which is compatible with \c IInspector::addPage.
* The caller is responsible for destroying the connection before PageTarget
* is destroyed, on the same thread where PageTarget's constructor and
* The caller is responsible for destroying the connection before HostTarget
* is destroyed, on the same thread where HostTarget's constructor and
* destructor execute.
*/
std::unique_ptr<ILocalConnection> connect(
@@ -136,19 +136,19 @@ class JSINSPECTOR_EXPORT PageTarget
SessionMetadata sessionMetadata = {});
/**
* Registers an instance with this PageTarget.
* Registers an instance with this HostTarget.
* \param delegate The InstanceTargetDelegate that will receive events from
* this InstanceTarget. The caller is responsible for ensuring that the
* InstanceTargetDelegate outlives this object.
* \return An InstanceTarget reference representing the newly created
* instance. This reference is only valid until unregisterInstance is called
* (or the PageTarget is destroyed). \pre There isn't currently an instance
* registered with this PageTarget.
* (or the HostTarget is destroyed). \pre There isn't currently an instance
* registered with this HostTarget.
*/
InstanceTarget& registerInstance(InstanceTargetDelegate& delegate);
/**
* Unregisters an instance from this PageTarget.
* Unregisters an instance from this HostTarget.
* \param instance The InstanceTarget reference previously returned by
* registerInstance.
*/
@@ -156,24 +156,24 @@ class JSINSPECTOR_EXPORT PageTarget
private:
/**
* Constructs a new PageTarget.
* Constructs a new HostTarget.
* The caller must call setExecutor immediately afterwards.
* \param delegate The PageTargetDelegate that will
* receive events from this PageTarget. The caller is responsible for ensuring
* that the PageTargetDelegate outlives this object.
* \param delegate The HostTargetDelegate that will
* receive events from this HostTarget. The caller is responsible for ensuring
* that the HostTargetDelegate outlives this object.
*/
PageTarget(PageTargetDelegate& delegate);
HostTarget(HostTargetDelegate& delegate);
PageTargetDelegate& delegate_;
WeakList<PageTargetSession> sessions_;
PageTargetController controller_{*this};
HostTargetDelegate& delegate_;
WeakList<HostTargetSession> sessions_;
HostTargetController controller_{*this};
// executionContextManager_ is a shared_ptr to guarantee its validity while
// the InstanceTarget is alive (just in case the InstanceTarget ends up
// briefly outliving the PageTarget, which it generally shouldn't).
// briefly outliving the HostTarget, which it generally shouldn't).
std::shared_ptr<ExecutionContextManager> executionContextManager_;
std::shared_ptr<InstanceTarget> currentInstance_{nullptr};
inline PageTargetDelegate& getDelegate() {
inline HostTargetDelegate& getDelegate() {
return delegate_;
}
@@ -181,10 +181,10 @@ class JSINSPECTOR_EXPORT PageTarget
return currentInstance_ != nullptr;
}
// Necessary to allow PageAgent to access PageTarget's internals in a
// controlled way (i.e. only PageTargetController gets friend access, while
// PageAgent itself doesn't).
friend class PageTargetController;
// Necessary to allow HostAgent to access HostTarget's internals in a
// controlled way (i.e. only HostTargetController gets friend access, while
// HostAgent itself doesn't).
friend class HostTargetController;
};
} // namespace facebook::react::jsinspector_modern
@@ -47,7 +47,7 @@ class InstanceAgent final {
bool handleRequest(const cdp::PreparsedRequest& req);
/**
* Replace the current RuntimeAgent pageAgent_ with a new one
* Replace the current RuntimeAgent hostAgent_ with a new one
* connected to the new RuntimeTarget.
* \param runtime The new runtime target. May be nullptr to indicate
* there's no current debuggable runtime.
@@ -47,7 +47,7 @@ InstanceTarget::~InstanceTarget() {
// they hold an InstanceTarget& that we must guarantee is valid.
assert(
agents_.empty() &&
"InstanceAgent objects must be destroyed before their InstanceTarget. Did you call PageTarget::unregisterInstance()?");
"InstanceAgent objects must be destroyed before their InstanceTarget. Did you call HostTarget::unregisterInstance()?");
}
RuntimeTarget& InstanceTarget::registerRuntime(
@@ -9,8 +9,8 @@
#include <jsinspector-modern/ExecutionContext.h>
#include <jsinspector-modern/FallbackRuntimeAgentDelegate.h>
#include <jsinspector-modern/HostTarget.h>
#include <jsinspector-modern/InstanceTarget.h>
#include <jsinspector-modern/PageTarget.h>
#include <jsinspector-modern/RuntimeTarget.h>
#include <jsinspector-modern/ScopedExecutor.h>
#include <jsinspector-modern/SessionState.h>
@@ -35,7 +35,7 @@ bool RuntimeAgent::handleRequest(const cdp::PreparsedRequest& req) {
ExecutionContextSelector contextSelector = ExecutionContextSelector::all();
// TODO: Eventually, move execution context targeting out of RuntimeAgent.
// Right now, there's only ever one context (Runtime) in a Page, so we can
// Right now, there's only ever one context (Runtime) in a Host, so we can
// handle it here for simplicity, and use session state to propagate
// bindings to the next RuntimeAgent.
if (req.params.count("executionContextId")) {
@@ -36,7 +36,7 @@ class RuntimeAgent final {
* \param executionContextDescription A description of the execution context
* represented by this runtime. This is used for disambiguating the
* source/destination of CDP messages when there are multiple runtimes
* (concurrently or over the life of a Page).
* (concurrently or over the life of a Host).
* \param sessionState The state of the session that created this agent.
* \param delegate The RuntimeAgentDelegate providing engine-specific
* CDP functionality.
@@ -82,7 +82,7 @@ class JSINSPECTOR_EXPORT RuntimeTarget
* \param executionContextDescription A description of the execution context
* represented by this runtime. This is used for disambiguating the
* source/destination of CDP messages when there are multiple runtimes
* (concurrently or over the life of a Page).
* (concurrently or over the life of a Host).
* \param delegate The object that will receive events from this target. The
* caller is responsible for
* ensuring that the delegate outlives this object.
@@ -109,9 +109,9 @@ class JSINSPECTOR_EXPORT RuntimeTarget
/**
* Create a new RuntimeAgent that can be used to debug the underlying JS VM.
* The agent will be destroyed when the session ends, the containing
* InstanceTarget is unregistered from its PageTarget, or the RuntimeAgent is
* InstanceTarget is unregistered from its HostTarget, or the RuntimeAgent is
* unregistered from its InstanceTarget (whichever happens first).
* \param channel A thread-safe channel for sending CDP messages to the
* \param channel A thread-safe channel forHostTargetDP messages to the
* frontend.
* \returns The new agent, or nullptr if the runtime is not debuggable.
*/
@@ -126,7 +126,7 @@ class JSINSPECTOR_EXPORT RuntimeTarget
* \param executionContextDescription A description of the execution context
* represented by this runtime. This is used for disambiguating the
* source/destination of CDP messages when there are multiple runtimes
* (concurrently or over the life of a Page).
* (concurrently or over the life of a Host).
* \param delegate The object that will receive events from this target.
* The caller is responsible for ensuring that the delegate outlives this
* object.
@@ -11,8 +11,8 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <jsinspector-modern/HostTarget.h>
#include <jsinspector-modern/InspectorInterfaces.h>
#include <jsinspector-modern/PageTarget.h>
#include <memory>
@@ -26,11 +26,11 @@ namespace facebook::react::jsinspector_modern {
namespace {
class PageTargetTest : public Test {
class HostTargetTest : public Test {
folly::QueuedImmediateExecutor immediateExecutor_;
protected:
PageTargetTest() {
HostTargetTest() {
EXPECT_CALL(runtimeTargetDelegate_, createAgentDelegate(_, _, _, _))
.WillRepeatedly(runtimeAgentDelegates_.lazily_make_unique<
FrontendChannel,
@@ -40,17 +40,17 @@ class PageTargetTest : public Test {
}
void connect() {
ASSERT_FALSE(toPage_) << "Can only connect once in a PageTargetTest.";
ASSERT_FALSE(toPage_) << "Can only connect once in a HostTargetTest.";
toPage_ = page_->connect(
remoteConnections_.make_unique(),
{.integrationName = "PageTargetTest"});
{.integrationName = "HostTargetTest"});
// We'll always get an onDisconnect call when we tear
// down the test. Expect it in order to satisfy the strict mock.
EXPECT_CALL(*remoteConnections_[0], onDisconnect());
}
MockPageTargetDelegate pageTargetDelegate_;
MockHostTargetDelegate hostTargetDelegate_;
MockRemoteConnection& fromPage() {
assert(toPage_);
@@ -61,8 +61,8 @@ class PageTargetTest : public Test {
immediateExecutor_.add(callback);
};
std::shared_ptr<PageTarget> page_ =
PageTarget::create(pageTargetDelegate_, inspectorExecutor_);
std::shared_ptr<HostTarget> page_ =
HostTarget::create(hostTargetDelegate_, inspectorExecutor_);
MockInstanceTargetDelegate instanceTargetDelegate_;
MockRuntimeTargetDelegate runtimeTargetDelegate_;
@@ -81,22 +81,22 @@ class PageTargetTest : public Test {
};
/**
* Simplified test harness focused on sending messages to and from a PageTarget.
* Simplified test harness focused on sending messages to and from a HostTarget.
*/
class PageTargetProtocolTest : public PageTargetTest {
class HostTargetProtocolTest : public HostTargetTest {
public:
PageTargetProtocolTest() {
HostTargetProtocolTest() {
connect();
}
private:
// Protocol tests shouldn't manually call connect()
using PageTargetTest::connect;
using HostTargetTest::connect;
};
} // namespace
TEST_F(PageTargetProtocolTest, UnrecognizedMethod) {
TEST_F(HostTargetProtocolTest, UnrecognizedMethod) {
EXPECT_CALL(
fromPage(),
onMessage(JsonParsed(AllOf(
@@ -109,7 +109,7 @@ TEST_F(PageTargetProtocolTest, UnrecognizedMethod) {
})");
}
TEST_F(PageTargetProtocolTest, TypeErrorInMethodName) {
TEST_F(HostTargetProtocolTest, TypeErrorInMethodName) {
EXPECT_CALL(
fromPage(),
onMessage(JsonParsed(AllOf(
@@ -123,7 +123,7 @@ TEST_F(PageTargetProtocolTest, TypeErrorInMethodName) {
})");
}
TEST_F(PageTargetProtocolTest, MissingId) {
TEST_F(HostTargetProtocolTest, MissingId) {
EXPECT_CALL(
fromPage(),
onMessage(JsonParsed(AllOf(
@@ -136,7 +136,7 @@ TEST_F(PageTargetProtocolTest, MissingId) {
})");
}
TEST_F(PageTargetProtocolTest, MalformedJson) {
TEST_F(HostTargetProtocolTest, MalformedJson) {
EXPECT_CALL(
fromPage(),
onMessage(JsonParsed(AllOf(
@@ -146,7 +146,7 @@ TEST_F(PageTargetProtocolTest, MalformedJson) {
toPage_->sendMessage("{");
}
TEST_F(PageTargetProtocolTest, InjectLogsToIdentifyBackend) {
TEST_F(HostTargetProtocolTest, InjectLogsToIdentifyBackend) {
InSequence s;
EXPECT_CALL(
@@ -167,12 +167,12 @@ TEST_F(PageTargetProtocolTest, InjectLogsToIdentifyBackend) {
})");
}
TEST_F(PageTargetProtocolTest, PageReloadMethod) {
TEST_F(HostTargetProtocolTest, PageReloadMethod) {
InSequence s;
EXPECT_CALL(
pageTargetDelegate_,
onReload(Eq(PageTargetDelegate::PageReloadRequest{
hostTargetDelegate_,
onReload(Eq(HostTargetDelegate::PageReloadRequest{
.ignoreCache = std::nullopt,
.scriptToEvaluateOnLoad = std::nullopt})))
.RetiresOnSaturation();
@@ -187,8 +187,8 @@ TEST_F(PageTargetProtocolTest, PageReloadMethod) {
})");
EXPECT_CALL(
pageTargetDelegate_,
onReload(Eq(PageTargetDelegate::PageReloadRequest{
hostTargetDelegate_,
onReload(Eq(HostTargetDelegate::PageReloadRequest{
.ignoreCache = true, .scriptToEvaluateOnLoad = "alert('hello');"})))
.RetiresOnSaturation();
EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({
@@ -206,13 +206,13 @@ TEST_F(PageTargetProtocolTest, PageReloadMethod) {
})");
}
TEST_F(PageTargetProtocolTest, RegisterUnregisterInstanceWithoutEvents) {
TEST_F(HostTargetProtocolTest, RegisterUnregisterInstanceWithoutEvents) {
auto& instanceTarget = page_->registerInstance(instanceTargetDelegate_);
page_->unregisterInstance(instanceTarget);
}
TEST_F(PageTargetTest, ConnectToAlreadyRegisteredInstanceWithoutEvents) {
TEST_F(HostTargetTest, ConnectToAlreadyRegisteredInstanceWithoutEvents) {
auto& instanceTarget = page_->registerInstance(instanceTargetDelegate_);
connect();
@@ -220,7 +220,7 @@ TEST_F(PageTargetTest, ConnectToAlreadyRegisteredInstanceWithoutEvents) {
page_->unregisterInstance(instanceTarget);
}
TEST_F(PageTargetProtocolTest, RegisterUnregisterInstanceWithEvents) {
TEST_F(HostTargetProtocolTest, RegisterUnregisterInstanceWithEvents) {
InSequence s;
EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({
@@ -240,7 +240,7 @@ TEST_F(PageTargetProtocolTest, RegisterUnregisterInstanceWithEvents) {
page_->unregisterInstance(instanceTarget);
}
TEST_F(PageTargetTest, ConnectToAlreadyRegisteredInstanceWithEvents) {
TEST_F(HostTargetTest, ConnectToAlreadyRegisteredInstanceWithEvents) {
auto& instanceTarget = page_->registerInstance(instanceTargetDelegate_);
connect();
@@ -263,7 +263,7 @@ TEST_F(PageTargetTest, ConnectToAlreadyRegisteredInstanceWithEvents) {
page_->unregisterInstance(instanceTarget);
}
TEST_F(PageTargetTest, ConnectToAlreadyRegisteredRuntimeWithEvents) {
TEST_F(HostTargetTest, ConnectToAlreadyRegisteredRuntimeWithEvents) {
auto& instanceTarget = page_->registerInstance(instanceTargetDelegate_);
auto& runtimeTarget =
instanceTarget.registerRuntime(runtimeTargetDelegate_, runtimeExecutor_);
@@ -298,7 +298,7 @@ TEST_F(PageTargetTest, ConnectToAlreadyRegisteredRuntimeWithEvents) {
page_->unregisterInstance(instanceTarget);
}
TEST_F(PageTargetProtocolTest, RuntimeAgentDelegateLifecycle) {
TEST_F(HostTargetProtocolTest, RuntimeAgentDelegateLifecycle) {
{
auto& instanceTarget = page_->registerInstance(instanceTargetDelegate_);
auto& runtimeTarget = instanceTarget.registerRuntime(
@@ -326,7 +326,7 @@ TEST_F(PageTargetProtocolTest, RuntimeAgentDelegateLifecycle) {
EXPECT_FALSE(runtimeAgentDelegates_[1]);
}
TEST_F(PageTargetProtocolTest, MethodNotHandledByRuntimeAgentDelegate) {
TEST_F(HostTargetProtocolTest, MethodNotHandledByRuntimeAgentDelegate) {
InSequence s;
auto& instanceTarget = page_->registerInstance(instanceTargetDelegate_);
@@ -352,7 +352,7 @@ TEST_F(PageTargetProtocolTest, MethodNotHandledByRuntimeAgentDelegate) {
page_->unregisterInstance(instanceTarget);
}
TEST_F(PageTargetProtocolTest, MethodHandledByRuntimeAgentDelegate) {
TEST_F(HostTargetProtocolTest, MethodHandledByRuntimeAgentDelegate) {
InSequence s;
auto& instanceTarget = page_->registerInstance(instanceTargetDelegate_);
@@ -385,7 +385,7 @@ TEST_F(PageTargetProtocolTest, MethodHandledByRuntimeAgentDelegate) {
page_->unregisterInstance(instanceTarget);
}
TEST_F(PageTargetProtocolTest, MessageRoutingWhileNoRuntimeAgentDelegate) {
TEST_F(HostTargetProtocolTest, MessageRoutingWhileNoRuntimeAgentDelegate) {
InSequence s;
EXPECT_CALL(
@@ -442,7 +442,7 @@ TEST_F(PageTargetProtocolTest, MessageRoutingWhileNoRuntimeAgentDelegate) {
})");
}
TEST_F(PageTargetProtocolTest, InstanceWithNullRuntimeAgentDelegate) {
TEST_F(HostTargetProtocolTest, InstanceWithNullRuntimeAgentDelegate) {
InSequence s;
EXPECT_CALL(runtimeTargetDelegate_, createAgentDelegate(_, _, _, _))
@@ -469,7 +469,7 @@ TEST_F(PageTargetProtocolTest, InstanceWithNullRuntimeAgentDelegate) {
page_->unregisterInstance(instanceTarget);
}
TEST_F(PageTargetProtocolTest, RuntimeAgentDelegateHasAccessToSessionState) {
TEST_F(HostTargetProtocolTest, RuntimeAgentDelegateHasAccessToSessionState) {
InSequence s;
// Send Runtime.enable before registering the Instance (which in turns creates
@@ -115,9 +115,9 @@ class MockInspectorPackagerConnectionDelegate
folly::Executor& executor_;
};
class MockPageTargetDelegate : public PageTargetDelegate {
class MockHostTargetDelegate : public HostTargetDelegate {
public:
// PageTargetDelegate methods
// HostTargetDelegate methods
MOCK_METHOD(void, onReload, (const PageReloadRequest& request), (override));
};
@@ -12,8 +12,8 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <jsinspector-modern/HostTarget.h>
#include <jsinspector-modern/InspectorInterfaces.h>
#include <jsinspector-modern/PageTarget.h>
#include <memory>
@@ -48,7 +48,7 @@ namespace {
* the provided folly::Executor) and the corresponding jsi::Runtime.
*/
template <typename EngineAdapter>
class JsiIntegrationPortableTest : public Test, private PageTargetDelegate {
class JsiIntegrationPortableTest : public Test, private HostTargetDelegate {
folly::QueuedImmediateExecutor immediateExecutor_;
protected:
@@ -129,8 +129,8 @@ class JsiIntegrationPortableTest : public Test, private PageTargetDelegate {
return result;
}
std::shared_ptr<PageTarget> page_ =
PageTarget::create(*this, inspectorExecutor_);
std::shared_ptr<HostTarget> page_ =
HostTarget::create(*this, inspectorExecutor_);
InstanceTarget* instance_{};
RuntimeTarget* runtimeTarget_{};
@@ -145,7 +145,7 @@ class JsiIntegrationPortableTest : public Test, private PageTargetDelegate {
std::unique_ptr<ILocalConnection> toPage_;
private:
// PageTargetDelegate methods
// HostTargetDelegate methods
void onReload(const PageReloadRequest& request) override {
(void)request;
@@ -30,7 +30,7 @@ ReactInstance::ReactInstance(
std::shared_ptr<MessageQueueThread> jsMessageQueueThread,
std::shared_ptr<TimerManager> timerManager,
JsErrorHandler::JsErrorHandlingFunc jsErrorHandlingFunc,
jsinspector_modern::PageTarget* parentInspectorTarget)
jsinspector_modern::HostTarget* parentInspectorTarget)
: runtime_(std::move(runtime)),
jsMessageQueueThread_(jsMessageQueueThread),
timerManager_(std::move(timerManager)),
@@ -35,7 +35,7 @@ class ReactInstance final : private jsinspector_modern::InstanceTargetDelegate {
std::shared_ptr<MessageQueueThread> jsMessageQueueThread,
std::shared_ptr<TimerManager> timerManager,
JsErrorHandler::JsErrorHandlingFunc JsErrorHandlingFunc,
jsinspector_modern::PageTarget* parentInspectorTarget = nullptr);
jsinspector_modern::HostTarget* parentInspectorTarget = nullptr);
RuntimeExecutor getUnbufferedRuntimeExecutor() noexcept;
@@ -87,7 +87,7 @@ class ReactInstance final : private jsinspector_modern::InstanceTargetDelegate {
jsinspector_modern::InstanceTarget* inspectorTarget_{nullptr};
jsinspector_modern::RuntimeTarget* runtimeInspectorTarget_{nullptr};
jsinspector_modern::PageTarget* parentInspectorTarget_{nullptr};
jsinspector_modern::HostTarget* parentInspectorTarget_{nullptr};
};
} // namespace facebook::react
@@ -28,9 +28,9 @@ RCT_MOCK_DEF(RCTHost, _RCTLogNativeInternal);
using namespace facebook::react;
class RCTHostPageTargetDelegate : public facebook::react::jsinspector_modern::PageTargetDelegate {
class RCTHostHostTargetDelegate : public facebook::react::jsinspector_modern::HostTargetDelegate {
public:
RCTHostPageTargetDelegate(RCTHost *host) : host_(host) {}
RCTHostHostTargetDelegate(RCTHost *host) : host_(host) {}
void onReload(const PageReloadRequest &request) override
{
@@ -67,8 +67,8 @@ class RCTHostPageTargetDelegate : public facebook::react::jsinspector_modern::Pa
RCTModuleRegistry *_moduleRegistry;
std::unique_ptr<RCTHostPageTargetDelegate> _inspectorPageDelegate;
std::shared_ptr<jsinspector_modern::PageTarget> _inspectorTarget;
std::unique_ptr<RCTHostHostTargetDelegate> _inspectorHostDelegate;
std::shared_ptr<jsinspector_modern::HostTarget> _inspectorTarget;
std::optional<int> _inspectorPageId;
}
@@ -157,7 +157,7 @@ class RCTHostPageTargetDelegate : public facebook::react::jsinspector_modern::Pa
RCTRegisterReloadCommandListener(self);
});
_inspectorPageDelegate = std::make_unique<RCTHostPageTargetDelegate>(self);
_inspectorHostDelegate = std::make_unique<RCTHostHostTargetDelegate>(self);
}
return self;
}
@@ -169,7 +169,7 @@ class RCTHostPageTargetDelegate : public facebook::react::jsinspector_modern::Pa
auto &inspectorFlags = jsinspector_modern::InspectorFlags::getInstance();
if (inspectorFlags.getEnableModernCDPRegistry() && !_inspectorPageId.has_value()) {
_inspectorTarget =
facebook::react::jsinspector_modern::PageTarget::create(*_inspectorPageDelegate, [](auto callback) {
facebook::react::jsinspector_modern::HostTarget::create(*_inspectorHostDelegate, [](auto callback) {
RCTExecuteOnMainQueue(^{
callback();
});
@@ -62,7 +62,7 @@ typedef void (^_Null_unspecified RCTInstanceInitialBundleLoadCompletionBlock)();
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
onInitialBundleLoad:(RCTInstanceInitialBundleLoadCompletionBlock)onInitialBundleLoad
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
parentInspectorTarget:(facebook::react::jsinspector_modern::PageTarget *)parentInspectorTarget;
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget;
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
@@ -84,7 +84,7 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags)
// APIs supporting interop with native modules and view managers
RCTBridgeModuleDecorator *_bridgeModuleDecorator;
jsinspector_modern::PageTarget *_parentInspectorTarget;
jsinspector_modern::HostTarget *_parentInspectorTarget;
}
#pragma mark - Public
@@ -95,7 +95,7 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags)
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)tmmDelegate
onInitialBundleLoad:(RCTInstanceInitialBundleLoadCompletionBlock)onInitialBundleLoad
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
parentInspectorTarget:(jsinspector_modern::PageTarget *)parentInspectorTarget
parentInspectorTarget:(jsinspector_modern::HostTarget *)parentInspectorTarget
{
if (self = [super init]) {
_performanceLogger = [RCTPerformanceLogger new];
@@ -54,7 +54,7 @@ static __weak ShimRCTInstance *weakShim = nil;
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)tmmDelegate
onInitialBundleLoad:(RCTInstanceInitialBundleLoadCompletionBlock)onInitialBundleLoad
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
parentInspectorTarget:(facebook::react::jsinspector_modern::PageTarget *)parentInspectorTarget
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
{
weakShim.initCount++;
return self;