blob: 1177090fc18623ef501c9ad4c3389bc2da91071e [file] [log] [blame]
/*
* Copyright (C) 2018 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:
* 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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
* 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"
#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;
}
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);
return result;
}
void InspectorTargetAgent::targetCreated(InspectorTarget& target)
{
auto addResult = m_targets.set(target.identifier(), &target);
ASSERT_UNUSED(addResult, addResult.isNewEntry);
if (!m_isConnected)
return;
target.connect(connectionType());
m_frontendDispatcher->targetCreated(buildTargetInfoObject(target));
}
void InspectorTargetAgent::targetDestroyed(InspectorTarget& target)
{
m_targets.remove(target.identifier());
if (!m_isConnected)
return;
target.disconnect();
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();
}
} // namespace Inspector