mDNS ist bequem, scheitert aber in Netzen, die Multicast filtern — das ist keine Seltenheit und kein Fehler des Nutzers. Bisher musste man erst eine Wartezeit absitzen, bevor die manuelle Eingabe angeboten wurde. Jetzt steht sie gleichberechtigt daneben: einmal gefragt, für beide Schritte gemerkt, per HPOS_ADB_MANUELL=1 auch vorab setzbar. Aus der manuellen Eingabe kommt man mit 'm' jederzeit zurück zur Suche, und eine Adresse ohne Port wird abgewiesen statt in ein stilles adb-connect auf Port 5555 zu laufen. Statt nach einer bestehenden Kopplung zu raten, wird sie schlicht erfragt — das erspart bei jedem Aufruf eine vergebliche mDNS-Suche. Fehlt Termux, nennt provision.sh jetzt die Bezugsquellen für alle vier Apps und bietet an, die Seite direkt auf dem Telefon zu öffnen. Mit dem Hinweis, warum der Play Store nicht taugt und warum alle Teile aus derselben Quelle stammen müssen: sonst passen die Signaturen nicht und die Zusatz-Apps verweigern den Dienst. Dazu ein Terminal-Test am Anfang. Die Skripte lesen aus /dev/tty, damit Pipes die Antworten nicht wegfressen — ohne Terminal gab das eine Kette unverständlicher Fehler statt einer klaren Ansage. Die Umleitung 2>/dev/null muss dabei VOR dem Schreibversuch stehen, sonst landet der Fehler trotzdem auf dem Bildschirm. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
276 lines
12 KiB
Bash
Executable File
276 lines
12 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: Entwickleroptionen aktiv. Die Verbindung geht per USB-Kabel ODER
|
|
# per WLAN (Android 11 und neuer) — das Skript fragt danach, wenn kein Gerät da ist.
|
|
#
|
|
# Aufruf: ./provision/provision.sh [--dry-run]
|
|
set -uo pipefail
|
|
|
|
TERMUX=com.termux
|
|
TROCKEN=0
|
|
[ "${1:-}" = "--dry-run" ] && TROCKEN=1
|
|
|
|
source "$(dirname "$0")/lib.sh"
|
|
|
|
# Wählt eine adb-Fassung aus, statt sich auf die Reihenfolge in PATH zu verlassen:
|
|
# Debians Paket ist Version 29 und kennt kein 'adb pair'. Rückgabewert 2 heißt
|
|
# "gefunden, aber zu alt für WLAN" — für USB reicht es trotzdem.
|
|
ADB_KANN_WLAN=1
|
|
adb_einrichten || ADB_KANN_WLAN=0
|
|
|
|
# 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"
|
|
hinweis "adb $(adb_version "$ADB_BIN") — $ADB_BIN"
|
|
|
|
HIER="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
ANZAHL=$(adb devices | grep -cw 'device$' || true)
|
|
|
|
# Ohne Gerät nicht einfach abbrechen: der häufigste Fall ist, dass gar kein Kabel
|
|
# zur Hand ist. Android 11+ kann Wireless Debugging, das reicht für alles hier.
|
|
if [ "$ANZAHL" -eq 0 ]; then
|
|
warn "Kein Gerät verbunden."
|
|
if [ ! -t 0 ]; then
|
|
hinweis "Keine Eingabe möglich — bitte erst ./provision/adb-wireless.sh ausführen."
|
|
exit 1
|
|
fi
|
|
cat <<'TEXT'
|
|
|
|
Wie soll verbunden werden?
|
|
|
|
[u] USB-Kabel
|
|
Entwickleroptionen und USB-Debugging aktiv, Dialog "Diesem Computer
|
|
vertrauen" auf dem Telefon bestätigt.
|
|
|
|
[w] WLAN, ohne Kabel (Android 11 und neuer)
|
|
Einmalige Kopplung per sechsstelligem Code. Danach läuft alles
|
|
über das Netz — ein Kabel wird nie gebraucht.
|
|
|
|
[a] Abbrechen
|
|
TEXT
|
|
[ "$ADB_KANN_WLAN" = 0 ] && warn "Achtung: das gefundene adb kann kein WLAN — [w] wird scheitern."
|
|
printf '\n Auswahl > '
|
|
read -r WAHL </dev/tty
|
|
case "$WAHL" in
|
|
w|W)
|
|
if [ ! -x "$HIER/adb-wireless.sh" ]; then
|
|
fehl "adb-wireless.sh nicht gefunden neben diesem Skript."
|
|
exit 1
|
|
fi
|
|
"$HIER/adb-wireless.sh" || exit 1
|
|
ANZAHL=$(adb devices | grep -cw 'device$' || true)
|
|
;;
|
|
u|U)
|
|
printf ' Kabel anschließen und Enter drücken > '
|
|
read -r _ </dev/tty
|
|
adb wait-for-device &
|
|
WARTE=$!
|
|
# Nicht ewig hängen bleiben, falls das Kabel nur lädt und keine Daten überträgt.
|
|
( sleep 60; kill "$WARTE" 2>/dev/null ) >/dev/null 2>&1 &
|
|
wait "$WARTE" 2>/dev/null
|
|
ANZAHL=$(adb devices | grep -cw 'device$' || true)
|
|
;;
|
|
*)
|
|
hinweis "Abgebrochen."
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
if [ "$ANZAHL" -eq 0 ]; then
|
|
fehl "Es ist weiterhin kein Gerät verbunden."
|
|
adb devices | sed 's/^/ /'
|
|
hinweis "Steht dort 'unauthorized', den Dialog auf dem Telefon bestätigen."
|
|
exit 1
|
|
fi
|
|
ok "Gerät verbunden"
|
|
elif [ "$ANZAHL" -gt 1 ]; then
|
|
fehl "Mehrere Geräte verbunden — bitte nur eines aktiv lassen."
|
|
adb devices | sed 's/^/ /'
|
|
hinweis "Überzählige trennen, per WLAN verbundene mit: adb disconnect <ip:port>"
|
|
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."
|
|
cat <<'TEXT'
|
|
|
|
Termux muss zuerst aufs Telefon. WICHTIG: nicht aus dem Play Store — die
|
|
Fassung dort ist seit Jahren nicht mehr gepflegt und für dieses Projekt
|
|
unbrauchbar. Alle Bestandteile müssen aus derselben Quelle stammen, sonst
|
|
passen die Signaturen nicht zusammen und die Zusatz-Apps verweigern den Dienst.
|
|
|
|
Empfohlen — F-Droid:
|
|
Termux https://f-droid.org/packages/com.termux/
|
|
Termux:API https://f-droid.org/packages/com.termux.api/
|
|
Termux:Boot https://f-droid.org/packages/com.termux.boot/
|
|
|
|
Oder direkt von GitHub:
|
|
Termux https://github.com/termux/termux-app/releases/latest
|
|
Termux:API https://github.com/termux/termux-api/releases/latest
|
|
Termux:Boot https://github.com/termux/termux-boot/releases/latest
|
|
|
|
Termux:X11 gibt es nur bei GitHub (Nightly, app-universal-debug.apk):
|
|
https://github.com/termux/termux-x11/releases
|
|
|
|
Auf dem Telefon einfach im Browser öffnen und die APK installieren.
|
|
"Installation aus unbekannten Quellen" muss für den Browser erlaubt sein.
|
|
TEXT
|
|
if [ "$TROCKEN" != 1 ]; then
|
|
printf '\n Soll ich die Termux-Seite auf dem Telefon öffnen? [J/n] > '
|
|
read -r OEFFNEN </dev/tty || OEFFNEN=n
|
|
case "${OEFFNEN:-j}" in
|
|
j|J|"")
|
|
adb shell am start -a android.intent.action.VIEW \
|
|
-d 'https://f-droid.org/packages/com.termux/' >/dev/null 2>&1 \
|
|
&& ok "Seite auf dem Telefon geöffnet" \
|
|
|| warn "Konnte den Browser nicht starten — bitte von Hand aufrufen."
|
|
;;
|
|
esac
|
|
fi
|
|
printf '\n'
|
|
hinweis "Danach dieses Skript erneut aufrufen."
|
|
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
|
|
|
|
# ── Repo aufs Telefon ────────────────────────────────────────────────────────
|
|
# adb push funktioniert auch über WLAN. Das erspart es, auf dem Telefon Zugangsdaten
|
|
# für ein privates Repo eintippen zu müssen — auf einer Bildschirmtastatur eine Qual.
|
|
kopf "Skripte aufs Telefon"
|
|
REPO_ROOT="$(cd "$HIER/.." && pwd)"
|
|
ZIEL=/sdcard/hpos
|
|
if [ "$TROCKEN" = 1 ]; then
|
|
warn "Trockenlauf — es wird nichts übertragen."
|
|
else
|
|
printf ' Die Spike-Skripte jetzt nach %s übertragen? [J/n] > ' "$ZIEL"
|
|
read -r UEBERTRAGEN </dev/tty || UEBERTRAGEN=n
|
|
case "${UEBERTRAGEN:-j}" in
|
|
j|J|"")
|
|
adb shell rm -rf "$ZIEL" >/dev/null 2>&1
|
|
if adb push "$REPO_ROOT" "$ZIEL" >/dev/null 2>&1; then
|
|
ok "Übertragen nach $ZIEL"
|
|
hinweis "In Termux nach ~ kopieren, damit die Dateien ausführbar sein können:"
|
|
hinweis " cp -r /sdcard/hpos ~/hpos && cd ~/hpos"
|
|
hinweis "(auf /sdcard gibt es keine Ausführungsrechte — das ist normal)"
|
|
else
|
|
warn "Übertragung fehlgeschlagen — dann per git clone auf dem Telefon."
|
|
fi
|
|
;;
|
|
*) hinweis "Übersprungen." ;;
|
|
esac
|
|
fi
|
|
|
|
kopf "Fertig"
|
|
cat <<TEXT
|
|
Nächste Schritte auf dem Telefon, in Termux:
|
|
|
|
cp -r /sdcard/hpos ~/hpos && cd ~/hpos # falls oben übertragen
|
|
# oder: 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.
|
|
|
|
Nicht vergessen: die oben genannten Handgriffe von Hand erledigen.
|
|
Ohne sie beendet das ROM den Stack über Nacht.
|
|
TEXT
|