RemoteInspector.cpp [plain text]
#include "config.h"
#include "RemoteInspector.h"
#if ENABLE(REMOTE_INSPECTOR)
#include "RemoteAutomationTarget.h"
#include "RemoteConnectionToTarget.h"
#include "RemoteInspectionTarget.h"
#include "RemoteInspectorConstants.h"
#include <wtf/MainThread.h>
#include <wtf/text/WTFString.h>
namespace Inspector {
bool RemoteInspector::startEnabled = true;
void RemoteInspector::startDisabled()
{
RemoteInspector::startEnabled = false;
}
unsigned RemoteInspector::nextAvailableTargetIdentifier()
{
unsigned nextValidTargetIdentifier;
do {
nextValidTargetIdentifier = m_nextAvailableTargetIdentifier++;
} while (!nextValidTargetIdentifier || nextValidTargetIdentifier == std::numeric_limits<unsigned>::max() || m_targetMap.contains(nextValidTargetIdentifier));
return nextValidTargetIdentifier;
}
void RemoteInspector::registerTarget(RemoteControllableTarget* target)
{
ASSERT_ARG(target, target);
std::lock_guard<Lock> lock(m_mutex);
unsigned targetIdentifier = nextAvailableTargetIdentifier();
target->setTargetIdentifier(targetIdentifier);
{
auto result = m_targetMap.set(targetIdentifier, target);
ASSERT_UNUSED(result, result.isNewEntry);
}
if (auto targetListing = listingForTarget(*target)) {
auto result = m_targetListingMap.set(targetIdentifier, targetListing);
ASSERT_UNUSED(result, result.isNewEntry);
}
pushListingsSoon();
}
void RemoteInspector::unregisterTarget(RemoteControllableTarget* target)
{
ASSERT_ARG(target, target);
std::lock_guard<Lock> lock(m_mutex);
unsigned targetIdentifier = target->targetIdentifier();
if (!targetIdentifier)
return;
bool wasRemoved = m_targetMap.remove(targetIdentifier);
ASSERT_UNUSED(wasRemoved, wasRemoved);
m_targetListingMap.remove(targetIdentifier);
if (auto connectionToTarget = m_targetConnectionMap.take(targetIdentifier))
connectionToTarget->targetClosed();
pushListingsSoon();
}
void RemoteInspector::updateTarget(RemoteControllableTarget* target)
{
ASSERT_ARG(target, target);
std::lock_guard<Lock> lock(m_mutex);
unsigned targetIdentifier = target->targetIdentifier();
if (!targetIdentifier)
return;
{
auto result = m_targetMap.set(targetIdentifier, target);
ASSERT_UNUSED(result, !result.isNewEntry);
}
if (auto targetListing = listingForTarget(*target))
m_targetListingMap.set(targetIdentifier, targetListing);
else
m_targetListingMap.remove(targetIdentifier);
pushListingsSoon();
}
void RemoteInspector::updateClientCapabilities()
{
ASSERT(isMainThread());
std::lock_guard<Lock> lock(m_mutex);
if (!m_client)
m_clientCapabilities = std::nullopt;
else {
RemoteInspector::Client::Capabilities updatedCapabilities = {
m_client->remoteAutomationAllowed(),
m_client->browserName(),
m_client->browserVersion()
};
m_clientCapabilities = updatedCapabilities;
}
}
void RemoteInspector::setClient(RemoteInspector::Client* client)
{
ASSERT((m_client && !client) || (!m_client && client));
{
std::lock_guard<Lock> lock(m_mutex);
m_client = client;
}
updateClientCapabilities();
pushListingsSoon();
}
void RemoteInspector::setupFailed(unsigned targetIdentifier)
{
std::lock_guard<Lock> lock(m_mutex);
m_targetConnectionMap.remove(targetIdentifier);
if (targetIdentifier == m_automaticInspectionCandidateTargetIdentifier)
m_automaticInspectionPaused = false;
updateHasActiveDebugSession();
updateTargetListing(targetIdentifier);
pushListingsSoon();
}
void RemoteInspector::setupCompleted(unsigned targetIdentifier)
{
std::lock_guard<Lock> lock(m_mutex);
if (targetIdentifier == m_automaticInspectionCandidateTargetIdentifier)
m_automaticInspectionPaused = false;
}
bool RemoteInspector::waitingForAutomaticInspection(unsigned)
{
return m_automaticInspectionPaused;
}
void RemoteInspector::clientCapabilitiesDidChange()
{
updateClientCapabilities();
pushListingsSoon();
}
void RemoteInspector::stop()
{
std::lock_guard<Lock> lock(m_mutex);
stopInternal(StopSource::API);
}
TargetListing RemoteInspector::listingForTarget(const RemoteControllableTarget& target) const
{
if (is<RemoteInspectionTarget>(target))
return listingForInspectionTarget(downcast<RemoteInspectionTarget>(target));
if (is<RemoteAutomationTarget>(target))
return listingForAutomationTarget(downcast<RemoteAutomationTarget>(target));
ASSERT_NOT_REACHED();
return nullptr;
}
void RemoteInspector::updateTargetListing(unsigned targetIdentifier)
{
auto target = m_targetMap.get(targetIdentifier);
if (!target)
return;
updateTargetListing(*target);
}
void RemoteInspector::updateTargetListing(const RemoteControllableTarget& target)
{
auto targetListing = listingForTarget(target);
if (!targetListing)
return;
m_targetListingMap.set(target.targetIdentifier(), targetListing);
pushListingsSoon();
}
void RemoteInspector::updateHasActiveDebugSession()
{
bool hasActiveDebuggerSession = !m_targetConnectionMap.isEmpty();
if (hasActiveDebuggerSession == m_hasActiveDebugSession)
return;
m_hasActiveDebugSession = hasActiveDebuggerSession;
}
}
#endif // ENABLE(REMOTE_INSPECTOR)