5 #include "src/inspector/v8-inspector-session-impl.h" 7 #include "src/inspector/injected-script.h" 8 #include "src/inspector/inspected-context.h" 9 #include "src/inspector/protocol/Protocol.h" 10 #include "src/inspector/remote-object-id.h" 11 #include "src/inspector/search-util.h" 12 #include "src/inspector/string-util.h" 13 #include "src/inspector/v8-console-agent-impl.h" 14 #include "src/inspector/v8-debugger-agent-impl.h" 15 #include "src/inspector/v8-debugger.h" 16 #include "src/inspector/v8-heap-profiler-agent-impl.h" 17 #include "src/inspector/v8-inspector-impl.h" 18 #include "src/inspector/v8-profiler-agent-impl.h" 19 #include "src/inspector/v8-runtime-agent-impl.h" 20 #include "src/inspector/v8-schema-agent-impl.h" 25 bool V8InspectorSession::canDispatchMethod(
const StringView& method) {
26 return stringViewStartsWith(method,
27 protocol::Runtime::Metainfo::commandPrefix) ||
28 stringViewStartsWith(method,
29 protocol::Debugger::Metainfo::commandPrefix) ||
30 stringViewStartsWith(method,
31 protocol::Profiler::Metainfo::commandPrefix) ||
33 method, protocol::HeapProfiler::Metainfo::commandPrefix) ||
34 stringViewStartsWith(method,
35 protocol::Console::Metainfo::commandPrefix) ||
36 stringViewStartsWith(method,
37 protocol::Schema::Metainfo::commandPrefix);
42 return InspectedContext::contextId(context);
45 std::unique_ptr<V8InspectorSessionImpl> V8InspectorSessionImpl::create(
46 V8InspectorImpl* inspector,
int contextGroupId,
int sessionId,
47 V8Inspector::Channel* channel,
const StringView& state) {
48 return std::unique_ptr<V8InspectorSessionImpl>(
new V8InspectorSessionImpl(
49 inspector, contextGroupId, sessionId, channel, state));
52 V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector,
55 V8Inspector::Channel* channel,
56 const StringView& savedState)
57 : m_contextGroupId(contextGroupId),
58 m_sessionId(sessionId),
59 m_inspector(inspector),
61 m_customObjectFormatterEnabled(false),
64 m_runtimeAgent(nullptr),
65 m_debuggerAgent(nullptr),
66 m_heapProfilerAgent(nullptr),
67 m_profilerAgent(nullptr),
68 m_consoleAgent(nullptr),
69 m_schemaAgent(nullptr) {
70 if (savedState.length()) {
71 std::unique_ptr<protocol::Value> state =
72 protocol::StringUtil::parseJSON(toString16(savedState));
73 if (state) m_state = protocol::DictionaryValue::cast(std::move(state));
74 if (!m_state) m_state = protocol::DictionaryValue::create();
76 m_state = protocol::DictionaryValue::create();
79 m_runtimeAgent.reset(
new V8RuntimeAgentImpl(
80 this,
this, agentState(protocol::Runtime::Metainfo::domainName)));
81 protocol::Runtime::Dispatcher::wire(&m_dispatcher, m_runtimeAgent.get());
83 m_debuggerAgent.reset(
new V8DebuggerAgentImpl(
84 this,
this, agentState(protocol::Debugger::Metainfo::domainName)));
85 protocol::Debugger::Dispatcher::wire(&m_dispatcher, m_debuggerAgent.get());
87 m_profilerAgent.reset(
new V8ProfilerAgentImpl(
88 this,
this, agentState(protocol::Profiler::Metainfo::domainName)));
89 protocol::Profiler::Dispatcher::wire(&m_dispatcher, m_profilerAgent.get());
91 m_heapProfilerAgent.reset(
new V8HeapProfilerAgentImpl(
92 this,
this, agentState(protocol::HeapProfiler::Metainfo::domainName)));
93 protocol::HeapProfiler::Dispatcher::wire(&m_dispatcher,
94 m_heapProfilerAgent.get());
96 m_consoleAgent.reset(
new V8ConsoleAgentImpl(
97 this,
this, agentState(protocol::Console::Metainfo::domainName)));
98 protocol::Console::Dispatcher::wire(&m_dispatcher, m_consoleAgent.get());
100 m_schemaAgent.reset(
new V8SchemaAgentImpl(
101 this,
this, agentState(protocol::Schema::Metainfo::domainName)));
102 protocol::Schema::Dispatcher::wire(&m_dispatcher, m_schemaAgent.get());
104 if (savedState.length()) {
105 m_runtimeAgent->restore();
106 m_debuggerAgent->restore();
107 m_heapProfilerAgent->restore();
108 m_profilerAgent->restore();
109 m_consoleAgent->restore();
113 V8InspectorSessionImpl::~V8InspectorSessionImpl() {
114 discardInjectedScripts();
115 m_consoleAgent->disable();
116 m_profilerAgent->disable();
117 m_heapProfilerAgent->disable();
118 m_debuggerAgent->disable();
119 m_runtimeAgent->disable();
120 m_inspector->disconnect(
this);
123 protocol::DictionaryValue* V8InspectorSessionImpl::agentState(
124 const String16& name) {
125 protocol::DictionaryValue* state = m_state->getObject(name);
127 std::unique_ptr<protocol::DictionaryValue> newState =
128 protocol::DictionaryValue::create();
129 state = newState.get();
130 m_state->setObject(name, std::move(newState));
137 class MessageBuffer :
public StringBuffer {
139 static std::unique_ptr<MessageBuffer> create(
140 std::unique_ptr<protocol::Serializable> message) {
141 return std::unique_ptr<MessageBuffer>(
142 new MessageBuffer(std::move(message)));
145 const StringView& string()
override {
147 m_serialized = StringBuffer::create(toStringView(m_message->serialize()));
148 m_message.reset(
nullptr);
150 return m_serialized->string();
154 explicit MessageBuffer(std::unique_ptr<protocol::Serializable> message)
155 : m_message(
std::move(message)) {}
157 std::unique_ptr<protocol::Serializable> m_message;
158 std::unique_ptr<StringBuffer> m_serialized;
163 void V8InspectorSessionImpl::sendProtocolResponse(
164 int callId, std::unique_ptr<protocol::Serializable> message) {
165 m_channel->sendResponse(callId, MessageBuffer::create(std::move(message)));
168 void V8InspectorSessionImpl::sendProtocolNotification(
169 std::unique_ptr<protocol::Serializable> message) {
170 m_channel->sendNotification(MessageBuffer::create(std::move(message)));
173 void V8InspectorSessionImpl::fallThrough(
int callId,
const String16& method,
174 const String16& message) {
179 void V8InspectorSessionImpl::flushProtocolNotifications() {
180 m_channel->flushProtocolNotifications();
183 void V8InspectorSessionImpl::reset() {
184 m_debuggerAgent->reset();
185 m_runtimeAgent->reset();
186 discardInjectedScripts();
189 void V8InspectorSessionImpl::discardInjectedScripts() {
190 m_inspectedObjects.clear();
191 int sessionId = m_sessionId;
192 m_inspector->forEachContext(m_contextGroupId,
193 [&sessionId](InspectedContext* context) {
194 context->discardInjectedScript(sessionId);
198 Response V8InspectorSessionImpl::findInjectedScript(
199 int contextId, InjectedScript*& injectedScript) {
200 injectedScript =
nullptr;
201 InspectedContext* context =
202 m_inspector->getContext(m_contextGroupId, contextId);
203 if (!context)
return Response::Error(
"Cannot find context with specified id");
204 injectedScript = context->getInjectedScript(m_sessionId);
205 if (!injectedScript) {
206 injectedScript = context->createInjectedScript(m_sessionId);
207 if (m_customObjectFormatterEnabled)
208 injectedScript->setCustomObjectFormatterEnabled(
true);
210 return Response::OK();
213 Response V8InspectorSessionImpl::findInjectedScript(
214 RemoteObjectIdBase* objectId, InjectedScript*& injectedScript) {
215 return findInjectedScript(objectId->contextId(), injectedScript);
218 void V8InspectorSessionImpl::releaseObjectGroup(
const StringView& objectGroup) {
219 releaseObjectGroup(toString16(objectGroup));
222 void V8InspectorSessionImpl::releaseObjectGroup(
const String16& objectGroup) {
223 int sessionId = m_sessionId;
224 m_inspector->forEachContext(
225 m_contextGroupId, [&objectGroup, &sessionId](InspectedContext* context) {
226 InjectedScript* injectedScript = context->getInjectedScript(sessionId);
227 if (injectedScript) injectedScript->releaseObjectGroup(objectGroup);
231 bool V8InspectorSessionImpl::unwrapObject(
232 std::unique_ptr<StringBuffer>* error,
const StringView& objectId,
234 std::unique_ptr<StringBuffer>* objectGroup) {
235 String16 objectGroupString;
236 Response response = unwrapObject(toString16(objectId),
object, context,
237 objectGroup ? &objectGroupString :
nullptr);
238 if (!response.isSuccess()) {
240 String16 errorMessage = response.errorMessage();
241 *error = StringBufferImpl::adopt(errorMessage);
245 if (objectGroup) *objectGroup = StringBufferImpl::adopt(objectGroupString);
249 Response V8InspectorSessionImpl::unwrapObject(
const String16& objectId,
252 String16* objectGroup) {
253 std::unique_ptr<RemoteObjectId> remoteId;
254 Response response = RemoteObjectId::parse(objectId, &remoteId);
255 if (!response.isSuccess())
return response;
256 InjectedScript* injectedScript =
nullptr;
257 response = findInjectedScript(remoteId.get(), injectedScript);
258 if (!response.isSuccess())
return response;
259 response = injectedScript->findObject(*remoteId,
object);
260 if (!response.isSuccess())
return response;
261 *context = injectedScript->context()->context();
262 if (objectGroup) *objectGroup = injectedScript->objectGroupName(*remoteId);
263 return Response::OK();
266 std::unique_ptr<protocol::Runtime::API::RemoteObject>
269 const StringView& groupName,
270 bool generatePreview) {
271 return wrapObject(context, value, toString16(groupName), generatePreview);
274 std::unique_ptr<protocol::Runtime::RemoteObject>
277 const String16& groupName,
278 bool generatePreview) {
279 InjectedScript* injectedScript =
nullptr;
280 findInjectedScript(InspectedContext::contextId(context), injectedScript);
281 if (!injectedScript)
return nullptr;
282 std::unique_ptr<protocol::Runtime::RemoteObject> result;
283 injectedScript->wrapObject(
285 generatePreview ? WrapMode::kWithPreview : WrapMode::kNoPreview, &result);
289 std::unique_ptr<protocol::Runtime::RemoteObject>
293 InjectedScript* injectedScript =
nullptr;
294 findInjectedScript(InspectedContext::contextId(context), injectedScript);
295 if (!injectedScript)
return nullptr;
296 return injectedScript->wrapTable(table, columns);
299 void V8InspectorSessionImpl::setCustomObjectFormatterEnabled(
bool enabled) {
300 m_customObjectFormatterEnabled = enabled;
301 int sessionId = m_sessionId;
302 m_inspector->forEachContext(
303 m_contextGroupId, [&enabled, &sessionId](InspectedContext* context) {
304 InjectedScript* injectedScript = context->getInjectedScript(sessionId);
306 injectedScript->setCustomObjectFormatterEnabled(enabled);
310 void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) {
311 m_inspector->forEachContext(m_contextGroupId,
312 [&agent](InspectedContext* context) {
313 agent->reportExecutionContextCreated(context);
317 void V8InspectorSessionImpl::dispatchProtocolMessage(
318 const StringView& message) {
321 std::unique_ptr<protocol::Value> parsedMessage =
322 protocol::StringUtil::parseJSON(message);
323 if (m_dispatcher.parseCommand(parsedMessage.get(), &callId, &method)) {
326 m_dispatcher.dispatch(callId, method, std::move(parsedMessage),
"");
330 std::unique_ptr<StringBuffer> V8InspectorSessionImpl::stateJSON() {
331 String16 json = m_state->serialize();
332 return StringBufferImpl::adopt(json);
335 std::vector<std::unique_ptr<protocol::Schema::API::Domain>>
336 V8InspectorSessionImpl::supportedDomains() {
337 std::vector<std::unique_ptr<protocol::Schema::Domain>> domains =
338 supportedDomainsImpl();
339 std::vector<std::unique_ptr<protocol::Schema::API::Domain>> result;
340 for (
size_t i = 0;
i < domains.size(); ++
i)
341 result.push_back(std::move(domains[
i]));
345 std::vector<std::unique_ptr<protocol::Schema::Domain>>
346 V8InspectorSessionImpl::supportedDomainsImpl() {
347 std::vector<std::unique_ptr<protocol::Schema::Domain>> result;
348 result.push_back(protocol::Schema::Domain::create()
349 .setName(protocol::Runtime::Metainfo::domainName)
350 .setVersion(protocol::Runtime::Metainfo::version)
352 result.push_back(protocol::Schema::Domain::create()
353 .setName(protocol::Debugger::Metainfo::domainName)
354 .setVersion(protocol::Debugger::Metainfo::version)
356 result.push_back(protocol::Schema::Domain::create()
357 .setName(protocol::Profiler::Metainfo::domainName)
358 .setVersion(protocol::Profiler::Metainfo::version)
360 result.push_back(protocol::Schema::Domain::create()
361 .setName(protocol::HeapProfiler::Metainfo::domainName)
362 .setVersion(protocol::HeapProfiler::Metainfo::version)
364 result.push_back(protocol::Schema::Domain::create()
365 .setName(protocol::Schema::Metainfo::domainName)
366 .setVersion(protocol::Schema::Metainfo::version)
371 void V8InspectorSessionImpl::addInspectedObject(
372 std::unique_ptr<V8InspectorSession::Inspectable> inspectable) {
373 m_inspectedObjects.insert(m_inspectedObjects.begin(), std::move(inspectable));
374 if (m_inspectedObjects.size() > kInspectedObjectBufferSize)
375 m_inspectedObjects.resize(kInspectedObjectBufferSize);
378 V8InspectorSession::Inspectable* V8InspectorSessionImpl::inspectedObject(
380 if (num >= m_inspectedObjects.size())
return nullptr;
381 return m_inspectedObjects[num].get();
384 void V8InspectorSessionImpl::schedulePauseOnNextStatement(
385 const StringView& breakReason,
const StringView& breakDetails) {
386 m_debuggerAgent->schedulePauseOnNextStatement(
387 toString16(breakReason),
388 protocol::DictionaryValue::cast(
389 protocol::StringUtil::parseJSON(breakDetails)));
392 void V8InspectorSessionImpl::cancelPauseOnNextStatement() {
393 m_debuggerAgent->cancelPauseOnNextStatement();
396 void V8InspectorSessionImpl::breakProgram(
const StringView& breakReason,
397 const StringView& breakDetails) {
398 m_debuggerAgent->breakProgram(
399 toString16(breakReason),
400 protocol::DictionaryValue::cast(
401 protocol::StringUtil::parseJSON(breakDetails)));
404 void V8InspectorSessionImpl::setSkipAllPauses(
bool skip) {
405 m_debuggerAgent->setSkipAllPauses(skip);
408 void V8InspectorSessionImpl::resume() { m_debuggerAgent->resume(); }
410 void V8InspectorSessionImpl::stepOver() { m_debuggerAgent->stepOver(); }
412 std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
413 V8InspectorSessionImpl::searchInTextByLines(
const StringView& text,
414 const StringView& query,
415 bool caseSensitive,
bool isRegex) {
417 std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches =
418 searchInTextByLinesImpl(
this, toString16(text), toString16(query),
419 caseSensitive, isRegex);
420 std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>> result;
421 for (
size_t i = 0;
i < matches.size(); ++
i)
422 result.push_back(std::move(matches[
i]));