app: Surface Ethernet uplink in the UI and gate wpa_supplicant access

When the configured Ethernet interface holds a DHCP-assigned IPv4 at
startup, the app now skips wifi.Initialize / StartEventMonitoring and
guards every wifi.* wrapper against a nil backend. This prevents D-Bus
calls to fi.w1.wpa_supplicant1 from re-activating the daemon via
dbus-activation, honoring the "do nothing" intent of the Ethernet path.

The probed state is exposed in SystemStatus and rendered in the header
as a third pill ("Ethernet · <IP>"); a new "disabled" connectionState
covers the WiFi pill in this mode.
This commit is contained in:
nemunaire 2026-05-02 11:24:36 +08:00
commit 8b1debdddc
7 changed files with 166 additions and 37 deletions

View file

@ -1,6 +1,7 @@
package wifi
import (
"errors"
"fmt"
"sort"
"strings"
@ -16,6 +17,13 @@ var (
wifiBroadcaster *WifiBroadcaster
)
// errWifiDisabled is returned by every wifi.* wrapper when no backend has
// been initialized. This happens when the application chose not to start
// wpa_supplicant because the Ethernet uplink is already providing
// connectivity — touching the D-Bus interface in that mode would re-activate
// the daemon via dbus-activation, defeating the intent.
var errWifiDisabled = errors.New("wifi backend disabled (Ethernet uplink active)")
// Initialize initializes the WiFi service with the specified backend
func Initialize(interfaceName string, backendName string) error {
// Create the appropriate backend using the factory
@ -38,6 +46,9 @@ func Close() {
// GetCachedNetworks returns previously discovered networks without triggering a scan
func GetCachedNetworks() ([]models.WiFiNetwork, error) {
if wifiBackend == nil {
return nil, errWifiDisabled
}
// Get ordered networks from backend
backendNetworks, err := wifiBackend.GetOrderedNetworks()
if err != nil {
@ -67,6 +78,9 @@ func GetCachedNetworks() ([]models.WiFiNetwork, error) {
// ScanNetworks scans for available WiFi networks
func ScanNetworks() ([]models.WiFiNetwork, error) {
if wifiBackend == nil {
return nil, errWifiDisabled
}
// Check if already scanning
scanning, err := wifiBackend.IsScanning()
if err == nil && scanning {
@ -114,6 +128,9 @@ func ScanNetworks() ([]models.WiFiNetwork, error) {
// Connect connects to a WiFi network
func Connect(ssid, password string) error {
if wifiBackend == nil {
return errWifiDisabled
}
// Use backend to connect
if err := wifiBackend.Connect(ssid, password); err != nil {
return err
@ -132,11 +149,17 @@ func Connect(ssid, password string) error {
// Disconnect disconnects from the current WiFi network
func Disconnect() error {
if wifiBackend == nil {
return errWifiDisabled
}
return wifiBackend.Disconnect()
}
// IsConnected checks if WiFi is connected
func IsConnected() bool {
if wifiBackend == nil {
return false
}
state, err := wifiBackend.GetConnectionState()
if err != nil {
return false
@ -146,11 +169,17 @@ func IsConnected() bool {
// GetConnectedSSID returns the SSID of the currently connected network
func GetConnectedSSID() string {
if wifiBackend == nil {
return ""
}
return wifiBackend.GetConnectedSSID()
}
// GetConnectionState returns the current WiFi connection state
func GetConnectionState() string {
if wifiBackend == nil {
return string(backend.StateDisconnected)
}
state, err := wifiBackend.GetConnectionState()
if err != nil {
return string(backend.StateDisconnected)
@ -160,6 +189,9 @@ func GetConnectionState() string {
// StartEventMonitoring initializes signal monitoring and WebSocket broadcasting
func StartEventMonitoring() error {
if wifiBackend == nil {
return nil
}
// Initialize broadcaster
wifiBroadcaster = NewWifiBroadcaster()