mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
fd4ca85d61
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>
80 lines
3.3 KiB
Python
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
|