import java.util.Properties plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } // Identifiants WebDAV de distribution (Nextcloud) lus depuis local.properties // — jamais commités. Voir local.properties + project_kazeia_installer_updates. val localProps = Properties().apply { val f = rootProject.file("local.properties") if (f.exists()) f.inputStream().use { load(it) } } fun localProp(key: String, default: String = ""): String = localProps.getProperty(key) ?: default // Keystore release — identifiants lus depuis /opt/Kazeia/keystore/credentials.properties // (hors git, à SAUVEGARDER hors machine). Voir docs/RELEASE_SIGNING.md. // Absent (autre machine) → le build release retombe sur la clé debug avec un warning. val releaseKeystoreProps = Properties().apply { val f = file("/opt/Kazeia/keystore/credentials.properties") if (f.exists()) f.inputStream().use { load(it) } } val hasReleaseKeystore = releaseKeystoreProps.getProperty("storeFile") ?.let { file(it).exists() } == true android { namespace = "com.kazeia" compileSdk = 36 ndkVersion = "27.3.13750724" signingConfigs { if (hasReleaseKeystore) { create("release") { storeFile = file(releaseKeystoreProps.getProperty("storeFile")) storePassword = releaseKeystoreProps.getProperty("storePassword") keyAlias = releaseKeystoreProps.getProperty("keyAlias") keyPassword = releaseKeystoreProps.getProperty("keyPassword") } } } defaultConfig { applicationId = "com.kazeia" minSdk = 28 targetSdk = 36 versionCode = 6 versionName = "0.1.5" // WebDAV de distribution — injecté depuis local.properties. buildConfigField("String", "WEBDAV_BASE", "\"${localProp("webdav.base")}\"") buildConfigField("String", "WEBDAV_USER", "\"${localProp("webdav.user")}\"") buildConfigField("String", "WEBDAV_PASS", "\"${localProp("webdav.pass")}\"") ndk { abiFilters += "arm64-v8a" } externalNativeBuild { cmake { cppFlags += "-std=c++17" arguments += "-DANDROID_STL=c++_shared" } } } externalNativeBuild { cmake { path = file("src/main/jni/CMakeLists.txt") version = "3.22.1" } } buildTypes { release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) if (hasReleaseKeystore) { signingConfig = signingConfigs.getByName("release") } else { logger.warn("⚠ keystore release absent (/opt/Kazeia/keystore/) — release signé en DEBUG. Voir docs/RELEASE_SIGNING.md") signingConfig = signingConfigs.getByName("debug") } } } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" } buildFeatures { viewBinding = true buildConfig = true } sourceSets { getByName("main") { jniLibs.srcDirs("src/main/jniLibs") } } } // Reproductibilité des jniLibs : les .so (gitignorés, 5 chaînes de build) doivent // correspondre au manifest versionné. Un build RELEASE avec des libs divergentes // échoue ; le debug reste libre (itération engine). Cf scripts/jnilibs.sh. val verifyJniLibs = tasks.register("verifyJniLibs") { commandLine("bash", rootProject.file("scripts/jnilibs.sh").absolutePath, "verify") } tasks.matching { it.name == "preReleaseBuild" }.configureEach { dependsOn(verifyJniLibs) } dependencies { // Tests unitaires JVM (src/test/) — logique pure : CrisisGuard, VectorIndex, Chunker. // Lancer : ./gradlew :app:testDebugUnitTest testImplementation("junit:junit:4.13.2") // Android implementation("androidx.core:core-ktx:1.15.0") implementation("androidx.appcompat:appcompat:1.7.0") implementation("androidx.recyclerview:recyclerview:1.4.0") implementation("com.google.android.material:material:1.12.0") implementation("androidx.constraintlayout:constraintlayout:2.2.1") // Coroutines implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0") // Lifecycle (StateFlow observation) implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7") // ONNX Runtime (for Silero VAD) implementation("com.microsoft.onnxruntime:onnxruntime-android-qnn:1.24.3") // LiteRT + QNN (for Whisper NPU) implementation("com.google.ai.edge.litert:litert:1.4.2") implementation("com.google.ai.edge.litert:litert-api:1.4.2") implementation("com.qualcomm.qti:qnn-litert-delegate:2.44.0") implementation("com.qualcomm.qti:qnn-runtime:2.44.0") // ExecuTorch JNI dependencies (for TTS CP on NPU) implementation("com.facebook.fbjni:fbjni:0.7.0") implementation("com.facebook.soloader:nativeloader:0.10.5") implementation(files("libs/executorch.jar")) // OkHttp — client WebDAV pour téléchargement modèles depuis Nextcloud implementation("com.squareup.okhttp3:okhttp:4.12.0") // WorkManager — orchestration du téléchargement modèles (foreground, reprise) implementation("androidx.work:work-runtime-ktx:2.9.1") // SQLCipher for encrypted conversation history (RGPD / secret médical) implementation("net.zetetic:sqlcipher-android:4.5.4@aar") implementation("androidx.sqlite:sqlite-ktx:2.4.0") // EncryptedSharedPreferences pour stocker la passphrase SQLCipher // (clef wrappée par Android Keystore, persistante). implementation("androidx.security:security-crypto:1.1.0-alpha06") // Unity as a Library (UaaL) — DISABLED // implementation(project(":unityLibrary")) // implementation("androidx.games:games-activity:3.0.5") // compileOnly(files("../unityLibrary/unityLibrary/libs/unity-classes.jar")) }