- 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>
166 lines
5.7 KiB
Plaintext
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")
|
|
}
|