archy/Android/app/build.gradle.kts
Dorian 504944fd08 fix(wallet+companion): pre-demo blockers — Send modal TDZ crash, cold-start inset collapse, loader branding — 0.5.10
- SendBitcoinModal crashed AT MOUNT on device ('Cannot access R before
  initialization'): the invoice-first block's watch() evaluates its
  computed source at setup, which read effectiveMethod while still in
  its temporal dead zone (declared 20 lines later). Send button did
  nothing and the failure poisoned sibling modal data. Block moved below
  effectiveMethod, with a comment so it can't drift back.
- Cold start injected 0px safe-area vars (onPageFinished can beat window
  attachment; rootWindowInsets null) — UI lost top/bottom margins and
  the tab bar sat in the gesture zone eating taps. Injection extracted
  to injectSafeAreaVars(), re-fired from an OnApplyWindowInsetsListener
  when real insets arrive, on page finish, and on reattach.
- MeshLoadingScreen wears the proper brand: pixel 'a' in the black
  circle-container + F*CK IPS MESH wordmark.

Served APK: 0.5.10 (vc30). Reproduced+diagnosed live on-device.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 09:03:43 +01:00

166 lines
5.7 KiB
Plaintext

plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "com.archipelago.app"
compileSdk = 35
defaultConfig {
applicationId = "com.archipelago.app"
minSdk = 26
targetSdk = 35
versionCode = 30
versionName = "0.5.10"
vectorDrawables {
useSupportLibrary = true
}
// The embedded FIPS mesh (libarchy_fips_core.so) is built arm64-only,
// matching real handsets. FipsNative.available gates every call, so
// the app still runs as a plain companion elsewhere (e.g. x86 emu).
ndk { abiFilters += "arm64-v8a" }
}
signingConfigs {
// Repo-dedicated debug keystore (committed at app/debug.keystore) so every
// machine — and the published companion download — signs debug builds with
// the SAME key. Without this, Gradle falls back to each machine's
// ~/.android/debug.keystore, so a build from a different machine has a
// different signature and the phone rejects the update ("App not installed").
getByName("debug") {
storeFile = file("debug.keystore")
storePassword = "android"
keyAlias = "androiddebugkey"
keyPassword = "android"
// Force both legacy JAR (v1) and APK Signature Scheme v2. AGP drops v1
// for minSdk>=24, but some OEM package installers (e.g. Samsung) reject
// a v2-only sideload with "App not installed" — keep v1 for max compat.
enableV1Signing = true
enableV2Signing = true
}
}
buildTypes {
debug {
// Separate app ID so a debug/test build installs alongside the
// release app instead of colliding on signature.
applicationIdSuffix = ".debug"
versionNameSuffix = "-debug"
signingConfig = signingConfigs.getByName("debug")
}
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.14"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
// ---------------------------------------------------------------------------
// Embedded FIPS mesh: cross-compile Android/rust/archy-fips-core via cargo-ndk
// into jniLibs before the native-libs merge, so a plain `gradlew assembleDebug`
// builds the Rust too. Requires rustup target aarch64-linux-android, cargo-ndk,
// and an NDK (ANDROID_NDK_HOME or the SDK's ndk/ dir).
// ---------------------------------------------------------------------------
val rustCrateDir = layout.projectDirectory.dir("../rust/archy-fips-core")
val jniLibsDir = layout.projectDirectory.dir("src/main/jniLibs")
tasks.register<Exec>("buildRustArm64") {
workingDir = rustCrateDir.asFile
inputs.dir(rustCrateDir.dir("src"))
inputs.file(rustCrateDir.file("Cargo.toml"))
outputs.dir(jniLibsDir)
// cargo/cargo-ndk live in ~/.cargo/bin, which Gradle's env may not have.
val home = System.getProperty("user.home")
environment("PATH", "$home/.cargo/bin:${System.getenv("PATH")}")
if (System.getenv("ANDROID_NDK_HOME") == null) {
val sdkNdk = file("$home/Library/Android/sdk/ndk")
.listFiles()?.maxByOrNull { it.name }
if (sdkNdk != null) environment("ANDROID_NDK_HOME", sdkNdk.absolutePath)
}
commandLine(
"cargo", "ndk",
"-t", "arm64-v8a",
"--platform", "26",
"-o", jniLibsDir.asFile.absolutePath,
"build", "--release",
)
}
tasks.matching {
it.name in listOf(
"mergeDebugNativeLibs", "mergeReleaseNativeLibs",
"mergeDebugJniLibFolders", "mergeReleaseJniLibFolders",
)
}.configureEach { dependsOn("buildRustArm64") }
dependencies {
val composeBom = platform("androidx.compose:compose-bom:2024.05.00")
implementation(composeBom)
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.2")
implementation("androidx.activity:activity-compose:1.9.0")
// Compose
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.material:material-icons-extended")
implementation("androidx.compose.animation:animation")
// Navigation
implementation("androidx.navigation:navigation-compose:2.7.7")
// DataStore for preferences
implementation("androidx.datastore:datastore-preferences:1.1.1")
// WebView
implementation("androidx.webkit:webkit:1.11.0")
// Splash screen
implementation("androidx.core:core-splashscreen:1.0.1")
// OkHttp for WebSocket (remote input)
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// CameraX + ZXing (Apache-2.0, on-device, no telemetry) for pairing-QR scanning
implementation("androidx.camera:camera-camera2:1.3.4")
implementation("androidx.camera:camera-lifecycle:1.3.4")
implementation("androidx.camera:camera-view:1.3.4")
implementation("com.google.zxing:core:3.5.3")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}