Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / web / WebDevToolsAgentImpl.cpp
blob5be0482b37c0e8fdeb461925bf96be396eaea4b2
1 /*
2 * Copyright (C) 2010-2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "config.h"
32 #include "web/WebDevToolsAgentImpl.h"
34 #include "bindings/core/v8/ScriptController.h"
35 #include "bindings/core/v8/V8Binding.h"
36 #include "core/InspectorBackendDispatcher.h"
37 #include "core/InspectorFrontend.h"
38 #include "core/frame/FrameConsole.h"
39 #include "core/frame/LocalFrame.h"
40 #include "core/frame/Settings.h"
41 #include "core/inspector/AsyncCallTracker.h"
42 #include "core/inspector/IdentifiersFactory.h"
43 #include "core/inspector/InjectedScriptHost.h"
44 #include "core/inspector/InjectedScriptManager.h"
45 #include "core/inspector/InspectorAnimationAgent.h"
46 #include "core/inspector/InspectorApplicationCacheAgent.h"
47 #include "core/inspector/InspectorCSSAgent.h"
48 #include "core/inspector/InspectorDOMAgent.h"
49 #include "core/inspector/InspectorDOMDebuggerAgent.h"
50 #include "core/inspector/InspectorDebuggerAgent.h"
51 #include "core/inspector/InspectorHeapProfilerAgent.h"
52 #include "core/inspector/InspectorInputAgent.h"
53 #include "core/inspector/InspectorInspectorAgent.h"
54 #include "core/inspector/InspectorInstrumentation.h"
55 #include "core/inspector/InspectorLayerTreeAgent.h"
56 #include "core/inspector/InspectorMemoryAgent.h"
57 #include "core/inspector/InspectorPageAgent.h"
58 #include "core/inspector/InspectorProfilerAgent.h"
59 #include "core/inspector/InspectorResourceAgent.h"
60 #include "core/inspector/InspectorResourceContentLoader.h"
61 #include "core/inspector/InspectorState.h"
62 #include "core/inspector/InspectorTaskRunner.h"
63 #include "core/inspector/InspectorTimelineAgent.h"
64 #include "core/inspector/InspectorTracingAgent.h"
65 #include "core/inspector/InspectorWorkerAgent.h"
66 #include "core/inspector/InstrumentingAgents.h"
67 #include "core/inspector/LayoutEditor.h"
68 #include "core/inspector/MainThreadDebugger.h"
69 #include "core/inspector/PageConsoleAgent.h"
70 #include "core/inspector/PageDebuggerAgent.h"
71 #include "core/inspector/PageRuntimeAgent.h"
72 #include "core/layout/LayoutView.h"
73 #include "core/page/FocusController.h"
74 #include "core/page/Page.h"
75 #include "modules/accessibility/InspectorAccessibilityAgent.h"
76 #include "modules/cachestorage/InspectorCacheStorageAgent.h"
77 #include "modules/device_orientation/DeviceOrientationInspectorAgent.h"
78 #include "modules/filesystem/InspectorFileSystemAgent.h"
79 #include "modules/indexeddb/InspectorIndexedDBAgent.h"
80 #include "modules/screen_orientation/ScreenOrientationInspectorAgent.h"
81 #include "modules/storage/InspectorDOMStorageAgent.h"
82 #include "modules/webdatabase/InspectorDatabaseAgent.h"
83 #include "platform/JSONValues.h"
84 #include "platform/RuntimeEnabledFeatures.h"
85 #include "platform/TraceEvent.h"
86 #include "platform/graphics/GraphicsContext.h"
87 #include "platform/graphics/paint/DisplayItemList.h"
88 #include "public/platform/Platform.h"
89 #include "public/platform/WebLayerTreeView.h"
90 #include "public/platform/WebRect.h"
91 #include "public/platform/WebString.h"
92 #include "public/web/WebDevToolsAgentClient.h"
93 #include "public/web/WebSettings.h"
94 #include "web/DevToolsEmulator.h"
95 #include "web/InspectorEmulationAgent.h"
96 #include "web/InspectorOverlayImpl.h"
97 #include "web/InspectorRenderingAgent.h"
98 #include "web/WebFrameWidgetImpl.h"
99 #include "web/WebInputEventConversion.h"
100 #include "web/WebLocalFrameImpl.h"
101 #include "web/WebSettingsImpl.h"
102 #include "web/WebViewImpl.h"
103 #include "wtf/MathExtras.h"
104 #include "wtf/Noncopyable.h"
105 #include "wtf/text/WTFString.h"
107 namespace blink {
109 class ClientMessageLoopAdapter : public MainThreadDebugger::ClientMessageLoop {
110 public:
111 ~ClientMessageLoopAdapter() override
113 s_instance = nullptr;
116 static void ensureMainThreadDebuggerCreated(WebDevToolsAgentClient* client)
118 if (s_instance)
119 return;
120 OwnPtr<ClientMessageLoopAdapter> instance = adoptPtr(new ClientMessageLoopAdapter(adoptPtr(client->createClientMessageLoop())));
121 s_instance = instance.get();
122 v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate();
123 V8PerIsolateData* data = V8PerIsolateData::from(isolate);
124 data->setScriptDebugger(MainThreadDebugger::create(instance.release(), isolate));
127 static void webViewImplClosed(WebViewImpl* view)
129 if (s_instance)
130 s_instance->m_frozenViews.remove(view);
133 static void webFrameWidgetImplClosed(WebFrameWidgetImpl* widget)
135 if (s_instance)
136 s_instance->m_frozenWidgets.remove(widget);
139 static void continueProgram()
141 // Release render thread if necessary.
142 if (s_instance && s_instance->m_running)
143 MainThreadDebugger::instance()->debugger()->continueProgram();
146 private:
147 ClientMessageLoopAdapter(PassOwnPtr<WebDevToolsAgentClient::WebKitClientMessageLoop> messageLoop)
148 : m_running(false)
149 , m_messageLoop(messageLoop) { }
151 void run(LocalFrame* frame) override
153 if (m_running)
154 return;
155 m_running = true;
157 // 0. Flush pending frontend messages.
158 WebLocalFrameImpl* frameImpl = WebLocalFrameImpl::fromFrame(frame);
159 WebDevToolsAgentImpl* agent = frameImpl->devToolsAgentImpl();
160 agent->flushPendingProtocolNotifications();
162 Vector<WebViewImpl*> views;
163 Vector<WebFrameWidgetImpl*> widgets;
165 // 1. Disable input events.
166 const HashSet<WebViewImpl*>& viewImpls = WebViewImpl::allInstances();
167 HashSet<WebViewImpl*>::const_iterator viewImplsEnd = viewImpls.end();
168 for (HashSet<WebViewImpl*>::const_iterator it = viewImpls.begin(); it != viewImplsEnd; ++it) {
169 WebViewImpl* view = *it;
170 m_frozenViews.add(view);
171 views.append(view);
172 view->setIgnoreInputEvents(true);
175 const HashSet<WebFrameWidgetImpl*>& widgetImpls = WebFrameWidgetImpl::allInstances();
176 HashSet<WebFrameWidgetImpl*>::const_iterator widgetImplsEnd = widgetImpls.end();
177 for (HashSet<WebFrameWidgetImpl*>::const_iterator it = widgetImpls.begin(); it != widgetImplsEnd; ++it) {
178 WebFrameWidgetImpl* widget = *it;
179 m_frozenWidgets.add(widget);
180 widgets.append(widget);
181 widget->setIgnoreInputEvents(true);
184 // 2. Notify embedder about pausing.
185 agent->client()->willEnterDebugLoop();
187 // 3. Disable active objects
188 WebView::willEnterModalLoop();
190 // 4. Process messages until quitNow is called.
191 m_messageLoop->run();
193 // 5. Resume active objects
194 WebView::didExitModalLoop();
196 // 6. Resume input events.
197 for (Vector<WebViewImpl*>::iterator it = views.begin(); it != views.end(); ++it) {
198 if (m_frozenViews.contains(*it)) {
199 // The view was not closed during the dispatch.
200 (*it)->setIgnoreInputEvents(false);
203 for (Vector<WebFrameWidgetImpl*>::iterator it = widgets.begin(); it != widgets.end(); ++it) {
204 if (m_frozenWidgets.contains(*it)) {
205 // The widget was not closed during the dispatch.
206 (*it)->setIgnoreInputEvents(false);
210 // 7. Notify embedder about resuming.
211 agent->client()->didExitDebugLoop();
213 // 8. All views have been resumed, clear the set.
214 m_frozenViews.clear();
215 m_frozenWidgets.clear();
217 m_running = false;
220 void quitNow() override
222 m_messageLoop->quitNow();
225 bool m_running;
226 OwnPtr<WebDevToolsAgentClient::WebKitClientMessageLoop> m_messageLoop;
227 typedef HashSet<WebViewImpl*> FrozenViewsSet;
228 FrozenViewsSet m_frozenViews;
229 typedef HashSet<WebFrameWidgetImpl*> FrozenWidgetsSet;
230 FrozenWidgetsSet m_frozenWidgets;
231 static ClientMessageLoopAdapter* s_instance;
234 ClientMessageLoopAdapter* ClientMessageLoopAdapter::s_instance = nullptr;
236 class PageInjectedScriptHostClient: public InjectedScriptHostClient {
237 public:
238 PageInjectedScriptHostClient() { }
240 ~PageInjectedScriptHostClient() override { }
242 void muteWarningsAndDeprecations()
244 FrameConsole::mute();
245 UseCounter::muteForInspector();
248 void unmuteWarningsAndDeprecations()
250 FrameConsole::unmute();
251 UseCounter::unmuteForInspector();
255 class DebuggerTask : public InspectorTaskRunner::Task {
256 public:
257 DebuggerTask(PassOwnPtr<WebDevToolsAgent::MessageDescriptor> descriptor)
258 : m_descriptor(descriptor)
262 ~DebuggerTask() override {}
263 virtual void run()
265 WebDevToolsAgent* webagent = m_descriptor->agent();
266 if (!webagent)
267 return;
269 WebDevToolsAgentImpl* agentImpl = static_cast<WebDevToolsAgentImpl*>(webagent);
270 if (agentImpl->m_attached)
271 agentImpl->dispatchMessageFromFrontend(m_descriptor->message());
274 private:
275 OwnPtr<WebDevToolsAgent::MessageDescriptor> m_descriptor;
278 // static
279 PassOwnPtrWillBeRawPtr<WebDevToolsAgentImpl> WebDevToolsAgentImpl::create(WebLocalFrameImpl* frame, WebDevToolsAgentClient* client)
281 WebViewImpl* view = frame->viewImpl();
282 // TODO(dgozman): sometimes view->mainFrameImpl() does return null, even though |frame| is meant to be main frame.
283 // See http://crbug.com/526162.
284 bool isMainFrame = view && !frame->parent();
285 if (!isMainFrame) {
286 WebDevToolsAgentImpl* agent = new WebDevToolsAgentImpl(frame, client, nullptr);
287 if (frame->frameWidget())
288 agent->layerTreeViewChanged(toWebFrameWidgetImpl(frame->frameWidget())->layerTreeView());
289 return adoptPtrWillBeNoop(agent);
292 WebDevToolsAgentImpl* agent = new WebDevToolsAgentImpl(frame, client, InspectorOverlayImpl::create(view));
293 agent->registerAgent(InspectorRenderingAgent::create(view));
294 agent->registerAgent(InspectorEmulationAgent::create(view));
295 // TODO(dgozman): migrate each of the following agents to frame once module is ready.
296 agent->registerAgent(InspectorDatabaseAgent::create(view->page()));
297 agent->registerAgent(DeviceOrientationInspectorAgent::create(view->page()));
298 agent->registerAgent(InspectorFileSystemAgent::create(view->page()));
299 agent->registerAgent(InspectorIndexedDBAgent::create(view->page()));
300 agent->registerAgent(InspectorAccessibilityAgent::create(view->page()));
301 agent->registerAgent(InspectorDOMStorageAgent::create(view->page()));
302 agent->registerAgent(InspectorCacheStorageAgent::create());
303 agent->layerTreeViewChanged(view->layerTreeView());
304 return adoptPtrWillBeNoop(agent);
307 WebDevToolsAgentImpl::WebDevToolsAgentImpl(
308 WebLocalFrameImpl* webLocalFrameImpl,
309 WebDevToolsAgentClient* client,
310 PassOwnPtrWillBeRawPtr<InspectorOverlayImpl> overlay)
311 : m_client(client)
312 , m_webLocalFrameImpl(webLocalFrameImpl)
313 , m_attached(false)
314 #if ENABLE(ASSERT)
315 , m_hasBeenDisposed(false)
316 #endif
317 , m_instrumentingAgents(m_webLocalFrameImpl->frame()->instrumentingAgents())
318 , m_injectedScriptManager(InjectedScriptManager::createForPage())
319 , m_resourceContentLoader(InspectorResourceContentLoader::create(m_webLocalFrameImpl->frame()))
320 , m_state(adoptPtrWillBeNoop(new InspectorCompositeState(this)))
321 , m_overlay(overlay)
322 , m_cssAgent(nullptr)
323 , m_resourceAgent(nullptr)
324 , m_layerTreeAgent(nullptr)
325 , m_agents(m_instrumentingAgents.get(), m_state.get())
326 , m_deferredAgentsInitialized(false)
328 ASSERT(isMainThread());
329 ASSERT(m_webLocalFrameImpl->frame());
331 long processId = Platform::current()->getUniqueIdForProcess();
332 ASSERT(processId > 0);
333 IdentifiersFactory::setProcessId(processId);
334 InjectedScriptManager* injectedScriptManager = m_injectedScriptManager.get();
336 OwnPtrWillBeRawPtr<InspectorInspectorAgent> inspectorAgentPtr(InspectorInspectorAgent::create(injectedScriptManager));
337 m_inspectorAgent = inspectorAgentPtr.get();
338 m_agents.append(inspectorAgentPtr.release());
340 OwnPtrWillBeRawPtr<InspectorPageAgent> pageAgentPtr(InspectorPageAgent::create(m_webLocalFrameImpl->frame(), m_overlay.get(), m_resourceContentLoader.get()));
341 m_pageAgent = pageAgentPtr.get();
342 m_agents.append(pageAgentPtr.release());
344 OwnPtrWillBeRawPtr<InspectorDOMAgent> domAgentPtr(InspectorDOMAgent::create(m_pageAgent, injectedScriptManager, m_overlay.get()));
345 m_domAgent = domAgentPtr.get();
346 m_agents.append(domAgentPtr.release());
348 OwnPtrWillBeRawPtr<InspectorLayerTreeAgent> layerTreeAgentPtr(InspectorLayerTreeAgent::create(m_pageAgent));
349 m_layerTreeAgent = layerTreeAgentPtr.get();
350 m_agents.append(layerTreeAgentPtr.release());
352 m_agents.append(InspectorTimelineAgent::create());
354 ClientMessageLoopAdapter::ensureMainThreadDebuggerCreated(m_client);
355 MainThreadDebugger* mainThreadDebugger = MainThreadDebugger::instance();
357 OwnPtrWillBeRawPtr<PageRuntimeAgent> pageRuntimeAgentPtr(PageRuntimeAgent::create(injectedScriptManager, this, mainThreadDebugger->debugger(), m_pageAgent));
358 m_pageRuntimeAgent = pageRuntimeAgentPtr.get();
359 m_agents.append(pageRuntimeAgentPtr.release());
361 OwnPtrWillBeRawPtr<PageConsoleAgent> pageConsoleAgentPtr = PageConsoleAgent::create(injectedScriptManager, m_domAgent, m_pageAgent);
362 m_pageConsoleAgent = pageConsoleAgentPtr.get();
364 OwnPtrWillBeRawPtr<InspectorWorkerAgent> workerAgentPtr = InspectorWorkerAgent::create(pageConsoleAgentPtr.get());
366 OwnPtrWillBeRawPtr<InspectorTracingAgent> tracingAgentPtr = InspectorTracingAgent::create(this, workerAgentPtr.get(), m_pageAgent);
367 m_tracingAgent = tracingAgentPtr.get();
368 m_agents.append(tracingAgentPtr.release());
370 m_agents.append(workerAgentPtr.release());
371 m_agents.append(pageConsoleAgentPtr.release());
373 m_agents.append(ScreenOrientationInspectorAgent::create(*m_webLocalFrameImpl->frame()));
376 WebDevToolsAgentImpl::~WebDevToolsAgentImpl()
378 ASSERT(m_hasBeenDisposed);
381 void WebDevToolsAgentImpl::dispose()
383 // Explicitly dispose of the agent before destructing to ensure
384 // same behavior (and correctness) with and without Oilpan.
385 if (m_attached)
386 Platform::current()->currentThread()->removeTaskObserver(this);
387 #if ENABLE(ASSERT)
388 ASSERT(!m_hasBeenDisposed);
389 m_hasBeenDisposed = true;
390 #endif
393 // static
394 void WebDevToolsAgentImpl::webViewImplClosed(WebViewImpl* webViewImpl)
396 ClientMessageLoopAdapter::webViewImplClosed(webViewImpl);
399 // static
400 void WebDevToolsAgentImpl::webFrameWidgetImplClosed(WebFrameWidgetImpl* webFrameWidgetImpl)
402 ClientMessageLoopAdapter::webFrameWidgetImplClosed(webFrameWidgetImpl);
405 DEFINE_TRACE(WebDevToolsAgentImpl)
407 visitor->trace(m_webLocalFrameImpl);
408 visitor->trace(m_instrumentingAgents);
409 visitor->trace(m_injectedScriptManager);
410 visitor->trace(m_resourceContentLoader);
411 visitor->trace(m_state);
412 visitor->trace(m_overlay);
413 visitor->trace(m_asyncCallTracker);
414 visitor->trace(m_inspectorAgent);
415 visitor->trace(m_domAgent);
416 visitor->trace(m_pageAgent);
417 visitor->trace(m_cssAgent);
418 visitor->trace(m_resourceAgent);
419 visitor->trace(m_layerTreeAgent);
420 visitor->trace(m_tracingAgent);
421 visitor->trace(m_pageRuntimeAgent);
422 visitor->trace(m_pageConsoleAgent);
423 visitor->trace(m_inspectorBackendDispatcher);
424 visitor->trace(m_agents);
427 void WebDevToolsAgentImpl::willBeDestroyed()
429 #if ENABLE(ASSERT)
430 Frame* frame = m_webLocalFrameImpl->frame();
431 ASSERT(frame);
432 ASSERT(m_pageAgent->inspectedFrame()->view());
433 #endif
435 detach();
436 m_injectedScriptManager->disconnect();
437 m_resourceContentLoader->dispose();
438 m_agents.discardAgents();
439 m_instrumentingAgents->reset();
442 void WebDevToolsAgentImpl::initializeDeferredAgents()
444 if (m_deferredAgentsInitialized)
445 return;
446 m_deferredAgentsInitialized = true;
448 InjectedScriptManager* injectedScriptManager = m_injectedScriptManager.get();
450 OwnPtrWillBeRawPtr<InspectorResourceAgent> resourceAgentPtr(InspectorResourceAgent::create(m_pageAgent));
451 m_resourceAgent = resourceAgentPtr.get();
452 m_agents.append(resourceAgentPtr.release());
454 OwnPtrWillBeRawPtr<InspectorCSSAgent> cssAgentPtr(InspectorCSSAgent::create(m_domAgent, m_pageAgent, m_resourceAgent, m_resourceContentLoader.get()));
455 m_cssAgent = cssAgentPtr.get();
456 m_agents.append(cssAgentPtr.release());
458 m_agents.append(InspectorAnimationAgent::create(m_pageAgent, m_domAgent));
460 m_agents.append(InspectorMemoryAgent::create());
462 m_agents.append(InspectorApplicationCacheAgent::create(m_pageAgent));
464 OwnPtrWillBeRawPtr<InspectorDebuggerAgent> debuggerAgentPtr(PageDebuggerAgent::create(MainThreadDebugger::instance(), m_pageAgent, injectedScriptManager));
465 InspectorDebuggerAgent* debuggerAgent = debuggerAgentPtr.get();
466 m_agents.append(debuggerAgentPtr.release());
467 m_asyncCallTracker = adoptPtrWillBeNoop(new AsyncCallTracker(debuggerAgent->v8DebuggerAgent(), m_instrumentingAgents.get()));
469 m_agents.append(InspectorDOMDebuggerAgent::create(injectedScriptManager, m_domAgent, debuggerAgent->v8DebuggerAgent()));
471 m_agents.append(InspectorInputAgent::create(m_pageAgent));
473 v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate();
474 m_agents.append(InspectorProfilerAgent::create(isolate, injectedScriptManager, m_overlay.get()));
476 m_agents.append(InspectorHeapProfilerAgent::create(isolate, injectedScriptManager));
478 m_pageAgent->setDebuggerAgent(debuggerAgent);
479 m_pageConsoleAgent->setDebuggerAgent(debuggerAgent->v8DebuggerAgent());
481 MainThreadDebugger* mainThreadDebugger = MainThreadDebugger::instance();
482 m_injectedScriptManager->injectedScriptHost()->init(
483 m_pageConsoleAgent.get(),
484 debuggerAgent->v8DebuggerAgent(),
485 bind<PassRefPtr<TypeBuilder::Runtime::RemoteObject>, PassRefPtr<JSONObject>>(&InspectorInspectorAgent::inspect, m_inspectorAgent.get()),
486 mainThreadDebugger->debugger(),
487 adoptPtr(new PageInjectedScriptHostClient()));
489 if (m_overlay)
490 m_overlay->init(m_cssAgent.get(), debuggerAgent, m_domAgent.get());
493 void WebDevToolsAgentImpl::registerAgent(PassOwnPtrWillBeRawPtr<InspectorAgent> agent)
495 m_agents.append(agent);
498 void WebDevToolsAgentImpl::attach(const WebString& hostId)
500 if (m_attached)
501 return;
503 // Set the attached bit first so that sync notifications were delivered.
504 m_attached = true;
506 initializeDeferredAgents();
507 m_resourceAgent->setHostId(hostId);
509 m_inspectorFrontend = adoptPtr(new InspectorFrontend(this));
510 // We can reconnect to existing front-end -> unmute state.
511 m_state->unmute();
512 m_agents.setFrontend(m_inspectorFrontend.get());
514 InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get());
515 InspectorInstrumentation::frontendCreated();
517 m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(this);
518 m_agents.registerInDispatcher(m_inspectorBackendDispatcher.get());
520 Platform::current()->currentThread()->addTaskObserver(this);
523 void WebDevToolsAgentImpl::reattach(const WebString& hostId, const WebString& savedState)
525 if (m_attached)
526 return;
528 attach(hostId);
529 m_state->loadFromCookie(savedState);
530 m_agents.restore();
533 void WebDevToolsAgentImpl::detach()
535 if (!m_attached)
536 return;
538 Platform::current()->currentThread()->removeTaskObserver(this);
540 m_inspectorBackendDispatcher->clearFrontend();
541 m_inspectorBackendDispatcher.clear();
543 // Destroying agents would change the state, but we don't want that.
544 // Pre-disconnect state will be used to restore inspector agents.
545 m_state->mute();
546 m_agents.clearFrontend();
547 m_inspectorFrontend.clear();
549 // Release overlay resources.
550 if (m_overlay)
551 m_overlay->clear();
552 InspectorInstrumentation::frontendDeleted();
553 InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
555 m_attached = false;
558 void WebDevToolsAgentImpl::continueProgram()
560 ClientMessageLoopAdapter::continueProgram();
563 void WebDevToolsAgentImpl::didCommitLoadForLocalFrame(LocalFrame* frame)
565 m_resourceContentLoader->didCommitLoadForLocalFrame(frame);
566 m_agents.didCommitLoadForLocalFrame(frame);
569 bool WebDevToolsAgentImpl::screencastEnabled()
571 return m_pageAgent->screencastEnabled();
574 void WebDevToolsAgentImpl::willAddPageOverlay(const GraphicsLayer* layer)
576 m_layerTreeAgent->willAddPageOverlay(layer);
579 void WebDevToolsAgentImpl::didRemovePageOverlay(const GraphicsLayer* layer)
581 m_layerTreeAgent->didRemovePageOverlay(layer);
584 void WebDevToolsAgentImpl::layerTreeViewChanged(WebLayerTreeView* layerTreeView)
586 m_tracingAgent->setLayerTreeId(layerTreeView ? layerTreeView->layerTreeId() : 0);
589 void WebDevToolsAgentImpl::enableTracing(const String& categoryFilter)
591 m_client->enableTracing(categoryFilter);
594 void WebDevToolsAgentImpl::disableTracing()
596 m_client->disableTracing();
599 void WebDevToolsAgentImpl::dispatchOnInspectorBackend(const WebString& message)
601 if (!m_attached)
602 return;
603 if (WebDevToolsAgent::shouldInterruptForMessage(message))
604 MainThreadDebugger::instance()->taskRunner()->runPendingTasks();
605 else
606 dispatchMessageFromFrontend(message);
609 void WebDevToolsAgentImpl::dispatchMessageFromFrontend(const String& message)
611 InspectorTaskRunner::IgnoreInterruptsScope scope(MainThreadDebugger::instance()->taskRunner());
612 if (m_inspectorBackendDispatcher)
613 m_inspectorBackendDispatcher->dispatch(message);
616 void WebDevToolsAgentImpl::inspectElementAt(const WebPoint& pointInRootFrame)
618 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent;
619 HitTestRequest request(hitType);
620 WebMouseEvent dummyEvent;
621 dummyEvent.type = WebInputEvent::MouseDown;
622 dummyEvent.x = pointInRootFrame.x;
623 dummyEvent.y = pointInRootFrame.y;
624 IntPoint transformedPoint = PlatformMouseEventBuilder(m_webLocalFrameImpl->frameView(), dummyEvent).position();
625 HitTestResult result(request, m_webLocalFrameImpl->frameView()->rootFrameToContents(transformedPoint));
626 m_webLocalFrameImpl->frame()->contentLayoutObject()->hitTest(result);
627 Node* node = result.innerNode();
628 if (!node && m_webLocalFrameImpl->frame()->document())
629 node = m_webLocalFrameImpl->frame()->document()->documentElement();
630 m_domAgent->inspect(node);
633 void WebDevToolsAgentImpl::sendProtocolResponse(int callId, PassRefPtr<JSONObject> message)
635 if (!m_attached)
636 return;
637 flushPendingProtocolNotifications();
638 m_client->sendProtocolMessage(callId, message->toJSONString(), m_stateCookie);
639 m_stateCookie = String();
642 void WebDevToolsAgentImpl::sendProtocolNotification(PassRefPtr<JSONObject> message)
644 if (!m_attached)
645 return;
646 m_notificationQueue.append(message);
649 void WebDevToolsAgentImpl::flush()
651 flushPendingProtocolNotifications();
654 void WebDevToolsAgentImpl::updateInspectorStateCookie(const String& state)
656 m_stateCookie = state;
659 void WebDevToolsAgentImpl::resumeStartup()
661 m_client->resumeStartup();
664 void WebDevToolsAgentImpl::evaluateInWebInspector(long callId, const WebString& script)
666 m_inspectorAgent->evaluateForTestInFrontend(callId, script);
669 void WebDevToolsAgentImpl::flushPendingProtocolNotifications()
671 if (!m_attached)
672 return;
674 m_agents.flushPendingProtocolNotifications();
675 for (size_t i = 0; i < m_notificationQueue.size(); ++i)
676 m_client->sendProtocolMessage(0, m_notificationQueue[i]->toJSONString(), WebString());
677 m_notificationQueue.clear();
680 void WebDevToolsAgentImpl::willProcessTask()
682 if (!m_attached)
683 return;
684 if (InspectorProfilerAgent* profilerAgent = m_instrumentingAgents->inspectorProfilerAgent())
685 profilerAgent->willProcessTask();
688 void WebDevToolsAgentImpl::didProcessTask()
690 if (!m_attached)
691 return;
692 if (InspectorProfilerAgent* profilerAgent = m_instrumentingAgents->inspectorProfilerAgent())
693 profilerAgent->didProcessTask();
694 flushPendingProtocolNotifications();
697 void WebDevToolsAgent::interruptAndDispatch(MessageDescriptor* rawDescriptor)
699 // rawDescriptor can't be a PassOwnPtr because interruptAndDispatch is a WebKit API function.
700 OwnPtr<MessageDescriptor> descriptor = adoptPtr(rawDescriptor);
701 OwnPtr<DebuggerTask> task = adoptPtr(new DebuggerTask(descriptor.release()));
702 MainThreadDebugger::interruptMainThreadAndRun(task.release());
705 bool WebDevToolsAgent::shouldInterruptForMessage(const WebString& message)
707 String commandName;
708 if (!InspectorBackendDispatcher::getCommandName(message, &commandName))
709 return false;
710 return commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_pauseCmd)
711 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_setBreakpointCmd)
712 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_setBreakpointByUrlCmd)
713 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_removeBreakpointCmd)
714 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_setBreakpointsActiveCmd);
717 } // namespace blink