#!/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 < 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