diff --git a/Libraries/LibWeb/HTML/WorkerAgentParent.cpp b/Libraries/LibWeb/HTML/WorkerAgentParent.cpp index 71822d7ce17..3e0b9515b2b 100644 --- a/Libraries/LibWeb/HTML/WorkerAgentParent.cpp +++ b/Libraries/LibWeb/HTML/WorkerAgentParent.cpp @@ -34,7 +34,7 @@ void WorkerAgentParent::initialize(JS::Realm& realm) // NOTE: This blocking IPC call may launch another process. // If spinning the event loop for this can cause other javascript to execute, we're in trouble. - auto worker_socket_file = Bindings::principal_host_defined_page(realm).client().request_worker_agent(); + auto worker_socket_file = Bindings::principal_host_defined_page(realm).client().request_worker_agent(Bindings::AgentType::DedicatedWorker); auto worker_socket = MUST(Core::LocalSocket::adopt_fd(worker_socket_file.take_fd())); MUST(worker_socket->set_blocking(true)); diff --git a/Libraries/LibWeb/Page/Page.h b/Libraries/LibWeb/Page/Page.h index 68ba9f5f318..f9da700cb87 100644 --- a/Libraries/LibWeb/Page/Page.h +++ b/Libraries/LibWeb/Page/Page.h @@ -2,7 +2,7 @@ * Copyright (c) 2020-2023, Andreas Kling * Copyright (c) 2021-2022, Linus Groh * Copyright (c) 2022, Sam Atkins - * Copyright (c) 2023, Shannon Booth + * Copyright (c) 2023-2025, Shannon Booth * * SPDX-License-Identifier: BSD-2-Clause */ @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -396,7 +397,7 @@ public: virtual void page_did_change_audio_play_state(HTML::AudioPlayState) { } - virtual IPC::File request_worker_agent() { return IPC::File {}; } + virtual IPC::File request_worker_agent([[maybe_unused]] Web::Bindings::AgentType worker_type) { return IPC::File {}; } virtual void page_did_mutate_dom([[maybe_unused]] FlyString const& type, [[maybe_unused]] DOM::Node const& target, [[maybe_unused]] DOM::NodeList& added_nodes, [[maybe_unused]] DOM::NodeList& removed_nodes, [[maybe_unused]] GC::Ptr previous_sibling, [[maybe_unused]] GC::Ptr next_sibling, [[maybe_unused]] Optional const& attribute_name) { } diff --git a/Libraries/LibWebView/HelperProcess.cpp b/Libraries/LibWebView/HelperProcess.cpp index c3af333b38b..98ff959dc92 100644 --- a/Libraries/LibWebView/HelperProcess.cpp +++ b/Libraries/LibWebView/HelperProcess.cpp @@ -167,7 +167,7 @@ ErrorOr> launch_image_decoder_process( return launch_server_process("ImageDecoder"sv, arguments); } -ErrorOr> launch_web_worker_process() +ErrorOr> launch_web_worker_process(Web::Bindings::AgentType type) { Vector arguments; @@ -179,6 +179,21 @@ ErrorOr> launch_web_worker_process() arguments.append("--image-decoder-socket"sv); arguments.append(ByteString::number(image_decoder_socket.fd())); + arguments.append("--type"sv); + switch (type) { + case Web::Bindings::AgentType::DedicatedWorker: + arguments.append("dedicated"sv); + break; + case Web::Bindings::AgentType::SharedWorker: + arguments.append("shared"sv); + break; + case Web::Bindings::AgentType::ServiceWorker: + arguments.append("service"sv); + break; + default: + VERIFY_NOT_REACHED(); + } + return launch_server_process("WebWorker"sv, move(arguments)); } diff --git a/Libraries/LibWebView/HelperProcess.h b/Libraries/LibWebView/HelperProcess.h index b36211f647d..fb258851514 100644 --- a/Libraries/LibWebView/HelperProcess.h +++ b/Libraries/LibWebView/HelperProcess.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ ErrorOr> launch_spare_web_content_proce Optional request_server_socket = {}); ErrorOr> launch_image_decoder_process(); -ErrorOr> launch_web_worker_process(); +ErrorOr> launch_web_worker_process(Web::Bindings::AgentType); ErrorOr> launch_request_server_process(); ErrorOr connect_new_request_server_client(); diff --git a/Libraries/LibWebView/WebContentClient.cpp b/Libraries/LibWebView/WebContentClient.cpp index ebffe484135..0147996af37 100644 --- a/Libraries/LibWebView/WebContentClient.cpp +++ b/Libraries/LibWebView/WebContentClient.cpp @@ -659,10 +659,10 @@ void WebContentClient::did_allocate_backing_stores(u64 page_id, i32 front_bitmap view->did_allocate_backing_stores({}, front_bitmap_id, front_bitmap, back_bitmap_id, back_bitmap); } -Messages::WebContentClient::RequestWorkerAgentResponse WebContentClient::request_worker_agent(u64 page_id) +Messages::WebContentClient::RequestWorkerAgentResponse WebContentClient::request_worker_agent(u64 page_id, Web::Bindings::AgentType worker_type) { if (auto view = view_for_page_id(page_id); view.has_value()) { - auto worker_client = MUST(WebView::launch_web_worker_process()); + auto worker_client = MUST(WebView::launch_web_worker_process(worker_type)); return worker_client->clone_transport(); } diff --git a/Libraries/LibWebView/WebContentClient.h b/Libraries/LibWebView/WebContentClient.h index a181b4e88e7..9c8feb017e4 100644 --- a/Libraries/LibWebView/WebContentClient.h +++ b/Libraries/LibWebView/WebContentClient.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -129,7 +130,7 @@ private: virtual void did_change_audio_play_state(u64 page_id, Web::HTML::AudioPlayState) override; virtual void did_update_navigation_buttons_state(u64 page_id, bool back_enabled, bool forward_enabled) override; virtual void did_allocate_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::ShareableBitmap, i32 back_bitmap_id, Gfx::ShareableBitmap) override; - virtual Messages::WebContentClient::RequestWorkerAgentResponse request_worker_agent(u64 page_id) override; + virtual Messages::WebContentClient::RequestWorkerAgentResponse request_worker_agent(u64 page_id, Web::Bindings::AgentType worker_type) override; Optional view_for_page_id(u64, SourceLocation = SourceLocation::current()); diff --git a/Services/WebContent/PageClient.cpp b/Services/WebContent/PageClient.cpp index 86c36aad0bb..3fb349aca11 100644 --- a/Services/WebContent/PageClient.cpp +++ b/Services/WebContent/PageClient.cpp @@ -664,9 +664,9 @@ void PageClient::page_did_allocate_backing_stores(i32 front_bitmap_id, Gfx::Shar client().async_did_allocate_backing_stores(m_id, front_bitmap_id, front_bitmap, back_bitmap_id, back_bitmap); } -IPC::File PageClient::request_worker_agent() +IPC::File PageClient::request_worker_agent(Web::Bindings::AgentType type) { - auto response = client().send_sync_but_allow_failure(m_id); + auto response = client().send_sync_but_allow_failure(m_id, type); if (!response) { dbgln("WebContent client disconnected during RequestWorkerAgent. Exiting peacefully."); exit(0); diff --git a/Services/WebContent/PageClient.h b/Services/WebContent/PageClient.h index e89450dfb87..6eb3fb6e615 100644 --- a/Services/WebContent/PageClient.h +++ b/Services/WebContent/PageClient.h @@ -172,7 +172,7 @@ private: virtual void page_did_insert_clipboard_entry(StringView data, StringView presentation_style, StringView mime_type) override; virtual void page_did_change_audio_play_state(Web::HTML::AudioPlayState) override; virtual void page_did_allocate_backing_stores(i32 front_bitmap_id, Gfx::ShareableBitmap front_bitmap, i32 back_bitmap_id, Gfx::ShareableBitmap back_bitmap) override; - virtual IPC::File request_worker_agent() override; + virtual IPC::File request_worker_agent(Web::Bindings::AgentType) override; virtual void page_did_mutate_dom(FlyString const& type, Web::DOM::Node const& target, Web::DOM::NodeList& added_nodes, Web::DOM::NodeList& removed_nodes, GC::Ptr previous_sibling, GC::Ptr next_sibling, Optional const& attribute_name) override; virtual void received_message_from_web_ui(String const& name, JS::Value data) override; diff --git a/Services/WebContent/WebContentClient.ipc b/Services/WebContent/WebContentClient.ipc index bf563c56791..ea8a2558c11 100644 --- a/Services/WebContent/WebContentClient.ipc +++ b/Services/WebContent/WebContentClient.ipc @@ -21,6 +21,7 @@ #include #include #include +#include endpoint WebContentClient { @@ -107,5 +108,5 @@ endpoint WebContentClient did_find_in_page(u64 page_id, size_t current_match_index, Optional total_match_count) =| - request_worker_agent(u64 page_id) => (IPC::File socket) // FIXME: Add required attributes to select a SharedWorker Agent + request_worker_agent(u64 page_id, Web::Bindings::AgentType worker_type) => (IPC::File socket) // FIXME: Add required attributes to select a SharedWorker Agent } diff --git a/Services/WebWorker/main.cpp b/Services/WebWorker/main.cpp index 3f4253bc205..871adb4ff23 100644 --- a/Services/WebWorker/main.cpp +++ b/Services/WebWorker/main.cpp @@ -33,6 +33,18 @@ static ErrorOr initialize_image_decoder(int image_decoder_socket); static ErrorOr initialize_resource_loader(GC::Heap&, int request_server_socket); +static ErrorOr agent_type_from_string(StringView type) +{ + if (type == "dedicated"sv) + return Web::Bindings::AgentType::DedicatedWorker; + if (type == "shared"sv) + return Web::Bindings::AgentType::SharedWorker; + if (type == "service"sv) + return Web::Bindings::AgentType::ServiceWorker; + + return Error::from_string_literal("Invalid worker type, must be one of: 'dedicated', 'shared', or 'service'"); +} + ErrorOr serenity_main(Main::Arguments arguments) { AK::set_rich_debug_enabled(true); @@ -40,6 +52,7 @@ ErrorOr serenity_main(Main::Arguments arguments) int request_server_socket { -1 }; int image_decoder_socket { -1 }; StringView serenity_resource_root; + StringView worker_type_string; Vector certificates; bool wait_for_debugger = false; @@ -49,11 +62,15 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_option(serenity_resource_root, "Absolute path to directory for serenity resources", "serenity-resource-root", 'r', "serenity-resource-root"); args_parser.add_option(certificates, "Path to a certificate file", "certificate", 'C', "certificate"); args_parser.add_option(wait_for_debugger, "Wait for debugger", "wait-for-debugger"); + args_parser.add_option(worker_type_string, "Type of WebWorker to start (dedicated, shared, or service)", "type", 't', "type"); + args_parser.parse(arguments); if (wait_for_debugger) Core::Process::wait_for_debugger_and_break(); + auto worker_type = TRY(agent_type_from_string(worker_type_string)); + #if defined(HAVE_QT) QCoreApplication app(arguments.argc, arguments.argv); Core::EventLoopManager::install(*new WebView::EventLoopManagerQt); @@ -68,7 +85,7 @@ ErrorOr serenity_main(Main::Arguments arguments) Web::Platform::FontPlugin::install(*new WebView::FontPlugin(false)); - Web::Bindings::initialize_main_thread_vm(Web::Bindings::AgentType::DedicatedWorker); + Web::Bindings::initialize_main_thread_vm(worker_type); TRY(initialize_resource_loader(Web::Bindings::main_thread_vm().heap(), request_server_socket));