1 | /* |
2 | * Copyright (C) 2016 Apple 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 |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "WorkerInspectorController.h" |
28 | |
29 | #include "CommandLineAPIHost.h" |
30 | #include "InstrumentingAgents.h" |
31 | #include "JSExecState.h" |
32 | #include "WebHeapAgent.h" |
33 | #include "WebInjectedScriptHost.h" |
34 | #include "WebInjectedScriptManager.h" |
35 | #include "WorkerAuditAgent.h" |
36 | #include "WorkerConsoleAgent.h" |
37 | #include "WorkerDebuggerAgent.h" |
38 | #include "WorkerGlobalScope.h" |
39 | #include "WorkerNetworkAgent.h" |
40 | #include "WorkerRuntimeAgent.h" |
41 | #include "WorkerThread.h" |
42 | #include "WorkerToPageFrontendChannel.h" |
43 | #include <JavaScriptCore/InspectorAgentBase.h> |
44 | #include <JavaScriptCore/InspectorBackendDispatcher.h> |
45 | #include <JavaScriptCore/InspectorFrontendChannel.h> |
46 | #include <JavaScriptCore/InspectorFrontendDispatchers.h> |
47 | #include <JavaScriptCore/InspectorFrontendRouter.h> |
48 | |
49 | #if ENABLE(SERVICE_WORKER) |
50 | #include "ServiceWorkerAgent.h" |
51 | #include "ServiceWorkerGlobalScope.h" |
52 | #endif |
53 | |
54 | namespace WebCore { |
55 | |
56 | using namespace JSC; |
57 | using namespace Inspector; |
58 | |
59 | WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope& workerGlobalScope) |
60 | : m_instrumentingAgents(InstrumentingAgents::create(*this)) |
61 | , m_injectedScriptManager(std::make_unique<WebInjectedScriptManager>(*this, WebInjectedScriptHost::create())) |
62 | , m_frontendRouter(FrontendRouter::create()) |
63 | , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef())) |
64 | , m_executionStopwatch(Stopwatch::create()) |
65 | , m_scriptDebugServer(workerGlobalScope) |
66 | , m_workerGlobalScope(workerGlobalScope) |
67 | { |
68 | ASSERT(workerGlobalScope.isContextThread()); |
69 | |
70 | auto workerContext = workerAgentContext(); |
71 | |
72 | auto consoleAgent = std::make_unique<WorkerConsoleAgent>(workerContext); |
73 | m_instrumentingAgents->setWebConsoleAgent(consoleAgent.get()); |
74 | m_agents.append(WTFMove(consoleAgent)); |
75 | |
76 | if (auto* commandLineAPIHost = m_injectedScriptManager->commandLineAPIHost()) |
77 | commandLineAPIHost->init(m_instrumentingAgents.copyRef()); |
78 | } |
79 | |
80 | WorkerInspectorController::~WorkerInspectorController() |
81 | { |
82 | ASSERT(!m_frontendRouter->hasFrontends()); |
83 | ASSERT(!m_forwardingChannel); |
84 | |
85 | m_instrumentingAgents->reset(); |
86 | } |
87 | |
88 | void WorkerInspectorController::workerTerminating() |
89 | { |
90 | m_injectedScriptManager->disconnect(); |
91 | |
92 | disconnectFrontend(Inspector::DisconnectReason::InspectedTargetDestroyed); |
93 | |
94 | m_agents.discardValues(); |
95 | } |
96 | |
97 | void WorkerInspectorController::connectFrontend() |
98 | { |
99 | ASSERT(!m_frontendRouter->hasFrontends()); |
100 | ASSERT(!m_forwardingChannel); |
101 | |
102 | createLazyAgents(); |
103 | |
104 | callOnMainThread([] { |
105 | InspectorInstrumentation::frontendCreated(); |
106 | }); |
107 | |
108 | m_executionStopwatch->reset(); |
109 | m_executionStopwatch->start(); |
110 | |
111 | m_forwardingChannel = std::make_unique<WorkerToPageFrontendChannel>(m_workerGlobalScope); |
112 | m_frontendRouter->connectFrontend(*m_forwardingChannel.get()); |
113 | m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get()); |
114 | } |
115 | |
116 | void WorkerInspectorController::disconnectFrontend(Inspector::DisconnectReason reason) |
117 | { |
118 | if (!m_frontendRouter->hasFrontends()) |
119 | return; |
120 | |
121 | ASSERT(m_forwardingChannel); |
122 | |
123 | callOnMainThread([] { |
124 | InspectorInstrumentation::frontendDeleted(); |
125 | }); |
126 | |
127 | m_agents.willDestroyFrontendAndBackend(reason); |
128 | m_frontendRouter->disconnectFrontend(*m_forwardingChannel.get()); |
129 | m_forwardingChannel = nullptr; |
130 | } |
131 | |
132 | void WorkerInspectorController::dispatchMessageFromFrontend(const String& message) |
133 | { |
134 | m_backendDispatcher->dispatch(message); |
135 | } |
136 | |
137 | WorkerAgentContext WorkerInspectorController::workerAgentContext() |
138 | { |
139 | AgentContext baseContext = { |
140 | *this, |
141 | *m_injectedScriptManager, |
142 | m_frontendRouter.get(), |
143 | m_backendDispatcher.get(), |
144 | }; |
145 | |
146 | WebAgentContext webContext = { |
147 | baseContext, |
148 | m_instrumentingAgents.get(), |
149 | }; |
150 | |
151 | WorkerAgentContext workerContext = { |
152 | webContext, |
153 | m_workerGlobalScope, |
154 | }; |
155 | |
156 | return workerContext; |
157 | } |
158 | |
159 | void WorkerInspectorController::createLazyAgents() |
160 | { |
161 | if (m_didCreateLazyAgents) |
162 | return; |
163 | |
164 | m_didCreateLazyAgents = true; |
165 | |
166 | auto workerContext = workerAgentContext(); |
167 | |
168 | m_agents.append(std::make_unique<WorkerRuntimeAgent>(workerContext)); |
169 | |
170 | #if ENABLE(SERVICE_WORKER) |
171 | if (is<ServiceWorkerGlobalScope>(m_workerGlobalScope)) { |
172 | m_agents.append(std::make_unique<ServiceWorkerAgent>(workerContext)); |
173 | m_agents.append(std::make_unique<WorkerNetworkAgent>(workerContext)); |
174 | } |
175 | #endif |
176 | |
177 | m_agents.append(std::make_unique<WebHeapAgent>(workerContext)); |
178 | m_agents.append(std::make_unique<WorkerDebuggerAgent>(workerContext)); |
179 | m_agents.append(std::make_unique<WorkerAuditAgent>(workerContext)); |
180 | } |
181 | |
182 | InspectorFunctionCallHandler WorkerInspectorController::functionCallHandler() const |
183 | { |
184 | return WebCore::functionCallHandlerFromAnyThread; |
185 | } |
186 | |
187 | InspectorEvaluateHandler WorkerInspectorController::evaluateHandler() const |
188 | { |
189 | return WebCore::evaluateHandlerFromAnyThread; |
190 | } |
191 | |
192 | VM& WorkerInspectorController::vm() |
193 | { |
194 | return m_workerGlobalScope.vm(); |
195 | } |
196 | |
197 | } // namespace WebCore |
198 | |