2023-02-02 10:00:30 +00:00
/*
* Copyright ( c ) 2023 , Andrew Kaster < akaster @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include "HelperProcess.h"
2024-04-04 20:13:14 +00:00
# include "Utilities.h"
2024-04-23 20:39:04 +00:00
# include <AK/Enumerate.h>
# include <LibCore/Process.h>
2024-06-30 04:24:01 +00:00
# include <LibWebView/Application.h>
2023-02-02 10:00:30 +00:00
2024-06-04 20:54:43 +00:00
template < typename ClientType , typename . . . ClientArguments >
static ErrorOr < NonnullRefPtr < ClientType > > launch_server_process (
2024-04-23 20:39:04 +00:00
StringView server_name ,
ReadonlySpan < ByteString > candidate_server_paths ,
2024-04-27 12:47:02 +00:00
Vector < ByteString > arguments ,
Ladybird : : EnableCallgrindProfiling enable_callgrind_profiling ,
2024-06-04 20:54:43 +00:00
ClientArguments & & . . . client_arguments )
2024-04-23 20:39:04 +00:00
{
2024-04-27 12:47:02 +00:00
if ( enable_callgrind_profiling = = Ladybird : : EnableCallgrindProfiling : : Yes ) {
arguments . prepend ( {
" --tool=callgrind " sv ,
" --instr-atstart=no " sv ,
" " sv , // Placeholder for the process path.
2024-04-23 20:39:04 +00:00
} ) ;
2024-04-27 12:47:02 +00:00
}
for ( auto [ i , path ] : enumerate ( candidate_server_paths ) ) {
Core : : ProcessSpawnOptions options { . name = server_name , . arguments = arguments } ;
if ( enable_callgrind_profiling = = Ladybird : : EnableCallgrindProfiling : : Yes ) {
options . executable = " valgrind " sv ;
options . search_for_executable_in_path = true ;
arguments [ 2 ] = path ;
} else {
options . executable = path ;
}
2024-06-04 20:54:43 +00:00
auto result = Core : : IPCProcess : : spawn < ClientType > ( move ( options ) , forward < ClientArguments > ( client_arguments ) . . . ) ;
2024-04-23 20:39:04 +00:00
if ( ! result . is_error ( ) ) {
auto process = result . release_value ( ) ;
2024-06-18 16:11:51 +00:00
if constexpr ( requires { process . client - > set_pid ( pid_t { } ) ; } )
process . client - > set_pid ( process . process . pid ( ) ) ;
2024-06-30 04:24:01 +00:00
WebView : : Application : : the ( ) . add_child_process ( WebView : : Process { WebView : : process_type_from_name ( server_name ) , process . client , move ( process . process ) } ) ;
2024-04-23 20:39:04 +00:00
2024-04-27 12:47:02 +00:00
if ( enable_callgrind_profiling = = Ladybird : : EnableCallgrindProfiling : : Yes ) {
dbgln ( ) ;
dbgln ( " \033 [1;45mLaunched {} process under callgrind! \033 [0m " , server_name ) ;
dbgln ( " \033 [100mRun ` \033 [4mcallgrind_control -i on \033 [24m` to start instrumentation and ` \033 [4mcallgrind_control -i off \033 [24m` stop it again. \033 [0m " ) ;
dbgln ( ) ;
}
2024-04-23 20:39:04 +00:00
return move ( process . client ) ;
}
if ( i = = candidate_server_paths . size ( ) - 1 ) {
warnln ( " Could not launch any of {}: {} " , candidate_server_paths , result . error ( ) ) ;
return result . release_error ( ) ;
}
}
VERIFY_NOT_REACHED ( ) ;
}
2023-12-01 17:18:40 +00:00
ErrorOr < NonnullRefPtr < WebView : : WebContentClient > > launch_web_content_process (
WebView : : ViewImplementation & view ,
2024-02-22 01:27:05 +00:00
ReadonlySpan < ByteString > candidate_web_content_paths ,
2024-04-15 23:39:48 +00:00
Ladybird : : WebContentOptions const & web_content_options ,
2024-06-26 19:44:42 +00:00
IPC : : File image_decoder_socket ,
2024-04-18 00:44:39 +00:00
Optional < IPC : : File > request_server_socket )
2023-02-02 10:00:30 +00:00
{
2024-04-23 20:39:04 +00:00
Vector < ByteString > arguments {
" --command-line " sv ,
web_content_options . command_line . to_byte_string ( ) ,
" --executable-path " sv ,
web_content_options . executable_path . to_byte_string ( ) ,
} ;
2023-08-01 17:56:10 +00:00
2024-07-16 16:52:12 +00:00
if ( web_content_options . config_path . has_value ( ) ) {
arguments . append ( " --config-path " sv ) ;
arguments . append ( web_content_options . config_path . value ( ) ) ;
}
2024-04-23 20:39:04 +00:00
if ( web_content_options . is_layout_test_mode = = Ladybird : : IsLayoutTestMode : : Yes )
arguments . append ( " --layout-test-mode " sv ) ;
if ( web_content_options . use_lagom_networking = = Ladybird : : UseLagomNetworking : : Yes )
arguments . append ( " --use-lagom-networking " sv ) ;
if ( web_content_options . wait_for_debugger = = Ladybird : : WaitForDebugger : : Yes )
arguments . append ( " --wait-for-debugger " sv ) ;
if ( web_content_options . log_all_js_exceptions = = Ladybird : : LogAllJSExceptions : : Yes )
arguments . append ( " --log-all-js-exceptions " sv ) ;
if ( web_content_options . enable_idl_tracing = = Ladybird : : EnableIDLTracing : : Yes )
arguments . append ( " --enable-idl-tracing " sv ) ;
2024-06-22 16:53:11 +00:00
if ( web_content_options . enable_http_cache = = Ladybird : : EnableHTTPCache : : Yes )
arguments . append ( " --enable-http-cache " sv ) ;
2024-04-23 20:39:04 +00:00
if ( web_content_options . expose_internals_object = = Ladybird : : ExposeInternalsObject : : Yes )
arguments . append ( " --expose-internals-object " sv ) ;
if ( auto server = mach_server_name ( ) ; server . has_value ( ) ) {
arguments . append ( " --mach-server-name " sv ) ;
arguments . append ( server . value ( ) ) ;
}
if ( request_server_socket . has_value ( ) ) {
arguments . append ( " --request-server-socket " sv ) ;
arguments . append ( ByteString : : number ( request_server_socket - > fd ( ) ) ) ;
2023-08-01 17:56:10 +00:00
}
2024-06-26 19:44:42 +00:00
arguments . append ( " --image-decoder-socket " sv ) ;
arguments . append ( ByteString : : number ( image_decoder_socket . fd ( ) ) ) ;
2024-06-26 18:57:15 +00:00
return launch_server_process < WebView : : WebContentClient > ( " WebContent " sv , candidate_web_content_paths , move ( arguments ) , web_content_options . enable_callgrind_profiling , view ) ;
2023-08-01 20:39:19 +00:00
}
2023-08-03 00:13:23 +00:00
2024-02-22 01:27:05 +00:00
ErrorOr < NonnullRefPtr < ImageDecoderClient : : Client > > launch_image_decoder_process ( ReadonlySpan < ByteString > candidate_image_decoder_paths )
2023-09-08 10:30:50 +00:00
{
2024-06-26 18:54:57 +00:00
Vector < ByteString > arguments ;
if ( auto server = mach_server_name ( ) ; server . has_value ( ) ) {
arguments . append ( " --mach-server-name " sv ) ;
arguments . append ( server . value ( ) ) ;
}
2024-06-26 18:57:15 +00:00
return launch_server_process < ImageDecoderClient : : Client > ( " ImageDecoder " sv , candidate_image_decoder_paths , arguments , Ladybird : : EnableCallgrindProfiling : : No ) ;
2023-09-08 10:30:50 +00:00
}
2024-07-06 02:41:07 +00:00
ErrorOr < NonnullRefPtr < Web : : HTML : : WebWorkerClient > > launch_web_worker_process ( ReadonlySpan < ByteString > candidate_web_worker_paths , RefPtr < Protocol : : RequestClient > request_client )
2024-01-06 20:13:59 +00:00
{
2024-07-06 02:41:07 +00:00
Vector < ByteString > arguments ;
if ( request_client ) {
auto socket = TRY ( connect_new_request_server_client ( * request_client ) ) ;
arguments . append ( " --request-server-socket " sv ) ;
arguments . append ( ByteString : : number ( socket . fd ( ) ) ) ;
arguments . append ( " --use-lagom-networking " sv ) ;
return launch_server_process < Web : : HTML : : WebWorkerClient > ( " WebWorker " sv , candidate_web_worker_paths , move ( arguments ) , Ladybird : : EnableCallgrindProfiling : : No ) ;
}
2024-04-15 23:39:48 +00:00
2024-06-26 18:57:15 +00:00
return launch_server_process < Web : : HTML : : WebWorkerClient > ( " WebWorker " sv , candidate_web_worker_paths , move ( arguments ) , Ladybird : : EnableCallgrindProfiling : : No ) ;
2024-01-06 20:13:59 +00:00
}
2024-02-22 01:27:05 +00:00
ErrorOr < NonnullRefPtr < Protocol : : RequestClient > > launch_request_server_process ( ReadonlySpan < ByteString > candidate_request_server_paths , StringView serenity_resource_root , Vector < ByteString > const & certificates )
2023-08-03 00:13:23 +00:00
{
2024-04-23 20:39:04 +00:00
Vector < ByteString > arguments ;
2024-04-15 23:39:48 +00:00
if ( ! serenity_resource_root . is_empty ( ) ) {
arguments . append ( " --serenity-resource-root " sv ) ;
arguments . append ( serenity_resource_root ) ;
}
2024-04-22 16:57:38 +00:00
2024-04-23 20:39:04 +00:00
for ( auto const & certificate : certificates )
arguments . append ( ByteString : : formatted ( " --certificate={} " , certificate ) ) ;
2024-04-15 23:39:48 +00:00
2024-04-22 16:57:38 +00:00
if ( auto server = mach_server_name ( ) ; server . has_value ( ) ) {
arguments . append ( " --mach-server-name " sv ) ;
arguments . append ( server . value ( ) ) ;
}
2024-06-26 18:57:15 +00:00
return launch_server_process < Protocol : : RequestClient > ( " RequestServer " sv , candidate_request_server_paths , move ( arguments ) , Ladybird : : EnableCallgrindProfiling : : No ) ;
2024-04-15 23:39:48 +00:00
}
2024-04-18 00:44:39 +00:00
ErrorOr < IPC : : File > connect_new_request_server_client ( Protocol : : RequestClient & client )
2024-04-15 23:39:48 +00:00
{
2024-04-18 00:44:39 +00:00
auto new_socket = client . send_sync_but_allow_failure < Messages : : RequestServer : : ConnectNewClient > ( ) ;
if ( ! new_socket )
2024-04-15 23:39:48 +00:00
return Error : : from_string_literal ( " Failed to connect to RequestServer " ) ;
2024-04-18 00:44:39 +00:00
auto socket = new_socket - > take_client_socket ( ) ;
2024-06-25 20:57:16 +00:00
TRY ( socket . clear_close_on_exec ( ) ) ;
2024-04-15 23:39:48 +00:00
2024-04-18 00:44:39 +00:00
return socket ;
2023-08-03 00:13:23 +00:00
}
2024-06-26 19:44:42 +00:00
ErrorOr < IPC : : File > connect_new_image_decoder_client ( ImageDecoderClient : : Client & client )
{
auto new_socket = client . send_sync_but_allow_failure < Messages : : ImageDecoderServer : : ConnectNewClients > ( 1 ) ;
if ( ! new_socket )
return Error : : from_string_literal ( " Failed to connect to ImageDecoder " ) ;
auto sockets = new_socket - > take_sockets ( ) ;
if ( sockets . size ( ) ! = 1 )
return Error : : from_string_literal ( " Failed to connect to ImageDecoder " ) ;
auto socket = sockets . take_last ( ) ;
TRY ( socket . clear_close_on_exec ( ) ) ;
return socket ;
}