[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[WebKit-https.git] / Source / WebCore / inspector / agents / InspectorWorkerAgent.cpp
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 "InspectorWorkerAgent.h"
28
29 #include "Document.h"
30 #include "InstrumentingAgents.h"
31
32
33 namespace WebCore {
34
35 using namespace Inspector;
36
37 InspectorWorkerAgent::InspectorWorkerAgent(PageAgentContext& context)
38     : InspectorAgentBase("Worker"_s, context)
39     , m_frontendDispatcher(makeUnique<Inspector::WorkerFrontendDispatcher>(context.frontendRouter))
40     , m_backendDispatcher(Inspector::WorkerBackendDispatcher::create(context.backendDispatcher, this))
41     , m_page(context.inspectedPage)
42 {
43 }
44
45 void InspectorWorkerAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
46 {
47     m_instrumentingAgents.setInspectorWorkerAgent(this);
48 }
49
50 void InspectorWorkerAgent::willDestroyFrontendAndBackend(DisconnectReason)
51 {
52     m_instrumentingAgents.setInspectorWorkerAgent(nullptr);
53
54     ErrorString ignored;
55     disable(ignored);
56 }
57
58 void InspectorWorkerAgent::enable(ErrorString&)
59 {
60     if (m_enabled)
61         return;
62
63     m_enabled = true;
64
65     connectToAllWorkerInspectorProxiesForPage();
66 }
67
68 void InspectorWorkerAgent::disable(ErrorString&)
69 {
70     if (!m_enabled)
71         return;
72
73     m_enabled = false;
74
75     disconnectFromAllWorkerInspectorProxies();
76 }
77
78 void InspectorWorkerAgent::initialized(ErrorString& errorString, const String& workerId)
79 {
80     WorkerInspectorProxy* proxy = m_connectedProxies.get(workerId);
81     if (!proxy) {
82         errorString = "Worker not found."_s;
83         return;
84     }
85
86     proxy->resumeWorkerIfPaused();
87 }
88
89 void InspectorWorkerAgent::sendMessageToWorker(ErrorString& errorString, const String& workerId, const String& message)
90 {
91     if (!m_enabled) {
92         errorString = "Worker inspection must be enabled."_s;
93         return;
94     }
95
96     WorkerInspectorProxy* proxy = m_connectedProxies.get(workerId);
97     if (!proxy) {
98         errorString = "Worker not found."_s;
99         return;
100     }
101
102     proxy->sendMessageToWorkerInspectorController(message);
103 }
104
105 void InspectorWorkerAgent::sendMessageFromWorkerToFrontend(WorkerInspectorProxy* proxy, const String& message)
106 {
107     m_frontendDispatcher->dispatchMessageFromWorker(proxy->identifier(), message);
108 }
109
110 bool InspectorWorkerAgent::shouldWaitForDebuggerOnStart() const
111 {
112     return m_enabled;
113 }
114
115 void InspectorWorkerAgent::workerStarted(WorkerInspectorProxy* proxy, const URL&)
116 {
117     if (!m_enabled)
118         return;
119
120     connectToWorkerInspectorProxy(proxy);
121 }
122
123 void InspectorWorkerAgent::workerTerminated(WorkerInspectorProxy* proxy)
124 {
125     if (!m_enabled)
126         return;
127
128     disconnectFromWorkerInspectorProxy(proxy);
129 }
130
131 void InspectorWorkerAgent::connectToAllWorkerInspectorProxiesForPage()
132 {
133     ASSERT(m_connectedProxies.isEmpty());
134
135     for (auto* proxy : WorkerInspectorProxy::allWorkerInspectorProxies()) {
136         if (!is<Document>(proxy->scriptExecutionContext()))
137             continue;
138
139         Document& document = downcast<Document>(*proxy->scriptExecutionContext());
140         if (document.page() != &m_page)
141             continue;
142
143         connectToWorkerInspectorProxy(proxy);
144     }
145 }
146
147 void InspectorWorkerAgent::disconnectFromAllWorkerInspectorProxies()
148 {
149     for (auto* proxy : copyToVector(m_connectedProxies.values()))
150         proxy->disconnectFromWorkerInspectorController();
151
152     m_connectedProxies.clear();
153 }
154
155 void InspectorWorkerAgent::connectToWorkerInspectorProxy(WorkerInspectorProxy* proxy)
156 {
157     proxy->connectToWorkerInspectorController(this);
158
159     m_connectedProxies.set(proxy->identifier(), proxy);
160
161     m_frontendDispatcher->workerCreated(proxy->identifier(), proxy->url());
162 }
163
164 void InspectorWorkerAgent::disconnectFromWorkerInspectorProxy(WorkerInspectorProxy* proxy)
165 {
166     m_frontendDispatcher->workerTerminated(proxy->identifier());
167
168     m_connectedProxies.remove(proxy->identifier());
169
170     proxy->disconnectFromWorkerInspectorController();
171 }
172
173 } // namespace Inspector