Title: [250988] trunk/Source
Revision
250988
Author
basuke.suz...@sony.com
Date
2019-10-10 14:20:12 -0700 (Thu, 10 Oct 2019)

Log Message

[WinCairo] Move remote communication handling from RemoteInspectorServer to RemoteInspector.
https://bugs.webkit.org/show_bug.cgi?id=202763

Reviewed by Ross Kirsling.

Source/_javascript_Core:

Because RemoteInspector now exists in UIProcess, the old implementation which communicate with RemoteInspector
in WebProcess and RemoteInspectorServer in UIProcess was meaningless or even bad. Remove this complex
implementation and move communication handling from RemoteInspectorServer to RemoteInspector and communicate
each other directly.

* inspector/remote/RemoteInspector.h:
* inspector/remote/socket/RemoteInspectorConnectionClient.cpp:
* inspector/remote/socket/RemoteInspectorConnectionClient.h:
* inspector/remote/socket/RemoteInspectorServer.cpp:
(Inspector::RemoteInspectorServer::~RemoteInspectorServer):
(Inspector::RemoteInspectorServer::start):
(Inspector::RemoteInspectorServer::didAccept):
* inspector/remote/socket/RemoteInspectorServer.h:
* inspector/remote/socket/RemoteInspectorSocket.cpp:
(Inspector::RemoteInspector::connect):
(Inspector::RemoteInspector::didClose):
(Inspector::RemoteInspector::sendWebInspectorEvent):
(Inspector::RemoteInspector::start):
(Inspector::RemoteInspector::stopInternal):
(Inspector::RemoteInspector::pushListingsNow):
(Inspector::RemoteInspector::pushListingsSoon):
(Inspector::RemoteInspector::sendMessageToRemote):
(Inspector::RemoteInspector::setup):
(Inspector::RemoteInspector::sendMessageToTarget):
(Inspector::RemoteInspector::backendCommands const):
(Inspector::RemoteInspector::dispatchMap):
(Inspector::RemoteInspector::setupInspectorClient):
(Inspector::RemoteInspector::setupTarget):
(Inspector::RemoteInspector::frontendDidClose):
(Inspector::RemoteInspector::sendMessageToBackend):
* inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp:
(Inspector::RemoteInspectorSocketEndpoint::~RemoteInspectorSocketEndpoint):
(Inspector::RemoteInspectorSocketEndpoint::listenInet):
(Inspector::RemoteInspectorSocketEndpoint::isListening):
(Inspector::RemoteInspectorSocketEndpoint::workerThread):
(Inspector::RemoteInspectorSocketEndpoint::generateConnectionID):
(Inspector::RemoteInspectorSocketEndpoint::makeConnection):
(Inspector::RemoteInspectorSocketEndpoint::createClient):
(Inspector::RemoteInspectorSocketEndpoint::createListener):
(Inspector::RemoteInspectorSocketEndpoint::invalidateListener):
(Inspector::RemoteInspectorSocketEndpoint::getPort const):
(Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled):
* inspector/remote/socket/RemoteInspectorSocketEndpoint.h:

Source/WebKit:

Remove deleted method invocations.

* UIProcess/win/WebProcessPoolWin.cpp:
(WebKit::initializeRemoteInspectorServer):
(WebKit::WebProcessPool::platformInitialize):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (250987 => 250988)


--- trunk/Source/_javascript_Core/ChangeLog	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-10-10 21:20:12 UTC (rev 250988)
@@ -1,3 +1,54 @@
+2019-10-10  Basuke Suzuki  <basuke.suz...@sony.com>
+
+        [WinCairo] Move remote communication handling from RemoteInspectorServer to RemoteInspector.
+        https://bugs.webkit.org/show_bug.cgi?id=202763
+
+        Reviewed by Ross Kirsling.
+
+        Because RemoteInspector now exists in UIProcess, the old implementation which communicate with RemoteInspector
+        in WebProcess and RemoteInspectorServer in UIProcess was meaningless or even bad. Remove this complex
+        implementation and move communication handling from RemoteInspectorServer to RemoteInspector and communicate
+        each other directly.
+
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/socket/RemoteInspectorConnectionClient.cpp:
+        * inspector/remote/socket/RemoteInspectorConnectionClient.h:
+        * inspector/remote/socket/RemoteInspectorServer.cpp:
+        (Inspector::RemoteInspectorServer::~RemoteInspectorServer):
+        (Inspector::RemoteInspectorServer::start):
+        (Inspector::RemoteInspectorServer::didAccept):
+        * inspector/remote/socket/RemoteInspectorServer.h:
+        * inspector/remote/socket/RemoteInspectorSocket.cpp:
+        (Inspector::RemoteInspector::connect):
+        (Inspector::RemoteInspector::didClose):
+        (Inspector::RemoteInspector::sendWebInspectorEvent):
+        (Inspector::RemoteInspector::start):
+        (Inspector::RemoteInspector::stopInternal):
+        (Inspector::RemoteInspector::pushListingsNow):
+        (Inspector::RemoteInspector::pushListingsSoon):
+        (Inspector::RemoteInspector::sendMessageToRemote):
+        (Inspector::RemoteInspector::setup):
+        (Inspector::RemoteInspector::sendMessageToTarget):
+        (Inspector::RemoteInspector::backendCommands const):
+        (Inspector::RemoteInspector::dispatchMap):
+        (Inspector::RemoteInspector::setupInspectorClient):
+        (Inspector::RemoteInspector::setupTarget):
+        (Inspector::RemoteInspector::frontendDidClose):
+        (Inspector::RemoteInspector::sendMessageToBackend):
+        * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp:
+        (Inspector::RemoteInspectorSocketEndpoint::~RemoteInspectorSocketEndpoint):
+        (Inspector::RemoteInspectorSocketEndpoint::listenInet):
+        (Inspector::RemoteInspectorSocketEndpoint::isListening):
+        (Inspector::RemoteInspectorSocketEndpoint::workerThread):
+        (Inspector::RemoteInspectorSocketEndpoint::generateConnectionID):
+        (Inspector::RemoteInspectorSocketEndpoint::makeConnection):
+        (Inspector::RemoteInspectorSocketEndpoint::createClient):
+        (Inspector::RemoteInspectorSocketEndpoint::createListener):
+        (Inspector::RemoteInspectorSocketEndpoint::invalidateListener):
+        (Inspector::RemoteInspectorSocketEndpoint::getPort const):
+        (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled):
+        * inspector/remote/socket/RemoteInspectorSocketEndpoint.h:
+
 2019-10-10  Yusuke Suzuki  <ysuz...@apple.com>
 
         Unreviewed, speculative fix build failure on 32bit

