| 
						
						
						
					 | 
					 | 
					@ -1,4 +1,5 @@ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from dataclasses import dataclass | 
					 | 
					 | 
					 | 
					from dataclasses import dataclass | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					from functools import partial | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from threading import Lock | 
					 | 
					 | 
					 | 
					from threading import Lock | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from typing import Literal | 
					 | 
					 | 
					 | 
					from typing import Literal | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -7,8 +8,8 @@ from openpilot.system.ui.lib.application import gui_app | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel | 
					 | 
					 | 
					 | 
					from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.ui.lib.wifi_manager import NetworkInfo, WifiManagerCallbacks, WifiManagerWrapper, SecurityType | 
					 | 
					 | 
					 | 
					from openpilot.system.ui.lib.wifi_manager import NetworkInfo, WifiManagerCallbacks, WifiManagerWrapper, SecurityType | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets import Widget | 
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets import Widget | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets.button import ButtonStyle, gui_button | 
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets.button import ButtonStyle, Button, TextAlignment | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets.confirm_dialog import confirm_dialog | 
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets.keyboard import Keyboard | 
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets.keyboard import Keyboard | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets.label import gui_label | 
					 | 
					 | 
					 | 
					from openpilot.system.ui.widgets.label import gui_label | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -67,8 +68,11 @@ class WifiManagerUI(Widget): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.keyboard = Keyboard(max_text_size=MAX_PASSWORD_LENGTH, min_text_size=MIN_PASSWORD_LENGTH, show_password_toggle=True) | 
					 | 
					 | 
					 | 
					    self.keyboard = Keyboard(max_text_size=MAX_PASSWORD_LENGTH, min_text_size=MIN_PASSWORD_LENGTH, show_password_toggle=True) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._networks: list[NetworkInfo] = [] | 
					 | 
					 | 
					 | 
					    self._networks: list[NetworkInfo] = [] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._networks_buttons: dict[str, Button] = {} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._forget_networks_buttons: dict[str, Button] = {} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._lock = Lock() | 
					 | 
					 | 
					 | 
					    self._lock = Lock() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.wifi_manager = wifi_manager | 
					 | 
					 | 
					 | 
					    self.wifi_manager = wifi_manager | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    self._confirm_dialog = ConfirmDialog("", "Forget", "Cancel") | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self.wifi_manager.set_callbacks( | 
					 | 
					 | 
					 | 
					    self.wifi_manager.set_callbacks( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      WifiManagerCallbacks( | 
					 | 
					 | 
					 | 
					      WifiManagerCallbacks( | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -91,10 +95,12 @@ class WifiManagerUI(Widget): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      match self.state: | 
					 | 
					 | 
					 | 
					      match self.state: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        case StateNeedsAuth(network): | 
					 | 
					 | 
					 | 
					        case StateNeedsAuth(network): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          self.keyboard.set_title("Enter password", f"for {network.ssid}") | 
					 | 
					 | 
					 | 
					          self.keyboard.set_title("Enter password", f"for {network.ssid}") | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          self.keyboard.reset() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          gui_app.set_modal_overlay(self.keyboard, lambda result: self._on_password_entered(network, result)) | 
					 | 
					 | 
					 | 
					          gui_app.set_modal_overlay(self.keyboard, lambda result: self._on_password_entered(network, result)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        case StateShowForgetConfirm(network): | 
					 | 
					 | 
					 | 
					        case StateShowForgetConfirm(network): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          gui_app.set_modal_overlay(lambda: confirm_dialog(f'Forget Wi-Fi Network "{network.ssid}"?', "Forget"), | 
					 | 
					 | 
					 | 
					          self._confirm_dialog.text = f'Forget Wi-Fi Network "{network.ssid}"?' | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                                    callback=lambda result: self.on_forgot_confirm_finished(network, result)) | 
					 | 
					 | 
					 | 
					          self._confirm_dialog.reset() | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					          gui_app.set_modal_overlay(self._confirm_dialog, callback=lambda result: self.on_forgot_confirm_finished(network, result)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        case _: | 
					 | 
					 | 
					 | 
					        case _: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          self._draw_network_list(rect) | 
					 | 
					 | 
					 | 
					          self._draw_network_list(rect) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -139,7 +145,7 @@ class WifiManagerUI(Widget): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    signal_icon_rect = rl.Rectangle(rect.x + rect.width - ICON_SIZE, rect.y + (ITEM_HEIGHT - ICON_SIZE) / 2, ICON_SIZE, ICON_SIZE) | 
					 | 
					 | 
					 | 
					    signal_icon_rect = rl.Rectangle(rect.x + rect.width - ICON_SIZE, rect.y + (ITEM_HEIGHT - ICON_SIZE) / 2, ICON_SIZE, ICON_SIZE) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    security_icon_rect = rl.Rectangle(signal_icon_rect.x - spacing - ICON_SIZE, rect.y + (ITEM_HEIGHT - ICON_SIZE) / 2, ICON_SIZE, ICON_SIZE) | 
					 | 
					 | 
					 | 
					    security_icon_rect = rl.Rectangle(signal_icon_rect.x - spacing - ICON_SIZE, rect.y + (ITEM_HEIGHT - ICON_SIZE) / 2, ICON_SIZE, ICON_SIZE) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    gui_label(ssid_rect, network.ssid, 55) | 
					 | 
					 | 
					 | 
					    self._networks_buttons[network.ssid].render(ssid_rect) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    status_text = "" | 
					 | 
					 | 
					 | 
					    status_text = "" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    match self.state: | 
					 | 
					 | 
					 | 
					    match self.state: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -162,18 +168,23 @@ class WifiManagerUI(Widget): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          self.btn_width, | 
					 | 
					 | 
					 | 
					          self.btn_width, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          80, | 
					 | 
					 | 
					 | 
					          80, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        ) | 
					 | 
					 | 
					 | 
					        ) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if isinstance(self.state, StateIdle) and gui_button(forget_btn_rect, "Forget", button_style=ButtonStyle.ACTION) and clicked: | 
					 | 
					 | 
					 | 
					        self._forget_networks_buttons[network.ssid].render(forget_btn_rect) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					          self.state = StateShowForgetConfirm(network) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._draw_status_icon(security_icon_rect, network) | 
					 | 
					 | 
					 | 
					    self._draw_status_icon(security_icon_rect, network) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    self._draw_signal_strength_icon(signal_icon_rect, network) | 
					 | 
					 | 
					 | 
					    self._draw_signal_strength_icon(signal_icon_rect, network) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if isinstance(self.state, StateIdle) and rl.check_collision_point_rec(rl.get_mouse_position(), ssid_rect) and clicked: | 
					 | 
					 | 
					 | 
					  def _networks_buttons_callback(self, network): | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if self.scroll_panel.is_touch_valid(): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      if not network.is_saved and network.security_type != SecurityType.OPEN: | 
					 | 
					 | 
					 | 
					      if not network.is_saved and network.security_type != SecurityType.OPEN: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.state = StateNeedsAuth(network) | 
					 | 
					 | 
					 | 
					        self.state = StateNeedsAuth(network) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      elif not network.is_connected: | 
					 | 
					 | 
					 | 
					      elif not network.is_connected: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.connect_to_network(network) | 
					 | 
					 | 
					 | 
					        self.connect_to_network(network) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def _forget_networks_buttons_callback(self, network): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if self.scroll_panel.is_touch_valid(): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      if isinstance(self.state, StateIdle): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        self.state = StateShowForgetConfirm(network) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def _draw_status_icon(self, rect, network: NetworkInfo): | 
					 | 
					 | 
					 | 
					  def _draw_status_icon(self, rect, network: NetworkInfo): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    """Draw the status icon based on network's connection state""" | 
					 | 
					 | 
					 | 
					    """Draw the status icon based on network's connection state""" | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    icon_file = None | 
					 | 
					 | 
					 | 
					    icon_file = None | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -211,6 +222,10 @@ class WifiManagerUI(Widget): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def _on_network_updated(self, networks: list[NetworkInfo]): | 
					 | 
					 | 
					 | 
					  def _on_network_updated(self, networks: list[NetworkInfo]): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    with self._lock: | 
					 | 
					 | 
					 | 
					    with self._lock: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      self._networks = networks | 
					 | 
					 | 
					 | 
					      self._networks = networks | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					      for n in self._networks: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        self._networks_buttons[n.ssid] = Button(n.ssid, partial(self._networks_buttons_callback, n), font_size=55, text_alignment=TextAlignment.LEFT, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                                button_style=ButtonStyle.NO_EFFECT) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        self._forget_networks_buttons[n.ssid] = Button("Forget", partial(self._forget_networks_buttons_callback, n), button_style=ButtonStyle.ACTION) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def _on_need_auth(self, ssid): | 
					 | 
					 | 
					 | 
					  def _on_need_auth(self, ssid): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    with self._lock: | 
					 | 
					 | 
					 | 
					    with self._lock: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |