PONGo_android/HANDOFF.md
2026-05-31 14:09:00 +02:00

4.9 KiB
Raw Blame History

Handoff — PON Go Android

Context for the next session/developer. Pairs with README.md and docs/MCMS_API.md.

Architecture

  • core/ — pure Kotlin, no Android UI deps. Mirrors the iOS networking core.
    • JSON: MCMS docs are heterogeneous Mongo documents, so we keep raw kotlinx.serialization JsonElement trees and read fields via the accessors in Json.kt (el["key"], .string/.int/.double/.array/.obj) — the analogue of the iOS JSONValue. Models (Models.kt) are thin wrappers over a JsonElement with computed properties.
    • ApiClient (OkHttp): builds versioned requests, injects Referer + X-CSRFToken (writes), unwraps the {status,data} envelope, maps status codes to ApiError, paginates via the next cursor. Call.await() bridges OkHttp to coroutines with cancellation.
    • Repositories return model wrappers; McmsConnection wires it all; auth/cookies in Networking.kt (SessionCookieJar + SessionStore), TLS policy in ServerTrust, secrets in KeychainStore (EncryptedSharedPreferences).
  • ui/ — Jetpack Compose. Navigation is state-based in MainActivity (a List<Screen> back stack + BackHandler), not Navigation-Compose — so detail screens and the dashboard drill-downs can take in-memory objects directly. Each screen has a plain state-holder class (…Model) exposing mutableStateOf fields + suspend load()/refresh() — the analogue of the iOS @Observable view models. No androidx ViewModel/DI.

Build / verify loop (this matters)

The dev machine had no kotlinc/gradle on PATH, but Android Studio provides everything. Two loops:

  • Full build (authoritative):
    export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
    ./gradlew :app:assembleDebug --no-daemon --console=plain
    
    Needs local.properties (sdk.dir=…, git-ignored). First run downloads deps to ~/.gradle; afterwards it's ~2060 s. This is what proves the whole app (UI + resources + manifest + icons) compiles.
  • Quick core-only check (no Gradle), when iterating on core/: the bundled compiler at …/Android Studio.app/Contents/plugins/Kotlin/kotlinc/bin/kotlinc with -Xplugin=…/kotlinc/lib/kotlinx-serialization-compiler-plugin.jar and a classpath of Maven jars (kotlinx-serialization-json/core, okhttp, okio-jvm, kotlinx-coroutines-core-jvm). Compiles every core/*.kt except KeychainStore.kt (androidx). Faster than a Gradle round-trip.

API gotchas (all handled in code — don't regress)

  • Single-encode URLs. Ids stay RAW in McmsEndpoint; ApiClient encodes the path once via HttpUrl.addPathSegments. Pre-encoding double-encoded MAC colons (:%3A%253A) → MCMS "invalid id".
  • 401 bounces to login; 403 does NOT (permission/CSRF — requiresReauthentication is 401-only).
  • Writes return {"status":"success"} with no data — the unwrap tolerates it.
  • ONU registration lives on OLT-STATE buckets (OltRepository.registrationMap), not ONU-STATE. Friendly names are ONU.Name / OLT.Name (NOT NETCONF.Name).
  • CPE DHCP comes from the web helper GET /api/cpe/onu/<id>/ — a versionless, bare [code, cpe…] array (use ApiClient.getRaw).
  • Firmware = Procedure 7: GET ONU-CFG → write filename/version into the inactive bank → full-doc PUT (FirmwareUpgrade.apply). Inactive-bank only, so service stays up until the ONU reboots. Still worth testing on a spare ONU.
  • Field paths were confirmed against live JSON; see docs/MCMS_API.md and the model accessors.

Trimmed vs iOS (intentional, easy to restore)

  • ONU detail tabs are Overview / CPE / Logs / Config — no separate Alarms tab. Current alarms live on ONU-STATE "Alarm" buckets if you want to add it.
  • Config shows pretty-printed JSON text, not the collapsible tree the iOS app has.
  • Dashboard ONU-state rows aren't tappable (the Health rows are). The iOS app drills ONU-state → filtered ONU list.
  • Toggles use rememberSaveable (survive rotation, not process death). Persist in prefs if you want parity with iOS @AppStorage.
  • Self-signed/cleartext: the TLS trust policy is in ServerTrust. Plain-HTTP hosts also need a usesCleartextTraffic/network-security-config exception (Android's ATS analogue) — add when needed.

Repo split

This folder is self-contained (has its own docs/MCMS_API.md). To make it a git repo: git init here; the included .gitignore already excludes build/, .gradle/, local.properties, .idea/. Commit the Gradle wrapper (gradlew, gradle/wrapper/*). The full dev-guide PDFs (323-1961-30x) live in the iOS repo if you ever need the deep source.

Possible next steps

Restore the trimmed items above; add OLT firmware (Procedure 8 bulk task); per-ONU live-alarms view; charts for PM history; pull-to-refresh on lists; dark-theme polish; a proper app theme from the brand colours.