diff --git a/Libraries/LibWebView/Application.cpp b/Libraries/LibWebView/Application.cpp index d0ab3fa3fee..423470ea20e 100644 --- a/Libraries/LibWebView/Application.cpp +++ b/Libraries/LibWebView/Application.cpp @@ -15,8 +15,10 @@ #include #include #include +#include #include #include +#include #include namespace WebView { @@ -168,6 +170,51 @@ void Application::initialize(Main::Arguments const& arguments, URL::URL new_tab_ } } +ErrorOr Application::launch_services() +{ + TRY(launch_request_server()); + TRY(launch_image_decoder_server()); + return {}; +} + +ErrorOr Application::launch_request_server() +{ + // FIXME: Create an abstraction to re-spawn the RequestServer and re-hook up its client hooks to each tab on crash + auto paths = TRY(get_paths_for_helper_process("RequestServer"sv)); + m_request_server_client = TRY(launch_request_server_process(paths)); + + return {}; +} + +ErrorOr Application::launch_image_decoder_server() +{ + auto paths = TRY(get_paths_for_helper_process("ImageDecoder"sv)); + m_image_decoder_client = TRY(launch_image_decoder_process(paths)); + + m_image_decoder_client->on_death = [this]() { + m_image_decoder_client = nullptr; + + if (auto result = launch_image_decoder_server(); result.is_error()) { + dbgln("Failed to restart image decoder: {}", result.error()); + VERIFY_NOT_REACHED(); + } + + auto client_count = WebContentClient::client_count(); + auto new_sockets = m_image_decoder_client->send_sync_but_allow_failure(client_count); + if (!new_sockets || new_sockets->sockets().is_empty()) { + dbgln("Failed to connect {} new clients to ImageDecoder", client_count); + VERIFY_NOT_REACHED(); + } + + WebContentClient::for_each_client([sockets = new_sockets->take_sockets()](WebContentClient& client) mutable { + client.async_connect_to_image_decoder(sockets.take_last()); + return IterationDecision::Continue; + }); + }; + + return {}; +} + int Application::execute() { int ret = m_event_loop.exec(); diff --git a/Libraries/LibWebView/Application.h b/Libraries/LibWebView/Application.h index 458afe8725c..8afdb570a61 100644 --- a/Libraries/LibWebView/Application.h +++ b/Libraries/LibWebView/Application.h @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -34,10 +36,15 @@ public: static ChromeOptions const& chrome_options() { return the().m_chrome_options; } static WebContentOptions const& web_content_options() { return the().m_web_content_options; } + static Requests::RequestClient& request_server_client() { return *the().m_request_server_client; } + static ImageDecoderClient::Client& image_decoder_client() { return *the().m_image_decoder_client; } + static CookieJar& cookie_jar() { return *the().m_cookie_jar; } Core::EventLoop& event_loop() { return m_event_loop; } + ErrorOr launch_services(); + void add_child_process(Process&&); // FIXME: Should these methods be part of Application, instead of deferring to ProcessManager? @@ -74,11 +81,17 @@ protected: private: void initialize(Main::Arguments const& arguments, URL::URL new_tab_page_url); + ErrorOr launch_request_server(); + ErrorOr launch_image_decoder_server(); + static Application* s_the; ChromeOptions m_chrome_options; WebContentOptions m_web_content_options; + RefPtr m_request_server_client; + RefPtr m_image_decoder_client; + RefPtr m_database; OwnPtr m_cookie_jar; diff --git a/Libraries/LibWebView/HelperProcess.cpp b/Libraries/LibWebView/HelperProcess.cpp index 9b5955fefc2..94c711712cd 100644 --- a/Libraries/LibWebView/HelperProcess.cpp +++ b/Libraries/LibWebView/HelperProcess.cpp @@ -135,24 +135,24 @@ ErrorOr> launch_image_decoder_process( return launch_server_process("ImageDecoder"sv, candidate_image_decoder_paths, arguments); } -ErrorOr> launch_web_worker_process(ReadonlySpan candidate_web_worker_paths, NonnullRefPtr request_client) +ErrorOr> launch_web_worker_process(ReadonlySpan candidate_web_worker_paths) { Vector arguments; - auto socket = TRY(connect_new_request_server_client(*request_client)); + auto socket = TRY(connect_new_request_server_client()); arguments.append("--request-server-socket"sv); arguments.append(ByteString::number(socket.fd())); return launch_server_process("WebWorker"sv, candidate_web_worker_paths, move(arguments)); } -ErrorOr> launch_request_server_process(ReadonlySpan candidate_request_server_paths, StringView serenity_resource_root) +ErrorOr> launch_request_server_process(ReadonlySpan candidate_request_server_paths) { Vector arguments; - if (!serenity_resource_root.is_empty()) { + if (!s_ladybird_resource_root.is_empty()) { arguments.append("--serenity-resource-root"sv); - arguments.append(serenity_resource_root); + arguments.append(s_ladybird_resource_root); } for (auto const& certificate : WebView::Application::chrome_options().certificates) @@ -166,9 +166,9 @@ ErrorOr> launch_request_server_process(Re return launch_server_process("RequestServer"sv, candidate_request_server_paths, move(arguments)); } -ErrorOr connect_new_request_server_client(Requests::RequestClient& client) +ErrorOr connect_new_request_server_client() { - auto new_socket = client.send_sync_but_allow_failure(); + auto new_socket = Application::request_server_client().send_sync_but_allow_failure(); if (!new_socket) return Error::from_string_literal("Failed to connect to RequestServer"); @@ -178,9 +178,9 @@ ErrorOr connect_new_request_server_client(Requests::RequestClient& cl return socket; } -ErrorOr connect_new_image_decoder_client(ImageDecoderClient::Client& client) +ErrorOr connect_new_image_decoder_client() { - auto new_socket = client.send_sync_but_allow_failure(1); + auto new_socket = Application::image_decoder_client().send_sync_but_allow_failure(1); if (!new_socket) return Error::from_string_literal("Failed to connect to ImageDecoder"); diff --git a/Libraries/LibWebView/HelperProcess.h b/Libraries/LibWebView/HelperProcess.h index a46c6a6e8cd..2d7a8b88c6e 100644 --- a/Libraries/LibWebView/HelperProcess.h +++ b/Libraries/LibWebView/HelperProcess.h @@ -25,10 +25,10 @@ ErrorOr> launch_web_content_process( Optional request_server_socket = {}); ErrorOr> launch_image_decoder_process(ReadonlySpan candidate_image_decoder_paths); -ErrorOr> launch_web_worker_process(ReadonlySpan candidate_web_worker_paths, NonnullRefPtr); -ErrorOr> launch_request_server_process(ReadonlySpan candidate_request_server_paths, StringView serenity_resource_root); +ErrorOr> launch_web_worker_process(ReadonlySpan candidate_web_worker_paths); +ErrorOr> launch_request_server_process(ReadonlySpan candidate_request_server_paths); -ErrorOr connect_new_request_server_client(Requests::RequestClient&); -ErrorOr connect_new_image_decoder_client(ImageDecoderClient::Client&); +ErrorOr connect_new_request_server_client(); +ErrorOr connect_new_image_decoder_client(); } diff --git a/UI/AppKit/Application/Application.h b/UI/AppKit/Application/Application.h index 7e81c5c812a..68e41d50275 100644 --- a/UI/AppKit/Application/Application.h +++ b/UI/AppKit/Application/Application.h @@ -23,9 +23,6 @@ class WebViewBridge; - (void)setupWebViewApplication:(Main::Arguments&)arguments newTabPageURL:(URL::URL)new_tab_page_url; -- (ErrorOr)launchRequestServer; -- (ErrorOr)launchImageDecoder; -- (ErrorOr>)launchWebContent:(Ladybird::WebViewBridge&)web_view_bridge; -- (ErrorOr)launchWebWorker; +- (ErrorOr)launchServices; @end diff --git a/UI/AppKit/Application/Application.mm b/UI/AppKit/Application/Application.mm index 240ebaf8eb7..5b704e49b3e 100644 --- a/UI/AppKit/Application/Application.mm +++ b/UI/AppKit/Application/Application.mm @@ -7,12 +7,7 @@ #include #include #include -#include -#include #include -#include -#include -#include #include #import @@ -68,75 +63,12 @@ ApplicationBridge::ApplicationBridge(Badge, Main::Argument m_application_bridge = Ladybird::ApplicationBridge::create(arguments, move(new_tab_page_url)); } -- (ErrorOr)launchRequestServer +- (ErrorOr)launchServices { - auto request_server_paths = TRY(WebView::get_paths_for_helper_process("RequestServer"sv)); - m_request_server_client = TRY(WebView::launch_request_server_process(request_server_paths, WebView::s_ladybird_resource_root)); - + TRY(m_application_bridge->launch_services()); return {}; } -static ErrorOr> launch_new_image_decoder() -{ - auto image_decoder_paths = TRY(WebView::get_paths_for_helper_process("ImageDecoder"sv)); - return WebView::launch_image_decoder_process(image_decoder_paths); -} - -- (ErrorOr)launchImageDecoder -{ - m_image_decoder_client = TRY(launch_new_image_decoder()); - - __weak Application* weak_self = self; - - m_image_decoder_client->on_death = [weak_self]() { - Application* self = weak_self; - if (self == nil) { - return; - } - - m_image_decoder_client = nullptr; - - if (auto err = [self launchImageDecoder]; err.is_error()) { - dbgln("Failed to restart image decoder: {}", err.error()); - VERIFY_NOT_REACHED(); - } - - auto num_clients = WebView::WebContentClient::client_count(); - auto new_sockets = m_image_decoder_client->send_sync_but_allow_failure(num_clients); - if (!new_sockets || new_sockets->sockets().size() == 0) { - dbgln("Failed to connect {} new clients to ImageDecoder", num_clients); - VERIFY_NOT_REACHED(); - } - - WebView::WebContentClient::for_each_client([sockets = new_sockets->take_sockets()](WebView::WebContentClient& client) mutable { - client.async_connect_to_image_decoder(sockets.take_last()); - return IterationDecision::Continue; - }); - }; - - return {}; -} - -- (ErrorOr>)launchWebContent:(Ladybird::WebViewBridge&)web_view_bridge -{ - // FIXME: Fail to open the tab, rather than crashing the whole application if this fails - auto request_server_socket = TRY(WebView::connect_new_request_server_client(*m_request_server_client)); - auto image_decoder_socket = TRY(WebView::connect_new_image_decoder_client(*m_image_decoder_client)); - - auto web_content_paths = TRY(WebView::get_paths_for_helper_process("WebContent"sv)); - auto web_content = TRY(WebView::launch_web_content_process(web_view_bridge, web_content_paths, move(image_decoder_socket), move(request_server_socket))); - - return web_content; -} - -- (ErrorOr)launchWebWorker -{ - auto web_worker_paths = TRY(WebView::get_paths_for_helper_process("WebWorker"sv)); - auto worker_client = TRY(WebView::launch_web_worker_process(web_worker_paths, *m_request_server_client)); - - return worker_client->clone_transport(); -} - #pragma mark - NSApplication - (void)terminate:(id)sender diff --git a/UI/AppKit/Interface/LadybirdWebView.mm b/UI/AppKit/Interface/LadybirdWebView.mm index 8a52383ffaf..28085b40280 100644 --- a/UI/AppKit/Interface/LadybirdWebView.mm +++ b/UI/AppKit/Interface/LadybirdWebView.mm @@ -12,9 +12,11 @@ #include #include #include +#include #include #include #include +#include #import #import @@ -344,18 +346,9 @@ static void copy_data_to_clipboard(StringView data, NSPasteboardType pasteboard_ return [self.observer onCreateNewTab:{} activateTab:activate_tab]; }; - m_web_view_bridge->on_request_web_content = [weak_self]() { - Application* application = NSApp; - LadybirdWebView* self = weak_self; - if (self == nil) { - VERIFY_NOT_REACHED(); - } - return [application launchWebContent:*(self->m_web_view_bridge)].release_value_but_fixme_should_propagate_errors(); - }; - m_web_view_bridge->on_request_worker_agent = []() { - Application* application = NSApp; - return [application launchWebWorker].release_value_but_fixme_should_propagate_errors(); + auto worker_client = MUST(WebView::launch_web_worker_process(MUST(WebView::get_paths_for_helper_process("WebWorker"sv)))); + return worker_client->clone_transport(); }; m_web_view_bridge->on_activate_tab = [weak_self]() { diff --git a/UI/AppKit/Interface/LadybirdWebViewBridge.cpp b/UI/AppKit/Interface/LadybirdWebViewBridge.cpp index c9319e58234..e6570c04d53 100644 --- a/UI/AppKit/Interface/LadybirdWebViewBridge.cpp +++ b/UI/AppKit/Interface/LadybirdWebViewBridge.cpp @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include #import @@ -143,11 +145,16 @@ Gfx::IntPoint WebViewBridge::to_widget_position(Gfx::IntPoint content_position) void WebViewBridge::initialize_client(CreateNewClient create_new_client) { - VERIFY(on_request_web_content); - if (create_new_client == CreateNewClient::Yes) { m_client_state = {}; - m_client_state.client = on_request_web_content(); + + auto request_server_socket = WebView::connect_new_request_server_client().release_value_but_fixme_should_propagate_errors(); + auto image_decoder_socket = WebView::connect_new_image_decoder_client().release_value_but_fixme_should_propagate_errors(); + + auto candidate_web_content_paths = WebView::get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors(); + auto new_client = launch_web_content_process(*this, candidate_web_content_paths, AK::move(image_decoder_socket), AK::move(request_server_socket)).release_value_but_fixme_should_propagate_errors(); + + m_client_state.client = new_client; } else { m_client_state.client->register_view(m_client_state.page_index, *this); } diff --git a/UI/AppKit/Interface/LadybirdWebViewBridge.h b/UI/AppKit/Interface/LadybirdWebViewBridge.h index e0374eb7b4f..a6760034863 100644 --- a/UI/AppKit/Interface/LadybirdWebViewBridge.h +++ b/UI/AppKit/Interface/LadybirdWebViewBridge.h @@ -50,7 +50,6 @@ public: }; Optional paintable(); - Function()> on_request_web_content; Function on_zoom_level_changed; private: diff --git a/UI/AppKit/main.mm b/UI/AppKit/main.mm index 6b53938a492..08b44d2ae5c 100644 --- a/UI/AppKit/main.mm +++ b/UI/AppKit/main.mm @@ -83,10 +83,7 @@ ErrorOr serenity_main(Main::Arguments arguments) view->did_allocate_iosurface_backing_stores(message.front_backing_store_id, move(message.front_backing_store_port), message.back_backing_store_id, move(message.back_backing_store_port)); }; - // FIXME: Create an abstraction to re-spawn the RequestServer and re-hook up its client hooks to each tab on crash - TRY([application launchRequestServer]); - - TRY([application launchImageDecoder]); + TRY([application launchServices]); auto* delegate = [[ApplicationDelegate alloc] init]; [NSApp setDelegate:delegate]; diff --git a/UI/Headless/Application.cpp b/UI/Headless/Application.cpp index 2822815153b..b521d389e74 100644 --- a/UI/Headless/Application.cpp +++ b/UI/Headless/Application.cpp @@ -73,17 +73,6 @@ void Application::create_platform_options(WebView::ChromeOptions& chrome_options web_content_options.is_layout_test_mode = is_layout_test_mode ? WebView::IsLayoutTestMode::Yes : WebView::IsLayoutTestMode::No; } -ErrorOr Application::launch_services() -{ - auto request_server_paths = TRY(WebView::get_paths_for_helper_process("RequestServer"sv)); - m_request_client = TRY(WebView::launch_request_server_process(request_server_paths, resources_folder)); - - auto image_decoder_paths = TRY(WebView::get_paths_for_helper_process("ImageDecoder"sv)); - m_image_decoder_client = TRY(WebView::launch_image_decoder_process(image_decoder_paths)); - - return {}; -} - ErrorOr Application::launch_test_fixtures() { Fixture::initialize_fixtures(); diff --git a/UI/Headless/Application.h b/UI/Headless/Application.h index 23a13b5357f..b916acb0512 100644 --- a/UI/Headless/Application.h +++ b/UI/Headless/Application.h @@ -9,10 +9,7 @@ #include #include #include -#include #include -#include -#include #include #include @@ -34,12 +31,8 @@ public: virtual void create_platform_arguments(Core::ArgsParser&) override; virtual void create_platform_options(WebView::ChromeOptions&, WebView::WebContentOptions&) override; - ErrorOr launch_services(); ErrorOr launch_test_fixtures(); - static Requests::RequestClient& request_client() { return *the().m_request_client; } - static ImageDecoderClient::Client& image_decoder_client() { return *the().m_image_decoder_client; } - HeadlessWebView& create_web_view(Core::AnonymousBuffer theme, Web::DevicePixelSize window_size); HeadlessWebView& create_child_web_view(HeadlessWebView const&, u64 page_index); void destroy_web_views(); @@ -70,9 +63,6 @@ public: int height { 600 }; private: - RefPtr m_request_client; - RefPtr m_image_decoder_client; - Vector> m_web_views; }; diff --git a/UI/Headless/HeadlessWebView.cpp b/UI/Headless/HeadlessWebView.cpp index e0be92096d6..4e0460c8d29 100644 --- a/UI/Headless/HeadlessWebView.cpp +++ b/UI/Headless/HeadlessWebView.cpp @@ -33,7 +33,7 @@ HeadlessWebView::HeadlessWebView(Core::AnonymousBuffer theme, Web::DevicePixelSi on_request_worker_agent = []() { auto web_worker_paths = MUST(WebView::get_paths_for_helper_process("WebWorker"sv)); - auto worker_client = MUST(WebView::launch_web_worker_process(web_worker_paths, Application::request_client())); + auto worker_client = MUST(WebView::launch_web_worker_process(web_worker_paths)); return worker_client->clone_transport(); }; @@ -162,8 +162,8 @@ NonnullOwnPtr HeadlessWebView::create_child(HeadlessWebView con void HeadlessWebView::initialize_client(CreateNewClient create_new_client) { if (create_new_client == CreateNewClient::Yes) { - auto request_server_socket = WebView::connect_new_request_server_client(Application::request_client()).release_value_but_fixme_should_propagate_errors(); - auto image_decoder_socket = WebView::connect_new_image_decoder_client(Application::image_decoder_client()).release_value_but_fixme_should_propagate_errors(); + auto request_server_socket = WebView::connect_new_request_server_client().release_value_but_fixme_should_propagate_errors(); + auto image_decoder_socket = WebView::connect_new_image_decoder_client().release_value_but_fixme_should_propagate_errors(); auto web_content_paths = WebView::get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors(); m_client_state.client = WebView::launch_web_content_process(*this, web_content_paths, move(image_decoder_socket), move(request_server_socket)).release_value_but_fixme_should_propagate_errors(); diff --git a/UI/Qt/Application.cpp b/UI/Qt/Application.cpp index 9ffa71e9870..ad4360b17a3 100644 --- a/UI/Qt/Application.cpp +++ b/UI/Qt/Application.cpp @@ -5,9 +5,7 @@ */ #include -#include #include -#include #include #include #include @@ -54,38 +52,6 @@ bool Application::event(QEvent* event) return QApplication::event(event); } -static ErrorOr> launch_new_image_decoder() -{ - auto paths = TRY(WebView::get_paths_for_helper_process("ImageDecoder"sv)); - return WebView::launch_image_decoder_process(paths); -} - -ErrorOr Application::initialize_image_decoder() -{ - m_image_decoder_client = TRY(launch_new_image_decoder()); - - m_image_decoder_client->on_death = [this] { - m_image_decoder_client = nullptr; - if (auto err = this->initialize_image_decoder(); err.is_error()) { - dbgln("Failed to restart image decoder: {}", err.error()); - VERIFY_NOT_REACHED(); - } - - auto num_clients = WebView::WebContentClient::client_count(); - auto new_sockets = m_image_decoder_client->send_sync_but_allow_failure(num_clients); - if (!new_sockets || new_sockets->sockets().size() == 0) { - dbgln("Failed to connect {} new clients to ImageDecoder", num_clients); - VERIFY_NOT_REACHED(); - } - - WebView::WebContentClient::for_each_client([sockets = new_sockets->take_sockets()](WebView::WebContentClient& client) mutable { - client.async_connect_to_image_decoder(sockets.take_last()); - return IterationDecision::Continue; - }); - }; - return {}; -} - void Application::show_task_manager_window() { if (!m_task_manager_window) { diff --git a/UI/Qt/Application.h b/UI/Qt/Application.h index bb6877c0da5..4bf346f1938 100644 --- a/UI/Qt/Application.h +++ b/UI/Qt/Application.h @@ -7,9 +7,6 @@ #pragma once #include -#include -#include -#include #include #include #include @@ -30,10 +27,6 @@ public: virtual bool event(QEvent* event) override; Function on_open_file; - RefPtr request_server_client; - - NonnullRefPtr image_decoder_client() const { return *m_image_decoder_client; } - ErrorOr initialize_image_decoder(); BrowserWindow& new_window(Vector const& initial_urls, BrowserWindow::IsPopupWindow is_popup_window = BrowserWindow::IsPopupWindow::No, Tab* parent_tab = nullptr, Optional page_index = {}); @@ -50,8 +43,6 @@ private: TaskManagerWindow* m_task_manager_window { nullptr }; BrowserWindow* m_active_window { nullptr }; - - RefPtr m_image_decoder_client; }; } diff --git a/UI/Qt/WebContentView.cpp b/UI/Qt/WebContentView.cpp index 26965c906e6..f5a41b553ca 100644 --- a/UI/Qt/WebContentView.cpp +++ b/UI/Qt/WebContentView.cpp @@ -128,8 +128,7 @@ WebContentView::WebContentView(QWidget* window, RefPtr(QApplication::instance())->request_server_client; - auto worker_client = MUST(WebView::launch_web_worker_process(MUST(WebView::get_paths_for_helper_process("WebWorker"sv)), *request_server_client)); + auto worker_client = MUST(WebView::launch_web_worker_process(MUST(WebView::get_paths_for_helper_process("WebWorker"sv)))); return worker_client->clone_transport(); }; @@ -629,13 +628,9 @@ void WebContentView::initialize_client(WebView::ViewImplementation::CreateNewCli if (create_new_client == CreateNewClient::Yes) { m_client_state = {}; - auto& request_server_client = static_cast(QApplication::instance())->request_server_client; - - // FIXME: Fail to open the tab, rather than crashing the whole application if this fails - auto request_server_socket = WebView::connect_new_request_server_client(*request_server_client).release_value_but_fixme_should_propagate_errors(); - - auto image_decoder = static_cast(QApplication::instance())->image_decoder_client(); - auto image_decoder_socket = WebView::connect_new_image_decoder_client(*image_decoder).release_value_but_fixme_should_propagate_errors(); + // FIXME: Fail to open the tab, rather than crashing the whole application if these fail. + auto request_server_socket = WebView::connect_new_request_server_client().release_value_but_fixme_should_propagate_errors(); + auto image_decoder_socket = WebView::connect_new_image_decoder_client().release_value_but_fixme_should_propagate_errors(); auto candidate_web_content_paths = WebView::get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors(); auto new_client = launch_web_content_process(*this, candidate_web_content_paths, AK::move(image_decoder_socket), AK::move(request_server_socket)).release_value_but_fixme_should_propagate_errors(); diff --git a/UI/Qt/main.cpp b/UI/Qt/main.cpp index 738c80db90a..af3c312b1f4 100644 --- a/UI/Qt/main.cpp +++ b/UI/Qt/main.cpp @@ -114,12 +114,7 @@ ErrorOr serenity_main(Main::Arguments arguments) WebView::copy_default_config_files(Ladybird::Settings::the()->directory()); - // FIXME: Create an abstraction to re-spawn the RequestServer and re-hook up its client hooks to each tab on crash - auto request_server_paths = TRY(WebView::get_paths_for_helper_process("RequestServer"sv)); - auto requests_client = TRY(WebView::launch_request_server_process(request_server_paths, WebView::s_ladybird_resource_root)); - app->request_server_client = move(requests_client); - - TRY(app->initialize_image_decoder()); + TRY(app->launch_services()); chrome_process.on_new_window = [&](auto const& urls) { app->new_window(urls);