Procházet zdrojové kódy

WebContent: Add a very-empty WebDriver IPC class to WebContent

This just sets up the infrastructure for the WebContent process to house
WebDriver IPCs, and adds an IPC for WebContent to create the WebDriver
connection. The WebDriverConnection class inside WebContent ultimately
will contain most of what is currently in WebDriver::Session (so the
copyright attributions are copied here as well).

The socket created by WebDriver is currently /tmp/browser_webdriver
(formatted with some IDs). This will be moved to the /tmp/webdriver
folder, as WebDriver will create multiple sockets to communicate with
both Browser and WebContent as the IPCs are iteratively moved to
WebContent. That path is unveiled here, though it is unused as of this
commit.
Timothy Flynn před 2 roky
rodič
revize
6b014489d4

+ 6 - 0
Userland/Services/WebContent/CMakeLists.txt

@@ -7,18 +7,24 @@ serenity_component(
 compile_ipc(WebContentServer.ipc WebContentServerEndpoint.h)
 compile_ipc(WebContentClient.ipc WebContentClientEndpoint.h)
 
+compile_ipc(WebDriverClient.ipc WebDriverClientEndpoint.h)
+compile_ipc(WebDriverServer.ipc WebDriverServerEndpoint.h)
+
 set(SOURCES
     ConnectionFromClient.cpp
     ConsoleGlobalObject.cpp
     ImageCodecPluginSerenity.cpp
     PageHost.cpp
     WebContentConsoleClient.cpp
+    WebDriverConnection.cpp
     main.cpp
 )
 
 set(GENERATED_SOURCES
     WebContentClientEndpoint.h
     WebContentServerEndpoint.h
+    WebDriverClientEndpoint.h
+    WebDriverServerEndpoint.h
 )
 
 serenity_bin(WebContent)

+ 9 - 0
Userland/Services/WebContent/ConnectionFromClient.cpp

@@ -69,6 +69,15 @@ Web::Page const& ConnectionFromClient::page() const
     return m_page_host->page();
 }
 
+void ConnectionFromClient::connect_to_webdriver(String const& webdriver_ipc_path)
+{
+    // FIXME: Propogate this error back to the browser.
+    if (auto result = m_page_host->connect_to_webdriver(webdriver_ipc_path); result.is_error())
+        dbgln("Unable to connect to the WebDriver process: {}", result.error());
+    else
+        set_is_webdriver_active(true);
+}
+
 void ConnectionFromClient::update_system_theme(Core::AnonymousBuffer const& theme_buffer)
 {
     Gfx::set_system_theme(theme_buffer);

+ 1 - 0
Userland/Services/WebContent/ConnectionFromClient.h

@@ -45,6 +45,7 @@ private:
     Web::Page& page();
     Web::Page const& page() const;
 
+    virtual void connect_to_webdriver(String const& webdriver_ipc_path) override;
     virtual void update_system_theme(Core::AnonymousBuffer const&) override;
     virtual void update_system_fonts(String const&, String const&, String const&) override;
     virtual void update_screen_rects(Vector<Gfx::IntRect> const&, u32) override;

+ 1 - 0
Userland/Services/WebContent/Forward.h

@@ -12,5 +12,6 @@ class ConnectionFromClient;
 class ConsoleGlobalObject;
 class PageHost;
 class WebContentConsoleClient;
+class WebDriverConnection;
 
 }

+ 10 - 0
Userland/Services/WebContent/PageHost.cpp

@@ -16,6 +16,7 @@
 #include <LibWeb/Painting/PaintableBox.h>
 #include <LibWeb/Platform/Timer.h>
 #include <WebContent/WebContentClientEndpoint.h>
+#include <WebContent/WebDriverConnection.h>
 
 namespace WebContent {
 
@@ -30,6 +31,8 @@ PageHost::PageHost(ConnectionFromClient& client)
     });
 }
 
+PageHost::~PageHost() = default;
+
 void PageHost::set_has_focus(bool has_focus)
 {
     m_has_focus = has_focus;
@@ -86,6 +89,13 @@ void PageHost::set_window_size(Gfx::IntSize const& size)
     page().set_window_size(size);
 }
 
+ErrorOr<void> PageHost::connect_to_webdriver(String const& webdriver_ipc_path)
+{
+    VERIFY(!m_webdriver);
+    m_webdriver = TRY(WebDriverConnection::connect(*this, webdriver_ipc_path));
+    return {};
+}
+
 Web::Layout::InitialContainingBlock* PageHost::layout_root()
 {
     auto* document = page().top_level_browsing_context().active_document();

+ 6 - 1
Userland/Services/WebContent/PageHost.h

@@ -9,6 +9,7 @@
 
 #include <LibGfx/Rect.h>
 #include <LibWeb/Page/Page.h>
+#include <WebContent/Forward.h>
 
 namespace WebContent {
 
@@ -20,7 +21,7 @@ class PageHost final : public Web::PageClient {
 
 public:
     static NonnullOwnPtr<PageHost> create(ConnectionFromClient& client) { return adopt_own(*new PageHost(client)); }
-    virtual ~PageHost() = default;
+    virtual ~PageHost();
 
     Web::Page& page() { return *m_page; }
     Web::Page const& page() const { return *m_page; }
@@ -40,6 +41,8 @@ public:
 
     Gfx::IntSize const& content_size() const { return m_content_size; }
 
+    ErrorOr<void> connect_to_webdriver(String const& webdriver_ipc_path);
+
 private:
     // ^PageClient
     virtual Gfx::Palette palette() const override;
@@ -90,6 +93,8 @@ private:
     RefPtr<Web::Platform::Timer> m_invalidation_coalescing_timer;
     Gfx::IntRect m_invalidation_rect;
     Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto };
+
+    RefPtr<WebDriverConnection> m_webdriver;
 };
 
 }

