diff --git a/.gitignore b/.gitignore index 598de081039..8e4678ba9bd 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,13 @@ sync-local.sh .exrc .helix/ +# Gradle/AndroidStudio +.gradle/ +.cxx/ +local.properties +# We can't build from cmd.exe anyway +gradlew.bat + Userland/Libraries/LibWasm/Tests/Fixtures/SpecTests Userland/Libraries/LibWasm/Tests/Spec diff --git a/Ladybird/.gitignore b/Ladybird/.gitignore index d7cdb5d3380..27c0a8d1724 100644 --- a/Ladybird/.gitignore +++ b/Ladybird/.gitignore @@ -1,12 +1,8 @@ .qmake.stash Makefile -ladybird *.o moc_* Build build CMakeLists.txt.user -android/gradle -android/gradlew* -android/assets/ - +Android/src/main/assets/ diff --git a/Ladybird/Android/build.gradle.kts b/Ladybird/Android/build.gradle.kts new file mode 100644 index 00000000000..76e7de66c24 --- /dev/null +++ b/Ladybird/Android/build.gradle.kts @@ -0,0 +1,78 @@ +import com.android.build.gradle.internal.tasks.factory.dependsOn + +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") +} + +// FIXME: Move this somewhere nicer, with better behavior (like controlling host compiler) +task("buildLagomTools") { + commandLine = listOf("sh", "-c", "cmake -S ../../Meta/Lagom -B $buildDir/lagom-tools " + + " -Dpackage=LagomTools -DCMAKE_INSTALL_PREFIX=$buildDir/lagom-tools-install -GNinja" + + " -DSERENITY_CACHE_DIR=$buildDir/caches;" + + " ninja -C $buildDir/lagom-tools install") +} +tasks.named("preBuild").dependsOn("buildLagomTools") + +android { + namespace = "org.serenityos.ladybird" + compileSdk = 33 + + defaultConfig { + applicationId = "org.serenityos.ladybird" + minSdk = 30 + targetSdk = 33 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + externalNativeBuild { + cmake { + cppFlags += "-std=c++20" + arguments += listOf( + "-DLagomTools_DIR=$buildDir/lagom-tools-install/share/LagomTools", + "-DSERENITY_CACHE_DIR=$buildDir/caches" + ) + } + } + ndk { + // Specifies the ABI configurations of your native + // libraries Gradle should build and package with your app. + abiFilters += listOf("x86_64", "arm64-v8a") + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + externalNativeBuild { + cmake { + path = file("../CMakeLists.txt") + version = "3.27.4" + } + } + + buildFeatures { + viewBinding = true + } +} + +dependencies { + implementation("androidx.core:core-ktx:1.10.1") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.material:material:1.9.0") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") +} diff --git a/Ladybird/Android/proguard-rules.pro b/Ladybird/Android/proguard-rules.pro new file mode 100644 index 00000000000..f1b424510da --- /dev/null +++ b/Ladybird/Android/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/Ladybird/Android/src/main/AndroidManifest.xml b/Ladybird/Android/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..a4fb6fed937 --- /dev/null +++ b/Ladybird/Android/src/main/AndroidManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + diff --git a/Ladybird/Android/src/main/cpp/LadybirdActivity.cpp b/Ladybird/Android/src/main/cpp/LadybirdActivity.cpp new file mode 100644 index 00000000000..66b07d0a405 --- /dev/null +++ b/Ladybird/Android/src/main/cpp/LadybirdActivity.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +extern "C" JNIEXPORT void JNICALL +Java_org_serenityos_ladybird_LadybirdActivity_initNativeCode(JNIEnv* env, jobject /* thiz */, jstring resource_dir) +{ + char const* raw_resource_dir = env->GetStringUTFChars(resource_dir, nullptr); + s_serenity_resource_root = raw_resource_dir; + __android_log_print(ANDROID_LOG_INFO, "Ladybird", "Serenity resource dir is %s", s_serenity_resource_root.characters()); + env->ReleaseStringUTFChars(resource_dir, raw_resource_dir); +} diff --git a/Ladybird/Android/src/main/cpp/WebViewImplementationNative.cpp b/Ladybird/Android/src/main/cpp/WebViewImplementationNative.cpp new file mode 100644 index 00000000000..e454768b2c7 --- /dev/null +++ b/Ladybird/Android/src/main/cpp/WebViewImplementationNative.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +using namespace WebView; + +namespace { +class WebViewImplementationNative : public WebView::ViewImplementation { +public: + virtual Gfx::IntRect viewport_rect() const override { return {}; } + virtual Gfx::IntPoint to_content_position(Gfx::IntPoint) const override { return {}; } + virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint) const override { return {}; } + virtual void update_zoom() override { } + + static jclass global_class_reference; + static jfieldID instance_pointer_field; +}; +jclass WebViewImplementationNative::global_class_reference; +jfieldID WebViewImplementationNative::instance_pointer_field; +} + +extern "C" JNIEXPORT void JNICALL +Java_org_serenityos_ladybird_WebViewImplementationNative_00024Companion_nativeClassInit(JNIEnv* env, jobject /* thiz */) +{ + auto local_class = env->FindClass("org/serenityos/ladybird/WebViewImplementationNative"); + if (!local_class) + TODO(); + WebViewImplementationNative::global_class_reference = reinterpret_cast(env->NewGlobalRef(local_class)); + + auto field = env->GetFieldID(WebViewImplementationNative::global_class_reference, "nativeInstance", "J"); + if (!field) + TODO(); + WebViewImplementationNative::instance_pointer_field = field; +} + +extern "C" JNIEXPORT jlong JNICALL +Java_org_serenityos_ladybird_WebViewImplementationNative_nativeObjectInit(JNIEnv*, jobject /* thiz */) +{ + auto instance = reinterpret_cast(new WebViewImplementationNative); + __android_log_print(ANDROID_LOG_DEBUG, "Ladybird", "New WebViewImplementationNative at %p", reinterpret_cast(instance)); + return instance; +} + +extern "C" JNIEXPORT void JNICALL +Java_org_serenityos_ladybird_WebViewImplementationNative_nativeObjectDispose(JNIEnv*, jobject /* thiz */, jlong instance) +{ + delete reinterpret_cast(instance); + __android_log_print(ANDROID_LOG_DEBUG, "Ladybird", "Destroyed WebViewImplementationNative at %p", reinterpret_cast(instance)); +} diff --git a/Ladybird/Android/src/main/java/org/serenityos/ladybird/LadybirdActivity.kt b/Ladybird/Android/src/main/java/org/serenityos/ladybird/LadybirdActivity.kt new file mode 100644 index 00000000000..f3e640ad6d1 --- /dev/null +++ b/Ladybird/Android/src/main/java/org/serenityos/ladybird/LadybirdActivity.kt @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2023, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +package org.serenityos.ladybird + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.widget.TextView +import org.serenityos.ladybird.databinding.ActivityMainBinding +import org.serenityos.ladybird.TransferAssets + +class LadybirdActivity : AppCompatActivity() { + + private lateinit var binding: ActivityMainBinding + private lateinit var resourceDir: String + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) + resourceDir = TransferAssets.transferAssets(this) + initNativeCode(resourceDir) + view = WebViewImplementationNative() + } + + override fun onDestroy() { + view.dispose() + super.onDestroy() + } + + private lateinit var view: WebViewImplementationNative + + /** + * A native method that is implemented by the 'ladybird' native library, + * which is packaged with this application. + */ + private external fun initNativeCode(resourceDir: String) + + companion object { + // Used to load the 'ladybird' library on application startup. + init { + System.loadLibrary("ladybird") + } + } +} diff --git a/Ladybird/Android/src/main/java/org/serenityos/ladybird/TransferAssets.java b/Ladybird/Android/src/main/java/org/serenityos/ladybird/TransferAssets.java new file mode 100644 index 00000000000..975e8a4fa5a --- /dev/null +++ b/Ladybird/Android/src/main/java/org/serenityos/ladybird/TransferAssets.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2022, Andrew Kaster + *

