[WinCairo] Implement Remote Web Inspector Client.
authorross.kirsling@sony.com <ross.kirsling@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 May 2019 21:17:02 +0000 (21:17 +0000)
committerross.kirsling@sony.com <ross.kirsling@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 20 May 2019 21:17:02 +0000 (21:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197434

Reviewed by Don Olmstead.

.:

* Source/cmake/OptionsWin.cmake:
* Source/cmake/OptionsWinCairo.cmake:

Source/JavaScriptCore:

* inspector/remote/socket/RemoteInspectorConnectionClient.cpp:
(Inspector::RemoteInspectorConnectionClient::didAccept): Deleted.
* inspector/remote/socket/RemoteInspectorConnectionClient.h:
(Inspector::RemoteInspectorConnectionClient::didAccept):
* inspector/remote/socket/RemoteInspectorServer.cpp:
(Inspector::RemoteInspectorServer::dispatchMap):

Source/WebKit:

* PlatformWin.cmake:
* UIProcess/RemoteWebInspectorProxy.cpp:
* UIProcess/RemoteWebInspectorProxy.h:
* UIProcess/socket/RemoteInspectorClient.cpp: Added.
* UIProcess/socket/RemoteInspectorClient.h: Added.
* UIProcess/socket/RemoteInspectorProtocolHandler.cpp: Added.
* UIProcess/socket/RemoteInspectorProtocolHandler.h: Added.
* UIProcess/win/RemoteWebInspectorProxyWin.cpp: Added.
* UIProcess/win/WebView.cpp:
(WebKit::WebView::WebView):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245536 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
ChangeLog
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorConnectionClient.cpp
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorConnectionClient.h
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorServer.cpp
Source/WebKit/ChangeLog
Source/WebKit/PlatformWin.cmake
Source/WebKit/UIProcess/RemoteWebInspectorProxy.cpp
Source/WebKit/UIProcess/RemoteWebInspectorProxy.h
Source/WebKit/UIProcess/socket/RemoteInspectorClient.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/socket/RemoteInspectorClient.h [new file with mode: 0644]
Source/WebKit/UIProcess/socket/RemoteInspectorProtocolHandler.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/socket/RemoteInspectorProtocolHandler.h [new file with mode: 0644]
Source/WebKit/UIProcess/win/RemoteWebInspectorProxyWin.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/win/WebView.cpp
Source/cmake/OptionsWin.cmake
Source/cmake/OptionsWinCairo.cmake

index 05f1e22..6982910 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2019-05-20  Ross Kirsling  <ross.kirsling@sony.com>
+
+        [WinCairo] Implement Remote Web Inspector Client.
+        https://bugs.webkit.org/show_bug.cgi?id=197434
+
+        Reviewed by Don Olmstead.
+
+        * Source/cmake/OptionsWin.cmake:
+        * Source/cmake/OptionsWinCairo.cmake:
+
 2019-05-17  Don Olmstead  <don.olmstead@sony.com>
 
         [CMake] Use builtin FindICU
index aef85d9..51815ba 100644 (file)
@@ -1,3 +1,17 @@
+2019-05-20  Ross Kirsling  <ross.kirsling@sony.com>
+
+        [WinCairo] Implement Remote Web Inspector Client.
+        https://bugs.webkit.org/show_bug.cgi?id=197434
+
+        Reviewed by Don Olmstead.
+
+        * inspector/remote/socket/RemoteInspectorConnectionClient.cpp:
+        (Inspector::RemoteInspectorConnectionClient::didAccept): Deleted.
+        * inspector/remote/socket/RemoteInspectorConnectionClient.h:
+        (Inspector::RemoteInspectorConnectionClient::didAccept):
+        * inspector/remote/socket/RemoteInspectorServer.cpp:
+        (Inspector::RemoteInspectorServer::dispatchMap):
+
 2019-05-20  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GLIB] Crash when instantiating a js object registered with jsc_context_register_class on window object cleared
index 56f46cd..0e90f18 100644 (file)
@@ -80,10 +80,6 @@ void RemoteInspectorConnectionClient::didReceiveWebInspectorEvent(ConnectionID c
     });
 }
 
-void RemoteInspectorConnectionClient::didAccept(ConnectionID, ConnectionID, Socket::Domain)
-{
-}
-
 } // namespace Inspector
 
 #endif // ENABLE(REMOTE_INSPECTOR)
