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