Files
web-terminal/android/host-registry/build.gradle.kts
Yaojia Wang e254918b1c
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
feat(android): native Android client — full app parity build (A1–A36 + S1)
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.
2026-07-10 16:41:21 +02:00

62 lines
2.5 KiB
Plaintext

// ─────────────────────────────────────────────────────────────────────────────
// :host-registry (A12) — Host list + LastSessionStore behind interfaces, backed by
// Jetpack DataStore (Preferences). Mirrors the iOS HostRegistry package: storage
// lives behind an interface (HostStore / LastSessionStore), the immutable list
// transforms (upserting/removing) are shared helpers that never mutate, and the
// in-memory doubles double as JVM-testable fakes for the AW4 ViewModel tests.
//
// Android-framework-bound (DataStore needs a Context/File), so DataStore-backed
// stores are exercised in androidTest (compile here, run on device — no emulator).
// The pure logic (Host list transforms, in-memory doubles, HostCodec at-rest
// reconstruct/drop-invalid) is covered by plain JVM JUnit5 unit tests.
//
// AGP 9 has built-in Kotlin → apply ONLY com.android.library (adding
// org.jetbrains.kotlin.android errors). The serialization compiler plugin is added
// via its alias and composes with the built-in Kotlin compilation (PersistedHost
// is @Serializable — the at-rest DTO).
// ─────────────────────────────────────────────────────────────────────────────
plugins {
id("com.android.library")
alias(libs.plugins.kotlin.serialization)
}
android {
namespace = "wang.yaojia.webterm.hostregistry"
compileSdk = 36
defaultConfig {
minSdk = 29
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
kotlin {
jvmToolchain(17)
}
dependencies {
api(project(":wire-protocol"))
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.androidx.datastore.preferences)
testImplementation(libs.bundles.unit.test)
testRuntimeOnly(libs.junit.platform.launcher)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.test.core)
androidTestImplementation(libs.androidx.test.runner)
}
// Local (JVM) unit tests run on the JUnit 5 platform, matching the pure modules
// and the :app design-token tests.
tasks.withType<Test>().configureEach {
useJUnitPlatform()
}