+ 2 - 0
Userland/Services/WebContent/WebContentServer.ipc

@@ -9,6 +9,8 @@
 
 endpoint WebContentServer
 {
+    connect_to_webdriver(String webdriver_ipc_path) =|
+
     update_system_theme(Core::AnonymousBuffer theme_buffer) =|
     update_system_fonts(String default_font_query, String fixed_width_font_query, String window_title_font_query) =|
     update_screen_rects(Vector<Gfx::IntRect> rects, u32 main_screen_index) =|

+ 2 - 0
Userland/Services/WebContent/WebDriverClient.ipc

@@ -0,0 +1,2 @@
+endpoint WebDriverClient {
+}

+ 37 - 0
Userland/Services/WebContent/WebDriverConnection.cpp

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2022, Florent Castelli <florent.castelli@gmail.com>
+ * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
+ * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org>
+ * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/JsonObject.h>
+#include <AK/JsonValue.h>
+#include <AK/Vector.h>
+#include <LibWeb/HTML/BrowsingContext.h>
+#include <LibWeb/Page/Page.h>
+#include <LibWeb/Platform/Timer.h>
+#include <WebContent/PageHost.h>
+#include <WebContent/WebDriverConnection.h>
+
+namespace WebContent {
+
+ErrorOr<NonnullRefPtr<WebDriverConnection>> WebDriverConnection::connect(PageHost& page_host, String const& webdriver_ipc_path)
+{
+    dbgln_if(WEBDRIVER_DEBUG, "Trying to connect to {}", webdriver_ipc_path);
+    auto socket = TRY(Core::Stream::LocalSocket::connect(webdriver_ipc_path));
+
+    dbgln_if(WEBDRIVER_DEBUG, "Connected to WebDriver");
+    return adopt_nonnull_ref_or_enomem(new (nothrow) WebDriverConnection(move(socket), page_host));
+}
+
+WebDriverConnection::WebDriverConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, PageHost& page_host)
+    : IPC::ConnectionToServer<WebDriverClientEndpoint, WebDriverServerEndpoint>(*this, move(socket))
+    , m_page_host(page_host)
+{
+}
+
+}

+ 35 - 0
Userland/Services/WebContent/WebDriverConnection.h

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022, Florent Castelli <florent.castelli@gmail.com>
+ * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibIPC/ConnectionToServer.h>
+#include <LibWeb/WebDriver/Response.h>
+#include <WebContent/Forward.h>
+#include <WebContent/WebDriverClientEndpoint.h>
+#include <WebContent/WebDriverServerEndpoint.h>
+
+namespace WebContent {
+
+class WebDriverConnection final
+    : public IPC::ConnectionToServer<WebDriverClientEndpoint, WebDriverServerEndpoint> {
+    C_OBJECT_ABSTRACT(WebDriverConnection)
+
+public:
+    static ErrorOr<NonnullRefPtr<WebDriverConnection>> connect(PageHost& page_host, String const& webdriver_ipc_path);
+    virtual ~WebDriverConnection() = default;
+
+private:
+    WebDriverConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, PageHost& page_host);
+
+    virtual void die() override { }
+
+    PageHost& m_page_host;
+};
+
+}

+ 2 - 0
Userland/Services/WebContent/WebDriverServer.ipc

@@ -0,0 +1,2 @@
+endpoint WebDriverServer {
+}

+ 6 - 0
Userland/Services/WebContent/main.cpp

@@ -7,6 +7,7 @@
 #include "ImageCodecPluginSerenity.h"
 #include <LibCore/EventLoop.h>
 #include <LibCore/LocalServer.h>
+#include <LibCore/Stream.h>
 #include <LibCore/System.h>
 #include <LibIPC/SingleServer.h>
 #include <LibMain/Main.h>
@@ -23,6 +24,11 @@ ErrorOr<int> serenity_main(Main::Arguments)
 {
     Core::EventLoop event_loop;
     TRY(Core::System::pledge("stdio recvfd sendfd accept unix rpath"));
+
+    // This must be first; we can't check if /tmp/webdriver exists once we've unveiled other paths.
+    if (Core::Stream::File::exists("/tmp/webdriver"sv))
+        TRY(Core::System::unveil("/tmp/webdriver", "rw"));
+
     TRY(Core::System::unveil("/sys/kernel/processes", "r"));
     TRY(Core::System::unveil("/res", "r"));
     TRY(Core::System::unveil("/etc/timezone", "r"));