90 lines
4.8 KiB
Markdown
90 lines
4.8 KiB
Markdown
# Native Android build
|
|
|
|
Architecture and issue ownership: [ADR](../docs/android/architecture.md) and
|
|
[parity matrix](../docs/android/parity.md). This scaffold implements #89. It is
|
|
an installable native Compose foundation; onboarding, secure storage and native
|
|
runtime packaging are implemented by their milestone issues.
|
|
|
|
## Reproducible setup
|
|
|
|
Use a stable workspace Rust toolchain satisfying Cargo.toml, a JDK 25 installation
|
|
(Android Studio's JetBrains Runtime 25 is suitable), Android SDK Platform 37,
|
|
build-tools 36.0.0 and NDK 30.0.16248370. The app emits JVM 17-compatible code
|
|
and supports minSdk 26. Set JAVA_HOME and ANDROID_HOME/ANDROID_SDK_ROOT or create
|
|
an ignored local.properties containing sdk.dir. Cargo must be in the IDE/build
|
|
process PATH, or set CARGO to its absolute executable path. No machine paths are
|
|
committed.
|
|
|
|
The committed Gradle 9.8.1 wrapper verifies the distribution SHA-256. Its JAR
|
|
SHA-256 is 3b8a25775a69158b5ad2b1d17a80a88dc7b40a352a73eb27d06c612a7ce68e98,
|
|
verified against the official Gradle version metadata. AGP 9.4.1 includes Kotlin
|
|
support; the Kotlin JVM/Compose plugin pin upgrades its classpath consistently
|
|
to 2.4.20. Do not additionally apply kotlin-android with built-in Kotlin enabled.
|
|
The version catalog is the single source for Android dependency/SDK/NDK pins.
|
|
|
|
From this directory:
|
|
|
|
```sh
|
|
./gradlew :app:assembleDebug :app:assembleRelease :app:testDebugUnitTest :app:lintDebug ktlintCheck
|
|
./gradlew :app:connectedDebugAndroidTest
|
|
```
|
|
|
|
Repeat the first command to verify configuration-cache reuse. Dependency
|
|
verification is strict by default; committed SHA-256 metadata covers resolved
|
|
build/test artifacts. Locks pin resolvable module configurations. To update an
|
|
approved version, edit the catalog, verify the upstream artifact/release/license,
|
|
then explicitly regenerate checksums/locks, inspect the diff and run the gates:
|
|
|
|
```sh
|
|
./gradlew :app:assembleDebug :app:assembleRelease :app:testDebugUnitTest :app:lintDebug ktlintCheck --write-verification-metadata sha256 --write-locks
|
|
```
|
|
|
|
## Boundaries and fixtures
|
|
|
|
The app composition root injects an Android-facing ShellRepository. Compose
|
|
features consume that contract through a Hilt ViewModel and collect immutable
|
|
StateFlow state with lifecycle awareness. Only core depends on rust-bridge;
|
|
platform implements core OS contracts. Gradle rejects forbidden module edges
|
|
and competing domain dependencies. The Rust android-build tool checks Kotlin
|
|
source/import boundaries and subprocess paths before every Android build.
|
|
These static checks accompany code review; they do not prove arbitrary Kotlin
|
|
code cannot conceal a domain implementation.
|
|
|
|
Debug-only Loading/Empty/Ready/Locked/Error fixtures are generated from the
|
|
storage-owned MobileShell::fixture by the Rust build tool. Debug controls select
|
|
the fixture and native tabs; these controls and generated fake states are absent
|
|
from release. Release displays the scaffold state and does not pretend to have
|
|
opened/decrypted a repository. Future #92 replaces scaffold wiring with generated
|
|
UniFFI calls; feature code continues to consume the facade.
|
|
|
|
## Identity, signing and update
|
|
|
|
All app build types keep de.rfc1437.ironstorage; test IDs are derived by AGP.
|
|
Version code 1 and name 1.0.1 are deterministic initial metadata. Debug signing
|
|
uses the standard local debug key. Release has no configured signing key and
|
|
produces an unsigned APK; #112 configures protected upload signing. Do not add
|
|
signing secrets or store passwords to the repository. Native symbol level FULL
|
|
and the selected three ABIs are declared for later Rust packaging; the scaffold
|
|
ships no native secret runtime or development network endpoint.
|
|
|
|
The manifest has only the exported launcher activity. Backup/cloud/device-transfer
|
|
exclusions and cleartext denial are explicit. Feature-specific services/permissions
|
|
are added with their owning issues. Resources use values directories for future
|
|
localization; vector/adaptive/monochrome icons and R8 consumer rules are present.
|
|
The launcher uses an unchanged copy of the iPhone vault artwork from
|
|
apple/Assets.xcassets/AppIcon.appiconset/AppIcon.png, inset for Android's adaptive
|
|
mask. Its themed monochrome layer keeps the round vault, wheel and hinge motif.
|
|
Keep the two platforms' launcher branding aligned when updating that artwork.
|
|
|
|
Install updates over the existing simulator app without uninstall or data reset:
|
|
|
|
```sh
|
|
adb -s DEVICE install -r app/build/outputs/apk/debug/app-debug.apk
|
|
```
|
|
|
|
Keep the same AVD and application ID. Never wipe its data/keychain or seed a test
|
|
app-data package as an update. After closing an issue, clean its project build
|
|
outputs and Cargo target; preserve the emulator and shared SDK/toolchain caches.
|
|
AGP's leaveApksInstalledAfterRun option is enabled so instrumented checks do not
|
|
uninstall the app after running. Keep it enabled for this persistent test device.
|