From 5912e47e32941e8335e3f3d82b4c1fba500c5261 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sun, 15 Nov 2026 15:59:49 +0100 Subject: [PATCH] feat(android): Cockpit-App und Android-Agent per MDM ausrollen Beide Apps lesen ihre Verbindungsdaten aus der App-Konfiguration des MDM (Android Managed Configuration). Sind host und token gesetzt, verbindet sich die App ohne QR-Code; die MDM-Werte haben Vorrang vor der Eingabe am Geraet. - Cockpit (com.ariacockpit): host, token, port, tls; natives Modul MdmConfig, gelesen beim Start in rvs.loadConfig() - Agent (de.hackersoft.ariaagent): zusaetzlich name, control, reply_mode; gelesen beim App-Start und nach dem Booten - README: Abschnitt "Ausrollen per MDM" mit Screenshots unter docs/images/mdm/ Co-Authored-By: Claude Opus 5.5 --- README.md | 61 +++++++++++++++++- .../android/app/src/main/AndroidManifest.xml | 4 ++ .../java/com/ariacockpit/MainApplication.kt | 1 + .../java/com/ariacockpit/MdmConfigModule.kt | 52 +++++++++++++++ .../app/src/main/res/values/mdm_strings.xml | 10 +++ .../app/src/main/res/xml/app_restrictions.xml | 25 +++++++ android/src/services/rvs.ts | 33 ++++++++++ docs/images/mdm/mdm-app-konfiguration.png | Bin 0 -> 19068 bytes docs/images/mdm/mdm-typ-auswahl.png | Bin 0 -> 2860 bytes .../android/app/src/main/AndroidManifest.xml | 5 ++ .../de/hackersoft/ariaagent/BootReceiver.kt | 1 + .../de/hackersoft/ariaagent/MainActivity.kt | 10 ++- .../java/de/hackersoft/ariaagent/MdmConfig.kt | 44 +++++++++++++ .../app/src/main/res/values/mdm_strings.xml | 15 +++++ .../app/src/main/res/xml/app_restrictions.xml | 41 ++++++++++++ 15 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 android/android/app/src/main/java/com/ariacockpit/MdmConfigModule.kt create mode 100644 android/android/app/src/main/res/values/mdm_strings.xml create mode 100644 android/android/app/src/main/res/xml/app_restrictions.xml create mode 100644 docs/images/mdm/mdm-app-konfiguration.png create mode 100644 docs/images/mdm/mdm-typ-auswahl.png create mode 100644 host-agent/android/app/src/main/java/de/hackersoft/ariaagent/MdmConfig.kt create mode 100644 host-agent/android/app/src/main/res/values/mdm_strings.xml create mode 100644 host-agent/android/app/src/main/res/xml/app_restrictions.xml diff --git a/README.md b/README.md index 17b0dbc..4fc8f08 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ ARIA hat zwei Rollen: | Compute-Node(s) (STT/TTS/LLM) | 1..n GPU-Rechner | `cd xtts && cp .env.example .env && docker compose up -d` | | Satellit(en) πŸ›°οΈ (optional) | Fremdes Netz (BΓΌro …) | `cd satellite && cp .env.example .env && docker compose up -d --build` | | Host-Agent(en) πŸ’» (optional) | Direkt auf einem Rechner | `cd host-agent && ./build.sh` β†’ Binary + `.env` auf den Rechner, starten (Details unten & in [`host-agent/README.md`](host-agent/README.md)) | -| Android-Agent πŸ“±πŸ“Ί (optional) | Handy, Tablet, Fire TV | `cd host-agent/android && ./build.sh` β†’ APK, oder per Satellit via ADB ausrollen (Details unten) | +| Android-Agent πŸ“±πŸ“Ί (optional) | Handy, Tablet, Fire TV | `cd host-agent/android && ./build.sh` β†’ APK, oder per Satellit via ADB bzw. per MDM ausrollen (Details unten) | | Android App | Stefans Handy | APK installieren (Auto-Update via RVS) | > Compute-Nodes sind optional: ohne sie faellt STT auf lokales Whisper (CPU, @@ -1267,6 +1267,65 @@ vorgeschlagen; nur wenn es keinen gibt, kommt der automatisch generierte. --- +## Ausrollen per MDM πŸ“² β€” Cockpit-App und Android-Agent + +Beide Android-Apps lassen sich ueber ein MDM verteilen. Die Zugangsdaten gibt +das MDM als **App-Konfiguration** (Android β€žManaged Configuration") mit β€” am +Geraet muss niemand einen QR-Code scannen oder etwas eintippen. + +Im MDM pro App den **Paketnamen** eintragen und darunter die Werte als +Schluessel / Typ / Wert: + +![MDM: App-Konfiguration mit Paketname, Schluessel, Typ und Wert](docs/images/mdm/mdm-app-konfiguration.png) + +Der Typ wird pro Zeile aus *Text*, *Zahl* oder *Ja/Nein* gewaehlt: + +![MDM: Auswahl des Typs (Text, Zahl, Ja/Nein)](docs/images/mdm/mdm-typ-auswahl.png) + +### Cockpit-App β€” Paketname `com.ariacockpit` + +| Schluessel | Typ | Wert | Pflicht | +|------------|-----|------|---------| +| `host` | Text | RVS-Hostname, z.B. `aria-rvs.example.de` (= `RVS_HOST`) | ja | +| `token` | Text | Pairing-Token (= `RVS_TOKEN`, derselbe wie im QR-Code) | ja | +| `port` | Zahl | `443` (= `RVS_PORT`) | nein, Standard 443 | +| `tls` | Ja/Nein | Ja (= `RVS_TLS`) | nein, Standard Ja | + +### Android-Agent β€” Paketname `de.hackersoft.ariaagent` + +| Schluessel | Typ | Wert | Pflicht | +|------------|-----|------|---------| +| `host` | Text | RVS-Hostname (= `RVS_HOST`) | ja | +| `token` | Text | Pairing-Token (= `RVS_TOKEN`) | ja | +| `port` | Zahl | `443` | nein, Standard 443 | +| `tls` | Ja/Nein | Ja | nein, Standard Ja | +| `name` | Text | Geraetename, so erscheint er in der Diagnostic | nein, sonst der Modellname | +| `control` | Ja/Nein | Ja = ARIA darf das Geraet steuern (tippen, wischen, Apps starten) | nein, Standard Nein | +| `reply_mode` | Text | `overlay` (Einblendung) oder `speech` (Sprache) | nein, Standard `overlay` | + +### Was dabei passiert + +- **Nur mit `host` UND `token`** uebernimmt die App die Werte. Fehlt einer der + beiden, bleibt alles wie bisher (QR-Code bzw. Eingabe am Geraet). +- **Das MDM hat Vorrang.** Eine Aenderung im MDM (z.B. neuer Token) ueberschreibt + die Werte am Geraet. Beim Agenten bleiben nicht gesetzte Schluessel auf ihrem + bisherigen Wert. +- **Wann gelesen wird:** Cockpit beim App-Start, der Agent beim App-Start und + nach einem Neustart des Geraets. Eine Aenderung im MDM greift also erst danach. +- **Was das MDM nicht erledigen kann:** Beim Agenten muessen die + Bedienungshilfe (fuer `control`), die Einblendung ueber anderen Apps und die + Bildschirm-Aufnahme weiterhin einmal am Geraet erlaubt werden β€” Android laesst + diese Spezialberechtigungen nicht per App-Konfiguration zu. Cockpit fragt + Mikrofon, Benachrichtigungen usw. wie gewohnt beim ersten Start. +- Der **Token ist ein Zugangsschluessel**: Wer ihn kennt, landet im selben + RVS-Room. Im MDM nur fuer Admins sichtbar ablegen. + +Welche Schluessel es gibt, steht in `res/xml/app_restrictions.xml` der +jeweiligen App (`android/android/app/...` bzw. `host-agent/android/app/...`); +ein MDM, das die Liste selbst ausliest, zeigt sie dort auch mit Beschreibung an. + +--- + ## Docker Volumes | Volume / Bind | Pfad im Container | Zweck | diff --git a/android/android/app/src/main/AndroidManifest.xml b/android/android/app/src/main/AndroidManifest.xml index c52bb4f..cea3178 100644 --- a/android/android/app/src/main/AndroidManifest.xml +++ b/android/android/app/src/main/AndroidManifest.xml @@ -38,6 +38,10 @@ android:allowBackup="false" android:networkSecurityConfig="@xml/network_security_config" android:theme="@style/AppTheme"> + + out.putString(key, v) + is Int -> out.putInt(key, v) + is Boolean -> out.putBoolean(key, v) + } + } + promise.resolve(out) + } catch (e: Exception) { + promise.resolve(Arguments.createMap()) + } + } +} + +class MdmConfigPackage : ReactPackage { + override fun createNativeModules(reactContext: ReactApplicationContext): List = + listOf(MdmConfigModule(reactContext)) + + override fun createViewManagers(reactContext: ReactApplicationContext): List> = + emptyList() +} diff --git a/android/android/app/src/main/res/values/mdm_strings.xml b/android/android/app/src/main/res/values/mdm_strings.xml new file mode 100644 index 0000000..f631d50 --- /dev/null +++ b/android/android/app/src/main/res/values/mdm_strings.xml @@ -0,0 +1,10 @@ + + + + RVS-Host + Hostname des RVS, z.B. aria-rvs.example.de + RVS-Port + TLS verwenden + Token + Derselbe Token wie im QR-Code + diff --git a/android/android/app/src/main/res/xml/app_restrictions.xml b/android/android/app/src/main/res/xml/app_restrictions.xml new file mode 100644 index 0000000..56c7e88 --- /dev/null +++ b/android/android/app/src/main/res/xml/app_restrictions.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/android/src/services/rvs.ts b/android/src/services/rvs.ts index 324a730..91a03d7 100644 --- a/android/src/services/rvs.ts +++ b/android/src/services/rvs.ts @@ -491,7 +491,40 @@ class RVSConnection { } } + /** + * Verbindungsdaten aus dem MDM (Managed Configuration), falls beim Ausrollen + * gesetzt. Nur gueltig mit host UND token. Schluessel: res/xml/app_restrictions.xml + */ + async loadMdmConfig(): Promise { + try { + const Mdm: any = NativeModules.MdmConfig; + if (Platform.OS !== 'android' || !Mdm?.getConfig) return null; + const m = await Mdm.getConfig(); + const host = String(m?.host ?? '').trim(); + const token = String(m?.token ?? '').trim(); + if (!host || !token) return null; + const port = Number(m.port); + return { + host, + token, + port: Number.isFinite(port) && port > 0 ? port : 443, + useTLS: m.tls !== false, + }; + } catch { + return null; + } + } + async loadConfig(): Promise { + // Vom MDM gesetzte Werte haben Vorrang: so kommen geaenderte Zugangsdaten + // beim naechsten App-Start an, ohne dass jemand am Geraet etwas tun muss. + const mdm = await this.loadMdmConfig(); + if (mdm) { + console.log('[RVS] Konfiguration aus dem MDM'); + this.config = mdm; + await this.saveConfig(mdm); + return mdm; + } try { const data = await AsyncStorage.getItem(RVSConnection.STORAGE_KEY); if (data) { diff --git a/docs/images/mdm/mdm-app-konfiguration.png b/docs/images/mdm/mdm-app-konfiguration.png new file mode 100644 index 0000000000000000000000000000000000000000..b7000599313665ef3cae477bd24882360122afe5 GIT binary patch literal 19068 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 + + + 0 } ?: 443 else old.port, + tls = if (b.containsKey("tls")) b.getBoolean("tls") else old.tls, + name = b.getString("name")?.trim().takeUnless { it.isNullOrEmpty() } ?: old.name, + controlEnabled = if (b.containsKey("control")) b.getBoolean("control") else old.controlEnabled, + replyMode = b.getString("reply_mode")?.trim() + ?.takeIf { it == "overlay" || it == "speech" } ?: old.replyMode, + ) + if (cfg == old) return null + cfg.save(ctx) + return cfg + } +} diff --git a/host-agent/android/app/src/main/res/values/mdm_strings.xml b/host-agent/android/app/src/main/res/values/mdm_strings.xml new file mode 100644 index 0000000..7443dd1 --- /dev/null +++ b/host-agent/android/app/src/main/res/values/mdm_strings.xml @@ -0,0 +1,15 @@ + + + + RVS-Host + Hostname des RVS, z.B. aria-rvs.example.de + RVS-Port + TLS verwenden + Token + Derselbe Token wie im QR-Code + Geraetename + So erscheint das Geraet in der Diagnostic (leer = Modellname) + Steuern erlauben + Antwort als + overlay (Einblendung) oder speech (Sprache) + diff --git a/host-agent/android/app/src/main/res/xml/app_restrictions.xml b/host-agent/android/app/src/main/res/xml/app_restrictions.xml new file mode 100644 index 0000000..95bd122 --- /dev/null +++ b/host-agent/android/app/src/main/res/xml/app_restrictions.xml @@ -0,0 +1,41 @@ + + + + + + + + + + +