Remove cast stop listener when the entity is torn down (#183321)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Franck Nijhof
2026-09-27 17:41:24 +02:00
committed by GitHub
co-authored by Claude
parent 32bda123ac
commit bf5007c1ea
2 changed files with 24 additions and 1 deletions
@@ -191,6 +191,7 @@ class CastDevice:
self._status_listener: CastStatusListener | None = None
self._add_remove_handler: Callable[[], None] | None = None
self._del_remove_handler: Callable[[], None] | None = None
self._stop_listener: Callable[[], None] | None = None
self._name: str | None = None
def _async_setup(self, name: str) -> None:
@@ -202,7 +203,9 @@ class CastDevice:
self._del_remove_handler = async_dispatcher_connect(
self.hass, SIGNAL_CAST_REMOVED, self._async_cast_removed
)
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self._async_stop)
self._stop_listener = self.hass.bus.async_listen(
EVENT_HOMEASSISTANT_STOP, self._async_stop
)
# async_create_background_task is used to avoid delaying
# startup wrapup if the device
# is discovered already during startup but then fails to respond
@@ -226,6 +229,9 @@ class CastDevice:
if self._del_remove_handler:
self._del_remove_handler()
self._del_remove_handler = None
if self._stop_listener:
self._stop_listener()
self._stop_listener = None
async def _async_connect_to_chromecast(self):
"""Set up the chromecast object."""
@@ -26,6 +26,7 @@ from homeassistant.components.cast.const import (
)
from homeassistant.components.cast.media_player import ChromecastInfo
from homeassistant.components.media_player import (
DOMAIN as MP_DOMAIN,
BrowseMedia,
MediaClass,
MediaPlayerEntityFeature,
@@ -2114,6 +2115,22 @@ async def test_disconnect_on_stop(hass: HomeAssistant) -> None:
assert chromecast.disconnect.call_count == 1
async def test_stop_listener_removed_with_entity(hass: HomeAssistant) -> None:
"""Test the stop listener is removed when the entity is removed."""
info = get_fake_chromecast_info()
await async_setup_media_player_cast(hass, info)
stop_listeners = hass.bus.async_listeners()[EVENT_HOMEASSISTANT_STOP]
entity = hass.data[MP_DOMAIN].get_entity("media_player.speaker")
await entity.async_remove()
await hass.async_block_till_done()
assert (
hass.bus.async_listeners().get(EVENT_HOMEASSISTANT_STOP, 0)
== stop_listeners - 1
)
async def test_entry_setup_no_config(hass: HomeAssistant) -> None:
"""Test deprecated empty yaml config.."""
await async_setup_component(hass, DOMAIN, {})