system/ui: performance optimizations for WiFi Manager with cached network data (#35170)

Performance optimizations for WiFi Manager with cached network data
pull/35177/head
Dean Lee 2 months ago committed by GitHub
parent eaa595958c
commit f1760e63d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 15
      system/ui/lib/wifi_manager.py
  2. 22
      system/ui/widgets/network.py

@ -1,5 +1,6 @@
import asyncio
import concurrent.futures
import copy
import threading
import time
import uuid
@ -56,6 +57,7 @@ class NetworkInfo:
security_type: SecurityType
path: str
bssid: str
is_saved: bool = False
# saved_path: str
@ -64,6 +66,7 @@ class WifiManagerCallbacks:
need_auth: Callable[[str], None] | None = None
activated: Callable[[], None] | None = None
forgotten: Callable[[], None] | None = None
networks_updated: Callable[[list[NetworkInfo]], None] | None = None
class WifiManager:
@ -452,6 +455,8 @@ class WifiManager:
del self.saved_connections[ssid]
if self.callbacks.forgotten:
self.callbacks.forgotten()
# Update network list to reflect the removed saved connection
asyncio.create_task(self._update_connection_status())
break
async def _add_saved_connection(self, path: str) -> None:
@ -460,6 +465,7 @@ class WifiManager:
settings = await self._get_connection_settings(path)
if ssid := self._extract_ssid(settings):
self.saved_connections[ssid] = path
await self._update_connection_status()
except DBusError as e:
cloudlog.error(f"Failed to add connection {path}: {e}")
@ -517,6 +523,7 @@ class WifiManager:
path=ap_path,
bssid=bssid,
is_connected=self.active_ap_path == ap_path,
is_saved=ssid in self.saved_connections
)
except DBusError as e:
@ -533,6 +540,9 @@ class WifiManager:
),
)
if self.callbacks.networks_updated:
self.callbacks.networks_updated(copy.deepcopy(self.networks))
async def _get_connection_settings(self, path):
"""Fetch connection settings for a specific connection path."""
try:
@ -628,11 +638,6 @@ class WifiManagerWrapper:
self._thread.join(timeout=2.0)
self._running = False
@property
def networks(self) -> list[NetworkInfo]:
"""Get the current list of networks."""
return self._run_coroutine_sync(lambda manager: manager.networks.copy(), default=[])
def is_saved(self, ssid: str) -> bool:
"""Check if a network is saved."""
return self._run_coroutine_sync(lambda manager: manager.is_saved(ssid), default=False)

@ -48,13 +48,15 @@ class WifiManagerUI:
self.scroll_panel = GuiScrollPanel()
self.keyboard = Keyboard()
self._networks: list[NetworkInfo] = []
self.wifi_manager = wifi_manager
self.wifi_manager.set_callbacks(WifiManagerCallbacks(self._on_need_auth, self._on_activated, self._on_forgotten))
self.wifi_manager.set_callbacks(WifiManagerCallbacks(self._on_need_auth, self._on_activated, self._on_forgotten, self._on_network_updated))
self.wifi_manager.start()
self.wifi_manager.connect()
def render(self, rect: rl.Rectangle):
if not self.wifi_manager.networks:
if not self._networks:
gui_label(rect, "Scanning Wi-Fi networks...", 72, alignment=rl.GuiTextAlignment.TEXT_ALIGN_CENTER)
return
@ -77,19 +79,19 @@ class WifiManagerUI:
self._draw_network_list(rect)
def _draw_network_list(self, rect: rl.Rectangle):
content_rect = rl.Rectangle(rect.x, rect.y, rect.width, len(self.wifi_manager.networks) * ITEM_HEIGHT)
content_rect = rl.Rectangle(rect.x, rect.y, rect.width, len(self._networks) * ITEM_HEIGHT)
offset = self.scroll_panel.handle_scroll(rect, content_rect)
clicked = self.scroll_panel.is_click_valid()
rl.begin_scissor_mode(int(rect.x), int(rect.y), int(rect.width), int(rect.height))
for i, network in enumerate(self.wifi_manager.networks):
for i, network in enumerate(self._networks):
y_offset = rect.y + i * ITEM_HEIGHT + offset.y
item_rect = rl.Rectangle(rect.x, y_offset, rect.width, ITEM_HEIGHT)
if not rl.check_collision_recs(item_rect, rect):
continue
self._draw_network_item(item_rect, network, clicked)
if i < len(self.wifi_manager.networks) - 1:
if i < len(self._networks) - 1:
line_y = int(item_rect.y + item_rect.height - 1)
rl.draw_line(int(item_rect.x), int(line_y), int(item_rect.x + item_rect.width), line_y, rl.LIGHTGRAY)
@ -115,7 +117,7 @@ class WifiManagerUI:
rl.gui_label(state_rect, status_text)
# If the network is saved, show the "Forget" button
if self.wifi_manager.is_saved(network.ssid):
if network.is_saved:
forget_btn_rect = rl.Rectangle(
rect.x + rect.width - self.btn_width,
rect.y + (ITEM_HEIGHT - 80) / 2,
@ -126,22 +128,26 @@ class WifiManagerUI:
self.state = StateShowForgetConfirm(network)
if isinstance(self.state, StateIdle) and rl.check_collision_point_rec(rl.get_mouse_position(), label_rect) and clicked:
if not self.wifi_manager.is_saved(network.ssid):
if not network.is_saved:
self.state = StateNeedsAuth(network)
else:
self.connect_to_network(network)
def connect_to_network(self, network: NetworkInfo, password=''):
self.state = StateConnecting(network)
if self.wifi_manager.is_saved(network.ssid) and not password:
if network.is_saved and not password:
self.wifi_manager.activate_connection(network.ssid)
else:
self.wifi_manager.connect_to_network(network.ssid, password)
def forget_network(self, network: NetworkInfo):
self.state = StateForgetting(network)
network.is_saved = False
self.wifi_manager.forget_connection(network.ssid)
def _on_network_updated(self, networks: list[NetworkInfo]):
self._networks = networks
def _on_need_auth(self, ssid):
match self.state:
case StateConnecting(ssid):

Loading…
Cancel
Save