blob: c4b92c83cfea29b31edbb34aa84025ba5c8b03b7 [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 "WebPageInspectorController.h"
#include "WebFrameProxy.h"
#include "WebPageInspectorTargetAgent.h"
#include "WebPageProxy.h"
#include <JavaScriptCore/InspectorAgentBase.h>
#include <JavaScriptCore/InspectorBackendDispatcher.h>
#include <JavaScriptCore/InspectorBackendDispatchers.h>
#include <JavaScriptCore/InspectorFrontendRouter.h>
namespace WebKit {
using namespace Inspector;
WebPageInspectorController::WebPageInspectorController(WebPageProxy& page)
: m_page(page)
, m_frontendRouter(FrontendRouter::create())
, m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
{
auto targetAgent = std::make_unique<WebPageInspectorTargetAgent>(m_frontendRouter.get(), m_backendDispatcher.get());
m_targetAgent = targetAgent.get();
m_agents.append(WTFMove(targetAgent));
}
void WebPageInspectorController::pageClosed()
{
disconnectAllFrontends();
m_agents.discardValues();
}
bool WebPageInspectorController::hasLocalFrontend() const
{
return m_frontendRouter->hasLocalFrontend();
}
void WebPageInspectorController::connectFrontend(Inspector::FrontendChannel& frontendChannel, bool, bool)
{
bool connectingFirstFrontend = !m_frontendRouter->hasFrontends();
m_frontendRouter->connectFrontend(frontendChannel);
if (connectingFirstFrontend)
m_agents.didCreateFrontendAndBackend(&m_frontendRouter.get(), &m_backendDispatcher.get());
m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
#if ENABLE(REMOTE_INSPECTOR)
if (hasLocalFrontend())
m_page.remoteInspectorInformationDidChange();
#endif
}
void WebPageInspectorController::disconnectFrontend(FrontendChannel& frontendChannel)
{
m_frontendRouter->disconnectFrontend(frontendChannel);
bool disconnectingLastFrontend = !m_frontendRouter->hasFrontends();
if (disconnectingLastFrontend)
m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectorDestroyed);
m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
#if ENABLE(REMOTE_INSPECTOR)
if (disconnectingLastFrontend)
m_page.remoteInspectorInformationDidChange();
#endif
}
void WebPageInspectorController::disconnectAllFrontends()
{
// FIXME: Handle a local inspector client.
if (!m_frontendRouter->hasFrontends())
return;
// Notify agents first, since they may need to use InspectorClient.
m_agents.willDestroyFrontendAndBackend(DisconnectReason::InspectedTargetDestroyed);
// Disconnect any remaining remote frontends.
m_frontendRouter->disconnectAllFrontends();
m_page.didChangeInspectorFrontendCount(m_frontendRouter->frontendCount());
#if ENABLE(REMOTE_INSPECTOR)
m_page.remoteInspectorInformationDidChange();
#endif
}
void WebPageInspectorController::dispatchMessageFromFrontend(const String& message)
{
m_backendDispatcher->dispatch(message);
}
#if ENABLE(REMOTE_INSPECTOR)
void WebPageInspectorController::setIndicating(bool indicating)
{
#if !PLATFORM(IOS_FAMILY)
m_page.setIndicating(indicating);
#else
if (indicating)
m_page.showInspectorIndication();
else
m_page.hideInspectorIndication();
#endif
}
#endif
void WebPageInspectorController::clearTargets()
{
for (auto& target : m_targets)
m_targetAgent->targetDestroyed(*target.get());
m_targets.clear();
}
void WebPageInspectorController::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type)
{
auto target = InspectorTargetProxy::create(m_page, targetId, type);
m_targets.append(target.copyRef());
m_targetAgent->targetCreated(target.get());
}
void WebPageInspectorController::destroyInspectorTarget(const String& targetId)
{
auto position = m_targets.findMatching([&](const auto& item) { return item->identifier() == targetId; });
if (position == notFound)
return;
auto& target = m_targets[position];
m_targetAgent->targetDestroyed(*target.get());
m_targets.remove(position);
}
void WebPageInspectorController::sendMessageToInspectorFrontend(const String& targetId, const String& message)
{
m_targetAgent->sendMessageFromTargetToFrontend(targetId, message);
}
} // namespace WebKit