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