+ * SPDX-License-Identifier: BSD-2-Clause + */ + +package org.serenityos.ladybird; + +import android.content.Context; +import android.content.res.AssetManager; +import android.util.Log; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import java.lang.String; + +public class TransferAssets { + /** + @return new ladybird resource root + */ + static public String transferAssets(Context context) { + Log.d("Ladybird", "Hello from java"); + Context applicationContext = context.getApplicationContext(); + File assetDir = applicationContext.getFilesDir(); + AssetManager assetManager = applicationContext.getAssets(); + if (!copyAsset(assetManager, "ladybird-assets.tar", assetDir.getAbsolutePath() + "/ladybird-assets.tar")) { + Log.e("Ladybird", "Unable to copy assets"); + return "Invalid Assets, this won't work"; + } + Log.d("Ladybird", "Copied ladybird-assets.tar to app-specific storage path"); + return assetDir.getAbsolutePath(); + } + + // ty to https://stackoverflow.com/a/22903693 for the sauce + private static boolean copyAsset(AssetManager assetManager, + String fromAssetPath, String toPath) { + try { + InputStream in = assetManager.open(fromAssetPath); + new File(toPath).createNewFile(); + OutputStream out = new FileOutputStream(toPath); + copyFile(in, out); + in.close(); + out.flush(); + out.close(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + private static void copyFile(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[4096]; + int read; + while ((read = in.read(buffer)) != -1) { + out.write(buffer, 0, read); + } + } +} diff --git a/Ladybird/Android/src/main/java/org/serenityos/ladybird/WebViewImplementationNative.kt b/Ladybird/Android/src/main/java/org/serenityos/ladybird/WebViewImplementationNative.kt new file mode 100644 index 00000000000..8852b56eab0 --- /dev/null +++ b/Ladybird/Android/src/main/java/org/serenityos/ladybird/WebViewImplementationNative.kt @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2023, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +package org.serenityos.ladybird + +import android.util.Log + +/** + * Wrapper around WebView::ViewImplementation for use by Kotlin + */ +class WebViewImplementationNative { + // Instance Pointer to native object, very unsafe :) + private var nativeInstance = nativeObjectInit() + + init { + Log.d( + "Ladybird", + "New WebViewImplementationNative (Kotlin) with nativeInstance ${this.nativeInstance}" + ) + } + + fun dispose() { + nativeObjectDispose(nativeInstance) + nativeInstance = 0 + } + + private external fun nativeObjectInit(): Long + private external fun nativeObjectDispose(instance: Long) + + companion object { + /* + * We use a static class initializer to allow the native code to cache some + * field offsets. This native function looks up and caches interesting + * class/field/method IDs. Throws on failure. + */ + private external fun nativeClassInit() + + init { + nativeClassInit() + } + } +}; diff --git a/Ladybird/Android/src/main/res/drawable/ic_launcher_background.xml b/Ladybird/Android/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000000..07d5da9cbf1 --- /dev/null +++ b/Ladybird/Android/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ladybird/Android/src/main/res/drawable/ic_launcher_foreground.xml b/Ladybird/Android/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 00000000000..7706ab9e6d4 --- /dev/null +++ b/Ladybird/Android/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/Ladybird/Android/src/main/res/layout/activity_main.xml b/Ladybird/Android/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000000..6043061dbd9 --- /dev/null +++ b/Ladybird/Android/src/main/res/layout/activity_main.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/Ladybird/Android/src/main/res/mipmap-anydpi/ic_launcher.xml b/Ladybird/Android/src/main/res/mipmap-anydpi/ic_launcher.xml new file mode 100644 index 00000000000..b3e26b4c60c --- /dev/null +++ b/Ladybird/Android/src/main/res/mipmap-anydpi/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Ladybird/Android/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/Ladybird/Android/src/main/res/mipmap-anydpi/ic_launcher_round.xml new file mode 100644 index 00000000000..b3e26b4c60c --- /dev/null +++ b/Ladybird/Android/src/main/res/mipmap-anydpi/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/Ladybird/Android/src/main/res/mipmap-hdpi/ic_launcher.webp b/Ladybird/Android/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 00000000000..c209e78ecd3 Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Ladybird/Android/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 00000000000..b2dfe3d1ba5 Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-mdpi/ic_launcher.webp b/Ladybird/Android/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 00000000000..4f0f1d64e58 Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Ladybird/Android/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 00000000000..62b611da081 Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Ladybird/Android/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 00000000000..948a3070fe3 Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Ladybird/Android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 00000000000..1b9a6956b3a Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Ladybird/Android/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 00000000000..28d4b77f9f0 Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Ladybird/Android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 00000000000..9287f508362 Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Ladybird/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 00000000000..aa7d6427e6f Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/Ladybird/Android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Ladybird/Android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 00000000000..9126ae37cbc Binary files /dev/null and b/Ladybird/Android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/Ladybird/Android/src/main/res/values-night/themes.xml b/Ladybird/Android/src/main/res/values-night/themes.xml new file mode 100644 index 00000000000..e7fd979824f --- /dev/null +++ b/Ladybird/Android/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + diff --git a/Ladybird/Android/src/main/res/values/colors.xml b/Ladybird/Android/src/main/res/values/colors.xml new file mode 100644 index 00000000000..ca1931bca99 --- /dev/null +++ b/Ladybird/Android/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + diff --git a/Ladybird/Android/src/main/res/values/strings.xml b/Ladybird/Android/src/main/res/values/strings.xml new file mode 100644 index 00000000000..f4749a649de --- /dev/null +++ b/Ladybird/Android/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Ladybird + diff --git a/Ladybird/Android/src/main/res/values/themes.xml b/Ladybird/Android/src/main/res/values/themes.xml new file mode 100644 index 00000000000..cbb2295eba2 --- /dev/null +++ b/Ladybird/Android/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ + + + + diff --git a/Ladybird/Android/src/main/res/xml/backup_rules.xml b/Ladybird/Android/src/main/res/xml/backup_rules.xml new file mode 100644 index 00000000000..148c18b6593 --- /dev/null +++ b/Ladybird/Android/src/main/res/xml/backup_rules.xml @@ -0,0 +1,13 @@ + + + + diff --git a/Ladybird/Android/src/main/res/xml/data_extraction_rules.xml b/Ladybird/Android/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 00000000000..0c4f95cab91 --- /dev/null +++ b/Ladybird/Android/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/Ladybird/CMakeLists.txt b/Ladybird/CMakeLists.txt index 1d6d5a33ddd..3fbfc4e4c09 100644 --- a/Ladybird/CMakeLists.txt +++ b/Ladybird/CMakeLists.txt @@ -75,6 +75,10 @@ add_compile_options(-Wno-expansion-to-defined) add_compile_options(-Wno-user-defined-literals) serenity_option(ENABLE_QT ON CACHE BOOL "Build ladybird application using Qt GUI") +if (ANDROID AND ENABLE_QT) + message(STATUS "Disabling Qt for Android") + set(ENABLE_QT OFF CACHE BOOL "" FORCE) +endif() if (ENABLE_QT) set(CMAKE_AUTOMOC ON) @@ -140,6 +144,13 @@ elseif (APPLE) -fobjc-arc -Wno-deprecated-anon-enum-enum-conversion # Required for CGImageCreate ) +elseif(ANDROID) + add_library(ladybird SHARED + ${SOURCES} + Android/src/main/cpp/LadybirdActivity.cpp + Android/src/main/cpp/WebViewImplementationNative.cpp + ) + target_link_libraries(ladybird PRIVATE log) else() # TODO: Check for other GUI frameworks here when we move them in-tree # For now, we can export a static library of common files for chromes to link to @@ -168,7 +179,6 @@ target_link_libraries(headless-browser PRIVATE LibWeb LibWebView LibWebSocket Li if (ANDROID) include(cmake/AndroidExtras.cmake) - link_android_libs(headless-browser) endif() add_custom_target(run${LADYBIRD_CUSTOM_TARGET_SUFFIX} diff --git a/Ladybird/Qt/AndroidPlatform.cpp b/Ladybird/Qt/AndroidPlatform.cpp deleted file mode 100644 index f239f5a91e8..00000000000 --- a/Ladybird/Qt/AndroidPlatform.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2022, Andrew Kaster - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifndef AK_OS_ANDROID -# error This file is for Android only, check CMake config! -#endif - -// HACK ALERT, we need to include LibMain manually here because the Qt build system doesn't include LibMain.a in the actual executable, -// nor include it in libladybird_.so -#include // NOLINT(bugprone-suspicious-include) - -extern DeprecatedString s_serenity_resource_root; - -void android_platform_init(); -static void extract_ladybird_resources(); -static ErrorOr extract_tar_archive(String archive_file, DeprecatedString output_directory); - -void android_platform_init() -{ - qDebug() << "Device supports OpenSSL: " << QSslSocket::supportsSsl(); - - QJniObject res = QJniObject::callStaticMethod("org/serenityos/ladybird/TransferAssets", - "transferAssets", - "(Landroid/content/Context;)Ljava/lang/String;", - QNativeInterface::QAndroidApplication::context()); - s_serenity_resource_root = res.toString().toUtf8().data(); - - extract_ladybird_resources(); -} - -void extract_ladybird_resources() -{ - qDebug() << "serenity resource root is " << s_serenity_resource_root.characters(); - auto file_or_error = Core::System::open(DeprecatedString::formatted("{}/res/icons/16x16/app-browser.png", s_serenity_resource_root), O_RDONLY); - if (file_or_error.is_error()) { - qDebug() << "Unable to open test file file as expected, extracting asssets..."; - - 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(String archive_file, DeprecatedString output_directory) -{ - constexpr size_t buffer_size = 4096; - - 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)); }; - - auto tar_stream = TRY(Archive::TarInputStream::construct(make(move(file)))); - - HashMap global_overrides; - HashMap local_overrides; - - auto get_override = [&](StringView key) -> Optional { - Optional maybe_local = local_overrides.get(key); - - if (maybe_local.has_value()) - return maybe_local; - - Optional maybe_global = global_overrides.get(key); - - if (maybe_global.has_value()) - return maybe_global; - - return {}; - }; - - 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) { - if (value.length() == 0) - global_overrides.remove(key); - else - global_overrides.set(key, value); - })); - break; - } - case Archive::TarFileType::ExtendedHeader: { - TRY(tar_stream->for_each_extended_header([&](StringView key, StringView value) { - local_overrides.set(key, value); - })); - break; - } - default: - warnln("Unknown extended header type '{}' of {}", (char)header.type_flag(), header.filename()); - VERIFY_NOT_REACHED(); - } - - TRY(tar_stream->advance()); - continue; - } - - 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()) { - case Archive::TarFileType::LongName: { - StringBuilder long_name; - - Array buffer; - - 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: - // None of the relevant headers, so continue as normal. - break; - } - - LexicalPath path = LexicalPath(header.filename()); - if (!header.prefix().is_empty()) - path = path.prepend(header.prefix()); - DeprecatedString filename = get_override("path"sv).value_or(path.string()); - - 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)); - - Array buffer; - 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; - } - case Archive::TarFileType::SymLink: { - MUST(Core::Directory::create(parent_path, Core::Directory::CreateDirectories::Yes)); - - TRY(Core::System::symlink(header.link_name(), absolute_path)); - break; - } - 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); - if (result_or_error.is_error() && result_or_error.error().code() != EEXIST) - return result_or_error.release_error(); - break; - } - default: - // FIXME: Implement other file types - warnln("file type '{}' of {} is not yet supported", (char)header.type_flag(), header.filename()); - VERIFY_NOT_REACHED(); - } - - // Non-global headers should be cleared after every file. - local_overrides.clear(); - - TRY(tar_stream->advance()); - } - return {}; -} diff --git a/Ladybird/RequestServer/CMakeLists.txt b/Ladybird/RequestServer/CMakeLists.txt index 5edf8ce633a..1f0cb91296a 100644 --- a/Ladybird/RequestServer/CMakeLists.txt +++ b/Ladybird/RequestServer/CMakeLists.txt @@ -19,9 +19,6 @@ add_executable(RequestServer ${REQUESTSERVER_SOURCES}) target_include_directories(RequestServer PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services/) target_include_directories(RequestServer PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..) target_link_libraries(RequestServer PRIVATE LibCore LibMain LibCrypto LibFileSystem LibGemini LibHTTP LibIPC LibMain LibTLS LibWebView) -if (ANDROID) - link_android_libs(RequestServer) -endif() if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") # Solaris has socket and networking related functions in two extra libraries target_link_libraries(RequestServer PRIVATE nsl socket) diff --git a/Ladybird/Utilities.cpp b/Ladybird/Utilities.cpp index 38fdc99c963..5fb193f8d18 100644 --- a/Ladybird/Utilities.cpp +++ b/Ladybird/Utilities.cpp @@ -22,10 +22,6 @@ ErrorOr application_directory() void platform_init() { -#ifdef AK_OS_ANDROID - extern void android_platform_init(); - android_platform_init(); -#else s_serenity_resource_root = [] { auto const* source_dir = getenv("SERENITY_SOURCE_DIR"); if (source_dir) { @@ -37,13 +33,12 @@ void platform_init() if (FileSystem::is_directory(home_lagom)) return home_lagom; auto app_dir = application_directory().release_value_but_fixme_should_propagate_errors().to_deprecated_string(); -# ifdef AK_OS_MACOS +#ifdef AK_OS_MACOS return LexicalPath(app_dir).parent().append("Resources"sv).string(); -# else +#else return LexicalPath(app_dir).parent().append("share"sv).string(); -# endif - }(); #endif + }(); } ErrorOr> get_paths_for_helper_process(StringView process_name) diff --git a/Ladybird/WebContent/CMakeLists.txt b/Ladybird/WebContent/CMakeLists.txt index be8229cdf88..d28dcbca609 100644 --- a/Ladybird/WebContent/CMakeLists.txt +++ b/Ladybird/WebContent/CMakeLists.txt @@ -56,9 +56,6 @@ endif() target_include_directories(WebContent PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services/) target_include_directories(WebContent PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/..) target_link_libraries(WebContent PRIVATE LibAudio LibCore LibFileSystem LibGfx LibIPC LibJS LibMain LibWeb LibWebSocket LibProtocol LibWebView) -if (ANDROID) - link_android_libs(WebContent) -endif() if (HAVE_PULSEAUDIO) target_compile_definitions(WebContent PRIVATE HAVE_PULSEAUDIO=1) diff --git a/Ladybird/WebDriver/CMakeLists.txt b/Ladybird/WebDriver/CMakeLists.txt index e2e7092c764..3efe82271bb 100644 --- a/Ladybird/WebDriver/CMakeLists.txt +++ b/Ladybird/WebDriver/CMakeLists.txt @@ -16,6 +16,3 @@ target_include_directories(WebDriver PRIVATE ${SERENITY_SOURCE_DIR}/Userland) target_include_directories(WebDriver PRIVATE ${SERENITY_SOURCE_DIR}/Userland/Services) target_link_libraries(WebDriver PRIVATE 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 deleted file mode 100644 index bddd787bd5e..00000000000 --- a/Ladybird/android/AndroidManifest.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/Ladybird/android/assets/.gitkeep b/Ladybird/android/assets/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/Ladybird/android/res/values/libs.xml b/Ladybird/android/res/values/libs.xml deleted file mode 100644 index fe63866f726..00000000000 --- a/Ladybird/android/res/values/libs.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/Ladybird/android/src/org/serenityos/ladybird/TransferAssets.java b/Ladybird/android/src/org/serenityos/ladybird/TransferAssets.java deleted file mode 100644 index edf5e8352d0..00000000000 --- a/Ladybird/android/src/org/serenityos/ladybird/TransferAssets.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (c) 2022, Andrew Kaster - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -package org.serenityos.ladybird; - -import android.content.Context; -import android.content.res.AssetManager; -import android.util.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import java.lang.String; - -public class TransferAssets -{ - /** - @returns new ladybird resource root - */ - static public String transferAssets(Context context) - { - Log.d("Ladybird", "Hello from java"); - Context applicationContext = context.getApplicationContext(); - File assetDir = applicationContext.getFilesDir(); - AssetManager assetManager = applicationContext.getAssets(); - if (!copyAsset(assetManager, "ladybird-assets.tar", assetDir.getAbsolutePath() + "/ladybird-assets.tar")) { - Log.e("Ladybird", "Unable to copy assets"); - return "Invalid Assets, this won't work"; - } - Log.d("Ladybird", "Copied ladybird-assets.tar to app-specific storage path"); - return assetDir.getAbsolutePath(); - } - - // ty to https://stackoverflow.com/a/22903693 for the sauce - private static boolean copyAsset(AssetManager assetManager, - String fromAssetPath, String toPath) { - InputStream in = null; - OutputStream out = null; - try { - in = assetManager.open(fromAssetPath); - new File(toPath).createNewFile(); - out = new FileOutputStream(toPath); - copyFile(in, out); - in.close(); - in = null; - out.flush(); - out.close(); - out = null; - return true; - } catch(Exception e) { - e.printStackTrace(); - return false; - } - } - - private static void copyFile(InputStream in, OutputStream out) throws IOException { - byte[] buffer = new byte[4096]; - int read; - while((read = in.read(buffer)) != -1){ - out.write(buffer, 0, read); - } - } -}; diff --git a/Ladybird/cmake/AndroidExtras.cmake b/Ladybird/cmake/AndroidExtras.cmake index 24e7f81b77d..cc137bd6ea1 100644 --- a/Ladybird/cmake/AndroidExtras.cmake +++ b/Ladybird/cmake/AndroidExtras.cmake @@ -3,42 +3,6 @@ # SPDX-License-Identifier: BSD-2-Clause # -# -# Source directory for androiddeployqt to use when bundling the application -# -set_property(TARGET ladybird APPEND PROPERTY - QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android -) - -# -# Android-specific sources and libs -# -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 -# Download the prebuilt binaries from KDAB for inclusion as recommended in Qt docs. -# -include(FetchContent) -FetchContent_Declare(android_openssl - GIT_REPOSITORY https://github.com/KDAB/android_openssl - GIT_TAG origin/master - GIT_SHALLOW TRUE -) -FetchContent_MakeAvailable(android_openssl) -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 # @@ -70,6 +34,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/src/main/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 58d0c76b158..237cab15a65 100644 --- a/Ladybird/cmake/InstallRules.cmake +++ b/Ladybird/cmake/InstallRules.cmake @@ -7,10 +7,6 @@ set(package ladybird) set(ladybird_applications ladybird SQLServer WebContent WebDriver WebSocketServer RequestServer headless-browser) 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 @@ -37,6 +33,9 @@ foreach (application IN LISTS ladybird_applications) endforeach() list(REMOVE_DUPLICATES all_required_lagom_libraries) +# Remove ladybird shlib if it exists +list(REMOVE_ITEM all_required_lagom_libraries ladybird) + # Install webcontent impl library if it exists if (TARGET webcontent) list(APPEND all_required_lagom_libraries webcontent) diff --git a/Meta/CMake/all_the_debug_macros.cmake b/Meta/CMake/all_the_debug_macros.cmake index b93bdc50f39..83d7848eac9 100644 --- a/Meta/CMake/all_the_debug_macros.cmake +++ b/Meta/CMake/all_the_debug_macros.cmake @@ -254,3 +254,5 @@ set(XML_PARSER_DEBUG ON) # set(ELF_DEBUG ON) # False positive: A32_DEBUG_INTERFACE is the name of a CPU feature, not a debug flag. # set(IA32_DEBUG_INTERFACE ON) +# False positive: ANDROID_LOG_DEBUG is a log level, not a debug flag +# set(ANDROID_LOG_DEBUG ON) diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000000..95cbdb3cac3 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,5 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id("com.android.application") version "8.1.1" apply false + id("org.jetbrains.kotlin.android") version "1.9.0" apply false +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000000..2cbd6d19d33 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,23 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# 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=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000000..e708b1c023e Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..56cc7951b45 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Sep 01 12:36:55 CEST 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 00000000000..4f906e0c811 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000000..d9d42c85763 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,18 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "Ladybird" +include("Ladybird") +project(":Ladybird").projectDir = file("Ladybird/Android")