2023-11-08 15:47:41 -03:00
/*
* Copyright ( c ) 2023 , Andrew Kaster < akaster @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include <LibCore/ArgsParser.h>
# include <LibCore/EventLoop.h>
2024-08-01 08:03:03 -03:00
# include <LibCore/Process.h>
2023-11-08 15:47:41 -03:00
# include <LibCore/System.h>
# include <LibFileSystem/FileSystem.h>
# include <LibIPC/SingleServer.h>
# include <LibMain/Main.h>
# include <LibWeb/Bindings/MainThreadVM.h>
# include <LibWeb/Loader/GeneratedPagesLoader.h>
# include <LibWeb/Loader/ResourceLoader.h>
# include <LibWeb/Platform/EventLoopPlugin.h>
# include <LibWeb/Platform/EventLoopPluginSerenity.h>
2024-11-10 12:26:07 -03:00
# include <LibWebView/HelperProcess.h>
2024-11-10 11:53:15 -03:00
# include <LibWebView/Plugins/FontPlugin.h>
2025-03-27 12:31:47 -03:00
# include <LibWebView/Plugins/ImageCodecPlugin.h>
2024-11-10 12:26:07 -03:00
# include <LibWebView/Utilities.h>
2023-11-08 15:47:41 -03:00
# include <WebWorker/ConnectionFromClient.h>
2025-03-27 12:31:47 -03:00
static ErrorOr < void > initialize_image_decoder ( int image_decoder_socket ) ;
2024-11-14 12:01:23 -03:00
static ErrorOr < void > initialize_resource_loader ( GC : : Heap & , int request_server_socket ) ;
2023-11-08 15:47:41 -03:00
2025-04-24 02:07:09 -03:00
static ErrorOr < Web : : Bindings : : AgentType > 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' " ) ;
}
2025-07-08 07:14:08 -03:00
ErrorOr < int > ladybird_main ( Main : : Arguments arguments )
2023-11-08 15:47:41 -03:00
{
2023-12-11 15:19:41 -03:00
AK : : set_rich_debug_enabled ( true ) ;
2024-04-15 20:39:48 -03:00
int request_server_socket { - 1 } ;
2025-03-27 12:31:47 -03:00
int image_decoder_socket { - 1 } ;
2024-01-06 17:13:59 -03:00
StringView serenity_resource_root ;
2025-04-24 02:07:09 -03:00
StringView worker_type_string ;
2024-07-10 08:50:21 -03:00
Vector < ByteString > certificates ;
2024-08-01 08:03:03 -03:00
bool wait_for_debugger = false ;
2023-11-08 15:47:41 -03:00
Core : : ArgsParser args_parser ;
2024-04-15 20:39:48 -03:00
args_parser . add_option ( request_server_socket , " File descriptor of the request server socket " , " request-server-socket " , ' s ' , " request-server-socket " ) ;
2025-03-27 12:31:47 -03:00
args_parser . add_option ( image_decoder_socket , " File descriptor of the socket for the ImageDecoder connection " , " image-decoder-socket " , ' i ' , " image_decoder_socket " ) ;
2024-01-06 17:13:59 -03:00
args_parser . add_option ( serenity_resource_root , " Absolute path to directory for serenity resources " , " serenity-resource-root " , ' r ' , " serenity-resource-root " ) ;
2024-07-10 08:50:21 -03:00
args_parser . add_option ( certificates , " Path to a certificate file " , " certificate " , ' C ' , " certificate " ) ;
2024-08-01 08:03:03 -03:00
args_parser . add_option ( wait_for_debugger , " Wait for debugger " , " wait-for-debugger " ) ;
2025-04-24 02:07:09 -03:00
args_parser . add_option ( worker_type_string , " Type of WebWorker to start (dedicated, shared, or service) " , " type " , ' t ' , " type " ) ;
2023-11-08 15:47:41 -03:00
args_parser . parse ( arguments ) ;
2024-08-01 08:03:03 -03:00
if ( wait_for_debugger )
Core : : Process : : wait_for_debugger_and_break ( ) ;
2025-04-24 02:07:09 -03:00
auto worker_type = TRY ( agent_type_from_string ( worker_type_string ) ) ;
2024-07-05 23:41:07 -03:00
Core : : EventLoop event_loop ;
2024-11-10 12:26:07 -03:00
WebView : : platform_init ( ) ;
2023-11-08 15:47:41 -03:00
2025-03-27 12:31:47 -03:00
TRY ( initialize_image_decoder ( image_decoder_socket ) ) ;
2023-11-08 15:47:41 -03:00
Web : : Platform : : EventLoopPlugin : : install ( * new Web : : Platform : : EventLoopPluginSerenity ) ;
2024-11-10 11:53:15 -03:00
Web : : Platform : : FontPlugin : : install ( * new WebView : : FontPlugin ( false ) ) ;
2023-11-08 15:47:41 -03:00
2025-04-24 02:07:09 -03:00
Web : : Bindings : : initialize_main_thread_vm ( worker_type ) ;
2023-11-08 15:47:41 -03:00
2024-10-30 10:38:57 -03:00
TRY ( initialize_resource_loader ( Web : : Bindings : : main_thread_vm ( ) . heap ( ) , request_server_socket ) ) ;
2023-11-08 15:47:41 -03:00
auto client = TRY ( IPC : : take_over_accepted_client_from_system_server < WebWorker : : ConnectionFromClient > ( ) ) ;
return event_loop . exec ( ) ;
}
2025-03-27 12:31:47 -03:00
static ErrorOr < void > initialize_image_decoder ( int image_decoder_socket )
{
2025-06-28 17:24:09 -03:00
# if !defined(AK_OS_WINDOWS)
2025-03-27 12:31:47 -03:00
static_assert ( IsSame < IPC : : Transport , IPC : : TransportSocket > , " Need to handle other IPC transports here " ) ;
2025-06-28 17:24:09 -03:00
# else
static_assert ( IsSame < IPC : : Transport , IPC : : TransportSocketWindows > , " Need to handle other IPC transports here " ) ;
# endif
2025-03-27 12:31:47 -03:00
auto socket = TRY ( Core : : LocalSocket : : adopt_fd ( image_decoder_socket ) ) ;
TRY ( socket - > set_blocking ( true ) ) ;
2025-04-08 17:01:46 -03:00
auto new_client = TRY ( try_make_ref_counted < ImageDecoderClient : : Client > ( make < IPC : : Transport > ( move ( socket ) ) ) ) ;
2025-03-27 12:31:47 -03:00
# ifdef AK_OS_WINDOWS
auto response = new_client - > send_sync < Messages : : ImageDecoderServer : : InitTransport > ( Core : : System : : getpid ( ) ) ;
new_client - > transport ( ) . set_peer_pid ( response - > peer_pid ( ) ) ;
# endif
Web : : Platform : : ImageCodecPlugin : : install ( * new WebView : : ImageCodecPlugin ( move ( new_client ) ) ) ;
return { } ;
}
2024-11-14 12:01:23 -03:00
static ErrorOr < void > initialize_resource_loader ( GC : : Heap & heap , int request_server_socket )
2023-11-08 15:47:41 -03:00
{
2025-06-28 17:24:09 -03:00
# if !defined(AK_OS_WINDOWS)
2024-10-22 18:47:33 -03:00
static_assert ( IsSame < IPC : : Transport , IPC : : TransportSocket > , " Need to handle other IPC transports here " ) ;
2025-06-28 17:24:09 -03:00
# else
static_assert ( IsSame < IPC : : Transport , IPC : : TransportSocketWindows > , " Need to handle other IPC transports here " ) ;
# endif
2024-04-15 20:39:48 -03:00
auto socket = TRY ( Core : : LocalSocket : : adopt_fd ( request_server_socket ) ) ;
TRY ( socket - > set_blocking ( true ) ) ;
2025-04-08 17:01:46 -03:00
auto request_client = TRY ( try_make_ref_counted < Requests : : RequestClient > ( make < IPC : : Transport > ( move ( socket ) ) ) ) ;
2025-03-27 12:31:47 -03:00
# ifdef AK_OS_WINDOWS
auto response = request_client - > send_sync < Messages : : RequestServer : : InitTransport > ( Core : : System : : getpid ( ) ) ;
request_client - > transport ( ) . set_peer_pid ( response - > peer_pid ( ) ) ;
# endif
2024-10-30 10:38:57 -03:00
Web : : ResourceLoader : : initialize ( heap , move ( request_client ) ) ;
2023-11-08 15:47:41 -03:00
return { } ;
}