Changeset 252770 in webkit
- Timestamp:
- Nov 22, 2019, 6:22:34 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 1 deleted
- 23 edited
- 2 copied
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/inspector/remote/RemoteInspector.h (modified) (3 diffs)
-
Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorGlib.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorServer.cpp (modified) (8 diffs)
-
Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorServer.h (modified) (2 diffs)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/PlatformGTK.cmake (modified) (2 diffs)
-
Source/WTF/wtf/PlatformWPE.cmake (modified) (2 diffs)
-
Source/WTF/wtf/glib/GSocketMonitor.cpp (copied) (copied from trunk/Source/WebKit/Platform/IPC/glib/GSocketMonitor.cpp ) (3 diffs)
-
Source/WTF/wtf/glib/GSocketMonitor.h (copied) (copied from trunk/Source/WebKit/Platform/IPC/glib/GSocketMonitor.h ) (4 diffs)
-
Source/WTF/wtf/glib/GTypedefs.h (modified) (1 diff)
-
Source/WTF/wtf/glib/GUniquePtr.h (modified) (1 diff)
-
Source/WTF/wtf/glib/SocketConnection.cpp (added)
-
Source/WTF/wtf/glib/SocketConnection.h (added)
-
Source/WebDriver/ChangeLog (modified) (1 diff)
-
Source/WebDriver/SessionHost.cpp (modified) (1 diff)
-
Source/WebDriver/SessionHost.h (modified) (3 diffs)
-
Source/WebDriver/glib/SessionHostGlib.cpp (modified) (12 diffs)
-
Source/WebDriver/socket/SessionHostSocket.cpp (modified) (1 diff)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/Platform/IPC/Connection.h (modified) (1 diff)
-
Source/WebKit/Platform/IPC/glib (deleted)
-
Source/WebKit/SourcesGTK.txt (modified) (1 diff)
-
Source/WebKit/SourcesWPE.txt (modified) (1 diff)
-
Source/WebKit/UIProcess/glib/RemoteInspectorClient.cpp (modified) (8 diffs)
-
Source/WebKit/UIProcess/glib/RemoteInspectorClient.h (modified) (3 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitGLib/TestAutomationSession.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r252767 r252770 1 2019-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 1 36 2019-11-22 Mark Lam <mark.lam@apple.com> 2 37 -
trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.h
r252323 r252770 48 48 #if USE(GLIB) 49 49 #include <wtf/glib/GRefPtr.h> 50 #include <wtf/glib/SocketConnection.h> 50 51 typedef GRefPtr<GVariant> TargetListing; 51 52 typedef struct _GCancellable GCancellable; 52 typedef struct _GDBusConnection GDBusConnection;53 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;54 53 #endif 55 54 … … 179 178 #endif 180 179 #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; 183 182 184 183 void receivedGetTargetListMessage(); … … 253 252 #endif 254 253 #if USE(GLIB) 255 GRefPtr<GDBusConnection> m_dbusConnection;254 RefPtr<SocketConnection> m_socketConnection; 256 255 GRefPtr<GCancellable> m_cancellable; 257 256 #endif -
trunk/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorGlib.cpp
r251227 r252770 37 37 #include <wtf/glib/GUniquePtr.h> 38 38 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 44 39 namespace Inspector { 45 40 … … 66 61 m_cancellable = adoptGRef(g_cancellable_new()); 67 62 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) { 77 66 RemoteInspector* inspector = static_cast<RemoteInspector*>(userData); 78 67 GUniqueOutPtr<GError> error; 79 if (GRefPtr<G DBusConnection> 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)); 81 70 else if (!g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) 82 71 g_warning("RemoteInspector failed to connect to inspector server at: %s: %s", g_getenv("WEBKIT_INSPECTOR_SERVER"), error->message); 83 }, this);72 }, this); 84 73 } 85 74 … … 101 90 102 91 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 95 const 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); 132 111 guint64 targetID; 133 112 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); 137 119 guint64 targetID; 138 120 const char* message; 139 121 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); 143 128 guint64 targetID; 144 129 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 } 155 133 }; 156 134 157 void RemoteInspector::setupConnection( GRefPtr<GDBusConnection>&& connection)135 void RemoteInspector::setupConnection(Ref<SocketConnection>&& connection) 158 136 { 159 137 LockHolder lock(m_mutex); 160 138 161 139 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); 172 143 if (!m_targetMap.isEmpty()) 173 144 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);182 145 } 183 146 … … 206 169 void RemoteInspector::pushListingsNow() 207 170 { 208 if (!m_ dbusConnection)171 if (!m_socketConnection) 209 172 return; 210 173 … … 218 181 g_variant_builder_close(&builder); 219 182 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)); 224 184 } 225 185 226 186 void RemoteInspector::pushListingsSoon() 227 187 { 228 if (!m_ dbusConnection)188 if (!m_socketConnection) 229 189 return; 230 190 … … 247 207 ASSERT(m_automaticInspectionPaused); 248 208 ASSERT(m_automaticInspectionCandidateTargetIdentifier); 249 ASSERT(m_ dbusConnection);209 ASSERT(m_socketConnection); 250 210 // FIXME: Implement automatic inspection. 251 211 } … … 254 214 { 255 215 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())); 264 220 } 265 221 -
trunk/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorServer.cpp
r252323 r252770 34 34 #include <wtf/glib/GUniquePtr.h> 35 35 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 43 36 namespace Inspector { 44 37 … … 47 40 static uint64_t connectionID = 0; 48 41 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>";88 42 } 89 43 … … 139 93 return capabilities; 140 94 } 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 96 const 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); 149 112 GRefPtr<GVariant> backendCommandsHash; 150 113 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); 154 121 guint64 connectionID, targetID; 155 122 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); 159 129 guint64 connectionID, targetID; 160 130 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); 164 137 guint64 targetID; 165 138 const char* message; 166 139 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); 170 146 guint64 connectionID, targetID; 171 147 const char* message; 172 148 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); 176 155 const char* sessionID; 177 156 GRefPtr<GVariant> sessionCapabilities; 178 157 g_variant_get(parameters, "(&s@a{sv})", &sessionID, &sessionCapabilities.outPtr()); 179 158 auto capabilities = processSessionCapabilities(sessionCapabilities.get()); 180 inspectorServer ->startAutomationSession(connection, sessionID, capabilities);159 inspectorServer.startAutomationSession(connection, sessionID, capabilities); 181 160 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)", 183 162 clientCapabilities ? clientCapabilities->browserName.utf8().data() : "", 184 163 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 } 194 166 }; 195 167 … … 202 174 RemoteInspectorServer::~RemoteInspectorServer() 203 175 { 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); 218 178 } 219 179 220 180 bool RemoteInspectorServer::start(const char* address, unsigned port) 221 181 { 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)); 227 186 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); 232 189 return false; 233 190 } 234 191 235 g_signal_connect(m_dbusServer.get(), "new-connection", G_CALLBACK(newConnectionCallback), this);236 g_dbus_server_start(m_dbusServer.get());237 238 192 return true; 239 193 } 240 194 241 gboolean RemoteInspectorServer:: newConnectionCallback(GDBusServer*, GDBusConnection* connection, RemoteInspectorServer* inspectorServer)242 { 243 inspectorServer-> newConnection(connection);195 gboolean RemoteInspectorServer::incomingConnectionCallback(GSocketService*, GSocketConnection* connection, GObject*, RemoteInspectorServer* inspectorServer) 196 { 197 inspectorServer->incomingConnection(SocketConnection::create(GRefPtr<GSocketConnection>(connection), s_messageHandlers, inspectorServer)); 244 198 return TRUE; 245 199 } 246 200 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); 201 void RemoteInspectorServer::incomingConnection(Ref<SocketConnection>&& connection) 202 { 203 ASSERT(!m_connections.contains(connection.ptr())); 204 m_connections.add(WTFMove(connection)); 205 } 206 207 void RemoteInspectorServer::setTargetList(SocketConnection& remoteInspectorConnection, GVariant* parameters) 208 { 209 ASSERT(m_connections.contains(&remoteInspectorConnection)); 210 auto addResult = m_remoteInspectorConnectionToIDMap.add(&remoteInspectorConnection, 0); 275 211 if (addResult.isNewEntry) { 276 212 addResult.iterator->value = generateConnectionID(); 277 m_idToRemoteInspectorConnectionMap.add(addResult.iterator->value, remoteInspectorConnection);213 m_idToRemoteInspectorConnectionMap.add(addResult.iterator->value, &remoteInspectorConnection); 278 214 } 279 215 … … 281 217 GRefPtr<GVariant> targetList; 282 218 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; 284 220 if (!clientConnection) 285 221 return; 286 222 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 226 GVariant* RemoteInspectorServer::setupInspectorClient(SocketConnection& clientConnection, const char* clientBackendCommandsHash) 302 227 { 303 228 ASSERT(!m_clientConnection); 304 m_clientConnection = clientConnection; 305 g_signal_connect(m_clientConnection.get(), "closed", G_CALLBACK(clientConnectionClosedCallback), this); 229 m_clientConnection = &clientConnection; 306 230 307 231 GVariant* backendCommands; … … 313 237 314 238 // 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); 324 241 325 242 return backendCommands; 326 243 } 327 244 328 void RemoteInspectorServer::setup( GDBusConnection*clientConnection, uint64_t connectionID, uint64_t targetID)329 { 330 ASSERT(m_clientConnection .get() == clientConnection || m_automationConnection.get() ==clientConnection);245 void RemoteInspectorServer::setup(SocketConnection& clientConnection, uint64_t connectionID, uint64_t targetID) 246 { 247 ASSERT(m_clientConnection == &clientConnection || m_automationConnection == &clientConnection); 331 248 ASSERT(m_idToRemoteInspectorConnectionMap.contains(connectionID)); 332 if ( clientConnection == m_automationConnection.get()) {249 if (&clientConnection == m_automationConnection) { 333 250 m_automationTargets.add(std::make_pair(connectionID, targetID)); 334 251 RemoteInspector::singleton().setup(targetID); … … 337 254 338 255 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 259 void RemoteInspectorServer::close(SocketConnection& clientConnection, uint64_t connectionID, uint64_t targetID) 260 { 261 ASSERT(m_clientConnection == &clientConnection || m_automationConnection == &clientConnection); 352 262 ASSERT(m_idToRemoteInspectorConnectionMap.contains(connectionID)); 353 if ( clientConnection == m_automationConnection.get()) {263 if (&clientConnection == m_automationConnection) { 354 264 // FIXME: automation. 355 265 return; … … 357 267 358 268 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)); 367 270 m_inspectionTargets.remove(std::make_pair(connectionID, targetID)); 368 271 } 369 272 370 void RemoteInspectorServer::c lientConnectionClosed(GDBusConnection*clientConnection)371 { 372 ASSERT(m_c lientConnection.get() == clientConnection || m_automationConnection.get() == clientConnection);373 if ( clientConnection == m_automationConnection.get()) {273 void RemoteInspectorServer::connectionDidClose(SocketConnection& clientConnection) 274 { 275 ASSERT(m_connections.contains(&clientConnection)); 276 if (&clientConnection == m_automationConnection) { 374 277 for (auto connectionTargetPair : m_automationTargets) 375 278 close(clientConnection, connectionTargetPair.first, connectionTargetPair.second); 376 279 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); 390 286 m_idToRemoteInspectorConnectionMap.remove(connectionID); 391 287 // Send an empty target list to the clients. 392 Vector< GRefPtr<GDBusConnection>> clientConnections = { m_automationConnection, m_clientConnection };393 for (auto & clientConnection : clientConnections) {394 if (!c lientConnection)288 Vector<SocketConnection*> clientConnections = { m_automationConnection, m_clientConnection }; 289 for (auto* connection : clientConnections) { 290 if (!connection) 395 291 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))); 403 293 } 404 294 } 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 298 void RemoteInspectorServer::sendMessageToBackend(SocketConnection& clientConnection, uint64_t connectionID, uint64_t targetID, const char* message) 299 { 300 ASSERT(m_clientConnection == &clientConnection || m_automationConnection == &clientConnection); 411 301 ASSERT(m_idToRemoteInspectorConnectionMap.contains(connectionID)); 412 if ( clientConnection == m_automationConnection.get()) {302 if (&clientConnection == m_automationConnection) { 413 303 RemoteInspector::singleton().sendMessageToTarget(targetID, message); 414 304 return; 415 305 } 416 306 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 310 void 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); 433 316 auto connectionTargetPair = std::make_pair(connectionID, targetID); 434 317 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; 436 319 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 323 void RemoteInspectorServer::startAutomationSession(SocketConnection& automationConnection, const char* sessionID, const RemoteInspector::Client::SessionCapabilities& capabilities) 448 324 { 449 325 if (!m_automationConnection) 450 m_automationConnection = automationConnection;451 ASSERT(m_automationConnection .get() ==automationConnection);326 m_automationConnection = &automationConnection; 327 ASSERT(m_automationConnection == &automationConnection); 452 328 453 329 RemoteInspector::singleton().requestAutomationSession(sessionID, capabilities); -
trunk/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorServer.h
r232833 r252770 32 32 #include <wtf/HashSet.h> 33 33 #include <wtf/glib/GRefPtr.h> 34 #include <wtf/glib/SocketConnection.h> 34 35 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; 36 typedef struct _GSocketConnection GSocketConnection; 37 typedef struct _GSocketService GSocketService; 42 38 43 39 namespace Inspector { … … 49 45 50 46 bool start(const char* address, unsigned port); 51 bool isRunning() const { return !!m_ dbusServer; }47 bool isRunning() const { return !!m_service; } 52 48 53 49 private: 54 GDBusInterfaceInfo* interfaceInfo(); 50 static gboolean incomingConnectionCallback(GSocketService*, GSocketConnection*, GObject*, RemoteInspectorServer*); 51 void incomingConnection(Ref<SocketConnection>&&); 55 52 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&); 60 62 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 }; 80 69 HashSet<std::pair<uint64_t, uint64_t>> m_inspectionTargets; 81 GRefPtr<GDBusConnection> m_automationConnection;82 70 HashSet<std::pair<uint64_t, uint64_t>> m_automationTargets; 83 71 }; -
trunk/Source/WTF/ChangeLog
r252754 r252770 1 2019-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 1 32 2019-11-21 Yusuke Suzuki <ysuzuki@apple.com> 2 33 -
trunk/Source/WTF/wtf/PlatformGTK.cmake
r250129 r252770 5 5 glib/GMutexLocker.h 6 6 glib/GRefPtr.h 7 glib/GSocketMonitor.h 7 8 glib/GTypedefs.h 8 9 glib/GUniquePtr.h 9 10 glib/RunLoopSourcePriority.h 11 glib/SocketConnection.h 10 12 glib/WTFGType.h 11 13 ) … … 25 27 glib/GLibUtilities.cpp 26 28 glib/GRefPtr.cpp 29 glib/GSocketMonitor.cpp 27 30 glib/RunLoopGLib.cpp 31 glib/SocketConnection.cpp 28 32 glib/URLGLib.cpp 29 33 -
trunk/Source/WTF/wtf/PlatformWPE.cmake
r250129 r252770 3 3 glib/GMutexLocker.h 4 4 glib/GRefPtr.h 5 glib/GSocketMonitor.h 5 6 glib/GTypedefs.h 6 7 glib/GUniquePtr.h 7 8 glib/RunLoopSourcePriority.h 9 glib/SocketConnection.h 8 10 glib/WTFGType.h 9 11 … … 20 22 glib/GLibUtilities.cpp 21 23 glib/GRefPtr.cpp 24 glib/GSocketMonitor.cpp 22 25 glib/RunLoopGLib.cpp 26 glib/SocketConnection.cpp 23 27 glib/URLGLib.cpp 24 28 -
trunk/Source/WTF/wtf/glib/GSocketMonitor.cpp
r252769 r252770 30 30 #include <wtf/glib/RunLoopSourcePriority.h> 31 31 32 namespace IPC{32 namespace WTF { 33 33 34 34 GSocketMonitor::~GSocketMonitor() … … 44 44 } 45 45 46 void GSocketMonitor::start(GSocket* socket, GIOCondition condition, RunLoop& runLoop, Function<gboolean (GIOCondition)>&& callback)46 void GSocketMonitor::start(GSocket* socket, GIOCondition condition, RunLoop& runLoop, Function<gboolean(GIOCondition)>&& callback) 47 47 { 48 48 stop(); … … 69 69 } 70 70 71 } // namespace IPC71 } // namespace WTF -
trunk/Source/WTF/wtf/glib/GSocketMonitor.h
r252769 r252770 24 24 */ 25 25 26 #ifndef GSocketMonitor_h 27 #define GSocketMonitor_h 26 #pragma once 28 27 29 28 #include <glib.h> … … 35 34 typedef struct _GSocket GSocket; 36 35 37 namespace IPC{36 namespace WTF { 38 37 39 38 class GSocketMonitor { … … 43 42 ~GSocketMonitor(); 44 43 45 void start(GSocket*, GIOCondition, RunLoop&, Function<gboolean (GIOCondition)>&&);44 void start(GSocket*, GIOCondition, RunLoop&, Function<gboolean(GIOCondition)>&&); 46 45 void stop(); 46 bool isActive() const { return !!m_source; } 47 47 48 48 private: … … 51 51 GRefPtr<GSource> m_source; 52 52 GRefPtr<GCancellable> m_cancellable; 53 Function<gboolean (GIOCondition)> m_callback;53 Function<gboolean(GIOCondition)> m_callback; 54 54 }; 55 55 56 } // namespace IPC56 } // namespace WTF 57 57 58 #endif // GSocketMonitor_h 58 using WTF::GSocketMonitor; -
trunk/Source/WTF/wtf/glib/GTypedefs.h
r246632 r252770 63 63 typedef struct _GVariantBuilder GVariantBuilder; 64 64 typedef struct _GVariantIter GVariantIter; 65 typedef struct _GVariantType GVariantType; 65 66 typedef union _GdkEvent GdkEvent; 66 67 typedef struct _GTimer GTimer; -
trunk/Source/WTF/wtf/glib/GUniquePtr.h
r247294 r252770 47 47 macro(GKeyFile, g_key_file_free) \ 48 48 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) 50 51 51 52 #define WTF_DEFINE_GPTR_DELETER(typeName, deleterFunc) \ -
trunk/Source/WebDriver/ChangeLog
r252408 r252770 1 2019-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 1 28 2019-11-13 Carlos Garcia Campos <cgarcia@igalia.com> 2 29 -
trunk/Source/WebDriver/SessionHost.cpp
r233122 r252770 56 56 } 57 57 messageBuilder.append('}'); 58 sendMessageToBackend( sequenceID,messageBuilder.toString());58 sendMessageToBackend(messageBuilder.toString()); 59 59 60 60 return sequenceID; -
trunk/Source/WebDriver/SessionHost.h
r239427 r252770 32 32 #if USE(GLIB) 33 33 #include <wtf/glib/GRefPtr.h> 34 typedef struct _GDBusConnection GDBusConnection; 35 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable; 34 #include <wtf/glib/SocketConnection.h> 36 35 typedef struct _GSubprocess GSubprocess; 37 36 #endif … … 72 71 73 72 void inspectorDisconnected(); 74 void sendMessageToBackend( long,const String&);73 void sendMessageToBackend(const String&); 75 74 void dispatchMessage(const String&); 76 75 77 76 #if USE(GLIB) 78 static void dbusConnectionClosedCallback(SessionHost*);79 static const GDBusInterfaceVTable s_interfaceVTable;77 static const SocketConnection::MessageHandlers s_messageHandlers; 78 void connectionDidClose(); 80 79 void launchBrowser(Function<void (Optional<String> error)>&&); 81 80 void connectToBrowser(std::unique_ptr<ConnectToBrowserAsyncData>&&); 82 81 bool matchCapabilities(GVariant*); 83 82 bool buildSessionCapabilities(GVariantBuilder*) const; 84 void setupConnection(GRefPtr<GDBusConnection>&&); 83 void setupConnection(Ref<SocketConnection>&&); 84 void didStartAutomationSession(GVariant*); 85 85 void setTargetList(uint64_t connectionID, Vector<Target>&&); 86 86 void sendMessageToFrontend(uint64_t connectionID, uint64_t targetID, const char* message); … … 98 98 Function<void (bool, Optional<String>)> m_startSessionCompletionHandler; 99 99 GRefPtr<GSubprocess> m_browser; 100 GRefPtr<GDBusConnection> m_dbusConnection;100 RefPtr<SocketConnection> m_socketConnection; 101 101 GRefPtr<GCancellable> m_cancellable; 102 102 #endif -
trunk/Source/WebDriver/glib/SessionHostGlib.cpp
r252323 r252770 33 33 #include <wtf/glib/GUniquePtr.h> 34 34 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 40 35 namespace WebDriver { 41 36 42 37 SessionHost::~SessionHost() 43 38 { 44 if (m_dbusConnection)45 g_signal_handlers_disconnect_matched(m_dbusConnection.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);46 39 g_cancellable_cancel(m_cancellable.get()); 40 if (m_socketConnection) 41 m_socketConnection->close(); 47 42 if (m_browser) 48 43 g_subprocess_force_exit(m_browser.get()); 49 44 } 50 45 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")) { 46 const 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); 71 62 guint64 connectionID; 72 63 GUniqueOutPtr<GVariantIter> iter; … … 84 75 targetList.uncheckedAppend({ targetID, name, static_cast<bool>(isPaired) }); 85 76 } 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); 89 83 guint64 connectionID, targetID; 90 84 const char* message; 91 85 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 } 102 89 }; 103 90 … … 109 96 bool SessionHost::isConnected() const 110 97 { 111 // Session is connected when launching or when dbusconnection 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()); 113 100 } 114 101 115 102 struct ConnectToBrowserAsyncData { 116 103 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) 118 105 : sessionHost(sessionHost) 119 , dbusAddress(WTFMove(dbusAddress))106 , inspectorAddress(WTFMove(inspectorAddress)) 120 107 , cancellable(cancellable) 121 108 , completionHandler(WTFMove(completionHandler)) … … 124 111 125 112 SessionHost* sessionHost; 126 GUniquePtr<char> dbusAddress;113 GUniquePtr<char> inspectorAddress; 127 114 GRefPtr<GCancellable> cancellable; 128 115 Function<void (Optional<String> error)> completionHandler; … … 174 161 }, this); 175 162 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))); 178 164 } 179 165 … … 188 174 return; 189 175 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) { 192 179 auto data = std::unique_ptr<ConnectToBrowserAsyncData>(static_cast<ConnectToBrowserAsyncData*>(userData)); 193 180 GUniqueOutPtr<GError> error; 194 GRefPtr<G DBusConnection> 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())); 195 182 if (!connection) { 196 183 if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) … … 205 192 return; 206 193 } 207 data->sessionHost->setupConnection( WTFMove(connection));194 data->sessionHost->setupConnection(SocketConnection::create(WTFMove(connection), s_messageHandlers, data->sessionHost)); 208 195 data->completionHandler(WTF::nullopt); 209 196 }, data); … … 211 198 } 212 199 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); 200 void SessionHost::connectionDidClose() 201 { 202 m_browser = nullptr; 203 inspectorDisconnected(); 204 m_socketConnection = nullptr; 205 } 206 207 void SessionHost::setupConnection(Ref<SocketConnection>&& connection) 208 { 209 ASSERT(!m_socketConnection); 230 210 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); 240 212 } 241 213 … … 328 300 void SessionHost::startAutomationSession(Function<void (bool, Optional<String>)>&& completionHandler) 329 301 { 330 ASSERT(m_ dbusConnection);302 ASSERT(m_socketConnection); 331 303 ASSERT(!m_startSessionCompletionHandler); 332 304 m_startSessionCompletionHandler = WTFMove(completionHandler); 333 305 m_sessionID = createCanonicalUUIDString(); 334 306 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 310 void 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); 361 317 } 362 318 … … 372 328 m_target = Target(); 373 329 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(); 376 332 m_connectionID = 0; 377 333 } … … 391 347 392 348 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)); 400 350 401 351 auto startSessionCompletionHandler = std::exchange(m_startSessionCompletionHandler, nullptr); … … 410 360 } 411 361 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); 362 void SessionHost::sendMessageToBackend(const String& message) 363 { 364 ASSERT(m_socketConnection); 421 365 ASSERT(m_connectionID); 422 366 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())); 445 368 } 446 369 -
trunk/Source/WebDriver/socket/SessionHostSocket.cpp
r245567 r252770 46 46 } 47 47 48 void SessionHost::sendMessageToBackend( long messageID,const String& message)48 void SessionHost::sendMessageToBackend(const String& message) 49 49 { 50 50 } -
trunk/Source/WebKit/ChangeLog
r252762 r252770 1 2019-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 1 23 2019-11-21 Jer Noble <jer.noble@apple.com> 2 24 -
trunk/Source/WebKit/Platform/IPC/Connection.h
r252636 r252770 52 52 53 53 #if USE(GLIB) 54 #include "GSocketMonitor.h"54 #include <wtf/glib/GSocketMonitor.h> 55 55 #endif 56 56 -
trunk/Source/WebKit/SourcesGTK.txt
r252234 r252770 45 45 NetworkProcess/webrtc/NetworkRTCSocket.cpp 46 46 47 Platform/IPC/glib/GSocketMonitor.cpp48 47 Platform/IPC/unix/AttachmentUnix.cpp 49 48 Platform/IPC/unix/ConnectionUnix.cpp -
trunk/Source/WebKit/SourcesWPE.txt
r251181 r252770 44 44 NetworkProcess/webrtc/NetworkRTCProvider.cpp 45 45 NetworkProcess/webrtc/NetworkRTCSocket.cpp 46 47 Platform/IPC/glib/GSocketMonitor.cpp48 46 49 47 Platform/IPC/unix/AttachmentUnix.cpp -
trunk/Source/WebKit/UIProcess/glib/RemoteInspectorClient.cpp
r251227 r252770 35 35 #include <wtf/text/Base64.h> 36 36 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 42 37 namespace WebKit { 43 38 … … 99 94 }; 100 95 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")) { 96 const 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); 121 114 guint64 connectionID; 122 115 GUniqueOutPtr<GVariantIter> iter; … … 134 127 targetList.uncheckedAppend({ targetID, type, name, url }); 135 128 } 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); 139 135 guint64 connectionID, targetID; 140 136 const char* message; 141 137 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 } 153 141 }; 154 142 … … 158 146 , m_cancellable(adoptGRef(g_cancellable_new())) 159 147 { 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) { 164 151 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())); 214 153 if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) 215 154 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); 219 161 } 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 165 RemoteInspectorClient::~RemoteInspectorClient() 166 { 167 g_cancellable_cancel(m_cancellable.get()); 168 } 169 170 void 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()))); 226 174 } 227 175 … … 238 186 } 239 187 240 void RemoteInspectorClient::connectionClosed() 241 { 242 g_cancellable_cancel(m_cancellable.get()); 188 void RemoteInspectorClient::connectionDidClose() 189 { 243 190 m_targets.clear(); 244 191 m_inspectorProxyMap.clear(); 245 m_ dbusConnection = nullptr;192 m_socketConnection = nullptr; 246 193 m_observer.connectionClosed(*this); 247 194 } … … 257 204 } 258 205 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)); 267 207 addResult.iterator->value->load(); 268 208 } … … 270 210 void RemoteInspectorClient::sendMessageToBackend(uint64_t connectionID, uint64_t targetID, const String& message) 271 211 { 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())); 279 213 } 280 214 … … 282 216 { 283 217 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)); 291 219 m_inspectorProxyMap.remove(std::make_pair(connectionID, targetID)); 292 220 } -
trunk/Source/WebKit/UIProcess/glib/RemoteInspectorClient.h
r215862 r252770 31 31 #include <wtf/Vector.h> 32 32 #include <wtf/glib/GRefPtr.h> 33 #include <wtf/glib/SocketConnection.h> 33 34 #include <wtf/text/WTFString.h> 34 35 35 36 typedef struct _GCancellable GCancellable; 36 typedef struct _GDBusConnection GDBusConnection;37 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;38 37 39 38 namespace WebKit { … … 73 72 74 73 private: 75 static void connectionClosedCallback(GDBusConnection*, gboolean remotePeerVanished, GError*, RemoteInspectorClient*);76 void setupConnection( GRefPtr<GDBusConnection>&&);77 void connection Closed();74 static const SocketConnection::MessageHandlers s_messageHandlers; 75 void setupConnection(Ref<SocketConnection>&&); 76 void connectionDidClose(); 78 77 79 static const GDBusInterfaceVTable s_interfaceVTable;80 78 void setBackendCommands(const char*); 81 79 void setTargetList(uint64_t connectionID, Vector<Target>&&); … … 85 83 String m_backendCommandsURL; 86 84 RemoteInspectorObserver& m_observer; 87 GRefPtr<GDBusConnection> m_dbusConnection;85 RefPtr<SocketConnection> m_socketConnection; 88 86 GRefPtr<GCancellable> m_cancellable; 89 87 HashMap<uint64_t, Vector<Target>> m_targets; -
trunk/Tools/ChangeLog
r252743 r252770 1 2019-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 1 12 2019-11-21 Wenson Hsieh <wenson_hsieh@apple.com> 2 13 -
trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestAutomationSession.cpp
r252356 r252770 23 23 #include <gio/gio.h> 24 24 #include <wtf/UUID.h> 25 #include <wtf/glib/SocketConnection.h> 25 26 #include <wtf/text/StringBuilder.h> 26 27 … … 29 30 MAKE_GLIB_TEST_FIXTURE(AutomationTest); 30 31 32 static const SocketConnection::MessageHandlers s_messageHandlers; 33 31 34 AutomationTest() 32 35 : m_mainLoop(adoptGRef(g_main_loop_new(nullptr, TRUE))) 33 36 { 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); 39 42 g_main_loop_run(m_mainLoop.get()); 40 43 } … … 58 61 }; 59 62 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()); 121 66 m_connection = WTFMove(connection); 122 registerDBusObject();123 67 g_main_loop_quit(m_mainLoop.get()); 124 68 } … … 156 100 } 157 101 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())); 161 103 } 162 104 … … 210 152 } 211 153 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 212 168 WebKitAutomationSession* requestSession(const char* sessionID) 213 169 { 214 170 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)); 232 172 auto timeoutID = g_timeout_add(1000, [](gpointer userData) -> gboolean { 233 173 g_main_loop_quit(static_cast<GMainLoop*>(userData)); … … 248 188 return; 249 189 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)); 252 191 g_main_loop_run(m_mainLoop.get()); 253 192 g_assert_true(m_target.isPaired); … … 312 251 313 252 GRefPtr<GMainLoop> m_mainLoop; 314 GRefPtr<GDBusConnection> m_connection;253 RefPtr<SocketConnection> m_connection; 315 254 WebKitAutomationSession* m_session; 316 255 guint64 m_connectionID { 0 }; … … 322 261 bool m_createWebViewInTabWasCalled { false }; 323 262 CString m_message; 263 }; 264 265 const 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 } 324 306 }; 325 307
Note:
See TracChangeset
for help on using the changeset viewer.