import java.util.Properties import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.kotlin.parcelize) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.androidx.navigation.safeargs) alias(libs.plugins.baselineprofile) alias(libs.plugins.ksp) } /* 'keystore.properties' should look like the following: storeFile=my.keystore storePassword=my_store_password keyAlias=my_key_alias keyPassword=my_key_password */ val keystoreProperties = Properties() val keystoreFileExists = rootProject.file("keystore.properties").exists(); if (keystoreFileExists) { keystoreProperties.load(rootProject.file("keystore.properties").inputStream()) } android { compileSdk = 36 defaultConfig { applicationId = "com.github.libretube" // Use a widely compatible minimum SDK to support physical ARM devices // (Android 6.0 / API 23 is a reasonable baseline) minSdk = 23 targetSdk = 36 versionCode = 76 versionName = "31.4-v7.2-heartbeat-stable-logout" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" resValue("string", "app_name", "YouTube Pro Premium") // Ensure native libraries are built for common ARM ABIs so APKs install on // physical devices. If your project doesn't use native code you can omit this. ndk { // Prefer ARM ABIs for physical devices. Keep x86/x86_64 if you also // want emulator compatibility. abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) } } ksp { arg("room.schemaLocation", "$projectDir/schemas") arg("exportSchema", "true") } viewBinding { enable = true } signingConfigs { if (keystoreFileExists) { create("release") { storeFile = keystoreProperties["storeFile"]?.let { file(it as String) } storePassword = keystoreProperties["storePassword"] as String keyAlias = keystoreProperties["keyAlias"] as String keyPassword = keystoreProperties["keyPassword"] as String } } } buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true signingConfig = signingConfigs.findByName("release")?.takeIf { it.storeFile != null } proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } getByName("debug") { isDebuggable = true applicationIdSuffix = ".debug" resValue("string", "app_name", "YouTube Pro Premium") } } compileOptions { isCoreLibraryDesugaringEnabled = true sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlin { compilerOptions { jvmTarget = JvmTarget.JVM_17 javaParameters = true } } packaging { jniLibs.excludes.add("lib/armeabi-v7a/*_neon.so") } tasks.register("testClasses") lint { abortOnError = false checkReleaseBuilds = false } buildFeatures { buildConfig = true resValues = true } dependenciesInfo { // Disables dependency metadata when building APKs. includeInApk = false // Disables dependency metadata when building Android App Bundles. includeInBundle = false } // language preference for Android 13 and above androidResources { generateLocaleConfig = true } namespace = "com.github.libretube" // Configure ABI splits. By default we disable ABI splits and request a // universal APK so a single APK can be installed on physical devices. splits { abi { isEnable = false // When true, generates an additional universal APK containing all ABIs // (useful if you enable splits but still want a universal artifact). isUniversalApk = true include("armeabi-v7a", "arm64-v8a", "x86", "x86_64") } } } dependencies { /* Android Core */ implementation(libs.androidx.activity) implementation(libs.androidx.appcompat) implementation(libs.androidx.core) implementation(libs.androidx.core.splashscreen) implementation(libs.androidx.constraintlayout) implementation(libs.androidx.fragment) implementation(libs.androidx.navigation.fragment) implementation(libs.androidx.navigation.ui) implementation(libs.androidx.preference) implementation(libs.androidx.documentfile) implementation(libs.androidx.work.runtime) implementation(libs.androidx.collection) implementation(libs.androidx.media) implementation(libs.androidx.mediarouter) // Google Cast framework implementation("com.google.android.gms:play-services-cast-framework:21.4.0") implementation(libs.androidx.swiperefreshlayout) /* Android Lifecycle */ implementation(libs.lifecycle.viewmodel) implementation(libs.lifecycle.runtime) implementation(libs.lifecycle.livedata) implementation(libs.lifecycle.service) /* Design */ implementation(libs.material) /* ExoPlayer */ implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.media3.ui) implementation(libs.androidx.media3.exoplayer.hls) implementation(libs.androidx.media3.exoplayer.dash) implementation(libs.androidx.media3.session) /* Retrofit and Kotlinx Serialization */ implementation(libs.square.retrofit) implementation(libs.logging.interceptor) implementation(libs.kotlinx.serialization) implementation(libs.kotlinx.datetime) implementation(libs.converter.kotlinx.serialization) /* NewPipe Extractor */ implementation(libs.newpipeextractor) /* Coil */ coreLibraryDesugaring(libs.desugaring) implementation(libs.coil) implementation(libs.coil.network.okhttp) /* Room */ ksp(libs.room.compiler) implementation(libs.room) /* Baseline profile generation */ implementation(libs.androidx.profileinstaller) baselineProfile(project(":baselineprofile")) /* AndroidX Paging */ implementation(libs.androidx.paging) /* Testing */ testImplementation(libs.junit) }