Replace "type" with "capabilities" in /json response (#42884)

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

## Context

We're introducing the concept of **capability flags** to provide granular control of behaviours in the Inspector Proxy, to replace the recently added `type: 'Legacy' | 'Modern'` target switch.

A capability flag disables a specific feature/hack in the Inspector Proxy layer by indicating that the target supports one or more modern CDP features.

## This diff

This updates the pages response in `jsinspector-modern` to send a capability flags configuration, replacing `InspectorPageType`/`"type"`.

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D53355413

fbshipit-source-id: 710f9eb11fcc61ab06bfc3051517dd4dd204c68a
This commit is contained in:
Alex Hunt
2024-02-06 04:09:53 -08:00
committed by Facebook GitHub Bot
parent 74ea826464
commit d75fc992a2
6 changed files with 42 additions and 28 deletions
@@ -430,7 +430,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
.integrationName = "iOS Bridge (RCTBridge)",
});
},
facebook::react::jsinspector_modern::InspectorPageType::Modern);
{.nativePageReloads = true});
}
Class bridgeClass = self.bridgeClass;
@@ -24,6 +24,13 @@ IRemoteConnection::~IRemoteConnection() {}
IInspector::~IInspector() {}
IPageStatusListener::~IPageStatusListener() {}
const folly::dynamic targetCapabilitiesToDynamic(
const InspectorTargetCapabilities& capabilities) {
return folly::dynamic::object(
"nativePageReloads", capabilities.nativePageReloads)(
"nativeSourceCodeFetching", capabilities.nativeSourceCodeFetching);
}
namespace {
class InspectorImpl : public IInspector {
@@ -32,7 +39,7 @@ class InspectorImpl : public IInspector {
const std::string& title,
const std::string& vm,
ConnectFunc connectFunc,
InspectorPageType type) override;
InspectorTargetCapabilities capabilities) override;
void removePage(int pageId) override;
std::vector<InspectorPageDescription> getPages() const override;
@@ -51,7 +58,7 @@ class InspectorImpl : public IInspector {
const std::string& title,
const std::string& vm,
ConnectFunc connectFunc,
InspectorPageType type);
InspectorTargetCapabilities capabilities);
operator InspectorPageDescription() const;
ConnectFunc getConnectFunc() const;
@@ -61,7 +68,7 @@ class InspectorImpl : public IInspector {
std::string title_;
std::string vm_;
ConnectFunc connectFunc_;
InspectorPageType type_;
InspectorTargetCapabilities capabilities_;
};
mutable std::mutex mutex_;
int nextPageId_{1};
@@ -74,19 +81,19 @@ InspectorImpl::Page::Page(
const std::string& title,
const std::string& vm,
ConnectFunc connectFunc,
InspectorPageType type)
InspectorTargetCapabilities capabilities)
: id_(id),
title_(title),
vm_(vm),
connectFunc_(std::move(connectFunc)),
type_(type) {}
capabilities_(std::move(capabilities)) {}
InspectorImpl::Page::operator InspectorPageDescription() const {
return InspectorPageDescription{
.id = id_,
.title = title_,
.vm = vm_,
.type = type_,
.capabilities = capabilities_,
};
}
@@ -98,12 +105,13 @@ int InspectorImpl::addPage(
const std::string& title,
const std::string& vm,
ConnectFunc connectFunc,
InspectorPageType type) {
InspectorTargetCapabilities capabilities) {
std::scoped_lock lock(mutex_);
int pageId = nextPageId_++;
assert(pages_.count(pageId) == 0 && "Unexpected duplicate page ID");
pages_.emplace(pageId, Page{pageId, title, vm, std::move(connectFunc), type});
pages_.emplace(
pageId, Page{pageId, title, vm, std::move(connectFunc), capabilities});
return pageId;
}
@@ -7,6 +7,8 @@
#pragma once
#include <folly/dynamic.h>
#include <functional>
#include <memory>
#include <string>
@@ -31,25 +33,19 @@ class IDestructible {
virtual ~IDestructible() = 0;
};
enum class InspectorPageType {
Legacy,
Modern,
struct InspectorTargetCapabilities {
const bool nativePageReloads = false;
const bool nativeSourceCodeFetching = false;
};
inline const char* pageTypeToString(InspectorPageType type) {
switch (type) {
case InspectorPageType::Legacy:
return "Legacy";
case InspectorPageType::Modern:
return "Modern";
}
}
const folly::dynamic targetCapabilitiesToDynamic(
const InspectorTargetCapabilities& capabilities);
struct InspectorPageDescription {
const int id;
const std::string title;
const std::string vm;
const InspectorPageType type;
const InspectorTargetCapabilities capabilities;
};
// Alias for backwards compatibility.
@@ -106,7 +102,7 @@ class JSINSPECTOR_EXPORT IInspector : public IDestructible {
const std::string& title,
const std::string& vm,
ConnectFunc connectFunc,
InspectorPageType type = InspectorPageType::Legacy) = 0;
InspectorTargetCapabilities capabilities = {}) = 0;
/// removePage is called by the VM to remove a page from the list of
/// debuggable pages.
@@ -157,9 +157,15 @@ folly::dynamic InspectorPackagerConnection::Impl::pages() {
folly::dynamic array = folly::dynamic::array();
for (const auto& page : pages) {
array.push_back(folly::dynamic::object("id", std::to_string(page.id))(
"title", page.title + " [C++ connection]")(
"app", app_)("vm", page.vm)("type", pageTypeToString(page.type)));
folly::dynamic pageDescription = folly::dynamic::object;
pageDescription["id"] = std::to_string(page.id);
pageDescription["title"] = page.title + " [C++ connection]";
pageDescription["app"] = app_;
pageDescription["vm"] = page.vm;
pageDescription["capabilities"] =
targetCapabilitiesToDynamic(page.capabilities);
array.push_back(pageDescription);
}
return array;
}
@@ -203,7 +203,8 @@ TEST_F(InspectorPackagerConnectionTest, TestGetPages) {
"mock-title",
"mock-vm",
localConnections_
.lazily_make_unique<std::unique_ptr<IRemoteConnection>>());
.lazily_make_unique<std::unique_ptr<IRemoteConnection>>(),
{.nativePageReloads = true});
// getPages now reports the page we registered.
EXPECT_CALL(
@@ -217,7 +218,10 @@ TEST_F(InspectorPackagerConnectionTest, TestGetPages) {
AtJsonPtr("/title", Eq("mock-title [C++ connection]")),
AtJsonPtr("/vm", Eq("mock-vm")),
AtJsonPtr("/id", Eq(std::to_string(pageId))),
AtJsonPtr("/type", Eq("Legacy")))}))))))
AtJsonPtr("/capabilities/nativePageReloads", Eq(true)),
AtJsonPtr(
"/capabilities/nativeSourceCodeFetching",
Eq(false)))}))))))
.RetiresOnSaturation();
webSockets_[0]->getDelegate().didReceiveMessage(R"({
"event": "getPages"
@@ -186,7 +186,7 @@ class RCTHostPageTargetDelegate : public facebook::react::jsinspector_modern::Pa
.integrationName = "iOS Bridgeless (RCTHost)",
});
},
facebook::react::jsinspector_modern::InspectorPageType::Modern);
{.nativePageReloads = true});
}
if (_instance) {
RCTLogWarn(