Files
StarPilot/openpilot/starpilot/galaxy/pairing_ready.py
T
Danny a531afd02a Bluetooth: Coordinate companion pairing and Android Auto ownership
Expose pairing readiness and coordinate adapter hand-offs with Android Auto.
Show app pairings separately, support individual removal, and improve pairing
controls on both comma screens. Add Galaxy companion endpoints and web asset
manifests, preserve the plain camera look, and fix headless speed-limit shapes.
2026-10-22 15:37:20 -07:00

52 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Whether comma can take a phone's Bluetooth pairing right now, so companion apps wait instead of failing."""
from collections.abc import Callable
# Short-lived states a phone may wait out; the others need someone to do something on comma.
TRANSIENT = frozenset(('starting', 'bridge_starting'))
BOOT_GRACE_SECONDS = 45.0
def system_uptime() -> float:
try:
with open('/proc/uptime') as stream:
return float(stream.read().split()[0])
except (OSError, ValueError, IndexError):
return BOOT_GRACE_SECONDS # no grace where the uptime cannot be read (not a comma)
def bridge_state() -> tuple[str, str]:
"""The phone bridge's (state, message); 'pending' whenever it cannot be read."""
try:
from openpilot.starpilot.galaxy_bluetooth.bootstrap import setup_state
return setup_state()
except Exception:
return 'pending', 'Bridge startup pending'
def pairing_readiness(*, parked: Callable[[], bool], snapshot: Callable[[], dict],
bridge: Callable[[], tuple[str, str]], uptime: Callable[[], float] = system_uptime) -> dict:
"""{'ready': bool, 'code': str, 'message': str}; checked in the order a person would fix them."""
def answer(ready: bool, code: str, message: str) -> dict:
return {'schema': 1, 'ready': ready, 'code': code, 'message': message}
if uptime() < BOOT_GRACE_SECONDS:
return answer(False, 'starting', 'Comma just started and Bluetooth is still getting ready.')
try:
is_parked = parked()
state = snapshot() if is_parked else {}
except Exception: # a readiness question must always get an answer, never an error
return answer(False, 'bluetooth_unavailable', 'Comma’s Bluetooth service is not responding.')
if not is_parked:
return answer(False, 'park_required', 'Park the car or turn it off to pair a phone.')
if state.get('errorCode') or not state.get('available', True):
return answer(False, 'bluetooth_unavailable', 'Comma’s Bluetooth adapter is not available.')
if not state.get('powered'):
return answer(False, 'bluetooth_off', 'Bluetooth is off on comma. Turn it on in Settings > Bluetooth.')
try:
bridge_state, bridge_message = bridge()
except Exception:
bridge_state, bridge_message = 'pending', ''
if bridge_state != 'ready':
return answer(False, 'bridge_starting', bridge_message or 'The phone Bluetooth bridge is starting.')
return answer(True, 'ready', 'Ready to pair.')