diff --git a/packages/react-native/Libraries/Blob/React-RCTBlob.podspec b/packages/react-native/Libraries/Blob/React-RCTBlob.podspec index 6d1c24ea00f..8b48d45e7f4 100644 --- a/packages/react-native/Libraries/Blob/React-RCTBlob.podspec +++ b/packages/react-native/Libraries/Blob/React-RCTBlob.podspec @@ -22,6 +22,9 @@ folly_version = folly_config[:version] header_search_paths = [ "\"$(PODS_ROOT)/RCT-Folly\"", + "\"$(PODS_ROOT)/boost\"", + "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fmt/include\"", "\"${PODS_ROOT}/Headers/Public/React-Codegen/react/renderer/components\"", ] @@ -44,6 +47,8 @@ Pod::Spec.new do |s| "HEADER_SEARCH_PATHS" => header_search_paths.join(' ') } + s.dependency "DoubleConversion" + s.dependency "fmt", "9.1.0" s.dependency "RCT-Folly", folly_version s.dependency "React-jsi" s.dependency "React-Core/RCTBlobHeaders" diff --git a/packages/react-native/React/CoreModules/React-CoreModules.podspec b/packages/react-native/React/CoreModules/React-CoreModules.podspec index 9a0938f25fc..b6f2cfb1e23 100644 --- a/packages/react-native/React/CoreModules/React-CoreModules.podspec +++ b/packages/react-native/React/CoreModules/React-CoreModules.podspec @@ -22,8 +22,11 @@ folly_version = folly_config[:version] socket_rocket_version = '0.7.0' header_search_paths = [ + "\"$(PODS_ROOT)/boost\"", "\"$(PODS_TARGET_SRCROOT)/React/CoreModules\"", "\"$(PODS_ROOT)/RCT-Folly\"", + "\"$(PODS_ROOT)/DoubleConversion\"", + "\"$(PODS_ROOT)/fmt/include\"", "\"${PODS_ROOT}/Headers/Public/React-Codegen/react/renderer/components\"", ] @@ -45,6 +48,8 @@ Pod::Spec.new do |s| "HEADER_SEARCH_PATHS" => header_search_paths.join(" ") } s.framework = "UIKit" + s.dependency "DoubleConversion" + s.dependency "fmt", "9.1.0" s.dependency "RCT-Folly", folly_version s.dependency "RCTTypeSafety", version s.dependency "React-Core/CoreModulesHeaders", version diff --git a/packages/react-native/ReactCommon/cxxreact/Instance.cpp b/packages/react-native/ReactCommon/cxxreact/Instance.cpp index e7a8eba6252..f6120eb76bd 100644 --- a/packages/react-native/ReactCommon/cxxreact/Instance.cpp +++ b/packages/react-native/ReactCommon/cxxreact/Instance.cpp @@ -316,4 +316,9 @@ void Instance::JSCallInvoker::scheduleAsync( } } +std::unique_ptr Instance::createRuntimeAgent( + jsinspector_modern::FrontendChannel frontendChannel) { + return nativeToJsBridge_->createRuntimeAgent(frontendChannel); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/cxxreact/Instance.h b/packages/react-native/ReactCommon/cxxreact/Instance.h index 1cc3750be10..747ed4524e2 100644 --- a/packages/react-native/ReactCommon/cxxreact/Instance.h +++ b/packages/react-native/ReactCommon/cxxreact/Instance.h @@ -151,6 +151,10 @@ class RN_EXPORT Instance : private jsinspector_modern::InstanceTargetDelegate { std::unique_ptr startupScript, std::string startupScriptSourceURL); + // From InstanceTargetDelegate + std::unique_ptr createRuntimeAgent( + jsinspector_modern::FrontendChannel frontendChannel) override; + std::shared_ptr callback_; std::shared_ptr nativeToJsBridge_; std::shared_ptr moduleRegistry_; diff --git a/packages/react-native/ReactCommon/cxxreact/JSExecutor.cpp b/packages/react-native/ReactCommon/cxxreact/JSExecutor.cpp index fa0cb3f1944..1989bb951f6 100644 --- a/packages/react-native/ReactCommon/cxxreact/JSExecutor.cpp +++ b/packages/react-native/ReactCommon/cxxreact/JSExecutor.cpp @@ -34,4 +34,11 @@ double JSExecutor::performanceNow() { return duration / NANOSECONDS_IN_MILLISECOND; } +std::unique_ptr +JSExecutor::createRuntimeAgent( + jsinspector_modern::FrontendChannel frontendChannel) { + (void)frontendChannel; + return nullptr; +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/cxxreact/JSExecutor.h b/packages/react-native/ReactCommon/cxxreact/JSExecutor.h index 09a1ac67296..3fdb5f495c3 100644 --- a/packages/react-native/ReactCommon/cxxreact/JSExecutor.h +++ b/packages/react-native/ReactCommon/cxxreact/JSExecutor.h @@ -12,6 +12,8 @@ #include #include +#include +#include #ifndef RN_EXPORT #define RN_EXPORT __attribute__((visibility("default"))) @@ -111,7 +113,8 @@ class RN_EXPORT JSExecutor { /** * Returns whether or not the underlying executor supports debugging via the - * Chrome remote debugging protocol. + * Chrome remote debugging protocol. If true, the executor should also + * override the \c createRuntimeAgent method. */ virtual bool isInspectable() { return false; @@ -136,6 +139,12 @@ class RN_EXPORT JSExecutor { const std::string& bundlePath); static double performanceNow(); + + /** + * Create a RuntimeAgent that can be used to debug the JS VM instance. + */ + virtual std::unique_ptr createRuntimeAgent( + jsinspector_modern::FrontendChannel frontendChannel); }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp b/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp index 5b48900d789..c9f7b17063a 100644 --- a/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp +++ b/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp @@ -343,4 +343,11 @@ NativeToJsBridge::getDecoratedNativeMethodCallInvoker( m_delegate, std::move(nativeMethodCallInvoker)); } +std::unique_ptr +NativeToJsBridge::createRuntimeAgent( + jsinspector_modern::FrontendChannel frontendChannel) { + auto agent = m_executor->createRuntimeAgent(std::move(frontendChannel)); + return agent; +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h b/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h index f8f59f596e4..d7d949b5f67 100644 --- a/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h +++ b/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace folly { struct dynamic; @@ -106,6 +107,13 @@ class NativeToJsBridge { std::shared_ptr getDecoratedNativeMethodCallInvoker( std::shared_ptr nativeInvoker) const; + /** + * Create a RuntimeAgent that can be used to debug the underlying JS VM + * instance. + */ + virtual std::unique_ptr createRuntimeAgent( + jsinspector_modern::FrontendChannel frontendChannel); + private: // This is used to avoid a race condition where a proxyCallback gets queued // after ~NativeToJsBridge(), on the same thread. In that case, the callback diff --git a/packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec b/packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec index b0edfc93d04..894f6614f44 100644 --- a/packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec +++ b/packages/react-native/ReactCommon/jsiexecutor/React-jsiexecutor.podspec @@ -43,6 +43,7 @@ Pod::Spec.new do |s| s.dependency "DoubleConversion" s.dependency "fmt", "9.1.0" s.dependency "glog" + add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern') if ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1" s.dependency 'hermes-engine' diff --git a/packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.cpp b/packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.cpp index c5020edde20..386f62109d7 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.cpp @@ -11,24 +11,19 @@ namespace facebook::react::jsinspector_modern { InstanceAgent::InstanceAgent( FrontendChannel frontendChannel, - InstanceTarget& target) - : frontendChannel_(frontendChannel), target_(target) { + InstanceTarget& target, + std::unique_ptr runtimeAgent) + : frontendChannel_(frontendChannel), + target_(target), + runtimeAgent_(std::move(runtimeAgent)) { (void)target_; } bool InstanceAgent::handleRequest(const cdp::PreparsedRequest& req) { - // NOTE: Our implementation of @cdp Runtime.getHeapUsage is a stub. - if (req.method == "Runtime.getHeapUsage") { - folly::dynamic res = folly::dynamic::object("id", req.id)( - "result", folly::dynamic::object("usedSize", 0)("totalSize", 0)); - frontendChannel_(folly::toJson(res)); + if (runtimeAgent_ && runtimeAgent_->handleRequest(req)) { return true; } return false; } -int InstanceAgent::getExecutionContextId() const { - return 1; -} - } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.h b/packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.h index 24759fe5744..52538786495 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.h @@ -9,6 +9,7 @@ #include #include +#include #include namespace facebook::react::jsinspector_modern { @@ -27,10 +28,13 @@ class InstanceAgent { * \param target The InstanceTarget that this agent is attached to. The * caller is responsible for ensuring that the InstanceTarget outlives this * object. + * \param runtimeAgent The RuntimeAgent that this agent will use to + * communicate with the JS runtime. */ explicit InstanceAgent( FrontendChannel frontendChannel, - InstanceTarget& target); + InstanceTarget& target, + std::unique_ptr runtimeAgent); /** * Handle a CDP request. The response will be sent over the provided @@ -39,16 +43,10 @@ class InstanceAgent { */ bool handleRequest(const cdp::PreparsedRequest& req); - /** - * Get the ID of the execution context that this agent is associated with. - * \see - * https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-ExecutionContextId - */ - int getExecutionContextId() const; - private: FrontendChannel frontendChannel_; InstanceTarget& target_; + std::unique_ptr runtimeAgent_; }; } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.cpp b/packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.cpp index c31c37cf38f..246baaf346f 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.cpp @@ -20,6 +20,9 @@ InstanceTargetDelegate::~InstanceTargetDelegate() {} std::unique_ptr InstanceTarget::createAgent( FrontendChannel channel) { - return std::make_unique(channel, *this); + auto runtimeAgent = delegate_.createRuntimeAgent(channel); + return std::make_unique( + channel, *this, std::move(runtimeAgent)); } + } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.h b/packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.h index 75fec740892..3f50756e70a 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.h @@ -8,8 +8,10 @@ #pragma once #include +#include #include +#include #include namespace facebook::react::jsinspector_modern { @@ -29,6 +31,17 @@ class InstanceTargetDelegate { InstanceTargetDelegate& operator=(const InstanceTargetDelegate&) = delete; InstanceTargetDelegate& operator=(InstanceTargetDelegate&&) = default; + /** + * Create a new RuntimeAgent that can be used to debug the underlying JS VM. + * The agent will be destroyed when the session ends or the InstanceTarget is + * unregistered from its PageTarget (whichever happens first). + * \param channel A thread-safe channel for sending CDP messages to the + * frontend. + * \returns The new agent, or nullptr if the target does not support JS + * debugging. + */ + virtual std::unique_ptr createRuntimeAgent( + FrontendChannel channel) = 0; virtual ~InstanceTargetDelegate(); }; diff --git a/packages/react-native/ReactCommon/jsinspector-modern/PageAgent.cpp b/packages/react-native/ReactCommon/jsinspector-modern/PageAgent.cpp index 0d7831b4bc4..5223ee719c4 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/PageAgent.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/PageAgent.cpp @@ -71,24 +71,15 @@ void PageAgent::handleRequest(const cdp::PreparsedRequest& req) { return; } + bool shouldSendOKResponse = false; + if (req.method == "Runtime.enable") { runtimeEnabled_ = true; - folly::dynamic res = folly::dynamic::object("id", req.id)( - "result", folly::dynamic::object()); - std::string json = folly::toJson(res); - frontendChannel_(json); - - if (instanceAgent_) { - folly::dynamic params = folly::dynamic::object( - "context", - folly::dynamic::object("id", instanceAgent_->getExecutionContextId())( - "origin", "")("name", "React Native")); - folly::dynamic contextCreated = folly::dynamic::object( - "method", "Runtime.executionContextCreated")("params", params); - frontendChannel_(folly::toJson(contextCreated)); - } - return; + // Fall through to letting the instance handle this request and send a + // response, but remember that we need to send a response in case the + // instance doesn't handle the request. + shouldSendOKResponse = true; } if (req.method == "Runtime.disable") { runtimeEnabled_ = false; @@ -96,13 +87,25 @@ void PageAgent::handleRequest(const cdp::PreparsedRequest& req) { "result", folly::dynamic::object()); std::string json = folly::toJson(res); frontendChannel_(json); - return; + + // Fall through to letting the instance handle this request and send a + // response, but remember that we need to send a response in case the + // instance doesn't handle the request. + shouldSendOKResponse = true; } if (instanceAgent_ && instanceAgent_->handleRequest(req)) { return; } + if (shouldSendOKResponse) { + folly::dynamic res = folly::dynamic::object("id", req.id)( + "result", folly::dynamic::object()); + std::string json = folly::toJson(res); + frontendChannel_(json); + return; + } + folly::dynamic res = folly::dynamic::object("id", req.id)( "error", folly::dynamic::object("code", -32601)( @@ -133,12 +136,8 @@ void PageAgent::setCurrentInstanceAgent( return; } if (previousInstanceAgent != nullptr) { - auto executionContextId = previousInstanceAgent->getExecutionContextId(); - folly::dynamic contextDestroyed = - folly::dynamic::object("method", "Runtime.executionContextDestroyed")( - "params", - folly::dynamic::object("executionContextId", executionContextId)); - frontendChannel_(folly::toJson(contextDestroyed)); + // TODO: Send Runtime.executionContextDestroyed here - at the moment we + // expect the runtime to do it for us. // Because we can only have a single instance, we can report all contexts // as cleared. @@ -147,13 +146,8 @@ void PageAgent::setCurrentInstanceAgent( frontendChannel_(folly::toJson(contextsCleared)); } if (instanceAgent_) { - folly::dynamic params = folly::dynamic::object( - "context", - folly::dynamic::object("id", instanceAgent_->getExecutionContextId())( - "origin", "")("name", "React Native")); - folly::dynamic contextCreated = folly::dynamic::object( - "method", "Runtime.executionContextCreated")("params", params); - frontendChannel_(folly::toJson(contextCreated)); + // TODO: Send Runtime.executionContextCreated here - at the moment we expect + // the runtime to do it for us. } } diff --git a/packages/react-native/ReactCommon/jsinspector-modern/Parsing.h b/packages/react-native/ReactCommon/jsinspector-modern/Parsing.h index 94d6401b6a1..4db24fcb2a3 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/Parsing.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/Parsing.h @@ -36,6 +36,13 @@ struct PreparsedRequest { * The parameters passed to the method, if any. */ folly::dynamic params; + + /** + * Equality operator, useful for unit tests + */ + inline bool operator==(const PreparsedRequest& rhs) const { + return id == rhs.id && method == rhs.method && params == rhs.params; + } }; /** diff --git a/packages/react-native/ReactCommon/jsinspector-modern/ReactCdp.h b/packages/react-native/ReactCommon/jsinspector-modern/ReactCdp.h index edbba4ecece..da28a4ae8bc 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/ReactCdp.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/ReactCdp.h @@ -9,3 +9,4 @@ #include #include +#include diff --git a/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.cpp b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.cpp new file mode 100644 index 00000000000..084d8891a38 --- /dev/null +++ b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.cpp @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +namespace facebook::react::jsinspector_modern { + +RuntimeAgent::~RuntimeAgent() {} + +} // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.h b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.h new file mode 100644 index 00000000000..7beba2f653f --- /dev/null +++ b/packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook::react::jsinspector_modern { + +/** + * An Agent interface that handles requests from the Chrome DevTools Protocol + * for a particular JS runtime instance. The exact mechanism of sending + * responses/events to the frontend is left up to the implementation, but + * implementations SHOULD use FrontendChannel or a similar abstraction. + */ +class RuntimeAgent { + public: + virtual ~RuntimeAgent(); + + /** + * Handle a CDP request. This implementation must perform any synchronization + * required between the thread on which this method is called and the thread + * where the JS runtime is executing. + * \returns true if this agent has responded, or will respond asynchronously, + * to the request (with either a success or error message). False if the + * agent expects another agent to respond to the request instead. + */ + virtual bool handleRequest(const cdp::PreparsedRequest& req) = 0; +}; + +} // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tests/InspectorMocks.h b/packages/react-native/ReactCommon/jsinspector-modern/tests/InspectorMocks.h index aaafc57c18b..b77b63efd0f 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tests/InspectorMocks.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/tests/InspectorMocks.h @@ -121,6 +121,29 @@ class MockPageTargetDelegate : public PageTargetDelegate { MOCK_METHOD(void, onReload, (const PageReloadRequest& request), (override)); }; -class MockInstanceTargetDelegate : public InstanceTargetDelegate {}; +class MockInstanceTargetDelegate : public InstanceTargetDelegate { + public: + // InstanceTargetDelegate methods + MOCK_METHOD( + std::unique_ptr, + createRuntimeAgent, + (FrontendChannel channel), + (override)); +}; + +class MockRuntimeAgent : public RuntimeAgent { + public: + inline MockRuntimeAgent(FrontendChannel frontendChannel) + : frontendChannel(std::move(frontendChannel)) {} + + // RuntimeAgent methods + MOCK_METHOD( + bool, + handleRequest, + (const cdp::PreparsedRequest& req), + (override)); + + const FrontendChannel frontendChannel; +}; } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tests/PageTargetTest.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tests/PageTargetTest.cpp index ae1c1062f17..3f7b1bc6fcf 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tests/PageTargetTest.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tests/PageTargetTest.cpp @@ -27,6 +27,11 @@ namespace { class PageTargetTest : public Test { protected: + PageTargetTest() { + EXPECT_CALL(instanceTargetDelegate_, createRuntimeAgent(_)) + .WillRepeatedly(runtimeAgents_.lazily_make_unique()); + } + void connect() { ASSERT_FALSE(toPage_) << "Can only connect once in a PageTargetTest."; toPage_ = page_.connect( @@ -47,6 +52,10 @@ class PageTargetTest : public Test { PageTarget page_{pageTargetDelegate_}; + MockInstanceTargetDelegate instanceTargetDelegate_; + + UniquePtrFactory> runtimeAgents_; + private: UniquePtrFactory> remoteConnections_; @@ -183,17 +192,13 @@ TEST_F(PageTargetProtocolTest, PageReloadMethod) { } TEST_F(PageTargetProtocolTest, RegisterUnregisterInstanceWithoutEvents) { - MockInstanceTargetDelegate instanceTargetDelegate; - - auto& instanceTarget = page_.registerInstance(instanceTargetDelegate); + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); page_.unregisterInstance(instanceTarget); } TEST_F(PageTargetTest, ConnectToAlreadyRegisteredInstanceWithoutEvents) { - MockInstanceTargetDelegate instanceTargetDelegate; - - auto& instanceTarget = page_.registerInstance(instanceTargetDelegate); + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); connect(); @@ -212,26 +217,8 @@ TEST_F(PageTargetProtocolTest, RegisterUnregisterInstanceWithEvents) { "method": "Runtime.enable" })"); - MockInstanceTargetDelegate instanceTargetDelegate; + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); - EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ - "method": "Runtime.executionContextCreated", - "params": { - "context": { - "id": 1, - "origin": "", - "name": "React Native" - } - } - })"))); - auto& instanceTarget = page_.registerInstance(instanceTargetDelegate); - - EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ - "method": "Runtime.executionContextDestroyed", - "params": { - "executionContextId": 1 - } - })"))); EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ "method": "Runtime.executionContextsCleared" })"))); @@ -239,88 +226,184 @@ TEST_F(PageTargetProtocolTest, RegisterUnregisterInstanceWithEvents) { } TEST_F(PageTargetTest, ConnectToAlreadyRegisteredInstanceWithEvents) { - MockInstanceTargetDelegate instanceTargetDelegate; - auto& instanceTarget = page_.registerInstance(instanceTargetDelegate); + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); connect(); InSequence s; + EXPECT_CALL(*runtimeAgents_[0], handleRequest(Eq(cdp::preparse(R"({ + "id": 1, + "method": "Runtime.enable" + })")))) + .RetiresOnSaturation(); EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ "id": 1, "result": {} })"))); - EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ - "method": "Runtime.executionContextCreated", - "params": { - "context": { - "id": 1, - "origin": "", - "name": "React Native" - } - } - })"))); toPage_->sendMessage(R"({ "id": 1, "method": "Runtime.enable" })"); - EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ - "method": "Runtime.executionContextDestroyed", - "params": { - "executionContextId": 1 - } - })"))); EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ "method": "Runtime.executionContextsCleared" })"))); page_.unregisterInstance(instanceTarget); } -TEST_F(PageTargetProtocolTest, RespondToHeapUsageMethodWhileInstanceExists) { - // NOTE: This test will be deleted once we add some real CDP method - // implementations to InstanceAgent. +TEST_F(PageTargetProtocolTest, RuntimeAgentLifecycle) { + { + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); + EXPECT_TRUE(runtimeAgents_[0]); + + page_.unregisterInstance(instanceTarget); + } + + EXPECT_FALSE(runtimeAgents_[0]); + + { + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); + + EXPECT_TRUE(runtimeAgents_[1]); + + page_.unregisterInstance(instanceTarget); + } + + EXPECT_FALSE(runtimeAgents_[1]); +} + +TEST_F(PageTargetProtocolTest, MethodNotHandledByRuntimeAgent) { + InSequence s; + + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); + + ASSERT_TRUE(runtimeAgents_[0]); + EXPECT_CALL(*runtimeAgents_[0], handleRequest(_)) + .WillOnce(Return(false)) + .RetiresOnSaturation(); EXPECT_CALL( - fromPage(), - onMessage(JsonParsed(AllOf( - AtJsonPtr("/error/code", Eq(-32601)), AtJsonPtr("/id", Eq(1)))))) + fromPage(), onMessage(JsonParsed(AtJsonPtr("/error/code", Eq(-32601))))) .RetiresOnSaturation(); - toPage_->sendMessage(R"({ "id": 1, - "method": "Runtime.getHeapUsage" - })"); - - MockInstanceTargetDelegate instanceTargetDelegate; - auto& instanceTarget = page_.registerInstance(instanceTargetDelegate); - - EXPECT_CALL(fromPage(), onMessage(JsonEq(R"({ - "id": 2, - "result": { - "usedSize": 0, - "totalSize": 0 - } - })"))); - - toPage_->sendMessage(R"({ - "id": 2, - "method": "Runtime.getHeapUsage" + "method": "CustomRuntimeDomain.Foo", + "params": { + "expression": "42" + } })"); page_.unregisterInstance(instanceTarget); +} + +TEST_F(PageTargetProtocolTest, MethodHandledByRuntimeAgent) { + InSequence s; + + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); + + ASSERT_TRUE(runtimeAgents_[0]); + EXPECT_CALL(*runtimeAgents_[0], handleRequest(_)) + .WillOnce(Return(true)) + .RetiresOnSaturation(); + toPage_->sendMessage(R"({ + "id": 1, + "method": "CustomRuntimeDomain.Foo", + "params": { + "expression": "42" + } + })"); + + static constexpr auto kFooResponse = R"({ + "id": 1, + "result": { + "fooValue": 42 + } + })"; + EXPECT_CALL(fromPage(), onMessage(JsonEq(kFooResponse))) + .RetiresOnSaturation(); + runtimeAgents_[0]->frontendChannel(kFooResponse); + + page_.unregisterInstance(instanceTarget); +} + +TEST_F(PageTargetProtocolTest, MessageRoutingWhileNoRuntimeAgent) { + InSequence s; EXPECT_CALL( - fromPage(), - onMessage(JsonParsed(AllOf( - AtJsonPtr("/error/code", Eq(-32601)), AtJsonPtr("/id", Eq(3)))))) + fromPage(), onMessage(JsonParsed(AtJsonPtr("/error/code", Eq(-32601))))) .RetiresOnSaturation(); + toPage_->sendMessage(R"({ + "id": 1, + "method": "CustomRuntimeDomain.Foo", + "params": { + "expression": "42" + } + })"); + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); + + ASSERT_TRUE(runtimeAgents_[0]); + EXPECT_CALL(*runtimeAgents_[0], handleRequest(_)) + .WillOnce(Return(true)) + .RetiresOnSaturation(); + toPage_->sendMessage(R"({ + "id": 2, + "method": "CustomRuntimeDomain.Foo", + "params": { + "expression": "42" + } + })"); + + static constexpr auto kFooResponse = R"({ + "id": 2, + "result": { + "fooValue": 42 + } + })"; + EXPECT_CALL(fromPage(), onMessage(JsonEq(kFooResponse))) + .RetiresOnSaturation(); + runtimeAgents_[0]->frontendChannel(kFooResponse); + + page_.unregisterInstance(instanceTarget); + + EXPECT_FALSE(runtimeAgents_[0]); + + EXPECT_CALL( + fromPage(), onMessage(JsonParsed(AtJsonPtr("/error/code", Eq(-32601))))) + .RetiresOnSaturation(); toPage_->sendMessage(R"({ "id": 3, - "method": "Runtime.getHeapUsage" + "method": "CustomRuntimeDomain.Foo", + "params": { + "expression": "42" + } })"); } +TEST_F(PageTargetProtocolTest, InstanceWithNullRuntimeAgent) { + InSequence s; + + EXPECT_CALL(instanceTargetDelegate_, createRuntimeAgent(_)) + .WillRepeatedly(ReturnNull()); + + auto& instanceTarget = page_.registerInstance(instanceTargetDelegate_); + + EXPECT_FALSE(runtimeAgents_[0]); + + EXPECT_CALL( + fromPage(), onMessage(JsonParsed(AtJsonPtr("/error/code", Eq(-32601))))) + .RetiresOnSaturation(); + toPage_->sendMessage(R"({ + "id": 1, + "method": "CustomRuntimeDomain.Foo", + "params": { + "expression": "42" + } + })"); + + page_.unregisterInstance(instanceTarget); +} + } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.cpp b/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.cpp index a0b11fe6686..e9e338b539a 100644 --- a/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.cpp +++ b/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.cpp @@ -8,6 +8,7 @@ #include "JSRuntimeFactory.h" namespace facebook::react { + jsi::Runtime& JSIRuntimeHolder::getRuntime() noexcept { return *runtime_; } @@ -16,4 +17,12 @@ JSIRuntimeHolder::JSIRuntimeHolder(std::unique_ptr runtime) : runtime_(std::move(runtime)) { assert(runtime_ != nullptr); } + +std::unique_ptr +JSIRuntimeHolder::createInspectorAgent( + jsinspector_modern::FrontendChannel frontendChannel) { + (void)frontendChannel; + return nullptr; +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.h b/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.h index 110c1f26590..0ffdb7896d7 100644 --- a/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.h +++ b/packages/react-native/ReactCommon/react/runtime/JSRuntimeFactory.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace facebook::react { @@ -20,6 +21,14 @@ class JSRuntime { public: virtual jsi::Runtime& getRuntime() noexcept = 0; + /** + * Creates a new inspector agent for this runtime, if the runtime is + * inspectable. Returns nullptr otherwise. + * \see InspectorTargetDelegate::createRuntimeAgent + */ + virtual std::unique_ptr + createInspectorAgent(jsinspector_modern::FrontendChannel frontendChannel) = 0; + virtual ~JSRuntime() = default; }; @@ -40,6 +49,8 @@ class JSRuntimeFactory { class JSIRuntimeHolder : public JSRuntime { public: jsi::Runtime& getRuntime() noexcept override; + std::unique_ptr createInspectorAgent( + jsinspector_modern::FrontendChannel frontendChannel) override; explicit JSIRuntimeHolder(std::unique_ptr runtime); diff --git a/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec b/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec index 15ba2bde3ea..eeb27776bf6 100644 --- a/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec +++ b/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec @@ -33,7 +33,7 @@ Pod::Spec.new do |s| s.source = source s.source_files = "hermes/*.{cpp,h}" s.header_dir = "react/runtime/hermes" - s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"${PODS_TARGET_SRCROOT}/../..\" \"${PODS_TARGET_SRCROOT}/../../hermes/executor\"", + s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"${PODS_TARGET_SRCROOT}/../..\" \"${PODS_TARGET_SRCROOT}/../../hermes/executor\" \"$(PODS_ROOT)/boost\"", "USE_HEADERMAP" => "YES", "CLANG_CXX_LANGUAGE_STANDARD" => "c++20", "GCC_WARN_PEDANTIC" => "YES" } diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp index cea0bfd0cd4..988fd15242c 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp @@ -460,4 +460,10 @@ void ReactInstance::handleMemoryPressureJs(int pressureLevel) { } } +std::unique_ptr +ReactInstance::createRuntimeAgent(jsinspector_modern::FrontendChannel channel) { + auto agent = runtime_->createInspectorAgent(std::move(channel)); + return agent; +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.h b/packages/react-native/ReactCommon/react/runtime/ReactInstance.h index e4fa651ae39..c52b916defe 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.h @@ -72,6 +72,10 @@ class ReactInstance final : private jsinspector_modern::InstanceTargetDelegate { void unregisterFromInspector(); private: + // From InstanceTargetDelegate + std::unique_ptr createRuntimeAgent( + jsinspector_modern::FrontendChannel channel) override; + std::shared_ptr runtime_; std::shared_ptr jsMessageQueueThread_; std::shared_ptr bufferedRuntimeExecutor_; diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 8a9a12708d9..55a146f89ec 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -123,6 +123,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -139,6 +140,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -154,7 +156,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -172,7 +174,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -189,6 +191,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -205,6 +208,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -221,6 +225,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -237,6 +242,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -253,6 +259,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -269,6 +276,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -285,6 +293,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -301,6 +310,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -317,6 +327,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -333,6 +344,7 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils @@ -349,17 +361,21 @@ PODS: - React-hermes - React-jsi - React-jsiexecutor + - React-jsinspector - React-perflogger - React-runtimescheduler - React-utils - SocketRocket (= 0.7.0) - Yoga - React-CoreModules (1000.0.0): + - DoubleConversion + - fmt (= 9.1.0) - RCT-Folly (= 2024.01.01.00) - RCTTypeSafety (= 1000.0.0) - React-Codegen - React-Core/CoreModulesHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) + - React-jsinspector - React-NativeModulesApple - React-RCTBlob - React-RCTImage (= 1000.0.0) @@ -375,7 +391,7 @@ PODS: - React-callinvoker (= 1000.0.0) - React-debug (= 1000.0.0) - React-jsi (= 1000.0.0) - - React-jsinspector (= 1000.0.0) + - React-jsinspector - React-logger (= 1000.0.0) - React-perflogger (= 1000.0.0) - React-runtimeexecutor (= 1000.0.0) @@ -967,6 +983,7 @@ PODS: - RCT-Folly (= 2024.01.01.00) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) + - React-jsinspector - React-perflogger (= 1000.0.0) - React-jsinspector (1000.0.0): - DoubleConversion @@ -988,6 +1005,7 @@ PODS: - React-Core - React-cxxreact - React-jsi + - React-jsinspector - React-runtimeexecutor - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core @@ -1026,12 +1044,15 @@ PODS: - React-utils - ReactCommon - React-RCTBlob (1000.0.0): + - DoubleConversion + - fmt (= 9.1.0) - hermes-engine - RCT-Folly (= 2024.01.01.00) - React-Codegen - React-Core/RCTBlobHeaders - React-Core/RCTWebSocket - React-jsi + - React-jsinspector - React-NativeModulesApple - React-RCTNetwork - ReactCommon @@ -1046,6 +1067,7 @@ PODS: - React-graphics - React-ImageManager - React-jsi + - React-jsinspector - React-nativeconfig - React-RCTImage - React-RCTText @@ -1445,9 +1467,9 @@ SPEC CHECKSUMS: FBLazyVector: f4492a543c5a8fa1502d3a5867e3f7252497cfe8 fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 - hermes-engine: 555b5d9c3dd704cf1d6af043928ea8d6936f5945 - MyNativeView: dd2b0ad0ea90d05a1776b18c7d3470aa8b69f9d1 - NativeCxxModuleExample: 31e3c8426cf9ca356c76d253e6fc7e98921a7f4d + hermes-engine: b6ed6780e02b97c31d4d84407f579e3523177780 + MyNativeView: 08e59984e995c857953374e22082d058be3cb945 + NativeCxxModuleExample: 51569707f2da9a460d1ebf74a29d02f0a86c549e OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8 RCT-Folly: 045d6ecaa59d826c5736dfba0b2f4083ff8d79df RCTDeprecation: 3808e36294137f9ee5668f4df2e73dc079cd1dcf @@ -1455,32 +1477,32 @@ SPEC CHECKSUMS: RCTTypeSafety: 5f57d4ae5dfafc85a0f575d756c909b584722c52 React: cb6dc75e09f32aeddb4d8fb58a394a67219a92fe React-callinvoker: bae59cbd6affd712bbfc703839dad868ff35069d - React-Codegen: 25f5198c8c8158ec8ba01ee189d3a1d6b63379d5 - React-Core: f36333c59576ea93c31573bc71fe29893fbc4484 - React-CoreModules: 04058009e696161fd7a9f55b43e04819c41f12e3 - React-cxxreact: d7e2b4279e31dee6ec2af7fd8fdd42b1fd0e655c - React-debug: 296b501a90c41f83961f58c6d96a01330d499da5 - React-Fabric: 2a9b753ed7595c5357f3043fb57fa0055d2f4301 - React-FabricImage: da62cc5089fe6bdaa6ec0ab6ccca75c7d679065d - React-featureflags: 23f83a12963770bf3cff300e8990678192436b36 - React-graphics: 7e646eb47b666d2cb4e148ec4afcecc4253f1736 + React-Codegen: b66fa3765bc7a786e88e56ff92459a41dec00b0f + React-Core: 738c8db837b21aae813479f2eb284d5507a5c256 + React-CoreModules: 0b94c427e958c1b7ce268d03aa39a1f424d76901 + React-cxxreact: dadc89738f0089c3e2b85f36de940a088759b20d + React-debug: 4097205dd5ff0ada516e7df5b6721a9464a6f20b + React-Fabric: a3214cc064ca25e029aff0a42e2beb8c87b71861 + React-FabricImage: 6daf9bcd047ac1c424cfd7cae298089f8d495761 + React-featureflags: 36f601a77af59dca45877a298c804883dd04f8d0 + React-graphics: 8d54d923bef33e9f423d06c4fd51431f917a4b2f React-hermes: 14e7007ebbfcc9f674c9c4f3ac768aa587b6da79 - React-ImageManager: 716592dcbe11a4960e1eb3d82adb264ee15b5f6d - React-jserrorhandler: 13a0cce4e1e445d2ace089dc6122fb85411a11b3 + React-ImageManager: 44304168f3ec4733a0191dadee7b1711291272f4 + React-jserrorhandler: 2809ae4d87fb880d2c18be72bcaed114e79f3993 React-jsi: b7645527d3f77afdea4365488e47dbc5b293177f - React-jsiexecutor: 6baaff1e509ce9269b0457d3a9e442e3ae895c33 - React-jsinspector: 7f94cd18b2d33a9c1fab31fd11949f2e0f777120 - React-jsitracing: dd08057dd5b74119cb406beb42028da85ed5b8a5 + React-jsiexecutor: 42eeb6b4e73e1b50caa3940ad0189171723c6b29 + React-jsinspector: 363ee50f69cb39cc2ee4eef0705f2fc4a33f83f3 + React-jsitracing: 46474207a88a3978c08e191d9cf33a6457722d65 React-logger: 8486d7a1d32b972414b1d34a93470ee2562c6ee2 - React-Mapbuffer: fd0d0306c1c4326be5f18a61e978d32a66b20a85 - React-nativeconfig: 40a2c848083ef4065c163c854e1c82b5f9e9db84 - React-NativeModulesApple: 67ee4e22f916aceaa8ccfc9c849d3e7de5d55b0b + React-Mapbuffer: 9d18546228182de42aae8cb047baa5e14886a922 + React-nativeconfig: a5a38eee09c6a57824489bf9005d46d2e3fbb78b + React-NativeModulesApple: ff03b94214a1628f920b43bb64964860fc227f9f React-perflogger: 70d009f755dd10002183454cdf5ad9b22de4a1d7 React-RCTActionSheet: 943bd5f540f3af1e5a149c13c4de81858edf718a React-RCTAnimation: 07583f0ebfa7154f0e696a75c32a8f8b180fc8c5 React-RCTAppDelegate: 60cfe221df61de818f6e6b200ff55b4346e6ea7c - React-RCTBlob: da87f794f188db6539a05b8e13cbc5a198c94848 - React-RCTFabric: d28cb914dbf28c6316d5863d8e6e11ab66704d8f + React-RCTBlob: 2dbf6931deac47ff5d3910e4c81cdd856ea239d6 + React-RCTFabric: e613b7e4aec23114ee6999295ca97b3f0508ee0f React-RCTImage: 8f46d82257827c2332bc4108fddef1a840f440a7 React-RCTLinking: efa67827466e50e07c5471447c12e474cbc5e336 React-RCTNetwork: a80529d2d90f79caa5e31d49e840735a10d6d91a @@ -1489,17 +1511,17 @@ SPEC CHECKSUMS: React-RCTTest: 3b9f62c66c3814ccace402441597160aefc9e812 React-RCTText: d9925903524a7b179cf7803162a98038e0bfb4fd React-RCTVibration: 33bef249bc4a637ed91bf1cf0d94d9329381dc7b - React-rendererdebug: 0abbd75e947eeae23542f3bf7491b048ae063141 - React-rncore: e903b3d2819a25674403c548ec103f34bf02ba2b - React-RuntimeApple: b43ad6a5d60157f37ff3139e4dfb0cd6340e9be6 - React-RuntimeCore: 7cfdac312222d7260d8ba9604686fbb4aa4f8a13 + React-rendererdebug: bc0f2a1816a4607e85ed603170a413c44c1d2635 + React-rncore: 79f594bc32c96203ab607bd9868ec76caa2f290c + React-RuntimeApple: 504b50d20ddf82de9c2c527c6b5a09119e03b737 + React-RuntimeCore: 9dc8d98bc09b0797c2dca7a30be5e8f84ecf5746 React-runtimeexecutor: e1c32bc249dd3cf3919cb4664fd8dc84ef70cff7 - React-RuntimeHermes: e1d75303b20b761391be4b9443a0181d0ffe4d97 - React-runtimescheduler: d5fecf52a345c1e557499ee86c864089c2a01fb8 - React-utils: d468de964db1cfd301b450755ba00518777704c4 - ReactCommon: 9e0640c274b0b7d1d46fd9e4b0d2e518be4898d5 - ReactCommon-Samples: ca3ac1e08ee7f73d2b3b4a77946cfb44204d09ca - ScreenshotManager: 5cdc3d3097325172021474d2741a0852ba712e05 + React-RuntimeHermes: b1f60690c9ed90d448f1325355f72c662c02e49a + React-runtimescheduler: 0df238ee8e88e1b8874d332856ee7d36870be4ad + React-utils: 00c57742056c9c90e58b1a8cd06ca50d30528d6f + ReactCommon: 4148a8bfb8bbfdbea8f517f98cadeeb0f30c8de8 + ReactCommon-Samples: 5d703e2b5e1c8ddb812e7b7cace5a8effbcc6438 + ScreenshotManager: 823189e19d4e6f7d4792fe1db6b037df7efc2fab SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: 53e99e2a727b8498ea9e8aed8d917b808c9ff2ea diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj index 393fa1e581e..edfdf6aa584 100644 --- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj +++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 111FD3845C7358250C2702B6 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 63C6B5E1C2465D85E9BDB6E5 /* libPods-RNTesterIntegrationTests.a */; }; + 00915AE8006CF5DB156153DD /* Pods_RNTester.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9DA138FE541ED31A6C589D7 /* Pods_RNTester.framework */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */; }; 383889DA23A7398900D06C3E /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */; }; @@ -15,8 +15,8 @@ 5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; }; 8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; }; 832F45BB2A8A6E1F0097B4E6 /* SwiftTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */; }; + 836E54623F6567BB812F3F6A /* Pods_RNTesterUnitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B5084412F9118F6F7FA99DA /* Pods_RNTesterUnitTests.framework */; }; CD10C7A5290BD4EB0033E1ED /* RCTEventEmitterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */; }; - DD6FAB12C0152128DD2DA1BE /* libPods-RNTester.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 175067970892CD30B8B0A8E0 /* libPods-RNTester.a */; }; E62F11832A5C6580000BF1C8 /* FlexibleSizeExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.mm */; }; E62F11842A5C6584000BF1C8 /* UpdatePropertiesExampleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.mm */; }; E7C1241A22BEC44B00DA25C0 /* RNTesterIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */; }; @@ -55,7 +55,7 @@ E7DB216422B2F3EC005AC45F /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB215F22B2F3EC005AC45F /* RCTUIManagerScenarioTests.m */; }; E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7DB213022B2C649005AC45F /* JavaScriptCore.framework */; }; E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7DB218B22B41FCD005AC45F /* XCTest.framework */; }; - F37EF1CF1FC0B3DD56375DC7 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D6942D0981036096211E5BDC /* libPods-RNTesterUnitTests.a */; }; + FA45ED19FFAECF4CFEFE0DC7 /* Pods_RNTesterIntegrationTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 87E71F82CA94BF2D3CA3110A /* Pods_RNTesterIntegrationTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -80,7 +80,6 @@ 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNTester/AppDelegate.h; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = ""; }; - 175067970892CD30B8B0A8E0 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 272E6B3B1BEA849E001FCF37 /* UpdatePropertiesExampleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UpdatePropertiesExampleView.h; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.h; sourceTree = ""; }; 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UpdatePropertiesExampleView.mm; path = RNTester/NativeExampleViews/UpdatePropertiesExampleView.mm; sourceTree = ""; }; 2734C5E31C1D7A09BF872585 /* Pods-RNTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.debug.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.debug.xcconfig"; sourceTree = ""; }; @@ -89,18 +88,18 @@ 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNTester/Images.xcassets; sourceTree = ""; }; 359825B9A5AE4A3F4AA612DD /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = ""; }; 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = ""; }; + 3B5084412F9118F6F7FA99DA /* Pods_RNTesterUnitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RNTesterUnitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "legacy_image@2x.png"; path = "RNTester/legacy_image@2x.png"; sourceTree = ""; }; 5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = ""; }; - 63C6B5E1C2465D85E9BDB6E5 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 66C3087F2D5BF762FE9E6422 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = ""; }; 7CDA7A212644C6BB8C0D00D8 /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = ""; }; 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNTester/LaunchScreen.storyboard; sourceTree = ""; }; 832F45BA2A8A6E1F0097B4E6 /* SwiftTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SwiftTest.swift; path = RNTester/SwiftTest.swift; sourceTree = ""; }; + 87E71F82CA94BF2D3CA3110A /* Pods_RNTesterIntegrationTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RNTesterIntegrationTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8BFB9C61D7BDE894E24BF24F /* Pods-RNTesterUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.release.xcconfig"; path = "Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.release.xcconfig"; sourceTree = ""; }; 9B8542B8C590B51BD0588751 /* Pods-RNTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester.release.xcconfig"; path = "Target Support Files/Pods-RNTester/Pods-RNTester.release.xcconfig"; sourceTree = ""; }; AC474BFB29BBD4A1002BDAED /* RNTester.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = RNTester.xctestplan; path = RNTester/RNTester.xctestplan; sourceTree = ""; }; CD10C7A4290BD4EB0033E1ED /* RCTEventEmitterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTEventEmitterTests.m; sourceTree = ""; }; - D6942D0981036096211E5BDC /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E771AEEA22B44E3100EA1189 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; E7C1241922BEC44B00DA25C0 /* RNTesterIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNTesterIntegrationTests.m; sourceTree = ""; }; E7DB209F22B2BA84005AC45F /* RNTesterUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNTesterUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -162,6 +161,7 @@ E7DB215E22B2F3EC005AC45F /* RCTLoggingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLoggingTests.m; sourceTree = ""; }; E7DB215F22B2F3EC005AC45F /* RCTUIManagerScenarioTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerScenarioTests.m; sourceTree = ""; }; E7DB218B22B41FCD005AC45F /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = XCTest.framework; sourceTree = DEVELOPER_DIR; }; + F9DA138FE541ED31A6C589D7 /* Pods_RNTester.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RNTester.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -169,7 +169,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DD6FAB12C0152128DD2DA1BE /* libPods-RNTester.a in Frameworks */, + 00915AE8006CF5DB156153DD /* Pods_RNTester.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -178,7 +178,7 @@ buildActionMask = 2147483647; files = ( E7DB213122B2C649005AC45F /* JavaScriptCore.framework in Frameworks */, - F37EF1CF1FC0B3DD56375DC7 /* libPods-RNTesterUnitTests.a in Frameworks */, + 836E54623F6567BB812F3F6A /* Pods_RNTesterUnitTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -188,7 +188,7 @@ files = ( E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */, E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */, - 111FD3845C7358250C2702B6 /* libPods-RNTesterIntegrationTests.a in Frameworks */, + FA45ED19FFAECF4CFEFE0DC7 /* Pods_RNTesterIntegrationTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -258,9 +258,9 @@ E7DB211822B2BD53005AC45F /* libReact-RCTText.a */, E7DB211A22B2BD53005AC45F /* libReact-RCTVibration.a */, E7DB212222B2BD53005AC45F /* libyoga.a */, - 175067970892CD30B8B0A8E0 /* libPods-RNTester.a */, - 63C6B5E1C2465D85E9BDB6E5 /* libPods-RNTesterIntegrationTests.a */, - D6942D0981036096211E5BDC /* libPods-RNTesterUnitTests.a */, + F9DA138FE541ED31A6C589D7 /* Pods_RNTester.framework */, + 87E71F82CA94BF2D3CA3110A /* Pods_RNTesterIntegrationTests.framework */, + 3B5084412F9118F6F7FA99DA /* Pods_RNTesterUnitTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -925,6 +925,8 @@ "${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx", "${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers", "${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios", + " ${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers", + " ${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers", ); IPHONEOS_DEPLOYMENT_TARGET = 13.4; MTL_ENABLE_DEBUG_INFO = YES; @@ -941,8 +943,6 @@ OTHER_LDFLAGS = ( "-ObjC", "-lc++", - "-Wl", - "-ld_classic", ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../react-native"; SDKROOT = iphoneos; @@ -1018,6 +1018,8 @@ "${PODS_CONFIGURATION_BUILD_DIR}/React-Fabric/React_Fabric.framework/Headers/react/renderer/components/view/platform/cxx", "${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers", "${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios", + " ${PODS_CONFIGURATION_BUILD_DIR}/ReactCommon/ReactCommon.framework/Headers", + " ${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers", ); IPHONEOS_DEPLOYMENT_TARGET = 13.4; MTL_ENABLE_DEBUG_INFO = NO; @@ -1033,8 +1035,6 @@ OTHER_LDFLAGS = ( "-ObjC", "-lc++", - "-Wl", - "-ld_classic", ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../react-native"; SDKROOT = iphoneos;