1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#pragma once
17
18#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
19
20#if !HAVE_INSPECTOR
21#error("This header can only be used when inspector is enabled")
22#endif
23
24#include "node_options.h"
25#include "v8.h"
26
27#include <cstddef>
28#include <memory>
29
30namespace v8_inspector {
31class StringView;
32}  // namespace v8_inspector
33
34namespace node {
35namespace inspector {
36
37class ParentInspectorHandle;
38class WorkerManager;
39class InspectorSessionDelegate;
40class InspectorSession;
41
42}  // namespace inspector
43}  // namespace node
44
45namespace v8impl {
46
47using node::ExclusiveAccess;
48using node::HostPort;
49using node::inspector::InspectorSession;
50using node::inspector::InspectorSessionDelegate;
51using node::inspector::ParentInspectorHandle;
52using node::inspector::WorkerManager;
53
54class IsolateData;
55using Environment = JSVM_Env__;
56
57class InspectorClient;
58class InspectorIo;
59
60struct ContextInfo {
61  explicit ContextInfo(const std::string& name) : name(name) {}
62  const std::string name;
63  std::string origin;
64  bool is_default = false;
65};
66
67class Agent {
68 public:
69  explicit Agent(Environment* env);
70  ~Agent();
71
72  // Create client_, may create io_ if option enabled
73  bool Start(const std::string& path,
74             std::shared_ptr<ExclusiveAccess<HostPort>> host_port,
75             bool is_main,
76             bool wait_for_connect);
77  // Stop and destroy io_
78  void Stop();
79
80  bool IsListening() { return io_ != nullptr; }
81  // Returns true if the Node inspector is actually in use. It will be true
82  // if either the user explicitly opted into inspector (e.g. with the
83  // --inspect command line flag) or if inspector JS API had been used.
84  bool IsActive();
85
86  // Blocks till frontend connects and sends "runIfWaitingForDebugger"
87  void WaitForConnect();
88  // Blocks till all the sessions with "WaitForDisconnectOnShutdown" disconnect
89  void WaitForDisconnect();
90  void ReportUncaughtException(v8::Local<v8::Value> error,
91                               v8::Local<v8::Message> message);
92
93  // Async stack traces instrumentation.
94  void AsyncTaskScheduled(const v8_inspector::StringView& taskName, void* task,
95                          bool recurring);
96  void AsyncTaskCanceled(void* task);
97  void AsyncTaskStarted(void* task);
98  void AsyncTaskFinished(void* task);
99  void AllAsyncTasksCanceled();
100
101  // Called to create inspector sessions that can be used from the same thread.
102  // The inspector responds by using the delegate to send messages back.
103  std::unique_ptr<InspectorSession> Connect(
104      std::unique_ptr<InspectorSessionDelegate> delegate,
105      bool prevent_shutdown);
106
107  void PauseOnNextJavascriptStatement(const std::string& reason);
108
109  std::string GetWsUrl() const;
110
111  // Can only be called from the main thread.
112  bool StartIoThread();
113
114  std::shared_ptr<ExclusiveAccess<HostPort>> host_port() { return host_port_; }
115  void ContextCreated(v8::Local<v8::Context> context, const ContextInfo& info);
116
117  inline Environment* env() const { return parent_env_; }
118
119 private:
120  Environment* parent_env_;
121  // Encapsulates majority of the Inspector functionality
122  std::shared_ptr<InspectorClient> client_;
123  // Interface for transports, e.g. WebSocket server
124  std::unique_ptr<InspectorIo> io_;
125  std::string path_;
126
127  std::shared_ptr<ExclusiveAccess<HostPort>> host_port_;
128};
129
130}  // namespace v8impl
131
132#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
133