Modified: trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.h (250987 => 250988)


--- trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.h	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/inspector/remote/RemoteInspector.h	2019-10-10 21:20:12 UTC (rev 250988)
@@ -57,7 +57,6 @@
 #include "RemoteConnectionToTarget.h"
 #include "RemoteInspectorConnectionClient.h"
 #include <wtf/JSONValues.h>
-#include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 
 namespace Inspector {
@@ -150,8 +149,12 @@
     void sendMessageToTarget(TargetID, const char* message);
 #endif
 #if USE(INSPECTOR_SOCKET_SERVER)
-    static void setConnectionIdentifier(PlatformSocketType);
-    static void setServerPort(uint16_t);
+    void requestAutomationSession(String&& sessionID, const Client::SessionCapabilities&);
+
+    bool isConnected() const { return !!m_clientConnection; }
+    void connect(ConnectionID);
+
+    void setBackendCommandsPath(const String& backendCommandsPath) { m_backendCommandsPath = backendCommandsPath; }
 #endif
 
 private:
@@ -214,10 +217,12 @@
 
     void sendWebInspectorEvent(const String&);
 
-    void receivedGetTargetListMessage(const Event&);
-    void receivedSetupMessage(const Event&);
-    void receivedDataMessage(const Event&);
-    void receivedCloseMessage(const Event&);
+    void setupInspectorClient(const Event&);
+    void setupTarget(const Event&);
+    void frontendDidClose(const Event&);
+    void sendMessageToBackend(const Event&);
+
+    String backendCommands() const;
 #endif
     static bool startEnabled;
 
@@ -240,9 +245,11 @@
 #endif
 
 #if USE(INSPECTOR_SOCKET_SERVER)
-    static PlatformSocketType s_connectionIdentifier;
-    static uint16_t s_serverPort;
-    Optional<ConnectionID> m_clientID;
+    // Connection from RemoteInspectorClient or WebDriver.
+    Optional<ConnectionID> m_clientConnection;
+    bool m_readyToPushListings { false };
+
+    String m_backendCommandsPath;
 #endif
 
     RemoteInspector::Client* m_client { nullptr };

Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorConnectionClient.cpp (250987 => 250988)


--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorConnectionClient.cpp	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorConnectionClient.cpp	2019-10-10 21:20:12 UTC (rev 250988)
@@ -46,12 +46,6 @@
     return endpoint.connectInet(serverAddr, serverPort, *this);
 }
 
