Skip to content

Commit e857abb

Browse files
authored
Allow fetching the Cloud ICE servers (home-assistant#157774)
1 parent 5b1829f commit e857abb

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed

homeassistant/components/cloud/client.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def __init__(
7171
self._google_config_init_lock = asyncio.Lock()
7272
self._relayer_region: str | None = None
7373
self._cloud_ice_servers_listener: Callable[[], None] | None = None
74+
self._ice_servers: list[RTCIceServer] = []
7475

7576
@property
7677
def base_path(self) -> Path:
@@ -117,6 +118,11 @@ def relayer_region(self) -> str | None:
117118
"""Return the connected relayer region."""
118119
return self._relayer_region
119120

121+
@property
122+
def ice_servers(self) -> list[RTCIceServer]:
123+
"""Return the current ICE servers."""
124+
return self._ice_servers
125+
120126
async def get_alexa_config(self) -> alexa_config.CloudAlexaConfig:
121127
"""Return Alexa config."""
122128
if self._alexa_config is None:
@@ -203,11 +209,8 @@ async def register_cloud_ice_server(
203209
ice_servers: list[RTCIceServer],
204210
) -> Callable[[], None]:
205211
"""Register cloud ice server."""
206-
207-
def get_ice_servers() -> list[RTCIceServer]:
208-
return ice_servers
209-
210-
return async_register_ice_servers(self._hass, get_ice_servers)
212+
self._ice_servers = ice_servers
213+
return async_register_ice_servers(self._hass, lambda: self._ice_servers)
211214

212215
async def async_register_cloud_ice_servers_listener(
213216
prefs: CloudPreferences,
@@ -268,6 +271,7 @@ async def cloud_stopped(self) -> None:
268271

269272
async def logout_cleanups(self) -> None:
270273
"""Cleanup some stuff after logout."""
274+
self._ice_servers = []
271275
await self.prefs.async_set_username(None)
272276

273277
if self._alexa_config:

homeassistant/components/cloud/http_api.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ def async_setup(hass: HomeAssistant) -> None:
9999
websocket_api.async_register_command(hass, websocket_hook_delete)
100100
websocket_api.async_register_command(hass, websocket_remote_connect)
101101
websocket_api.async_register_command(hass, websocket_remote_disconnect)
102+
websocket_api.async_register_command(hass, websocket_webrtc_ice_servers)
102103

103104
websocket_api.async_register_command(hass, google_assistant_get)
104105
websocket_api.async_register_command(hass, google_assistant_list)
@@ -1107,6 +1108,7 @@ async def alexa_sync(
11071108

11081109

11091110
@websocket_api.websocket_command({"type": "cloud/tts/info"})
1111+
@callback
11101112
def tts_info(
11111113
hass: HomeAssistant,
11121114
connection: websocket_api.ActiveConnection,
@@ -1134,3 +1136,22 @@ def tts_info(
11341136
)
11351137

11361138
connection.send_result(msg["id"], {"languages": result})
1139+
1140+
1141+
@websocket_api.websocket_command(
1142+
{
1143+
vol.Required("type"): "cloud/webrtc/ice_servers",
1144+
}
1145+
)
1146+
@_require_cloud_login
1147+
@callback
1148+
def websocket_webrtc_ice_servers(
1149+
hass: HomeAssistant,
1150+
connection: websocket_api.ActiveConnection,
1151+
msg: dict[str, Any],
1152+
) -> None:
1153+
"""Handle get WebRTC ICE servers websocket command."""
1154+
connection.send_result(
1155+
msg["id"],
1156+
[server.to_dict() for server in hass.data[DATA_CLOUD].client.ice_servers],
1157+
)

tests/components/cloud/test_http_api.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from hass_nabucasa.remote import CertificateStatus
2323
import pytest
2424
from syrupy.assertion import SnapshotAssertion
25+
from webrtc_models import RTCIceServer
2526

2627
from homeassistant.components import system_health
2728
from homeassistant.components.alexa import errors as alexa_errors
@@ -2186,3 +2187,39 @@ async def mock_empty_info(hass: HomeAssistant) -> dict[str, Any]:
21862187
req = await cloud_client.get("/api/cloud/support_package")
21872188
assert req.status == HTTPStatus.OK
21882189
assert await req.text() == snapshot
2190+
2191+
2192+
async def test_websocket_ice_servers(
2193+
hass: HomeAssistant,
2194+
hass_ws_client: WebSocketGenerator,
2195+
cloud: MagicMock,
2196+
setup_cloud: None,
2197+
) -> None:
2198+
"""Test getting ICE servers."""
2199+
cloud.client._ice_servers = [
2200+
RTCIceServer(urls="stun:stun.l.bla.com:19302"),
2201+
RTCIceServer(
2202+
urls="turn:turn.example.com:3478", username="user", credential="pass"
2203+
),
2204+
]
2205+
client = await hass_ws_client(hass)
2206+
2207+
await client.send_json_auto_id({"type": "cloud/webrtc/ice_servers"})
2208+
response = await client.receive_json()
2209+
2210+
assert response["success"]
2211+
assert response["result"] == [
2212+
{"urls": "stun:stun.l.bla.com:19302"},
2213+
{
2214+
"urls": "turn:turn.example.com:3478",
2215+
"username": "user",
2216+
"credential": "pass",
2217+
},
2218+
]
2219+
2220+
cloud.id_token = None
2221+
2222+
await client.send_json_auto_id({"type": "cloud/webrtc/ice_servers"})
2223+
response = await client.receive_json()
2224+
assert not response["success"]
2225+
assert response["error"]["code"] == "not_logged_in"

0 commit comments

Comments
 (0)