Vier Beweise, die das Projekt tragen, als eigenständig lauffähige Skripte:
S1 Plasma Mobile in proot über genestetes kwin_wayland im X11-Backend.
Fällt selbsttätig auf startplasmamobile und dann auf XFCE zurück, damit
ein Fehlschlag eindeutig Plasma zuzuordnen ist und nicht der Umgebung.
S2 Mikrofon über PulseAudio mit OpenSL-Quelle. Misst den Pegel statt nur die
Dateigröße — der typische Fehlschlag ist eine formal korrekte WAV-Datei
voller Stille.
S3 Virtuelle PipeWire-Kamera per GStreamer-pipewiresink, ohne Kernel-Modul.
Setzt die Firefox-Einstellung vorab, damit der Test nicht an einem
vergessenen Häkchen scheitert.
S4 Intent-Handoff mit lauffähiger Mini-Bridge: xdg-open-Handler für geo:,
tel: und sms:, Token-Authentifizierung, feste Liste erlaubter Schemata.
provision/provision.sh setzt die Hintergrundbeschränkungen per ADB und benennt,
was ADB nicht kann und von Hand erledigt werden muss.
Dokumentiert sind auch die sieben verworfenen Wege — Waydroid, AVF, QEMU, SIP,
APK-Daten-Redirect, Fenster-Durchreichung und der Android-Server — mit Belegen,
damit sie nicht erneut durchdacht werden müssen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
113 lines
5.6 KiB
Markdown
113 lines
5.6 KiB
Markdown
# Machbarkeit ohne Root
|
||
|
||
Was auf ungerootetem Stock-Android geht und was nicht — mit Belegen, damit niemand
|
||
gegen eine Wand plant.
|
||
|
||
Legende: ✅ bewiesen möglich · 🔬 im Spike zu beweisen · ❌ nachweislich unmöglich ·
|
||
➖ bewusst außerhalb des Projekts
|
||
|
||
## Basis
|
||
|
||
| Funktion | | Weg |
|
||
|---|---|---|
|
||
| `$HOME` im echten Telefonspeicher, kein Image | ✅ | proot-distro legt einen normalen Verzeichnisbaum an |
|
||
| Debian + Desktop mit GPU-Beschleunigung | 🔬 | Termux-X11 + Turnip/Zink (Adreno) bzw. virgl/ANGLE (Mali) |
|
||
| Plasma Mobile in proot | 🔬 | **S1** — `kwin_wayland --x11-display` genestet; braucht dort weder DRM noch logind |
|
||
| Backup, Snapshots, Einzeldatei-Restore, Web-UI | ✅ | restic + rclone + eigener Daemon |
|
||
| Klonen auf neues Telefon per WLAN | ✅ | mDNS + restic-REST |
|
||
|
||
## Telefonie und Nachrichten
|
||
|
||
| Funktion | | Weg |
|
||
|---|---|---|
|
||
| SMS empfangen und senden | ✅ | Bridge als Default-SMS-App. Sideloaded → Play-Policy greift nicht |
|
||
| Anrufe steuern: wählen, annehmen, auflegen, DTMF, Anrufliste | ✅ | Bridge als Default-Dialer (`InCallService`) |
|
||
| **Anruf-Audio in die Linux-Umgebung leiten** | ❌ | `VOICE_CALL` erfordert `CAPTURE_AUDIO_OUTPUT` — System-App-Permission, seit Android 6 gesperrt; der Accessibility-Umweg wurde 2022 geschlossen |
|
||
|
||
**Beleg:** [issuetracker 236553834](https://issuetracker.google.com/issues/236553834)
|
||
|
||
Konsequenz: Audio bleibt auf dem Android-Pfad, dieselbe Hörmuschel wie immer. Bedienung
|
||
und alle Daten liegen im Linux. Ein SIP-Aufbau als Umgehung wurde geprüft und verworfen
|
||
(siehe [verworfene-entscheidungen.md](verworfene-entscheidungen.md)).
|
||
|
||
## Medien
|
||
|
||
| Funktion | | Weg |
|
||
|---|---|---|
|
||
| Mikrofon im Linux | 🔬 | **S2** — PulseAudio mit OpenSL-Source in Termux, `PULSE_SERVER` in den proot |
|
||
| Kamera in Browser und Element (Videocall) | 🔬 | **S3** — virtuelle PipeWire-Kamera, reiner Userspace |
|
||
| Kamera als `/dev/videoX` | ❌ | `v4l2loopback` ist ein Kernel-Modul → Root. Kein Userspace-Ersatz |
|
||
|
||
**Beleg für den Kamera-Weg:** [PipeWire is the new v4l2loopback](https://www.ideasonboard.com/news/pipewire-is-the-new-v4l2loopback/) ·
|
||
[PipeWire-Kamera in Firefox](https://jgrulich.cz/2024/01/30/how-to-use-pipewire-camera-in-firefox/)
|
||
|
||
Ein GStreamer-`pipewiresink` mit `media.class=Video/Source` erzeugt einen Kamera-Node
|
||
ohne Kernel-Modul. Firefox ab 122 nimmt ihn über `media.webrtc.camera.allow-pipewire`
|
||
und `xdg-desktop-portal-kde` an.
|
||
|
||
**Mikrofon-Konflikt:** Android vergibt das Mikro exklusiv an die Vordergrund-App.
|
||
Solange Termux-X11 vorn ist, hat der Linux-Stack es. Bei einem Mobilfunk-Anruf hat die
|
||
Telefonie Vorrang. Da es keine nativen Nutzer-Apps im Vordergrund gibt, tritt der
|
||
Konflikt praktisch kaum auf.
|
||
|
||
## Android-Apps auf dem Host
|
||
|
||
| Funktion | | Weg |
|
||
|---|---|---|
|
||
| Host-App aus dem Linux mit Daten aufrufen | 🔬 | **S4** — `xdg-open`-Handler für `geo:`/`tel:`/`sms:` → Bridge → Intent |
|
||
| Installierte Apps sichern und wiederherstellen | ✅ | `QUERY_ALL_PACKAGES` + `ApplicationInfo.sourceDir`; APKs unter `/data/app/…/base.apk` sind weltlesbar |
|
||
| Banking- und TAN-Apps | ✅ | Nativ auf dem Host, Play Integrity ist dort intakt |
|
||
| **App-Daten sichern** | ❌ | Siehe unten — zwei unabhängige K.-o.-Gründe |
|
||
| Host-App als Fenster im Linux-Desktop | ➖ | Technisch möglich, bewusst verworfen |
|
||
|
||
### Warum App-Daten nicht sicherbar sind
|
||
|
||
Zwei Gründe, jeder für sich schon ausreichend:
|
||
|
||
1. **Es gibt kein gemeinsames Verzeichnis.** Seit Android 11 ist `/sdcard/Android/data`
|
||
auch für Inhaber von `MANAGE_EXTERNAL_STORAGE` gesperrt; `/data/data/<pkg>` gehört
|
||
einer fremden UID mit Modus 0700. App und Termux haben keinen Ort, den beide
|
||
beschreiben können.
|
||
**Beleg:** [Storage updates in Android 11](https://developer.android.com/about/versions/11/privacy/storage)
|
||
2. **APK-Patchen skaliert nicht.** Selbst mit einem solchen Verzeichnis müsste man in
|
||
beliebigen, obfuszierten APKs jeden I/O-Pfad umschreiben — `getFilesDir`,
|
||
`SharedPreferences`, `SQLiteOpenHelper`, dazu native Bibliotheken. Bei jedem
|
||
App-Update von vorn.
|
||
|
||
**Konsequenz als Nutzungsregel:** Auf dem Host laufen nur konto-gebundene Apps, bei
|
||
denen "APK zurück plus einmal anmelden" ein vollständiger Restore ist. Alles mit rein
|
||
lokalen Daten bekommt eine Linux-Anwendung — TOTP etwa über KeePassXC statt einer
|
||
Authenticator-App.
|
||
|
||
## Hardware-Zugriff
|
||
|
||
| Funktion | | Weg |
|
||
|---|---|---|
|
||
| Sensoren, Taschenlampe, Akku, GPS, Vibration | ✅ | Termux:API + Bridge |
|
||
| NFC-Tags lesen und schreiben | ✅ | Bridge-APK |
|
||
| Kontaktloses Bezahlen (HCE) | ➖ | Framework-only und Play-Integrity-gebunden. Bleibt Sache des Host-Android via Google Pay |
|
||
|
||
## Hintergrundbetrieb
|
||
|
||
Der Punkt, an dem das Konzept in der Praxis scheitern könnte. Zwei Ebenen:
|
||
|
||
**Android-Standardebene** — vollständig per ADB abschaltbar und neustartfest:
|
||
|
||
```bash
|
||
adb shell dumpsys deviceidle whitelist +com.termux
|
||
adb shell cmd appops set com.termux RUN_IN_BACKGROUND allow
|
||
adb shell cmd appops set com.termux RUN_ANY_IN_BACKGROUND allow
|
||
adb shell am set-standby-bucket com.termux never
|
||
adb shell settings put global adaptive_battery_management_enabled 0
|
||
```
|
||
|
||
Entwickleroptionen helfen hier **nicht** — sie betreffen nur gecachte Prozesse.
|
||
|
||
**Herstellerebene** — nicht per ADB erreichbar, muss manuell erledigt werden. OxygenOS 12
|
||
basiert auf ColorOS, dessen App-Einfrierung liegt unterhalb der Android-Mechanismen:
|
||
Akku-Optimierung für Termux auf "Nicht optimieren", "Sleep Standby Optimization" aus,
|
||
adaptive Akkunutzung aus, App im Task-Manager anpinnen.
|
||
|
||
**Nachweis statt Annahme:** Der Stack muss eine Nacht überleben. Scheitert das, ist es
|
||
ein früher Warnschuss für das Gesamtkonzept, kein Detail.
|