-Optional<ConnectionID> RemoteInspectorConnectionClient::listenInet(const char* address, uint16_t port)
-{
-    auto& endpoint = Inspector::RemoteInspectorSocketEndpoint::singleton();
-    return endpoint.listenInet(address, port, *this);
-}
-
 Optional<ConnectionID> RemoteInspectorConnectionClient::createClient(PlatformSocketType socket)
 {
     auto& endpoint = Inspector::RemoteInspectorSocketEndpoint::singleton();

Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorConnectionClient.h (250987 => 250988)


--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorConnectionClient.h	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorConnectionClient.h	2019-10-10 21:20:12 UTC (rev 250988)
@@ -43,12 +43,10 @@
     virtual ~RemoteInspectorConnectionClient();
 
     Optional<ConnectionID> connectInet(const char* serverAddr, uint16_t serverPort);
-    Optional<ConnectionID> listenInet(const char* address, uint16_t port);
     Optional<ConnectionID> createClient(PlatformSocketType);
     void send(ConnectionID, const uint8_t* data, size_t);
 
     void didReceive(ConnectionID, Vector<uint8_t>&&) override;
-    void didAccept(ConnectionID, ConnectionID, Socket::Domain) override { }
 
     struct Event {
         String methodName;

Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.cpp (250987 => 250988)


--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.cpp	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.cpp	2019-10-10 21:20:12 UTC (rev 250988)
@@ -29,96 +29,10 @@
 #if ENABLE(REMOTE_INSPECTOR)
 
 #include "RemoteInspectorMessageParser.h"
-#include <wtf/FileSystem.h>
-#include <wtf/JSONValues.h>
 #include <wtf/MainThread.h>
-#include <wtf/RunLoop.h>
 
 namespace Inspector {
 
-Optional<PlatformSocketType> RemoteInspectorServer::connect()
-{
-    if (auto sockets = Socket::createPair()) {
-        if (auto id = createClient(sockets->at(0))) {
-            LockHolder lock(m_connectionsLock);
-            m_inspectorConnections.append(id.value());
-
-            return sockets->at(1);
-        }
-    }
-
-    return WTF::nullopt;
-}
-
-Optional<uint16_t> RemoteInspectorServer::listenForTargets()
-{
-    if (m_inspectorListener) {
-        LOG_ERROR("Inspector server is already listening for targets.");
-        return WTF::nullopt;
-    }
-
-    if (auto connection = listenInet("127.0.0.1", 0)) {
-        m_inspectorListener = connection;
-
-        auto& endpoint = RemoteInspectorSocketEndpoint::singleton();
-        return endpoint.getPort(*connection);
-    }
-
-    return WTF::nullopt;
-}
-
-void RemoteInspectorServer::didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain type)
-{
-    ASSERT(!isMainThread());
-
-    if (type == Socket::Domain::Local || (m_inspectorListener && listenerID == *m_inspectorListener)) {
-        LockHolder lock(m_connectionsLock);
-        m_inspectorConnections.append(acceptedID);
-    } else if (type == Socket::Domain::Network) {
-        if (m_clientConnection) {
-            LOG_ERROR("Inspector server can accept only 1 client");
-            return;
-        }
-        m_clientConnection = acceptedID;
-    }
-}
-
-void RemoteInspectorServer::didClose(ConnectionID id)
-{
-    ASSERT(!isMainThread());
-
-    if (id == m_clientConnection) {
-        // Connection from the remote client closed.
-        clientConnectionClosed();
-        return;
-    }
-
-    // Connection from WebProcess closed.
-    RunLoop::main().dispatch([this, id] {
-        connectionClosed(id);
-    });
-}
-
-HashMap<String, RemoteInspectorConnectionClient::CallHandler>& RemoteInspectorServer::dispatchMap()
-{
-    static NeverDestroyed<HashMap<String, CallHandler>> dispatchMap = HashMap<String, CallHandler>({
-        { "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;
-}
-
-void RemoteInspectorServer::sendWebInspectorEvent(ConnectionID id, const String& event)
-{
-    const CString message = event.utf8();
-    send(id, reinterpret_cast<const uint8_t*>(message.data()), message.length());
-}
-
 RemoteInspectorServer& RemoteInspectorServer::singleton()
 {
     static NeverDestroyed<RemoteInspectorServer> server;
@@ -125,157 +39,33 @@
     return server;
 }
 
-bool RemoteInspectorServer::start(const char* address, uint16_t port)
+RemoteInspectorServer::~RemoteInspectorServer()
 {
-    m_server = listenInet(address, port);
-    return isRunning();
+    auto& endpoint = Inspector::RemoteInspectorSocketEndpoint::singleton();
+    endpoint.invalidateListener(*this);
 }
 
-void RemoteInspectorServer::setTargetList(const Event& event)
+bool RemoteInspectorServer::start(const char* address, uint16_t port)
 {
-    ASSERT(isMainThread());
-
-    if (!m_clientConnection || !event.message)
-        return;
-
-    auto targetListEvent = JSON::Object::create();
-    targetListEvent->setString("event"_s, "SetTargetList"_s);
-    targetListEvent->setInteger("connectionID"_s, event.clientID);
-    targetListEvent->setString("message"_s, event.message.value());
-    sendWebInspectorEvent(m_clientConnection.value(), targetListEvent->toJSONString());
+    auto& endpoint = Inspector::RemoteInspectorSocketEndpoint::singleton();
+    m_server = endpoint.listenInet(address, port, *this, RemoteInspector::singleton());
+    return isRunning();
 }
 
-void RemoteInspectorServer::setupInspectorClient(const Event&)
+bool RemoteInspectorServer::didAccept(ConnectionID acceptedID, ConnectionID, Socket::Domain)
 {
-    ASSERT(isMainThread());
-
-    auto backendCommandsEvent = JSON::Object::create();
-    backendCommandsEvent->setString("event"_s, "BackendCommands"_s);
-    backendCommandsEvent->setString("message"_s, backendCommands());
-    sendWebInspectorEvent(m_clientConnection.value(), backendCommandsEvent->toJSONString());
-
-    auto setupEvent = JSON::Object::create();
-    setupEvent->setString("event"_s, "GetTargetList"_s);
-
-    LockHolder lock(m_connectionsLock);
-    for (auto connection : m_inspectorConnections)
-        sendWebInspectorEvent(connection, setupEvent->toJSONString());
-}
-
-void RemoteInspectorServer::setup(const Event& event)
-{
-    ASSERT(isMainThread());
-
-    if (!event.targetID || !event.connectionID)
-        return;
-
-    m_inspectionTargets.add(std::make_pair(event.connectionID.value(), event.targetID.value()));
-
-    auto setupEvent = JSON::Object::create();
-    setupEvent->setString("event"_s, "Setup"_s);
-    setupEvent->setInteger("targetID"_s, event.targetID.value());
-    sendWebInspectorEvent(event.connectionID.value(), setupEvent->toJSONString());
-}
-
-void RemoteInspectorServer::sendCloseEvent(ConnectionID connectionID, TargetID targetID)
-{
-    ASSERT(isMainThread());
-
-    auto closeEvent = JSON::Object::create();
-    closeEvent->setString("event"_s, "FrontendDidClose"_s);
-    closeEvent->setInteger("targetID"_s, targetID);
-    sendWebInspectorEvent(connectionID, closeEvent->toJSONString());
-}
-
-void RemoteInspectorServer::close(const Event& event)
-{
-    ASSERT(isMainThread());
-
-    sendCloseEvent(event.connectionID.value(), event.targetID.value());
-    m_inspectionTargets.remove(std::make_pair(event.connectionID.value(), event.targetID.value()));
-}
-
-void RemoteInspectorServer::clientConnectionClosed()
-{
     ASSERT(!isMainThread());
 
-    m_clientConnection = WTF::nullopt;
+    auto& inspector = RemoteInspector::singleton();
+    if (inspector.isConnected()) {
+        LOG_ERROR("RemoteInspector can accept only 1 client");
 
-    RunLoop::main().dispatch([this] {
-        LockHolder lock(m_connectionsLock);
-        for (auto connectionTargetPair : m_inspectionTargets)
-            sendCloseEvent(connectionTargetPair.first, connectionTargetPair.second);
-        m_inspectionTargets.clear();
-    });
-}
-
-void RemoteInspectorServer::connectionClosed(ConnectionID clientID)
-{
-    ASSERT(isMainThread());
-
-    LockHolder lock(m_connectionsLock);
-    if (m_inspectorConnections.removeFirst(clientID) && m_clientConnection) {
-        auto closedEvent = JSON::Object::create();
-        closedEvent->setString("event"_s, "SetTargetList"_s);
-        closedEvent->setInteger("connectionID"_s, clientID);
-        auto targetList = JSON::Array::create();
-        closedEvent->setString("message"_s, targetList->toJSONString());
-        sendWebInspectorEvent(m_clientConnection.value(), closedEvent->toJSONString());
+        return false;
     }
+    inspector.connect(acceptedID);
+    return true;
 }
 
-void RemoteInspectorServer::sendMessageToBackend(const Event& event)
-{
-    ASSERT(isMainThread());
-
-    if (!event.connectionID || !event.targetID || !event.message)
-        return;
-
-    auto sendEvent = JSON::Object::create();
-    sendEvent->setString("event"_s, "SendMessageToTarget"_s);
-    sendEvent->setInteger("targetID"_s, event.targetID.value());
-    sendEvent->setString("message"_s, event.message.value());
-    sendWebInspectorEvent(event.connectionID.value(), sendEvent->toJSONString());
-}
-
-void RemoteInspectorServer::sendMessageToFrontend(const Event& event)
-{
-    if (!m_clientConnection)
-        return;
-
-    ASSERT(isMainThread());
-
-    if (!event.targetID || !event.message)
-        return;
-
-    auto sendEvent = JSON::Object::create();
-    sendEvent->setString("event"_s, "SendMessageToFrontend"_s);
-    sendEvent->setInteger("targetID"_s, event.targetID.value());
-    sendEvent->setInteger("connectionID"_s, event.clientID);
-    sendEvent->setString("message"_s, event.message.value());
-    sendWebInspectorEvent(m_clientConnection.value(), sendEvent->toJSONString());
-}
-
-String RemoteInspectorServer::backendCommands() const
-{
-    if (m_backendCommandsPath.isEmpty())
-        return { };
-
-    auto handle = FileSystem::openFile(m_backendCommandsPath, FileSystem::FileOpenMode::Read);
-    if (!FileSystem::isHandleValid(handle))
-        return { };
-
-    String result;
-    long long size;
-    if (FileSystem::getFileSize(handle, size)) {
-        Vector<LChar> buffer(size);
-        if (FileSystem::readFromFile(handle, reinterpret_cast<char*>(buffer.data()), size) == size)
-            result = String::adopt(WTFMove(buffer));
-    }
-    FileSystem::closeFile(handle);
-    return result;
-}
-
 } // namespace Inspector
 
 #endif // ENABLE(REMOTE_INSPECTOR)

Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.h (250987 => 250988)


--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.h	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.h	2019-10-10 21:20:12 UTC (rev 250988)
@@ -28,66 +28,27 @@
 #if ENABLE(REMOTE_INSPECTOR)
 
 #include "RemoteInspector.h"
+#include "RemoteInspectorSocketEndpoint.h"
 
-#include "RemoteInspectorConnectionClient.h"
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/Lock.h>
-
 namespace Inspector {
 
-class RemoteInspectorServer : public RemoteInspectorConnectionClient {
+class RemoteInspectorServer final : public RemoteInspectorSocketEndpoint::Listener {
 public:
+    ~RemoteInspectorServer();
+
     JS_EXPORT_PRIVATE static RemoteInspectorServer& singleton();
 
     JS_EXPORT_PRIVATE bool start(const char* address, uint16_t port);
     bool isRunning() const { return !!m_server; }
 
-    JS_EXPORT_PRIVATE Optional<uint16_t> listenForTargets();
-    JS_EXPORT_PRIVATE Optional<PlatformSocketType> connect();
-
-    void setBackendCommandsPath(const String& backendCommandsPath) { m_backendCommandsPath = backendCommandsPath; }
-
 private:
     friend class NeverDestroyed<RemoteInspectorServer>;
     RemoteInspectorServer() { Socket::init(); }
 
-    void connectionClosed(ConnectionID);
+    bool didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain) override;
+    void didClose(ConnectionID) override { }
 
-    void setTargetList(const Event&);
-    void setupInspectorClient(const Event&);
-    void setup(const Event&);
-    void close(const Event&);
-    void sendMessageToFrontend(const Event&);
-    void sendMessageToBackend(const Event&);
-
-    void sendCloseEvent(ConnectionID, TargetID);
-    void clientConnectionClosed();
-
-    void didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain) override;
-    void didClose(ConnectionID) override;
-
-    void sendWebInspectorEvent(ConnectionID, const String&);
-
-    String backendCommands() const;
-
-    HashMap<String, CallHandler>& dispatchMap() override;
-
-    HashSet<std::pair<ConnectionID, TargetID>> m_inspectionTargets;
-
     Optional<ConnectionID> m_server;
-
-    // Connections to the WebProcess.
-    Vector<ConnectionID> m_inspectorConnections;
-    Lock m_connectionsLock;
-
-    // Listener for targets.
-    Optional<ConnectionID> m_inspectorListener;
-
-    // Connection from RemoteInspectorClient.
-    Optional<ConnectionID> m_clientConnection;
-
-    String m_backendCommandsPath;
 };
 
 } // namespace Inspector

Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocket.cpp (250987 => 250988)


--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocket.cpp	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocket.cpp	2019-10-10 21:20:12 UTC (rev 250988)
@@ -31,6 +31,7 @@
 #include "RemoteAutomationTarget.h"
 #include "RemoteConnectionToTarget.h"
 #include "RemoteInspectionTarget.h"
+#include <wtf/FileSystem.h>
 #include <wtf/JSONValues.h>
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
@@ -38,9 +39,6 @@
 
 namespace Inspector {
 
-PlatformSocketType RemoteInspector::s_connectionIdentifier = INVALID_SOCKET_VALUE;
-uint16_t RemoteInspector::s_serverPort = 0;
-
 RemoteInspector& RemoteInspector::singleton()
 {
     static NeverDestroyed<RemoteInspector> shared;
@@ -53,11 +51,20 @@
     start();
 }
 
-void RemoteInspector::didClose(ConnectionID id)
+void RemoteInspector::connect(ConnectionID id)
 {
-    if (id != m_clientID.value())
-        return;
+    ASSERT(!isConnected());
 
+    m_clientConnection = id;
+    start();
+}
+
+void RemoteInspector::didClose(ConnectionID)
+{
+    ASSERT(isConnected());
+
+    m_clientConnection = WTF::nullopt;
+
     RunLoop::current().dispatch([=] {
         LockHolder lock(m_mutex);
         stopInternal(StopSource::API);
@@ -64,25 +71,13 @@
     });
 }
 
-HashMap<String, RemoteInspector::CallHandler>& RemoteInspector::dispatchMap()
-{
-    static NeverDestroyed<HashMap<String, CallHandler>> methods = HashMap<String, CallHandler>({
-        { "GetTargetList"_s, static_cast<CallHandler>(&RemoteInspector::receivedGetTargetListMessage) },
-        { "Setup"_s, static_cast<CallHandler>(&RemoteInspector::receivedSetupMessage) },
-        { "SendMessageToTarget"_s, static_cast<CallHandler>(&RemoteInspector::receivedDataMessage) },
-        { "FrontendDidClose"_s, static_cast<CallHandler>(&RemoteInspector::receivedCloseMessage) },
-    });
-
-    return methods;
-}
-
 void RemoteInspector::sendWebInspectorEvent(const String& event)
 {
-    if (!m_clientID)
+    if (!m_clientConnection)
         return;
 
     const CString message = event.utf8();
-    send(m_clientID.value(), reinterpret_cast<const uint8_t*>(message.data()), message.length());
+    send(m_clientConnection.value(), reinterpret_cast<const uint8_t*>(message.data()), message.length());
 }
 
 void RemoteInspector::start()
@@ -89,19 +84,10 @@
 {
     LockHolder lock(m_mutex);
 
-    if (m_enabled || (s_connectionIdentifier == INVALID_SOCKET_VALUE && !s_serverPort))
+    if (m_enabled)
         return;
 
     m_enabled = true;
-
-    if (s_connectionIdentifier != INVALID_SOCKET_VALUE) {
-        m_clientID = createClient(s_connectionIdentifier);
-        s_connectionIdentifier = INVALID_SOCKET_VALUE;
-    } else
-        m_clientID = connectInet("127.0.0.1", s_serverPort);
-
-    if (!m_targetMap.isEmpty())
-        pushListingsSoon();
 }
 
 void RemoteInspector::stopInternal(StopSource)
@@ -111,6 +97,7 @@
 
     m_enabled = false;
     m_pushScheduled = false;
+    m_readyToPushListings = false;
 
     for (auto targetConnection : m_targetConnectionMap.values())
         targetConnection->close();
@@ -119,7 +106,6 @@
     updateHasActiveDebugSession();
 
     m_automaticInspectionPaused = false;
-    m_clientID = WTF::nullopt;
 }
 
 TargetListing RemoteInspector::listingForInspectionTarget(const RemoteInspectionTarget& target) const
@@ -154,7 +140,7 @@
 
 void RemoteInspector::pushListingsNow()
 {
-    if (!m_clientID)
+    if (!isConnected() || !m_readyToPushListings)
         return;
 
     m_pushScheduled = false;
@@ -166,12 +152,14 @@
     auto jsonEvent = JSON::Object::create();
     jsonEvent->setString("event"_s, "SetTargetList"_s);
     jsonEvent->setString("message"_s, targetListJSON->toJSONString());
+    jsonEvent->setInteger("connectionID"_s, m_clientConnection.value());
+    jsonEvent->setBoolean("remoteAutomationAllowed"_s, m_clientCapabilities && m_clientCapabilities->remoteAutomationAllowed);
     sendWebInspectorEvent(jsonEvent->toJSONString());
 }
 
 void RemoteInspector::pushListingsSoon()
 {
-    if (!m_clientID)
+    if (!isConnected())
         return;
 
     if (m_pushScheduled)
@@ -192,52 +180,106 @@
 
 void RemoteInspector::sendMessageToRemote(TargetID targetIdentifier, const String& message)
 {
-    LockHolder lock(m_mutex);
-    if (!m_clientID)
+    if (!m_clientConnection)
         return;
 
     auto sendMessageEvent = JSON::Object::create();
     sendMessageEvent->setInteger("targetID"_s, targetIdentifier);
     sendMessageEvent->setString("event"_s, "SendMessageToFrontend"_s);
+    sendMessageEvent->setInteger("connectionID"_s, m_clientConnection.value());
     sendMessageEvent->setString("message"_s, message);
     sendWebInspectorEvent(sendMessageEvent->toJSONString());
 }
 
-void RemoteInspector::receivedGetTargetListMessage(const Event&)
+void RemoteInspector::setup(TargetID targetIdentifier)
 {
-    ASSERT(isMainThread());
+    RemoteControllableTarget* target;
+    {
+        LockHolder lock(m_mutex);
+        target = m_targetMap.get(targetIdentifier);
+        if (!target)
+            return;
+    }
 
+    auto connectionToTarget = adoptRef(*new RemoteConnectionToTarget(*target));
+    ASSERT(is<RemoteInspectionTarget>(target) || is<RemoteAutomationTarget>(target));
+    if (!connectionToTarget->setup()) {
+        connectionToTarget->close();
+        return;
+    }
+
     LockHolder lock(m_mutex);
-    pushListingsNow();
+    m_targetConnectionMap.set(targetIdentifier, WTFMove(connectionToTarget));
+
+    updateHasActiveDebugSession();
 }
 
-void RemoteInspector::receivedSetupMessage(const Event& event)
+void RemoteInspector::sendMessageToTarget(TargetID targetIdentifier, const char* message)
 {
+    if (auto connectionToTarget = m_targetConnectionMap.get(targetIdentifier))
+        connectionToTarget->sendMessageToTarget(String::fromUTF8(message));
+}
+
+String RemoteInspector::backendCommands() const
+{
+    if (m_backendCommandsPath.isEmpty())
+        return { };
+
+    auto handle = FileSystem::openFile(m_backendCommandsPath, FileSystem::FileOpenMode::Read);
+    if (!FileSystem::isHandleValid(handle))
+        return { };
+
+    String result;
+    long long size;
+    if (FileSystem::getFileSize(handle, size)) {
+        Vector<LChar> buffer(size);
+        if (FileSystem::readFromFile(handle, reinterpret_cast<char*>(buffer.data()), size) == size)
+            result = String::adopt(WTFMove(buffer));
+    }
+    FileSystem::closeFile(handle);
+    return result;
+}
+
+// RemoteInspectorConnectionClient handlers
+
+HashMap<String, RemoteInspectorConnectionClient::CallHandler>& RemoteInspector::dispatchMap()
+{
+    static NeverDestroyed<HashMap<String, CallHandler>> methods = HashMap<String, CallHandler>({
+        { "SetupInspectorClient"_s, static_cast<CallHandler>(&RemoteInspector::setupInspectorClient) },
+        { "Setup"_s, static_cast<CallHandler>(&RemoteInspector::setupTarget) },
+        { "FrontendDidClose"_s, static_cast<CallHandler>(&RemoteInspector::frontendDidClose) },
+        { "SendMessageToBackend"_s, static_cast<CallHandler>(&RemoteInspector::sendMessageToBackend) },
+    });
+
+    return methods;
+}
+
+void RemoteInspector::setupInspectorClient(const Event&)
+{
     ASSERT(isMainThread());
 
-    if (event.targetID)
-        setup(event.targetID.value());
+    auto backendCommandsEvent = JSON::Object::create();
+    backendCommandsEvent->setString("event"_s, "BackendCommands"_s);
+    backendCommandsEvent->setString("message"_s, backendCommands());
+    sendWebInspectorEvent(backendCommandsEvent->toJSONString());
+
+    m_readyToPushListings = true;
+
+    LockHolder lock(m_mutex);
+    pushListingsNow();
 }
 
-void RemoteInspector::receivedDataMessage(const Event& event)
+void RemoteInspector::setupTarget(const Event& event)
 {
     ASSERT(isMainThread());
 
-    if (!event.targetID || !event.message)
+    if (!event.targetID || !event.connectionID)
         return;
 
-    RefPtr<RemoteConnectionToTarget> connectionToTarget;
-    {
-        LockHolder lock(m_mutex);
-        connectionToTarget = m_targetConnectionMap.get(event.targetID.value());
-        if (!connectionToTarget)
-            return;
-    }
-
-    connectionToTarget->sendMessageToTarget(event.message.value());
+    setup(event.targetID.value());
 }
 
-void RemoteInspector::receivedCloseMessage(const Event& event)
+void RemoteInspector::frontendDidClose(const Event& event)
 {
     ASSERT(isMainThread());
 
@@ -259,45 +301,24 @@
         connectionToTarget->close();
 }
 
-void RemoteInspector::setup(TargetID targetIdentifier)
+void RemoteInspector::sendMessageToBackend(const Event& event)
 {
-    RemoteControllableTarget* target;
+    ASSERT(isMainThread());
+
+    if (!event.connectionID || !event.targetID || !event.message)
+        return;
+
+    RefPtr<RemoteConnectionToTarget> connectionToTarget;
     {
         LockHolder lock(m_mutex);
-        target = m_targetMap.get(targetIdentifier);
-        if (!target)
+        connectionToTarget = m_targetConnectionMap.get(event.targetID.value());
+        if (!connectionToTarget)
             return;
     }
 
-    auto connectionToTarget = adoptRef(*new RemoteConnectionToTarget(*target));
-    ASSERT(is<RemoteInspectionTarget>(target) || is<RemoteAutomationTarget>(target));
-    if (!connectionToTarget->setup()) {
-        connectionToTarget->close();
-        return;
-    }
-
-    LockHolder lock(m_mutex);
-    m_targetConnectionMap.set(targetIdentifier, WTFMove(connectionToTarget));
-
-    updateHasActiveDebugSession();
+    connectionToTarget->sendMessageToTarget(event.message.value());
 }
 
-void RemoteInspector::sendMessageToTarget(TargetID targetIdentifier, const char* message)
-{
-    if (auto connectionToTarget = m_targetConnectionMap.get(targetIdentifier))
-        connectionToTarget->sendMessageToTarget(String::fromUTF8(message));
-}
-
-void RemoteInspector::setConnectionIdentifier(PlatformSocketType connectionIdentifier)
-{
-    RemoteInspector::s_connectionIdentifier = connectionIdentifier;
-}
-
-void RemoteInspector::setServerPort(uint16_t port)
-{
-    RemoteInspector::s_serverPort = port;
-}
-
 } // namespace Inspector
 
 #endif // ENABLE(REMOTE_INSPECTOR)

Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp (250987 => 250988)


--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp	2019-10-10 21:20:12 UTC (rev 250988)
@@ -30,6 +30,7 @@
 
 #include <wtf/CryptographicallyRandomNumber.h>
 #include <wtf/MainThread.h>
+#include <wtf/RunLoop.h>
 #include <wtf/text/WTFString.h>
 
 namespace Inspector {
@@ -64,6 +65,8 @@
     Socket::close(m_wakeupReceiveSocket);
     for (const auto& connection : m_connections.values())
         Socket::close(connection->socket);
+    for (const auto& connection : m_listeners.values())
+        Socket::close(connection->socket);
 }
 
 void RemoteInspectorSocketEndpoint::wakeupWorkerThread()
@@ -79,10 +82,10 @@
     return WTF::nullopt;
 }
 
-Optional<ConnectionID> RemoteInspectorSocketEndpoint::listenInet(const char* address, uint16_t port, Client& client)
+Optional<ConnectionID> RemoteInspectorSocketEndpoint::listenInet(const char* address, uint16_t port, Listener& listener, Client& client)
 {
     if (auto socket = Socket::listen(address, port))
-        return createClient(*socket, client);
+        return createListener(*socket, listener, client);
 
     return WTF::nullopt;
 }
@@ -90,8 +93,8 @@
 bool RemoteInspectorSocketEndpoint::isListening(ConnectionID id)
 {
     LockHolder lock(m_connectionsLock);
-    if (const auto& connection = m_connections.get(id))
-        return Socket::isListening(connection->socket);
+    if (m_listeners.contains(id))
+        return true;
     return false;
 }
 
@@ -100,6 +103,10 @@
     PollingDescriptor wakeup = Socket::preparePolling(m_wakeupReceiveSocket);
 
     while (!m_shouldAbortWorkerThread) {
+#if USE(GENERIC_EVENT_LOOP) || USE(WINDOWS_EVENT_LOOP)
+        RunLoop::iterate();
+#endif
+
         Vector<PollingDescriptor> pollfds;
         Vector<ConnectionID> ids;
         {
@@ -108,6 +115,10 @@
                 pollfds.append(connection.value->poll);
                 ids.append(connection.key);
             }
+            for (const auto& connection : m_listeners) {
+                pollfds.append(connection.value->poll);
+                ids.append(connection.key);
+            }
         }
         pollfds.append(wakeup);
 
@@ -123,35 +134,52 @@
         for (size_t i = 0; i < ids.size(); i++) {
             auto id = ids[i];
 
-            if (Socket::isReadable(pollfds[i]) && isListening(id))
-                acceptInetSocketIfEnabled(id);
-            else if (Socket::isReadable(pollfds[i]))
-                recvIfEnabled(id);
-            else if (Socket::isWritable(pollfds[i]))
+            if (Socket::isReadable(pollfds[i])) {
+                if (isListening(id))
+                    acceptInetSocketIfEnabled(id);
+                else
+                    recvIfEnabled(id);
+            } else if (Socket::isWritable(pollfds[i]))
                 sendIfEnabled(id);
         }
     }
 }
 
-Optional<ConnectionID> RemoteInspectorSocketEndpoint::createClient(PlatformSocketType socket, Client& client)
+ConnectionID RemoteInspectorSocketEndpoint::generateConnectionID()
 {
-    if (!Socket::isValid(socket))
-        return WTF::nullopt;
+    ASSERT(m_connectionsLock.isLocked());
 
-    LockHolder lock(m_connectionsLock);
-
     ConnectionID id;
     do {
         id = cryptographicallyRandomNumber();
-    } while (!id || m_connections.contains(id));
+    } while (!id || m_connections.contains(id) || m_listeners.contains(id));
 
+    return id;
+}
+
+std::unique_ptr<RemoteInspectorSocketEndpoint::Connection> RemoteInspectorSocketEndpoint::makeConnection(PlatformSocketType socket, Client& client)
+{
+    ASSERT(m_connectionsLock.isLocked());
+
     Socket::setup(socket);
 
     auto connection = makeUnique<Connection>(client);
 
-    connection->id = id;
+    connection->id = generateConnectionID();
     connection->poll = Socket::preparePolling(socket);
     connection->socket = socket;
+
+    return connection;
+}
+
+Optional<ConnectionID> RemoteInspectorSocketEndpoint::createClient(PlatformSocketType socket, Client& client)
+{
+    if (!Socket::isValid(socket))
+        return WTF::nullopt;
+
+    LockHolder lock(m_connectionsLock);
+    auto connection = makeConnection(socket, client);
+    auto id = connection->id;
     m_connections.add(id, WTFMove(connection));
     wakeupWorkerThread();
 
@@ -158,6 +186,24 @@
     return id;
 }
 
