@ -4,6 +4,7 @@ from typing import cast
import pyray as rl
import pyray as rl
from openpilot . common . filter_simple import FirstOrderFilter
from openpilot . common . filter_simple import FirstOrderFilter
from openpilot . common . params import Params
from openpilot . system . ui . lib . application import gui_app , DEFAULT_FPS
from openpilot . system . ui . lib . application import gui_app , DEFAULT_FPS
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 WifiManager , SecurityType , Network , MeteredType
from openpilot . system . ui . lib . wifi_manager import WifiManager , SecurityType , Network , MeteredType
@ -13,7 +14,9 @@ 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 TextAlignment , gui_label
from openpilot . system . ui . widgets . label import TextAlignment , gui_label
from openpilot . system . ui . widgets . scroller import Scroller
from openpilot . system . ui . widgets . scroller import Scroller
from openpilot . system . ui . widgets . list_view import text_item , button_item , ListItem , ToggleAction , MultipleButtonAction , ButtonAction
from openpilot . system . ui . widgets . list_view import ButtonAction , ListItem , MultipleButtonAction , ToggleAction , button_item , text_item
from openpilot . selfdrive . ui . ui_state import ui_state
from openpilot . selfdrive . ui . lib . prime_state import PrimeType
NM_DEVICE_STATE_NEED_AUTH = 60
NM_DEVICE_STATE_NEED_AUTH = 60
MIN_PASSWORD_LENGTH = 8
MIN_PASSWORD_LENGTH = 8
@ -114,34 +117,54 @@ class AdvancedNetworkSettings(Widget):
super ( ) . __init__ ( )
super ( ) . __init__ ( )
self . _wifi_manager = wifi_manager
self . _wifi_manager = wifi_manager
self . _wifi_manager . set_callbacks ( networks_updated = self . _on_network_updated )
self . _wifi_manager . set_callbacks ( networks_updated = self . _on_network_updated )
self . _params = Params ( )
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 )
# Tethering
# Tethering
self . _tethering_action = ToggleAction ( initial_state = False )
self . _tethering_action = ToggleAction ( initial_state = False )
self . _ tethering_btn = ListItem ( title = " Enable Tethering " , action_item = self . _tethering_action , callback = self . _toggle_tethering )
tethering_btn = ListItem ( title = " Enable Tethering " , action_item = self . _tethering_action , callback = self . _toggle_tethering )
# Tethering P assword
# Edit tethering p assword
self . _tethering_password_action = ButtonAction ( text = " EDIT " )
self . _tethering_password_action = ButtonAction ( text = " EDIT " )
self . _ tethering_password_btn = ListItem ( title = " Tethering Password " , action_item = self . _tethering_password_action , callback = self . _edit_tethering_password )
tethering_password_btn = ListItem ( title = " Tethering Password " , action_item = self . _tethering_password_action , callback = self . _edit_tethering_password )
# TODO: Roaming toggle, edit APN settings, and cellular metered toggle
# Roaming toggle
roaming_enabled = self . _params . get_bool ( " GsmRoaming " )
self . _roaming_action = ToggleAction ( initial_state = roaming_enabled )
self . _roaming_btn = ListItem ( title = " Enable Roaming " , action_item = self . _roaming_action , callback = self . _toggle_roaming )
# Metered
# Cellular metered toggle
cellular_metered = self . _params . get_bool ( " GsmMetered " )
self . _cellular_metered_action = ToggleAction ( initial_state = cellular_metered )
self . _cellular_metered_btn = ListItem ( title = " Cellular Metered " , description = " Prevent large data uploads when on a metered cellular connection " ,
action_item = self . _cellular_metered_action , callback = self . _toggle_cellular_metered )
# APN setting
self . _apn_btn = button_item ( " APN Setting " , " EDIT " , callback = self . _edit_apn )
# Wi-Fi metered toggle
self . _wifi_metered_action = MultipleButtonAction ( [ " default " , " metered " , " unmetered " ] , 255 , 0 , callback = self . _toggle_wifi_metered )
self . _wifi_metered_action = MultipleButtonAction ( [ " default " , " metered " , " unmetered " ] , 255 , 0 , callback = self . _toggle_wifi_metered )
self . _wifi_metered_btn = ListItem ( title = " Wi-Fi Network Metered " , description = " Prevent large data uploads when on a metered Wi-Fi connection " ,
wifi_metered_btn = ListItem ( title = " Wi-Fi Network Metered " , description = " Prevent large data uploads when on a metered Wi-Fi connection " ,
action_item = self . _wifi_metered_action )
action_item = self . _wifi_metered_action )
items : list [ Widget ] = [
items : list [ Widget ] = [
self . _tethering_btn ,
tethering_btn ,
self . _tethering_password_btn ,
tethering_password_btn ,
text_item ( " IP Address " , lambda : self . _wifi_manager . ipv4_address ) ,
text_item ( " IP Address " , lambda : self . _wifi_manager . ipv4_address ) ,
self . _wifi_metered_btn ,
self . _roaming_btn ,
self . _apn_btn ,
self . _cellular_metered_btn ,
wifi_metered_btn ,
button_item ( " Hidden Network " , " CONNECT " , callback = self . _connect_to_hidden_network ) ,
button_item ( " Hidden Network " , " CONNECT " , callback = self . _connect_to_hidden_network ) ,
]
]
self . _scroller = Scroller ( items , line_separator = True , spacing = 0 )
self . _scroller = Scroller ( items , line_separator = True , spacing = 0 )
# Set initial config
metered = self . _params . get_bool ( " GsmMetered " )
self . _wifi_manager . update_gsm_settings ( roaming_enabled , self . _params . get ( " GsmApn " ) or " " , metered )
def _on_network_updated ( self , networks : list [ Network ] ) :
def _on_network_updated ( self , networks : list [ Network ] ) :
self . _tethering_action . set_enabled ( True )
self . _tethering_action . set_enabled ( True )
self . _tethering_action . set_state ( self . _wifi_manager . is_tethering_active ( ) )
self . _tethering_action . set_state ( self . _wifi_manager . is_tethering_active ( ) )
@ -162,6 +185,35 @@ class AdvancedNetworkSettings(Widget):
self . _wifi_metered_action . set_enabled ( False )
self . _wifi_metered_action . set_enabled ( False )
self . _wifi_manager . set_tethering_active ( checked )
self . _wifi_manager . set_tethering_active ( checked )
def _toggle_roaming ( self ) :
roaming_state = self . _roaming_action . state
self . _params . put_bool ( " GsmRoaming " , roaming_state )
self . _wifi_manager . update_gsm_settings ( roaming_state , self . _params . get ( " GsmApn " ) or " " , self . _params . get_bool ( " GsmMetered " ) )
def _edit_apn ( self ) :
def update_apn ( result ) :
if result != 1 :
return
apn = self . _keyboard . text . strip ( )
if apn == " " :
self . _params . remove ( " GsmApn " )
else :
self . _params . put ( " GsmApn " , apn )
self . _wifi_manager . update_gsm_settings ( self . _params . get_bool ( " GsmRoaming " ) , apn , self . _params . get_bool ( " GsmMetered " ) )
current_apn = self . _params . get ( " GsmApn " ) or " "
self . _keyboard . reset ( min_text_size = 0 )
self . _keyboard . set_title ( " Enter APN " , " leave blank for automatic configuration " )
self . _keyboard . set_text ( current_apn )
gui_app . set_modal_overlay ( self . _keyboard , update_apn )
def _toggle_cellular_metered ( self ) :
metered = self . _cellular_metered_action . state
self . _params . put_bool ( " GsmMetered " , metered )
self . _wifi_manager . update_gsm_settings ( self . _params . get_bool ( " GsmRoaming " ) , self . _params . get ( " GsmApn " ) or " " , metered )
def _toggle_wifi_metered ( self , metered ) :
def _toggle_wifi_metered ( self , metered ) :
metered_type = { 0 : MeteredType . UNKNOWN , 1 : MeteredType . YES , 2 : MeteredType . NO } . get ( metered , MeteredType . UNKNOWN )
metered_type = { 0 : MeteredType . UNKNOWN , 1 : MeteredType . YES , 2 : MeteredType . NO } . get ( metered , MeteredType . UNKNOWN )
self . _wifi_metered_action . set_enabled ( False )
self . _wifi_metered_action . set_enabled ( False )
@ -207,6 +259,14 @@ class AdvancedNetworkSettings(Widget):
self . _keyboard . set_text ( self . _wifi_manager . tethering_password )
self . _keyboard . set_text ( self . _wifi_manager . tethering_password )
gui_app . set_modal_overlay ( self . _keyboard , update_password )
gui_app . set_modal_overlay ( self . _keyboard , update_password )
def _update_state ( self ) :
# If not using prime SIM, show GSM settings and enable IPv4 forwarding
show_cell_settings = ui_state . prime_state . get_type ( ) in ( PrimeType . NONE , PrimeType . LITE )
self . _wifi_manager . set_ipv4_forward ( show_cell_settings )
self . _roaming_btn . set_visible ( show_cell_settings )
self . _apn_btn . set_visible ( show_cell_settings )
self . _cellular_metered_btn . set_visible ( show_cell_settings )
def _render ( self , _ ) :
def _render ( self , _ ) :
self . _scroller . render ( self . _rect )
self . _scroller . render ( self . _rect )