index 873a051..c6a6296 100644 (file)
@@ -37,7 +37,7 @@ namespace Inspector {
 class RemoteInspectorConnectionClient : public CanMakeWeakPtr<RemoteInspectorConnectionClient> {
 public:
     void didReceiveWebInspectorEvent(ConnectionID, Vector<uint8_t>&&);
-    virtual void didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain);
+    virtual void didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain) { }
     virtual void didClose(ConnectionID) = 0;
 
     struct Event {
index 8935089..d2a5c3a 100644 (file)
@@ -109,12 +109,12 @@ void RemoteInspectorServer::didClose(ConnectionID id)
 HashMap<String, RemoteInspectorConnectionClient::CallHandler>& RemoteInspectorServer::dispatchMap()
 {
     static NeverDestroyed<HashMap<String, CallHandler>> dispatchMap = HashMap<String, CallHandler>({
-        { "SetTargetList"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::setTargetList) },
-        { "SetupInspectorClient"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::setupInspectorClient) },
-        { "Setup"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::setup) },
-        { "FrontendDidClose"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::close) },
-        { "SendMessageToFrontend"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::sendMessageToFrontend) },
-        { "SendMessageToBackend"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::sendMessageToBackend) },
+        { "SetTargetList"_s, static_cast<CallHandler>(&RemoteInspectorServer::setTargetList) },
+        { "SetupInspectorClient"_s, static_cast<CallHandler>(&RemoteInspectorServer::setupInspectorClient) },
+        { "Setup"_s, static_cast<CallHandler>(&RemoteInspectorServer::setup) },
+        { "FrontendDidClose"_s, static_cast<CallHandler>(&RemoteInspectorServer::close) },
+        { "SendMessageToFrontend"_s, static_cast<CallHandler>(&RemoteInspectorServer::sendMessageToFrontend) },
+        { "SendMessageToBackend"_s, static_cast<CallHandler>(&RemoteInspectorServer::sendMessageToBackend) },
     });
 
     return dispatchMap;
index e4af44c..efeb55c 100644 (file)
@@ -1,3 +1,21 @@
+2019-05-20  Ross Kirsling  <ross.kirsling@sony.com>
+
+        [WinCairo] Implement Remote Web Inspector Client.
+        https://bugs.webkit.org/show_bug.cgi?id=197434
+
+        Reviewed by Don Olmstead.
+
+        * PlatformWin.cmake:
+        * UIProcess/RemoteWebInspectorProxy.cpp:
+        * UIProcess/RemoteWebInspectorProxy.h:
+        * UIProcess/socket/RemoteInspectorClient.cpp: Added.
+        * UIProcess/socket/RemoteInspectorClient.h: Added.
+        * UIProcess/socket/RemoteInspectorProtocolHandler.cpp: Added.
+        * UIProcess/socket/RemoteInspectorProtocolHandler.h: Added.
+        * UIProcess/win/RemoteWebInspectorProxyWin.cpp: Added.
+        * UIProcess/win/WebView.cpp:
+        (WebKit::WebView::WebView):
+
 2019-05-20  Per Arne Vollan  <pvollan@apple.com>
 
         [macOS] STP can't launch any WebContent processes
index c3514e8..b5c4ec1 100644 (file)
@@ -182,6 +182,19 @@ if (${WTF_PLATFORM_WIN_CAIRO})
     )
 endif ()
 
+if (ENABLE_REMOTE_INSPECTOR)
+    list(APPEND WebKit_SOURCES
+        UIProcess/socket/RemoteInspectorClient.cpp
+        UIProcess/socket/RemoteInspectorProtocolHandler.cpp
+
+        UIProcess/win/RemoteWebInspectorProxyWin.cpp
+    )
+
+    list(APPEND WebKit_INCLUDE_DIRECTORIES
+        "${WEBKIT_DIR}/UIProcess/socket"
+    )
+endif ()
+
 set(SharedWebKitLibraries
     ${WebKit_LIBRARIES}
 )
index 87b224e..954098b 100644 (file)
@@ -170,7 +170,7 @@ void RemoteWebInspectorProxy::closeFrontendPageAndWindow()
     platformCloseFrontendPageAndWindow();
 }
 
