#!/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 ' read -r _ /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" fi # Mehrere Geräte sind kein Fehler, sondern der Normalfall beim Gerätewechsel: # altes und neues Telefon müssen gleichzeitig erreichbar sein. Statt abzubrechen # wird gefragt — und die Auswahl gilt danach für ALLE folgenden Befehle, weil die # adb-Hülle in lib.sh selbsttätig -s ergänzt. if ! geraet_waehlen; then fehl "Es ist kein Gerät verbunden." 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 hinweis "Ziel: ${ADB_SERIAL:-(einziges Gerät)}" [ "$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 ] && [ -x "$HIER/install-termux.sh" ]; then cat <<'TEXT' Das muss aber niemand von Hand machen: install-termux.sh lädt alle vier Apps von GitHub und installiert sie über die bestehende adb-Verbindung — per WLAN genauso wie per Kabel. TEXT printf '\n Jetzt automatisch installieren? [J/n] > ' read -r AUTOINSTALL ' read -r _ /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" # Termux selbst braucht RECORD_AUDIO und Speicherzugriff — nicht nur Termux:API. # PulseAudio läuft IM Termux-Prozess und öffnet das Mikrofon über OpenSL ES von # dort aus. Eine Berechtigung, die nur Termux:API hat, nützt ihm nichts: das # Modul lädt dann zwar, liefert aber keinen brauchbaren Ton. for perm in \ android.permission.RECORD_AUDIO \ android.permission.READ_EXTERNAL_STORAGE \ android.permission.WRITE_EXTERNAL_STORAGE do adbs "${perm##*.} für Termux" pm grant "$TERMUX" "$perm" 2>/dev/null || true done # Termux:API bedient Kamera, Sensoren, Standort und Taschenlampe. 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 "${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." hinweis "Eine App, die eine Berechtigung gar nicht anmeldet, lässt sich nicht beschenken." # ── Was ADB nicht kann ─────────────────────────────────────────────────────── kopf "Von Hand zu erledigen" HERSTELLER=$(adb shell getprop ro.product.manufacturer 2>/dev/null | tr -d '\r') cat </dev/null || true)" ZIEL=/sdcard/hpos-init.sh if [ -z "$REPO_URL" ]; then warn "Keine Repo-Adresse gefunden (kein origin-Remote gesetzt)." hinweis "Ohne sie kann das Telefon die Quellen nicht holen." printf ' Adresse von Hand eingeben (leer = überspringen) > ' read -r REPO_URL ' "$ZIEL" read -r UEBERTRAGEN "$TMP" if adb push "$TMP" "$ZIEL" >/dev/null 2>&1; then ok "Übertragen nach $ZIEL" else warn "Übertragung fehlgeschlagen." fi rm -f "$TMP" ;; *) hinweis "Übersprungen." ;; esac fi # ── Entwicklerzugang ───────────────────────────────────────────────────────── # Öffentlichen Schlüssel gleich mitschicken, damit später kein Passwort auf der # Bildschirmtastatur eingetippt werden muss. if [ "$TROCKEN" != 1 ]; then PUBKEY="" for k in ~/.ssh/id_ed25519.pub ~/.ssh/id_rsa.pub; do [ -r "$k" ] && { PUBKEY="$k"; break; } done if [ -n "$PUBKEY" ]; then kopf "Entwicklerzugang" hinweis "Für SSH nach Termux — echte Tastatur statt Bildschirmtastatur." printf ' Öffentlichen Schlüssel (%s) aufs Telefon legen? [J/n] > ' "$(basename "$PUBKEY")" read -r SCHLUESSEL /dev/null 2>&1; then ok "Schlüssel abgelegt unter /sdcard/hpos-id.pub" hinweis "Auf dem Telefon einrichten: bash ~/hpos/tools/dev-ssh.sh" else warn "Übertragung fehlgeschlagen" fi ;; esac fi fi kopf "Fertig" cat <