1plugins {2 id "com.android.application"3 id "org.jetbrains.kotlin.android"4 id "org.jetbrains.kotlin.plugin.compose"5 id "org.jetbrains.kotlin.plugin.parcelize"6 id "org.jetbrains.kotlin.plugin.serialization"7 id "kotlin-kapt"8 id "com.google.dagger.hilt.android"9}1011android {12 namespace "com.peachpasswords"13 compileSdk 351415 defaultConfig {16 applicationId "com.peachpasswords"17 minSdk 2618 targetSdk 3519 versionCode 24011820 versionName "2.5.18"2122 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"23 vectorDrawables {24 useSupportLibrary true25 }26 }2728 signingConfigs {29 release {30 // Read from local.properties (koh-ignored) so the keystore and its31 // password never enter version history. Absent on a machine without32 // the key -> release build stays unsigned rather than failing.33 def props = new Properties()34 def f = rootProject.file("local.properties")35 if (f.exists()) { f.withInputStream { props.load(it) } }36 if (props.getProperty("peachStoreFile")) {37 storeFile file(props.getProperty("peachStoreFile"))38 storePassword props.getProperty("peachStorePassword")39 keyAlias props.getProperty("peachKeyAlias")40 keyPassword props.getProperty("peachKeyPassword")41 }42 // v3 is the only escape hatch from "this key is forever": it carries a43 // rotation lineage, so a future key can be proven to descend from this44 // one instead of forcing every tester to uninstall and lose their45 // vault. AGP leaves it off unless asked.46 enableV2Signing true47 enableV3Signing true48 }49 }5051 // ABI splits were tried and removed: the native libraries are ~2.5 MB of a52 // 24 MB APK, so per-ABI builds saved 8% in exchange for four artifacts and53 // a "which one do I need?" question at every install. The weight is 62 MB of54 // DEX, because `minifyEnabled false` below leaves R8 off entirely — that is55 // the lever worth pulling, and it needs its own pass with real-device56 // verification (kotlinx.serialization, BouncyCastle, Hilt, Compose).5758 buildTypes {59 debug {60 applicationIdSuffix ".debug"61 versionNameSuffix "-debug"62 debuggable true63 }64 release {65 signingConfig signingConfigs.release66 minifyEnabled false67 proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"68 }69 }7071 compileOptions {72 sourceCompatibility JavaVersion.VERSION_1773 targetCompatibility JavaVersion.VERSION_1774 }7576 kotlinOptions {77 jvmTarget = "17"78 }7980 buildFeatures {81 compose true82 buildConfig true83 }8485 composeOptions {86 kotlinCompilerExtensionVersion "1.5.15"87 }8889 packaging {90 resources {91 excludes += [92 "/META-INF/{AL2.0,LGPL2.1}",93 "META-INF/DEPENDENCIES",94 "META-INF/LICENSE*",95 "META-INF/NOTICE*",96 ]97 }98 }99100 testOptions {101 unitTests.all {102 def coreDir = rootProject.file("../peach-browser/crypto-core")103 def nativeLibrary = new File(104 coreDir,105 "target/release/libpeach_noise_core.dylib",106 )107 if (coreDir.exists()) {108 dependsOn rootProject.tasks.named("buildRustNoiseHost")109 systemProperty "peach.noise.library.path", nativeLibrary.absolutePath110 }111 }112 }113}114115dependencies {116 implementation platform("androidx.compose:compose-bom:2024.06.00")117 androidTestImplementation platform("androidx.compose:compose-bom:2024.06.00")118119 implementation "androidx.activity:activity-compose:1.9.2"120 implementation "androidx.autofill:autofill:1.1.0"121 implementation "androidx.biometric:biometric:1.1.0"122 implementation "androidx.core:core-splashscreen:1.0.1"123 implementation "androidx.appcompat:appcompat:1.7.0"124 implementation "androidx.credentials:credentials:1.5.0"125 implementation "androidx.credentials:credentials-play-services-auth:1.5.0"126 implementation "androidx.glance:glance-appwidget:1.1.0"127 implementation "androidx.glance:glance-material3:1.1.0"128 implementation "androidx.hilt:hilt-navigation-compose:1.2.0"129 // In-app updates: a periodic release check that survives Doze without a130 // service. hilt-work lets the worker take UpdateRepository by injection131 // rather than reaching for a global.132 implementation "androidx.hilt:hilt-work:1.2.0"133 kapt "androidx.hilt:hilt-compiler:1.2.0"134 implementation "androidx.work:work-runtime-ktx:2.9.1"135 implementation "androidx.lifecycle:lifecycle-runtime-compose:2.8.4"136 implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4"137 implementation "androidx.lifecycle:lifecycle-process:2.8.4"138 implementation "androidx.navigation:navigation-compose:2.8.0"139 // MN-6: androidx.security:security-crypto has no stable 1.1.x release — the only140 // stable line is 1.0.0 (2021), which lacks the Tink updates and Android 12+ fixes141 // in the 1.1.0 alphas and is widely superseded in production. Deliberately pinned142 // to an exact alpha (never a floating range) so the resolved artifact is143 // reproducible. Revisit if/when 1.1.0 stabilises. Used only for the duress/license144 // EncryptedSharedPreferences; the vault slots are sealed by VaultCrypto, not this.145 implementation "androidx.security:security-crypto:1.1.0-alpha06"146 implementation "androidx.compose.material3:material3"147 implementation "androidx.compose.ui:ui"148 implementation "androidx.compose.ui:ui-tooling-preview"149 implementation "androidx.compose.foundation:foundation"150 implementation "androidx.compose.material:material-icons-extended"151 implementation "androidx.core:core-ktx:1.13.1"152 implementation "com.google.android.material:material:1.12.0"153154 implementation "com.google.dagger:hilt-android:2.51.1"155 kapt "com.google.dagger:hilt-compiler:2.51.1"156 implementation "com.google.zxing:core:3.5.3"157 implementation "androidx.camera:camera-core:1.3.4"158 implementation "androidx.camera:camera-camera2:1.3.4"159 implementation "androidx.camera:camera-lifecycle:1.3.4"160 implementation "androidx.camera:camera-view:1.3.4"161 implementation "com.squareup.okhttp3:okhttp:4.12.0"162 implementation "org.bouncycastle:bcprov-jdk18on:1.78.1"163 // zstd-jni (reference libzstd) — per-section compression for the PeachScript164 // PCHS binary format (MF-2). Required for cross-platform interop with the165 // browser's zstd sections. The @aar variant ships the Android jniLibs166 // (lib/<abi>/libzstd-jni.so); the plain jar bundles only desktop natives and167 // would fail with UnsatisfiedLinkError on-device.168 implementation "com.github.luben:zstd-jni:1.5.6-3@aar"169 // The @aar ships only Android .so; the plain jar carries the desktop natives170 // the host JVM unit tests need.171 testImplementation "com.github.luben:zstd-jni:1.5.6-3"172 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"173 implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1"174175 debugImplementation "androidx.compose.ui:ui-tooling"176 debugImplementation "androidx.compose.ui:ui-test-manifest"177178 androidTestImplementation "androidx.test.ext:junit:1.2.1"179 androidTestImplementation "androidx.test.espresso:espresso-core:3.6.1"180 androidTestImplementation "androidx.compose.ui:ui-test-junit4"181182 testImplementation "junit:junit:4.13.2"183 // Real org.json on the unit-test classpath; android.jar's is a throwing stub,184 // so the release-manifest parser would otherwise be untestable off-device.185 testImplementation "org.json:json:20240303"186 testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1"187}