+Optional<ConnectionID> RemoteInspectorSocketEndpoint::createListener(PlatformSocketType socket, Listener& listener, Client& client)
+{
+    if (!Socket::isValid(socket))
+        return WTF::nullopt;
+
+    LockHolder lock(m_connectionsLock);
+
+    Socket::setup(socket);
+
+    auto connection = makeConnection(socket, client);
+    auto id = connection->id;
+    connection->listener = &listener;
+    m_listeners.add(id, WTFMove(connection));
+    wakeupWorkerThread();
+
+    return id;
+}
+
 void RemoteInspectorSocketEndpoint::invalidateClient(Client& client)
 {
     LockHolder lock(m_connectionsLock);
@@ -173,9 +219,26 @@
     });
 }
 
+void RemoteInspectorSocketEndpoint::invalidateListener(Listener& listener)
+{
+    LockHolder lock(m_connectionsLock);
+    m_listeners.removeIf([&listener](auto& keyValue) {
+        const auto& connection = keyValue.value;
+
+        if (connection->listener == &listener) {
+            Socket::close(connection->socket);
+            return true;
+        }
+
+        return false;
+    });
+}
+
 Optional<uint16_t> RemoteInspectorSocketEndpoint::getPort(ConnectionID id) const
 {
     LockHolder lock(m_connectionsLock);
+    if (const auto& connection = m_listeners.get(id))
+        return Socket::getPort(connection->socket);
     if (const auto& connection = m_connections.get(id))
         return Socket::getPort(connection->socket);
 
@@ -254,17 +317,18 @@
 
 void RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled(ConnectionID id)
 {
-    if (!isListening(id))
-        return;
+    ASSERT(isListening(id));
 
     LockHolder lock(m_connectionsLock);
-    if (const auto& connection = m_connections.get(id)) {
+    if (const auto& connection = m_listeners.get(id)) {
         if (auto socket = Socket::accept(connection->socket)) {
             // Need to unlock before calling createClient as it also attempts to lock.
             lock.unlockEarly();
             if (auto newID = createClient(*socket, connection->client)) {
-                connection->client.didAccept(newID.value(), id, Socket::Domain::Network);
-                return;
+                if (connection->listener->didAccept(newID.value(), connection->id, Socket::Domain::Network))
+                    return;
+
+                m_connections.remove(id);
             }
 
             Socket::close(*socket);

Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.h (250987 => 250988)


--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.h	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.h	2019-10-10 21:20:12 UTC (rev 250988)
@@ -44,10 +44,15 @@
     class Client {
     public:
         virtual void didReceive(ConnectionID, Vector<uint8_t>&&) = 0;
-        virtual void didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain) = 0;
         virtual void didClose(ConnectionID) = 0;
     };
 
+    class Listener {
+    public:
+        virtual bool didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain) = 0;
+        virtual void didClose(ConnectionID) = 0;
+    };
+
     static RemoteInspectorSocketEndpoint& singleton();
 
     RemoteInspectorSocketEndpoint();
@@ -54,12 +59,14 @@
     ~RemoteInspectorSocketEndpoint();
 
     Optional<ConnectionID> connectInet(const char* serverAddr, uint16_t serverPort, Client&);
-    Optional<ConnectionID> listenInet(const char* address, uint16_t port, Client&);
+    Optional<ConnectionID> listenInet(const char* address, uint16_t port, Listener&, Client&);
     void invalidateClient(Client&);
+    void invalidateListener(Listener&);
 
     void send(ConnectionID, const uint8_t* data, size_t);
 
     Optional<ConnectionID> createClient(PlatformSocketType, Client&);
+    Optional<ConnectionID> createListener(PlatformSocketType, Listener&, Client&);
 
     Optional<uint16_t> getPort(ConnectionID) const;
 
@@ -76,8 +83,12 @@
         PlatformSocketType socket { INVALID_SOCKET_VALUE };
         PollingDescriptor poll;
         Client& client;
+        Listener* listener { };
     };
 
+    ConnectionID generateConnectionID();
+    std::unique_ptr<Connection> makeConnection(PlatformSocketType, Client&);
+
     void recvIfEnabled(ConnectionID);
     void sendIfEnabled(ConnectionID);
     void workerThread();
@@ -87,6 +98,7 @@
 
     mutable Lock m_connectionsLock;
     HashMap<ConnectionID, std::unique_ptr<Connection>> m_connections;
+    HashMap<ConnectionID, std::unique_ptr<Connection>> m_listeners;
 
     PlatformSocketType m_wakeupSendSocket { INVALID_SOCKET_VALUE };
     PlatformSocketType m_wakeupReceiveSocket { INVALID_SOCKET_VALUE };

Modified: trunk/Source/WebKit/ChangeLog (250987 => 250988)


--- trunk/Source/WebKit/ChangeLog	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/WebKit/ChangeLog	2019-10-10 21:20:12 UTC (rev 250988)
@@ -1,3 +1,16 @@
+2019-10-10  Basuke Suzuki  <basuke.suz...@sony.com>
+
+        [WinCairo] Move remote communication handling from RemoteInspectorServer to RemoteInspector.
+        https://bugs.webkit.org/show_bug.cgi?id=202763
+
+        Reviewed by Ross Kirsling.
+
+        Remove deleted method invocations.
+
+        * UIProcess/win/WebProcessPoolWin.cpp:
+        (WebKit::initializeRemoteInspectorServer):
+        (WebKit::WebProcessPool::platformInitialize):
+
 2019-10-10  Youenn Fablet  <you...@apple.com>
 
         Do not timeout a load intercepted by service worker that receives a response

Modified: trunk/Source/WebKit/UIProcess/win/WebProcessPoolWin.cpp (250987 => 250988)


--- trunk/Source/WebKit/UIProcess/win/WebProcessPoolWin.cpp	2019-10-10 20:30:21 UTC (rev 250987)
+++ trunk/Source/WebKit/UIProcess/win/WebProcessPoolWin.cpp	2019-10-10 21:20:12 UTC (rev 250988)
@@ -65,7 +65,7 @@
     if (!port)
         return;
 
-    Inspector::RemoteInspectorServer::singleton().setBackendCommandsPath(backendCommandsPath());
+    Inspector::RemoteInspector::singleton().setBackendCommandsPath(backendCommandsPath());
     Inspector::RemoteInspectorServer::singleton().start(host.utf8().data(), port.value());
 }
 #endif
@@ -73,11 +73,8 @@
 void WebProcessPool::platformInitialize()
 {
 #if ENABLE(REMOTE_INSPECTOR)
-    if (const char* address = getenv("WEBKIT_INSPECTOR_SERVER")) {
+    if (const char* address = getenv("WEBKIT_INSPECTOR_SERVER"))
         initializeRemoteInspectorServer(address);
-        auto port = Inspector::RemoteInspectorServer::singleton().listenForTargets();
-        Inspector::RemoteInspector::setServerPort(port.valueOr(0));
-    }
 #endif
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to