blob: c8096064badf9efa888660fa646937bd09c1183f [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_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)
{
return Protocol::Target::TargetInfo::create()
.setTargetId(target.identifier())
.setType(targetTypeToProtocolType(target.type()))
.release();
}
void InspectorTargetAgent::targetCreated(InspectorTarget& target)
{
auto addResult = m_targets.set(target.identifier(), &target);
ASSERT_UNUSED(addResult, addResult.isNewEntry);
if (!m_isConnected)
return;
target.connect(frontendChannel());
m_frontendDispatcher->targetCreated(buildTargetInfoObject(target));
}
void InspectorTargetAgent::targetDestroyed(InspectorTarget& target)
{
m_targets.remove(target.identifier());
if (!m_isConnected)
return;
target.disconnect(frontendChannel());
m_frontendDispatcher->targetDestroyed(target.identifier());
}
void InspectorTargetAgent::connectToTargets()
{
auto& channel = frontendChannel();
for (InspectorTarget* target : m_targets.values()) {
target->connect(channel);
m_frontendDispatcher->targetCreated(buildTargetInfoObject(*target));
}
}
void InspectorTargetAgent::disconnectFromTargets()
{
auto& channel = frontendChannel();
for (InspectorTarget* target : m_targets.values())
target->disconnect(channel);
}
} // namespace Inspector