diff --git a/src/daemon/user.rs b/src/daemon/user.rs index 55e3908..80fd3d1 100644 --- a/src/daemon/user.rs +++ b/src/daemon/user.rs @@ -127,6 +127,11 @@ async fn create_connections( let (tdp_tx, rx) = unbounded_channel(); let tdp_service = TdpManagerService::new(rx, &system, &connection).await; + let tdp_tx = if tdp_service.is_ok() { + Some(tdp_tx) + } else { + None + }; create_interfaces(connection.clone(), system.clone(), channel, jm_tx, tdp_tx).await?; diff --git a/src/manager/user.rs b/src/manager/user.rs index 3546379..5a486a8 100644 --- a/src/manager/user.rs +++ b/src/manager/user.rs @@ -29,7 +29,7 @@ use crate::power::{ get_available_cpu_scaling_governors, get_available_gpu_performance_levels, get_available_gpu_power_profiles, get_available_platform_profiles, get_cpu_scaling_governor, get_gpu_clocks, get_gpu_clocks_range, get_gpu_performance_level, get_gpu_power_profile, - get_max_charge_level, get_platform_profile, tdp_limit_manager, TdpManagerCommand, + get_max_charge_level, get_platform_profile, TdpManagerCommand, }; use crate::screenreader::OrcaManager; use crate::wifi::{ @@ -151,7 +151,7 @@ struct Manager2 { struct PerformanceProfile1 { proxy: Proxy<'static>, - tdp_limit_manager: UnboundedSender, + tdp_limit_manager: Option>, } struct ScreenReader0 { @@ -588,25 +588,27 @@ impl PerformanceProfile1 { let _: () = self.proxy.call("SetPerformanceProfile", &(profile)).await?; self.performance_profile_changed(&ctx).await?; let connection = connection.clone(); - let manager = self.tdp_limit_manager.clone(); - let _ = manager.send(TdpManagerCommand::UpdateDownloadMode); - tokio::spawn(async move { - let (tx, rx) = oneshot::channel(); - manager.send(TdpManagerCommand::IsActive(tx))?; - if rx.await?? { - let tdp_limit = TdpLimit1 { manager }; - connection - .object_server() - .at(MANAGER_PATH, tdp_limit) - .await?; - } else { - connection - .object_server() - .remove::(MANAGER_PATH) - .await?; - } - Ok::<(), Error>(()) - }); + if let Some(manager) = self.tdp_limit_manager.as_ref() { + let manager = manager.clone(); + let _ = manager.send(TdpManagerCommand::UpdateDownloadMode); + tokio::spawn(async move { + let (tx, rx) = oneshot::channel(); + manager.send(TdpManagerCommand::IsActive(tx))?; + if rx.await?? { + let tdp_limit = TdpLimit1 { manager }; + connection + .object_server() + .at(MANAGER_PATH, tdp_limit) + .await?; + } else { + connection + .object_server() + .remove::(MANAGER_PATH) + .await?; + } + Ok::<(), Error>(()) + }); + } Ok(()) } @@ -854,7 +856,7 @@ async fn create_config_interfaces( proxy: &Proxy<'static>, object_server: &ObjectServer, job_manager: &UnboundedSender, - tdp_manager: &UnboundedSender, + tdp_manager: Option>, ) -> Result<()> { let Some(config) = platform_config().await? else { return Ok(()); @@ -891,9 +893,9 @@ async fn create_config_interfaces( object_server.at(MANAGER_PATH, fan_control).await?; } - if let Ok(manager) = tdp_limit_manager().await { + if let Some(manager) = tdp_manager { let low_power_mode = LowPowerMode1 { - manager: tdp_manager.clone(), + manager: manager.clone(), }; if config .tdp_limit @@ -903,12 +905,17 @@ async fn create_config_interfaces( { object_server.at(MANAGER_PATH, low_power_mode).await?; } - if manager.is_active().await? { - let tdp_limit = TdpLimit1 { - manager: tdp_manager.clone(), - }; - object_server.at(MANAGER_PATH, tdp_limit).await?; - } + + let object_server = object_server.clone(); + tokio::spawn(async move { + let (tx, rx) = oneshot::channel(); + manager.send(TdpManagerCommand::IsActive(tx))?; + if rx.await?? { + let tdp_limit = TdpLimit1 { manager }; + object_server.at(MANAGER_PATH, tdp_limit).await?; + } + Ok::<(), Error>(()) + }); } if let Some(ref config) = config.performance_profile { @@ -954,7 +961,7 @@ pub(crate) async fn create_interfaces( system: Connection, daemon: Sender, job_manager: UnboundedSender, - tdp_manager: UnboundedSender, + tdp_manager: Option>, ) -> Result<()> { let proxy = Builder::::new(&system) .destination("com.steampowered.SteamOSManager1")? @@ -1000,7 +1007,7 @@ pub(crate) async fn create_interfaces( let object_server = session.object_server(); object_server.at(MANAGER_PATH, manager).await?; - create_config_interfaces(&proxy, object_server, &job_manager, &tdp_manager).await?; + create_config_interfaces(&proxy, object_server, &job_manager, tdp_manager).await?; if device_type().await.unwrap_or_default() == DeviceType::SteamDeck { object_server.at(MANAGER_PATH, als).await?; @@ -1073,7 +1080,7 @@ mod test { use std::os::unix::fs::PermissionsExt; use std::time::Duration; use tokio::fs::{set_permissions, write}; - use tokio::sync::mpsc::unbounded_channel; + use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver}; use tokio::time::sleep; use zbus::object_server::Interface; use zbus::Connection; @@ -1081,6 +1088,8 @@ mod test { struct TestHandle { _handle: testing::TestHandle, connection: Connection, + _rx_job: UnboundedReceiver, + rx_tdp: Option>, } fn all_config() -> Option { @@ -1114,8 +1123,19 @@ mod test { async fn start(mut platform_config: Option) -> Result { let mut handle = testing::start(); let (tx_ctx, _rx_ctx) = channel::(); - let (tx_job, _rx_job) = unbounded_channel::(); - let (tx_tdp, _rx_tdp) = unbounded_channel::(); + let (tx_job, rx_job) = unbounded_channel::(); + let (tx_tdp, rx_tdp) = { + if platform_config + .as_ref() + .and_then(|config| config.tdp_limit.as_ref()) + .is_some() + { + let (tx_tdp, rx_tdp) = unbounded_channel::(); + (Some(tx_tdp), Some(rx_tdp)) + } else { + (None, None) + } + }; if let Some(ref mut config) = platform_config { config.set_test_paths(); @@ -1165,6 +1185,8 @@ mod test { Ok(TestHandle { _handle: handle, connection, + _rx_job: rx_job, + rx_tdp, }) } @@ -1289,7 +1311,15 @@ mod test { #[tokio::test] async fn interface_matches_tdp_limit1() { - let test = start(all_config()).await.expect("start"); + let mut test = start(all_config()).await.expect("start"); + + let TdpManagerCommand::IsActive(reply) = + test.rx_tdp.as_mut().unwrap().recv().await.unwrap() + else { + panic!(); + }; + reply.send(Ok(true)).unwrap(); + sleep(Duration::from_millis(1)).await; assert!(test_interface_matches::(&test.connection) .await @@ -1303,6 +1333,21 @@ mod test { assert!(test_interface_missing::(&test.connection).await); } + #[tokio::test] + async fn interface_inactive_tdp_limit1() { + let mut test = start(all_config()).await.expect("start"); + + let TdpManagerCommand::IsActive(reply) = + test.rx_tdp.as_mut().unwrap().recv().await.unwrap() + else { + panic!(); + }; + reply.send(Ok(false)).unwrap(); + sleep(Duration::from_millis(1)).await; + + assert!(test_interface_missing::(&test.connection).await); + } + #[tokio::test] async fn interface_matches_hdmi_cec1() { let test = start(all_config()).await.expect("start");