Establish native Linux ARM64 Android CI and verification gates (#94)
This commit is contained in:
1 parent
1abd75282e
commit
66b1d4a4c4
29 files changed
+1882
-56
No files matched your search
+18
-17
@@ -1,9 +1,11 @@
|
||||
# Native Android build
|
||||
|
||||
Architecture and issue ownership: [ADR](../docs/android/architecture.md) and
|
||||
[parity matrix](../docs/android/parity.md). The native foundation implements #89 and #92. Onboarding and secure storage
|
||||
are implemented by their milestone issues. Both variants now invoke Rust through
|
||||
the generated UniFFI API.
|
||||
[parity matrix](../docs/android/parity.md). The native foundation implements #89–#94, including private storage, Keystore
|
||||
callbacks and build gates. Both variants invoke Rust through the generated
|
||||
UniFFI API. Onboarding and the feature screens remain owned by their milestone
|
||||
issues. The full [CI and emulator workflow](../docs/android/ci.md) documents the
|
||||
ARM-only runner/toolchain policy and artifact audits.
|
||||
|
||||
## Reproducible setup
|
||||
|
||||
@@ -63,10 +65,11 @@ 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 packaged. Native runtime packaging is described
|
||||
and the selected two ARM ABIs are packaged. Native runtime packaging is described
|
||||
below; no development network endpoint is included.
|
||||
|
||||
The manifest has only the exported launcher activity. Backup/cloud/device-transfer
|
||||
The manifest exports the launcher and the reviewed AndroidX profile receiver
|
||||
protected by the privileged DUMP permission. 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.
|
||||
@@ -93,14 +96,14 @@ Install the pinned build tools once:
|
||||
|
||||
```sh
|
||||
rustup toolchain install 1.97.1 --profile minimal
|
||||
rustup target add --toolchain 1.97.1 aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
|
||||
rustup target add --toolchain 1.97.1 aarch64-linux-android armv7-linux-androideabi
|
||||
cargo install cargo-ndk --version 4.1.2 --locked
|
||||
```
|
||||
|
||||
Gradle checks the actual Cargo/cargo-ndk/NDK revisions before building. Each
|
||||
variant compiles crates/android with cargo-ndk into its own generated jniLibs,
|
||||
then verifies ELF architecture, 16 KB LOAD alignment, and byte-identical UniFFI
|
||||
metadata across all three ABIs. A packaging step selects only the Android library
|
||||
metadata across both ARM ABIs. A packaging step selects only the Android library
|
||||
and rejects accidental inclusion of the dependency Apple cdylib. The thin Android crate re-exports the existing
|
||||
UniFFI component; it duplicates no storage rules or converters. #91 owns the
|
||||
platform-neutral contract extraction. No handwritten JNI or unsafe Rust is added.
|
||||
@@ -126,15 +129,14 @@ newer state. Blocking fixture calls finish in Rust when a coroutine is cancelled
|
||||
no thread is forcibly stopped. Long storage operations must use their Rust-owned
|
||||
cancellation methods when their feature is integrated.
|
||||
|
||||
No Rust-to-Kotlin platform callbacks are installed by #92. When #93 adds them,
|
||||
use generated UniFFI/JNA callback adapters only: JNA attaches a calling native
|
||||
#93 installs Rust-to-Kotlin Keystore callbacks through generated UniFFI/JNA
|
||||
adapters: JNA attaches a calling native
|
||||
thread to the JVM; retain the callback for the full Rust owner lifetime, release
|
||||
it after unregistering, never assume the callback runs on the Android main thread,
|
||||
and marshal UI/Activity work onto Main. Keep storage decisions in Rust and avoid
|
||||
blocking the main thread or calling back into a held Rust lock.
|
||||
|
||||
JNA 5.19.1 is packaged as its Android AAR, filtered to arm64-v8a, armeabi-v7a and
|
||||
x86_64. The release set may only be narrowed by changing the support decision in
|
||||
JNA 5.19.1 is packaged as its Android AAR, filtered to arm64-v8a, armeabi-v7a only. The release set is arm64-v8a and armeabi-v7a under the user amendment to
|
||||
#88, not by silently omitting an ABI. All source/lock/config files are task inputs;
|
||||
outputs live only under build/. Debug and release compile independently, and
|
||||
unchanged builds reuse their outputs. R8 keeps generated/JNA reflection entry
|
||||
@@ -144,17 +146,16 @@ that file and outputs/mapping/release/mapping.txt with the matching release.
|
||||
AAB base/lib entries let Play produce per-ABI splits.
|
||||
|
||||
The auditNativePackages gate inspects every native dependency in both APKs and
|
||||
the AAB, checks all three ABI directories and both Rust/JNA libraries, and rejects
|
||||
the AAB, checks both ARM ABI directories and both Rust/JNA libraries, and rejects
|
||||
ELF segments below 16 KB alignment or APK native entries that are compressed or
|
||||
not ZIP-aligned to 16 KB. Follow the official [16 KB runtime validation](https://developer.android.com/guide/practices/page-sizes):
|
||||
use an actual 16 KB system image, check adb shell getconf PAGE_SIZE is 16384,
|
||||
disable page-size compatibility mode, and run both instrumented test suites.
|
||||
An ELF/ZIP audit is not a substitute for that runtime test. Milestone validation
|
||||
is emulator-only per the user instruction of 2026-10-08; physical devices are
|
||||
outside the test scope for every issue. Keep x86_64 emulator evidence separate
|
||||
from the Apple Silicon arm64 emulator run.
|
||||
outside the test scope for every issue. The user removed x86_64 Android from the current support scope on 2026-10-08.
|
||||
|
||||
Validation recorded on 2026-10-08 for #92:
|
||||
Historical validation recorded on 2026-10-08 for #92 (before the ARM-only scope update):
|
||||
|
||||
| Environment | Verified |
|
||||
| --- | --- |
|
||||
@@ -165,5 +166,5 @@ Validation recorded on 2026-10-08 for #92:
|
||||
| Physical devices | Excluded from milestone testing by user instruction |
|
||||
| x86_64 runtime | System image installed; QEMU2 rejects x86_64 on this aarch64 Mac, including with acceleration disabled |
|
||||
|
||||
The outstanding x86_64 emulator check needs a compatible host; cross-compilation
|
||||
and static package checks do not establish x86_64 runtime coverage.
|
||||
The historical x86_64 runtime gap is no longer a required check under the current
|
||||
ARM-only support decision.
|
||||
Reference in new issue
Block a user