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
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
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.
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"
109 class ClientMessageLoopAdapter
: public MainThreadDebugger::ClientMessageLoop
{
111 ~ClientMessageLoopAdapter() override
113 s_instance
= nullptr;
116 static void ensureMainThreadDebuggerCreated(WebDevToolsAgentClient
* client
)
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
)
130 s_instance
->m_frozenViews
.remove(view
);
133 static void webFrameWidgetImplClosed(WebFrameWidgetImpl
* widget
)
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();
147 ClientMessageLoopAdapter(PassOwnPtr
<WebDevToolsAgentClient::WebKitClientMessageLoop
> messageLoop
)
149 , m_messageLoop(messageLoop
) { }
151 void run(LocalFrame
* frame
) override
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
);
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();
220 void quitNow() override
222 m_messageLoop
->quitNow();
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
{
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
{
257 DebuggerTask(PassOwnPtr
<WebDevToolsAgent::MessageDescriptor
> descriptor
)
258 : m_descriptor(descriptor
)
262 ~DebuggerTask() override
{}
265 WebDevToolsAgent
* webagent
= m_descriptor
->agent();
269 WebDevToolsAgentImpl
* agentImpl
= static_cast<WebDevToolsAgentImpl
*>(webagent
);
270 if (agentImpl
->m_attached
)
271 agentImpl
->dispatchMessageFromFrontend(m_descriptor
->message());
275 OwnPtr
<WebDevToolsAgent::MessageDescriptor
> m_descriptor
;
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();
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
)
312 , m_webLocalFrameImpl(webLocalFrameImpl
)
315 , m_hasBeenDisposed(false)
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)))
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.
386 Platform::current()->currentThread()->removeTaskObserver(this);
388 ASSERT(!m_hasBeenDisposed
);
389 m_hasBeenDisposed
= true;
394 void WebDevToolsAgentImpl::webViewImplClosed(WebViewImpl
* webViewImpl
)
396 ClientMessageLoopAdapter::webViewImplClosed(webViewImpl
);
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()
430 Frame
* frame
= m_webLocalFrameImpl
->frame();
432 ASSERT(m_pageAgent
->inspectedFrame()->view());
436 m_injectedScriptManager
->disconnect();
437 m_resourceContentLoader
->dispose();
438 m_agents
.discardAgents();
439 m_instrumentingAgents
->reset();
442 void WebDevToolsAgentImpl::initializeDeferredAgents()
444 if (m_deferredAgentsInitialized
)
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()));
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
)
503 // Set the attached bit first so that sync notifications were delivered.
506 initializeDeferredAgents();
507 m_resourceAgent
->setHostId(hostId
);
509 m_inspectorFrontend
= adoptPtr(new InspectorFrontend(this));
510 // We can reconnect to existing front-end -> unmute state.
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
)
529 m_state
->loadFromCookie(savedState
);
533 void WebDevToolsAgentImpl::detach()
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.
546 m_agents
.clearFrontend();
547 m_inspectorFrontend
.clear();
549 // Release overlay resources.
552 InspectorInstrumentation::frontendDeleted();
553 InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents
.get());
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
)
603 if (WebDevToolsAgent::shouldInterruptForMessage(message
))
604 MainThreadDebugger::instance()->taskRunner()->runPendingTasks();
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
)
637 flushPendingProtocolNotifications();
638 m_client
->sendProtocolMessage(callId
, message
->toJSONString(), m_stateCookie
);
639 m_stateCookie
= String();
642 void WebDevToolsAgentImpl::sendProtocolNotification(PassRefPtr
<JSONObject
> message
)
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()
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()
684 if (InspectorProfilerAgent
* profilerAgent
= m_instrumentingAgents
->inspectorProfilerAgent())
685 profilerAgent
->willProcessTask();
688 void WebDevToolsAgentImpl::didProcessTask()
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
)
708 if (!InspectorBackendDispatcher::getCommandName(message
, &commandName
))
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
);