summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/inspector/remote/RemoteInspector.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/inspector/remote/RemoteInspector.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/inspector/remote/RemoteInspector.cpp')
-rw-r--r--Source/JavaScriptCore/inspector/remote/RemoteInspector.cpp224
1 files changed, 224 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/inspector/remote/RemoteInspector.cpp b/Source/JavaScriptCore/inspector/remote/RemoteInspector.cpp
new file mode 100644
index 000000000..af88dc13e
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/remote/RemoteInspector.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2013-2016 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 "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 remote control is not allowed, a null listing is returned.
+ 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);
+
+ // The listing may never have been added if remote control isn't allowed.
+ 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 the target has just allowed remote control, then the listing won't exist yet.
+ // If the target has no identifier remove the old listing.
+ 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() // remoteAutomationAllowed
+ };
+
+ m_clientCapabilities = updatedCapabilities;
+ }
+}
+
+void RemoteInspector::setRemoteInspectorClient(RemoteInspector::Client* client)
+{
+ ASSERT_ARG(client, client);
+ ASSERT(!m_client);
+
+ {
+ std::lock_guard<Lock> lock(m_mutex);
+ m_client = client;
+ }
+
+ // Send an updated listing that includes whether the client allows remote automation.
+ 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)
+{
+ // We don't take the lock to check this because we assume it will be checked repeatedly.
+ 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::updateHasActiveDebugSession()
+{
+ bool hasActiveDebuggerSession = !m_targetConnectionMap.isEmpty();
+ if (hasActiveDebuggerSession == m_hasActiveDebugSession)
+ return;
+
+ m_hasActiveDebugSession = hasActiveDebuggerSession;
+
+ // FIXME: Expose some way to access this state in an embedder.
+ // Legacy iOS WebKit 1 had a notification. This will need to be smarter with WebKit2.
+}
+
+} // namespace Inspector
+
+#endif // ENABLE(REMOTE_INSPECTOR)