2022-10-05 15:23:41 +02:00
/*
2024-10-04 13:19:50 +02:00
* Copyright ( c ) 2020 - 2024 , Andreas Kling < andreas @ ladybird . org >
2022-10-05 15:23:41 +02:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include <AK/LexicalPath.h>
2023-08-05 10:42:26 -06:00
# include <Ladybird/FontPlugin.h>
# include <Ladybird/ImageCodecPlugin.h>
# include <Ladybird/Utilities.h>
2022-11-14 08:13:37 -05:00
# include <LibCore/ArgsParser.h>
2022-10-05 15:23:41 +02:00
# include <LibCore/EventLoop.h>
# include <LibCore/LocalServer.h>
2023-12-20 09:52:17 -07:00
# include <LibCore/Process.h>
2024-02-23 13:40:16 -07:00
# include <LibCore/Resource.h>
2022-11-14 08:13:37 -05:00
# include <LibCore/SystemServerTakeover.h>
2024-08-19 20:35:49 +02:00
# include <LibGfx/Font/FontDatabase.h>
2022-11-14 08:13:37 -05:00
# include <LibIPC/ConnectionFromClient.h>
2023-06-17 13:16:35 +02:00
# include <LibJS/Bytecode/Interpreter.h>
2022-10-05 15:23:41 +02:00
# include <LibMain/Main.h>
2024-08-28 12:08:38 +02:00
# include <LibMedia/Audio/Loader.h>
2024-08-06 21:51:20 -06:00
# include <LibRequests/RequestClient.h>
2023-03-17 10:56:59 -04:00
# include <LibWeb/Bindings/MainThreadVM.h>
2023-07-21 11:59:49 +02:00
# include <LibWeb/HTML/Window.h>
2022-10-05 15:23:41 +02:00
# include <LibWeb/Loader/ContentFilter.h>
2023-09-21 17:32:31 +02:00
# include <LibWeb/Loader/GeneratedPagesLoader.h>
2022-10-05 15:23:41 +02:00
# include <LibWeb/Loader/ResourceLoader.h>
2023-04-17 13:55:42 -04:00
# include <LibWeb/PermissionsPolicy/AutoplayAllowlist.h>
2023-07-04 05:02:19 -05:00
# include <LibWeb/Platform/AudioCodecPluginAgnostic.h>
2023-04-24 18:02:29 +02:00
# include <LibWeb/Platform/EventLoopPluginSerenity.h>
2022-10-05 15:23:41 +02:00
# include <WebContent/ConnectionFromClient.h>
2023-11-29 09:34:38 -07:00
# include <WebContent/PageClient.h>
2022-11-14 11:08:44 -05:00
# include <WebContent/WebDriverConnection.h>
2022-10-05 15:23:41 +02:00
2023-08-07 19:42:06 -06:00
# if defined(HAVE_QT)
# include <Ladybird / Qt / EventLoopImplementationQt.h>
# include <QCoreApplication>
2023-11-02 13:53:38 -04:00
# if defined(HAVE_QT_MULTIMEDIA)
# include <Ladybird / Qt / AudioCodecPluginQt.h>
# endif
2023-08-07 19:42:06 -06:00
# endif
2024-04-04 14:13:14 -06:00
# if defined(AK_OS_MACOS)
2024-04-20 23:35:17 -04:00
# include <LibCore / Platform / ProcessStatisticsMach.h>
2024-04-04 14:13:14 -06:00
# endif
2024-07-16 18:52:12 +02:00
static ErrorOr < void > load_content_filters ( StringView config_path ) ;
static ErrorOr < void > load_autoplay_allowlist ( StringView config_path ) ;
2024-10-07 16:07:48 -04:00
static ErrorOr < void > initialize_resource_loader ( int request_server_socket ) ;
2024-06-26 13:44:42 -06:00
static ErrorOr < void > initialize_image_decoder ( int image_decoder_socket ) ;
static ErrorOr < void > reinitialize_image_decoder ( IPC : : File const & image_decoder_socket ) ;
2022-10-05 15:23:41 +02:00
2024-04-16 08:02:41 +02:00
namespace JS {
extern bool g_log_all_js_exceptions ;
}
2024-04-16 14:39:57 +02:00
namespace Web : : WebIDL {
extern bool g_enable_idl_tracing ;
}
2024-06-22 18:53:11 +02:00
namespace Web : : Fetch : : Fetching {
extern bool g_http_cache_enabled ;
}
2022-10-05 15:23:41 +02:00
ErrorOr < int > serenity_main ( Main : : Arguments arguments )
{
2023-12-11 11:19:41 -07:00
AK : : set_rich_debug_enabled ( true ) ;
2023-08-07 19:42:06 -06:00
# if defined(HAVE_QT)
2023-07-30 14:37:30 +02:00
QCoreApplication app ( arguments . argc , arguments . argv ) ;
2022-10-05 15:23:41 +02:00
2023-04-25 17:38:48 +02:00
Core : : EventLoopManager : : install ( * new Ladybird : : EventLoopManagerQt ) ;
2023-08-07 19:42:06 -06:00
# endif
2023-04-24 14:51:19 +02:00
Core : : EventLoop event_loop ;
2022-10-07 17:08:29 -06:00
platform_init ( ) ;
2023-04-24 18:02:29 +02:00
Web : : Platform : : EventLoopPlugin : : install ( * new Web : : Platform : : EventLoopPluginSerenity ) ;
2023-06-12 13:44:10 -04:00
2023-06-20 12:43:04 -04:00
Web : : Platform : : AudioCodecPlugin : : install_creation_hook ( [ ] ( auto loader ) {
2023-11-02 13:53:38 -04:00
# if defined(HAVE_QT_MULTIMEDIA)
2023-08-02 12:01:17 -06:00
return Ladybird : : AudioCodecPluginQt : : create ( move ( loader ) ) ;
2023-11-02 13:53:38 -04:00
# elif defined(AK_OS_MACOS) || defined(HAVE_PULSEAUDIO)
return Web : : Platform : : AudioCodecPluginAgnostic : : create ( move ( loader ) ) ;
2023-08-07 19:42:06 -06:00
# else
2023-08-14 13:05:16 -04:00
( void ) loader ;
return Error : : from_string_literal ( " Don't know how to initialize audio in this configuration! " ) ;
2023-07-04 05:02:19 -05:00
# endif
2023-06-12 13:44:10 -04:00
} ) ;
2022-10-05 15:23:41 +02:00
2024-01-16 18:55:40 +01:00
StringView command_line { } ;
StringView executable_path { } ;
2024-07-21 16:50:14 +02:00
auto config_path = ByteString : : formatted ( " {}/ladybird/default-config " , s_ladybird_resource_root ) ;
2024-04-04 14:13:14 -06:00
StringView mach_server_name { } ;
2024-02-06 08:25:22 -07:00
Vector < ByteString > certificates ;
2024-04-15 17:39:48 -06:00
int request_server_socket { - 1 } ;
2024-06-26 13:44:42 -06:00
int image_decoder_socket { - 1 } ;
2023-05-06 12:46:14 +02:00
bool is_layout_test_mode = false ;
2024-04-21 08:46:38 +12:00
bool expose_internals_object = false ;
2023-12-20 09:52:17 -07:00
bool wait_for_debugger = false ;
2024-04-16 08:02:41 +02:00
bool log_all_js_exceptions = false ;
2024-04-16 14:39:57 +02:00
bool enable_idl_tracing = false ;
2024-06-22 18:53:11 +02:00
bool enable_http_cache = false ;
2024-08-01 18:49:24 +01:00
bool force_cpu_painting = false ;
2024-08-19 20:35:49 +02:00
bool force_fontconfig = false ;
2023-05-05 19:48:48 +02:00
Core : : ArgsParser args_parser ;
2024-01-16 18:55:40 +01:00
args_parser . add_option ( command_line , " Chrome process command line " , " command-line " , 0 , " command_line " ) ;
args_parser . add_option ( executable_path , " Chrome process executable path " , " executable-path " , 0 , " executable_path " ) ;
2024-07-16 18:52:12 +02:00
args_parser . add_option ( config_path , " Ladybird configuration path " , " config-path " , 0 , " config_path " ) ;
2024-04-15 17:39:48 -06:00
args_parser . add_option ( request_server_socket , " File descriptor of the socket for the RequestServer connection " , " request-server-socket " , ' r ' , " request_server_socket " ) ;
2024-06-26 13:44:42 -06: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-04-21 08:34:56 +12:00
args_parser . add_option ( is_layout_test_mode , " Is layout test mode " , " layout-test-mode " ) ;
2024-04-21 08:46:38 +12:00
args_parser . add_option ( expose_internals_object , " Expose internals object " , " expose-internals-object " ) ;
2024-07-10 12:50:21 +01:00
args_parser . add_option ( certificates , " Path to a certificate file " , " certificate " , ' C ' , " certificate " ) ;
2024-04-21 08:34:56 +12:00
args_parser . add_option ( wait_for_debugger , " Wait for debugger " , " wait-for-debugger " ) ;
2024-04-04 14:13:14 -06:00
args_parser . add_option ( mach_server_name , " Mach server name " , " mach-server-name " , 0 , " mach_server_name " ) ;
2024-04-21 08:34:56 +12:00
args_parser . add_option ( log_all_js_exceptions , " Log all JavaScript exceptions " , " log-all-js-exceptions " ) ;
args_parser . add_option ( enable_idl_tracing , " Enable IDL tracing " , " enable-idl-tracing " ) ;
2024-06-22 18:53:11 +02:00
args_parser . add_option ( enable_http_cache , " Enable HTTP cache " , " enable-http-cache " ) ;
2024-08-01 18:49:24 +01:00
args_parser . add_option ( force_cpu_painting , " Force CPU painting " , " force-cpu-painting " ) ;
2024-08-19 20:35:49 +02:00
args_parser . add_option ( force_fontconfig , " Force using fontconfig for font loading " , " force-fontconfig " ) ;
2023-10-27 17:28:18 +02:00
2023-05-05 19:48:48 +02:00
args_parser . parse ( arguments ) ;
2023-12-20 09:52:17 -07:00
if ( wait_for_debugger ) {
Core : : Process : : wait_for_debugger_and_break ( ) ;
}
2024-08-19 20:35:49 +02:00
if ( force_fontconfig ) {
Gfx : : FontDatabase : : the ( ) . set_force_fontconfig ( true ) ;
}
2024-09-04 17:26:16 +02:00
Gfx : : FontDatabase : : the ( ) . load_all_fonts_from_uri ( " resource://fonts " sv ) ;
2024-08-01 18:49:24 +01:00
// Layout test mode implies internals object is exposed and the Skia CPU backend is used
if ( is_layout_test_mode ) {
2024-04-21 08:46:38 +12:00
expose_internals_object = true ;
2024-08-01 18:49:24 +01:00
force_cpu_painting = true ;
}
2024-04-21 08:46:38 +12:00
2024-01-16 18:55:40 +01:00
Web : : set_chrome_process_command_line ( command_line ) ;
Web : : set_chrome_process_executable_path ( executable_path ) ;
2023-10-27 17:28:18 +02:00
2024-07-19 16:42:14 +02:00
// Always use the CPU backend for layout tests, as the GPU backend is not deterministic
2024-08-01 18:49:24 +01:00
WebContent : : PageClient : : set_use_skia_painter ( force_cpu_painting ? WebContent : : PageClient : : UseSkiaPainter : : CPUBackend : WebContent : : PageClient : : UseSkiaPainter : : GPUBackendIfAvailable ) ;
2024-06-15 00:18:04 +03:00
2024-06-22 18:53:11 +02:00
if ( enable_http_cache ) {
Web : : Fetch : : Fetching : : g_http_cache_enabled = true ;
}
2024-04-04 14:13:14 -06:00
# if defined(AK_OS_MACOS)
if ( ! mach_server_name . is_empty ( ) ) {
2024-08-30 13:26:17 -04:00
[[maybe_unused]] auto server_port = Core : : Platform : : register_with_mach_server ( mach_server_name ) ;
// FIXME: For some reason, our implementation of IOSurface does not work on Intel macOS. Remove this conditional
// compilation when that is resolved.
# if ARCH(AARCH64)
2024-06-20 21:34:51 +03:00
WebContent : : BackingStoreManager : : set_browser_mach_port ( move ( server_port ) ) ;
2024-08-30 13:26:17 -04:00
# endif
2024-04-04 14:13:14 -06:00
}
# endif
2024-10-07 16:07:48 -04:00
TRY ( initialize_resource_loader ( request_server_socket ) ) ;
2024-06-26 13:44:42 -06:00
TRY ( initialize_image_decoder ( image_decoder_socket ) ) ;
2024-04-21 08:46:38 +12:00
Web : : HTML : : Window : : set_internals_object_exposed ( expose_internals_object ) ;
2023-07-21 11:59:49 +02:00
2023-08-02 12:01:17 -06:00
Web : : Platform : : FontPlugin : : install ( * new Ladybird : : FontPlugin ( is_layout_test_mode ) ) ;
2022-10-05 15:23:41 +02:00
2024-07-09 02:59:25 -06:00
TRY ( Web : : Bindings : : initialize_main_thread_vm ( Web : : HTML : : EventLoop : : Type : : Window ) ) ;
2023-03-17 10:56:59 -04:00
2024-04-16 08:02:41 +02:00
if ( log_all_js_exceptions ) {
JS : : g_log_all_js_exceptions = true ;
}
2024-04-16 14:39:57 +02:00
if ( enable_idl_tracing ) {
Web : : WebIDL : : g_enable_idl_tracing = true ;
}
2024-07-16 18:52:12 +02:00
auto maybe_content_filter_error = load_content_filters ( config_path ) ;
2022-10-05 15:23:41 +02:00
if ( maybe_content_filter_error . is_error ( ) )
dbgln ( " Failed to load content filters: {} " , maybe_content_filter_error . error ( ) ) ;
2024-07-16 18:52:12 +02:00
auto maybe_autoplay_allowlist_error = load_autoplay_allowlist ( config_path ) ;
2023-04-17 13:55:42 -04:00
if ( maybe_autoplay_allowlist_error . is_error ( ) )
dbgln ( " Failed to load autoplay allowlist: {} " , maybe_autoplay_allowlist_error . error ( ) ) ;
2022-12-15 09:18:52 -05:00
auto webcontent_socket = TRY ( Core : : take_over_socket_from_system_server ( " WebContent " sv ) ) ;
auto webcontent_client = TRY ( WebContent : : ConnectionFromClient : : try_create ( move ( webcontent_socket ) ) ) ;
2024-06-26 13:44:42 -06:00
webcontent_client - > on_image_decoder_connection = [ & ] ( auto & socket_file ) {
auto maybe_error = reinitialize_image_decoder ( socket_file ) ;
if ( maybe_error . is_error ( ) )
dbgln ( " Failed to reinitialize image decoder: {} " , maybe_error . error ( ) ) ;
} ;
2023-04-24 14:51:19 +02:00
return event_loop . exec ( ) ;
2022-10-05 15:23:41 +02:00
}
2024-07-16 18:52:12 +02:00
static ErrorOr < void > load_content_filters ( StringView config_path )
2022-10-05 15:23:41 +02:00
{
auto buffer = TRY ( ByteBuffer : : create_uninitialized ( 4096 ) ) ;
2023-04-21 07:36:40 -04:00
2024-07-16 18:52:12 +02:00
auto file = TRY ( Core : : File : : open ( ByteString : : formatted ( " {}/BrowserContentFilters.txt " , config_path ) , Core : : File : : OpenMode : : Read ) ) ;
auto ad_filter_list = TRY ( Core : : InputBufferedFile : : create ( move ( file ) ) ) ;
2024-02-23 13:40:16 -07:00
2023-04-21 07:54:56 -04:00
Vector < String > patterns ;
2023-04-21 07:36:40 -04:00
2022-10-05 15:23:41 +02:00
while ( TRY ( ad_filter_list - > can_read_line ( ) ) ) {
auto line = TRY ( ad_filter_list - > read_line ( buffer ) ) ;
2023-04-21 07:36:40 -04:00
if ( line . is_empty ( ) )
continue ;
2023-04-21 07:54:56 -04:00
auto pattern = TRY ( String : : from_utf8 ( line ) ) ;
TRY ( patterns . try_append ( move ( pattern ) ) ) ;
2022-10-05 15:23:41 +02:00
}
2023-04-21 07:36:40 -04:00
auto & content_filter = Web : : ContentFilter : : the ( ) ;
TRY ( content_filter . set_patterns ( patterns ) ) ;
2022-10-05 15:23:41 +02:00
return { } ;
}
2023-04-17 13:55:42 -04:00
2024-07-16 18:52:12 +02:00
static ErrorOr < void > load_autoplay_allowlist ( StringView config_path )
2023-04-17 13:55:42 -04:00
{
auto buffer = TRY ( ByteBuffer : : create_uninitialized ( 4096 ) ) ;
2024-07-16 18:52:12 +02:00
auto file = TRY ( Core : : File : : open ( ByteString : : formatted ( " {}/BrowserAutoplayAllowlist.txt " , config_path ) , Core : : File : : OpenMode : : Read ) ) ;
auto allowlist = TRY ( Core : : InputBufferedFile : : create ( move ( file ) ) ) ;
2024-02-23 13:40:16 -07:00
2023-04-17 13:55:42 -04:00
Vector < String > origins ;
while ( TRY ( allowlist - > can_read_line ( ) ) ) {
auto line = TRY ( allowlist - > read_line ( buffer ) ) ;
if ( line . is_empty ( ) )
continue ;
auto domain = TRY ( String : : from_utf8 ( line ) ) ;
TRY ( origins . try_append ( move ( domain ) ) ) ;
}
auto & autoplay_allowlist = Web : : PermissionsPolicy : : AutoplayAllowlist : : the ( ) ;
TRY ( autoplay_allowlist . enable_for_origins ( origins ) ) ;
return { } ;
}
2023-08-07 19:42:06 -06:00
2024-10-07 16:07:48 -04:00
ErrorOr < void > initialize_resource_loader ( int request_server_socket )
2023-08-07 19:42:06 -06:00
{
2024-04-15 17:39:48 -06:00
auto socket = TRY ( Core : : LocalSocket : : adopt_fd ( request_server_socket ) ) ;
TRY ( socket - > set_blocking ( true ) ) ;
2023-08-07 19:42:06 -06:00
2024-10-07 16:07:48 -04:00
auto request_client = TRY ( try_make_ref_counted < Requests : : RequestClient > ( move ( socket ) ) ) ;
Web : : ResourceLoader : : initialize ( move ( request_client ) ) ;
2024-04-15 17:39:48 -06:00
2023-08-07 19:42:06 -06:00
return { } ;
}
2024-06-26 13:44:42 -06:00
ErrorOr < void > initialize_image_decoder ( int image_decoder_socket )
{
auto socket = TRY ( Core : : LocalSocket : : adopt_fd ( image_decoder_socket ) ) ;
TRY ( socket - > set_blocking ( true ) ) ;
auto new_client = TRY ( try_make_ref_counted < ImageDecoderClient : : Client > ( move ( socket ) ) ) ;
Web : : Platform : : ImageCodecPlugin : : install ( * new Ladybird : : ImageCodecPlugin ( move ( new_client ) ) ) ;
return { } ;
}
ErrorOr < void > reinitialize_image_decoder ( IPC : : File const & image_decoder_socket )
{
auto socket = TRY ( Core : : LocalSocket : : adopt_fd ( image_decoder_socket . take_fd ( ) ) ) ;
TRY ( socket - > set_blocking ( true ) ) ;
auto new_client = TRY ( try_make_ref_counted < ImageDecoderClient : : Client > ( move ( socket ) ) ) ;
static_cast < Ladybird : : ImageCodecPlugin & > ( Web : : Platform : : ImageCodecPlugin : : the ( ) ) . set_client ( move ( new_client ) ) ;
return { } ;
}