2022-10-05 16:23:41 +03:00
/*
2023-04-24 19:02:29 +03:00
* Copyright ( c ) 2020 - 2023 , Andreas Kling < kling @ serenityos . org >
2022-10-05 16:23:41 +03:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include <AK/LexicalPath.h>
2023-08-05 19:42:26 +03:00
# include <Ladybird/FontPlugin.h>
# include <Ladybird/HelperProcess.h>
# include <Ladybird/ImageCodecPlugin.h>
# include <Ladybird/Utilities.h>
2023-06-20 19:43:04 +03:00
# include <LibAudio/Loader.h>
2022-11-14 16:13:37 +03:00
# include <LibCore/ArgsParser.h>
2022-10-05 16:23:41 +03:00
# include <LibCore/EventLoop.h>
# include <LibCore/LocalServer.h>
# include <LibCore/System.h>
2022-11-14 16:13:37 +03:00
# include <LibCore/SystemServerTakeover.h>
# include <LibIPC/ConnectionFromClient.h>
2023-06-17 14:16:35 +03:00
# include <LibJS/Bytecode/Interpreter.h>
2022-10-05 16:23:41 +03:00
# include <LibMain/Main.h>
2023-03-17 17:56:59 +03:00
# include <LibWeb/Bindings/MainThreadVM.h>
2023-07-21 12:59:49 +03:00
# include <LibWeb/HTML/Window.h>
2022-10-05 16:23:41 +03:00
# include <LibWeb/Loader/ContentFilter.h>
# include <LibWeb/Loader/FrameLoader.h>
# include <LibWeb/Loader/ResourceLoader.h>
2023-04-17 20:55:42 +03:00
# include <LibWeb/PermissionsPolicy/AutoplayAllowlist.h>
2023-07-04 13:02:19 +03:00
# include <LibWeb/Platform/AudioCodecPluginAgnostic.h>
2023-04-24 19:02:29 +03:00
# include <LibWeb/Platform/EventLoopPluginSerenity.h>
2022-10-05 16:23:41 +03:00
# include <LibWeb/WebSockets/WebSocket.h>
2023-08-01 23:39:19 +03:00
# include <LibWebView/RequestServerAdapter.h>
2023-08-03 03:13:23 +03:00
# include <LibWebView/WebSocketClientAdapter.h>
2022-10-05 16:23:41 +03:00
# include <WebContent/ConnectionFromClient.h>
2022-11-22 16:09:55 +03:00
# include <WebContent/PageHost.h>
2022-11-14 19:08:44 +03:00
# include <WebContent/WebDriverConnection.h>
2022-10-05 16:23:41 +03:00
2023-08-08 04:42:06 +03:00
# if defined(HAVE_QT)
# include <Ladybird / Qt / AudioCodecPluginQt.h>
# include <Ladybird / Qt / EventLoopImplementationQt.h>
# include <Ladybird / Qt / RequestManagerQt.h>
# include <Ladybird / Qt / WebSocketClientManagerQt.h>
# include <QCoreApplication>
# endif
2022-10-05 16:23:41 +03:00
static ErrorOr < void > load_content_filters ( ) ;
2023-04-17 20:55:42 +03:00
static ErrorOr < void > load_autoplay_allowlist ( ) ;
2023-08-08 04:42:06 +03:00
static ErrorOr < void > initialize_lagom_networking ( ) ;
2022-10-05 16:23:41 +03:00
ErrorOr < int > serenity_main ( Main : : Arguments arguments )
{
2023-08-08 04:42:06 +03:00
# if defined(HAVE_QT)
2023-07-30 15:37:30 +03:00
QCoreApplication app ( arguments . argc , arguments . argv ) ;
2022-10-05 16:23:41 +03:00
2023-04-25 18:38:48 +03:00
Core : : EventLoopManager : : install ( * new Ladybird : : EventLoopManagerQt ) ;
2023-08-08 04:42:06 +03:00
# endif
2023-04-24 15:51:19 +03:00
Core : : EventLoop event_loop ;
2022-10-08 02:08:29 +03:00
platform_init ( ) ;
2023-04-24 19:02:29 +03:00
Web : : Platform : : EventLoopPlugin : : install ( * new Web : : Platform : : EventLoopPluginSerenity ) ;
2023-08-02 21:01:17 +03:00
Web : : Platform : : ImageCodecPlugin : : install ( * new Ladybird : : ImageCodecPlugin ) ;
2023-06-12 20:44:10 +03:00
2023-06-20 19:43:04 +03:00
Web : : Platform : : AudioCodecPlugin : : install_creation_hook ( [ ] ( auto loader ) {
2023-09-08 20:25:56 +03:00
# if defined(AK_OS_MACOS) || defined(HAVE_PULSEAUDIO)
2023-07-04 13:02:19 +03:00
return Web : : Platform : : AudioCodecPluginAgnostic : : create ( move ( loader ) ) ;
2023-08-08 04:42:06 +03:00
# elif defined(HAVE_QT)
2023-08-02 21:01:17 +03:00
return Ladybird : : AudioCodecPluginQt : : create ( move ( loader ) ) ;
2023-08-08 04:42:06 +03:00
# else
2023-08-14 20:05:16 +03:00
( void ) loader ;
return Error : : from_string_literal ( " Don't know how to initialize audio in this configuration! " ) ;
2023-07-04 13:02:19 +03:00
# endif
2023-06-12 20:44:10 +03:00
} ) ;
2022-10-05 16:23:41 +03:00
2022-12-04 21:43:54 +03:00
Web : : FrameLoader : : set_default_favicon_path ( DeprecatedString : : formatted ( " {}/res/icons/16x16/app-browser.png " , s_serenity_resource_root ) ) ;
2022-10-05 16:23:41 +03:00
2023-05-05 20:48:48 +03:00
int webcontent_fd_passing_socket { - 1 } ;
2023-05-06 13:46:14 +03:00
bool is_layout_test_mode = false ;
2023-08-01 23:39:19 +03:00
bool use_lagom_networking = false ;
2023-05-05 20:48:48 +03:00
Core : : ArgsParser args_parser ;
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 13:46:14 +03:00
args_parser . add_option ( is_layout_test_mode , " Is layout test mode " , " layout-test-mode " , 0 ) ;
2023-08-01 23:39:19 +03:00
args_parser . add_option ( use_lagom_networking , " Enable Lagom servers for networking " , " use-lagom-networking " , 0 ) ;
2023-05-05 20:48:48 +03:00
args_parser . parse ( arguments ) ;
2023-08-08 04:42:06 +03:00
# if defined(HAVE_QT)
if ( ! use_lagom_networking ) {
2023-08-02 20:52:59 +03:00
Web : : ResourceLoader : : initialize ( Ladybird : : RequestManagerQt : : create ( ) ) ;
2023-08-03 03:13:23 +03:00
Web : : WebSockets : : WebSocketClientManager : : initialize ( Ladybird : : WebSocketClientManagerQt : : create ( ) ) ;
2023-08-08 04:42:06 +03:00
} else
# endif
{
TRY ( initialize_lagom_networking ( ) ) ;
2023-08-01 23:39:19 +03:00
}
2023-07-21 12:59:49 +03:00
Web : : HTML : : Window : : set_internals_object_exposed ( is_layout_test_mode ) ;
2023-05-05 20:48:48 +03:00
VERIFY ( webcontent_fd_passing_socket > = 0 ) ;
2023-08-02 21:01:17 +03:00
Web : : Platform : : FontPlugin : : install ( * new Ladybird : : FontPlugin ( is_layout_test_mode ) ) ;
2022-10-05 16:23:41 +03:00
2023-08-13 23:34:57 +03:00
Web : : FrameLoader : : set_resource_directory_url ( DeprecatedString : : formatted ( " file://{}/res " , s_serenity_resource_root ) ) ;
2022-12-04 21:43:54 +03:00
Web : : FrameLoader : : set_error_page_url ( DeprecatedString : : formatted ( " file://{}/res/html/error.html " , s_serenity_resource_root ) ) ;
2023-08-13 23:35:35 +03:00
Web : : FrameLoader : : set_directory_page_url ( DeprecatedString : : formatted ( " file://{}/res/html/directory.html " , s_serenity_resource_root ) ) ;
2022-10-05 16:23:41 +03:00
2023-03-17 17:56:59 +03:00
TRY ( Web : : Bindings : : initialize_main_thread_vm ( ) ) ;
2022-10-05 16:23:41 +03: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 20:55:42 +03: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 17:18:52 +03: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-09 01:05:44 +03:00
webcontent_client - > set_fd_passing_socket ( TRY ( Core : : LocalSocket : : adopt_fd ( webcontent_fd_passing_socket ) ) ) ;
2022-12-15 17:18:52 +03:00
2023-04-24 15:51:19 +03:00
return event_loop . exec ( ) ;
2022-10-05 16:23:41 +03:00
}
static ErrorOr < void > load_content_filters ( )
{
2023-02-09 05:02:46 +03:00
auto file_or_error = Core : : File : : open ( DeprecatedString : : formatted ( " {}/home/anon/.config/BrowserContentFilters.txt " , s_serenity_resource_root ) , Core : : File : : OpenMode : : Read ) ;
2022-10-05 16:23:41 +03:00
if ( file_or_error . is_error ( ) )
2023-02-09 05:02:46 +03:00
file_or_error = Core : : File : : open ( DeprecatedString : : formatted ( " {}/res/ladybird/BrowserContentFilters.txt " , s_serenity_resource_root ) , Core : : File : : OpenMode : : Read ) ;
2022-10-05 16:23:41 +03:00
if ( file_or_error . is_error ( ) )
return file_or_error . release_error ( ) ;
2023-04-21 14:36:40 +03:00
2022-10-05 16:23:41 +03:00
auto file = file_or_error . release_value ( ) ;
2023-05-04 01:45:18 +03:00
auto ad_filter_list = TRY ( Core : : InputBufferedFile : : create ( move ( file ) ) ) ;
2022-10-05 16:23:41 +03:00
auto buffer = TRY ( ByteBuffer : : create_uninitialized ( 4096 ) ) ;
2023-04-21 14:36:40 +03:00
2023-04-21 14:54:56 +03:00
Vector < String > patterns ;
2023-04-21 14:36:40 +03:00
2022-10-05 16:23:41 +03:00
while ( TRY ( ad_filter_list - > can_read_line ( ) ) ) {
auto line = TRY ( ad_filter_list - > read_line ( buffer ) ) ;
2023-04-21 14:36:40 +03:00
if ( line . is_empty ( ) )
continue ;
2023-04-21 14:54:56 +03:00
auto pattern = TRY ( String : : from_utf8 ( line ) ) ;
TRY ( patterns . try_append ( move ( pattern ) ) ) ;
2022-10-05 16:23:41 +03:00
}
2023-04-21 14:36:40 +03:00
auto & content_filter = Web : : ContentFilter : : the ( ) ;
TRY ( content_filter . set_patterns ( patterns ) ) ;
2022-10-05 16:23:41 +03:00
return { } ;
}
2023-04-17 20:55:42 +03:00
static ErrorOr < void > load_autoplay_allowlist ( )
{
auto file_or_error = Core : : File : : open ( TRY ( String : : formatted ( " {}/home/anon/.config/BrowserAutoplayAllowlist.txt " , s_serenity_resource_root ) ) , Core : : File : : OpenMode : : Read ) ;
if ( file_or_error . is_error ( ) )
file_or_error = Core : : File : : open ( TRY ( String : : formatted ( " {}/res/ladybird/BrowserAutoplayAllowlist.txt " , s_serenity_resource_root ) ) , Core : : File : : OpenMode : : Read ) ;
if ( file_or_error . is_error ( ) )
return file_or_error . release_error ( ) ;
auto file = file_or_error . release_value ( ) ;
2023-05-04 01:45:18 +03:00
auto allowlist = TRY ( Core : : InputBufferedFile : : create ( move ( file ) ) ) ;
2023-04-17 20:55:42 +03:00
auto buffer = TRY ( ByteBuffer : : create_uninitialized ( 4096 ) ) ;
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-08 04:42:06 +03:00
static ErrorOr < void > initialize_lagom_networking ( )
{
auto candidate_request_server_paths = TRY ( get_paths_for_helper_process ( " RequestServer " sv ) ) ;
auto request_server_client = TRY ( launch_request_server_process ( candidate_request_server_paths , s_serenity_resource_root ) ) ;
Web : : ResourceLoader : : initialize ( TRY ( WebView : : RequestServerAdapter : : try_create ( move ( request_server_client ) ) ) ) ;
auto candidate_web_socket_paths = TRY ( get_paths_for_helper_process ( " WebSocket " sv ) ) ;
auto web_socket_client = TRY ( launch_web_socket_process ( candidate_web_socket_paths , s_serenity_resource_root ) ) ;
Web : : WebSockets : : WebSocketClientManager : : initialize ( TRY ( WebView : : WebSocketClientManagerAdapter : : try_create ( move ( web_socket_client ) ) ) ) ;
return { } ;
}