2023-02-02 05:00:30 -05:00
/*
* Copyright ( c ) 2023 , Andrew Kaster < akaster @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2024-04-23 16:39:04 -04:00
# include <AK/Enumerate.h>
# include <LibCore/Process.h>
2024-06-30 00:24:01 -04:00
# include <LibWebView/Application.h>
2024-11-10 10:26:07 -05:00
# include <LibWebView/HelperProcess.h>
# include <LibWebView/Utilities.h>
namespace WebView {
2023-02-02 05:00:30 -05:00
2024-06-04 16:54:43 -04:00
template < typename ClientType , typename . . . ClientArguments >
static ErrorOr < NonnullRefPtr < ClientType > > launch_server_process (
2024-04-23 16:39:04 -04:00
StringView server_name ,
2024-04-27 08:47:02 -04:00
Vector < ByteString > arguments ,
2024-06-04 16:54:43 -04:00
ClientArguments & & . . . client_arguments )
2024-04-23 16:39:04 -04:00
{
2024-08-01 07:03:03 -04:00
auto process_type = WebView : : process_type_from_name ( server_name ) ;
auto const & chrome_options = WebView : : Application : : chrome_options ( ) ;
2024-11-13 16:04:33 -05:00
auto candidate_server_paths = TRY ( get_paths_for_helper_process ( server_name ) ) ;
2024-08-01 07:13:09 -04:00
if ( chrome_options . profile_helper_process = = process_type ) {
2024-04-27 08:47:02 -04:00
arguments . prepend ( {
" --tool=callgrind " sv ,
" --instr-atstart=no " sv ,
" " sv , // Placeholder for the process path.
2024-04-23 16:39:04 -04:00
} ) ;
2024-04-27 08:47:02 -04:00
}
2024-08-01 07:03:03 -04:00
if ( chrome_options . debug_helper_process = = process_type )
arguments . append ( " --wait-for-debugger " sv ) ;
2024-04-27 08:47:02 -04:00
for ( auto [ i , path ] : enumerate ( candidate_server_paths ) ) {
Core : : ProcessSpawnOptions options { . name = server_name , . arguments = arguments } ;
2024-08-01 07:13:09 -04:00
if ( chrome_options . profile_helper_process = = process_type ) {
2024-04-27 08:47:02 -04:00
options . executable = " valgrind " sv ;
options . search_for_executable_in_path = true ;
arguments [ 2 ] = path ;
} else {
options . executable = path ;
}
2024-10-22 15:27:15 -04:00
auto result = WebView : : Process : : spawn < ClientType > ( process_type , move ( options ) , forward < ClientArguments > ( client_arguments ) . . . ) ;
2024-04-23 16:39:04 -04:00
if ( ! result . is_error ( ) ) {
2024-10-22 15:27:15 -04:00
auto & & [ process , client ] = result . release_value ( ) ;
2024-04-23 16:39:04 -04:00
2024-10-22 15:27:15 -04:00
if constexpr ( requires { client - > set_pid ( pid_t { } ) ; } )
client - > set_pid ( process . pid ( ) ) ;
2024-06-18 12:11:51 -04:00
2024-10-22 15:27:15 -04:00
WebView : : Application : : the ( ) . add_child_process ( move ( process ) ) ;
2024-04-23 16:39:04 -04:00
2024-08-01 07:13:09 -04:00
if ( chrome_options . profile_helper_process = = process_type ) {
2024-04-27 08:47:02 -04:00
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-10-22 15:27:15 -04:00
return move ( client ) ;
2024-04-23 16:39:04 -04:00
}
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 12:18:40 -05:00
ErrorOr < NonnullRefPtr < WebView : : WebContentClient > > launch_web_content_process (
WebView : : ViewImplementation & view ,
2024-06-26 15:44:42 -04:00
IPC : : File image_decoder_socket ,
2024-04-17 20:44:39 -04:00
Optional < IPC : : File > request_server_socket )
2023-02-02 05:00:30 -05:00
{
2024-07-30 14:01:05 -04:00
auto const & web_content_options = WebView : : Application : : web_content_options ( ) ;
2024-04-23 16:39:04 -04: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 13:56:10 -04:00
2024-07-16 12:52:12 -04:00
if ( web_content_options . config_path . has_value ( ) ) {
arguments . append ( " --config-path " sv ) ;
arguments . append ( web_content_options . config_path . value ( ) ) ;
}
2024-07-30 14:01:05 -04:00
if ( web_content_options . is_layout_test_mode = = WebView : : IsLayoutTestMode : : Yes )
2024-04-23 16:39:04 -04:00
arguments . append ( " --layout-test-mode " sv ) ;
2024-07-30 14:01:05 -04:00
if ( web_content_options . log_all_js_exceptions = = WebView : : LogAllJSExceptions : : Yes )
2024-04-23 16:39:04 -04:00
arguments . append ( " --log-all-js-exceptions " sv ) ;
2024-07-30 14:01:05 -04:00
if ( web_content_options . enable_idl_tracing = = WebView : : EnableIDLTracing : : Yes )
2024-04-23 16:39:04 -04:00
arguments . append ( " --enable-idl-tracing " sv ) ;
2024-07-30 14:01:05 -04:00
if ( web_content_options . enable_http_cache = = WebView : : EnableHTTPCache : : Yes )
2024-06-22 12:53:11 -04:00
arguments . append ( " --enable-http-cache " sv ) ;
2024-07-30 14:01:05 -04:00
if ( web_content_options . expose_internals_object = = WebView : : ExposeInternalsObject : : Yes )
2024-04-23 16:39:04 -04:00
arguments . append ( " --expose-internals-object " sv ) ;
2024-08-01 13:49:24 -04:00
if ( web_content_options . force_cpu_painting = = WebView : : ForceCPUPainting : : Yes )
arguments . append ( " --force-cpu-painting " sv ) ;
2024-08-19 14:35:49 -04:00
if ( web_content_options . force_fontconfig = = WebView : : ForceFontconfig : : Yes )
arguments . append ( " --force-fontconfig " sv ) ;
2024-10-31 11:06:01 -04:00
if ( web_content_options . collect_garbage_on_every_allocation = = WebView : : CollectGarbageOnEveryAllocation : : Yes )
arguments . append ( " --collect-garbage-on-every-allocation " sv ) ;
2024-12-09 16:51:19 -05:00
if ( web_content_options . is_headless = = WebView : : IsHeadless : : Yes )
arguments . append ( " --headless " sv ) ;
2024-12-16 06:23:10 -05:00
if ( web_content_options . paint_viewport_scrollbars = = PaintViewportScrollbars : : No )
arguments . append ( " --disable-scrollbar-painting " sv ) ;
2024-10-31 11:06:01 -04:00
2024-12-02 20:46:04 -05:00
if ( auto const maybe_echo_server_port = web_content_options . echo_server_port ; maybe_echo_server_port . has_value ( ) ) {
arguments . append ( " --echo-server-port " sv ) ;
arguments . append ( ByteString : : number ( maybe_echo_server_port . value ( ) ) ) ;
}
2024-04-23 16:39:04 -04:00
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 13:56:10 -04:00
}
2024-06-26 15:44:42 -04:00
arguments . append ( " --image-decoder-socket " sv ) ;
arguments . append ( ByteString : : number ( image_decoder_socket . fd ( ) ) ) ;
2024-11-13 16:04:33 -05:00
return launch_server_process < WebView : : WebContentClient > ( " WebContent " sv , move ( arguments ) , view ) ;
2023-08-01 16:39:19 -04:00
}
2023-08-02 20:13:23 -04:00
2024-11-13 16:04:33 -05:00
ErrorOr < NonnullRefPtr < ImageDecoderClient : : Client > > launch_image_decoder_process ( )
2023-09-08 06:30:50 -04:00
{
2024-06-26 14:54:57 -04:00
Vector < ByteString > arguments ;
if ( auto server = mach_server_name ( ) ; server . has_value ( ) ) {
arguments . append ( " --mach-server-name " sv ) ;
arguments . append ( server . value ( ) ) ;
}
2024-11-13 16:04:33 -05:00
return launch_server_process < ImageDecoderClient : : Client > ( " ImageDecoder " sv , arguments ) ;
2023-09-08 06:30:50 -04:00
}
2024-11-13 16:04:33 -05:00
ErrorOr < NonnullRefPtr < Web : : HTML : : WebWorkerClient > > launch_web_worker_process ( )
2024-01-06 15:13:59 -05:00
{
2024-07-05 22:41:07 -04:00
Vector < ByteString > arguments ;
2024-10-07 15:18:07 -04:00
2024-11-13 15:33:02 -05:00
auto socket = TRY ( connect_new_request_server_client ( ) ) ;
2024-10-07 15:18:07 -04:00
arguments . append ( " --request-server-socket " sv ) ;
arguments . append ( ByteString : : number ( socket . fd ( ) ) ) ;
2024-04-15 19:39:48 -04:00
2024-11-13 16:04:33 -05:00
return launch_server_process < Web : : HTML : : WebWorkerClient > ( " WebWorker " sv , move ( arguments ) ) ;
2024-01-06 15:13:59 -05:00
}
2024-11-13 16:04:33 -05:00
ErrorOr < NonnullRefPtr < Requests : : RequestClient > > launch_request_server_process ( )
2023-08-02 20:13:23 -04:00
{
2024-04-23 16:39:04 -04:00
Vector < ByteString > arguments ;
2024-11-13 15:33:02 -05:00
if ( ! s_ladybird_resource_root . is_empty ( ) ) {
2024-04-15 19:39:48 -04:00
arguments . append ( " --serenity-resource-root " sv ) ;
2024-11-13 15:33:02 -05:00
arguments . append ( s_ladybird_resource_root ) ;
2024-04-15 19:39:48 -04:00
}
2024-04-22 12:57:38 -04:00
2024-07-30 14:01:05 -04:00
for ( auto const & certificate : WebView : : Application : : chrome_options ( ) . certificates )
2024-04-23 16:39:04 -04:00
arguments . append ( ByteString : : formatted ( " --certificate={} " , certificate ) ) ;
2024-04-15 19:39:48 -04:00
2024-04-22 12:57:38 -04:00
if ( auto server = mach_server_name ( ) ; server . has_value ( ) ) {
arguments . append ( " --mach-server-name " sv ) ;
arguments . append ( server . value ( ) ) ;
}
2024-11-01 18:53:43 -04:00
auto client = TRY ( launch_server_process < Requests : : RequestClient > ( " RequestServer " sv , move ( arguments ) ) ) ;
WebView : : Application : : chrome_options ( ) . dns_settings . visit (
[ ] ( WebView : : SystemDNS ) { } ,
[ & ] ( WebView : : DNSOverTLS const & dns_over_tls ) {
dbgln ( " Setting DNS server to {}:{} with TLS " , dns_over_tls . server_address , dns_over_tls . port ) ;
client - > async_set_dns_server ( dns_over_tls . server_address , dns_over_tls . port , true ) ;
} ,
[ & ] ( WebView : : DNSOverUDP const & dns_over_udp ) {
dbgln ( " Setting DNS server to {}:{} " , dns_over_udp . server_address , dns_over_udp . port ) ;
client - > async_set_dns_server ( dns_over_udp . server_address , dns_over_udp . port , false ) ;
} ) ;
return client ;
2024-04-15 19:39:48 -04:00
}
2024-11-13 15:33:02 -05:00
ErrorOr < IPC : : File > connect_new_request_server_client ( )
2024-04-15 19:39:48 -04:00
{
2024-11-13 15:33:02 -05:00
auto new_socket = Application : : request_server_client ( ) . send_sync_but_allow_failure < Messages : : RequestServer : : ConnectNewClient > ( ) ;
2024-04-17 20:44:39 -04:00
if ( ! new_socket )
2024-04-15 19:39:48 -04:00
return Error : : from_string_literal ( " Failed to connect to RequestServer " ) ;
2024-04-17 20:44:39 -04:00
auto socket = new_socket - > take_client_socket ( ) ;
2024-06-25 16:57:16 -04:00
TRY ( socket . clear_close_on_exec ( ) ) ;
2024-04-15 19:39:48 -04:00
2024-04-17 20:44:39 -04:00
return socket ;
2023-08-02 20:13:23 -04:00
}
2024-06-26 15:44:42 -04:00
2024-11-13 15:33:02 -05:00
ErrorOr < IPC : : File > connect_new_image_decoder_client ( )
2024-06-26 15:44:42 -04:00
{
2024-11-13 15:33:02 -05:00
auto new_socket = Application : : image_decoder_client ( ) . send_sync_but_allow_failure < Messages : : ImageDecoderServer : : ConnectNewClients > ( 1 ) ;
2024-06-26 15:44:42 -04:00
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 ;
}
2024-11-10 10:26:07 -05:00
}