diff --git a/Userland/Applications/Browser/CMakeLists.txt b/Userland/Applications/Browser/CMakeLists.txt index e5956a02e98..caa300669af 100644 --- a/Userland/Applications/Browser/CMakeLists.txt +++ b/Userland/Applications/Browser/CMakeLists.txt @@ -5,6 +5,9 @@ serenity_component( DEPENDS BrowserSettings ImageDecoder RequestServer WebContent WebSocket ) +compile_ipc(WebDriverSessionServer.ipc WebDriverSessionServerEndpoint.h) +compile_ipc(WebDriverSessionClient.ipc WebDriverSessionClientEndpoint.h) + compile_gml(BrowserWindow.gml BrowserWindowGML.h browser_window_gml) compile_gml(EditBookmark.gml EditBookmarkGML.h edit_bookmark_gml) compile_gml(StorageWidget.gml StorageWidgetGML.h storage_widget_gml) @@ -24,6 +27,7 @@ set(SOURCES StorageModel.cpp StorageWidget.cpp Tab.cpp + WebDriverConnection.cpp WindowActions.cpp main.cpp ) @@ -33,6 +37,8 @@ set(GENERATED_SOURCES EditBookmarkGML.h StorageWidgetGML.h TabGML.h + WebDriverSessionClientEndpoint.h + WebDriverSessionServerEndpoint.h ) serenity_app(Browser ICON app-browser) diff --git a/Userland/Applications/Browser/WebDriverConnection.cpp b/Userland/Applications/Browser/WebDriverConnection.cpp new file mode 100644 index 00000000000..9d4960fd809 --- /dev/null +++ b/Userland/Applications/Browser/WebDriverConnection.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022, Florent Castelli + * Copyright (c) 2022, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "WebDriverConnection.h" +#include "BrowserWindow.h" + +namespace Browser { + +WebDriverConnection::WebDriverConnection(NonnullOwnPtr socket, NonnullRefPtr browser_window) + : IPC::ConnectionToServer(*this, move(socket)) + , m_browser_window(move(browser_window)) +{ +} + +void WebDriverConnection::quit() +{ + dbgln("WebDriverConnection: quit"); + if (auto browser_window = m_browser_window.strong_ref()) + browser_window->close(); +} + +Messages::WebDriverSessionClient::GetUrlResponse WebDriverConnection::get_url() +{ + dbgln("WebDriverConnection: get_url"); + if (auto browser_window = m_browser_window.strong_ref()) + return { browser_window->active_tab().url() }; + return { URL("") }; +} + +void WebDriverConnection::set_url(AK::URL const& url) +{ + dbgln("WebDriverConnection: set_url {}", url); + if (auto browser_window = m_browser_window.strong_ref()) + browser_window->active_tab().load(url); +} + +Messages::WebDriverSessionClient::GetTitleResponse WebDriverConnection::get_title() +{ + dbgln("WebDriverConnection: get_title"); + if (auto browser_window = m_browser_window.strong_ref()) + return { browser_window->active_tab().title() }; + return { "" }; +} + +} diff --git a/Userland/Applications/Browser/WebDriverConnection.h b/Userland/Applications/Browser/WebDriverConnection.h new file mode 100644 index 00000000000..c887ce30c47 --- /dev/null +++ b/Userland/Applications/Browser/WebDriverConnection.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022, Florent Castelli + * Copyright (c) 2022, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "BrowserWindow.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Browser { + +class WebDriverConnection final + : public IPC::ConnectionToServer { + C_OBJECT_ABSTRACT(WebDriverConnection) +public: + static ErrorOr> connect_to_webdriver(NonnullRefPtr browser_window, String path) + { + dbgln("Trying to connect to {}", path); + auto result = TRY(Core::Stream::LocalSocket::connect(path)); + dbgln("Connected to WebDriver"); + return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) WebDriverConnection(move(result), browser_window))); + } + + virtual ~WebDriverConnection() = default; + + virtual void die() override { } + + virtual void quit() override; + virtual Messages::WebDriverSessionClient::GetUrlResponse get_url() override; + virtual void set_url(AK::URL const& url) override; + virtual Messages::WebDriverSessionClient::GetTitleResponse get_title() override; + +private: + WebDriverConnection(NonnullOwnPtr socket, NonnullRefPtr browser_window); + + WeakPtr m_browser_window; +}; + +} diff --git a/Userland/Applications/Browser/WebDriverSessionClient.ipc b/Userland/Applications/Browser/WebDriverSessionClient.ipc new file mode 100644 index 00000000000..361a634add8 --- /dev/null +++ b/Userland/Applications/Browser/WebDriverSessionClient.ipc @@ -0,0 +1,9 @@ +#include + +endpoint WebDriverSessionClient { + quit() =| + + get_url() => (URL url) + set_url(URL url) =| + get_title() => (String title) +} diff --git a/Userland/Applications/Browser/WebDriverSessionServer.ipc b/Userland/Applications/Browser/WebDriverSessionServer.ipc new file mode 100644 index 00000000000..0f8e2e33422 --- /dev/null +++ b/Userland/Applications/Browser/WebDriverSessionServer.ipc @@ -0,0 +1,2 @@ +endpoint WebDriverSessionServer { +} diff --git a/Userland/Applications/Browser/main.cpp b/Userland/Applications/Browser/main.cpp index 393c45359e4..f8d83a05b61 100644 --- a/Userland/Applications/Browser/main.cpp +++ b/Userland/Applications/Browser/main.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -62,12 +63,15 @@ ErrorOr serenity_main(Main::Arguments arguments) return 1; } - TRY(Core::System::pledge("stdio recvfd sendfd unix cpath rpath wpath proc exec")); + TRY(Core::System::pledge("stdio recvfd sendfd unix fattr cpath rpath wpath proc exec")); Vector specified_urls; + String webdriver_ipc_path; Core::ArgsParser args_parser; args_parser.add_positional_argument(specified_urls, "URLs to open", "url", Core::ArgsParser::Required::No); + args_parser.add_option(webdriver_ipc_path, "Path to WebDriver IPC", "webdriver", 0, "path"); + args_parser.parse(arguments); auto app = TRY(GUI::Application::try_create(arguments)); @@ -81,6 +85,11 @@ ErrorOr serenity_main(Main::Arguments arguments) TRY(Desktop::Launcher::add_allowed_url(URL::create_with_file_scheme(Core::StandardPaths::downloads_directory()))); TRY(Desktop::Launcher::seal_allowlist()); + if (!webdriver_ipc_path.is_empty()) { + specified_urls.empend("about:blank"); + TRY(Core::System::unveil(webdriver_ipc_path.view(), "rw"sv)); + } + TRY(Core::System::unveil("/proc/all", "r")); TRY(Core::System::unveil("/tmp/session/%sid/portal/filesystemaccess", "rw")); TRY(Core::System::unveil("/tmp/session/%sid/portal/filesystemaccess", "rw")); @@ -135,6 +144,10 @@ ErrorOr serenity_main(Main::Arguments arguments) Browser::CookieJar cookie_jar; auto window = Browser::BrowserWindow::construct(cookie_jar, first_url); + RefPtr web_driver_connection; + + if (!webdriver_ipc_path.is_empty()) + web_driver_connection = TRY(Browser::WebDriverConnection::connect_to_webdriver(window, webdriver_ipc_path)); auto content_filters_watcher = TRY(Core::FileWatcher::create()); content_filters_watcher->on_change = [&](Core::FileWatcherEvent const&) {