AAwireless: Stop tearing the Session down every 60s

This commit is contained in:
Danny
2026-11-02 17:33:41 -08:00
parent fb9b3516b1
commit 5be95f48df
4 changed files with 18 additions and 7 deletions
@@ -42,12 +42,12 @@ class AutoConnectPolicy:
def start_refused(self, now: float) -> None:
self._not_before = now + START_REFUSED_WAIT
def decide(self, now: float, *, enabled: bool, onroad: bool, car_link: bool, ready: bool, running: bool) -> str | None:
def decide(self, now: float, *, enabled: bool, onroad: bool, car_link: bool, ready: bool, running: bool, linked: bool = False) -> str | None:
"""Return "start", "stop" or None."""
if onroad and not self._was_onroad:
self.suppressed = False # a new drive
self._was_onroad = onroad
present = onroad or car_link
present = onroad or car_link or (running and linked)
if running:
if present:
@@ -2,13 +2,13 @@
import re
DEFAULTS = {"connect_delay_s": 0.0, "max_window": 2, "phone_services": False, "phone_frames": False,
"bootstrap_experiments": False}
"bootstrap_experiments": False, "stay_while_projecting": False}
FINGERPRINT_KEYS = ("head_unit_make", "head_unit_model", "car_make", "car_model", "car_year")
RULES: list[dict] = [
{"id": "aawireless", "label": "AAWireless", "match": {},
"tuning": {"max_window": 30, "phone_services": True, "phone_frames": True}},
"tuning": {"max_window": 30, "phone_services": True, "phone_frames": True, "stay_while_projecting": True}},
{"id": "unofficial", "label": "Unofficial dongle", "match": {}, "tuning": {"bootstrap_experiments": True}},
]
@@ -930,7 +930,8 @@ class Supervisor:
self._set(error=f'Waiting for selected car: {error}'[:300])
car_link = bool(car_device and car_device["connected"]) or now - self._car_seen_at < CAR_LINK_HOLD
onroad = self._onroad()
action = self.auto.decide(now, enabled=True, onroad=onroad, car_link=car_link,
linked = car_profiles.tuning(self.config)["stay_while_projecting"] and self._status.get("state") in ("streaming", "suspended")
action = self.auto.decide(now, enabled=True, onroad=onroad, car_link=car_link, linked=linked,
ready=adapter_ready and bool(device and device["paired"]) and (not companion or car_link), running=running)
self._apply_auto_action(now, action, onroad)
@@ -19,8 +19,8 @@ def identity(tmp_path_factory):
return make_identity(tmp_path_factory.mktemp("identity"))
def decide(policy, now, onroad=False, car_link=False, ready=True, running=False, enabled=True):
return policy.decide(now, enabled=enabled, onroad=onroad, car_link=car_link, ready=ready, running=running)
def decide(policy, now, onroad=False, car_link=False, ready=True, running=False, enabled=True, linked=False):
return policy.decide(now, enabled=enabled, onroad=onroad, car_link=car_link, ready=ready, running=running, linked=linked)
# -------------------------------------------------------------------- policy
@@ -45,6 +45,16 @@ def test_policy_stops_after_car_gone():
assert decide(policy, 100) is None # stopped, car still gone: no restart
def test_policy_keeps_a_projecting_session_when_the_car_link_drops():
policy = AutoConnectPolicy()
assert decide(policy, 0, car_link=True) == "start"
assert decide(policy, 1, car_link=True, running=True) is None
for now in range(2, 400, 10):
assert decide(policy, now, running=True, linked=True) is None
assert decide(policy, 400, running=True) is None # stream ended: grace period starts
assert decide(policy, 400 + auto_connect.STOP_AFTER, running=True) == "stop"
def test_policy_leaves_sessions_that_never_saw_the_car():
policy = AutoConnectPolicy()
for now in range(0, 300, 10):