Web Inspector: Push Remote Inspector debugging connection management into JavaScriptCore
[WebKit-https.git] / Source / WebCore / inspector / InspectorController.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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.
17  *
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.
29  */
30
31 #include "config.h"
32
33 #if ENABLE(INSPECTOR)
34
35 #include "InspectorController.h"
36
37 #include "DOMWrapperWorld.h"
38 #include "GraphicsContext.h"
39 #include "IdentifiersFactory.h"
40 #include "InjectedScriptHost.h"
41 #include "InjectedScriptManager.h"
42 #include "InspectorAgent.h"
43 #include "InspectorApplicationCacheAgent.h"
44 #include "InspectorBackendDispatchers.h"
45 #include "InspectorBaseAgent.h"
46 #include "InspectorCSSAgent.h"
47 #include "InspectorCanvasAgent.h"
48 #include "InspectorClient.h"
49 #include "InspectorDOMAgent.h"
50 #include "InspectorDOMDebuggerAgent.h"
51 #include "InspectorDOMStorageAgent.h"
52 #include "InspectorDatabaseAgent.h"
53 #include "InspectorDebuggerAgent.h"
54 #include "InspectorFrontend.h"
55 #include "InspectorFrontendClient.h"
56 #include "InspectorHeapProfilerAgent.h"
57 #include "InspectorIndexedDBAgent.h"
58 #include "InspectorInputAgent.h"
59 #include "InspectorInstrumentation.h"
60 #include "InspectorLayerTreeAgent.h"
61 #include "InspectorMemoryAgent.h"
62 #include "InspectorOverlay.h"
63 #include "InspectorPageAgent.h"
64 #include "InspectorProfilerAgent.h"
65 #include "InspectorResourceAgent.h"
66 #include "InspectorTimelineAgent.h"
67 #include "InspectorWorkerAgent.h"
68 #include "InstrumentingAgents.h"
69 #include "MainFrame.h"
70 #include "PageConsoleAgent.h"
71 #include "PageDebuggerAgent.h"
72 #include "PageRuntimeAgent.h"
73 #include "Page.h"
74 #include "ScriptObject.h"
75 #include "Settings.h"
76
77 namespace WebCore {
78
79 InspectorController::InspectorController(Page* page, InspectorClient* inspectorClient)
80     : m_instrumentingAgents(InstrumentingAgents::create())
81     , m_injectedScriptManager(InjectedScriptManager::createForPage())
82     , m_overlay(InspectorOverlay::create(page, inspectorClient))
83     , m_inspectorFrontendChannel(nullptr)
84     , m_page(page)
85     , m_inspectorClient(inspectorClient)
86     , m_isUnderTest(false)
87 #if ENABLE(REMOTE_INSPECTOR)
88     , m_hasRemoteFrontend(false)
89 #endif
90 {
91     OwnPtr<InspectorAgent> inspectorAgentPtr(InspectorAgent::create(page, m_injectedScriptManager.get(), m_instrumentingAgents.get()));
92     m_inspectorAgent = inspectorAgentPtr.get();
93     m_agents.append(inspectorAgentPtr.release());
94
95     OwnPtr<InspectorPageAgent> pageAgentPtr(InspectorPageAgent::create(m_instrumentingAgents.get(), page, m_inspectorAgent, m_injectedScriptManager.get(), inspectorClient, m_overlay.get()));
96     InspectorPageAgent* pageAgent = pageAgentPtr.get();
97     m_pageAgent = pageAgentPtr.get();
98     m_agents.append(pageAgentPtr.release());
99
100     OwnPtr<InspectorDOMAgent> domAgentPtr(InspectorDOMAgent::create(m_instrumentingAgents.get(), pageAgent, m_injectedScriptManager.get(), m_overlay.get(), inspectorClient));
101     m_domAgent = domAgentPtr.get();
102     m_agents.append(domAgentPtr.release());
103
104     m_agents.append(InspectorCSSAgent::create(m_instrumentingAgents.get(), m_domAgent));
105
106 #if ENABLE(SQL_DATABASE)
107     OwnPtr<InspectorDatabaseAgent> databaseAgentPtr(InspectorDatabaseAgent::create(m_instrumentingAgents.get()));
108     InspectorDatabaseAgent* databaseAgent = databaseAgentPtr.get();
109     m_agents.append(databaseAgentPtr.release());
110 #endif
111
112 #if ENABLE(INDEXED_DATABASE)
113     m_agents.append(InspectorIndexedDBAgent::create(m_instrumentingAgents.get(), m_injectedScriptManager.get(), pageAgent));
114 #endif
115
116     OwnPtr<InspectorDOMStorageAgent> domStorageAgentPtr(InspectorDOMStorageAgent::create(m_instrumentingAgents.get(), m_pageAgent));
117     InspectorDOMStorageAgent* domStorageAgent = domStorageAgentPtr.get();
118     m_agents.append(domStorageAgentPtr.release());
119
120     OwnPtr<InspectorMemoryAgent> memoryAgentPtr(InspectorMemoryAgent::create(m_instrumentingAgents.get()));
121     m_memoryAgent = memoryAgentPtr.get();
122     m_agents.append(memoryAgentPtr.release());
123
124     m_agents.append(InspectorTimelineAgent::create(m_instrumentingAgents.get(), pageAgent, m_memoryAgent, InspectorTimelineAgent::PageInspector,
125        inspectorClient));
126     m_agents.append(InspectorApplicationCacheAgent::create(m_instrumentingAgents.get(), pageAgent));
127
128     OwnPtr<InspectorResourceAgent> resourceAgentPtr(InspectorResourceAgent::create(m_instrumentingAgents.get(), pageAgent, inspectorClient));
129     m_resourceAgent = resourceAgentPtr.get();
130     m_agents.append(resourceAgentPtr.release());
131
132     OwnPtr<InspectorRuntimeAgent> runtimeAgentPtr(PageRuntimeAgent::create(m_instrumentingAgents.get(), m_injectedScriptManager.get(), page, pageAgent));
133     InspectorRuntimeAgent* runtimeAgent = runtimeAgentPtr.get();
134     m_agents.append(runtimeAgentPtr.release());
135
136     OwnPtr<InspectorConsoleAgent> consoleAgentPtr(PageConsoleAgent::create(m_instrumentingAgents.get(), m_inspectorAgent, m_injectedScriptManager.get(), m_domAgent));
137     InspectorConsoleAgent* consoleAgent = consoleAgentPtr.get();
138     m_agents.append(consoleAgentPtr.release());
139
140 #if ENABLE(JAVASCRIPT_DEBUGGER)
141     OwnPtr<InspectorDebuggerAgent> debuggerAgentPtr(PageDebuggerAgent::create(m_instrumentingAgents.get(), pageAgent, m_injectedScriptManager.get(), m_overlay.get()));
142     m_debuggerAgent = debuggerAgentPtr.get();
143     m_agents.append(debuggerAgentPtr.release());
144
145     OwnPtr<InspectorDOMDebuggerAgent> domDebuggerAgentPtr(InspectorDOMDebuggerAgent::create(m_instrumentingAgents.get(), m_domAgent, m_debuggerAgent, m_inspectorAgent));
146     m_domDebuggerAgent = domDebuggerAgentPtr.get();
147     m_agents.append(domDebuggerAgentPtr.release());
148
149     OwnPtr<InspectorProfilerAgent> profilerAgentPtr(InspectorProfilerAgent::create(m_instrumentingAgents.get(), consoleAgent, page, m_injectedScriptManager.get()));
150     m_profilerAgent = profilerAgentPtr.get();
151     m_agents.append(profilerAgentPtr.release());
152
153     m_agents.append(InspectorHeapProfilerAgent::create(m_instrumentingAgents.get(), m_injectedScriptManager.get()));
154 #endif
155
156     m_agents.append(InspectorWorkerAgent::create(m_instrumentingAgents.get()));
157
158     m_agents.append(InspectorCanvasAgent::create(m_instrumentingAgents.get(), pageAgent, m_injectedScriptManager.get()));
159
160     m_agents.append(InspectorInputAgent::create(m_instrumentingAgents.get(), page));
161
162 #if USE(ACCELERATED_COMPOSITING)
163     m_agents.append(InspectorLayerTreeAgent::create(m_instrumentingAgents.get()));
164 #endif
165
166     ASSERT_ARG(inspectorClient, inspectorClient);
167     m_injectedScriptManager->injectedScriptHost()->init(m_inspectorAgent
168         , consoleAgent
169 #if ENABLE(SQL_DATABASE)
170         , databaseAgent
171 #endif
172         , domStorageAgent
173         , m_domAgent
174         , m_debuggerAgent
175     );
176
177 #if ENABLE(JAVASCRIPT_DEBUGGER)
178     runtimeAgent->setScriptDebugServer(&m_debuggerAgent->scriptDebugServer());
179 #endif
180 }
181
182 InspectorController::~InspectorController()
183 {
184     m_instrumentingAgents->reset();
185     m_agents.discardAgents();
186     ASSERT(!m_inspectorClient);
187 }
188
189 PassOwnPtr<InspectorController> InspectorController::create(Page* page, InspectorClient* client)
190 {
191     return adoptPtr(new InspectorController(page, client));
192 }
193
194 void InspectorController::inspectedPageDestroyed()
195 {
196     disconnectFrontend();
197     m_injectedScriptManager->disconnect();
198     m_inspectorClient->inspectorDestroyed();
199     m_inspectorClient = 0;
200     m_page = 0;
201 }
202
203 void InspectorController::setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> inspectorFrontendClient)
204 {
205     m_inspectorFrontendClient = inspectorFrontendClient;
206 }
207
208 bool InspectorController::hasLocalFrontend() const
209 {
210 #if ENABLE(REMOTE_INSPECTOR)
211     return hasFrontend() && !m_hasRemoteFrontend;
212 #else
213     return hasFrontend();
214 #endif
215 }
216
217 bool InspectorController::hasRemoteFrontend() const
218 {
219 #if ENABLE(REMOTE_INSPECTOR)
220     return m_hasRemoteFrontend;
221 #else
222     return false;
223 #endif
224 }
225
226 bool InspectorController::hasInspectorFrontendClient() const
227 {
228     return m_inspectorFrontendClient;
229 }
230
231 void InspectorController::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld& world)
232 {
233     if (&world != &mainThreadNormalWorld())
234         return;
235
236     // If the page is supposed to serve as InspectorFrontend notify inspector frontend
237     // client that it's cleared so that the client can expose inspector bindings.
238     if (m_inspectorFrontendClient && frame->isMainFrame())
239         m_inspectorFrontendClient->windowObjectCleared();
240 }
241
242 void InspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel)
243 {
244     ASSERT(frontendChannel);
245     ASSERT(m_inspectorClient);
246     ASSERT(!m_inspectorFrontendChannel);
247     ASSERT(!m_inspectorBackendDispatcher);
248
249     m_inspectorFrontendChannel = frontendChannel;
250     m_inspectorBackendDispatcher = InspectorBackendDispatcher::create(frontendChannel);
251
252     m_agents.didCreateFrontendAndBackend(frontendChannel, m_inspectorBackendDispatcher.get());
253
254     InspectorInstrumentation::registerInstrumentingAgents(m_instrumentingAgents.get());
255     InspectorInstrumentation::frontendCreated();
256
257 #if ENABLE(REMOTE_INSPECTOR)
258     if (!m_hasRemoteFrontend)
259         m_page->remoteInspectorInformationDidChange();
260 #endif
261 }
262
263 void InspectorController::disconnectFrontend()
264 {
265     if (!m_inspectorFrontendChannel)
266         return;
267
268     m_agents.willDestroyFrontendAndBackend();
269
270     m_inspectorBackendDispatcher->clearFrontend();
271     m_inspectorBackendDispatcher.clear();
272     m_inspectorFrontendChannel = nullptr;
273
274     // relese overlay page resources
275     m_overlay->freePage();
276     InspectorInstrumentation::frontendDeleted();
277     InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
278
279 #if ENABLE(REMOTE_INSPECTOR)
280     if (!m_hasRemoteFrontend)
281         m_page->remoteInspectorInformationDidChange();
282 #endif
283 }
284
285 void InspectorController::show()
286 {
287     ASSERT(!hasRemoteFrontend());
288
289     if (!enabled())
290         return;
291
292     if (m_inspectorFrontendChannel)
293         m_inspectorClient->bringFrontendToFront();
294     else {
295         InspectorFrontendChannel* frontendChannel = m_inspectorClient->openInspectorFrontend(this);
296         if (frontendChannel)
297             connectFrontend(frontendChannel);
298     }
299 }
300
301 void InspectorController::close()
302 {
303     if (!m_inspectorFrontendChannel)
304         return;
305     disconnectFrontend();
306     m_inspectorClient->closeInspectorFrontend();
307 }
308
309 void InspectorController::setProcessId(long processId)
310 {
311     IdentifiersFactory::setProcessId(processId);
312 }
313
314 bool InspectorController::isUnderTest()
315 {
316     return m_isUnderTest;
317 }
318
319 void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
320 {
321     m_isUnderTest = true;
322     m_inspectorAgent->evaluateForTestInFrontend(callId, script);
323 }
324
325 void InspectorController::drawHighlight(GraphicsContext& context) const
326 {
327     m_overlay->paint(context);
328 }
329
330 void InspectorController::getHighlight(Highlight* highlight) const
331 {
332     m_overlay->getHighlight(highlight);
333 }
334
335 PassRefPtr<InspectorObject> InspectorController::buildObjectForHighlightedNode() const
336 {
337     return m_overlay->buildObjectForHighlightedNode();
338 }
339
340 void InspectorController::inspect(Node* node)
341 {
342     if (!enabled())
343         return;
344
345     if (!hasRemoteFrontend())
346         show();
347
348     m_domAgent->inspect(node);
349 }
350
351 bool InspectorController::enabled() const
352 {
353     return m_inspectorAgent->developerExtrasEnabled();
354 }
355
356 Page* InspectorController::inspectedPage() const
357 {
358     return m_page;
359 }
360
361 void InspectorController::setInjectedScriptForOrigin(const String& origin, const String& source)
362 {
363     m_inspectorAgent->setInjectedScriptForOrigin(origin, source);
364 }
365
366 void InspectorController::dispatchMessageFromFrontend(const String& message)
367 {
368     if (m_inspectorBackendDispatcher)
369         m_inspectorBackendDispatcher->dispatch(message);
370 }
371
372 void InspectorController::hideHighlight()
373 {
374     ErrorString error;
375     m_domAgent->hideHighlight(&error);
376 }
377
378 Node* InspectorController::highlightedNode() const
379 {
380     return m_overlay->highlightedNode();
381 }
382
383 void InspectorController::setIndicating(bool indicating)
384 {
385     // FIXME: For non-iOS clients, we should have InspectorOverlay do something here.
386     if (indicating)
387         m_inspectorClient->indicate();
388     else
389         m_inspectorClient->hideIndication();
390 }
391
392 #if ENABLE(JAVASCRIPT_DEBUGGER)
393 bool InspectorController::profilerEnabled() const
394 {
395     return m_profilerAgent->enabled();
396 }
397
398 void InspectorController::setProfilerEnabled(bool enable)
399 {
400     ErrorString error;
401     if (enable)
402         m_profilerAgent->enable(&error);
403     else
404         m_profilerAgent->disable(&error);
405 }
406
407 void InspectorController::resume()
408 {
409     if (m_debuggerAgent) {
410         ErrorString error;
411         m_debuggerAgent->resume(&error);
412     }
413 }
414 #endif
415
416 void InspectorController::setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize)
417 {
418     m_resourceAgent->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
419 }
420
421 void InspectorController::didBeginFrame()
422 {
423     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
424         timelineAgent->didBeginFrame();
425     if (InspectorCanvasAgent* canvasAgent = m_instrumentingAgents->inspectorCanvasAgent())
426         canvasAgent->didBeginFrame();
427 }
428
429 void InspectorController::didCancelFrame()
430 {
431     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
432         timelineAgent->didCancelFrame();
433 }
434
435 void InspectorController::willComposite()
436 {
437     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
438         timelineAgent->willComposite();
439 }
440
441 void InspectorController::didComposite()
442 {
443     if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
444         timelineAgent->didComposite();
445 }
446
447 } // namespace WebCore
448
449 #endif // ENABLE(INSPECTOR)