fix: track intent-retry tasks in the unload-cancelled task registry so removal can't trigger a shell() auto-reconnect (reviewer F2)

This commit is contained in:
James Mackay committed 2026-10-08 08:43:23 +01:00
1 parent b91a4242ba
commit a1e671ac6a
1 file changed
+14 -3
@@ -258,11 +258,11 @@ class NvidiaShieldMediaPlayer(MediaPlayerEntity):
and self._adb_poller.connected and self._adb_poller.connected
): ):
# The command was originally served by ADB — retry over ADB. # The command was originally served by ADB — retry over ADB.
self.hass.async_create_task( self._track_task(
self._adb_poller.send_media_command(intent.adb_command) self._adb_poller.send_media_command(intent.adb_command)
) )
else: else:
self.hass.async_create_task( self._track_task(
self._cmd(intent.command) self._cmd(intent.command)
) )
self._intent_timer_unsub = async_call_later( self._intent_timer_unsub = async_call_later(
@@ -377,7 +377,18 @@ class NvidiaShieldMediaPlayer(MediaPlayerEntity):
@callback @callback
def _adb_poll_callback(self, _now) -> None: def _adb_poll_callback(self, _now) -> None:
"""Schedule the ADB poll as a tracked task (cancelled on unload).""" """Schedule the ADB poll as a tracked task (cancelled on unload)."""
task = self.hass.async_create_task(self._adb_poll()) self._track_task(self._adb_poll())
def _track_task(self, coro) -> None:
"""Dispatch a background task and register it for unload cancellation.
Any fire-and-forget task that can touch the ADB poller must go through
here: a bare hass.async_create_task survives entity removal and, with
shell()'s auto-reconnect, can re-handshake the socket for a removed
entity (reviewer finding F2). Cancelation in async_will_remove_from_hass
covers poll and intent-retry tasks alike.
"""
task = self.hass.async_create_task(coro)
self._adb_poll_tasks.add(task) self._adb_poll_tasks.add(task)
task.add_done_callback(self._adb_poll_tasks.discard) task.add_done_callback(self._adb_poll_tasks.discard)