feat(connection): ADB foreground fallback on the watchdog cadence when the protocol push is silent (store priority protocol > ADB); audio-playback hint filtered through SYSTEM_MEDIA_PACKAGES (P3-2b,c)
This commit is contained in:
1 parent
f1e49a661b
commit
8885ddd5b5
3 files changed
+51
-4
No files matched your search
@@ -36,6 +36,7 @@ from .const import (
|
||||
ADB_RECONNECT_BACKOFF_START,
|
||||
ADB_RECONNECT_JITTER,
|
||||
STATE_STORE_TTL,
|
||||
SYSTEM_MEDIA_PACKAGES,
|
||||
)
|
||||
from .ha_adb_common import MediaSessionInfo, parse_audio_playback
|
||||
|
||||
@@ -53,11 +54,21 @@ FIELD_IS_AVAILABLE = "is_available"
|
||||
FIELD_CURRENT_APP = "current_app"
|
||||
FIELD_VOLUME_INFO = "volume_info"
|
||||
|
||||
# ADB fallback foreground identity (P3-2): stamped only when the protocol
|
||||
# push is silent; consumers prefer FIELD_CURRENT_APP over this.
|
||||
FIELD_FOREGROUND = "foreground"
|
||||
|
||||
# ADB-derived fields (cleared when the ADB connection goes down — they are
|
||||
# regenerated by the watchdog); protocol pushes (IS_ON/IS_AVAILABLE/
|
||||
# CURRENT_APP/VOLUME_INFO) are device-reported truth and expire by TTL only,
|
||||
# so an ADB outage never clobbers them.
|
||||
ADB_FIELDS = (FIELD_AWAKE, FIELD_SESSIONS, FIELD_AUDIO_PLAYBACK, FIELD_RUNNING_APPS)
|
||||
ADB_FIELDS = (
|
||||
FIELD_AWAKE,
|
||||
FIELD_SESSIONS,
|
||||
FIELD_AUDIO_PLAYBACK,
|
||||
FIELD_RUNNING_APPS,
|
||||
FIELD_FOREGROUND,
|
||||
)
|
||||
PROTOCOL_FIELDS = (
|
||||
FIELD_IS_ON,
|
||||
FIELD_IS_AVAILABLE,
|
||||
@@ -371,6 +382,12 @@ class ShieldConnectionManager:
|
||||
"""Protocol current-app push (raw package; name resolution deferred)."""
|
||||
return self.store.get(FIELD_CURRENT_APP)
|
||||
|
||||
@property
|
||||
def foreground_app(self) -> str | None:
|
||||
"""Best foreground identity: protocol push first, ADB parse fallback
|
||||
(P3-2 store priority: FIELD_CURRENT_APP > FIELD_FOREGROUND)."""
|
||||
return self.store.get(FIELD_CURRENT_APP) or self.store.get(FIELD_FOREGROUND)
|
||||
|
||||
@property
|
||||
def volume_info(self) -> tuple | None:
|
||||
"""Protocol volume push as ``(level, max, muted)`` — readout only
|
||||
@@ -598,10 +615,23 @@ class ShieldConnectionManager:
|
||||
# Full dump, no truncation (B4) — low sessions must not be lost.
|
||||
await poller.poll_media_sessions(head_lines=None)
|
||||
self.store.set(FIELD_SESSIONS, list(poller.all_sessions))
|
||||
self.store.set(
|
||||
FIELD_AUDIO_PLAYBACK, parse_audio_playback(poller.last_dump or "")
|
||||
)
|
||||
# Zero-cost hint from the same dump; system processes filtered
|
||||
# (mediashell/systemui/tv settings/diagtools report "audio").
|
||||
playback = [
|
||||
pkg
|
||||
for pkg in parse_audio_playback(poller.last_dump or "")
|
||||
if pkg not in SYSTEM_MEDIA_PACKAGES
|
||||
]
|
||||
self.store.set(FIELD_AUDIO_PLAYBACK, playback)
|
||||
self.store.set(FIELD_RUNNING_APPS, await poller.poll_running_apps())
|
||||
# Foreground fallback (P3-2): ADB parse only when the protocol
|
||||
# push is silent — store priority is protocol > ADB, so this
|
||||
# never overwrites a live push.
|
||||
if self.store.get(FIELD_CURRENT_APP) is None:
|
||||
foreground = await poller.poll_foreground()
|
||||
if foreground:
|
||||
self.store.set(FIELD_FOREGROUND, foreground)
|
||||
self._cache_last_known(foreground)
|
||||
else:
|
||||
# Standby: playback data is not current — expire it.
|
||||
self.store.set(FIELD_SESSIONS, [])
|
||||
|
||||
Reference in new issue
Block a user