blob: d7743bc97b36696c6d1c3f3afdefebec632d5f36 [file] [log] [blame]
/*
* Copyright (C) 2011 Google 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:
*
* * 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.
*/
#include "core/inspector/InspectorWorkerAgent.h"
#include "core/dom/Document.h"
#include "core/inspector/InspectedFrames.h"
#include "platform/weborigin/KURL.h"
#include "wtf/RefPtr.h"
#include "wtf/text/WTFString.h"
namespace blink {
namespace WorkerAgentState {
static const char autoAttach[] = "autoAttach";
static const char waitForDebuggerOnStart[] = "waitForDebuggerOnStart";
};
InspectorWorkerAgent::InspectorWorkerAgent(InspectedFrames* inspectedFrames)
: m_inspectedFrames(inspectedFrames) {}
InspectorWorkerAgent::~InspectorWorkerAgent() {}
void InspectorWorkerAgent::restore() {
if (!autoAttachEnabled())
return;
m_instrumentingAgents->addInspectorWorkerAgent(this);
connectToAllProxies();
}
Response InspectorWorkerAgent::disable() {
if (autoAttachEnabled()) {
disconnectFromAllProxies();
m_instrumentingAgents->removeInspectorWorkerAgent(this);
}
m_state->setBoolean(WorkerAgentState::autoAttach, false);
m_state->setBoolean(WorkerAgentState::waitForDebuggerOnStart, false);
return Response::OK();
}
Response InspectorWorkerAgent::setAutoAttach(bool autoAttach,
bool waitForDebuggerOnStart) {
m_state->setBoolean(WorkerAgentState::waitForDebuggerOnStart,
waitForDebuggerOnStart);
if (autoAttach == autoAttachEnabled())
return Response::OK();
m_state->setBoolean(WorkerAgentState::autoAttach, autoAttach);
if (autoAttach) {
m_instrumentingAgents->addInspectorWorkerAgent(this);
connectToAllProxies();
} else {
disconnectFromAllProxies();
m_instrumentingAgents->removeInspectorWorkerAgent(this);
}
return Response::OK();
}
bool InspectorWorkerAgent::autoAttachEnabled() {
return m_state->booleanProperty(WorkerAgentState::autoAttach, false);
}
Response InspectorWorkerAgent::sendMessageToTarget(const String& targetId,
const String& message) {
WorkerInspectorProxy* proxy = m_connectedProxies.get(targetId);
if (!proxy)
return Response::Error("Not attached to a target with given id");
proxy->sendMessageToInspector(message);
return Response::OK();
}
void InspectorWorkerAgent::setTracingSessionId(const String& sessionId) {
m_tracingSessionId = sessionId;
if (sessionId.isEmpty())
return;
for (auto& idProxy : m_connectedProxies)
idProxy.value->writeTimelineStartedEvent(sessionId);
}
bool InspectorWorkerAgent::shouldWaitForDebuggerOnWorkerStart() {
return autoAttachEnabled() &&
m_state->booleanProperty(WorkerAgentState::waitForDebuggerOnStart,
false);
}
void InspectorWorkerAgent::didStartWorker(WorkerInspectorProxy* proxy,
bool waitingForDebugger) {
DCHECK(frontend() && autoAttachEnabled());
connectToProxy(proxy, waitingForDebugger);
if (!m_tracingSessionId.isEmpty())
proxy->writeTimelineStartedEvent(m_tracingSessionId);
}
void InspectorWorkerAgent::workerTerminated(WorkerInspectorProxy* proxy) {
DCHECK(frontend() && autoAttachEnabled());
if (m_connectedProxies.find(proxy->inspectorId()) == m_connectedProxies.end())
return;
frontend()->detachedFromTarget(proxy->inspectorId());
proxy->disconnectFromInspector(this);
m_connectedProxies.remove(proxy->inspectorId());
}
void InspectorWorkerAgent::connectToAllProxies() {
for (WorkerInspectorProxy* proxy : WorkerInspectorProxy::allProxies()) {
if (proxy->getDocument()->frame() &&
m_inspectedFrames->contains(proxy->getDocument()->frame()))
connectToProxy(proxy, false);
}
}
void InspectorWorkerAgent::disconnectFromAllProxies() {
for (auto& idProxy : m_connectedProxies)
idProxy.value->disconnectFromInspector(this);
m_connectedProxies.clear();
}
void InspectorWorkerAgent::didCommitLoadForLocalFrame(LocalFrame* frame) {
if (!autoAttachEnabled() || frame != m_inspectedFrames->root())
return;
// During navigation workers from old page may die after a while.
// Usually, it's fine to report them terminated later, but some tests
// expect strict set of workers, and we reuse renderer between tests.
for (auto& idProxy : m_connectedProxies) {
frontend()->detachedFromTarget(idProxy.key);
idProxy.value->disconnectFromInspector(this);
}
m_connectedProxies.clear();
}
void InspectorWorkerAgent::connectToProxy(WorkerInspectorProxy* proxy,
bool waitingForDebugger) {
m_connectedProxies.set(proxy->inspectorId(), proxy);
proxy->connectToInspector(this);
DCHECK(frontend());
frontend()->attachedToTarget(protocol::Target::TargetInfo::create()
.setTargetId(proxy->inspectorId())
.setType("worker")
.setTitle(proxy->url())
.setUrl(proxy->url())
.build(),
waitingForDebugger);
}
void InspectorWorkerAgent::dispatchMessageFromWorker(
WorkerInspectorProxy* proxy,
const String& message) {
frontend()->receivedMessageFromTarget(proxy->inspectorId(), message);
}
DEFINE_TRACE(InspectorWorkerAgent) {
visitor->trace(m_connectedProxies);
visitor->trace(m_inspectedFrames);
InspectorBaseAgent::trace(visitor);
}
} // namespace blink