- Kotlin 68.4%
- Shell 20.9%
- JavaScript 7.9%
- PowerShell 1.6%
- AIDL 0.6%
- Other 0.4%
SecureSettingsDeviceControl: spegne il pannello scrivendo stay_on_while_plugged_in (WRITE_SECURE_SETTINGS) + screen_off_timeout (WRITE_SETTINGS) dove non c'e' dh-support, i sysfs backlight sono inerti e l'app non puo' fare `su` (Dahua DS04 / RK3288). Riaccensione via FLAG_TURN_SCREEN_ON + reorder-to-front (non richiede WAKE_LOCK). - cascade [android, secure-settings, generic] SOLO per box non-Dahua; secure-settings e' no-op senza i grant adb -> parco invariato, ramo Dahua T982 (enableBackLight) invariato - PARTIAL_WAKE_LOCK reso best-effort (try/catch): alcuni ROM (DS04) negano WAKE_LOCK pur dichiarato nel manifest -> non deve crashare - wake via finestra gated su lastScreenHandler == secure-settings - bump player 1.1.38 (code 41) |
||
|---|---|---|
| app | ||
| docs | ||
| field-installer | ||
| gradle/wrapper | ||
| launcher | ||
| protocol | ||
| tools | ||
| .gitignore | ||
| build.gradle.kts | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| README.md | ||
| settings.gradle.kts | ||
Kipanga Player (Android)
Stack di digital signage Android per totem unattended. Due APK co-firmate:
cloud.kipanga.player— renderizza la playlist del cliente (template HTML + JS sopra una WebView, ExoPlayer nativo per i video spot-creator), pollanode.kipanga.cloudper la config, scarica gli asset gallery, manda heartbeat.cloud.kipanga.launcher— Device Owner (o soft-kiosk dove il DO non è possibile). Fa da HOME di sistema, detiene le policy kiosk (Lock Task whitelist, status bar / keyguard disabled, stay-on-while-plugged-in), gira un watchdog che si appaia via AIDL col player e lo force-restart se hung, fa silent OTA install della APK player, e ospita lo stack di accesso remoto (Dropbear SSH su :2222, reverse tunnel, screenshot).
Più un modulo installer di supporto:
cloud.kipanga.installer(field-installer/) — app Android per il tecnico (telefono dedicato) che porta unadbstatico bundlato e installa/provisiona la flotta senza Mac né root. Mirror on-device ditools/kipanga-fleet-installer.sh.
Versioni correnti: player 1.1.35 (code 38), launcher 1.1.10 (code 13),
field-installer 1.0.1 (code 2); contratto AIDL ProtocolVersion.CURRENT = 3.
Le APK sono stabili e kiosk-locked. Bench box di validazione: T982 (Amlogic S905, Android 11), DS04 (Dahua RK3288, Android 8.1), Navori StiX (S922X). Target produzione: Android 11+ / API 30+.
Documentazione
| Documento | Per chi | Cosa contiene |
|---|---|---|
docs/dev/ONBOARDING.md |
sviluppatori | ambiente, struttura moduli, build, test, convenzioni |
docs/dev/ARCHITECTURE.md |
sviluppatori | forma a runtime, contratto AIDL, schema state.json, failure mode |
docs/dev/COMPATIBILITY.md |
sviluppatori | matrice di compatibilità launcher↔player↔AIDL proto |
docs/dev/PROVISIONING.md |
sviluppatori / tecnici | modello a 3 classi HW (Clean-DO / Reclaim / Soft-kiosk), engine kipanga-provision.sh |
docs/ops/PREPARAZIONE_PERIFERICA.md |
tecnici onsite | prerequisiti/prima messa a punto per modello (compatibilità, no account, ADB, quirk) |
docs/ops/INSTALLAZIONE.md |
tecnici onsite | provisioning presso il cliente — percorso cavo USB / WiFi |
docs/ops/COMANDI_SSH.md |
supporto / tecnici | cheat-sheet comandi operativi via SSH (reboot, refresh, log, stato, screenshot) |
docs/ops/ACCESSO_REMOTO.md |
supporto | SSH, reverse tunnel, screenshot |
docs/ops/OTA_SAFE_PROCEDURE.md |
rilascio / supporto | procedura OTA sicura: preflight statico, canary bench, soak, batch rollout |
docs/ops/TROUBLESHOOTING.md |
supporto / tecnici | diagnosi e recupero device, factory reset |
docs/ops/COMBO_TELECOMANDO.md |
tecnici | gesture hardware (hold WiFi / hold factory-reset) |
field-installer/README.md |
sviluppatori / tecnici | app installer Android (adb bundlato), architettura e uso |
docs/team-server/ |
team server Kipanga | API OTA / provisioning, problemi di data-quality |
Stato
| Area | Stato |
|---|---|
| Robustezza player (state.json, tolerant config parser, WebView watchdog, log rotator, SC retry+refresh, restart-on-do-refresh) | ✅ done |
Launcher + modulo AIDL :protocol + watchdog |
✅ done |
| Device Owner + Lock Task + kiosk UI policies | ✅ done |
Tooling provisioning (kipanga-install.sh, kipanga-provision.sh, kipanga-fleet-installer.sh, field-installer, QR template) |
✅ done |
| SSH interattivo su Android (fix Dropbear getpwnam/segfault, sessioni PTY/console) | ✅ done — validato su T982 + StiX |
| OTA: silent player install via AIDL launcher | ✅ done client-side — endpoint server pendenti, vedi docs/team-server/API_OTA_PROVISIONING.md |
| SSH server locale (Dropbear cross-compilato, patch Android-compat) | ✅ done |
Reverse SSH tunnel outbound device→pop.pointonpeople.com |
✅ done — validato end-to-end |
Screenshot remoto via MediaProjection + endpoint HTTP |
✅ done (consent auto-tappato, zero operator interaction) |
authorized_keys fleet-wide sync (ETag, atomic write) |
✅ done |
| Controllo remoto interattivo — stream MJPEG + iniezione tap/swipe via HTTP | ✅ done client-side — da testare su HW reale |
Stack tecnologico
| Layer | Scelta |
|---|---|
| Linguaggio | Kotlin 2.2.21 |
| Build | Gradle 9.4.1 (wrapper) + AGP 9.2.0 |
| JVM toolchain | 21 |
| Min / target SDK | 28 / 34 |
| HTTP (player) | OkHttp 4.12 |
| HTTP (launcher) | java.net.HttpURLConnection (solo stdlib — dex piccola) |
| JSON | Gson 2.10.1 + TolerantConfigParser custom |
| Async | Kotlinx Coroutines 1.7.3 |
| WebView | WebView di sistema (Chromium, warm-up al boot) |
| Video nativo | androidx.media3 / ExoPlayer 1.3.1 |
| IPC | AIDL — ILauncherWatchdog nel modulo :protocol |
| Test | JUnit 4 + kotlin-test, unit JVM (:app:testDebugUnitTest) |
Layout repo
KipangaPlayer/
├── app/ :app — cloud.kipanga.player
├── launcher/ :launcher — cloud.kipanga.launcher (Device Owner / soft-kiosk)
│ └── src/main/jniLibs/<abi>/libdropbear.so — SSH server cross-compiled (committato)
├── field-installer/:field-installer — cloud.kipanga.installer (app installer, adb bundlato)
├── protocol/ :protocol — Android library, solo contratto AIDL
├── tools/
│ ├── kipanga-install.sh — provisioning onsite one-script (scan+install+DO)
│ ├── kipanga-provision.sh — engine provisioning a 3 classi HW
│ ├── kipanga-fleet-installer.sh — engine di riferimento del field-installer
│ ├── ota-preflight.sh — gate statico OTA (firma + manifest + versionCode)
│ ├── ota-canary-watch.sh — soak automatico del canary
│ ├── install_tunnel_key.sh — converte + installa la chiave del reverse tunnel
│ ├── build-dropbear.sh — cross-compile del server SSH (con patch Android)
│ ├── qr_provisioning_template.json — template QR factory-reset
│ └── … (provision-dahua-ys.sh, dahua-ds04-webview.sh, kipanga-release.sh, …)
├── docs/ — vedi sezione Documentazione sopra
└── README.md
Build rapida
# Debug, entrambe le APK
./gradlew :app:assembleDebug :launcher:assembleDebug
# Release firmate (keystore in ~/.kipanga-secrets/keystore.properties)
./gradlew :app:assembleRelease :launcher:assembleRelease
# Unit test del player
./gradlew :app:testDebugUnitTest
# Provisioning onsite (scan rete + install launcher/player + Device Owner)
tools/kipanga-install.sh
Setup completo, struttura dei moduli e convenzioni →
docs/dev/ONBOARDING.md.
Pipeline a runtime (in breve)
Boot → MainActivity launcher → DO policies applied → player lanciato → config
pollata da node.kipanga.cloud → registration se status_code ∈ {0,5} →
gallery sync → page render → metronome rotation. Watchdog AIDL ogni 10 s; se
silenzio > 30 s il launcher force-restart il player. Flag dal server:
do_refresh=1 (restart pulito), do_upgrade=1 (re-fetch template firmware),
do_apk_upgrade=1 (silent self-update).
Quadro completo → docs/dev/ARCHITECTURE.md.