28cdec0236e0e12d64b510cf227626502d073845
[WebKit-https.git] / Source / WebCore / inspector / WorkerInspectorController.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  * Copyright (C) 2015 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "config.h"
33 #include "WorkerInspectorController.h"
34
35 #include "CommandLineAPIHost.h"
36 #include "InspectorInstrumentation.h"
37 #include "InspectorTimelineAgent.h"
38 #include "InstrumentingAgents.h"
39 #include "JSDOMWindowBase.h"
40 #include "JSMainThreadExecState.h"
41 #include "WebInjectedScriptHost.h"
42 #include "WebInjectedScriptManager.h"
43 #include "WorkerConsoleAgent.h"
44 #include "WorkerDebuggerAgent.h"
45 #include "WorkerGlobalScope.h"
46 #include "WorkerReportingProxy.h"
47 #include "WorkerRuntimeAgent.h"
48 #include "WorkerThread.h"
49 #include <inspector/InspectorBackendDispatcher.h>
50 #include <inspector/InspectorFrontendChannel.h>
51 #include <inspector/InspectorFrontendDispatchers.h>
52 #include <inspector/InspectorFrontendRouter.h>
53 #include <wtf/Stopwatch.h>
54
55 using namespace JSC;
56 using namespace Inspector;
57
58 namespace WebCore {
59
60 namespace {
61
62 class PageInspectorProxy : public FrontendChannel {
63     WTF_MAKE_FAST_ALLOCATED;
64 public:
65     explicit PageInspectorProxy(WorkerGlobalScope& workerGlobalScope)
66         : m_workerGlobalScope(workerGlobalScope) { }
67     virtual ~PageInspectorProxy() { }
68
69     virtual ConnectionType connectionType() const override { return ConnectionType::Local; }
70 private:
71     virtual bool sendMessageToFrontend(const String& message) override
72     {
73         m_workerGlobalScope.thread().workerReportingProxy().postMessageToPageInspector(message);
74         return true;
75     }
76     WorkerGlobalScope& m_workerGlobalScope;
77 };
78
79 }
80
81 WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope& workerGlobalScope)
82     : m_workerGlobalScope(workerGlobalScope)
83     , m_instrumentingAgents(InstrumentingAgents::create(*this))
84     , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create()))
85     , m_executionStopwatch(Stopwatch::create())
86     , m_frontendRouter(FrontendRouter::create())
87     , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
88 {
89     AgentContext baseContext = {
90         *this,
91         *m_injectedScriptManager,
92         m_frontendRouter.get(),
93         m_backendDispatcher.get()
94     };
95
96     WebAgentContext webContext = {
97         baseContext,
98         m_instrumentingAgents.get()
99     };
100
101     WorkerAgentContext workerContext = {
102         webContext,
103         workerGlobalScope,
104     };
105
106     auto runtimeAgent = std::make_unique<WorkerRuntimeAgent>(workerContext);
107     m_runtimeAgent = runtimeAgent.get();
108     m_instrumentingAgents->setWorkerRuntimeAgent(m_runtimeAgent);
109     m_agents.append(WTF::move(runtimeAgent));
110
111     auto consoleAgent = std::make_unique<WorkerConsoleAgent>(workerContext);
112     m_instrumentingAgents->setWebConsoleAgent(consoleAgent.get());
113
114     auto debuggerAgent = std::make_unique<WorkerDebuggerAgent>(workerContext);
115     m_runtimeAgent->setScriptDebugServer(&debuggerAgent->scriptDebugServer());
116     m_agents.append(WTF::move(debuggerAgent));
117
118     m_agents.append(std::make_unique<InspectorTimelineAgent>(workerContext, nullptr, InspectorTimelineAgent::WorkerInspector));
119     m_agents.append(WTF::move(consoleAgent));
120
121     if (CommandLineAPIHost* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) {
122         commandLineAPIHost->init(nullptr
123             , nullptr
124             , nullptr
125             , nullptr
126             , nullptr
127         );
128     }
129 }
130  
131 WorkerInspectorController::~WorkerInspectorController()
132 {
133     ASSERT(!m_frontendRouter->hasFrontends());
134     ASSERT(!m_forwardingChannel);
135
136     m_instrumentingAgents->reset();
137 }
138
139 void WorkerInspectorController::connectFrontend()
140 {
141     ASSERT(!m_frontendRouter->hasFrontends());
142     ASSERT(!m_forwardingChannel);
143
144     m_forwardingChannel = std::make_unique<PageInspectorProxy>(m_workerGlobalScope);
145     m_frontendRouter->connectFrontend(m_forwardingChannel.get());
146     m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get());
147 }
148
149 void WorkerInspectorController::disconnectFrontend(Inspector::DisconnectReason reason)
150 {
151     ASSERT(m_frontendRouter->hasFrontends());
152     ASSERT(m_forwardingChannel);
153
154     m_agents.willDestroyFrontendAndBackend(reason);
155     m_frontendRouter->disconnectFrontend(m_forwardingChannel.get());
156     m_forwardingChannel = nullptr;
157 }
158
159 void WorkerInspectorController::dispatchMessageFromFrontend(const String& message)
160 {
161     m_backendDispatcher->dispatch(message);
162 }
163
164 void WorkerInspectorController::resume()
165 {
166     ErrorString unused;
167     m_runtimeAgent->run(unused);
168 }
169
170 InspectorFunctionCallHandler WorkerInspectorController::functionCallHandler() const
171 {
172     return WebCore::functionCallHandlerFromAnyThread;
173 }
174
175 InspectorEvaluateHandler WorkerInspectorController::evaluateHandler() const
176 {
177     return WebCore::evaluateHandlerFromAnyThread;
178 }
179
180 void WorkerInspectorController::willCallInjectedScriptFunction(JSC::ExecState* scriptState, const String& scriptName, int scriptLine)
181 {
182     ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(scriptState);
183     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willCallFunction(scriptExecutionContext, scriptName, scriptLine);
184     m_injectedScriptInstrumentationCookies.append(cookie);
185 }
186
187 void WorkerInspectorController::didCallInjectedScriptFunction(JSC::ExecState* scriptState)
188 {
189     ASSERT(!m_injectedScriptInstrumentationCookies.isEmpty());
190     ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(scriptState);
191     InspectorInstrumentationCookie cookie = m_injectedScriptInstrumentationCookies.takeLast();
192     InspectorInstrumentation::didCallFunction(cookie, scriptExecutionContext);
193 }
194
195 Ref<Stopwatch> WorkerInspectorController::executionStopwatch()
196 {
197     return m_executionStopwatch.copyRef();
198 }
199
200 VM& WorkerInspectorController::vm()
201 {
202     return JSDOMWindowBase::commonVM();
203 }
204
205 } // namespace WebCore