Scaffold native Android build and enforce Rust boundaries (#89)
Dependency security audit / rustsec (push) Failing after 22s
Dependency security audit / rustsec (push) Failing after 22s
This commit is contained in:
1 parent
30d9119302
commit
e079b82b15
62 files changed
+5822
No files matched your search
@@ -0,0 +1,89 @@
|
||||
# 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.
|
||||
Reference in new issue
Block a user