From aced4072cfebb1c41a06a2a25179c4c0bd173fe0 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Wed, 12 Jun 2024 09:39:08 -0700 Subject: [PATCH] Add ReactNativeApplication CDP domain (#44894) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44894 Adds the new CDP domain `ReactNativeApplication`, with the following messages: - `ReactNativeApplication.enable` (method) — Sent by the connected frontend to enable features under this domain. - `ReactNativeApplication.metadataUpdated` (event) — Sent by the backend containing a metadata object about the host. We intend to use this for displaying richer information in the debugger frontend, such as device information and React Native version. Changelog: [General][Added] - Add `ReactNativeApplication.[enable,metadataUpdated]` CDP messages for reading host metadata Reviewed By: motiz88 Differential Revision: D58288490 fbshipit-source-id: 02384f0cdfaa35f1c5de9fad7ddd5aab483b2768 --- .../jsinspector-modern/HostAgent.cpp | 14 ++++++++ .../jsinspector-modern/HostTarget.cpp | 8 +++++ .../jsinspector-modern/HostTarget.h | 2 ++ .../jsinspector-modern/SessionState.h | 1 + .../tests/JsiIntegrationTest.cpp | 36 +++++++++++++++++++ 5 files changed, 61 insertions(+) diff --git a/packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp b/packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp index 36efb78e951..46c1a94df31 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/HostAgent.cpp @@ -129,6 +129,20 @@ void HostAgent::handleRequest(const cdp::PreparsedRequest& req) { sendFuseboxNotice(); } + shouldSendOKResponse = true; + isFinishedHandlingRequest = true; + } else if (req.method == "ReactNativeApplication.enable") { + sessionState_.isReactNativeApplicationDomainEnabled = true; + + frontendChannel_(cdp::jsonNotification( + "ReactNativeApplication.metadataUpdated", + hostMetadataToDynamic(hostMetadata_))); + + shouldSendOKResponse = true; + isFinishedHandlingRequest = true; + } else if (req.method == "ReactNativeApplication.disable") { + sessionState_.isReactNativeApplicationDomainEnabled = false; + shouldSendOKResponse = true; isFinishedHandlingRequest = true; } else if (req.method == "Tracing.start") { diff --git a/packages/react-native/ReactCommon/jsinspector-modern/HostTarget.cpp b/packages/react-native/ReactCommon/jsinspector-modern/HostTarget.cpp index 69cbf598a13..00810280c05 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/HostTarget.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/HostTarget.cpp @@ -220,4 +220,12 @@ bool HostTargetController::decrementPauseOverlayCounter() { return true; } +folly::dynamic hostMetadataToDynamic(const HostTargetMetadata& metadata) { + folly::dynamic result = folly::dynamic::object; + + result["integrationName"] = metadata.integrationName.value_or(nullptr); + + return result; +} + } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/HostTarget.h b/packages/react-native/ReactCommon/jsinspector-modern/HostTarget.h index dc271e2e056..9fb5ab26f36 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/HostTarget.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/HostTarget.h @@ -251,4 +251,6 @@ class JSINSPECTOR_EXPORT HostTarget friend class HostTargetController; }; +folly::dynamic hostMetadataToDynamic(const HostTargetMetadata& metadata); + } // namespace facebook::react::jsinspector_modern diff --git a/packages/react-native/ReactCommon/jsinspector-modern/SessionState.h b/packages/react-native/ReactCommon/jsinspector-modern/SessionState.h index 36c4c72666f..28074ba4bd3 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/SessionState.h +++ b/packages/react-native/ReactCommon/jsinspector-modern/SessionState.h @@ -22,6 +22,7 @@ struct SessionState { // TODO: Generalise this to arbitrary domains bool isDebuggerDomainEnabled{false}; bool isLogDomainEnabled{false}; + bool isReactNativeApplicationDomainEnabled{false}; bool isRuntimeDomainEnabled{false}; /** diff --git a/packages/react-native/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp b/packages/react-native/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp index c357215339e..c83486375da 100644 --- a/packages/react-native/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp +++ b/packages/react-native/ReactCommon/jsinspector-modern/tests/JsiIntegrationTest.cpp @@ -332,6 +332,42 @@ TYPED_TEST(JsiIntegrationPortableTest, FuseboxSetClientMetadata) { })"); } +TYPED_TEST(JsiIntegrationPortableTest, ReactNativeApplicationEnable) { + this->connect(); + + this->expectMessageFromPage(JsonEq(R"({ + "id": 1, + "result": {} + })")); + this->expectMessageFromPage(JsonEq(R"({ + "method": "ReactNativeApplication.metadataUpdated", + "params": { + "integrationName": "JsiIntegrationTest" + } + })")); + + this->toPage_->sendMessage(R"({ + "id": 1, + "method": "ReactNativeApplication.enable", + "params": {} + })"); +} + +TYPED_TEST(JsiIntegrationPortableTest, ReactNativeApplicationDisable) { + this->connect(); + + this->expectMessageFromPage(JsonEq(R"({ + "id": 1, + "result": {} + })")); + + this->toPage_->sendMessage(R"({ + "id": 1, + "method": "ReactNativeApplication.disable", + "params": {} + })"); +} + #pragma endregion // AllEngines #pragma region AllHermesVariants