Register RCTHost with modern CDP backend (#42393)

Summary:
Changelog: [Internal][iOS] - Enable stub modern CDP backend in Bridgeless behind a feature flag

Minimally integrates the stub native CDP backend implementation (D50936932) into iOS Bridgeless.

This integration registers itself as a "Modern" target (D50967794, D50967795) to instruct `inspector-proxy` to disable its CDP hacks related to source map fetching, reloads, etc. This gives us a mostly-clean slate on which to develop and test native CDP functionality.

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

Test Plan:
1. `js1 run`
2. Enable the modern CDP backend by grafting D52844391
3. Enable Bridgeless in RNTester by grafting D52910646
4. `buck2 install rntester-ios`
5. Dev Menu -> Open Debugger
6. Observe console message self-identifying the backend + iOS Bridgeless
7. Observe that the debugger stays connected when the app is reloaded (albeit without doing anything very interesting just yet)

{F1329876835}

Reviewed By: huntie

Differential Revision: D50936931

Pulled By: motiz88

fbshipit-source-id: ff8f919d0370266aea2916da349520bc76d690ab
This commit is contained in:
Moti Zilberman
2024-01-22 05:00:01 -08:00
committed by Facebook GitHub Bot
parent 748d674dd5
commit 8a4c85316d
5 changed files with 50 additions and 1 deletions
@@ -12,6 +12,18 @@
#include <optional>
#include <string>
#ifndef JSINSPECTOR_EXPORT
#ifdef _MSC_VER
#ifdef CREATE_SHARED_LIBRARY
#define JSINSPECTOR_EXPORT __declspec(dllexport)
#else
#define JSINSPECTOR_EXPORT
#endif // CREATE_SHARED_LIBRARY
#else // _MSC_VER
#define JSINSPECTOR_EXPORT __attribute__((visibility("default")))
#endif // _MSC_VER
#endif // !defined(JSINSPECTOR_EXPORT)
namespace facebook::react::jsinspector_modern {
/**
@@ -19,7 +31,7 @@ namespace facebook::react::jsinspector_modern {
* "Host" in React Native's architecture - the entity that manages the
* lifecycle of a React Instance.
*/
class PageTarget {
class JSINSPECTOR_EXPORT PageTarget {
public:
struct SessionMetadata {
std::optional<std::string> integrationName;
@@ -35,4 +35,5 @@ target_link_libraries(
jsi
jsireact
react_utils
jsinspector
)
@@ -62,4 +62,5 @@ Pod::Spec.new do |s|
s.dependency "React-jsc"
end
s.dependency "React-jsinspector"
end
@@ -65,6 +65,7 @@ Pod::Spec.new do |s|
s.dependency "React-RuntimeCore"
s.dependency "React-Mapbuffer"
s.dependency "React-jserrorhandler"
s.dependency "React-jsinspector"
if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1"
s.dependency "hermes-engine"
@@ -17,6 +17,10 @@
#import <React/RCTMockDef.h>
#import <React/RCTPerformanceLogger.h>
#import <React/RCTReloadCommand.h>
#import <jsinspector-modern/InspectorFlags.h>
#import <jsinspector-modern/InspectorInterfaces.h>
#import <jsinspector-modern/ReactCdp.h>
#import <optional>
RCT_MOCK_DEF(RCTHost, _RCTLogNativeInternal);
#define _RCTLogNativeInternal RCT_MOCK_USE(RCTHost, _RCTLogNativeInternal)
@@ -47,6 +51,9 @@ using namespace facebook::react;
std::vector<__weak RCTFabricSurface *> _attachedSurfaces;
RCTModuleRegistry *_moduleRegistry;
std::unique_ptr<jsinspector_modern::PageTarget> _inspectorTarget;
std::optional<int> _inspectorPageId;
}
+ (void)initialize
@@ -141,6 +148,28 @@ using namespace facebook::react;
- (void)start
{
auto &inspectorFlags = jsinspector_modern::InspectorFlags::getInstance();
if (inspectorFlags.getEnableModernCDPRegistry() && !_inspectorPageId.has_value()) {
_inspectorTarget = std::make_unique<jsinspector_modern::PageTarget>();
__weak RCTHost *weakSelf = self;
_inspectorPageId = facebook::react::jsinspector_modern::getInspectorInstance().addPage(
"React Native Bridgeless (Experimental)",
/* vm */ "",
[weakSelf](std::unique_ptr<facebook::react::jsinspector_modern::IRemoteConnection> remote)
-> std::unique_ptr<facebook::react::jsinspector_modern::ILocalConnection> {
RCTHost *strongSelf = weakSelf;
if (!strongSelf) {
// This can happen if we're about to be dealloc'd. Reject the connection.
return nullptr;
}
return strongSelf->_inspectorTarget->connect(
std::move(remote),
{
.integrationName = "iOS Bridgeless (RCTHost)",
});
},
facebook::react::jsinspector_modern::InspectorPageType::Modern);
}
if (_instance) {
RCTLogWarn(
@"RCTHost should not be creating a new instance if one already exists. This implies there is a bug with how/when this method is being called.");
@@ -228,6 +257,11 @@ using namespace facebook::react;
- (void)dealloc
{
if (_inspectorPageId.has_value()) {
facebook::react::jsinspector_modern::getInspectorInstance().removePage(*_inspectorPageId);
_inspectorPageId.reset();
_inspectorTarget.reset();
}
[_instance invalidate];
}