testsAndMisc/python_pkg/phone_lease/owner.py
Krzysztof kuhy Rudnicki c0c51036fc phone_lease: per-app leases, a self-cleaning whole-phone lease, one serial
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
2026-09-25 15:05:57 +02:00

37 lines
1.3 KiB
Python

"""Which Claude session is calling: the identity every lease is held under."""
from __future__ import annotations
import os
from pathlib import Path
# Set this to name the owner explicitly (CI, a script without a claude parent).
OWNER_ENV = "PHONE_LEASE_OWNER"
def owner_id(pid: int | None = None, environ: dict[str, str] | None = None) -> str:
"""Identify the calling session.
``PHONE_LEASE_OWNER`` wins. Otherwise walk up from ``pid`` (this process
by default) to the nearest ancestor whose ``comm`` is ``claude`` -- one
per session -- and fall back to this process's own pid when there is none.
"""
env = os.environ if environ is None else environ
explicit = env.get(OWNER_ENV)
if explicit:
return explicit
current = os.getpid() if pid is None else pid
origin = current
while current > 1:
try:
comm = Path(f"/proc/{current}/comm").read_text(encoding="utf-8").strip()
stat = Path(f"/proc/{current}/stat").read_text(encoding="utf-8")
except OSError:
break
if comm == "claude":
return f"claude:{current}"
# Field 4 of /proc/<pid>/stat is the parent pid; the comm field before
# it may contain spaces, so split after its closing paren.
current = int(stat.rsplit(")", 1)[1].split()[1])
return f"pid:{origin}"