From 18f8a0f997e6408bc5f67db2ccd3193ba64ae3d0 Mon Sep 17 00:00:00 2001 From: Zephyron Date: Fri, 21 Feb 2025 18:46:48 +1000 Subject: Add license verification for Android app Implements a LicenseVerifier class to ensure app integrity and license compliance: - Verifies the app's package name matches the official release - Validates app signature against official release signature - Allows debug and EA (Early Access) builds - Shows violation dialog and exits if verification fails - Enforces GPLv3 license compliance for modified versions This helps prevent unauthorized modified versions from being distributed without source code, as required by the GPLv3 license. --- src/android/app/build.gradle.kts | 82 ++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 42 deletions(-) (limited to 'src/android/app/build.gradle.kts') diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index aa98969cc..27081d9c3 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -1,8 +1,9 @@ // SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-FileCopyrightText: 2025 citron Emulator Project +// SPDX-FileCopyrightText: 2023 citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later import android.annotation.SuppressLint +import kotlin.collections.setOf import org.jlleitschuh.gradle.ktlint.reporter.ReporterType import com.github.triplet.gradle.androidpublisher.ReleaseStatus @@ -26,22 +27,21 @@ val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toIn @Suppress("UnstableApiUsage") android { namespace = "org.citron.citron_emu" - compileSdk = 35 - ndkVersion = "28.0.13004108" // "26.3.11579264" + compileSdkVersion = "android-34" + ndkVersion = "26.1.10909125" buildFeatures { viewBinding = true - buildConfig = true } compileOptions { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "21" + jvmTarget = "17" } packaging { @@ -57,7 +57,7 @@ android { // TODO If this is ever modified, change application_id in strings.xml applicationId = "org.citron.citron_emu" minSdk = 30 - targetSdk = 35 + targetSdk = 34 versionName = getGitVersion() versionCode = if (System.getenv("AUTO_VERSIONED") == "true") { @@ -75,6 +75,15 @@ android { buildConfigField("String", "BRANCH", "\"${getBranch()}\"") } + android.applicationVariants.all { + val variant = this + variant.outputs.all { + if (this is com.android.build.gradle.internal.api.ApkVariantOutputImpl) { + outputFileName = "Citron-${variant.versionName}-${variant.name}.apk" + } + } + } + val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE") signingConfigs { if (keystoreFile != null) { @@ -106,12 +115,10 @@ android { resValue("string", "app_name_suffixed", "Citron") isDefault = true - isShrinkResources = true isMinifyEnabled = true - isJniDebuggable = false isDebuggable = false proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), + getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" ) } @@ -121,10 +128,9 @@ android { register("relWithDebInfo") { resValue("string", "app_name_suffixed", "Citron Debug Release") signingConfig = signingConfigs.getByName("default") - isMinifyEnabled = true isDebuggable = true proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), + getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" ) versionNameSuffix = "-relWithDebInfo" @@ -165,7 +171,6 @@ android { path = file("../../../CMakeLists.txt") } } - buildToolsVersion = "35.0.1" defaultConfig { externalNativeBuild { @@ -183,14 +188,14 @@ android { "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON" ) - abiFilters("arm64-v8a") // , "x86_64") + abiFilters("arm64-v8a", "x86_64") } } } } tasks.create("ktlintReset") { - delete(File(layout.buildDirectory.toString() + File.separator + "intermediates/ktLint")) + delete(File(buildDir.path + File.separator + "intermediates/ktLint")) } val showFormatHelp = { @@ -207,6 +212,13 @@ ktlint { version.set("0.47.1") android.set(true) ignoreFailures.set(false) + disabledRules.set( + setOf( + "no-wildcard-imports", + "package-name", + "import-ordering" + ) + ) reporters { reporter(ReporterType.CHECKSTYLE) } @@ -222,36 +234,24 @@ play { } dependencies { - // AndroidX Core & UI implementation("androidx.core:core-ktx:1.12.0") - implementation("androidx.core:core-splashscreen:1.0.1") implementation("androidx.appcompat:appcompat:1.6.1") - implementation("androidx.constraintlayout:constraintlayout:2.1.4") implementation("androidx.recyclerview:recyclerview:1.3.1") - implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") - implementation("androidx.window:window:1.2.0-beta03") - implementation("com.google.android.material:material:1.9.0") - - // AndroidX Navigation - implementation("androidx.navigation:navigation-fragment-ktx:2.7.4") - implementation("androidx.navigation:navigation-ui-ktx:2.7.4") - - // AndroidX Lifecycle - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") - implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2") - - // AndroidX Other + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + implementation("androidx.fragment:fragment-ktx:1.6.1") implementation("androidx.documentfile:documentfile:1.0.1") - implementation("androidx.fragment:fragment-ktx:1.6.2") + implementation("com.google.android.material:material:1.9.0") implementation("androidx.preference:preference-ktx:1.2.1") - - // Kotlin - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0") - - // Third Party Libraries + implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2") implementation("io.coil-kt:coil:2.2.2") + implementation("androidx.core:core-splashscreen:1.0.1") + implementation("androidx.window:window:1.2.0-beta03") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") + implementation("androidx.navigation:navigation-fragment-ktx:2.7.4") + implementation("androidx.navigation:navigation-ui-ktx:2.7.4") implementation("info.debatty:java-string-similarity:2.0.0") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0") } fun runGitCommand(command: List): String { @@ -259,9 +259,7 @@ fun runGitCommand(command: List): String { ProcessBuilder(command) .directory(project.rootDir) .redirectOutput(ProcessBuilder.Redirect.PIPE) - - .redirectError(ProcessBuilder.Redirect.PIPE) - + .redirectError(ProcessBuilder.Redirect.PIPE) .start().inputStream.bufferedReader().use { it.readText() } .trim() } catch (e: Exception) { -- cgit v1.2.3