1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-02 03:28:28 -04:00

fix(iwd): update rfkill to allow backend management

- Fixes #2221
This commit is contained in:
purian23
2026-07-04 21:57:27 -04:00
parent c5c3105469
commit 7dffe85e94
3 changed files with 117 additions and 7 deletions
+25 -1
View File
@@ -114,6 +114,14 @@ func (b *IWDBackend) discoverDevices() error {
return fmt.Errorf("failed to get managed objects: %w", err)
}
return b.applyManagedObjects(objects)
}
func (b *IWDBackend) applyManagedObjects(objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant) error {
b.stationPath = ""
b.devicePath = ""
b.adapterPath = ""
for path, interfaces := range objects {
if _, hasStation := interfaces[iwdStationInterface]; hasStation {
b.stationPath = path
@@ -129,6 +137,13 @@ func (b *IWDBackend) discoverDevices() error {
b.stateMutex.Unlock()
}
}
if poweredVar, ok := devProps["Powered"]; ok {
if powered, ok := poweredVar.Value().(bool); ok {
b.stateMutex.Lock()
b.state.WiFiEnabled = powered
b.stateMutex.Unlock()
}
}
}
}
if _, hasAdapter := interfaces[iwdAdapterInterface]; hasAdapter {
@@ -136,9 +151,18 @@ func (b *IWDBackend) discoverDevices() error {
}
}
if b.stationPath == "" || b.devicePath == "" {
if b.devicePath == "" {
return fmt.Errorf("no WiFi device found")
}
if b.stationPath == "" {
b.stateMutex.Lock()
b.state.WiFiEnabled = false
b.state.WiFiConnected = false
b.state.NetworkStatus = StatusDisconnected
b.state.WiFiNetworks = nil
b.stateMutex.Unlock()
log.Infof("iwd device %s has no station interface; treating WiFi as disabled", b.devicePath)
}
return nil
}
@@ -4,6 +4,7 @@ import (
"fmt"
"time"
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
"github.com/godbus/dbus/v5"
)
@@ -35,12 +36,7 @@ func (b *IWDBackend) StartMonitoring(onStateChange func()) error {
}
if b.stationPath != "" {
err := b.conn.AddMatchSignal(
dbus.WithMatchObjectPath(b.stationPath),
dbus.WithMatchInterface(dbusPropertiesInterface),
dbus.WithMatchMember("PropertiesChanged"),
)
if err != nil {
if err := b.addStationSignalMatch(b.stationPath); err != nil {
return fmt.Errorf("failed to add station signal match: %w", err)
}
}
@@ -81,6 +77,48 @@ func (b *IWDBackend) refreshWiFiNetworkState() bool {
return b.updateSavedWiFiNetworks() == nil
}
func (b *IWDBackend) addStationSignalMatch(path dbus.ObjectPath) error {
return b.conn.AddMatchSignal(
dbus.WithMatchObjectPath(path),
dbus.WithMatchInterface(dbusPropertiesInterface),
dbus.WithMatchMember("PropertiesChanged"),
)
}
func (b *IWDBackend) handleStationAdded(path dbus.ObjectPath) bool {
if path == "" || path == b.stationPath {
return false
}
b.stationPath = path
if err := b.addStationSignalMatch(path); err != nil {
log.Warnf("Failed to add iwd station signal match for %s: %v", path, err)
}
if err := b.updateState(); err != nil {
log.Warnf("Failed to update iwd state after station appeared: %v", err)
}
return b.refreshWiFiNetworkState()
}
func (b *IWDBackend) handleStationRemoved(path dbus.ObjectPath) bool {
if path == "" || path != b.stationPath {
return false
}
b.stationPath = ""
b.stateMutex.Lock()
b.state.WiFiEnabled = false
b.state.WiFiConnected = false
b.state.WiFiSSID = ""
b.state.WiFiSignal = 0
b.state.NetworkStatus = StatusDisconnected
b.state.WiFiNetworks = nil
b.stateMutex.Unlock()
return true
}
func (b *IWDBackend) signalHandler(sigChan chan *dbus.Signal) {
defer b.sigWG.Done()
@@ -98,7 +136,13 @@ func (b *IWDBackend) signalHandler(sigChan chan *dbus.Signal) {
if sig.Name == dbusObjectManager+".InterfacesAdded" {
if len(sig.Body) >= 2 {
path, _ := sig.Body[0].(dbus.ObjectPath)
if interfaces, ok := sig.Body[1].(map[string]map[string]dbus.Variant); ok {
if _, ok := interfaces[iwdStationInterface]; ok {
if b.handleStationAdded(path) && b.onStateChange != nil {
b.onStateChange()
}
}
if _, ok := interfaces[iwdKnownNetworkInterface]; ok {
if b.refreshWiFiNetworkState() && b.onStateChange != nil {
b.onStateChange()
@@ -111,8 +155,15 @@ func (b *IWDBackend) signalHandler(sigChan chan *dbus.Signal) {
if sig.Name == dbusObjectManager+".InterfacesRemoved" {
if len(sig.Body) >= 2 {
path, _ := sig.Body[0].(dbus.ObjectPath)
if interfaces, ok := sig.Body[1].([]string); ok {
for _, iface := range interfaces {
if iface == iwdStationInterface {
if b.handleStationRemoved(path) && b.onStateChange != nil {
b.onStateChange()
}
break
}
if iface == iwdKnownNetworkInterface {
if b.refreshWiFiNetworkState() && b.onStateChange != nil {
b.onStateChange()
@@ -169,6 +169,41 @@ func TestIWDBackend_MapIwdDBusError(t *testing.T) {
}
}
func TestIWDBackend_ApplyManagedObjects_DeviceWithoutStation(t *testing.T) {
backend, _ := NewIWDBackend()
err := backend.applyManagedObjects(map[dbus.ObjectPath]map[string]map[string]dbus.Variant{
"/net/connman/iwd/0/1": {
iwdDeviceInterface: {
"Name": dbus.MakeVariant("wlan0"),
"Powered": dbus.MakeVariant(false),
},
},
})
assert.NoError(t, err)
assert.Equal(t, dbus.ObjectPath("/net/connman/iwd/0/1"), backend.devicePath)
assert.Empty(t, backend.stationPath)
state, err := backend.GetCurrentState()
assert.NoError(t, err)
assert.Equal(t, "wlan0", state.WiFiDevice)
assert.False(t, state.WiFiEnabled)
assert.False(t, state.WiFiConnected)
}
func TestIWDBackend_ApplyManagedObjects_NoDevice(t *testing.T) {
backend, _ := NewIWDBackend()
err := backend.applyManagedObjects(map[dbus.ObjectPath]map[string]map[string]dbus.Variant{
"/net/connman/iwd/0": {
iwdAdapterInterface: {},
},
})
assert.ErrorContains(t, err, "no WiFi device found")
}
func TestIWDSavedWiFiProfilesFromManagedObjects(t *testing.T) {
objects := map[dbus.ObjectPath]map[string]map[string]dbus.Variant{
"/net/connman/iwd/known_network/1": {