mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 21:07:03 +01:00
Several sessions can now share one phone: a lease covers one package (the real screen stays the default scope, so existing callers keep their meaning), and only phone-wide actions take `--whole-phone`, which is capped at 300 s and runs its `--cleanup` commands exactly once on release or, via a detached reaper, on expiry. The serial is always resolved, never the "default" placeholder that let android_ui and phone_deploy lease different keys for the same phone (2026-09-25). Adds status --json, holds and whoami for phone_vd.sh and the raw-adb hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012Ajzz98xksbfak8CaunZWC
70 lines
2.0 KiB
Python
70 lines
2.0 KiB
Python
"""Run a whole-phone lease's cleanup commands, even if nobody releases it.
|
|
|
|
A forced Doze left behind by a crashed session breaks every other session's
|
|
network and alarms until someone notices, so cleanup cannot depend on the
|
|
holder remembering: a detached reaper watches each lease that has cleanup
|
|
commands and runs them the moment it expires.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import shlex
|
|
import subprocess
|
|
import sys
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Iterable
|
|
|
|
# One cleanup command may not hang the reaper or a caller's release.
|
|
CLEANUP_TIMEOUT = 30.0
|
|
# The repo root, so the detached reaper can import python_pkg from anywhere.
|
|
_REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def run(commands: Iterable[str]) -> list[int]:
|
|
"""Run each command (no shell), returning exit codes; never raises.
|
|
|
|
A failing or missing command is reported as a non-zero code rather than
|
|
raised, because the remaining cleanup steps must still run.
|
|
"""
|
|
codes: list[int] = []
|
|
for command in commands:
|
|
try:
|
|
done = subprocess.run(
|
|
shlex.split(command),
|
|
check=False,
|
|
timeout=CLEANUP_TIMEOUT,
|
|
capture_output=True,
|
|
)
|
|
except OSError, ValueError, subprocess.TimeoutExpired:
|
|
codes.append(127)
|
|
continue
|
|
codes.append(done.returncode)
|
|
return codes
|
|
|
|
|
|
def spawn_reaper(serial: str, owner: str, scope: str) -> None:
|
|
"""Start a detached ``phone_lease reap`` for one freshly taken lease."""
|
|
env = {**os.environ, "PYTHONPATH": str(_REPO_ROOT)}
|
|
subprocess.Popen(
|
|
[
|
|
sys.executable,
|
|
"-m",
|
|
"python_pkg.phone_lease",
|
|
"reap",
|
|
serial,
|
|
"--owner",
|
|
owner,
|
|
"--scope",
|
|
scope,
|
|
],
|
|
env=env,
|
|
start_new_session=True,
|
|
stdin=subprocess.DEVNULL,
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL,
|
|
)
|