-#if !ENABLE(REMOTE_INSPECTOR) || (!PLATFORM(MAC) && !PLATFORM(GTK))
+#if !ENABLE(REMOTE_INSPECTOR) && !PLATFORM(MAC)
 WebPageProxy* RemoteWebInspectorProxy::platformCreateFrontendPageAndWindow()
 {
     notImplemented();
index 0fd0e83..5ebbb68 100644 (file)
@@ -48,6 +48,7 @@ class CertificateInfo;
 namespace WebKit {
 
 class WebPageProxy;
+class WebView;
 
 class RemoteWebInspectorProxyClient {
 public:
@@ -88,6 +89,13 @@ public:
     void updateWindowTitle(const CString&);
 #endif
 
+#if PLATFORM(WIN_CAIRO)
+    LRESULT sizeChange();
+    LRESULT onClose();
+
+    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+#endif
+
     void closeFromCrash();
 
 private:
@@ -139,6 +147,10 @@ private:
     GtkWidget* m_webView { nullptr };
     GtkWidget* m_window { nullptr };
 #endif
+#if PLATFORM(WIN_CAIRO)
+    HWND m_frontendHandle;
+    RefPtr<WebView> m_webView;
+#endif
 };
 
 } // namespace WebKit
diff --git a/Source/WebKit/UIProcess/socket/RemoteInspectorClient.cpp b/Source/WebKit/UIProcess/socket/RemoteInspectorClient.cpp
new file mode 100644 (file)
index 0000000..eb2ac85
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2019 Sony Interactive Entertainment Inc.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "RemoteInspectorClient.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "RemoteWebInspectorProxy.h"
+#include <wtf/MainThread.h>
+
+namespace WebKit {
+
+class RemoteInspectorProxy final : public RemoteWebInspectorProxyClient {
+    WTF_MAKE_FAST_ALLOCATED();
+public:
+    RemoteInspectorProxy(RemoteInspectorClient& inspectorClient, ConnectionID connectionID, TargetID targetID)
+        : m_proxy(RemoteWebInspectorProxy::create())
+        , m_inspectorClient(inspectorClient)
+        , m_connectionID(connectionID)
+        , m_targetID(targetID)
+    {
+        m_proxy->setClient(this);
+    }
+
+    ~RemoteInspectorProxy()
+    {
+        m_proxy->setClient(nullptr);
+        m_proxy->invalidate();
+    }
+
+    void load()
+    {
+        m_proxy->load("web", "");
+    }
+
+    void show()
+    {
+        m_proxy->show();
+    }
+
+    void sendMessageToFrontend(const String& message)
+    {
+        m_proxy->sendMessageToFrontend(message);
+    }
+
+    void sendMessageToBackend(const String& message) override
+    {
+        m_inspectorClient.sendMessageToBackend(m_connectionID, m_targetID, message);
+    }
+
+    void closeFromFrontend() override
+    {
+        m_inspectorClient.closeFromFrontend(m_connectionID, m_targetID);
+    }
+
+private:
+    Ref<RemoteWebInspectorProxy> m_proxy;
+    RemoteInspectorClient& m_inspectorClient;
+    ConnectionID m_connectionID;
+    TargetID m_targetID;
+};
+
+RemoteInspectorClient::RemoteInspectorClient(const char* address, unsigned port, RemoteInspectorObserver& observer)
+    : m_observer(observer)
+{
+    m_socket = Inspector::RemoteInspectorSocketEndpoint::create(this, "RemoteInspectorClient");
+
+    m_connectionID = m_socket->connectInet(address, port);
+    if (!m_connectionID) {
+        LOG_ERROR("Inspector client could not connect to %s:%d", address, port);
+        m_socket = nullptr;
+        return;
+    }
+
+    startInitialCommunication();
+}
+
+RemoteInspectorClient::~RemoteInspectorClient()
+{
+}
+
+void RemoteInspectorClient::sendWebInspectorEvent(const String& event)
+{
+    ASSERT(isMainThread());
+    ASSERT(m_connectionID.hasValue());
+    auto message = event.utf8();
+    m_socket->send(m_connectionID.value(), reinterpret_cast<const uint8_t*>(message.data()), message.length());
+}
+
+HashMap<String, Inspector::RemoteInspectorConnectionClient::CallHandler>& RemoteInspectorClient::dispatchMap()
+{
+    static NeverDestroyed<HashMap<String, CallHandler>> dispatchMap = HashMap<String, CallHandler>({
+        { "SetTargetList"_s, static_cast<CallHandler>(&RemoteInspectorClient::setTargetList) },
+        { "SendMessageToFrontend"_s, static_cast<CallHandler>(&RemoteInspectorClient::sendMessageToFrontend) },
+    });
+
+    return dispatchMap;
+}
+
+void RemoteInspectorClient::startInitialCommunication()
+{
+    auto event = JSON::Object::create();
+    event->setString("event"_s, "SetupInspectorClient"_s);
+    sendWebInspectorEvent(event->toJSONString());
+}
+
+void RemoteInspectorClient::connectionClosed()
+{
+    m_targets.clear();
+    m_inspectorProxyMap.clear();
+    m_observer.connectionClosed(*this);
+}
+
+void RemoteInspectorClient::didClose(ConnectionID)
+{
+}
+
+void RemoteInspectorClient::inspect(ConnectionID connectionID, TargetID targetID)
+{
+    auto addResult = m_inspectorProxyMap.ensure(std::make_pair(connectionID, targetID), [this, connectionID, targetID] {
+        return std::make_unique<RemoteInspectorProxy>(*this, connectionID, targetID);
+    });
+
+    if (!addResult.isNewEntry) {
+        addResult.iterator->value->show();
+        return;
+    }
+
+    auto setupEvent = JSON::Object::create();
+    setupEvent->setString("event"_s, "Setup"_s);
+    setupEvent->setInteger("connectionID"_s, connectionID);
+    setupEvent->setInteger("targetID"_s, targetID);
+    sendWebInspectorEvent(setupEvent->toJSONString());
+
+    addResult.iterator->value->load();
+}
+
+void RemoteInspectorClient::sendMessageToBackend(ConnectionID connectionID, TargetID targetID, const String& message)
+{
+    auto backendEvent = JSON::Object::create();
+    backendEvent->setString("event"_s, "SendMessageToBackend"_s);
+    backendEvent->setInteger("connectionID"_s, connectionID);
+    backendEvent->setInteger("targetID"_s, targetID);
+    backendEvent->setString("message"_s, message);
+    sendWebInspectorEvent(backendEvent->toJSONString());
+}
+
+void RemoteInspectorClient::closeFromFrontend(ConnectionID connectionID, TargetID targetID)
+{
+    auto closedEvent = JSON::Object::create();
+    closedEvent->setString("event"_s, "FrontendDidClose"_s);
+    closedEvent->setInteger("connectionID"_s, connectionID);
+    closedEvent->setInteger("targetID"_s, targetID);
+    sendWebInspectorEvent(closedEvent->toJSONString());
+
+    m_inspectorProxyMap.remove(std::make_pair(connectionID, targetID));
+}
+
+void RemoteInspectorClient::setTargetList(const Event& event)
+{
+    if (!event.connectionID || !event.message)
+        return;
+
+    RefPtr<JSON::Value> messageValue;
+    if (!JSON::Value::parseJSON(event.message.value(), messageValue))
+        return;
+
+    RefPtr<JSON::Array> messageArray;
+    if (!messageValue->asArray(messageArray))
+        return;
+
+    Vector<Target> targetList;
+    for (auto& itemValue : *messageArray) {
+        RefPtr<JSON::Object> itemObject;
+        if (!itemValue->asObject(itemObject))
+            continue;
+
+        Target target;
+        if (!itemObject->getInteger("targetID"_s, target.id)
+            || !itemObject->getString("name"_s, target.name)
+            || !itemObject->getString("url"_s, target.url)
+            || !itemObject->getString("type"_s, target.type))
+            continue;
+
+        targetList.append(WTFMove(target));
+    }
+
+    auto connectionID = event.connectionID.value();
+
+    // Find closed targets to remove them.
+    Vector<TargetID, 4> targetsToRemove;
+    for (auto& pair : m_inspectorProxyMap.keys()) {
+        if (pair.first != connectionID)
+            continue;
+
+        bool found = false;
+        for (auto& target : targetList) {
+            if (target.id == pair.second) {
+                found = true;
+                break;
+            }
+        }
+
+        if (!found)
+            targetsToRemove.append(pair.second);
+    }
+    for (auto& targetID : targetsToRemove)
+        m_inspectorProxyMap.remove(std::make_pair(connectionID, targetID));
+
+    m_targets.set(connectionID, WTFMove(targetList));
+    m_observer.targetListChanged(*this);
+}
+
+void RemoteInspectorClient::sendMessageToFrontend(const Event& event)
+{
+    if (!event.connectionID || !event.targetID || !event.message)
+        return;
+
+    auto proxy = m_inspectorProxyMap.get(std::make_pair(event.connectionID.value(), event.targetID.value()));
+    if (!proxy) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+
+    proxy->sendMessageToFrontend(event.message.value());
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/socket/RemoteInspectorClient.h b/Source/WebKit/UIProcess/socket/RemoteInspectorClient.h
new file mode 100644 (file)
index 0000000..d5b3584
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 Sony Interactive Entertainment Inc.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include <JavaScriptCore/RemoteControllableTarget.h>
+#include <JavaScriptCore/RemoteInspectorConnectionClient.h>
+#include <JavaScriptCore/RemoteInspectorSocketEndpoint.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+class RemoteInspectorClient;
+class RemoteInspectorProxy;
+
+class RemoteInspectorObserver {
+public:
+    virtual ~RemoteInspectorObserver() { }
+    virtual void targetListChanged(RemoteInspectorClient&) = 0;
+    virtual void connectionClosed(RemoteInspectorClient&) = 0;
+};
+
+using ConnectionID = Inspector::ConnectionID;
+using TargetID = Inspector::TargetID;
+
+class RemoteInspectorClient : public Inspector::RemoteInspectorConnectionClient {
+    WTF_MAKE_FAST_ALLOCATED();
+public:
+    RemoteInspectorClient(const char* address, unsigned port, RemoteInspectorObserver&);
+    ~RemoteInspectorClient();
+
+    struct Target {
+        TargetID id;
+        String type;
+        String name;
+        String url;
+    };
+
+    const HashMap<ConnectionID, Vector<Target>>& targets() const { return m_targets; }
+
+    void inspect(ConnectionID, TargetID);
+    void sendMessageToBackend(ConnectionID, TargetID, const String&);
+    void closeFromFrontend(ConnectionID, TargetID);
+
+private:
+    friend class NeverDestroyed<RemoteInspectorClient>;
+
+    void startInitialCommunication();
+    void connectionClosed();
+
+    void setTargetList(const Event&);
+    void sendMessageToFrontend(const Event&);
+    void setBackendCommands(const Event&);
+
+    void didClose(ConnectionID) override;
+    HashMap<String, CallHandler>& dispatchMap() override;
+
+    void sendWebInspectorEvent(const String&);
+
+    RemoteInspectorObserver& m_observer;
+    std::unique_ptr<Inspector::RemoteInspectorSocketEndpoint> m_socket;
+    Optional<ConnectionID> m_connectionID;
+    HashMap<ConnectionID, Vector<Target>> m_targets;
+    HashMap<std::pair<ConnectionID, TargetID>, std::unique_ptr<RemoteInspectorProxy>> m_inspectorProxyMap;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/socket/RemoteInspectorProtocolHandler.cpp b/Source/WebKit/UIProcess/socket/RemoteInspectorProtocolHandler.cpp
new file mode 100644 (file)
index 0000000..812e458
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2019 Sony Interactive Entertainment Inc.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "RemoteInspectorProtocolHandler.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "APINavigation.h"
+#include "APIUserContentWorld.h"
+#include "WebPageGroup.h"
+#include "WebPageProxy.h"
+#include "WebScriptMessageHandler.h"
+#include "WebUserContentControllerProxy.h"
+#include <WebCore/SerializedScriptValue.h>
+#include <wtf/URL.h>
+#include <wtf/text/StringBuilder.h>
+
+namespace WebKit {
+
+using namespace WebCore;
+
+class ScriptMessageClient final : public WebScriptMessageHandler::Client {
+public:
+    ScriptMessageClient(RemoteInspectorProtocolHandler& inspectorProtocolHandler)
+        : m_inspectorProtocolHandler(inspectorProtocolHandler) { }
+
+    ~ScriptMessageClient() { }
+
+    void didPostMessage(WebPageProxy& page, const FrameInfoData&, WebCore::SerializedScriptValue& serializedScriptValue) override
+    {
+        auto tokens = serializedScriptValue.toString().split(":");
+        if (tokens.size() != 2)
+            return;
+
+        URL requestURL { { }, page.pageLoadState().url() };
+        m_inspectorProtocolHandler.inspect(requestURL.hostAndPort(), tokens[0].toUIntStrict(), tokens[1].toUIntStrict());
+    }
+
+private:
+    RemoteInspectorProtocolHandler& m_inspectorProtocolHandler;
+};
+
+void RemoteInspectorProtocolHandler::inspect(const String& hostAndPort, ConnectionID connectionID, TargetID targetID)
+{
+    if (auto* client = m_inspectorClients.get(hostAndPort))
+        client->inspect(connectionID, targetID);
+}
+
+void RemoteInspectorProtocolHandler::targetListChanged(RemoteInspectorClient&)
+{
+    m_page.reload({ });
+}
+
+void RemoteInspectorProtocolHandler::platformStartTask(WebPageProxy& pageProxy, WebURLSchemeTask& task)
+{
+    auto& requestURL = task.request().url();
+    if (!requestURL.port())
+        return;
+
+    auto* client = m_inspectorClients.ensure(requestURL.hostAndPort(), [this, &requestURL] {
+        return std::make_unique<RemoteInspectorClient>(requestURL.host().utf8().data(), requestURL.port().value(), *this);
+    }).iterator->value.get();
+
+    // Setup target postMessage listener
+    auto handler = WebScriptMessageHandler::create(std::make_unique<ScriptMessageClient>(*this), "inspector", API::UserContentWorld::normalWorld());
+    pageProxy.pageGroup().userContentController().addUserScriptMessageHandler(handler.get());
+
+    StringBuilder htmlBuilder;
+    htmlBuilder.append(
+        "<html><head><title>Remote Inspector</title>"
+        "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
+        "<style>"
+        "  h1 { color: #babdb6; text-shadow: 0 1px 0 white; margin-bottom: 0; }"
+        "  html { font-family: -webkit-system-font; font-size: 11pt; color: #2e3436; padding: 20px 20px 0 20px; background-color: #f6f6f4; "
+        "         background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #eeeeec), color-stop(1, #f6f6f4));"
+        "         background-size: 100% 5em; background-repeat: no-repeat; }"
+        "  table { width: 100%; border-collapse: collapse; }"
+        "  table, td { border: 1px solid #d3d7cf; border-left: none; border-right: none; }"
+        "  p { margin-bottom: 30px; }"
+        "  td { padding: 15px; }"
+        "  td.data { width: 200px; }"
+        "  .targetname { font-weight: bold; }"
+        "  .targeturl { color: #babdb6; }"
+        "  td.input { width: 64px; }"
+        "  input { width: 100%; padding: 8px; }"
+        "</style>"
+        "</head><body><h1>Inspectable targets</h1>");
+
+    if (client->targets().isEmpty())
+        htmlBuilder.append("<p>No targets found</p>");
+    else {
+        htmlBuilder.append("<table>");
+        for (auto& connectionID : client->targets().keys()) {
+            for (auto& target : client->targets().get(connectionID)) {
+                htmlBuilder.append(makeString(
+                    "<tbody><tr>"
+                    "<td class=\"data\"><div class=\"targetname\">", target.name, "</div><div class=\"targeturl\">", target.url, "</div></td>"
+                    "<td class=\"input\"><input type=\"button\" value=\"Inspect\" onclick=\"window.webkit.messageHandlers.inspector.postMessage('", connectionID, ":", target.id, "');\"></td>"
+                    "</tr></tbody>"
+                ));
+            }
+        }
+        htmlBuilder.append("</table>");
+    }
+
+    htmlBuilder.append("</body></html>");
+
+    auto html = htmlBuilder.toString().utf8();
+    pageProxy.loadData({ reinterpret_cast<const uint8_t*>(html.data()), html.length() }, "text/html"_s, "UTF-8"_s, requestURL);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/socket/RemoteInspectorProtocolHandler.h b/Source/WebKit/UIProcess/socket/RemoteInspectorProtocolHandler.h
new file mode 100644 (file)
index 0000000..e0ac34e
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Sony Interactive Entertainment Inc.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#pragma once
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "RemoteInspectorClient.h"
+#include "WebURLSchemeHandler.h"
+
+namespace WTF {
+class URL;
+}
+
+namespace WebKit {
+
+class WebURLSchemeTask;
+
+class RemoteInspectorProtocolHandler final : public RemoteInspectorObserver, public WebURLSchemeHandler {
+public:
+    static Ref<RemoteInspectorProtocolHandler> create(WebPageProxy& page) { return adoptRef(*new RemoteInspectorProtocolHandler(page)); }
+
+    void inspect(const String&, ConnectionID, TargetID);
+
+private:
+    RemoteInspectorProtocolHandler(WebPageProxy& page)
+        : m_page(page) { }
+
+    // RemoteInspectorObserver
+    void targetListChanged(RemoteInspectorClient&) final;
+    void connectionClosed(RemoteInspectorClient&) final { }
+
+    // WebURLSchemeHandler
+    void platformStartTask(WebPageProxy&, WebURLSchemeTask&) final;
+    void platformStopTask(WebPageProxy&, WebURLSchemeTask&) final { }
+    void platformTaskCompleted(WebURLSchemeTask&) final { }
+
+    HashMap<String, std::unique_ptr<RemoteInspectorClient>> m_inspectorClients;
+    WebPageProxy& m_page;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
diff --git a/Source/WebKit/UIProcess/win/RemoteWebInspectorProxyWin.cpp b/Source/WebKit/UIProcess/win/RemoteWebInspectorProxyWin.cpp
new file mode 100644 (file)
index 0000000..0da1e53
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019 Sony Interactive Entertainment Inc.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "RemoteWebInspectorProxy.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include "APIPageConfiguration.h"
+#include "WebInspectorProxy.h"
+#include "WebPageGroup.h"
+#include "WebPageProxy.h"
+#include "WebView.h"
+#include <WebCore/IntRect.h>
+
+namespace WebKit {
+
+static LPCTSTR RemoteWebInspectorProxyPointerProp = TEXT("RemoteWebInspectorProxyPointer");
+const LPCWSTR RemoteWebInspectorProxyClassName = L"RemoteWebInspectorProxyClass";
+
+LRESULT CALLBACK RemoteWebInspectorProxy::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    RemoteWebInspectorProxy* client = reinterpret_cast<RemoteWebInspectorProxy*>(::GetProp(hwnd, RemoteWebInspectorProxyPointerProp));
+
+    switch (msg) {
+    case WM_SIZE:
+        return client->sizeChange();
+    case WM_CLOSE:
+        return client->onClose();
+    default:
+        break;
+    }
+
+    return ::DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+static ATOM registerWindowClass()
+{
+    static bool haveRegisteredWindowClass = false;
+    if (haveRegisteredWindowClass)
+        return true;
+
+    WNDCLASSEX wcex;
+    wcex.cbSize = sizeof(WNDCLASSEX);
+    wcex.style          = 0;
+    wcex.lpfnWndProc    = RemoteWebInspectorProxy::WndProc;
+    wcex.cbClsExtra     = 0;
+    wcex.cbWndExtra     = 0;
+    wcex.hInstance      = 0;
+    wcex.hIcon          = 0;
+    wcex.hCursor        = LoadCursor(0, IDC_ARROW);
+    wcex.hbrBackground  = 0;
+    wcex.lpszMenuName   = 0;
+    wcex.lpszClassName  = RemoteWebInspectorProxyClassName;
+    wcex.hIconSm        = 0;
+
+    haveRegisteredWindowClass = true;
+    return ::RegisterClassEx(&wcex);
+}
+
+LRESULT RemoteWebInspectorProxy::sizeChange()
+{
+    if (!m_webView)
+        return 0;
+
+    RECT rect;
+    ::GetClientRect(m_frontendHandle, &rect);
+    ::SetWindowPos(m_webView->window(), 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
+    return 0;
+}
+
+LRESULT RemoteWebInspectorProxy::onClose()
+{
+    ::ShowWindow(m_frontendHandle, SW_HIDE);
+    frontendDidClose();
+    return 0;
+}
+
+WebPageProxy* RemoteWebInspectorProxy::platformCreateFrontendPageAndWindow()
+{
+    RefPtr<WebPreferences> preferences = WebPreferences::create(String(), "WebKit2.", "WebKit2.");
+    preferences->setAllowFileAccessFromFileURLs(true);
+
+#if ENABLE(DEVELOPER_MODE)
+    preferences->setDeveloperExtrasEnabled(true);
+    preferences->setLogsPageMessagesToSystemConsoleEnabled(true);
+#endif
+
+    RefPtr<WebPageGroup> pageGroup = WebPageGroup::create(inspectorPageGroupIdentifierForPage(nullptr));
+
+    auto pageConfiguration = API::PageConfiguration::create();
+    pageConfiguration->setProcessPool(&inspectorProcessPool(inspectorLevelForPage(nullptr)));
+    pageConfiguration->setPreferences(preferences.get());
+    pageConfiguration->setPageGroup(pageGroup.get());
+
+    WebCore::IntRect rect(60, 200, 1500, 1000);
+    registerWindowClass();
+    m_frontendHandle = ::CreateWindowEx(0, RemoteWebInspectorProxyClassName, 0, WS_OVERLAPPEDWINDOW,
+        rect.x(), rect.y(), rect.width(), rect.height(), 0, 0, 0, 0);
+
+    ::SetProp(m_frontendHandle, RemoteWebInspectorProxyPointerProp, reinterpret_cast<HANDLE>(this));
+    ShowWindow(m_frontendHandle, SW_SHOW);
+
+    RECT r;
+    ::GetClientRect(m_frontendHandle, &r);
+    m_webView = WebView::create(r, pageConfiguration, m_frontendHandle);
+    return m_webView->page();
+}
+
+void RemoteWebInspectorProxy::platformBringToFront() { }
+void RemoteWebInspectorProxy::platformSave(const String&, const String&, bool, bool) { }
+void RemoteWebInspectorProxy::platformAppend(const String&, const String&) { }
+void RemoteWebInspectorProxy::platformSetSheetRect(const WebCore::FloatRect&) { }
+void RemoteWebInspectorProxy::platformStartWindowDrag() { }
+void RemoteWebInspectorProxy::platformOpenInNewTab(const String&) { }
+void RemoteWebInspectorProxy::platformShowCertificate(const WebCore::CertificateInfo&) { }
+
+void RemoteWebInspectorProxy::platformCloseFrontendPageAndWindow()
+{
+    ::DestroyWindow(m_frontendHandle);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(REMOTE_INSPECTOR)
index 962f302..5dd305c 100644 (file)
@@ -33,6 +33,7 @@
 #include "NativeWebKeyboardEvent.h"
 #include "NativeWebMouseEvent.h"
 #include "NativeWebWheelEvent.h"
+#include "RemoteInspectorProtocolHandler.h"
 #include "WKAPICast.h"
 #include "WebContextMenuProxyWin.h"
 #include "WebEditCommandProxy.h"
@@ -236,6 +237,10 @@ WebView::WebView(RECT rect, const API::PageConfiguration& configuration, HWND pa
     if (m_page->drawingArea())
         m_page->drawingArea()->setSize(IntSize(rect.right - rect.left, rect.bottom - rect.top));
 
+#if ENABLE(REMOTE_INSPECTOR)
+    m_page->setURLSchemeHandlerForScheme(RemoteInspectorProtocolHandler::create(*m_page), "inspector");
+#endif
+
     // FIXME: Initializing the tooltip window here matches WebKit win, but seems like something
     // we could do on demand to save resources.
     initializeToolTipWindow();
index 3e8f769..1223bed 100644 (file)
@@ -68,7 +68,6 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_AUDIO PUBLIC OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_XSLT PUBLIC ON)
 
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SMOOTH_SCROLLING PRIVATE OFF)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USER_MESSAGE_HANDLERS PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USERSELECT_ALL PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBGL PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CRYPTO PRIVATE OFF)
@@ -77,6 +76,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CRYPTO PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_SYSTEM_MALLOC PRIVATE ON)
 
 if (${WTF_PLATFORM_WIN_CAIRO})
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USER_MESSAGE_HANDLERS PRIVATE ON)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER PUBLIC OFF)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_ENCRYPTED_MEDIA PUBLIC OFF)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INTL PUBLIC ON)
@@ -96,6 +96,7 @@ if (${WTF_PLATFORM_WIN_CAIRO})
     # FIXME: Implement plugin process on Modern WebKit. https://bugs.webkit.org/show_bug.cgi?id=185313
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
 else ()
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USER_MESSAGE_HANDLERS PRIVATE OFF)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_ENCRYPTED_MEDIA PUBLIC ON)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INTL PUBLIC OFF)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PUBLIC_SUFFIX_LIST PRIVATE OFF)
index 0fbad95..17a8216 100644 (file)
@@ -29,7 +29,7 @@ SET_AND_EXPOSE_TO_BUILD(USE_CURL ON)
 SET_AND_EXPOSE_TO_BUILD(USE_TEXTURE_MAPPER ON)
 SET_AND_EXPOSE_TO_BUILD(USE_TEXTURE_MAPPER_GL ON)
 SET_AND_EXPOSE_TO_BUILD(USE_MEDIA_FOUNDATION ON)
-SET_AND_EXPOSE_TO_BUILD(USE_INSPECTOR_SOCKET_SERVER ENABLE_REMOTE_INSPECTOR)
+SET_AND_EXPOSE_TO_BUILD(USE_INSPECTOR_SOCKET_SERVER ${ENABLE_REMOTE_INSPECTOR})
 
 set(ENABLE_GRAPHICS_CONTEXT_3D ON)
 set(ENABLE_WEBKIT ON)