feat(android): native Android client — full app parity build (A1–A36 + S1)
Some checks failed
relay-tripwire / cross-tenant-tripwire (push) Has been cancelled
ios / package-tests (APIClient) (push) Has been cancelled
ios / package-tests (HostRegistry) (push) Has been cancelled
ios / package-tests (SessionCore) (push) Has been cancelled
ios / package-tests (WireProtocol) (push) Has been cancelled
ios / testsupport-tests (push) Has been cancelled
ios / app-tests (push) Has been cancelled
ios / ipad-tests (push) Has been cancelled
ios / integration-tests (push) Has been cancelled
ios / ui-test (push) Has been cancelled
ios / ios17-floor-tests (push) Has been cancelled
Some checks failed
relay-tripwire / cross-tenant-tripwire (push) Has been cancelled
ios / package-tests (APIClient) (push) Has been cancelled
ios / package-tests (HostRegistry) (push) Has been cancelled
ios / package-tests (SessionCore) (push) Has been cancelled
ios / package-tests (WireProtocol) (push) Has been cancelled
ios / testsupport-tests (push) Has been cancelled
ios / app-tests (push) Has been cancelled
ios / ipad-tests (push) Has been cancelled
ios / integration-tests (push) Has been cancelled
ios / ui-test (push) Has been cancelled
ios / ios17-floor-tests (push) Has been cancelled
Mirror the iOS P0+P1 client as a Gradle multi-module app. Pure-JVM (Kover ≥80% gated): :wire-protocol (frozen contract + HostEndpoint CSWSH origin + byte-exact codec), :session-core (SessionEngine + reconnect/ping/gate/digest reducers), :api-client, :client-tls (pure PKCS12/keymanager), :transport-okhttp (OkHttp WS+REST). Framework: :app (Compose M3 Adaptive, Hilt, FCM, 11 screens + NavGraph), :terminal-view (Termux terminal-emulator/-view via JitPack, Apache-2.0 — the renderer seam proven headless), :host-registry (DataStore), :client-tls-android (AndroidKeyStore + Tink). Highlights: single-key-home mTLS (non-exportable AndroidKeyStore key + re-reading X509KeyManager + connectionPool.evictAll on rotation, ping-pong single-commit so a failed rotation never clobbers the prior identity); FCM Allow/Deny trust split (Deny=BroadcastReceiver, Allow=trampoline Activity hosting BiometricPrompt); per-consumer-Channel EventBus (R10); config-surviving RetainedSessionHolder; byte-exact KeyByteMap; §5.4 pairing warning tiers. Verified: ~484 JVM tests + Kover ≥80% on the pure modules + :app assembles to an APK; all framework modules assemble. Device behaviors (rendering/IME/FCM/biometric/camera, E2E A34/A35, S2 real-handset FCM spike) deferred to android/DEVICE_QA_CHECKLIST.md per plan §7 (no emulator/Firebase here). Built via multi-agent orchestration (TDD builders → adversarial cross-review → fix → re-verify → independent gate); progress in android/PROGRESS_ANDROID.md.
This commit is contained in:
@@ -103,7 +103,10 @@ AGP library module compiled against SDK 35 and produced an AAR):
|
||||
|
||||
- **SDK location:** `/usr/local/share/android-commandlinetools`
|
||||
(installed via `brew install --cask android-commandlinetools`).
|
||||
- **Installed packages:** `platform-tools`, `platforms;android-35`, `build-tools;35.0.0`.
|
||||
- **Installed packages:** `platform-tools`, `platforms;android-35`, `platforms;android-36`,
|
||||
`build-tools;35.0.0`, `build-tools;36.0.0`. (`:app` compiles against SDK **36** — the
|
||||
Kotlin-2.3.21-contemporaneous androidx/Compose line refuses SDK 35; `platforms;android-37`
|
||||
is not fetchable here as the cmdline-tools are too old to parse the v4 repo XML.)
|
||||
- **`android/local.properties`** (gitignored) points Gradle at it:
|
||||
`sdk.dir=/usr/local/share/android-commandlinetools`.
|
||||
- **Shell env** (for `sdkmanager`/`adb`): `export ANDROID_HOME=/usr/local/share/android-commandlinetools`.
|
||||
@@ -116,7 +119,15 @@ AGP library module compiled against SDK 35 and produced an AAR):
|
||||
compatible with Gradle 9.6.1.
|
||||
- **Gotcha:** AGP 9 has **built-in Kotlin** — apply ONLY the android plugin. Adding
|
||||
`org.jetbrains.kotlin.android` errors with "no longer required since AGP 9.0".
|
||||
- Module block: `android { namespace = "…"; compileSdk = 35; defaultConfig { minSdk = 29 } }`.
|
||||
- Module block: `android { namespace = "…"; compileSdk = 36; defaultConfig { minSdk = 29 } }`.
|
||||
(Framework modules target `compileSdk = 36`; `targetSdk` stays `35` per plan §2.)
|
||||
- **`:app` UI-stack version matrix** (A13, proven `:app:assembleDebug` green): AGP 9.2.1 ·
|
||||
Kotlin 2.3.21 · Compose-compiler plugin `org.jetbrains.kotlin.plugin.compose` = 2.3.21 ·
|
||||
Compose BOM `2025.11.01` (→ material3 1.4.0, ui/foundation 1.9.5, material3.adaptive 1.2.0,
|
||||
material3-adaptive-navigation-suite 1.4.0) · Hilt (dagger) 2.60.1 via KSP `2.3.9` ·
|
||||
androidx core-ktx 1.17.0 / activity-compose 1.12.4 / lifecycle 2.10.0. Apply plugins:
|
||||
`android.application` + `kotlin.plugin.compose` + `ksp` + `dagger.hilt.android` (NEVER
|
||||
`kotlin.android`). Bump these together with `compileSdk 37` once platform 37 is installable.
|
||||
|
||||
To add more SDK pieces later (e.g. an emulator image for instrumented tests):
|
||||
`sdkmanager "system-images;android-35;google_apis;arm64-v8a" "emulator"`.
|
||||
|
||||
Reference in New Issue
Block a user