InspectorTargetAgent.cpp [plain text]
#include "config.h"
#include "InspectorTargetAgent.h"
#include "InspectorTarget.h"
namespace Inspector {
InspectorTargetAgent::InspectorTargetAgent(FrontendRouter& frontendRouter, BackendDispatcher& backendDispatcher)
: InspectorAgentBase("Target"_s)
, m_router(frontendRouter)
, m_frontendDispatcher(makeUnique<TargetFrontendDispatcher>(frontendRouter))
, m_backendDispatcher(TargetBackendDispatcher::create(backendDispatcher, this))
{
}
InspectorTargetAgent::~InspectorTargetAgent() = default;
void InspectorTargetAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
{
m_isConnected = true;
connectToTargets();
}
void InspectorTargetAgent::willDestroyFrontendAndBackend(DisconnectReason)
{
disconnectFromTargets();
m_isConnected = false;
m_shouldPauseOnStart = false;
}
void InspectorTargetAgent::setPauseOnStart(ErrorString&, bool pauseOnStart)
{
m_shouldPauseOnStart = pauseOnStart;
}
void InspectorTargetAgent::resume(ErrorString& errorString, const String& targetId)
{
auto* target = m_targets.get(targetId);
if (!target) {
errorString = "Missing target for given targetId"_s;
return;
}
if (!target->isPaused()) {
errorString = "Target for given targetId is not paused"_s;
return;
}
target->resume();
}
void InspectorTargetAgent::sendMessageToTarget(ErrorString& errorString, const String& targetId, const String& message)
{
InspectorTarget* target = m_targets.get(targetId);
if (!target) {
errorString = "Missing target for given targetId"_s;
return;
}
target->sendMessageToTargetBackend(message);
}
void InspectorTargetAgent::sendMessageFromTargetToFrontend(const String& targetId, const String& message)
{
ASSERT_WITH_MESSAGE(m_targets.get(targetId), "Sending a message from an untracked target to the frontend.");
m_frontendDispatcher->dispatchMessageFromTarget(targetId, message);
}
static Protocol::Target::TargetInfo::Type targetTypeToProtocolType(InspectorTargetType type)
{
switch (type) {
case InspectorTargetType::Page:
return Protocol::Target::TargetInfo::Type::Page;
case InspectorTargetType::DedicatedWorker:
return Protocol::Target::TargetInfo::Type::Worker;
case InspectorTargetType::ServiceWorker:
return Protocol::Target::TargetInfo::Type::ServiceWorker;
}
ASSERT_NOT_REACHED();
return Protocol::Target::TargetInfo::Type::Page;
}
static Ref<Protocol::Target::TargetInfo> buildTargetInfoObject(const InspectorTarget& target)
{
auto result = Protocol::Target::TargetInfo::create()
.setTargetId(target.identifier())
.setType(targetTypeToProtocolType(target.type()))
.release();
if (target.isProvisional())
result->setIsProvisional(true);
if (target.isPaused())
result->setIsPaused(true);
return result;
}
void InspectorTargetAgent::targetCreated(InspectorTarget& target)
{
auto addResult = m_targets.set(target.identifier(), &target);
ASSERT_UNUSED(addResult, addResult.isNewEntry);
if (!m_isConnected)
return;
if (m_shouldPauseOnStart)
target.pause();
target.connect(connectionType());
m_frontendDispatcher->targetCreated(buildTargetInfoObject(target));
}
void InspectorTargetAgent::targetDestroyed(InspectorTarget& target)
{
m_targets.remove(target.identifier());
if (!m_isConnected)
return;
m_frontendDispatcher->targetDestroyed(target.identifier());
}
void InspectorTargetAgent::didCommitProvisionalTarget(const String& oldTargetID, const String& committedTargetID)
{
if (!m_isConnected)
return;
auto* target = m_targets.get(committedTargetID);
if (!target)
return;
m_frontendDispatcher->didCommitProvisionalTarget(oldTargetID, committedTargetID);
}
FrontendChannel::ConnectionType InspectorTargetAgent::connectionType() const
{
return m_router.hasLocalFrontend() ? Inspector::FrontendChannel::ConnectionType::Local : Inspector::FrontendChannel::ConnectionType::Remote;
}
void InspectorTargetAgent::connectToTargets()
{
for (InspectorTarget* target : m_targets.values()) {
target->connect(connectionType());
m_frontendDispatcher->targetCreated(buildTargetInfoObject(*target));
}
}
void InspectorTargetAgent::disconnectFromTargets()
{
for (InspectorTarget* target : m_targets.values())
target->disconnect();
}
}