From 7147c2695447492a6b456674a4dd1b30b344084e Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Sun, 11 May 2025 01:00:28 +0800 Subject: [PATCH] system/ui: fix WIFI authentication callback and connection tracking (#35169) fix authentication callback and state handling --- system/ui/lib/wifi_manager.py | 22 +++++++++++++++++++--- system/ui/widgets/network.py | 11 ++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/system/ui/lib/wifi_manager.py b/system/ui/lib/wifi_manager.py index ff1809236..d3d9bb441 100644 --- a/system/ui/lib/wifi_manager.py +++ b/system/ui/lib/wifi_manager.py @@ -61,7 +61,7 @@ class NetworkInfo: @dataclass class WifiManagerCallbacks: - need_auth: Callable[[], None] | None = None + need_auth: Callable[[str], None] | None = None activated: Callable[[], None] | None = None forgotten: Callable[[], None] | None = None @@ -78,6 +78,7 @@ class WifiManager: self.scan_task: asyncio.Task | None = None self._tethering_ssid = "weedle-" + Params().get("DongleId", encoding="utf-8") self.running: bool = True + self._current_connection_ssid: str | None = None async def connect(self) -> None: """Connect to the DBus system bus.""" @@ -133,6 +134,9 @@ class WifiManager: try: nm_iface = await self._get_interface(NM, path, NM_CONNECTION_IFACE) await nm_iface.call_delete() + if self._current_connection_ssid == ssid: + self._current_connection_ssid = None + del self.saved_connections[ssid] return True except DBusError as e: cloudlog.error(f"Failed to delete connection for SSID: {ssid}. Error: {e}") @@ -153,6 +157,7 @@ class WifiManager: async def connect_to_network(self, ssid: str, password: str = None, bssid: str = None, is_hidden: bool = False) -> None: """Connect to a selected Wi-Fi network.""" try: + self._current_connection_ssid = ssid connection = { 'connection': { 'type': Variant('s', '802-11-wireless'), @@ -182,8 +187,8 @@ class WifiManager: nm_iface = await self._get_interface(NM, NM_PATH, NM_IFACE) await nm_iface.call_add_and_activate_connection(connection, self.device_path, "/") await self._update_connection_status() - except DBusError as e: + self._current_connection_ssid = None cloudlog.error(f"Error connecting to network: {e}") def is_saved(self, ssid: str) -> bool: @@ -403,11 +408,22 @@ class WifiManager: if self.callbacks.activated: self.callbacks.activated() asyncio.create_task(self._update_connection_status()) + self._current_connection_ssid = None elif new_state in (NMDeviceState.DISCONNECTED, NMDeviceState.NEED_AUTH): for network in self.networks: network.is_connected = False if new_state == NMDeviceState.NEED_AUTH and reason == NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT and self.callbacks.need_auth: - self.callbacks.need_auth() + if self._current_connection_ssid: + self.callbacks.need_auth(self._current_connection_ssid) + else: + # Try to find the network from active_ap_path + for network in self.networks: + if network.path == self.active_ap_path: + self.callbacks.need_auth(network.ssid) + break + else: + # Couldn't identify the network that needs auth + cloudlog.error("Network needs authentication but couldn't identify which one") def _on_new_connection(self, path: str) -> None: """Callback for NewConnection signal.""" diff --git a/system/ui/widgets/network.py b/system/ui/widgets/network.py index 59427b57b..0e9ad349b 100644 --- a/system/ui/widgets/network.py +++ b/system/ui/widgets/network.py @@ -142,10 +142,15 @@ class WifiManagerUI: self.state = StateForgetting(network) self.wifi_manager.forget_connection(network.ssid) - def _on_need_auth(self): + def _on_need_auth(self, ssid): match self.state: - case StateConnecting(network): - self.state = StateNeedsAuth(network) + case StateConnecting(ssid): + self.state = StateNeedsAuth(ssid) + case _: + # Find network by SSID + network = next((n for n in self.wifi_manager.networks if n.ssid == ssid), None) + if network: + self.state = StateNeedsAuth(network) def _on_activated(self): if isinstance(self.state, StateConnecting):