11cb0ef41Sopenharmony_ci#include "worker_agent.h"
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci#include "main_thread_interface.h"
41cb0ef41Sopenharmony_ci#include "worker_inspector.h"
51cb0ef41Sopenharmony_ci#include "util-inl.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cinamespace node {
81cb0ef41Sopenharmony_cinamespace inspector {
91cb0ef41Sopenharmony_cinamespace protocol {
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciclass NodeWorkers
121cb0ef41Sopenharmony_ci    : public std::enable_shared_from_this<NodeWorkers> {
131cb0ef41Sopenharmony_ci public:
141cb0ef41Sopenharmony_ci  explicit NodeWorkers(std::weak_ptr<NodeWorker::Frontend> frontend,
151cb0ef41Sopenharmony_ci                      std::shared_ptr<MainThreadHandle> thread)
161cb0ef41Sopenharmony_ci                      : frontend_(frontend), thread_(thread) {}
171cb0ef41Sopenharmony_ci  void WorkerCreated(const std::string& title,
181cb0ef41Sopenharmony_ci                     const std::string& url,
191cb0ef41Sopenharmony_ci                     bool waiting,
201cb0ef41Sopenharmony_ci                     std::shared_ptr<MainThreadHandle> target);
211cb0ef41Sopenharmony_ci  void Receive(const std::string& id, const std::string& message);
221cb0ef41Sopenharmony_ci  void Send(const std::string& id, const std::string& message);
231cb0ef41Sopenharmony_ci  void Detached(const std::string& id);
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci private:
261cb0ef41Sopenharmony_ci  std::weak_ptr<NodeWorker::Frontend> frontend_;
271cb0ef41Sopenharmony_ci  std::shared_ptr<MainThreadHandle> thread_;
281cb0ef41Sopenharmony_ci  std::unordered_map<std::string, std::unique_ptr<InspectorSession>> sessions_;
291cb0ef41Sopenharmony_ci  int next_target_id_ = 0;
301cb0ef41Sopenharmony_ci};
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cinamespace {
331cb0ef41Sopenharmony_ciclass AgentWorkerInspectorDelegate : public WorkerDelegate {
341cb0ef41Sopenharmony_ci public:
351cb0ef41Sopenharmony_ci  explicit AgentWorkerInspectorDelegate(std::shared_ptr<NodeWorkers> workers)
361cb0ef41Sopenharmony_ci                                        : workers_(workers) {}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  void WorkerCreated(const std::string& title,
391cb0ef41Sopenharmony_ci                     const std::string& url,
401cb0ef41Sopenharmony_ci                     bool waiting,
411cb0ef41Sopenharmony_ci                     std::shared_ptr<MainThreadHandle> target) override {
421cb0ef41Sopenharmony_ci    workers_->WorkerCreated(title, url, waiting, target);
431cb0ef41Sopenharmony_ci  }
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci private:
461cb0ef41Sopenharmony_ci  std::shared_ptr<NodeWorkers> workers_;
471cb0ef41Sopenharmony_ci};
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ciclass ParentInspectorSessionDelegate : public InspectorSessionDelegate {
501cb0ef41Sopenharmony_ci public:
511cb0ef41Sopenharmony_ci  ParentInspectorSessionDelegate(const std::string& id,
521cb0ef41Sopenharmony_ci                                 std::shared_ptr<NodeWorkers> workers)
531cb0ef41Sopenharmony_ci                                 : id_(id), workers_(workers) {}
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  ~ParentInspectorSessionDelegate() override {
561cb0ef41Sopenharmony_ci    workers_->Detached(id_);
571cb0ef41Sopenharmony_ci  }
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  void SendMessageToFrontend(const v8_inspector::StringView& msg) override {
601cb0ef41Sopenharmony_ci    std::string message = protocol::StringUtil::StringViewToUtf8(msg);
611cb0ef41Sopenharmony_ci    workers_->Send(id_, message);
621cb0ef41Sopenharmony_ci  }
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci private:
651cb0ef41Sopenharmony_ci  std::string id_;
661cb0ef41Sopenharmony_ci  std::shared_ptr<NodeWorkers> workers_;
671cb0ef41Sopenharmony_ci};
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_cistd::unique_ptr<NodeWorker::WorkerInfo> WorkerInfo(const std::string& id,
701cb0ef41Sopenharmony_ci                                                   const std::string& title,
711cb0ef41Sopenharmony_ci                                                   const std::string& url) {
721cb0ef41Sopenharmony_ci  return NodeWorker::WorkerInfo::create()
731cb0ef41Sopenharmony_ci      .setWorkerId(id)
741cb0ef41Sopenharmony_ci      .setTitle(title)
751cb0ef41Sopenharmony_ci      .setUrl(url)
761cb0ef41Sopenharmony_ci      .setType("worker").build();
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci}  // namespace
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ciWorkerAgent::WorkerAgent(std::weak_ptr<WorkerManager> manager)
811cb0ef41Sopenharmony_ci                         : manager_(manager) {}
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_civoid WorkerAgent::Wire(UberDispatcher* dispatcher) {
851cb0ef41Sopenharmony_ci  frontend_.reset(new NodeWorker::Frontend(dispatcher->channel()));
861cb0ef41Sopenharmony_ci  NodeWorker::Dispatcher::wire(dispatcher, this);
871cb0ef41Sopenharmony_ci  auto manager = manager_.lock();
881cb0ef41Sopenharmony_ci  CHECK_NOT_NULL(manager);
891cb0ef41Sopenharmony_ci  workers_ =
901cb0ef41Sopenharmony_ci      std::make_shared<NodeWorkers>(frontend_, manager->MainThread());
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ciDispatchResponse WorkerAgent::sendMessageToWorker(const String& message,
941cb0ef41Sopenharmony_ci                                                  const String& sessionId) {
951cb0ef41Sopenharmony_ci  workers_->Receive(sessionId, message);
961cb0ef41Sopenharmony_ci  return DispatchResponse::OK();
971cb0ef41Sopenharmony_ci}
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ciDispatchResponse WorkerAgent::enable(bool waitForDebuggerOnStart) {
1001cb0ef41Sopenharmony_ci  auto manager = manager_.lock();
1011cb0ef41Sopenharmony_ci  if (!manager) {
1021cb0ef41Sopenharmony_ci    return DispatchResponse::OK();
1031cb0ef41Sopenharmony_ci  }
1041cb0ef41Sopenharmony_ci  if (!event_handle_) {
1051cb0ef41Sopenharmony_ci    std::unique_ptr<AgentWorkerInspectorDelegate> delegate(
1061cb0ef41Sopenharmony_ci            new AgentWorkerInspectorDelegate(workers_));
1071cb0ef41Sopenharmony_ci    event_handle_ = manager->SetAutoAttach(std::move(delegate));
1081cb0ef41Sopenharmony_ci  }
1091cb0ef41Sopenharmony_ci  event_handle_->SetWaitOnStart(waitForDebuggerOnStart);
1101cb0ef41Sopenharmony_ci  return DispatchResponse::OK();
1111cb0ef41Sopenharmony_ci}
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciDispatchResponse WorkerAgent::disable() {
1141cb0ef41Sopenharmony_ci  event_handle_.reset();
1151cb0ef41Sopenharmony_ci  return DispatchResponse::OK();
1161cb0ef41Sopenharmony_ci}
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ciDispatchResponse WorkerAgent::detach(const String& sessionId) {
1191cb0ef41Sopenharmony_ci  workers_->Detached(sessionId);
1201cb0ef41Sopenharmony_ci  return DispatchResponse::OK();
1211cb0ef41Sopenharmony_ci}
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_civoid NodeWorkers::WorkerCreated(const std::string& title,
1241cb0ef41Sopenharmony_ci                                const std::string& url,
1251cb0ef41Sopenharmony_ci                                bool waiting,
1261cb0ef41Sopenharmony_ci                                std::shared_ptr<MainThreadHandle> target) {
1271cb0ef41Sopenharmony_ci  auto frontend = frontend_.lock();
1281cb0ef41Sopenharmony_ci  if (!frontend)
1291cb0ef41Sopenharmony_ci    return;
1301cb0ef41Sopenharmony_ci  std::string id = std::to_string(++next_target_id_);
1311cb0ef41Sopenharmony_ci  auto delegate = thread_->MakeDelegateThreadSafe(
1321cb0ef41Sopenharmony_ci      std::unique_ptr<InspectorSessionDelegate>(
1331cb0ef41Sopenharmony_ci          new ParentInspectorSessionDelegate(id, shared_from_this())));
1341cb0ef41Sopenharmony_ci  sessions_[id] = target->Connect(std::move(delegate), true);
1351cb0ef41Sopenharmony_ci  frontend->attachedToWorker(id, WorkerInfo(id, title, url), waiting);
1361cb0ef41Sopenharmony_ci}
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_civoid NodeWorkers::Send(const std::string& id, const std::string& message) {
1391cb0ef41Sopenharmony_ci  auto frontend = frontend_.lock();
1401cb0ef41Sopenharmony_ci  if (frontend)
1411cb0ef41Sopenharmony_ci    frontend->receivedMessageFromWorker(id, message);
1421cb0ef41Sopenharmony_ci}
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_civoid NodeWorkers::Receive(const std::string& id, const std::string& message) {
1451cb0ef41Sopenharmony_ci  auto it = sessions_.find(id);
1461cb0ef41Sopenharmony_ci  if (it != sessions_.end())
1471cb0ef41Sopenharmony_ci    it->second->Dispatch(Utf8ToStringView(message)->string());
1481cb0ef41Sopenharmony_ci}
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_civoid NodeWorkers::Detached(const std::string& id) {
1511cb0ef41Sopenharmony_ci  if (sessions_.erase(id) == 0)
1521cb0ef41Sopenharmony_ci    return;
1531cb0ef41Sopenharmony_ci  auto frontend = frontend_.lock();
1541cb0ef41Sopenharmony_ci  if (frontend) {
1551cb0ef41Sopenharmony_ci    frontend->detachedFromWorker(id);
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci}
1581cb0ef41Sopenharmony_ci}  // namespace protocol
1591cb0ef41Sopenharmony_ci}  // namespace inspector
1601cb0ef41Sopenharmony_ci}  // namespace node
161