diff --git a/Ladybird/AndroidPlatform.cpp b/Ladybird/AndroidPlatform.cpp index 436e51766e..f239f5a91e 100644 --- a/Ladybird/AndroidPlatform.cpp +++ b/Ladybird/AndroidPlatform.cpp @@ -10,9 +10,10 @@ #include #include #include +#include #include -#include #include +#include #include #include @@ -31,7 +32,7 @@ extern DeprecatedString s_serenity_resource_root; void android_platform_init(); static void extract_ladybird_resources(); -static ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedString output_directory); +static ErrorOr extract_tar_archive(String archive_file, DeprecatedString output_directory); void android_platform_init() { @@ -53,31 +54,25 @@ void extract_ladybird_resources() if (file_or_error.is_error()) { qDebug() << "Unable to open test file file as expected, extracting asssets..."; - MUST(extract_tar_archive(DeprecatedString::formatted("{}/ladybird-assets.tar", s_serenity_resource_root), s_serenity_resource_root)); + MUST(extract_tar_archive(MUST(String::formatted("{}/ladybird-assets.tar", s_serenity_resource_root)), s_serenity_resource_root)); } else { qDebug() << "Opened app-browser.png test file, good to go!"; qDebug() << "Hopefully no developer changed the asset files and expected them to be re-extracted!"; } } -ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedString output_directory) +ErrorOr extract_tar_archive(String archive_file, DeprecatedString output_directory) { constexpr size_t buffer_size = 4096; - auto file = TRY(Core::DeprecatedFile::open(archive_file, Core::OpenMode::ReadOnly)); + auto file = TRY(Core::InputBufferedFile::create(TRY(Core::File::open(archive_file, Core::File::OpenMode::Read)))); DeprecatedString old_pwd = TRY(Core::System::getcwd()); TRY(Core::System::chdir(output_directory)); ScopeGuard go_back = [&old_pwd] { MUST(Core::System::chdir(old_pwd)); }; - Core::InputFileStream file_stream(file); - - Archive::TarInputStream tar_stream(file_stream); - if (!tar_stream.valid()) { - qDebug() << "the provided file is not a well-formatted ustar file"; - return Error::from_errno(EINVAL); - } + auto tar_stream = TRY(Archive::TarInputStream::construct(make(move(file)))); HashMap global_overrides; HashMap local_overrides; @@ -96,14 +91,14 @@ ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedStrin return {}; }; - for (; !tar_stream.finished(); tar_stream.advance()) { - Archive::TarFileHeader const& header = tar_stream.header(); + while (!tar_stream->finished()) { + Archive::TarFileHeader const& header = tar_stream->header(); // Handle meta-entries earlier to avoid consuming the file content stream. if (header.content_is_like_extended_header()) { switch (header.type_flag()) { case Archive::TarFileType::GlobalExtendedHeader: { - TRY(tar_stream.for_each_extended_header([&](StringView key, StringView value) { + TRY(tar_stream->for_each_extended_header([&](StringView key, StringView value) { if (value.length() == 0) global_overrides.remove(key); else @@ -112,7 +107,7 @@ ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedStrin break; } case Archive::TarFileType::ExtendedHeader: { - TRY(tar_stream.for_each_extended_header([&](StringView key, StringView value) { + TRY(tar_stream->for_each_extended_header([&](StringView key, StringView value) { local_overrides.set(key, value); })); break; @@ -122,10 +117,11 @@ ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedStrin VERIFY_NOT_REACHED(); } + TRY(tar_stream->advance()); continue; } - Archive::TarFileStream file_stream = tar_stream.file_contents(); + Archive::TarFileStream file_stream = tar_stream->file_contents(); // Handle other header types that don't just have an effect on extraction. switch (header.type_flag()) { @@ -133,12 +129,14 @@ ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedStrin StringBuilder long_name; Array buffer; - size_t bytes_read; - while ((bytes_read = file_stream.read(buffer)) > 0) - long_name.append(reinterpret_cast(buffer.data()), bytes_read); + while (!file_stream.is_eof()) { + auto slice = TRY(file_stream.read_some(buffer)); + long_name.append(reinterpret_cast(slice.data()), slice.size()); + } local_overrides.set("path", long_name.to_deprecated_string()); + TRY(tar_stream->advance()); continue; } default: @@ -151,20 +149,22 @@ ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedStrin path = path.prepend(header.prefix()); DeprecatedString filename = get_override("path"sv).value_or(path.string()); - DeprecatedString absolute_path = Core::DeprecatedFile::absolute_path(filename); + DeprecatedString absolute_path = TRY(FileSystem::absolute_path(filename)).to_deprecated_string(); auto parent_path = LexicalPath(absolute_path).parent(); + auto header_mode = TRY(header.mode()); switch (header.type_flag()) { case Archive::TarFileType::NormalFile: case Archive::TarFileType::AlternateNormalFile: { MUST(Core::Directory::create(parent_path, Core::Directory::CreateDirectories::Yes)); - int fd = TRY(Core::System::open(absolute_path, O_CREAT | O_WRONLY, header.mode())); + int fd = TRY(Core::System::open(absolute_path, O_CREAT | O_WRONLY, header_mode)); Array buffer; - size_t bytes_read; - while ((bytes_read = file_stream.read(buffer)) > 0) - TRY(Core::System::write(fd, buffer.span().slice(0, bytes_read))); + while (!file_stream.is_eof()) { + auto slice = TRY(file_stream.read_some(buffer)); + TRY(Core::System::write(fd, slice)); + } TRY(Core::System::close(fd)); break; @@ -178,9 +178,9 @@ ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedStrin case Archive::TarFileType::Directory: { MUST(Core::Directory::create(parent_path, Core::Directory::CreateDirectories::Yes)); - auto result_or_error = Core::System::mkdir(absolute_path, header.mode()); + auto result_or_error = Core::System::mkdir(absolute_path, header_mode); if (result_or_error.is_error() && result_or_error.error().code() != EEXIST) - return result_or_error.error(); + return result_or_error.release_error(); break; } default: @@ -191,8 +191,8 @@ ErrorOr extract_tar_archive(DeprecatedString archive_file, DeprecatedStrin // Non-global headers should be cleared after every file. local_overrides.clear(); - } - file_stream.close(); + TRY(tar_stream->advance()); + } return {}; } diff --git a/Ladybird/CMakeLists.txt b/Ladybird/CMakeLists.txt index edf618dfeb..327cc5d83c 100644 --- a/Ladybird/CMakeLists.txt +++ b/Ladybird/CMakeLists.txt @@ -97,9 +97,7 @@ set(SOURCES main.cpp ) -qt_add_executable(ladybird ${SOURCES} - MANUAL_FINALIZATION -) +qt_add_executable(ladybird ${SOURCES}) target_link_libraries(ladybird PRIVATE Qt::Core Qt::Gui Qt::Network Qt::Widgets LibCore LibFileSystem LibGfx LibGUI LibIPC LibJS LibMain LibWeb LibWebView LibSQL) target_include_directories(ladybird PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) @@ -128,6 +126,7 @@ set_target_properties(ladybird PROPERTIES if (ANDROID) include(cmake/AndroidExtras.cmake) + link_android_libs(headless-browser) endif() add_custom_target(run${LADYBIRD_CUSTOM_TARGET_SUFFIX} @@ -141,8 +140,6 @@ add_custom_target(debug${LADYBIRD_CUSTOM_TARGET_SUFFIX} USES_TERMINAL ) -qt_finalize_executable(ladybird) - add_subdirectory(SQLServer) add_subdirectory(WebContent) add_subdirectory(WebDriver) diff --git a/Ladybird/WebContent/CMakeLists.txt b/Ladybird/WebContent/CMakeLists.txt index 93204007dc..29d78b67d5 100644 --- a/Ladybird/WebContent/CMakeLists.txt +++ b/Ladybird/WebContent/CMakeLists.txt @@ -28,3 +28,6 @@ qt_add_executable(WebContent ${WEBCONTENT_SOURCES}) target_include_directories(WebContent PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services/) target_include_directories(WebContent PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..) target_link_libraries(WebContent PRIVATE Qt::Core Qt::Gui Qt::Network Qt::Multimedia LibAudio LibCore LibFileSystem LibGfx LibIPC LibJS LibMain LibWeb LibWebSocket) +if (ANDROID) + link_android_libs(WebContent) +endif() diff --git a/Ladybird/WebDriver/CMakeLists.txt b/Ladybird/WebDriver/CMakeLists.txt index 72dcd2e547..11f36a1bbc 100644 --- a/Ladybird/WebDriver/CMakeLists.txt +++ b/Ladybird/WebDriver/CMakeLists.txt @@ -17,3 +17,6 @@ target_include_directories(WebDriver PRIVATE ${SERENITY_SOURCE_DIR}/Userland) target_include_directories(WebDriver PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services) target_link_libraries(WebDriver PRIVATE Qt::Core Qt::Network LibCore LibFileSystem LibGfx LibIPC LibJS LibMain LibWeb LibWebSocket) add_dependencies(WebDriver headless-browser) +if (ANDROID) + link_android_libs(WebDriver) +endif() diff --git a/Ladybird/android/AndroidManifest.xml b/Ladybird/android/AndroidManifest.xml index d128be4f66..bddd787bd5 100644 --- a/Ladybird/android/AndroidManifest.xml +++ b/Ladybird/android/AndroidManifest.xml @@ -14,8 +14,5 @@ - - - diff --git a/Ladybird/android/assets/.gitkeep b/Ladybird/android/assets/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Ladybird/android/build.gradle b/Ladybird/android/build.gradle deleted file mode 100644 index 4c711790f8..0000000000 --- a/Ladybird/android/build.gradle +++ /dev/null @@ -1,81 +0,0 @@ -buildscript { - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.0.2' - } -} - -repositories { - google() - mavenCentral() -} - -apply plugin: 'com.android.application' - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) -} - -android { - /******************************************************* - * The following variables: - * - androidBuildToolsVersion, - * - androidCompileSdkVersion - * - qtAndroidDir - holds the path to qt android files - * needed to build any Qt application - * on Android. - * - * are defined in gradle.properties file. This file is - * updated by QtCreator and androiddeployqt tools. - * Changing them manually might break the compilation! - *******************************************************/ - - compileSdkVersion androidCompileSdkVersion.toInteger() - buildToolsVersion androidBuildToolsVersion - ndkVersion androidNdkVersion - - // Extract native libraries from the APK - packagingOptions.jniLibs.useLegacyPackaging true - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = [qtAndroidDir + '/src', 'src', 'java'] - aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl'] - res.srcDirs = [qtAndroidDir + '/res', 'res'] - resources.srcDirs = ['resources'] - renderscript.srcDirs = ['src'] - assets.srcDirs = ['assets'] - jniLibs.srcDirs = ['libs'] - } - } - - tasks.withType(JavaCompile) { - options.incremental = true - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - lintOptions { - abortOnError false - } - - // Do not compress Qt binary resources file - aaptOptions { - noCompress 'rcc' - } - - defaultConfig { - resConfig "en" - minSdkVersion qtMinSdkVersion - targetSdkVersion qtTargetSdkVersion - ndk.abiFilters = qtTargetAbiList.split(",") - } -} diff --git a/Ladybird/android/gradle.properties b/Ladybird/android/gradle.properties deleted file mode 100644 index 263d70238a..0000000000 --- a/Ladybird/android/gradle.properties +++ /dev/null @@ -1,14 +0,0 @@ -# Project-wide Gradle settings. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2500m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# Enable building projects in parallel -org.gradle.parallel=true - -# Gradle caching allows reusing the build artifacts from a previous -# build with the same inputs. However, over time, the cache size will -# grow. Uncomment the following line to enable it. -#org.gradle.caching=true diff --git a/Ladybird/cmake/AndroidExtras.cmake b/Ladybird/cmake/AndroidExtras.cmake index c1f39e7342..24e7f81b77 100644 --- a/Ladybird/cmake/AndroidExtras.cmake +++ b/Ladybird/cmake/AndroidExtras.cmake @@ -13,8 +13,12 @@ set_property(TARGET ladybird APPEND PROPERTY # # Android-specific sources and libs # -target_sources(ladybird PRIVATE AndroidPlatform.cpp) -target_link_libraries(ladybird PRIVATE LibCompress LibArchive) +add_library(android_init STATIC AndroidPlatform.cpp) +target_link_libraries(android_init PUBLIC Qt::Core Qt::Gui Qt::Network LibCompress LibArchive LibFileSystem) + +macro(link_android_libs target) + target_link_libraries(${target} PRIVATE android_init) +endmacro() # # NDK and Qt don't ship OpenSSL for Android @@ -27,7 +31,13 @@ FetchContent_Declare(android_openssl GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(android_openssl) -set_property(TARGET ladybird APPEND PROPERTY QT_ANDROID_EXTRA_LIBS ${ANDROID_EXTRA_LIBS}) +link_android_libs(ladybird) +target_link_libraries(ladybird PRIVATE Qt::Network) +set_property(TARGET ladybird APPEND PROPERTY QT_ANDROID_EXTRA_LIBS ${ANDROID_EXTRA_LIBS} + "${CMAKE_CURRENT_BINARY_DIR}/WebContent/libWebContent_${ANDROID_ABI}.so" + "${CMAKE_CURRENT_BINARY_DIR}/SQLServer/libSQLServer_${ANDROID_ABI}.so" + "${CMAKE_CURRENT_BINARY_DIR}/WebDriver/libWebDriver_${ANDROID_ABI}.so" +) # # Copy resources into tarball for inclusion in /assets of APK @@ -60,6 +70,6 @@ add_custom_target(copy-content-filters "asset-bundle/res/ladybird/BrowserContentFilters.txt" ) add_dependencies(archive-assets copy-autoplay-allowlist copy-content-filters) -add_custom_target(copy-assets COMMAND ${CMAKE_COMMAND} -E copy_if_different ladybird-assets.tar.gz "${CMAKE_SOURCE_DIR}/android/assets") +add_custom_target(copy-assets COMMAND ${CMAKE_COMMAND} -E copy_if_different ladybird-assets.tar.gz "${CMAKE_SOURCE_DIR}/android/assets/") add_dependencies(copy-assets archive-assets) add_dependencies(ladybird copy-assets) diff --git a/Ladybird/cmake/InstallRules.cmake b/Ladybird/cmake/InstallRules.cmake index ea134c82ad..6ed7f2bef3 100644 --- a/Ladybird/cmake/InstallRules.cmake +++ b/Ladybird/cmake/InstallRules.cmake @@ -6,7 +6,13 @@ set(package ladybird) set(ladybird_applications ladybird SQLServer WebContent WebDriver headless-browser) -install(TARGETS ${ladybird_applications} +set(app_install_targets ${ladybird_applications}) +if (ANDROID) + # androiddeployqt will get confused with duplicate resources if we install every app + set(app_install_targets ladybird) +endif() + +install(TARGETS ${app_install_targets} EXPORT ladybirdTargets RUNTIME COMPONENT ladybird_Runtime