diff options
Diffstat (limited to 'Source/WebCore/inspector/InspectorWorkerAgent.cpp')
-rw-r--r-- | Source/WebCore/inspector/InspectorWorkerAgent.cpp | 278 |
1 files changed, 105 insertions, 173 deletions
diff --git a/Source/WebCore/inspector/InspectorWorkerAgent.cpp b/Source/WebCore/inspector/InspectorWorkerAgent.cpp index b8108b54f..13222c785 100644 --- a/Source/WebCore/inspector/InspectorWorkerAgent.cpp +++ b/Source/WebCore/inspector/InspectorWorkerAgent.cpp @@ -1,242 +1,174 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorWorkerAgent.h" -#include "InspectorForwarding.h" -#include "InspectorWebFrontendDispatchers.h" +#include "Document.h" #include "InstrumentingAgents.h" -#include "URL.h" -#include "WorkerGlobalScopeProxy.h" -#include <inspector/InspectorValues.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/RefPtr.h> using namespace Inspector; namespace WebCore { -class InspectorWorkerAgent::WorkerFrontendChannel : public WorkerGlobalScopeProxy::PageInspector { - WTF_MAKE_FAST_ALLOCATED; -public: - explicit WorkerFrontendChannel(InspectorWorkerFrontendDispatcher* frontendDispatcher, WorkerGlobalScopeProxy* proxy) - : m_frontendDispatcher(frontendDispatcher) - , m_proxy(proxy) - , m_id(s_nextId++) - , m_connected(false) - { - } - virtual ~WorkerFrontendChannel() - { - disconnectFromWorkerGlobalScope(); - } - - int id() const { return m_id; } - WorkerGlobalScopeProxy* proxy() const { return m_proxy; } - - void connectToWorkerGlobalScope() - { - if (m_connected) - return; - m_connected = true; - m_proxy->connectToInspector(this); - } - - void disconnectFromWorkerGlobalScope() - { - if (!m_connected) - return; - m_connected = false; - m_proxy->disconnectFromInspector(); - } - -private: - // WorkerGlobalScopeProxy::PageInspector implementation - virtual void dispatchMessageFromWorker(const String& message) override - { - RefPtr<InspectorValue> value = InspectorValue::parseJSON(message); - if (!value) - return; - RefPtr<InspectorObject> messageObject = value->asObject(); - if (!messageObject) - return; - m_frontendDispatcher->dispatchMessageFromWorker(m_id, messageObject); - } - - InspectorWorkerFrontendDispatcher* m_frontendDispatcher; - WorkerGlobalScopeProxy* m_proxy; - int m_id; - bool m_connected; - static int s_nextId; -}; - -int InspectorWorkerAgent::WorkerFrontendChannel::s_nextId = 1; - -InspectorWorkerAgent::InspectorWorkerAgent(InstrumentingAgents* instrumentingAgents) - : InspectorAgentBase(ASCIILiteral("Worker"), instrumentingAgents) - , m_enabled(false) - , m_shouldPauseDedicatedWorkerOnStart(false) +InspectorWorkerAgent::InspectorWorkerAgent(PageAgentContext& context) + : InspectorAgentBase(ASCIILiteral("Worker"), context) + , m_frontendDispatcher(std::make_unique<Inspector::WorkerFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(Inspector::WorkerBackendDispatcher::create(context.backendDispatcher, this)) + , m_page(context.inspectedPage) { - m_instrumentingAgents->setInspectorWorkerAgent(this); } -InspectorWorkerAgent::~InspectorWorkerAgent() +void InspectorWorkerAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*) { - m_instrumentingAgents->setInspectorWorkerAgent(nullptr); + m_instrumentingAgents.setInspectorWorkerAgent(this); } -void InspectorWorkerAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorWorkerAgent::willDestroyFrontendAndBackend(DisconnectReason) { - m_frontendDispatcher = std::make_unique<InspectorWorkerFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorWorkerBackendDispatcher::create(backendDispatcher, this); + m_instrumentingAgents.setInspectorWorkerAgent(nullptr); + + ErrorString ignored; + disable(ignored); } -void InspectorWorkerAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorWorkerAgent::enable(ErrorString&) { - m_shouldPauseDedicatedWorkerOnStart = false; - disable(nullptr); + if (m_enabled) + return; - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); + m_enabled = true; + + connectToAllWorkerInspectorProxiesForPage(); } -void InspectorWorkerAgent::enable(ErrorString*) +void InspectorWorkerAgent::disable(ErrorString&) { - m_enabled = true; - if (!m_frontendDispatcher) + if (!m_enabled) return; - createWorkerFrontendChannelsForExistingWorkers(); + m_enabled = false; + + disconnectFromAllWorkerInspectorProxies(); } -void InspectorWorkerAgent::disable(ErrorString*) +void InspectorWorkerAgent::initialized(ErrorString& errorString, const String& workerId) { - m_enabled = false; - if (!m_frontendDispatcher) + WorkerInspectorProxy* proxy = m_connectedProxies.get(workerId); + if (!proxy) { + errorString = ASCIILiteral("Worker not found."); return; + } - destroyWorkerFrontendChannels(); + proxy->resumeWorkerIfPaused(); } -void InspectorWorkerAgent::canInspectWorkers(ErrorString*, bool* result) +void InspectorWorkerAgent::sendMessageToWorker(ErrorString& errorString, const String& workerId, const String& message) { - *result = true; -} + if (!m_enabled) { + errorString = ASCIILiteral("Worker inspection must be enabled."); + return; + } -void InspectorWorkerAgent::connectToWorker(ErrorString* error, int workerId) -{ - WorkerFrontendChannel* channel = m_idToChannel.get(workerId); - if (channel) - channel->connectToWorkerGlobalScope(); - else - *error = "Worker is gone"; -} + WorkerInspectorProxy* proxy = m_connectedProxies.get(workerId); + if (!proxy) { + errorString = ASCIILiteral("Worker not found."); + return; + } -void InspectorWorkerAgent::disconnectFromWorker(ErrorString* error, int workerId) -{ - WorkerFrontendChannel* channel = m_idToChannel.get(workerId); - if (channel) - channel->disconnectFromWorkerGlobalScope(); - else - *error = "Worker is gone"; + proxy->sendMessageToWorkerInspectorController(message); } -void InspectorWorkerAgent::sendMessageToWorker(ErrorString* error, int workerId, const RefPtr<InspectorObject>& message) +void InspectorWorkerAgent::sendMessageFromWorkerToFrontend(WorkerInspectorProxy* proxy, const String& message) { - WorkerFrontendChannel* channel = m_idToChannel.get(workerId); - if (channel) - channel->proxy()->sendMessageToInspector(message->toJSONString()); - else - *error = "Worker is gone"; + m_frontendDispatcher->dispatchMessageFromWorker(proxy->identifier(), message); } -void InspectorWorkerAgent::setAutoconnectToWorkers(ErrorString*, bool value) +bool InspectorWorkerAgent::shouldWaitForDebuggerOnStart() const { - m_shouldPauseDedicatedWorkerOnStart = value; + return m_enabled; } -bool InspectorWorkerAgent::shouldPauseDedicatedWorkerOnStart() const +void InspectorWorkerAgent::workerStarted(WorkerInspectorProxy* proxy, const URL&) { - return m_shouldPauseDedicatedWorkerOnStart; + if (!m_enabled) + return; + + connectToWorkerInspectorProxy(proxy); } -void InspectorWorkerAgent::didStartWorkerGlobalScope(WorkerGlobalScopeProxy* workerGlobalScopeProxy, const URL& url) +void InspectorWorkerAgent::workerTerminated(WorkerInspectorProxy* proxy) { - m_dedicatedWorkers.set(workerGlobalScopeProxy, url.string()); - if (m_frontendDispatcher && m_enabled) - createWorkerFrontendChannel(workerGlobalScopeProxy, url.string()); + if (!m_enabled) + return; + + disconnectFromWorkerInspectorProxy(proxy); } -void InspectorWorkerAgent::workerGlobalScopeTerminated(WorkerGlobalScopeProxy* proxy) +void InspectorWorkerAgent::connectToAllWorkerInspectorProxiesForPage() { - m_dedicatedWorkers.remove(proxy); - for (WorkerChannels::iterator it = m_idToChannel.begin(); it != m_idToChannel.end(); ++it) { - if (proxy == it->value->proxy()) { - m_frontendDispatcher->workerTerminated(it->key); - delete it->value; - m_idToChannel.remove(it); - return; - } + ASSERT(m_connectedProxies.isEmpty()); + + for (auto* proxy : WorkerInspectorProxy::allWorkerInspectorProxies()) { + if (!is<Document>(proxy->scriptExecutionContext())) + continue; + + Document& document = downcast<Document>(*proxy->scriptExecutionContext()); + if (document.page() != &m_page) + continue; + + connectToWorkerInspectorProxy(proxy); } } -void InspectorWorkerAgent::createWorkerFrontendChannelsForExistingWorkers() +void InspectorWorkerAgent::disconnectFromAllWorkerInspectorProxies() { - for (DedicatedWorkers::iterator it = m_dedicatedWorkers.begin(); it != m_dedicatedWorkers.end(); ++it) - createWorkerFrontendChannel(it->key, it->value); + Vector<WorkerInspectorProxy*> proxies; + copyValuesToVector(m_connectedProxies, proxies); + for (auto* proxy : proxies) + proxy->disconnectFromWorkerInspectorController(); + + m_connectedProxies.clear(); } -void InspectorWorkerAgent::destroyWorkerFrontendChannels() +void InspectorWorkerAgent::connectToWorkerInspectorProxy(WorkerInspectorProxy* proxy) { - for (WorkerChannels::iterator it = m_idToChannel.begin(); it != m_idToChannel.end(); ++it) { - it->value->disconnectFromWorkerGlobalScope(); - delete it->value; - } - m_idToChannel.clear(); + proxy->connectToWorkerInspectorController(this); + + m_connectedProxies.set(proxy->identifier(), proxy); + + m_frontendDispatcher->workerCreated(proxy->identifier(), proxy->url()); } -void InspectorWorkerAgent::createWorkerFrontendChannel(WorkerGlobalScopeProxy* workerGlobalScopeProxy, const String& url) +void InspectorWorkerAgent::disconnectFromWorkerInspectorProxy(WorkerInspectorProxy* proxy) { - WorkerFrontendChannel* channel = new WorkerFrontendChannel(m_frontendDispatcher.get(), workerGlobalScopeProxy); - m_idToChannel.set(channel->id(), channel); + m_frontendDispatcher->workerTerminated(proxy->identifier()); - ASSERT(m_frontendDispatcher); - if (m_shouldPauseDedicatedWorkerOnStart) - channel->connectToWorkerGlobalScope(); - m_frontendDispatcher->workerCreated(channel->id(), url, m_shouldPauseDedicatedWorkerOnStart); -} + m_connectedProxies.remove(proxy->identifier()); -} // namespace WebCore + proxy->disconnectFromWorkerInspectorController(); +} -#endif // ENABLE(INSPECTOR) +} // namespace Inspector |