Files
linux-on-android-without-root/provision/provision.sh
T
StefanandClaude Opus 5 ad2c98443b Phase 0: Repo-Gerüst, Dokumentation und Machbarkeits-Spike
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>
2026-08-09 17:25:36 +02:00

156 lines
7.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# HPOS — Ersteinrichtung vom PC aus, per ADB.
#
# ADB wird ausschließlich hier gebraucht, einmalig. Im Dauerbetrieb kommt das
# System mit gewöhnlichen App-Berechtigungen aus — das ist eine harte Regel des
# Projekts, siehe CONTRIBUTING.md.
#
# Voraussetzung: Telefon per USB, Entwickleroptionen und USB-Debugging aktiv,
# der Dialog "Diesem Computer vertrauen" bestätigt.
#
# Aufruf: ./provision/provision.sh [--dry-run]
set -uo pipefail
TERMUX=com.termux
TROCKEN=0
[ "${1:-}" = "--dry-run" ] && TROCKEN=1
if [ -t 1 ]; then
C_OK=$'\033[32m'; C_WARN=$'\033[33m'; C_ERR=$'\033[31m'
C_HEAD=$'\033[1;36m'; C_DIM=$'\033[2m'; C_OFF=$'\033[0m'
else
C_OK=""; C_WARN=""; C_ERR=""; C_HEAD=""; C_DIM=""; C_OFF=""
fi
kopf() { printf '\n%s══ %s ══%s\n' "$C_HEAD" "$*" "$C_OFF"; }
ok() { printf '%s ✓%s %s\n' "$C_OK" "$C_OFF" "$*"; }
warn() { printf '%s !%s %s\n' "$C_WARN" "$C_OFF" "$*"; }
fehl() { printf '%s ✗%s %s\n' "$C_ERR" "$C_OFF" "$*"; }
hinweis() { printf '%s %s%s\n' "$C_DIM" "$*" "$C_OFF"; }
# Führt ein adb-Kommando aus und meldet das Ergebnis, ohne bei Fehlschlag
# abzubrechen: Hersteller-ROMs kennen nicht jedes appops-Ziel, und ein fehlendes
# ist kein Grund, die restliche Einrichtung liegen zu lassen.
adbs() {
local beschreibung="$1"; shift
if [ "$TROCKEN" = 1 ]; then
printf '%s ? %s%s (adb shell %s)\n' "$C_DIM" "$beschreibung" "$C_OFF" "$*"
return 0
fi
local aus
if aus=$(adb shell "$@" 2>&1); then
if printf '%s' "$aus" | grep -qiE 'error|exception|denied|unknown'; then
warn "$beschreibung — ROM hat abgelehnt"
hinweis "$(printf '%s' "$aus" | head -1)"
return 1
fi
ok "$beschreibung"
return 0
fi
warn "$beschreibung — fehlgeschlagen"
hinweis "$(printf '%s' "$aus" | head -1)"
return 1
}
# ── Gerät ────────────────────────────────────────────────────────────────────
kopf "Gerät"
command -v adb >/dev/null 2>&1 || { fehl "adb nicht gefunden. Bitte android-tools-adb installieren."; exit 1; }
ANZAHL=$(adb devices | grep -cw 'device$' || true)
if [ "$ANZAHL" -eq 0 ]; then
fehl "Kein Gerät verbunden oder nicht autorisiert."
hinweis "adb devices prüfen. Steht dort 'unauthorized', den Dialog auf dem Telefon bestätigen."
exit 1
elif [ "$ANZAHL" -gt 1 ]; then
fehl "Mehrere Geräte verbunden — bitte nur eines anschließen."
exit 1
fi
for p in ro.product.manufacturer ro.product.model ro.product.device \
ro.build.version.release ro.board.platform; do
printf ' %-28s %s\n' "$p" "$(adb shell getprop "$p" 2>/dev/null | tr -d '\r')"
done
[ "$TROCKEN" = 1 ] && warn "Trockenlauf — es wird nichts verändert."
# ── Termux vorhanden? ────────────────────────────────────────────────────────
kopf "Termux"
if adb shell pm list packages 2>/dev/null | tr -d '\r' | grep -q "^package:$TERMUX$"; then
ok "$TERMUX ist installiert"
else
fehl "$TERMUX ist nicht installiert."
hinweis "Termux von F-Droid oder GitHub installieren, dann dieses Skript erneut laufen lassen."
hinweis "Nicht aus dem Play Store — die dortige Fassung ist veraltet und unbrauchbar."
exit 1
fi
# ── Hintergrundbetrieb, Android-Standardebene ────────────────────────────────
# Der Punkt, an dem das Konzept in der Praxis scheitern kann. Diese Maßnahmen
# überleben Neustarts. Die Entwickleroptionen helfen hier NICHT — sie betreffen
# nur gecachte Prozesse, nicht Vordergrunddienste.
kopf "Hintergrundbetrieb (Android-Standardebene)"
adbs "Aus der Doze-Beschränkung ausgenommen" dumpsys deviceidle whitelist "+$TERMUX"
adbs "RUN_IN_BACKGROUND erlaubt" cmd appops set "$TERMUX" RUN_IN_BACKGROUND allow
adbs "RUN_ANY_IN_BACKGROUND erlaubt" cmd appops set "$TERMUX" RUN_ANY_IN_BACKGROUND allow
adbs "Standby-Bucket auf 'never' gesetzt" am set-standby-bucket "$TERMUX" never
adbs "Adaptive Akkunutzung abgeschaltet" settings put global adaptive_battery_management_enabled 0
adbs "Akku-Optimierung ignoriert" cmd appops set "$TERMUX" REQUEST_IGNORE_BATTERY_OPTIMIZATIONS allow
# Die Zusatz-APKs, sofern schon installiert. Fehlen sie, ist das hier kein Problem.
for extra in com.termux.api com.termux.x11 com.termux.boot; do
if adb shell pm list packages 2>/dev/null | tr -d '\r' | grep -q "^package:$extra$"; then
adbs " $extra aus der Doze-Beschränkung" dumpsys deviceidle whitelist "+$extra"
adbs " $extra darf im Hintergrund laufen" cmd appops set "$extra" RUN_ANY_IN_BACKGROUND allow
fi
done
# ── Berechtigungen ───────────────────────────────────────────────────────────
kopf "Berechtigungen"
for perm in \
android.permission.RECORD_AUDIO \
android.permission.CAMERA \
android.permission.ACCESS_FINE_LOCATION \
android.permission.READ_EXTERNAL_STORAGE \
android.permission.WRITE_EXTERNAL_STORAGE
do
adbs "$(basename "${perm//./\/}") für Termux:API" pm grant com.termux.api "$perm" 2>/dev/null || true
done
hinweis "Fehlschläge sind normal, solange Termux:API noch nicht installiert ist."
# ── Was ADB nicht kann ───────────────────────────────────────────────────────
kopf "Von Hand zu erledigen"
HERSTELLER=$(adb shell getprop ro.product.manufacturer 2>/dev/null | tr -d '\r')
cat <<TEXT
Die folgenden Punkte liegen unterhalb der Android-Mechanismen und sind per
ADB nicht zuverlässig erreichbar. Ohne sie beendet das ROM den Stack über Nacht.
1. Einstellungen → Apps → Termux → Akku → "Nicht optimieren"
2. Einstellungen → Akku → "Sleep Standby Optimization" ausschalten
3. Einstellungen → Akku → adaptive Akkunutzung ausschalten
4. Termux im Task-Manager anpinnen (Schloss-Symbol)
5. Für Overlay-Begleit-Apps: "Über anderen Apps anzeigen" erlauben
TEXT
case "$HERSTELLER" in
[Oo]ne[Pp]lus|OPPO|oppo|realme)
printf '\n%s Zu deinem Gerät:%s\n' "$C_WARN" "$C_OFF"
hinweis "OxygenOS/ColorOS friert Apps besonders aggressiv ein."
hinweis "Zusätzlich unter Einstellungen → Akku → Akkuoptimierung die"
hinweis "erweiterte bzw. 'intelligente' Optimierung für Termux abschalten."
;;
[Xx]iaomi|[Rr]edmi|[Pp]oco|samsung|Samsung)
printf '\n%s Zu deinem Gerät:%s\n' "$C_WARN" "$C_OFF"
hinweis "Dieser Hersteller ist für aggressives Beenden bekannt."
hinweis "Zusätzlich Autostart erlauben und die App von der Speicherbereinigung ausnehmen."
;;
esac
kopf "Fertig"
cat <<TEXT
Nächster Schritt auf dem Telefon, in Termux:
pkg install -y git
git clone <repo-url> hpos && cd hpos
bash spike/00-bootstrap-termux.sh
Danach die Beweise der Reihe nach — S1 zuerst, weil er der wackligste ist.
Ergebnisse gehören nach docs/spike-protokoll.md.
TEXT