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
54namespace WebCore {
55
56using namespace JSC;
57using namespace Inspector;
58
59WorkerInspectorController::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
80WorkerInspectorController::~WorkerInspectorController()
81{
82 ASSERT(!m_frontendRouter->hasFrontends());
83 ASSERT(!m_forwardingChannel);
84
85 m_instrumentingAgents->reset();
86}
87
88void WorkerInspectorController::workerTerminating()
89{
90 m_injectedScriptManager->disconnect();
91
92 disconnectFrontend(Inspector::DisconnectReason::InspectedTargetDestroyed);
93
94 m_agents.discardValues();
95}
96
97void 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
116void 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
132void WorkerInspectorController::dispatchMessageFromFrontend(const String& message)
133{
134 m_backendDispatcher->dispatch(message);
135}
136
137WorkerAgentContext 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
159void 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
182InspectorFunctionCallHandler WorkerInspectorController::functionCallHandler() const
183{
184 return WebCore::functionCallHandlerFromAnyThread;
185}
186
187InspectorEvaluateHandler WorkerInspectorController::evaluateHandler() const
188{
189 return WebCore::evaluateHandlerFromAnyThread;
190}
191
192VM& WorkerInspectorController::vm()
193{
194 return m_workerGlobalScope.vm();
195}
196
197} // namespace WebCore
198