Changeset 252770 in webkit


Ignore:
Timestamp:
Nov 22, 2019 6:22:34 AM (4 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK][WPE] RemoteInspector: use sockets instead of DBus
https://bugs.webkit.org/show_bug.cgi?id=204503

Reviewed by Žan Doberšek.

Source/JavaScriptCore:

It turns out DBus is event slower than expected. Using GSockets API we can simplify the code and make it a lot
more efficient. This will drastically reduce the time to run WebDriver tests in the bots.

  • inspector/remote/RemoteInspector.h:
  • inspector/remote/glib/RemoteInspectorGlib.cpp:

(Inspector::RemoteInspector::start):
(Inspector::RemoteInspector::stopInternal):
(Inspector::RemoteInspector::setupConnection):
(Inspector::RemoteInspector::pushListingsNow):
(Inspector::RemoteInspector::pushListingsSoon):
(Inspector::RemoteInspector::sendAutomaticInspectionCandidateMessage):
(Inspector::RemoteInspector::sendMessageToRemote):

  • inspector/remote/glib/RemoteInspectorServer.cpp:

(Inspector::RemoteInspectorServer::~RemoteInspectorServer):
(Inspector::RemoteInspectorServer::start):
(Inspector::RemoteInspectorServer::incomingConnectionCallback):
(Inspector::RemoteInspectorServer::incomingConnection):
(Inspector::RemoteInspectorServer::setTargetList):
(Inspector::RemoteInspectorServer::setupInspectorClient):
(Inspector::RemoteInspectorServer::setup):
(Inspector::RemoteInspectorServer::close):
(Inspector::RemoteInspectorServer::connectionDidClose):
(Inspector::RemoteInspectorServer::sendMessageToBackend):
(Inspector::RemoteInspectorServer::sendMessageToFrontend):
(Inspector::RemoteInspectorServer::startAutomationSession):

  • inspector/remote/glib/RemoteInspectorServer.h:

(Inspector::RemoteInspectorServer::isRunning const):

Source/WebDriver:

Use GSockets API instead of DBus.

  • SessionHost.cpp:

(WebDriver::SessionHost::sendCommandToBackend):

  • SessionHost.h:
  • glib/SessionHostGlib.cpp:

(WebDriver::SessionHost::~SessionHost):
(WebDriver::SessionHost::isConnected const):
(WebDriver::ConnectToBrowserAsyncData::ConnectToBrowserAsyncData):
(WebDriver::SessionHost::launchBrowser):
(WebDriver::SessionHost::connectToBrowser):
(WebDriver::SessionHost::connectionDidClose):
(WebDriver::SessionHost::setupConnection):
(WebDriver::SessionHost::startAutomationSession):
(WebDriver::SessionHost::didStartAutomationSession):
(WebDriver::SessionHost::setTargetList):
(WebDriver::SessionHost::sendMessageToBackend):

  • socket/SessionHostSocket.cpp:

(WebDriver::SessionHost::sendMessageToBackend):

Source/WebKit:

Use GSockets API instead of DBus.

  • Platform/IPC/Connection.h:
  • SourcesGTK.txt: Remove GSocketMonitor that has been moved to WTF.
  • SourcesWPE.txt: Ditto.
  • UIProcess/glib/RemoteInspectorClient.cpp:

(WebKit::RemoteInspectorClient::RemoteInspectorClient):
(WebKit::RemoteInspectorClient::~RemoteInspectorClient):
(WebKit::RemoteInspectorClient::setupConnection):
(WebKit::RemoteInspectorClient::connectionDidClose):
(WebKit::RemoteInspectorClient::inspect):
(WebKit::RemoteInspectorClient::sendMessageToBackend):
(WebKit::RemoteInspectorClient::closeFromFrontend):

  • UIProcess/glib/RemoteInspectorClient.h:

Source/WTF:

Add SocketConnection class.

  • wtf/PlatformGTK.cmake:
  • wtf/PlatformWPE.cmake:
  • wtf/glib/GSocketMonitor.cpp: Renamed from Source/WebKit/Platform/IPC/glib/GSocketMonitor.cpp.

(WTF::GSocketMonitor::start):

  • wtf/glib/GSocketMonitor.h: Renamed from Source/WebKit/Platform/IPC/glib/GSocketMonitor.h.

(WTF::GSocketMonitor::isActive const):

  • wtf/glib/GTypedefs.h:
  • wtf/glib/GUniquePtr.h:
  • wtf/glib/SocketConnection.cpp: Added.

(WTF::SocketConnection::SocketConnection):
(WTF::SocketConnection::~SocketConnection):
(WTF::SocketConnection::read):
(WTF::SocketConnection::readMessage):
(WTF::SocketConnection::sendMessage):
(WTF::SocketConnection::write):
(WTF::SocketConnection::waitForSocketWritability):
(WTF::SocketConnection::close):
(WTF::SocketConnection::didClose):

  • wtf/glib/SocketConnection.h: Added.

(WTF::SocketConnection::create):
(WTF::SocketConnection::isClosed const):

Tools:

Update the unit tests to not use DBus.

  • TestWebKitAPI/Tests/WebKitGLib/TestAutomationSession.cpp:
Location:
trunk
Files:
2 added
1 deleted
23 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r252767 r252770  
     12019-11-22  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][WPE] RemoteInspector: use sockets instead of DBus
     4        https://bugs.webkit.org/show_bug.cgi?id=204503
     5
     6        Reviewed by Žan Doberšek.
     7
     8        It turns out DBus is event slower than expected. Using GSockets API we can simplify the code and make it a lot
     9        more efficient. This will drastically reduce the time to run WebDriver tests in the bots.
     10
     11        * inspector/remote/RemoteInspector.h:
     12        * inspector/remote/glib/RemoteInspectorGlib.cpp:
     13        (Inspector::RemoteInspector::start):
     14        (Inspector::RemoteInspector::stopInternal):
     15        (Inspector::RemoteInspector::setupConnection):
     16        (Inspector::RemoteInspector::pushListingsNow):
     17        (Inspector::RemoteInspector::pushListingsSoon):
     18        (Inspector::RemoteInspector::sendAutomaticInspectionCandidateMessage):
     19        (Inspector::RemoteInspector::sendMessageToRemote):
     20        * inspector/remote/glib/RemoteInspectorServer.cpp:
     21        (Inspector::RemoteInspectorServer::~RemoteInspectorServer):
     22        (Inspector::RemoteInspectorServer::start):
     23        (Inspector::RemoteInspectorServer::incomingConnectionCallback):
     24        (Inspector::RemoteInspectorServer::incomingConnection):
     25        (Inspector::RemoteInspectorServer::setTargetList):
     26        (Inspector::RemoteInspectorServer::setupInspectorClient):
     27        (Inspector::RemoteInspectorServer::setup):
     28        (Inspector::RemoteInspectorServer::close):
     29        (Inspector::RemoteInspectorServer::connectionDidClose):
     30        (Inspector::RemoteInspectorServer::sendMessageToBackend):
     31        (Inspector::RemoteInspectorServer::sendMessageToFrontend):
     32        (Inspector::RemoteInspectorServer::startAutomationSession):
     33        * inspector/remote/glib/RemoteInspectorServer.h:
     34        (Inspector::RemoteInspectorServer::isRunning const):
     35
    1362019-11-22  Mark Lam  <mark.lam@apple.com>
    237
  • trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.h

    r252323 r252770  
    4848#if USE(GLIB)
    4949#include <wtf/glib/GRefPtr.h>
     50#include <wtf/glib/SocketConnection.h>
    5051typedef GRefPtr<GVariant> TargetListing;
    5152typedef struct _GCancellable GCancellable;
    52 typedef struct _GDBusConnection GDBusConnection;
    53 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;
    5453#endif
    5554
     
    179178#endif
    180179#if USE(GLIB)
    181     void setupConnection(GRefPtr<GDBusConnection>&&);
    182     static const GDBusInterfaceVTable s_interfaceVTable;
     180    void setupConnection(Ref<SocketConnection>&&);
     181    static const SocketConnection::MessageHandlers s_messageHandlers;
    183182
    184183    void receivedGetTargetListMessage();
     
    253252#endif
    254253#if USE(GLIB)
    255     GRefPtr<GDBusConnection> m_dbusConnection;
     254    RefPtr<SocketConnection> m_socketConnection;
    256255    GRefPtr<GCancellable> m_cancellable;
    257256#endif
  • trunk/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorGlib.cpp

    r251227 r252770  
    3737#include <wtf/glib/GUniquePtr.h>
    3838
    39 #define REMOTE_INSPECTOR_DBUS_INTERFACE "org.webkit.RemoteInspector"
    40 #define REMOTE_INSPECTOR_DBUS_OBJECT_PATH "/org/webkit/RemoteInspector"
    41 #define INSPECTOR_DBUS_INTERFACE "org.webkit.Inspector"
    42 #define INSPECTOR_DBUS_OBJECT_PATH "/org/webkit/Inspector"
    43 
    4439namespace Inspector {
    4540
     
    6661    m_cancellable = adoptGRef(g_cancellable_new());
    6762
    68     GUniquePtr<char> inspectorAddress(g_strdup(g_getenv("WEBKIT_INSPECTOR_SERVER")));
    69     char* portPtr = g_strrstr(inspectorAddress.get(), ":");
    70     ASSERT(portPtr);
    71     *portPtr = '\0';
    72     portPtr++;
    73     unsigned port = g_ascii_strtoull(portPtr, nullptr, 10);
    74     GUniquePtr<char> dbusAddress(g_strdup_printf("tcp:host=%s,port=%u", inspectorAddress.get(), port));
    75     g_dbus_connection_new_for_address(dbusAddress.get(), G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, nullptr, m_cancellable.get(),
    76         [](GObject*, GAsyncResult* result, gpointer userData) {
     63    GRefPtr<GSocketClient> socketClient = adoptGRef(g_socket_client_new());
     64    g_socket_client_connect_to_host_async(socketClient.get(), g_getenv("WEBKIT_INSPECTOR_SERVER"), 0, m_cancellable.get(),
     65        [](GObject* client, GAsyncResult* result, gpointer userData) {
    7766            RemoteInspector* inspector = static_cast<RemoteInspector*>(userData);
    7867            GUniqueOutPtr<GError> error;
    79             if (GRefPtr<GDBusConnection> connection = adoptGRef(g_dbus_connection_new_for_address_finish(result, &error.outPtr())))
    80                 inspector->setupConnection(WTFMove(connection));
     68            if (GRefPtr<GSocketConnection> connection = adoptGRef(g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(client), result, &error.outPtr())))
     69                inspector->setupConnection(SocketConnection::create(WTFMove(connection), s_messageHandlers, inspector));
    8170            else if (!g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    8271                g_warning("RemoteInspector failed to connect to inspector server at: %s: %s", g_getenv("WEBKIT_INSPECTOR_SERVER"), error->message);
    83     }, this);
     72        }, this);
    8473}
    8574
     
    10190
    10291    m_automaticInspectionPaused = false;
    103     m_dbusConnection = nullptr;
    104 }
    105 
    106 static const char introspectionXML[] =
    107     "<node>"
    108     "  <interface name='" REMOTE_INSPECTOR_DBUS_INTERFACE "'>"
    109     "    <method name='GetTargetList'>"
    110     "    </method>"
    111     "    <method name='Setup'>"
    112     "      <arg type='t' name='target' direction='in'/>"
    113     "    </method>"
    114     "    <method name='SendMessageToTarget'>"
    115     "      <arg type='t' name='target' direction='in'/>"
    116     "      <arg type='s' name='message' direction='in'/>"
    117     "    </method>"
    118     "    <method name='FrontendDidClose'>"
    119     "      <arg type='t' name='target' direction='in'/>"
    120     "    </method>"
    121     "  </interface>"
    122     "</node>";
    123 
    124 const GDBusInterfaceVTable RemoteInspector::s_interfaceVTable = {
    125     // method_call
    126     [] (GDBusConnection*, const gchar* /*sender*/, const gchar* /*objectPath*/, const gchar* /*interfaceName*/, const gchar* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) {
    127         auto* inspector = static_cast<RemoteInspector*>(userData);
    128         if (!g_strcmp0(methodName, "GetTargetList")) {
    129             inspector->receivedGetTargetListMessage();
    130             g_dbus_method_invocation_return_value(invocation, nullptr);
    131         } else if (!g_strcmp0(methodName, "Setup")) {
     92    m_socketConnection = nullptr;
     93}
     94
     95const SocketConnection::MessageHandlers RemoteInspector::s_messageHandlers = {
     96    { "DidClose", std::pair<CString, SocketConnection::MessageCallback> { { },
     97        [](SocketConnection&, GVariant*, gpointer userData) {
     98            auto& inspector = *static_cast<RemoteInspector*>(userData);
     99            inspector.stop();
     100        }}
     101    },
     102    { "GetTargetList", std::pair<CString, SocketConnection::MessageCallback> { { },
     103        [](SocketConnection&, GVariant*, gpointer userData) {
     104            auto& inspector = *static_cast<RemoteInspector*>(userData);
     105            inspector.receivedGetTargetListMessage();
     106        }}
     107    },
     108    { "Setup", std::pair<CString, SocketConnection::MessageCallback> { "(t)",
     109        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     110            auto& inspector = *static_cast<RemoteInspector*>(userData);
    132111            guint64 targetID;
    133112            g_variant_get(parameters, "(t)", &targetID);
    134             inspector->receivedSetupMessage(targetID);
    135             g_dbus_method_invocation_return_value(invocation, nullptr);
    136         } else if (!g_strcmp0(methodName, "SendMessageToTarget")) {
     113            inspector.receivedSetupMessage(targetID);
     114        }}
     115    },
     116    { "SendMessageToTarget", std::pair<CString, SocketConnection::MessageCallback> { "(ts)",
     117        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     118            auto& inspector = *static_cast<RemoteInspector*>(userData);
    137119            guint64 targetID;
    138120            const char* message;
    139121            g_variant_get(parameters, "(t&s)", &targetID, &message);
    140             inspector->receivedDataMessage(targetID, message);
    141             g_dbus_method_invocation_return_value(invocation, nullptr);
    142         } else if (!g_strcmp0(methodName, "FrontendDidClose")) {
     122            inspector.receivedDataMessage(targetID, message);
     123        }}
     124    },
     125    { "FrontendDidClose", std::pair<CString, SocketConnection::MessageCallback> { "(t)",
     126        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     127            auto& inspector = *static_cast<RemoteInspector*>(userData);
    143128            guint64 targetID;
    144129            g_variant_get(parameters, "(t)", &targetID);
    145             inspector->receivedCloseMessage(targetID);
    146             g_dbus_method_invocation_return_value(invocation, nullptr);
    147         }
    148     },
    149     // get_property
    150     nullptr,
    151     // set_property
    152     nullptr,
    153     // padding
    154     { 0 }
     130            inspector.receivedCloseMessage(targetID);
     131        }}
     132    }
    155133};
    156134
    157 void RemoteInspector::setupConnection(GRefPtr<GDBusConnection>&& connection)
     135void RemoteInspector::setupConnection(Ref<SocketConnection>&& connection)
    158136{
    159137    LockHolder lock(m_mutex);
    160138
    161139    ASSERT(connection);
    162     ASSERT(!m_dbusConnection);
    163     m_dbusConnection = WTFMove(connection);
    164 
    165     static GDBusNodeInfo* introspectionData = nullptr;
    166     if (!introspectionData)
    167         introspectionData = g_dbus_node_info_new_for_xml(introspectionXML, nullptr);
    168 
    169     g_dbus_connection_register_object(m_dbusConnection.get(), REMOTE_INSPECTOR_DBUS_OBJECT_PATH,
    170         introspectionData->interfaces[0], &s_interfaceVTable, this, nullptr, nullptr);
    171 
     140    ASSERT(!m_socketConnection);
     141
     142    m_socketConnection = WTFMove(connection);
    172143    if (!m_targetMap.isEmpty())
    173144        pushListingsSoon();
    174 }
    175 
    176 static void dbusConnectionCallAsyncReadyCallback(GObject* source, GAsyncResult* result, gpointer)
    177 {
    178     GUniqueOutPtr<GError> error;
    179     GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error.outPtr()));
    180     if (!resultVariant && !g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    181         g_warning("RemoteInspector failed to send DBus message: %s", error->message);
    182145}
    183146
     
    206169void RemoteInspector::pushListingsNow()
    207170{
    208     if (!m_dbusConnection)
     171    if (!m_socketConnection)
    209172        return;
    210173
     
    218181    g_variant_builder_close(&builder);
    219182    g_variant_builder_add(&builder, "b", m_clientCapabilities && m_clientCapabilities->remoteAutomationAllowed);
    220     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    221         INSPECTOR_DBUS_OBJECT_PATH, INSPECTOR_DBUS_INTERFACE, "SetTargetList",
    222         g_variant_builder_end(&builder), nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    223         -1, m_cancellable.get(), dbusConnectionCallAsyncReadyCallback, nullptr);
     183    m_socketConnection->sendMessage("SetTargetList", g_variant_builder_end(&builder));
    224184}
    225185
    226186void RemoteInspector::pushListingsSoon()
    227187{
    228     if (!m_dbusConnection)
     188    if (!m_socketConnection)
    229189        return;
    230190
     
    247207    ASSERT(m_automaticInspectionPaused);
    248208    ASSERT(m_automaticInspectionCandidateTargetIdentifier);
    249     ASSERT(m_dbusConnection);
     209    ASSERT(m_socketConnection);
    250210    // FIXME: Implement automatic inspection.
    251211}
     
    254214{
    255215    LockHolder lock(m_mutex);
    256     if (!m_dbusConnection)
    257         return;
    258 
    259     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    260         INSPECTOR_DBUS_OBJECT_PATH, INSPECTOR_DBUS_INTERFACE, "SendMessageToFrontend",
    261         g_variant_new("(ts)", static_cast<guint64>(targetIdentifier), message.utf8().data()),
    262         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    263         -1, m_cancellable.get(), dbusConnectionCallAsyncReadyCallback, nullptr);
     216    if (!m_socketConnection)
     217        return;
     218
     219    m_socketConnection->sendMessage("SendMessageToFrontend", g_variant_new("(ts)", static_cast<guint64>(targetIdentifier), message.utf8().data()));
    264220}
    265221
  • trunk/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorServer.cpp

    r252323 r252770  
    3434#include <wtf/glib/GUniquePtr.h>
    3535
    36 #define INSPECTOR_DBUS_INTERFACE "org.webkit.Inspector"
    37 #define INSPECTOR_DBUS_OBJECT_PATH "/org/webkit/Inspector"
    38 #define REMOTE_INSPECTOR_DBUS_INTERFACE "org.webkit.RemoteInspector"
    39 #define REMOTE_INSPECTOR_DBUS_OBJECT_PATH "/org/webkit/RemoteInspector"
    40 #define REMOTE_INSPECTOR_CLIENT_DBUS_INTERFACE "org.webkit.RemoteInspectorClient"
    41 #define REMOTE_INSPECTOR_CLIENT_OBJECT_PATH "/org/webkit/RemoteInspectorClient"
    42 
    4336namespace Inspector {
    4437
     
    4740    static uint64_t connectionID = 0;
    4841    return ++connectionID;
    49 }
    50 
    51 namespace RemoteInspectorServerInternal {
    52 static const char introspectionXML[] =
    53     "<node>"
    54     "  <interface name='" INSPECTOR_DBUS_INTERFACE "'>"
    55     "    <method name='SetTargetList'>"
    56     "      <arg type='a(tsssb)' name='list' direction='in'/>"
    57     "      <arg type='b' name='remoteAutomationEnabled' direction='in'/>"
    58     "    </method>"
    59     "    <method name='SetupInspectorClient'>"
    60     "      <arg type='ay' name='backendCommandsHash' direction='in'/>"
    61     "      <arg type='ay' name='backendCommands' direction='out'/>"
    62     "    </method>"
    63     "    <method name='Setup'>"
    64     "      <arg type='t' name='connection' direction='in'/>"
    65     "      <arg type='t' name='target' direction='in'/>"
    66     "    </method>"
    67     "    <method name='FrontendDidClose'>"
    68     "      <arg type='t' name='connection' direction='in'/>"
    69     "      <arg type='t' name='target' direction='in'/>"
    70     "    </method>"
    71     "    <method name='SendMessageToFrontend'>"
    72     "      <arg type='t' name='target' direction='in'/>"
    73     "      <arg type='s' name='message' direction='in'/>"
    74     "    </method>"
    75     "    <method name='SendMessageToBackend'>"
    76     "      <arg type='t' name='connection' direction='in'/>"
    77     "      <arg type='t' name='target' direction='in'/>"
    78     "      <arg type='s' name='message' direction='in'/>"
    79     "    </method>"
    80     "    <method name='StartAutomationSession'>"
    81     "      <arg type='s' name='sessionID' direction='in'/>"
    82     "      <arg type='a{sv}' name='capabilities' direction='in'/>"
    83     "      <arg type='s' name='browserName' direction='out'/>"
    84     "      <arg type='s' name='browserVersion' direction='out'/>"
    85     "    </method>"
    86     "  </interface>"
    87     "</node>";
    8842}
    8943
     
    13993    return capabilities;
    14094}
    141 const GDBusInterfaceVTable RemoteInspectorServer::s_interfaceVTable = {
    142     // method_call
    143     [] (GDBusConnection* connection, const gchar* /*sender*/, const gchar* /*objectPath*/, const gchar* /*interfaceName*/, const gchar* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) {
    144         auto* inspectorServer = static_cast<RemoteInspectorServer*>(userData);
    145         if (!g_strcmp0(methodName, "SetTargetList")) {
    146             inspectorServer->setTargetList(connection, parameters);
    147             g_dbus_method_invocation_return_value(invocation, nullptr);
    148         } else if (!g_strcmp0(methodName, "SetupInspectorClient")) {
     95
     96const SocketConnection::MessageHandlers RemoteInspectorServer::s_messageHandlers = {
     97    { "DidClose", std::pair<CString, SocketConnection::MessageCallback> { { },
     98        [](SocketConnection& connection, GVariant*, gpointer userData) {
     99            auto& inspectorServer = *static_cast<RemoteInspectorServer*>(userData);
     100            inspectorServer.connectionDidClose(connection);
     101        }}
     102    },
     103    { "SetTargetList", std::pair<CString, SocketConnection::MessageCallback> { "(a(tsssb)b)",
     104        [](SocketConnection& connection, GVariant* parameters, gpointer userData) {
     105            auto& inspectorServer = *static_cast<RemoteInspectorServer*>(userData);
     106            inspectorServer.setTargetList(connection, parameters);
     107        }}
     108    },
     109    { "SetupInspectorClient", std::pair<CString, SocketConnection::MessageCallback> { "(ay)",
     110        [](SocketConnection& connection, GVariant* parameters, gpointer userData) {
     111            auto& inspectorServer = *static_cast<RemoteInspectorServer*>(userData);
    149112            GRefPtr<GVariant> backendCommandsHash;
    150113            g_variant_get(parameters, "(@ay)", &backendCommandsHash.outPtr());
    151             auto* backendCommands = inspectorServer->setupInspectorClient(connection, g_variant_get_bytestring(backendCommandsHash.get()));
    152             g_dbus_method_invocation_return_value(invocation, g_variant_new("(@ay)", backendCommands));
    153         } else if (!g_strcmp0(methodName, "Setup")) {
     114            auto* backendCommands = inspectorServer.setupInspectorClient(connection, g_variant_get_bytestring(backendCommandsHash.get()));
     115            connection.sendMessage("DidSetupInspectorClient", g_variant_new("(@ay)", backendCommands));
     116        }}
     117    },
     118    { "Setup", std::pair<CString, SocketConnection::MessageCallback> { "(tt)",
     119        [](SocketConnection& connection, GVariant* parameters, gpointer userData) {
     120            auto& inspectorServer = *static_cast<RemoteInspectorServer*>(userData);
    154121            guint64 connectionID, targetID;
    155122            g_variant_get(parameters, "(tt)", &connectionID, &targetID);
    156             inspectorServer->setup(connection, connectionID, targetID);
    157             g_dbus_method_invocation_return_value(invocation, nullptr);
    158         } else if (!g_strcmp0(methodName, "FrontendDidClose")) {
     123            inspectorServer.setup(connection, connectionID, targetID);
     124        }}
     125    },
     126    { "FrontendDidClose", std::pair<CString, SocketConnection::MessageCallback> { "(tt)",
     127        [](SocketConnection& connection, GVariant* parameters, gpointer userData) {
     128            auto& inspectorServer = *static_cast<RemoteInspectorServer*>(userData);
    159129            guint64 connectionID, targetID;
    160130            g_variant_get(parameters, "(tt)", &connectionID, &targetID);
    161             inspectorServer->close(connection, connectionID, targetID);
    162             g_dbus_method_invocation_return_value(invocation, nullptr);
    163         } else if (!g_strcmp0(methodName, "SendMessageToFrontend")) {
     131            inspectorServer.close(connection, connectionID, targetID);
     132        }}
     133    },
     134    { "SendMessageToFrontend", std::pair<CString, SocketConnection::MessageCallback> { "(ts)",
     135        [](SocketConnection& connection, GVariant* parameters, gpointer userData) {
     136            auto& inspectorServer = *static_cast<RemoteInspectorServer*>(userData);
    164137            guint64 targetID;
    165138            const char* message;
    166139            g_variant_get(parameters, "(t&s)", &targetID, &message);
    167             inspectorServer->sendMessageToFrontend(connection, targetID, message);
    168             g_dbus_method_invocation_return_value(invocation, nullptr);
    169         } else if (!g_strcmp0(methodName, "SendMessageToBackend")) {
     140            inspectorServer.sendMessageToFrontend(connection, targetID, message);
     141        }}
     142    },
     143    { "SendMessageToBackend", std::pair<CString, SocketConnection::MessageCallback> { "(tts)",
     144        [](SocketConnection& connection, GVariant* parameters, gpointer userData) {
     145            auto& inspectorServer = *static_cast<RemoteInspectorServer*>(userData);
    170146            guint64 connectionID, targetID;
    171147            const char* message;
    172148            g_variant_get(parameters, "(tt&s)", &connectionID, &targetID, &message);
    173             inspectorServer->sendMessageToBackend(connection, connectionID, targetID, message);
    174             g_dbus_method_invocation_return_value(invocation, nullptr);
    175         } else if (!g_strcmp0(methodName, "StartAutomationSession")) {
     149            inspectorServer.sendMessageToBackend(connection, connectionID, targetID, message);
     150        }}
     151    },
     152    { "StartAutomationSession", std::pair<CString, SocketConnection::MessageCallback> { "(sa{sv})",
     153        [](SocketConnection& connection, GVariant* parameters, gpointer userData) {
     154            auto& inspectorServer = *static_cast<RemoteInspectorServer*>(userData);
    176155            const char* sessionID;
    177156            GRefPtr<GVariant> sessionCapabilities;
    178157            g_variant_get(parameters, "(&s@a{sv})", &sessionID, &sessionCapabilities.outPtr());
    179158            auto capabilities = processSessionCapabilities(sessionCapabilities.get());
    180             inspectorServer->startAutomationSession(connection, sessionID, capabilities);
     159            inspectorServer.startAutomationSession(connection, sessionID, capabilities);
    181160            auto clientCapabilities = RemoteInspector::singleton().clientCapabilities();
    182             g_dbus_method_invocation_return_value(invocation, g_variant_new("(ss)",
     161            connection.sendMessage("DidStartAutomationSession", g_variant_new("(ss)",
    183162                clientCapabilities ? clientCapabilities->browserName.utf8().data() : "",
    184163                clientCapabilities ? clientCapabilities->browserVersion.utf8().data() : ""));
    185         } else
    186             g_dbus_method_invocation_return_value(invocation, nullptr);
    187     },
    188     // get_property
    189     nullptr,
    190     // set_property
    191     nullptr,
    192     // padding
    193     { 0 }
     164        }}
     165    }
    194166};
    195167
     
    202174RemoteInspectorServer::~RemoteInspectorServer()
    203175{
    204     g_cancellable_cancel(m_cancellable.get());
    205     if (m_dbusServer)
    206         g_dbus_server_stop(m_dbusServer.get());
    207     if (m_introspectionData)
    208         g_dbus_node_info_unref(m_introspectionData);
    209 }
    210 
    211 GDBusInterfaceInfo* RemoteInspectorServer::interfaceInfo()
    212 {
    213     if (!m_introspectionData) {
    214         m_introspectionData = g_dbus_node_info_new_for_xml(RemoteInspectorServerInternal::introspectionXML, nullptr);
    215         ASSERT(m_introspectionData);
    216     }
    217     return m_introspectionData->interfaces[0];
     176    if (m_service)
     177        g_signal_handlers_disconnect_matched(m_service.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
    218178}
    219179
    220180bool RemoteInspectorServer::start(const char* address, unsigned port)
    221181{
    222     GUniquePtr<char> dbusAddress(g_strdup_printf("tcp:host=%s,port=%u", address, port));
    223     GUniquePtr<char> uid(g_dbus_generate_guid());
    224 
    225     m_cancellable = adoptGRef(g_cancellable_new());
    226 
     182    m_service = adoptGRef(g_socket_service_new());
     183    g_signal_connect(m_service.get(), "incoming", G_CALLBACK(incomingConnectionCallback), this);
     184
     185    GRefPtr<GSocketAddress> socketAddress = adoptGRef(g_inet_socket_address_new_from_string(address, port));
    227186    GUniqueOutPtr<GError> error;
    228     m_dbusServer = adoptGRef(g_dbus_server_new_sync(dbusAddress.get(), G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS, uid.get(), nullptr, m_cancellable.get(), &error.outPtr()));
    229     if (!m_dbusServer) {
    230         if (!g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    231             g_warning("Failed to start remote inspector server on %s: %s\n", dbusAddress.get(), error->message);
     187    if (!g_socket_listener_add_address(G_SOCKET_LISTENER(m_service.get()), socketAddress.get(), G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, nullptr, nullptr, &error.outPtr())) {
     188        g_warning("Failed to start remote inspector server on %s:%u: %s\n", address, port, error->message);
    232189        return false;
    233190    }
    234191
    235     g_signal_connect(m_dbusServer.get(), "new-connection", G_CALLBACK(newConnectionCallback), this);
    236     g_dbus_server_start(m_dbusServer.get());
    237 
    238192    return true;
    239193}
    240194
    241 gboolean RemoteInspectorServer::newConnectionCallback(GDBusServer*, GDBusConnection* connection, RemoteInspectorServer* inspectorServer)
    242 {
    243     inspectorServer->newConnection(connection);
     195gboolean RemoteInspectorServer::incomingConnectionCallback(GSocketService*, GSocketConnection* connection, GObject*, RemoteInspectorServer* inspectorServer)
     196{
     197    inspectorServer->incomingConnection(SocketConnection::create(GRefPtr<GSocketConnection>(connection), s_messageHandlers, inspectorServer));
    244198    return TRUE;
    245199}
    246200
    247 void RemoteInspectorServer::connectionClosedCallback(GDBusConnection* connection, gboolean /*remotePeerVanished*/, GError*, RemoteInspectorServer* server)
    248 {
    249     server->connectionClosed(connection);
    250 }
    251 
    252 void RemoteInspectorServer::newConnection(GDBusConnection* connection)
    253 {
    254     ASSERT(!m_connections.contains(connection));
    255     m_connections.add(connection);
    256     g_signal_connect(connection, "closed", G_CALLBACK(connectionClosedCallback), this);
    257 
    258     g_dbus_connection_register_object(connection, INSPECTOR_DBUS_OBJECT_PATH, interfaceInfo(), &s_interfaceVTable, this, nullptr, nullptr);
    259 }
    260 
    261 namespace RemoteInspectorServerInternal {
    262 static void dbusConnectionCallAsyncReadyCallback(GObject* source, GAsyncResult* result, gpointer)
    263 {
    264     GUniqueOutPtr<GError> error;
    265     GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error.outPtr()));
    266     if (!resultVariant && !g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    267         WTFLogAlways("RemoteInspectorServer failed to send DBus message: %s", error->message);
    268 }
    269 }
    270 
    271 void RemoteInspectorServer::setTargetList(GDBusConnection* remoteInspectorConnection, GVariant* parameters)
    272 {
    273     ASSERT(m_connections.contains(remoteInspectorConnection));
    274     auto addResult = m_remoteInspectorConnectionToIDMap.add(remoteInspectorConnection, 0);
     201void RemoteInspectorServer::incomingConnection(Ref<SocketConnection>&& connection)
     202{
     203    ASSERT(!m_connections.contains(connection.ptr()));
     204    m_connections.add(WTFMove(connection));
     205}
     206
     207void RemoteInspectorServer::setTargetList(SocketConnection& remoteInspectorConnection, GVariant* parameters)
     208{
     209    ASSERT(m_connections.contains(&remoteInspectorConnection));
     210    auto addResult = m_remoteInspectorConnectionToIDMap.add(&remoteInspectorConnection, 0);
    275211    if (addResult.isNewEntry) {
    276212        addResult.iterator->value = generateConnectionID();
    277         m_idToRemoteInspectorConnectionMap.add(addResult.iterator->value, remoteInspectorConnection);
     213        m_idToRemoteInspectorConnectionMap.add(addResult.iterator->value, &remoteInspectorConnection);
    278214    }
    279215
     
    281217    GRefPtr<GVariant> targetList;
    282218    g_variant_get(parameters, "(@a(tsssb)b)", &targetList.outPtr(), &remoteAutomationEnabled);
    283     GDBusConnection* clientConnection = remoteAutomationEnabled && m_automationConnection ? m_automationConnection.get() : m_clientConnection.get();
     219    SocketConnection* clientConnection = remoteAutomationEnabled && m_automationConnection ? m_automationConnection : m_clientConnection;
    284220    if (!clientConnection)
    285221        return;
    286222
    287     g_dbus_connection_call(clientConnection, nullptr,
    288         REMOTE_INSPECTOR_CLIENT_OBJECT_PATH,
    289         REMOTE_INSPECTOR_CLIENT_DBUS_INTERFACE,
    290         "SetTargetList",
    291         g_variant_new("(t@a(tsssb))", m_remoteInspectorConnectionToIDMap.get(remoteInspectorConnection), targetList.get()),
    292         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    293         -1, m_cancellable.get(), RemoteInspectorServerInternal::dbusConnectionCallAsyncReadyCallback, nullptr);
    294 }
    295 
    296 void RemoteInspectorServer::clientConnectionClosedCallback(GDBusConnection* connection, gboolean /*remotePeerVanished*/, GError*, RemoteInspectorServer* server)
    297 {
    298     server->clientConnectionClosed(connection);
    299 }
    300 
    301 GVariant* RemoteInspectorServer::setupInspectorClient(GDBusConnection* clientConnection, const char* clientBackendCommandsHash)
     223    clientConnection->sendMessage("SetTargetList", g_variant_new("(t@a(tsssb))", addResult.iterator->value, targetList.get()));
     224}
     225
     226GVariant* RemoteInspectorServer::setupInspectorClient(SocketConnection& clientConnection, const char* clientBackendCommandsHash)
    302227{
    303228    ASSERT(!m_clientConnection);
    304     m_clientConnection = clientConnection;
    305     g_signal_connect(m_clientConnection.get(), "closed", G_CALLBACK(clientConnectionClosedCallback), this);
     229    m_clientConnection = &clientConnection;
    306230
    307231    GVariant* backendCommands;
     
    313237
    314238    // Ask all remote inspectors to push their target lists to notify the new client.
    315     for (auto* remoteInspectorConnection : m_remoteInspectorConnectionToIDMap.keys()) {
    316         g_dbus_connection_call(remoteInspectorConnection, nullptr,
    317             REMOTE_INSPECTOR_DBUS_OBJECT_PATH,
    318             REMOTE_INSPECTOR_DBUS_INTERFACE,
    319             "GetTargetList",
    320             nullptr,
    321             nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    322             -1, m_cancellable.get(), RemoteInspectorServerInternal::dbusConnectionCallAsyncReadyCallback, nullptr);
    323     }
     239    for (auto* remoteInspectorConnection : m_remoteInspectorConnectionToIDMap.keys())
     240        remoteInspectorConnection->sendMessage("GetTargetList", nullptr);
    324241
    325242    return backendCommands;
    326243}
    327244
    328 void RemoteInspectorServer::setup(GDBusConnection* clientConnection, uint64_t connectionID, uint64_t targetID)
    329 {
    330     ASSERT(m_clientConnection.get() == clientConnection || m_automationConnection.get() == clientConnection);
     245void RemoteInspectorServer::setup(SocketConnection& clientConnection, uint64_t connectionID, uint64_t targetID)
     246{
     247    ASSERT(m_clientConnection == &clientConnection || m_automationConnection == &clientConnection);
    331248    ASSERT(m_idToRemoteInspectorConnectionMap.contains(connectionID));
    332     if (clientConnection == m_automationConnection.get()) {
     249    if (&clientConnection == m_automationConnection) {
    333250        m_automationTargets.add(std::make_pair(connectionID, targetID));
    334251        RemoteInspector::singleton().setup(targetID);
     
    337254
    338255    m_inspectionTargets.add(std::make_pair(connectionID, targetID));
    339     auto* remoteInspectorConnection = m_idToRemoteInspectorConnectionMap.get(connectionID);
    340     g_dbus_connection_call(remoteInspectorConnection, nullptr,
    341         REMOTE_INSPECTOR_DBUS_OBJECT_PATH,
    342         REMOTE_INSPECTOR_DBUS_INTERFACE,
    343         "Setup",
    344         g_variant_new("(t)", targetID),
    345         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    346         -1, m_cancellable.get(), RemoteInspectorServerInternal::dbusConnectionCallAsyncReadyCallback, nullptr);
    347 }
    348 
    349 void RemoteInspectorServer::close(GDBusConnection* clientConnection, uint64_t connectionID, uint64_t targetID)
    350 {
    351     ASSERT(m_clientConnection.get() == clientConnection || m_automationConnection.get() == clientConnection);
     256    m_idToRemoteInspectorConnectionMap.get(connectionID)->sendMessage("Setup", g_variant_new("(t)", targetID));
     257}
     258
     259void RemoteInspectorServer::close(SocketConnection& clientConnection, uint64_t connectionID, uint64_t targetID)
     260{
     261    ASSERT(m_clientConnection == &clientConnection || m_automationConnection == &clientConnection);
    352262    ASSERT(m_idToRemoteInspectorConnectionMap.contains(connectionID));
    353     if (clientConnection == m_automationConnection.get()) {
     263    if (&clientConnection == m_automationConnection) {
    354264        // FIXME: automation.
    355265        return;
     
    357267
    358268    ASSERT(m_inspectionTargets.contains(std::make_pair(connectionID, targetID)));
    359     auto* remoteInspectorConnection = m_idToRemoteInspectorConnectionMap.get(connectionID);
    360     g_dbus_connection_call(remoteInspectorConnection, nullptr,
    361         REMOTE_INSPECTOR_DBUS_OBJECT_PATH,
    362         REMOTE_INSPECTOR_DBUS_INTERFACE,
    363         "FrontendDidClose",
    364         g_variant_new("(t)", targetID),
    365         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    366         -1, m_cancellable.get(), RemoteInspectorServerInternal::dbusConnectionCallAsyncReadyCallback, nullptr);
     269    m_idToRemoteInspectorConnectionMap.get(connectionID)->sendMessage("FrontendDidClose", g_variant_new("(t)", targetID));
    367270    m_inspectionTargets.remove(std::make_pair(connectionID, targetID));
    368271}
    369272
    370 void RemoteInspectorServer::clientConnectionClosed(GDBusConnection* clientConnection)
    371 {
    372     ASSERT(m_clientConnection.get() == clientConnection || m_automationConnection.get() == clientConnection);
    373     if (clientConnection == m_automationConnection.get()) {
     273void RemoteInspectorServer::connectionDidClose(SocketConnection& clientConnection)
     274{
     275    ASSERT(m_connections.contains(&clientConnection));
     276    if (&clientConnection == m_automationConnection) {
    374277        for (auto connectionTargetPair : m_automationTargets)
    375278            close(clientConnection, connectionTargetPair.first, connectionTargetPair.second);
    376279        m_automationConnection = nullptr;
    377         return;
    378     }
    379 
    380     for (auto connectionTargetPair : m_inspectionTargets)
    381         close(clientConnection, connectionTargetPair.first, connectionTargetPair.second);
    382     m_clientConnection = nullptr;
    383 }
    384 
    385 void RemoteInspectorServer::connectionClosed(GDBusConnection* remoteInspectorConnection)
    386 {
    387     ASSERT(m_connections.contains(remoteInspectorConnection));
    388     if (m_remoteInspectorConnectionToIDMap.contains(remoteInspectorConnection)) {
    389         uint64_t connectionID = m_remoteInspectorConnectionToIDMap.take(remoteInspectorConnection);
     280    } else if (&clientConnection == m_clientConnection) {
     281        for (auto connectionTargetPair : m_inspectionTargets)
     282            close(clientConnection, connectionTargetPair.first, connectionTargetPair.second);
     283        m_clientConnection = nullptr;
     284    } else if (m_remoteInspectorConnectionToIDMap.contains(&clientConnection)) {
     285        uint64_t connectionID = m_remoteInspectorConnectionToIDMap.take(&clientConnection);
    390286        m_idToRemoteInspectorConnectionMap.remove(connectionID);
    391287        // Send an empty target list to the clients.
    392         Vector<GRefPtr<GDBusConnection>> clientConnections = { m_automationConnection, m_clientConnection };
    393         for (auto& clientConnection : clientConnections) {
    394             if (!clientConnection)
     288        Vector<SocketConnection*> clientConnections = { m_automationConnection, m_clientConnection };
     289        for (auto* connection : clientConnections) {
     290            if (!connection)
    395291                continue;
    396             g_dbus_connection_call(clientConnection.get(), nullptr,
    397                 REMOTE_INSPECTOR_CLIENT_OBJECT_PATH,
    398                 REMOTE_INSPECTOR_CLIENT_DBUS_INTERFACE,
    399                 "SetTargetList",
    400                 g_variant_new("(t@a(tsssb))", connectionID, g_variant_new_array(G_VARIANT_TYPE("(tsssb)"), nullptr, 0)),
    401                 nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    402                 -1, m_cancellable.get(), RemoteInspectorServerInternal::dbusConnectionCallAsyncReadyCallback, nullptr);
     292            connection->sendMessage("SetTargetList", g_variant_new("(t@a(tsssb))", connectionID, g_variant_new_array(G_VARIANT_TYPE("(tsssb)"), nullptr, 0)));
    403293        }
    404294    }
    405     m_connections.remove(remoteInspectorConnection);
    406 }
    407 
    408 void RemoteInspectorServer::sendMessageToBackend(GDBusConnection* clientConnection, uint64_t connectionID, uint64_t targetID, const char* message)
    409 {
    410     ASSERT(m_clientConnection.get() == clientConnection || m_automationConnection.get() == clientConnection);
     295    m_connections.remove(&clientConnection);
     296}
     297
     298void RemoteInspectorServer::sendMessageToBackend(SocketConnection& clientConnection, uint64_t connectionID, uint64_t targetID, const char* message)
     299{
     300    ASSERT(m_clientConnection == &clientConnection || m_automationConnection == &clientConnection);
    411301    ASSERT(m_idToRemoteInspectorConnectionMap.contains(connectionID));
    412     if (clientConnection == m_automationConnection.get()) {
     302    if (&clientConnection == m_automationConnection) {
    413303        RemoteInspector::singleton().sendMessageToTarget(targetID, message);
    414304        return;
    415305    }
    416306
    417     auto* remoteInspectorConnection = m_idToRemoteInspectorConnectionMap.get(connectionID);
    418     g_dbus_connection_call(remoteInspectorConnection, nullptr,
    419         REMOTE_INSPECTOR_DBUS_OBJECT_PATH,
    420         REMOTE_INSPECTOR_DBUS_INTERFACE,
    421         "SendMessageToTarget",
    422         g_variant_new("(t&s)", targetID, message),
    423         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    424         -1, m_cancellable.get(), RemoteInspectorServerInternal::dbusConnectionCallAsyncReadyCallback, nullptr);
    425 }
    426 
    427 void RemoteInspectorServer::sendMessageToFrontend(GDBusConnection* remoteInspectorConnection, uint64_t targetID, const char* message)
    428 {
    429     ASSERT(m_connections.contains(remoteInspectorConnection));
    430     ASSERT(m_remoteInspectorConnectionToIDMap.contains(remoteInspectorConnection));
    431 
    432     uint64_t connectionID = m_remoteInspectorConnectionToIDMap.get(remoteInspectorConnection);
     307    m_idToRemoteInspectorConnectionMap.get(connectionID)->sendMessage("SendMessageToTarget", g_variant_new("(t&s)", targetID, message));
     308}
     309
     310void RemoteInspectorServer::sendMessageToFrontend(SocketConnection& remoteInspectorConnection, uint64_t targetID, const char* message)
     311{
     312    ASSERT(m_connections.contains(&remoteInspectorConnection));
     313    ASSERT(m_remoteInspectorConnectionToIDMap.contains(&remoteInspectorConnection));
     314
     315    uint64_t connectionID = m_remoteInspectorConnectionToIDMap.get(&remoteInspectorConnection);
    433316    auto connectionTargetPair = std::make_pair(connectionID, targetID);
    434317    ASSERT(m_automationTargets.contains(connectionTargetPair) || m_inspectionTargets.contains(connectionTargetPair));
    435     GDBusConnection* clientConnection = m_inspectionTargets.contains(connectionTargetPair) ? m_clientConnection.get() : m_automationConnection.get();
     318    SocketConnection* clientConnection = m_inspectionTargets.contains(connectionTargetPair) ? m_clientConnection : m_automationConnection;
    436319    ASSERT(clientConnection);
    437 
    438     g_dbus_connection_call(clientConnection, nullptr,
    439         REMOTE_INSPECTOR_CLIENT_OBJECT_PATH,
    440         REMOTE_INSPECTOR_CLIENT_DBUS_INTERFACE,
    441         "SendMessageToFrontend",
    442         g_variant_new("(tt&s)", m_remoteInspectorConnectionToIDMap.get(remoteInspectorConnection), targetID, message),
    443         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    444         -1, m_cancellable.get(), RemoteInspectorServerInternal::dbusConnectionCallAsyncReadyCallback, nullptr);
    445 }
    446 
    447 void RemoteInspectorServer::startAutomationSession(GDBusConnection* automationConnection, const char* sessionID, const RemoteInspector::Client::SessionCapabilities& capabilities)
     320    clientConnection->sendMessage("SendMessageToFrontend", g_variant_new("(tt&s)", connectionID, targetID, message));
     321}
     322
     323void RemoteInspectorServer::startAutomationSession(SocketConnection& automationConnection, const char* sessionID, const RemoteInspector::Client::SessionCapabilities& capabilities)
    448324{
    449325    if (!m_automationConnection)
    450         m_automationConnection = automationConnection;
    451     ASSERT(m_automationConnection.get() == automationConnection);
     326        m_automationConnection = &automationConnection;
     327    ASSERT(m_automationConnection == &automationConnection);
    452328
    453329    RemoteInspector::singleton().requestAutomationSession(sessionID, capabilities);
  • trunk/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorServer.h

    r232833 r252770  
    3232#include <wtf/HashSet.h>
    3333#include <wtf/glib/GRefPtr.h>
     34#include <wtf/glib/SocketConnection.h>
    3435
    35 typedef struct _GCancellable GCancellable;
    36 typedef struct _GDBusConnection GDBusConnection;
    37 typedef struct _GDBusInterfaceInfo GDBusInterfaceInfo;
    38 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;
    39 typedef struct _GDBusNodeInfo GDBusNodeInfo;
    40 typedef struct _GDBusServer GDBusServer;
    41 typedef struct _GVariant GVariant;
     36typedef struct _GSocketConnection GSocketConnection;
     37typedef struct _GSocketService GSocketService;
    4238
    4339namespace Inspector {
     
    4945
    5046    bool start(const char* address, unsigned port);
    51     bool isRunning() const { return !!m_dbusServer; }
     47    bool isRunning() const { return !!m_service; }
    5248
    5349private:
    54     GDBusInterfaceInfo* interfaceInfo();
     50    static gboolean incomingConnectionCallback(GSocketService*, GSocketConnection*, GObject*, RemoteInspectorServer*);
     51    void incomingConnection(Ref<SocketConnection>&&);
    5552
    56     static gboolean newConnectionCallback(GDBusServer*, GDBusConnection*, RemoteInspectorServer*);
    57     static void connectionClosedCallback(GDBusConnection*, gboolean remotePeerVanished, GError*, RemoteInspectorServer*);
    58     void newConnection(GDBusConnection*);
    59     void connectionClosed(GDBusConnection*);
     53    static const SocketConnection::MessageHandlers s_messageHandlers;
     54    void connectionDidClose(SocketConnection&);
     55    void setTargetList(SocketConnection&, GVariant*);
     56    GVariant* setupInspectorClient(SocketConnection&, const char* clientBackendCommandsHash);
     57    void setup(SocketConnection&, uint64_t connectionID, uint64_t targetID);
     58    void close(SocketConnection&, uint64_t connectionID, uint64_t targetID);
     59    void sendMessageToFrontend(SocketConnection&, uint64_t target, const char*);
     60    void sendMessageToBackend(SocketConnection&, uint64_t connectionID, uint64_t targetID, const char*);
     61    void startAutomationSession(SocketConnection&, const char* sessionID, const RemoteInspector::Client::SessionCapabilities&);
    6062
    61     static const GDBusInterfaceVTable s_interfaceVTable;
    62     void setTargetList(GDBusConnection*, GVariant*);
    63     GVariant* setupInspectorClient(GDBusConnection*, const char* clientBackendCommandsHash);
    64     void setup(GDBusConnection*, uint64_t connectionID, uint64_t targetID);
    65     void close(GDBusConnection*, uint64_t connectionID, uint64_t targetID);
    66     void clientConnectionClosed(GDBusConnection*);
    67     void sendMessageToFrontend(GDBusConnection*, uint64_t target, const char*);
    68     void sendMessageToBackend(GDBusConnection*, uint64_t connectionID, uint64_t targetID, const char*);
    69     void startAutomationSession(GDBusConnection*, const char* sessionID, const RemoteInspector::Client::SessionCapabilities&);
    70 
    71     static void clientConnectionClosedCallback(GDBusConnection*, gboolean remotePeerVanished, GError*, RemoteInspectorServer*);
    72 
    73     GDBusNodeInfo* m_introspectionData { nullptr };
    74     GRefPtr<GDBusServer> m_dbusServer;
    75     GRefPtr<GCancellable> m_cancellable;
    76     HashSet<GRefPtr<GDBusConnection>> m_connections;
    77     HashMap<GDBusConnection*, uint64_t> m_remoteInspectorConnectionToIDMap;
    78     HashMap<uint64_t, GDBusConnection*> m_idToRemoteInspectorConnectionMap;
    79     GRefPtr<GDBusConnection> m_clientConnection;
     63    GRefPtr<GSocketService> m_service;
     64    HashSet<RefPtr<SocketConnection>> m_connections;
     65    HashMap<SocketConnection*, uint64_t> m_remoteInspectorConnectionToIDMap;
     66    HashMap<uint64_t, SocketConnection*> m_idToRemoteInspectorConnectionMap;
     67    SocketConnection* m_clientConnection { nullptr };
     68    SocketConnection* m_automationConnection { nullptr };
    8069    HashSet<std::pair<uint64_t, uint64_t>> m_inspectionTargets;
    81     GRefPtr<GDBusConnection> m_automationConnection;
    8270    HashSet<std::pair<uint64_t, uint64_t>> m_automationTargets;
    8371};
  • trunk/Source/WTF/ChangeLog

    r252754 r252770  
     12019-11-22  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][WPE] RemoteInspector: use sockets instead of DBus
     4        https://bugs.webkit.org/show_bug.cgi?id=204503
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Add SocketConnection class.
     9
     10        * wtf/PlatformGTK.cmake:
     11        * wtf/PlatformWPE.cmake:
     12        * wtf/glib/GSocketMonitor.cpp: Renamed from Source/WebKit/Platform/IPC/glib/GSocketMonitor.cpp.
     13        (WTF::GSocketMonitor::start):
     14        * wtf/glib/GSocketMonitor.h: Renamed from Source/WebKit/Platform/IPC/glib/GSocketMonitor.h.
     15        (WTF::GSocketMonitor::isActive const):
     16        * wtf/glib/GTypedefs.h:
     17        * wtf/glib/GUniquePtr.h:
     18        * wtf/glib/SocketConnection.cpp: Added.
     19        (WTF::SocketConnection::SocketConnection):
     20        (WTF::SocketConnection::~SocketConnection):
     21        (WTF::SocketConnection::read):
     22        (WTF::SocketConnection::readMessage):
     23        (WTF::SocketConnection::sendMessage):
     24        (WTF::SocketConnection::write):
     25        (WTF::SocketConnection::waitForSocketWritability):
     26        (WTF::SocketConnection::close):
     27        (WTF::SocketConnection::didClose):
     28        * wtf/glib/SocketConnection.h: Added.
     29        (WTF::SocketConnection::create):
     30        (WTF::SocketConnection::isClosed const):
     31
    1322019-11-21  Yusuke Suzuki  <ysuzuki@apple.com>
    233
  • trunk/Source/WTF/wtf/PlatformGTK.cmake

    r250129 r252770  
    55    glib/GMutexLocker.h
    66    glib/GRefPtr.h
     7    glib/GSocketMonitor.h
    78    glib/GTypedefs.h
    89    glib/GUniquePtr.h
    910    glib/RunLoopSourcePriority.h
     11    glib/SocketConnection.h
    1012    glib/WTFGType.h
    1113)
     
    2527    glib/GLibUtilities.cpp
    2628    glib/GRefPtr.cpp
     29    glib/GSocketMonitor.cpp
    2730    glib/RunLoopGLib.cpp
     31    glib/SocketConnection.cpp
    2832    glib/URLGLib.cpp
    2933
  • trunk/Source/WTF/wtf/PlatformWPE.cmake

    r250129 r252770  
    33    glib/GMutexLocker.h
    44    glib/GRefPtr.h
     5    glib/GSocketMonitor.h
    56    glib/GTypedefs.h
    67    glib/GUniquePtr.h
    78    glib/RunLoopSourcePriority.h
     9    glib/SocketConnection.h
    810    glib/WTFGType.h
    911
     
    2022    glib/GLibUtilities.cpp
    2123    glib/GRefPtr.cpp
     24    glib/GSocketMonitor.cpp
    2225    glib/RunLoopGLib.cpp
     26    glib/SocketConnection.cpp
    2327    glib/URLGLib.cpp
    2428
  • trunk/Source/WTF/wtf/glib/GSocketMonitor.cpp

    r252769 r252770  
    3030#include <wtf/glib/RunLoopSourcePriority.h>
    3131
    32 namespace IPC {
     32namespace WTF {
    3333
    3434GSocketMonitor::~GSocketMonitor()
     
    4444}
    4545
    46 void GSocketMonitor::start(GSocket* socket, GIOCondition condition, RunLoop& runLoop, Function<gboolean (GIOCondition)>&& callback)
     46void GSocketMonitor::start(GSocket* socket, GIOCondition condition, RunLoop& runLoop, Function<gboolean(GIOCondition)>&& callback)
    4747{
    4848    stop();
     
    6969}
    7070
    71 } // namespace IPC
     71} // namespace WTF
  • trunk/Source/WTF/wtf/glib/GSocketMonitor.h

    r252769 r252770  
    2424 */
    2525
    26 #ifndef GSocketMonitor_h
    27 #define GSocketMonitor_h
     26#pragma once
    2827
    2928#include <glib.h>
     
    3534typedef struct _GSocket GSocket;
    3635
    37 namespace IPC {
     36namespace WTF {
    3837
    3938class GSocketMonitor {
     
    4342    ~GSocketMonitor();
    4443
    45     void start(GSocket*, GIOCondition, RunLoop&, Function<gboolean (GIOCondition)>&&);
     44    void start(GSocket*, GIOCondition, RunLoop&, Function<gboolean(GIOCondition)>&&);
    4645    void stop();
     46    bool isActive() const { return !!m_source; }
    4747
    4848private:
     
    5151    GRefPtr<GSource> m_source;
    5252    GRefPtr<GCancellable> m_cancellable;
    53     Function<gboolean (GIOCondition)> m_callback;
     53    Function<gboolean(GIOCondition)> m_callback;
    5454};
    5555
    56 } // namespace IPC
     56} // namespace WTF
    5757
    58 #endif // GSocketMonitor_h
     58using WTF::GSocketMonitor;
  • trunk/Source/WTF/wtf/glib/GTypedefs.h

    r246632 r252770  
    6363typedef struct _GVariantBuilder GVariantBuilder;
    6464typedef struct _GVariantIter GVariantIter;
     65typedef struct _GVariantType GVariantType;
    6566typedef union _GdkEvent GdkEvent;
    6667typedef struct _GTimer GTimer;
  • trunk/Source/WTF/wtf/glib/GUniquePtr.h

    r247294 r252770  
    4747    macro(GKeyFile, g_key_file_free) \
    4848    macro(char*, g_strfreev) \
    49     macro(GVariantIter, g_variant_iter_free)
     49    macro(GVariantIter, g_variant_iter_free) \
     50    macro(GVariantType, g_variant_type_free)
    5051
    5152#define WTF_DEFINE_GPTR_DELETER(typeName, deleterFunc) \
  • trunk/Source/WebDriver/ChangeLog

    r252408 r252770  
     12019-11-22  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][WPE] RemoteInspector: use sockets instead of DBus
     4        https://bugs.webkit.org/show_bug.cgi?id=204503
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Use GSockets API instead of DBus.
     9
     10        * SessionHost.cpp:
     11        (WebDriver::SessionHost::sendCommandToBackend):
     12        * SessionHost.h:
     13        * glib/SessionHostGlib.cpp:
     14        (WebDriver::SessionHost::~SessionHost):
     15        (WebDriver::SessionHost::isConnected const):
     16        (WebDriver::ConnectToBrowserAsyncData::ConnectToBrowserAsyncData):
     17        (WebDriver::SessionHost::launchBrowser):
     18        (WebDriver::SessionHost::connectToBrowser):
     19        (WebDriver::SessionHost::connectionDidClose):
     20        (WebDriver::SessionHost::setupConnection):
     21        (WebDriver::SessionHost::startAutomationSession):
     22        (WebDriver::SessionHost::didStartAutomationSession):
     23        (WebDriver::SessionHost::setTargetList):
     24        (WebDriver::SessionHost::sendMessageToBackend):
     25        * socket/SessionHostSocket.cpp:
     26        (WebDriver::SessionHost::sendMessageToBackend):
     27
    1282019-11-13  Carlos Garcia Campos  <cgarcia@igalia.com>
    229
  • trunk/Source/WebDriver/SessionHost.cpp

    r233122 r252770  
    5656    }
    5757    messageBuilder.append('}');
    58     sendMessageToBackend(sequenceID, messageBuilder.toString());
     58    sendMessageToBackend(messageBuilder.toString());
    5959
    6060    return sequenceID;
  • trunk/Source/WebDriver/SessionHost.h

    r239427 r252770  
    3232#if USE(GLIB)
    3333#include <wtf/glib/GRefPtr.h>
    34 typedef struct _GDBusConnection GDBusConnection;
    35 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;
     34#include <wtf/glib/SocketConnection.h>
    3635typedef struct _GSubprocess GSubprocess;
    3736#endif
     
    7271
    7372    void inspectorDisconnected();
    74     void sendMessageToBackend(long, const String&);
     73    void sendMessageToBackend(const String&);
    7574    void dispatchMessage(const String&);
    7675
    7776#if USE(GLIB)
    78     static void dbusConnectionClosedCallback(SessionHost*);
    79     static const GDBusInterfaceVTable s_interfaceVTable;
     77    static const SocketConnection::MessageHandlers s_messageHandlers;
     78    void connectionDidClose();
    8079    void launchBrowser(Function<void (Optional<String> error)>&&);
    8180    void connectToBrowser(std::unique_ptr<ConnectToBrowserAsyncData>&&);
    8281    bool matchCapabilities(GVariant*);
    8382    bool buildSessionCapabilities(GVariantBuilder*) const;
    84     void setupConnection(GRefPtr<GDBusConnection>&&);
     83    void setupConnection(Ref<SocketConnection>&&);
     84    void didStartAutomationSession(GVariant*);
    8585    void setTargetList(uint64_t connectionID, Vector<Target>&&);
    8686    void sendMessageToFrontend(uint64_t connectionID, uint64_t targetID, const char* message);
     
    9898    Function<void (bool, Optional<String>)> m_startSessionCompletionHandler;
    9999    GRefPtr<GSubprocess> m_browser;
    100     GRefPtr<GDBusConnection> m_dbusConnection;
     100    RefPtr<SocketConnection> m_socketConnection;
    101101    GRefPtr<GCancellable> m_cancellable;
    102102#endif
  • trunk/Source/WebDriver/glib/SessionHostGlib.cpp

    r252323 r252770  
    3333#include <wtf/glib/GUniquePtr.h>
    3434
    35 #define REMOTE_INSPECTOR_CLIENT_DBUS_INTERFACE "org.webkit.RemoteInspectorClient"
    36 #define REMOTE_INSPECTOR_CLIENT_OBJECT_PATH "/org/webkit/RemoteInspectorClient"
    37 #define INSPECTOR_DBUS_INTERFACE "org.webkit.Inspector"
    38 #define INSPECTOR_DBUS_OBJECT_PATH "/org/webkit/Inspector"
    39 
    4035namespace WebDriver {
    4136
    4237SessionHost::~SessionHost()
    4338{
    44     if (m_dbusConnection)
    45         g_signal_handlers_disconnect_matched(m_dbusConnection.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
    4639    g_cancellable_cancel(m_cancellable.get());
     40    if (m_socketConnection)
     41        m_socketConnection->close();
    4742    if (m_browser)
    4843        g_subprocess_force_exit(m_browser.get());
    4944}
    5045
    51 static const char introspectionXML[] =
    52     "<node>"
    53     "  <interface name='" REMOTE_INSPECTOR_CLIENT_DBUS_INTERFACE "'>"
    54     "    <method name='SetTargetList'>"
    55     "      <arg type='t' name='connectionID' direction='in'/>"
    56     "      <arg type='a(tsssb)' name='list' direction='in'/>"
    57     "    </method>"
    58     "    <method name='SendMessageToFrontend'>"
    59     "      <arg type='t' name='connectionID' direction='in'/>"
    60     "      <arg type='t' name='target' direction='in'/>"
    61     "      <arg type='s' name='message' direction='in'/>"
    62     "    </method>"
    63     "  </interface>"
    64     "</node>";
    65 
    66 const GDBusInterfaceVTable SessionHost::s_interfaceVTable = {
    67     // method_call
    68     [](GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) {
    69         auto* sessionHost = static_cast<SessionHost*>(userData);
    70         if (!g_strcmp0(methodName, "SetTargetList")) {
     46const SocketConnection::MessageHandlers SessionHost::s_messageHandlers = {
     47    { "DidClose", std::pair<CString, SocketConnection::MessageCallback> { { },
     48        [](SocketConnection&, GVariant*, gpointer userData) {
     49            auto& sessionHost = *static_cast<SessionHost*>(userData);
     50            sessionHost.connectionDidClose();
     51        }}
     52    },
     53    { "DidStartAutomationSession", std::pair<CString, SocketConnection::MessageCallback> { "(ss)",
     54        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     55            auto& sessionHost = *static_cast<SessionHost*>(userData);
     56            sessionHost.didStartAutomationSession(parameters);
     57        }}
     58    },
     59    { "SetTargetList", std::pair<CString, SocketConnection::MessageCallback> { "(ta(tsssb))",
     60        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     61            auto& sessionHost = *static_cast<SessionHost*>(userData);
    7162            guint64 connectionID;
    7263            GUniqueOutPtr<GVariantIter> iter;
     
    8475                    targetList.uncheckedAppend({ targetID, name, static_cast<bool>(isPaired) });
    8576            }
    86             sessionHost->setTargetList(connectionID, WTFMove(targetList));
    87             g_dbus_method_invocation_return_value(invocation, nullptr);
    88         } else if (!g_strcmp0(methodName, "SendMessageToFrontend")) {
     77            sessionHost.setTargetList(connectionID, WTFMove(targetList));
     78        }}
     79    },
     80    { "SendMessageToFrontend", std::pair<CString, SocketConnection::MessageCallback> { "(tts)",
     81        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     82            auto& sessionHost = *static_cast<SessionHost*>(userData);
    8983            guint64 connectionID, targetID;
    9084            const char* message;
    9185            g_variant_get(parameters, "(tt&s)", &connectionID, &targetID, &message);
    92             sessionHost->sendMessageToFrontend(connectionID, targetID, message);
    93             g_dbus_method_invocation_return_value(invocation, nullptr);
    94         }
    95     },
    96     // get_property
    97     nullptr,
    98     // set_property
    99     nullptr,
    100     // padding
    101     { 0 }
     86            sessionHost.sendMessageToFrontend(connectionID, targetID, message);
     87        }}
     88    }
    10289};
    10390
     
    10996bool SessionHost::isConnected() const
    11097{
    111     // Session is connected when launching or when dbus connection hasn't been closed.
    112     return m_browser && (!m_dbusConnection || !g_dbus_connection_is_closed(m_dbusConnection.get()));
     98    // Session is connected when launching or when socket connection hasn't been closed.
     99    return m_browser && (!m_socketConnection || !m_socketConnection->isClosed());
    113100}
    114101
    115102struct ConnectToBrowserAsyncData {
    116103    WTF_MAKE_STRUCT_FAST_ALLOCATED;
    117     ConnectToBrowserAsyncData(SessionHost* sessionHost, GUniquePtr<char>&& dbusAddress, GCancellable* cancellable, Function<void (Optional<String> error)>&& completionHandler)
     104    ConnectToBrowserAsyncData(SessionHost* sessionHost, GUniquePtr<char>&& inspectorAddress, GCancellable* cancellable, Function<void(Optional<String>)>&& completionHandler)
    118105        : sessionHost(sessionHost)
    119         , dbusAddress(WTFMove(dbusAddress))
     106        , inspectorAddress(WTFMove(inspectorAddress))
    120107        , cancellable(cancellable)
    121108        , completionHandler(WTFMove(completionHandler))
     
    124111
    125112    SessionHost* sessionHost;
    126     GUniquePtr<char> dbusAddress;
     113    GUniquePtr<char> inspectorAddress;
    127114    GRefPtr<GCancellable> cancellable;
    128115    Function<void (Optional<String> error)> completionHandler;
     
    174161    }, this);
    175162
    176     GUniquePtr<char> dbusAddress(g_strdup_printf("tcp:host=%s,port=%u", "127.0.0.1", port));
    177     connectToBrowser(makeUnique<ConnectToBrowserAsyncData>(this, WTFMove(dbusAddress), m_cancellable.get(), WTFMove(completionHandler)));
     163    connectToBrowser(makeUnique<ConnectToBrowserAsyncData>(this, WTFMove(inspectorAddress), m_cancellable.get(), WTFMove(completionHandler)));
    178164}
    179165
     
    188174            return;
    189175
    190         g_dbus_connection_new_for_address(data->dbusAddress.get(), G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, nullptr, data->cancellable.get(),
    191             [](GObject*, GAsyncResult* result, gpointer userData) {
     176        GRefPtr<GSocketClient> socketClient = adoptGRef(g_socket_client_new());
     177        g_socket_client_connect_to_host_async(socketClient.get(), data->inspectorAddress.get(), 0, data->cancellable.get(),
     178            [](GObject* client, GAsyncResult* result, gpointer userData) {
    192179                auto data = std::unique_ptr<ConnectToBrowserAsyncData>(static_cast<ConnectToBrowserAsyncData*>(userData));
    193180                GUniqueOutPtr<GError> error;
    194                 GRefPtr<GDBusConnection> connection = adoptGRef(g_dbus_connection_new_for_address_finish(result, &error.outPtr()));
     181                GRefPtr<GSocketConnection> connection = adoptGRef(g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(client), result, &error.outPtr()));
    195182                if (!connection) {
    196183                    if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
     
    205192                    return;
    206193                }
    207                 data->sessionHost->setupConnection(WTFMove(connection));
     194                data->sessionHost->setupConnection(SocketConnection::create(WTFMove(connection), s_messageHandlers, data->sessionHost));
    208195                data->completionHandler(WTF::nullopt);
    209196        }, data);
     
    211198}
    212199
    213 void SessionHost::dbusConnectionClosedCallback(SessionHost* sessionHost)
    214 {
    215     sessionHost->m_browser = nullptr;
    216     sessionHost->inspectorDisconnected();
    217 }
    218 
    219 static void dbusConnectionCallAsyncReadyCallback(GObject* source, GAsyncResult* result, gpointer)
    220 {
    221     GUniqueOutPtr<GError> error;
    222     GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error.outPtr()));
    223     if (!resultVariant && !g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    224         WTFLogAlways("RemoteInspectorServer failed to send DBus message: %s", error->message);
    225 }
    226 
    227 void SessionHost::setupConnection(GRefPtr<GDBusConnection>&& connection)
    228 {
    229     ASSERT(!m_dbusConnection);
     200void SessionHost::connectionDidClose()
     201{
     202    m_browser = nullptr;
     203    inspectorDisconnected();
     204    m_socketConnection = nullptr;
     205}
     206
     207void SessionHost::setupConnection(Ref<SocketConnection>&& connection)
     208{
     209    ASSERT(!m_socketConnection);
    230210    ASSERT(connection);
    231     m_dbusConnection = WTFMove(connection);
    232 
    233     g_signal_connect_swapped(m_dbusConnection.get(), "closed", G_CALLBACK(dbusConnectionClosedCallback), this);
    234 
    235     static GDBusNodeInfo* introspectionData = nullptr;
    236     if (!introspectionData)
    237         introspectionData = g_dbus_node_info_new_for_xml(introspectionXML, nullptr);
    238 
    239     g_dbus_connection_register_object(m_dbusConnection.get(), REMOTE_INSPECTOR_CLIENT_OBJECT_PATH, introspectionData->interfaces[0], &s_interfaceVTable, this, nullptr, nullptr);
     211    m_socketConnection = WTFMove(connection);
    240212}
    241213
     
    328300void SessionHost::startAutomationSession(Function<void (bool, Optional<String>)>&& completionHandler)
    329301{
    330     ASSERT(m_dbusConnection);
     302    ASSERT(m_socketConnection);
    331303    ASSERT(!m_startSessionCompletionHandler);
    332304    m_startSessionCompletionHandler = WTFMove(completionHandler);
    333305    m_sessionID = createCanonicalUUIDString();
    334306    GVariantBuilder builder;
    335     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    336         INSPECTOR_DBUS_OBJECT_PATH,
    337         INSPECTOR_DBUS_INTERFACE,
    338         "StartAutomationSession",
    339         g_variant_new("(sa{sv})", m_sessionID.utf8().data(), buildSessionCapabilities(&builder) ? &builder : nullptr),
    340         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    341         -1, m_cancellable.get(), [](GObject* source, GAsyncResult* result, gpointer userData) {
    342             GUniqueOutPtr<GError> error;
    343             GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error.outPtr()));
    344             if (!resultVariant && g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    345                 return;
    346 
    347             auto sessionHost = static_cast<SessionHost*>(userData);
    348             if (!resultVariant) {
    349                 auto completionHandler = std::exchange(sessionHost->m_startSessionCompletionHandler, nullptr);
    350                 completionHandler(false, makeString("Failed to start automation session: ", String::fromUTF8(error->message)));
    351                 return;
    352             }
    353 
    354             if (!sessionHost->matchCapabilities(resultVariant.get())) {
    355                 auto completionHandler = std::exchange(sessionHost->m_startSessionCompletionHandler, nullptr);
    356                 completionHandler(false, WTF::nullopt);
    357                 return;
    358             }
    359         }, this
    360     );
     307    m_socketConnection->sendMessage("StartAutomationSession", g_variant_new("(sa{sv})", m_sessionID.utf8().data(), buildSessionCapabilities(&builder) ? &builder : nullptr));
     308}
     309
     310void SessionHost::didStartAutomationSession(GVariant* parameters)
     311{
     312    if (matchCapabilities(parameters))
     313        return;
     314
     315    auto completionHandler = std::exchange(m_startSessionCompletionHandler, nullptr);
     316    completionHandler(false, WTF::nullopt);
    361317}
    362318
     
    372328        m_target = Target();
    373329        if (m_connectionID) {
    374             if (m_dbusConnection)
    375                 g_dbus_connection_close(m_dbusConnection.get(), nullptr, nullptr, nullptr);
     330            if (m_socketConnection)
     331                m_socketConnection->close();
    376332            m_connectionID = 0;
    377333        }
     
    391347
    392348    m_connectionID = connectionID;
    393     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    394         INSPECTOR_DBUS_OBJECT_PATH,
    395         INSPECTOR_DBUS_INTERFACE,
    396         "Setup",
    397         g_variant_new("(tt)", m_connectionID, m_target.id),
    398         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    399         -1, m_cancellable.get(), dbusConnectionCallAsyncReadyCallback, nullptr);
     349    m_socketConnection->sendMessage("Setup", g_variant_new("(tt)", m_connectionID, m_target.id));
    400350
    401351    auto startSessionCompletionHandler = std::exchange(m_startSessionCompletionHandler, nullptr);
     
    410360}
    411361
    412 struct MessageContext {
    413     WTF_MAKE_STRUCT_FAST_ALLOCATED;
    414     long messageID;
    415     SessionHost* host;
    416 };
    417 
    418 void SessionHost::sendMessageToBackend(long messageID, const String& message)
    419 {
    420     ASSERT(m_dbusConnection);
     362void SessionHost::sendMessageToBackend(const String& message)
     363{
     364    ASSERT(m_socketConnection);
    421365    ASSERT(m_connectionID);
    422366    ASSERT(m_target.id);
    423 
    424     auto messageContext = makeUnique<MessageContext>(MessageContext { messageID, this });
    425     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    426         INSPECTOR_DBUS_OBJECT_PATH,
    427         INSPECTOR_DBUS_INTERFACE,
    428         "SendMessageToBackend",
    429         g_variant_new("(tts)", m_connectionID, m_target.id, message.utf8().data()),
    430         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    431         -1, m_cancellable.get(), [](GObject* source, GAsyncResult* result, gpointer userData) {
    432             auto messageContext = std::unique_ptr<MessageContext>(static_cast<MessageContext*>(userData));
    433             GUniqueOutPtr<GError> error;
    434             GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error.outPtr()));
    435             if (!resultVariant && !g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
    436                 auto responseHandler = messageContext->host->m_commandRequests.take(messageContext->messageID);
    437                 if (responseHandler) {
    438                     auto errorObject = JSON::Object::create();
    439                     errorObject->setInteger("code"_s, -32603);
    440                     errorObject->setString("message"_s, String::fromUTF8(error->message));
    441                     responseHandler({ WTFMove(errorObject), true });
    442                 }
    443             }
    444         }, messageContext.release());
     367    m_socketConnection->sendMessage("SendMessageToBackend", g_variant_new("(tts)", m_connectionID, m_target.id, message.utf8().data()));
    445368}
    446369
  • trunk/Source/WebDriver/socket/SessionHostSocket.cpp

    r245567 r252770  
    4646}
    4747
    48 void SessionHost::sendMessageToBackend(long messageID, const String& message)
     48void SessionHost::sendMessageToBackend(const String& message)
    4949{
    5050}
  • trunk/Source/WebKit/ChangeLog

    r252762 r252770  
     12019-11-22  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][WPE] RemoteInspector: use sockets instead of DBus
     4        https://bugs.webkit.org/show_bug.cgi?id=204503
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Use GSockets API instead of DBus.
     9
     10        * Platform/IPC/Connection.h:
     11        * SourcesGTK.txt: Remove GSocketMonitor that has been moved to WTF.
     12        * SourcesWPE.txt: Ditto.
     13        * UIProcess/glib/RemoteInspectorClient.cpp:
     14        (WebKit::RemoteInspectorClient::RemoteInspectorClient):
     15        (WebKit::RemoteInspectorClient::~RemoteInspectorClient):
     16        (WebKit::RemoteInspectorClient::setupConnection):
     17        (WebKit::RemoteInspectorClient::connectionDidClose):
     18        (WebKit::RemoteInspectorClient::inspect):
     19        (WebKit::RemoteInspectorClient::sendMessageToBackend):
     20        (WebKit::RemoteInspectorClient::closeFromFrontend):
     21        * UIProcess/glib/RemoteInspectorClient.h:
     22
    1232019-11-21  Jer Noble  <jer.noble@apple.com>
    224
  • trunk/Source/WebKit/Platform/IPC/Connection.h

    r252636 r252770  
    5252
    5353#if USE(GLIB)
    54 #include "GSocketMonitor.h"
     54#include <wtf/glib/GSocketMonitor.h>
    5555#endif
    5656
  • trunk/Source/WebKit/SourcesGTK.txt

    r252234 r252770  
    4545NetworkProcess/webrtc/NetworkRTCSocket.cpp
    4646
    47 Platform/IPC/glib/GSocketMonitor.cpp
    4847Platform/IPC/unix/AttachmentUnix.cpp
    4948Platform/IPC/unix/ConnectionUnix.cpp
  • trunk/Source/WebKit/SourcesWPE.txt

    r251181 r252770  
    4444NetworkProcess/webrtc/NetworkRTCProvider.cpp
    4545NetworkProcess/webrtc/NetworkRTCSocket.cpp
    46 
    47 Platform/IPC/glib/GSocketMonitor.cpp
    4846
    4947Platform/IPC/unix/AttachmentUnix.cpp
  • trunk/Source/WebKit/UIProcess/glib/RemoteInspectorClient.cpp

    r251227 r252770  
    3535#include <wtf/text/Base64.h>
    3636
    37 #define REMOTE_INSPECTOR_CLIENT_DBUS_INTERFACE "org.webkit.RemoteInspectorClient"
    38 #define REMOTE_INSPECTOR_CLIENT_OBJECT_PATH "/org/webkit/RemoteInspectorClient"
    39 #define INSPECTOR_DBUS_INTERFACE "org.webkit.Inspector"
    40 #define INSPECTOR_DBUS_OBJECT_PATH "/org/webkit/Inspector"
    41 
    4237namespace WebKit {
    4338
     
    9994};
    10095
    101 static const char introspectionXML[] =
    102     "<node>"
    103     "  <interface name='" REMOTE_INSPECTOR_CLIENT_DBUS_INTERFACE "'>"
    104     "    <method name='SetTargetList'>"
    105     "      <arg type='t' name='connectionID' direction='in'/>"
    106     "      <arg type='a(tsssb)' name='list' direction='in'/>"
    107     "    </method>"
    108     "    <method name='SendMessageToFrontend'>"
    109     "      <arg type='t' name='connectionID' direction='in'/>"
    110     "      <arg type='t' name='target' direction='in'/>"
    111     "      <arg type='s' name='message' direction='in'/>"
    112     "    </method>"
    113     "  </interface>"
    114     "</node>";
    115 
    116 const GDBusInterfaceVTable RemoteInspectorClient::s_interfaceVTable = {
    117     // method_call
    118     [](GDBusConnection* connection, const gchar* sender, const gchar* objectPath, const gchar* interfaceName, const gchar* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) {
    119         auto* client = static_cast<RemoteInspectorClient*>(userData);
    120         if (!g_strcmp0(methodName, "SetTargetList")) {
     96const SocketConnection::MessageHandlers RemoteInspectorClient::s_messageHandlers = {
     97    { "DidClose", std::pair<CString, SocketConnection::MessageCallback> { { },
     98        [](SocketConnection&, GVariant*, gpointer userData) {
     99            auto& client = *static_cast<RemoteInspectorClient*>(userData);
     100            client.connectionDidClose();
     101        }}
     102    },
     103    { "DidSetupInspectorClient", std::pair<CString, SocketConnection::MessageCallback> { "(ay)",
     104        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     105            auto& client = *static_cast<RemoteInspectorClient*>(userData);
     106            GRefPtr<GVariant> backendCommandsVariant;
     107            g_variant_get(parameters, "(@ay)", &backendCommandsVariant.outPtr());
     108            client.setBackendCommands(g_variant_get_bytestring(backendCommandsVariant.get()));
     109        }}
     110    },
     111    { "SetTargetList", std::pair<CString, SocketConnection::MessageCallback> { "(ta(tsssb))",
     112        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     113            auto& client = *static_cast<RemoteInspectorClient*>(userData);
    121114            guint64 connectionID;
    122115            GUniqueOutPtr<GVariantIter> iter;
     
    134127                    targetList.uncheckedAppend({ targetID, type, name, url });
    135128            }
    136             client->setTargetList(connectionID, WTFMove(targetList));
    137             g_dbus_method_invocation_return_value(invocation, nullptr);
    138         } else if (!g_strcmp0(methodName, "SendMessageToFrontend")) {
     129            client.setTargetList(connectionID, WTFMove(targetList));
     130        }}
     131    },
     132    { "SendMessageToFrontend", std::pair<CString, SocketConnection::MessageCallback> { "(tts)",
     133        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     134            auto& client = *static_cast<RemoteInspectorClient*>(userData);
    139135            guint64 connectionID, targetID;
    140136            const char* message;
    141137            g_variant_get(parameters, "(tt&s)", &connectionID, &targetID, &message);
    142             client->sendMessageToFrontend(connectionID, targetID, message);
    143             g_dbus_method_invocation_return_value(invocation, nullptr);
    144         } else
    145             g_dbus_method_invocation_return_value(invocation, nullptr);
    146     },
    147     // get_property
    148     nullptr,
    149     // set_property
    150     nullptr,
    151     // padding
    152     { 0 }
     138            client.sendMessageToFrontend(connectionID, targetID, message);
     139        }}
     140    }
    153141};
    154142
     
    158146    , m_cancellable(adoptGRef(g_cancellable_new()))
    159147{
    160     GUniquePtr<char> dbusAddress(g_strdup_printf("tcp:host=%s,port=%u", address, port));
    161     g_dbus_connection_new_for_address(dbusAddress.get(), G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, nullptr, m_cancellable.get(),
    162         [](GObject*, GAsyncResult* result, gpointer userData) {
    163             auto* client = static_cast<RemoteInspectorClient*>(userData);
     148    GRefPtr<GSocketClient> socketClient = adoptGRef(g_socket_client_new());
     149    g_socket_client_connect_to_host_async(socketClient.get(), m_hostAndPort.utf8().data(), 0, m_cancellable.get(),
     150        [](GObject* object, GAsyncResult* result, gpointer userData) {
    164151            GUniqueOutPtr<GError> error;
    165             GRefPtr<GDBusConnection> connection = adoptGRef(g_dbus_connection_new_for_address_finish(result, &error.outPtr()));
    166             if (!connection && !g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    167                 WTFLogAlways("RemoteInspectorClient failed to connect to inspector server: %s", error->message);
    168             client->setupConnection(WTFMove(connection));
    169     }, this);
    170 }
    171 
    172 RemoteInspectorClient::~RemoteInspectorClient()
    173 {
    174 }
    175 
    176 static void dbusConnectionCallAsyncReadyCallback(GObject* source, GAsyncResult* result, gpointer)
    177 {
    178     GUniqueOutPtr<GError> error;
    179     GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error.outPtr()));
    180     if (!resultVariant && !g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    181         WTFLogAlways("RemoteInspectorClient failed to send DBus message: %s", error->message);
    182 }
    183 
    184 void RemoteInspectorClient::connectionClosedCallback(GDBusConnection* connection, gboolean /*remotePeerVanished*/, GError*, RemoteInspectorClient* client)
    185 {
    186     ASSERT_UNUSED(connection, client->m_dbusConnection.get() == connection);
    187     client->connectionClosed();
    188 }
    189 
    190 void RemoteInspectorClient::setupConnection(GRefPtr<GDBusConnection>&& connection)
    191 {
    192     m_dbusConnection = WTFMove(connection);
    193     if (!m_dbusConnection) {
    194         m_observer.connectionClosed(*this);
    195         return;
    196     }
    197     g_signal_connect(m_dbusConnection.get(), "closed", G_CALLBACK(connectionClosedCallback), this);
    198 
    199     static GDBusNodeInfo* introspectionData = nullptr;
    200     if (!introspectionData)
    201         introspectionData = g_dbus_node_info_new_for_xml(introspectionXML, nullptr);
    202 
    203     g_dbus_connection_register_object(m_dbusConnection.get(), REMOTE_INSPECTOR_CLIENT_OBJECT_PATH, introspectionData->interfaces[0], &s_interfaceVTable, this, nullptr, nullptr);
    204 
    205     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    206         INSPECTOR_DBUS_OBJECT_PATH,
    207         INSPECTOR_DBUS_INTERFACE,
    208         "SetupInspectorClient",
    209         g_variant_new("(@ay)", g_variant_new_bytestring(Inspector::backendCommandsHash().data())),
    210         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    211         -1, m_cancellable.get(), [](GObject* source, GAsyncResult* result, gpointer userData) {
    212             GUniqueOutPtr<GError> error;
    213             GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error.outPtr()));
     152            GRefPtr<GSocketConnection> connection = adoptGRef(g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(object), result, &error.outPtr()));
    214153            if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
    215154                return;
    216             if (!resultVariant) {
    217                 WTFLogAlways("RemoteInspectorClient failed to send DBus message: %s", error->message);
    218                 return;
     155            auto* client = static_cast<RemoteInspectorClient*>(userData);
     156            if (connection)
     157                client->setupConnection(SocketConnection::create(WTFMove(connection), s_messageHandlers, client));
     158            else {
     159                WTFLogAlways("RemoteInspectorClient failed to connect to inspector server: %s", error->message);
     160                client->m_observer.connectionClosed(*client);
    219161            }
    220 
    221             auto* client = static_cast<RemoteInspectorClient*>(userData);
    222             GRefPtr<GVariant> backendCommandsVariant;
    223             g_variant_get(resultVariant.get(), "(@ay)", &backendCommandsVariant.outPtr());
    224             client->setBackendCommands(g_variant_get_bytestring(backendCommandsVariant.get()));
    225         }, this);
     162    }, this);
     163}
     164
     165RemoteInspectorClient::~RemoteInspectorClient()
     166{
     167    g_cancellable_cancel(m_cancellable.get());
     168}
     169
     170void RemoteInspectorClient::setupConnection(Ref<SocketConnection>&& connection)
     171{
     172    m_socketConnection = WTFMove(connection);
     173    m_socketConnection->sendMessage("SetupInspectorClient", g_variant_new("(@ay)", g_variant_new_bytestring(Inspector::backendCommandsHash().data())));
    226174}
    227175
     
    238186}
    239187
    240 void RemoteInspectorClient::connectionClosed()
    241 {
    242     g_cancellable_cancel(m_cancellable.get());
     188void RemoteInspectorClient::connectionDidClose()
     189{
    243190    m_targets.clear();
    244191    m_inspectorProxyMap.clear();
    245     m_dbusConnection = nullptr;
     192    m_socketConnection = nullptr;
    246193    m_observer.connectionClosed(*this);
    247194}
     
    257204    }
    258205
    259     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    260         INSPECTOR_DBUS_OBJECT_PATH,
    261         INSPECTOR_DBUS_INTERFACE,
    262         "Setup",
    263         g_variant_new("(tt)", connectionID, targetID),
    264         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    265         -1, m_cancellable.get(), dbusConnectionCallAsyncReadyCallback, nullptr);
    266 
     206    m_socketConnection->sendMessage("Setup", g_variant_new("(tt)", connectionID, targetID));
    267207    addResult.iterator->value->load();
    268208}
     
    270210void RemoteInspectorClient::sendMessageToBackend(uint64_t connectionID, uint64_t targetID, const String& message)
    271211{
    272     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    273         INSPECTOR_DBUS_OBJECT_PATH,
    274         INSPECTOR_DBUS_INTERFACE,
    275         "SendMessageToBackend",
    276         g_variant_new("(tts)", connectionID, targetID, message.utf8().data()),
    277         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    278         -1, m_cancellable.get(), dbusConnectionCallAsyncReadyCallback, nullptr);
     212    m_socketConnection->sendMessage("SendMessageToBackend", g_variant_new("(tts)", connectionID, targetID, message.utf8().data()));
    279213}
    280214
     
    282216{
    283217    ASSERT(m_inspectorProxyMap.contains(std::make_pair(connectionID, targetID)));
    284     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
    285         INSPECTOR_DBUS_OBJECT_PATH,
    286         INSPECTOR_DBUS_INTERFACE,
    287         "FrontendDidClose",
    288         g_variant_new("(tt)", connectionID, targetID),
    289         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
    290         -1, m_cancellable.get(), dbusConnectionCallAsyncReadyCallback, nullptr);
     218    m_socketConnection->sendMessage("FrontendDidClose", g_variant_new("(tt)", connectionID, targetID));
    291219    m_inspectorProxyMap.remove(std::make_pair(connectionID, targetID));
    292220}
  • trunk/Source/WebKit/UIProcess/glib/RemoteInspectorClient.h

    r215862 r252770  
    3131#include <wtf/Vector.h>
    3232#include <wtf/glib/GRefPtr.h>
     33#include <wtf/glib/SocketConnection.h>
    3334#include <wtf/text/WTFString.h>
    3435
    3536typedef struct _GCancellable GCancellable;
    36 typedef struct _GDBusConnection GDBusConnection;
    37 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;
    3837
    3938namespace WebKit {
     
    7372
    7473private:
    75     static void connectionClosedCallback(GDBusConnection*, gboolean remotePeerVanished, GError*, RemoteInspectorClient*);
    76     void setupConnection(GRefPtr<GDBusConnection>&&);
    77     void connectionClosed();
     74    static const SocketConnection::MessageHandlers s_messageHandlers;
     75    void setupConnection(Ref<SocketConnection>&&);
     76    void connectionDidClose();
    7877
    79     static const GDBusInterfaceVTable s_interfaceVTable;
    8078    void setBackendCommands(const char*);
    8179    void setTargetList(uint64_t connectionID, Vector<Target>&&);
     
    8583    String m_backendCommandsURL;
    8684    RemoteInspectorObserver& m_observer;
    87     GRefPtr<GDBusConnection> m_dbusConnection;
     85    RefPtr<SocketConnection> m_socketConnection;
    8886    GRefPtr<GCancellable> m_cancellable;
    8987    HashMap<uint64_t, Vector<Target>> m_targets;
  • trunk/Tools/ChangeLog

    r252743 r252770  
     12019-11-22  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][WPE] RemoteInspector: use sockets instead of DBus
     4        https://bugs.webkit.org/show_bug.cgi?id=204503
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Update the unit tests to not use DBus.
     9
     10        * TestWebKitAPI/Tests/WebKitGLib/TestAutomationSession.cpp:
     11
    1122019-11-21  Wenson Hsieh  <wenson_hsieh@apple.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestAutomationSession.cpp

    r252356 r252770  
    2323#include <gio/gio.h>
    2424#include <wtf/UUID.h>
     25#include <wtf/glib/SocketConnection.h>
    2526#include <wtf/text/StringBuilder.h>
    2627
     
    2930    MAKE_GLIB_TEST_FIXTURE(AutomationTest);
    3031
     32    static const SocketConnection::MessageHandlers s_messageHandlers;
     33
    3134    AutomationTest()
    3235        : m_mainLoop(adoptGRef(g_main_loop_new(nullptr, TRUE)))
    3336    {
    34         g_dbus_connection_new_for_address("tcp:host=127.0.0.1,port=2229",
    35             G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, nullptr, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
    36                 GRefPtr<GDBusConnection> connection = adoptGRef(g_dbus_connection_new_for_address_finish(result, nullptr));
    37                 static_cast<AutomationTest*>(userData)->setConnection(WTFMove(connection));
    38             }, this);
     37        GRefPtr<GSocketClient> socketClient = adoptGRef(g_socket_client_new());
     38        g_socket_client_connect_to_host_async(socketClient.get(), "127.0.0.1:2229", 0, nullptr, [](GObject* client, GAsyncResult* result, gpointer userData) {
     39            GRefPtr<GSocketConnection> connection = adoptGRef(g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(client), result, nullptr));
     40            static_cast<AutomationTest*>(userData)->setConnection(SocketConnection::create(WTFMove(connection), s_messageHandlers, userData));
     41        }, this);
    3942        g_main_loop_run(m_mainLoop.get());
    4043    }
     
    5861    };
    5962
    60     const GDBusInterfaceVTable s_interfaceVTable = {
    61         // method_call
    62         [](GDBusConnection* connection, const gchar* sender, const gchar* objectPath, const gchar* interfaceName, const gchar* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) {
    63             auto* test = static_cast<AutomationTest*>(userData);
    64             if (!g_strcmp0(methodName, "SetTargetList")) {
    65                 guint64 connectionID;
    66                 GUniqueOutPtr<GVariantIter> iter;
    67                 g_variant_get(parameters, "(ta(tsssb))", &connectionID, &iter.outPtr());
    68                 guint64 targetID;
    69                 const char* type;
    70                 const char* name;
    71                 const char* dummy;
    72                 gboolean isPaired;
    73                 while (g_variant_iter_loop(iter.get(), "(t&s&s&sb)", &targetID, &type, &name, &dummy, &isPaired)) {
    74                     if (!g_strcmp0(type, "Automation")) {
    75                         test->setTarget(connectionID, Target(targetID, name, isPaired));
    76                         break;
    77                     }
    78                 }
    79                 g_dbus_method_invocation_return_value(invocation, nullptr);
    80             } else if (!g_strcmp0(methodName, "SendMessageToFrontend")) {
    81                 guint64 connectionID, targetID;
    82                 const char* message;
    83                 g_variant_get(parameters, "(tt&s)", &connectionID, &targetID, &message);
    84                 test->receivedMessage(connectionID, targetID, message);
    85                 g_dbus_method_invocation_return_value(invocation, nullptr);
    86             }
    87         },
    88         // get_property
    89         nullptr,
    90         // set_property
    91         nullptr,
    92         // padding
    93         { 0 }
    94     };
    95 
    96     void registerDBusObject()
    97     {
    98         static const char introspectionXML[] =
    99             "<node>"
    100             "  <interface name='org.webkit.RemoteInspectorClient'>"
    101             "    <method name='SetTargetList'>"
    102             "      <arg type='t' name='connectionID' direction='in'/>"
    103             "      <arg type='a(tsssb)' name='list' direction='in'/>"
    104             "    </method>"
    105             "    <method name='SendMessageToFrontend'>"
    106             "      <arg type='t' name='connectionID' direction='in'/>"
    107             "      <arg type='t' name='target' direction='in'/>"
    108             "      <arg type='s' name='message' direction='in'/>"
    109             "    </method>"
    110             "  </interface>"
    111             "</node>";
    112         static GDBusNodeInfo* introspectionData = nullptr;
    113         if (!introspectionData)
    114             introspectionData = g_dbus_node_info_new_for_xml(introspectionXML, nullptr);
    115         g_dbus_connection_register_object(m_connection.get(), "/org/webkit/RemoteInspectorClient", introspectionData->interfaces[0], &s_interfaceVTable, this, nullptr, nullptr);
    116     }
    117 
    118     void setConnection(GRefPtr<GDBusConnection>&& connection)
    119     {
    120         g_assert_true(G_IS_DBUS_CONNECTION(connection.get()));
     63    void setConnection(Ref<SocketConnection>&& connection)
     64    {
     65        g_assert_true(connection.ptr());
    12166        m_connection = WTFMove(connection);
    122         registerDBusObject();
    12367        g_main_loop_quit(m_mainLoop.get());
    12468    }
     
    156100        }
    157101        messageBuilder.append('}');
    158         g_dbus_connection_call(m_connection.get(), nullptr, "/org/webkit/Inspector", "org.webkit.Inspector",
    159             "SendMessageToBackend", g_variant_new("(tts)", m_connectionID, m_target.id, messageBuilder.toString().utf8().data()),
    160             nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, nullptr, nullptr, nullptr);
     102        m_connection->sendMessage("SendMessageToBackend", g_variant_new("(tts)", m_connectionID, m_target.id, messageBuilder.toString().utf8().data()));
    161103    }
    162104
     
    210152    }
    211153
     154    void didStartAutomationSession(GVariant* capabilities)
     155    {
     156        if (!m_session)
     157            return;
     158
     159        g_assert_nonnull(capabilities);
     160        const char* browserName;
     161        const char* browserVersion;
     162        g_variant_get(capabilities, "(&s&s)", &browserName, &browserVersion);
     163        g_assert_cmpstr(browserName, ==, "AutomationTestBrowser");
     164        GUniquePtr<char> versionString = toVersionString(WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION);
     165        g_assert_cmpstr(browserVersion, ==, versionString.get());
     166    }
     167
    212168    WebKitAutomationSession* requestSession(const char* sessionID)
    213169    {
    214170        auto signalID = g_signal_connect(m_webContext.get(), "automation-started", G_CALLBACK(automationStartedCallback), this);
    215         g_dbus_connection_call(m_connection.get(), nullptr, "/org/webkit/Inspector", "org.webkit.Inspector",
    216             "StartAutomationSession", g_variant_new("(sa{sv})", sessionID, nullptr), nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, nullptr,
    217             [](GObject* source, GAsyncResult* result, gpointer userData) {
    218                 auto* test = static_cast<AutomationTest*>(userData);
    219                 if (!test->m_session)
    220                     return;
    221 
    222                 GRefPtr<GVariant> capabilities = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, nullptr));
    223                 g_assert_nonnull(capabilities.get());
    224                 const char* browserName;
    225                 const char* browserVersion;
    226                 g_variant_get(capabilities.get(), "(&s&s)", &browserName, &browserVersion);
    227                 g_assert_cmpstr(browserName, ==, "AutomationTestBrowser");
    228                 GUniquePtr<char> versionString = toVersionString(WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION);
    229                 g_assert_cmpstr(browserVersion, ==, versionString.get());
    230             }, this
    231         );
     171        m_connection->sendMessage("StartAutomationSession", g_variant_new("(sa{sv})", sessionID, nullptr));
    232172        auto timeoutID = g_timeout_add(1000, [](gpointer userData) -> gboolean {
    233173            g_main_loop_quit(static_cast<GMainLoop*>(userData));
     
    248188            return;
    249189        g_assert_cmpuint(m_target.id, !=, 0);
    250         g_dbus_connection_call(m_connection.get(), nullptr, "/org/webkit/Inspector", "org.webkit.Inspector",
    251             "Setup", g_variant_new("(tt)", m_connectionID, m_target.id), nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, nullptr, nullptr, nullptr);
     190        m_connection->sendMessage("Setup", g_variant_new("(tt)", m_connectionID, m_target.id));
    252191        g_main_loop_run(m_mainLoop.get());
    253192        g_assert_true(m_target.isPaired);
     
    312251
    313252    GRefPtr<GMainLoop> m_mainLoop;
    314     GRefPtr<GDBusConnection> m_connection;
     253    RefPtr<SocketConnection> m_connection;
    315254    WebKitAutomationSession* m_session;
    316255    guint64 m_connectionID { 0 };
     
    322261    bool m_createWebViewInTabWasCalled { false };
    323262    CString m_message;
     263};
     264
     265const SocketConnection::MessageHandlers AutomationTest::s_messageHandlers = {
     266    { "DidClose", std::pair<CString, SocketConnection::MessageCallback> { { },
     267        [](SocketConnection&, GVariant*, gpointer userData) {
     268            auto& test = *static_cast<AutomationTest*>(userData);
     269            test.m_connection = nullptr;
     270        }}
     271    },
     272    { "DidStartAutomationSession", std::pair<CString, SocketConnection::MessageCallback> { "(ss)",
     273        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     274            auto& test = *static_cast<AutomationTest*>(userData);
     275            test.didStartAutomationSession(parameters);
     276        }}
     277    },
     278    { "SetTargetList", std::pair<CString, SocketConnection::MessageCallback> { "(ta(tsssb))",
     279        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     280            auto& test = *static_cast<AutomationTest*>(userData);
     281            guint64 connectionID;
     282            GUniqueOutPtr<GVariantIter> iter;
     283            g_variant_get(parameters, "(ta(tsssb))", &connectionID, &iter.outPtr());
     284            guint64 targetID;
     285            const char* type;
     286            const char* name;
     287            const char* dummy;
     288            gboolean isPaired;
     289            while (g_variant_iter_loop(iter.get(), "(t&s&s&sb)", &targetID, &type, &name, &dummy, &isPaired)) {
     290                if (!g_strcmp0(type, "Automation")) {
     291                    test.setTarget(connectionID, Target(targetID, name, isPaired));
     292                    break;
     293                }
     294            }
     295        }}
     296    },
     297    { "SendMessageToFrontend", std::pair<CString, SocketConnection::MessageCallback> { "(tts)",
     298        [](SocketConnection&, GVariant* parameters, gpointer userData) {
     299            auto& test = *static_cast<AutomationTest*>(userData);
     300            guint64 connectionID, targetID;
     301            const char* message;
     302            g_variant_get(parameters, "(tt&s)", &connectionID, &targetID, &message);
     303            test.receivedMessage(connectionID, targetID, message);
     304        }}
     305    }
    324306};
    325307
Note: See TracChangeset for help on using the changeset viewer.