2022-10-05 15:23:41 +02:00
/*
2024-04-16 08:02:41 +02:00
* Copyright ( c ) 2020 - 2024 , Andreas Kling < kling @ serenityos . 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/HelperProcess.h>
# include <Ladybird/ImageCodecPlugin.h>
# include <Ladybird/Utilities.h>
2023-06-20 12:43:04 -04:00
# include <LibAudio/Loader.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-10-05 15:23:41 +02:00
# include <LibCore/System.h>
2022-11-14 08:13:37 -05:00
# include <LibCore/SystemServerTakeover.h>
# 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>
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 <LibWeb/WebSockets/WebSocket.h>
2023-08-01 14:39:19 -06:00
# include <LibWebView/RequestServerAdapter.h>
2023-08-02 18:13:23 -06:00
# include <LibWebView/WebSocketClientAdapter.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 <Ladybird / Qt / RequestManagerQt.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)
# include <LibWebView / Platform / ProcessStatisticsMach.h>
# endif
2022-10-05 15:23:41 +02:00
static ErrorOr < void > load_content_filters ( ) ;
2023-04-17 13:55:42 -04:00
static ErrorOr < void > load_autoplay_allowlist ( ) ;
2024-02-06 08:25:22 -07:00
static ErrorOr < void > initialize_lagom_networking ( Vector < ByteString > const & certificates ) ;
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 ;
}
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-08-02 12:01:17 -06:00
Web : : Platform : : ImageCodecPlugin : : install ( * new Ladybird : : ImageCodecPlugin ) ;
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-04-04 14:13:14 -06:00
StringView mach_server_name { } ;
2024-02-06 08:25:22 -07:00
Vector < ByteString > certificates ;
2023-05-05 19:48:48 +02:00
int webcontent_fd_passing_socket { - 1 } ;
2023-05-06 12:46:14 +02:00
bool is_layout_test_mode = false ;
2023-08-01 14:39:19 -06:00
bool use_lagom_networking = false ;
2023-10-27 17:28:18 +02:00
bool use_gpu_painting = 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 ;
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-02-06 08:25:22 -07:00
args_parser . add_option ( certificates , " Path to a certificate file " , " certificate " , ' C ' , " certificate " ) ;
2023-05-05 19:48:48 +02:00
args_parser . add_option ( webcontent_fd_passing_socket , " File descriptor of the passing socket for the WebContent connection " , " webcontent-fd-passing-socket " , ' c ' , " webcontent_fd_passing_socket " ) ;
2023-05-06 12:46:14 +02:00
args_parser . add_option ( is_layout_test_mode , " Is layout test mode " , " layout-test-mode " , 0 ) ;
2023-08-01 14:39:19 -06:00
args_parser . add_option ( use_lagom_networking , " Enable Lagom servers for networking " , " use-lagom-networking " , 0 ) ;
2023-10-27 17:28:18 +02:00
args_parser . add_option ( use_gpu_painting , " Enable GPU painting " , " use-gpu-painting " , 0 ) ;
2023-12-20 09:52:17 -07:00
args_parser . add_option ( wait_for_debugger , " Wait for debugger " , " wait-for-debugger " , 0 ) ;
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-16 08:02:41 +02:00
args_parser . add_option ( log_all_js_exceptions , " Log all JavaScript exceptions " , " log-all-js-exceptions " , 0 ) ;
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-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
if ( use_gpu_painting ) {
2023-11-29 09:34:38 -07:00
WebContent : : PageClient : : set_use_gpu_painter ( ) ;
2023-10-27 17:28:18 +02:00
}
2024-04-04 14:13:14 -06:00
# if defined(AK_OS_MACOS)
if ( ! mach_server_name . is_empty ( ) ) {
WebView : : register_with_mach_server ( mach_server_name ) ;
}
# endif
2023-08-07 19:42:06 -06:00
# if defined(HAVE_QT)
2024-03-06 01:50:52 +01:00
if ( ! use_lagom_networking )
2023-08-02 11:52:59 -06:00
Web : : ResourceLoader : : initialize ( Ladybird : : RequestManagerQt : : create ( ) ) ;
2024-03-06 01:50:52 +01:00
else
2023-08-07 19:42:06 -06:00
# endif
2024-02-06 08:25:22 -07:00
TRY ( initialize_lagom_networking ( certificates ) ) ;
2023-08-01 14:39:19 -06:00
2023-07-21 11:59:49 +02:00
Web : : HTML : : Window : : set_internals_object_exposed ( is_layout_test_mode ) ;
2023-05-05 19:48:48 +02:00
VERIFY ( webcontent_fd_passing_socket > = 0 ) ;
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
2023-03-17 10:56:59 -04:00
TRY ( Web : : Bindings : : initialize_main_thread_vm ( ) ) ;
2024-04-16 08:02:41 +02:00
if ( log_all_js_exceptions ) {
JS : : g_log_all_js_exceptions = true ;
}
2022-10-05 15:23:41 +02:00
auto maybe_content_filter_error = load_content_filters ( ) ;
if ( maybe_content_filter_error . is_error ( ) )
dbgln ( " Failed to load content filters: {} " , maybe_content_filter_error . error ( ) ) ;
2023-04-17 13:55:42 -04:00
auto maybe_autoplay_allowlist_error = load_autoplay_allowlist ( ) ;
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 ) ) ) ;
2023-02-08 23:05:44 +01:00
webcontent_client - > set_fd_passing_socket ( TRY ( Core : : LocalSocket : : adopt_fd ( webcontent_fd_passing_socket ) ) ) ;
2022-12-15 09:18:52 -05:00
2023-04-24 14:51:19 +02:00
return event_loop . exec ( ) ;
2022-10-05 15:23:41 +02:00
}
static ErrorOr < void > load_content_filters ( )
{
auto buffer = TRY ( ByteBuffer : : create_uninitialized ( 4096 ) ) ;
2023-04-21 07:36:40 -04:00
2024-02-23 13:40:16 -07:00
auto resource = TRY ( Core : : Resource : : load_from_uri ( " resource://ladybird/BrowserContentFilters.txt " sv ) ) ;
auto ad_filter_list = TRY ( InputBufferedSeekable < FixedMemoryStream > : : create ( make < FixedMemoryStream > ( resource - > data ( ) ) ) ) ;
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
static ErrorOr < void > load_autoplay_allowlist ( )
{
auto buffer = TRY ( ByteBuffer : : create_uninitialized ( 4096 ) ) ;
2024-02-23 13:40:16 -07:00
auto resource = TRY ( Core : : Resource : : load_from_uri ( " resource://ladybird/BrowserAutoplayAllowlist.txt " sv ) ) ;
auto allowlist = TRY ( InputBufferedSeekable < FixedMemoryStream > : : create ( make < FixedMemoryStream > ( resource - > data ( ) ) ) ) ;
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-02-06 08:25:22 -07:00
static ErrorOr < void > initialize_lagom_networking ( Vector < ByteString > const & certificates )
2023-08-07 19:42:06 -06:00
{
auto candidate_request_server_paths = TRY ( get_paths_for_helper_process ( " RequestServer " sv ) ) ;
2024-02-06 08:25:22 -07:00
auto request_server_client = TRY ( launch_request_server_process ( candidate_request_server_paths , s_serenity_resource_root , certificates ) ) ;
2023-08-07 19:42:06 -06:00
Web : : ResourceLoader : : initialize ( TRY ( WebView : : RequestServerAdapter : : try_create ( move ( request_server_client ) ) ) ) ;
return { } ;
}