Files
StarPilot/openpilot/starpilot/audio/default_enrollment.py
T
firestar5683 fd4ca85d61 Audio
Provide alert playback and volume control with a native audio callback that does not depend on the Python GIL.

Co-authored-by: Daniel Koepping <elkoled@gmail.com>
2026-10-14 20:02:39 -05:00

80 lines
3.3 KiB
Python

"""Enroll a settings namespace in the built-in sounds once, before consumers start."""
from pathlib import Path
import json
import os
import tempfile
from openpilot.starpilot.state_migration import (
_atomic_write, _fsync_dir, _outside_params, _params_lock, _private_dir, _read_value, canonical_json, digest,
)
def _write_selection(namespace):
fd, temporary = tempfile.mkstemp(prefix=".sound-default-", dir=namespace.parent)
try:
with os.fdopen(fd, "wb") as output:
output.write(b"starpilot")
output.flush()
os.fsync(output.fileno())
os.replace(temporary, namespace / "SoundPack")
_fsync_dir(namespace)
finally:
Path(temporary).unlink(missing_ok=True)
def enroll_default_sounds(params, storage) -> bool:
namespace, storage = Path(params.get_param_path()).absolute(), Path(storage).absolute()
_outside_params(namespace, storage)
with _params_lock(namespace):
identity = {"version": 1, "namespace": str(namespace), "target": str(namespace.resolve(strict=True))}
marker_dir = storage / "sound-default-once"
new_directory = not marker_dir.exists()
_private_dir(marker_dir)
if new_directory:
_fsync_dir(storage)
marker = marker_dir / f"{digest(str(namespace).encode())}.json"
complete = {**identity, "state": "complete"}
try:
encoded = _read_value(marker)
except FileNotFoundError:
encoded = None
previous = json.loads(encoded) if encoded is not None else None
if previous is not None:
if not isinstance(previous, dict) or type(previous.get("version")) is not int or previous["version"] != 1 or encoded != canonical_json(previous):
raise ValueError("Invalid sound enrollment marker")
if previous == complete:
return False
state = previous.get("state")
required = {*identity, "state"} | ({"before_sha256"} if state == "pending" else set())
if state not in ("pending", "complete") or set(previous) != required:
raise ValueError("Invalid sound enrollment marker")
if previous["namespace"] != identity["namespace"] or not isinstance(previous["target"], str) or not Path(previous["target"]).is_absolute():
raise ValueError("Invalid sound enrollment identity")
before = previous.get("before_sha256")
if before is not None and (not isinstance(before, str) or len(before) != 64 or any(c not in "0123456789abcdef" for c in before)):
raise ValueError("Invalid sound enrollment source")
if any(previous[key] != value for key, value in identity.items()):
previous = None
selection = namespace / "SoundPack"
try:
raw = _read_value(selection)
except FileNotFoundError:
raw = None
current = digest(raw) if raw is not None else None
if previous is None:
previous = {**identity, "state": "pending", "before_sha256": current}
_atomic_write(marker, canonical_json(previous))
elif current != previous["before_sha256"] and raw != b"starpilot":
# A later choice takes precedence over an interrupted startup enrollment.
_atomic_write(marker, canonical_json(complete))
return False
if raw != b"starpilot":
_write_selection(namespace)
if _read_value(selection) != b"starpilot":
raise ValueError("Sound enrollment could not verify its selection")
_atomic_write(marker, canonical_json(complete))
return True