jiuyiUniapp/service/node_modules/react-native/ReactCommon/jsinspector-modern/InstanceAgent.cpp

156 lines
5.0 KiB
C++

/*
* 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 <jsinspector-modern/InstanceAgent.h>
#include "CdpJson.h"
#include "RuntimeTarget.h"
namespace facebook::react::jsinspector_modern {
InstanceAgent::InstanceAgent(
FrontendChannel frontendChannel,
InstanceTarget& target,
SessionState& sessionState)
: frontendChannel_(frontendChannel),
target_(target),
sessionState_(sessionState) {
(void)target_;
}
bool InstanceAgent::handleRequest(const cdp::PreparsedRequest& req) {
if (req.method == "Runtime.enable") {
maybeSendExecutionContextCreatedNotification();
maybeSendPendingConsoleMessages();
// Fall through
}
if (runtimeAgent_ && runtimeAgent_->handleRequest(req)) {
return true;
}
return false;
}
void InstanceAgent::setCurrentRuntime(RuntimeTarget* runtimeTarget) {
auto previousRuntimeAgent = std::move(runtimeAgent_);
if (runtimeTarget) {
runtimeAgent_ = runtimeTarget->createAgent(frontendChannel_, sessionState_);
} else {
runtimeAgent_.reset();
}
if (!sessionState_.isRuntimeDomainEnabled) {
return;
}
if (previousRuntimeAgent != nullptr) {
auto& previousContext =
previousRuntimeAgent->getExecutionContextDescription();
folly::dynamic params =
folly::dynamic::object("executionContextId", previousContext.id);
if (previousContext.uniqueId.has_value()) {
params["executionContextUniqueId"] = *previousContext.uniqueId;
}
frontendChannel_(
cdp::jsonNotification("Runtime.executionContextDestroyed", params));
}
maybeSendExecutionContextCreatedNotification();
maybeSendPendingConsoleMessages();
}
void InstanceAgent::maybeSendExecutionContextCreatedNotification() {
if (runtimeAgent_ != nullptr) {
auto& newContext = runtimeAgent_->getExecutionContextDescription();
folly::dynamic params = folly::dynamic::object(
"context",
folly::dynamic::object("id", newContext.id)(
"origin", newContext.origin)("name", newContext.name));
if (newContext.uniqueId.has_value()) {
params["uniqueId"] = *newContext.uniqueId;
}
frontendChannel_(
cdp::jsonNotification("Runtime.executionContextCreated", params));
}
}
void InstanceAgent::sendConsoleMessage(SimpleConsoleMessage message) {
if (runtimeAgent_ && sessionState_.isRuntimeDomainEnabled) {
sendConsoleMessageImmediately(std::move(message));
} else {
sessionState_.pendingSimpleConsoleMessages.emplace_back(std::move(message));
}
}
static std::string consoleMessageTypeName(ConsoleAPIType type) {
switch (type) {
case ConsoleAPIType::kLog:
return "log";
case ConsoleAPIType::kDebug:
return "debug";
case ConsoleAPIType::kInfo:
return "info";
case ConsoleAPIType::kError:
return "error";
case ConsoleAPIType::kWarning:
return "warning";
case ConsoleAPIType::kDir:
return "dir";
case ConsoleAPIType::kDirXML:
return "dirxml";
case ConsoleAPIType::kTable:
return "table";
case ConsoleAPIType::kTrace:
return "trace";
case ConsoleAPIType::kStartGroup:
return "startGroup";
case ConsoleAPIType::kStartGroupCollapsed:
return "startGroupCollapsed";
case ConsoleAPIType::kEndGroup:
return "endGroup";
case ConsoleAPIType::kClear:
return "clear";
case ConsoleAPIType::kAssert:
return "assert";
case ConsoleAPIType::kTimeEnd:
return "timeEnd";
case ConsoleAPIType::kCount:
return "count";
default:
assert(false && "unknown console API type");
return "error";
}
}
void InstanceAgent::sendConsoleMessageImmediately(
SimpleConsoleMessage message) {
assert(runtimeAgent_ != nullptr);
folly::dynamic argsParam = folly::dynamic::array();
for (auto& arg : message.args) {
argsParam.push_back(folly::dynamic::object("type", "string")("value", arg));
}
frontendChannel_(cdp::jsonNotification(
"Runtime.consoleAPICalled",
folly::dynamic::object("type", consoleMessageTypeName(message.type))(
"timestamp", message.timestamp)("args", std::move(argsParam))(
"executionContextId",
runtimeAgent_->getExecutionContextDescription().id)(
// We use the @cdp Runtime.consoleAPICalled `context` parameter to
// mark synthetic messages generated by the backend, i.e. not
// originating in a real `console.*` API call.
"context",
runtimeAgent_->getExecutionContextDescription().name +
"#InstanceAgent")));
}
void InstanceAgent::maybeSendPendingConsoleMessages() {
if (runtimeAgent_ != nullptr) {
auto messages = std::move(sessionState_.pendingSimpleConsoleMessages);
sessionState_.pendingSimpleConsoleMessages.clear();
for (auto& message : messages) {
sendConsoleMessageImmediately(std::move(message));
}
}
}
} // namespace facebook::react::jsinspector_modern