From 8301342728c9581719e3d98acdffb03127de73f6 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Wed, 30 Sep 2026 01:34:18 +0200 Subject: [PATCH] feat(satellite): ADB-Rollout wartet auf die Geraete-Bestaetigung (ein Klick genuegt) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bisher: 1. Klick -> 'unauthorized' (Fehler), am Fire TV bestaetigen, 2. Klick -> klappt. Jetzt wartet der Satellit nach dem ersten connect bis zu ADB_AUTH_WAIT_SEC (90s) auf die Autorisierung und installiert danach automatisch weiter — der Dialog auf dem Fernseher erscheint ja erst DURCH das connect. - _adb_wait_authorized(): pollt adb devices alle 2s und verbindet neu (nach dem Bestaetigen wechselt der Zustand oft erst mit frischem connect auf 'device'). - adb.install/adb.connect nutzen es; scheitert es doch, nennt die Meldung Wartezeit und Zustand statt nur 'unauthorized'. - Brain-Timeout fuer adb.* auf 320s (Warten + Download + Installation). - Diagnostic: Hinweis erscheint SOFORT beim Klick ('Jetzt auf den Bildschirm des Geraets schauen'), nicht erst als Fehler hinterher. Co-Authored-By: Claude Opus 4.8 --- aria-brain/agent.py | 6 ++-- diagnostic/index.html | 15 ++++++++-- satellite/satellite.py | 62 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 70 insertions(+), 13 deletions(-) diff --git a/aria-brain/agent.py b/aria-brain/agent.py index f0408df..8c1234f 100644 --- a/aria-brain/agent.py +++ b/aria-brain/agent.py @@ -2670,8 +2670,10 @@ class Agent: # Langlaeufer brauchen mehr als den Bridge-Default (20s): eine APK ueber # WLAN zu installieren dauert 30-60s. Ohne das meldet ARIA "Timeout", # obwohl die Installation noch laeuft. - slow = action.startswith("adb.") or action == "ssh.exec" - sat_timeout = 200.0 if slow else 20.0 + # adb.*: Warten auf die Geraete-Autorisierung (bis 90s) + Download + + # Installation koennen zusammen mehrere Minuten dauern. + sat_timeout = (320.0 if action.startswith("adb.") + else 200.0 if action == "ssh.exec" else 20.0) result = _post("/internal/satellite", { "op": "command", "satellite": sat, "device": arguments.get("device") or "", "action": action, "params": params, diff --git a/diagnostic/index.html b/diagnostic/index.html index af40640..58fdecc 100644 --- a/diagnostic/index.html +++ b/diagnostic/index.html @@ -1605,8 +1605,9 @@
Installiert die Agent-App per ADB über das Netzwerk. Voraussetzung am Gerät: ADB-Debugging aktiv (Fire TV: Einstellungen › Mein Fire TV › - Entwickleroptionen) — beim ersten Mal erscheint dort ein Dialog - „USB-Debugging zulassen?", den Du bestätigen musst. + Entwickleroptionen). Beim ersten Mal erscheint dort + „USB-Debugging zulassen?" — einfach bestätigen, während der Rollout läuft: + er wartet darauf und macht dann automatisch weiter.
läuft …'; + const log = document.getElementById('apk-log'); + log.style.display = 'block'; + log.innerHTML = '👀 Jetzt auf den Bildschirm des Geräts schauen.\n' + + 'Beim ersten Mal erscheint dort „USB-Debugging zulassen?" — bestätigen\n' + + '(Haken bei „Immer erlauben"). Ich warte bis zu 90 Sekunden darauf und\n' + + 'installiere dann automatisch weiter. Kein zweiter Klick nötig.\n\n' + + 'Danach: APK laden + installieren, zusammen 1–3 Minuten.'; send({ action: 'sat_command', satellite: apkTarget.satId, cmd: 'adb.install', requestId: apkRequestId, params: { ip: apkTarget.ip, url } }); } diff --git a/satellite/satellite.py b/satellite/satellite.py index b0b89ba..80338d9 100644 --- a/satellite/satellite.py +++ b/satellite/satellite.py @@ -145,6 +145,10 @@ CONTROL_ALLOWLIST = [ # Download brauchen. ADB_PORT = int(os.environ.get("ADB_PORT", "5555") or "5555") ADB_TIMEOUT_SEC = float(os.environ.get("ADB_TIMEOUT_SEC", "180") or "180") +# Beim ERSTEN Verbinden zeigt das Geraet "USB-Debugging zulassen?" auf dem +# Bildschirm. Statt mit Fehler abzubrechen (und den Nutzer nochmal klicken zu +# lassen) wartet der Satellit so lange auf die Bestaetigung. +ADB_AUTH_WAIT_SEC = float(os.environ.get("ADB_AUTH_WAIT_SEC", "90") or "90") APK_CACHE_DIR = os.environ.get("APK_CACHE_DIR", "/data/apk") APK_MAX_BYTES = int(os.environ.get("APK_MAX_BYTES", str(64 * 1024 * 1024)) or str(64 * 1024 * 1024)) @@ -1121,6 +1125,28 @@ def _adb_state(target: str) -> str: return "" +def _adb_wait_authorized(target: str, seconds: float) -> tuple: + """Wartet, bis das Geraet autorisiert ist ('device'). + + Beim ersten Kontakt erscheint auf dem Fernseher/Handy der Dialog + "USB-Debugging zulassen?". Frueher brach die Installation hier ab und man + musste nach dem Bestaetigen ein zweites Mal starten — jetzt wartet der + Satellit einfach, bis der Nutzer bestaetigt hat. Gibt (ok, zustand). + """ + import time as _time + deadline = _time.time() + max(0.0, seconds) + last = _adb_state(target) + while _time.time() < deadline: + if last == "device": + return True, last + _time.sleep(2.0) + # Erneut verbinden: nach dem Bestaetigen wechselt der Zustand oft erst + # mit einem frischen connect von 'unauthorized'/'offline' auf 'device'. + _adb_run(["connect", target], timeout=15) + last = _adb_state(target) + return last == "device", last + + def _do_adb_devices(params: dict) -> dict: """Listet die dem Satelliten bekannten ADB-Geraete.""" rc, out, err = _adb_run(["devices", "-l"], timeout=20) @@ -1140,10 +1166,19 @@ def _do_adb_connect(params: dict) -> dict: if not target: return {"ok": False, "error": "ip/host erforderlich."} ok, msg = _adb_connect(target) - if not ok: + state = _adb_state(target) + wait = float(params.get("auth_wait") or ADB_AUTH_WAIT_SEC) + if (not ok or state != "device") and wait > 0: + authed, state = _adb_wait_authorized(target, wait) + if not authed: + return {"ok": False, "error": + "Nicht autorisiert — auf dem Bildschirm des Geraets " + "'USB-Debugging zulassen?' bestaetigen. " + f"(gewartet: {wait:.0f}s, Zustand: '{state or '?'}')"} + msg = f"verbunden (nach Bestaetigung am Geraet)" + elif not ok: return {"ok": False, "error": msg} - return {"ok": True, "result": {"target": target, "state": _adb_state(target), - "message": msg}} + return {"ok": True, "result": {"target": target, "state": state, "message": msg}} def _do_adb_shell(params: dict) -> dict: @@ -1241,12 +1276,23 @@ def _do_adb_install(params: dict) -> dict: return {"ok": False, "error": err} ok, msg = _adb_connect(target) - if not ok: - return {"ok": False, "error": msg} state = _adb_state(target) - if state and state != "device": - return {"ok": False, "error": f"Geraet im Zustand '{state}' — " - "bei 'unauthorized' den Dialog auf dem Bildschirm bestaetigen."} + # Erstkontakt: Das Geraet zeigt jetzt "USB-Debugging zulassen?" auf dem + # Bildschirm. Statt abzubrechen warten wir auf die Bestaetigung — ein Klick + # im Diagnostic genuegt, kein zweiter Anlauf noetig. + wait = float(params.get("auth_wait") or ADB_AUTH_WAIT_SEC) + if (not ok or state != "device") and wait > 0: + logger.info("[adb] %s: warte bis zu %.0fs auf Autorisierung (Zustand '%s')", + target, wait, state or "?") + authed, state = _adb_wait_authorized(target, wait) + if not authed: + hint = ("Das Geraet hat die Verbindung nicht autorisiert. Auf dem " + "Bildschirm erscheint 'USB-Debugging zulassen?' — bitte " + "bestaetigen (Haken bei 'Immer erlauben'). " + f"Ich habe {wait:.0f}s gewartet, Zustand: '{state or 'nicht erreichbar'}'.") + return {"ok": False, "error": hint if (state or ok) else msg} + elif not ok: + return {"ok": False, "error": msg} args = ["-s", target, "install", "-r"] # -r = Update statt Neuinstallation if params.get("downgrade"):