refactor(connection): public protocol_active accessor replaces the remote entity's private reach-in; media_player module docstring describes the Phase 2 architecture (F7)
This commit is contained in:
1 parent
5f8c3290cc
commit
a65c893339
3 files changed
+23
-10
No files matched your search
@@ -347,6 +347,15 @@ class ShieldConnectionManager:
|
|||||||
"""Visible recent-task apps, ordered by recency."""
|
"""Visible recent-task apps, ordered by recency."""
|
||||||
return self.store.get(FIELD_RUNNING_APPS, [])
|
return self.store.get(FIELD_RUNNING_APPS, [])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def protocol_active(self) -> bool:
|
||||||
|
"""True when the remote-protocol transport is wired for this entry.
|
||||||
|
|
||||||
|
Entities use this instead of reaching into ``_protocol``: a passive
|
||||||
|
manager means "no transport", not "broken transport".
|
||||||
|
"""
|
||||||
|
return self._protocol is not None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool | None:
|
def is_on(self) -> bool | None:
|
||||||
"""Protocol power push (device reports on/off state)."""
|
"""Protocol power push (device reports on/off state)."""
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
"""Media player entity for Nvidia Shield.
|
"""Media player entity for Nvidia Shield.
|
||||||
|
|
||||||
State architecture:
|
Phase 2 architecture (docs/MVP_PLAN.md §2): the entry's ShieldConnectionManager
|
||||||
- Power/availability: androidtv_remote (local push, fast)
|
(connection.py) owns both transports — ADB (adb_shell, state source) and the
|
||||||
- Playback state: Jellyfin (polling, slow 10-30s)
|
absorbed remote protocol (androidtvremote2, local push) — plus their StateStore;
|
||||||
- Metadata: Jellyfin attributes
|
this entity is a thin callback-view over it.
|
||||||
- ALL commands: androidtv_remote (Jellyfin is read-only)
|
|
||||||
|
|
||||||
ADB connection/polling lives in the entry's ShieldConnectionManager
|
State architecture:
|
||||||
(connection.py); this entity is a thin callback-view over its StateStore.
|
- Power ladder: protocol is_on push → ADB wake (exact mWakefulness) → plug off
|
||||||
|
- Playback state: Jellyfin (polling, slow 10-30s) or ADB media session
|
||||||
|
- Metadata: Jellyfin attributes
|
||||||
|
- Commands: protocol key push → ADB keyevent → external androidtv_remote
|
||||||
|
(the last tier is transitional; removed in Phase 4)
|
||||||
|
|
||||||
Intent tracking bridges the gap between instant commands and slow Jellyfin polling:
|
Intent tracking bridges the gap between instant commands and slow Jellyfin polling:
|
||||||
1. User presses pause → intent recorded → UI shows paused immediately
|
1. User presses pause → intent recorded → UI shows paused immediately
|
||||||
2. Command sent to androidtv_remote → Shield pauses on screen
|
2. Command sent over the serving transport → Shield pauses on screen
|
||||||
3. 10-30s later Jellyfin confirms paused → intent cleared
|
3. 10-30s later Jellyfin confirms paused → intent cleared
|
||||||
4. If Jellyfin doesn't confirm in 30s → retry once → if still no → surrender to truth
|
4. If Jellyfin doesn't confirm in 30s → retry once on the serving
|
||||||
|
transport (protocol/ADB stamped on the intent) → surrender to truth
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ class NvidiaShieldRemoteEntity(RemoteEntity):
|
|||||||
manager = self._manager_of()
|
manager = self._manager_of()
|
||||||
if not isinstance(manager, ShieldConnectionManager):
|
if not isinstance(manager, ShieldConnectionManager):
|
||||||
return True
|
return True
|
||||||
if manager._protocol is None:
|
if not manager.protocol_active:
|
||||||
return True
|
return True
|
||||||
return manager.is_available is not False
|
return manager.is_available is not False
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user