From 18b0560d60bda4d594fd43a1db9bdbfc8fb9122b Mon Sep 17 00:00:00 2001 From: akrm al-hakimi Date: Tue, 17 Mar 2026 18:55:51 -0400 Subject: [PATCH] feat(#283): expose `WirelessHardwareEnabled` through API --- nmrs/src/api/network_manager.rs | 8 +++++++- nmrs/src/core/device.rs | 6 ++++++ nmrs/src/dbus/main_nm.rs | 4 ++++ nmrs/tests/integration_test.rs | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/nmrs/src/api/network_manager.rs b/nmrs/src/api/network_manager.rs index 025c0b14..daac7032 100644 --- a/nmrs/src/api/network_manager.rs +++ b/nmrs/src/api/network_manager.rs @@ -13,7 +13,7 @@ use crate::core::connection_settings::{ }; use crate::core::device::{ is_connecting, list_bluetooth_devices, list_devices, set_wifi_enabled, wait_for_wifi_ready, - wifi_enabled, + wifi_enabled, wifi_hardware_enabled, }; use crate::core::scan::{current_network, list_networks, scan_networks}; use crate::core::vpn::{connect_vpn, disconnect_vpn, get_vpn_info, list_vpn_connections}; @@ -424,6 +424,12 @@ impl NetworkManager { set_wifi_enabled(&self.conn, value).await } + /// Returns whether wireless hardware is currently enabled. + /// Reflects rfkill state which helps check if the radio is enabled or blocked. + pub async fn wifi_hardware_enabled(&self) -> Result { + wifi_hardware_enabled(&self.conn).await + } + /// Waits for a Wi-Fi device to become ready (disconnected or activated). pub async fn wait_for_wifi_ready(&self) -> Result<()> { wait_for_wifi_ready(&self.conn).await diff --git a/nmrs/src/core/device.rs b/nmrs/src/core/device.rs index ecf34e2b..e67e93a0 100644 --- a/nmrs/src/core/device.rs +++ b/nmrs/src/core/device.rs @@ -278,6 +278,12 @@ pub(crate) async fn wifi_enabled(conn: &Connection) -> Result { Ok(nm.wireless_enabled().await?) } +/// Returns whether wireless hardware is enabled. +pub(crate) async fn wifi_hardware_enabled(conn: &Connection) -> Result { + let nm = NMProxy::new(conn).await?; + Ok(nm.wireless_hardware_enabled().await?) +} + #[cfg(test)] mod tests { use super::*; diff --git a/nmrs/src/dbus/main_nm.rs b/nmrs/src/dbus/main_nm.rs index b9ead63d..818877e8 100644 --- a/nmrs/src/dbus/main_nm.rs +++ b/nmrs/src/dbus/main_nm.rs @@ -25,6 +25,10 @@ pub trait NM { #[zbus(property)] fn set_wireless_enabled(&self, value: bool) -> zbus::Result<()>; + /// Whether wireless hardware is enabled. + #[zbus(property)] + fn wireless_hardware_enabled(&self) -> zbus::Result; + /// Paths to all active connections. #[zbus(property)] fn active_connections(&self) -> zbus::Result>; diff --git a/nmrs/tests/integration_test.rs b/nmrs/tests/integration_test.rs index 5e3758a0..d2ddb992 100644 --- a/nmrs/tests/integration_test.rs +++ b/nmrs/tests/integration_test.rs @@ -141,6 +141,23 @@ async fn test_wifi_enabled_get_set() { ); } +#[tokio::test] +async fn test_wifi_hardware_enabled() { + require_networkmanager!(); + + let nm = NetworkManager::new() + .await + .expect("Failed to connect to NetworkManager"); + + require_wifi!(&nm); + + // Read-only property — just verify the call succeeds + let _ = nm + .wifi_hardware_enabled() + .await + .expect("Failed to get WiFi hardware enabled state"); +} + /// Test waiting for WiFi to be ready #[tokio::test] async fn test_wait_for_wifi_ready() {