From fc25da30afa1fb4fb3e49acb8980c12ba0ba5bdb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 29 Jul 2024 20:44:07 -0700 Subject: [PATCH] manager/user: Move relevant methods to GpuPowerProfile1, update as specified --- com.steampowered.SteamOSManager1.Manager.xml | 21 ----- src/bin/steamosctl.rs | 24 +++--- src/manager/root.rs | 2 +- src/manager/user.rs | 80 +++++++++++++------- src/power.rs | 35 +++++---- src/proxy/manager.rs | 10 --- 6 files changed, 84 insertions(+), 88 deletions(-) diff --git a/com.steampowered.SteamOSManager1.Manager.xml b/com.steampowered.SteamOSManager1.Manager.xml index 437b22d..e7badba 100644 --- a/com.steampowered.SteamOSManager1.Manager.xml +++ b/com.steampowered.SteamOSManager1.Manager.xml @@ -138,27 +138,6 @@ --> - - - - - - diff --git a/src/bin/steamosctl.rs b/src/bin/steamosctl.rs index eb05bd0..09df163 100644 --- a/src/bin/steamosctl.rs +++ b/src/bin/steamosctl.rs @@ -14,8 +14,8 @@ use steamos_manager::hardware::FanControlState; use steamos_manager::power::{CPUScalingGovernor, GPUPerformanceLevel, GPUPowerProfile}; use steamos_manager::proxy::{ AmbientLightSensor1Proxy, CpuScaling1Proxy, FactoryReset1Proxy, FanControl1Proxy, - HdmiCec1Proxy, Manager2Proxy, ManagerProxy, Storage1Proxy, UpdateBios1Proxy, UpdateDock1Proxy, - WifiPowerManagement1Proxy, + GpuPowerProfile1Proxy, HdmiCec1Proxy, Manager2Proxy, ManagerProxy, Storage1Proxy, + UpdateBios1Proxy, UpdateDock1Proxy, WifiPowerManagement1Proxy, }; use steamos_manager::wifi::{WifiBackend, WifiDebugMode, WifiPowerManagement}; use zbus::fdo::PropertiesProxy; @@ -62,7 +62,7 @@ enum Commands { }, /// Get the GPU power profiles supported on this device - GetGPUPowerProfiles, + GetAvailableGPUPowerProfiles, /// Get the current GPU power profile GetGPUPowerProfile, @@ -250,17 +250,18 @@ async fn main() -> Result<()> { .set_cpu_scaling_governor(governor.to_string().as_str()) .await?; } - Commands::GetGPUPowerProfiles => { - let profiles = proxy.gpu_power_profiles().await?; + Commands::GetAvailableGPUPowerProfiles => { + let proxy = GpuPowerProfile1Proxy::new(&conn).await?; + let profiles = proxy.available_gpu_power_profiles().await?; println!("Profiles:\n"); - for key in profiles.keys().sorted() { - let name = &profiles[key]; - println!("{key}: {name}"); + for name in profiles.into_iter().sorted() { + println!("- {name}"); } } Commands::GetGPUPowerProfile => { + let proxy = GpuPowerProfile1Proxy::new(&conn).await?; let profile = proxy.gpu_power_profile().await?; - let profile_type = GPUPowerProfile::try_from(profile); + let profile_type = GPUPowerProfile::try_from(profile.as_str()); match profile_type { Ok(t) => { let name = t.to_string(); @@ -272,7 +273,10 @@ async fn main() -> Result<()> { } } Commands::SetGPUPowerProfile { profile } => { - proxy.set_gpu_power_profile(*profile as u32).await?; + let proxy = GpuPowerProfile1Proxy::new(&conn).await?; + proxy + .set_gpu_power_profile(profile.to_string().as_str()) + .await?; } Commands::SetGPUPerformanceLevel { level } => { proxy.set_gpu_performance_level(*level as u32).await?; diff --git a/src/manager/root.rs b/src/manager/root.rs index 5498c1b..037d071 100644 --- a/src/manager/root.rs +++ b/src/manager/root.rs @@ -184,7 +184,7 @@ impl SteamOSManager { .await } - async fn set_gpu_power_profile(&self, value: u32) -> fdo::Result<()> { + async fn set_gpu_power_profile(&self, value: &str) -> fdo::Result<()> { let profile = GPUPowerProfile::try_from(value).map_err(to_zbus_fdo_error)?; set_gpu_power_profile(profile) .await diff --git a/src/manager/user.rs b/src/manager/user.rs index 7631357..b43fcfa 100644 --- a/src/manager/user.rs +++ b/src/manager/user.rs @@ -7,7 +7,6 @@ */ use anyhow::Result; -use std::collections::HashMap; use tokio::sync::mpsc::{Sender, UnboundedSender}; use tokio::sync::oneshot; use tracing::error; @@ -22,9 +21,9 @@ use crate::error::{to_zbus_error, to_zbus_fdo_error, zbus_to_zbus_fdo}; use crate::hardware::{check_support, HardwareCurrentlySupported}; use crate::job::JobManagerCommand; use crate::power::{ - get_available_cpu_scaling_governors, get_cpu_scaling_governor, get_gpu_clocks, - get_gpu_clocks_range, get_gpu_performance_level, get_gpu_power_profile, get_gpu_power_profiles, - get_tdp_limit, + get_available_cpu_scaling_governors, get_available_gpu_power_profiles, + get_cpu_scaling_governor, get_gpu_clocks, get_gpu_clocks_range, get_gpu_performance_level, + get_gpu_power_profile, get_tdp_limit, }; use crate::wifi::{get_wifi_backend, get_wifi_power_management_state}; use crate::API_VERSION; @@ -111,6 +110,10 @@ struct FanControl1 { proxy: Proxy<'static>, } +struct GpuPowerProfile1 { + proxy: Proxy<'static>, +} + struct HdmiCec1 { hdmi_cec: HdmiCecControl<'static>, } @@ -157,30 +160,6 @@ impl SteamOSManager { API_VERSION } - #[zbus(property(emits_changed_signal = "false"))] - async fn gpu_power_profiles(&self) -> fdo::Result> { - get_gpu_power_profiles().await.map_err(to_zbus_fdo_error) - } - - #[zbus(property(emits_changed_signal = "false"))] - async fn gpu_power_profile(&self) -> fdo::Result { - match get_gpu_power_profile().await { - Ok(profile) => Ok(profile as u32), - Err(e) => { - error!("Error getting GPU power profile: {e}"); - Err(to_zbus_fdo_error(e)) - } - } - } - - #[zbus(property)] - async fn set_gpu_power_profile(&self, profile: u32) -> zbus::Result<()> { - self.proxy - .call("SetGpuPowerProfile", &(profile)) - .await - .map_err(to_zbus_error) - } - #[zbus(property(emits_changed_signal = "false"))] async fn gpu_performance_level(&self) -> fdo::Result { match get_gpu_performance_level().await { @@ -354,6 +333,38 @@ impl FanControl1 { } } +#[interface(name = "com.steampowered.SteamOSManager1.GpuPowerProfile1")] +impl GpuPowerProfile1 { + #[zbus(property(emits_changed_signal = "false"))] + async fn available_gpu_power_profiles(&self) -> fdo::Result> { + let (_, names): (Vec, Vec) = get_available_gpu_power_profiles() + .await + .map_err(to_zbus_fdo_error)? + .into_iter() + .unzip(); + Ok(names) + } + + #[zbus(property(emits_changed_signal = "false"))] + async fn gpu_power_profile(&self) -> fdo::Result { + match get_gpu_power_profile().await { + Ok(profile) => Ok(profile.to_string()), + Err(e) => { + error!("Error getting GPU power profile: {e}"); + Err(to_zbus_fdo_error(e)) + } + } + } + + #[zbus(property)] + async fn set_gpu_power_profile(&self, profile: &str) -> zbus::Result<()> { + self.proxy + .call("SetGpuPowerProfile", &(profile)) + .await + .map_err(to_zbus_error) + } +} + impl HdmiCec1 { async fn new(connection: &Connection) -> Result { let hdmi_cec = HdmiCecControl::new(connection).await?; @@ -482,6 +493,9 @@ pub(crate) async fn create_interfaces( let fan_control = FanControl1 { proxy: proxy.clone(), }; + let gpu_power_profile = GpuPowerProfile1 { + proxy: proxy.clone(), + }; let hdmi_cec = HdmiCec1::new(&session).await?; let manager2 = Manager2 { proxy: proxy.clone(), @@ -509,6 +523,7 @@ pub(crate) async fn create_interfaces( object_server.at(MANAGER_PATH, cpu_scaling).await?; object_server.at(MANAGER_PATH, factory_reset).await?; object_server.at(MANAGER_PATH, fan_control).await?; + object_server.at(MANAGER_PATH, gpu_power_profile).await?; object_server.at(MANAGER_PATH, hdmi_cec).await?; object_server.at(MANAGER_PATH, manager2).await?; object_server.at(MANAGER_PATH, storage).await?; @@ -621,6 +636,15 @@ mod test { .unwrap()); } + #[tokio::test] + async fn interface_matches_gpu_power_profile1() { + let test = start().await.expect("start"); + + assert!(test_interface_matches::(&test.connection) + .await + .unwrap()); + } + #[tokio::test] async fn interface_matches_hdmi_cec1() { let test = start().await.expect("start"); diff --git a/src/power.rs b/src/power.rs index 747e514..11d4cd5 100644 --- a/src/power.rs +++ b/src/power.rs @@ -8,7 +8,6 @@ use anyhow::{anyhow, bail, ensure, Result}; use lazy_static::lazy_static; use regex::Regex; -use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::str::FromStr; use strum::{Display, EnumString}; @@ -195,11 +194,11 @@ pub(crate) async fn get_gpu_power_profile() -> Result { bail!("Unable to determine current GPU power profile"); } -pub(crate) async fn get_gpu_power_profiles() -> Result> { +pub(crate) async fn get_available_gpu_power_profiles() -> Result> { let contents = read_gpu_sysfs_contents(GPU_POWER_PROFILE_SUFFIX).await?; let deck = is_deck().await?; - let mut map = HashMap::new(); + let mut map = Vec::new(); let lines = contents.lines(); for line in lines { let caps = GPU_POWER_PROFILE_REGEX.captures(line); @@ -216,13 +215,13 @@ pub(crate) async fn get_gpu_power_profiles() -> Result> { // the other profiles aren't correctly tuned for the hardware. if value == GPUPowerProfile::Capped as u32 || value == GPUPowerProfile::Uncapped as u32 { - map.insert(value, name.to_string()); + map.push((value, name.to_string())); } else { // Got unsupported value, so don't include it } } else { // Do basic validation to ensure our enum is up to date? - map.insert(value, name.to_string()); + map.push((value, name.to_string())); } } Ok(map) @@ -774,10 +773,10 @@ CCLK_RANGE in Core0: .await .expect("fake_model"); - let profiles = get_gpu_power_profiles().await.expect("get"); + let profiles = get_available_gpu_power_profiles().await.expect("get"); assert_eq!( profiles, - HashMap::from([ + &[ ( GPUPowerProfile::FullScreen as u32, String::from("3D_FULL_SCREEN") @@ -788,20 +787,20 @@ CCLK_RANGE in Core0: (GPUPowerProfile::Custom as u32, String::from("CUSTOM")), (GPUPowerProfile::Capped as u32, String::from("CAPPED")), (GPUPowerProfile::Uncapped as u32, String::from("UNCAPPED")) - ]) + ] ); fake_model(HardwareVariant::Jupiter) .await .expect("fake_model"); - let profiles = get_gpu_power_profiles().await.expect("get"); + let profiles = get_available_gpu_power_profiles().await.expect("get"); assert_eq!( profiles, - HashMap::from([ + &[ (GPUPowerProfile::Capped as u32, String::from("CAPPED")), (GPUPowerProfile::Uncapped as u32, String::from("UNCAPPED")) - ]) + ] ); } @@ -831,35 +830,35 @@ CCLK_RANGE in Core0: .await .expect("fake_model"); - let profiles = get_gpu_power_profiles().await.expect("get"); + let profiles = get_available_gpu_power_profiles().await.expect("get"); assert_eq!( profiles, - HashMap::from([ - (2, String::from("CGA")), + &[ ( GPUPowerProfile::FullScreen as u32, String::from("3D_FULL_SCREEN") ), + (2, String::from("CGA")), (GPUPowerProfile::Video as u32, String::from("VIDEO")), (GPUPowerProfile::VR as u32, String::from("VR")), (GPUPowerProfile::Compute as u32, String::from("COMPUTE")), (GPUPowerProfile::Custom as u32, String::from("CUSTOM")), (GPUPowerProfile::Capped as u32, String::from("CAPPED")), (GPUPowerProfile::Uncapped as u32, String::from("UNCAPPED")) - ]) + ] ); fake_model(HardwareVariant::Jupiter) .await .expect("fake_model"); - let profiles = get_gpu_power_profiles().await.expect("get"); + let profiles = get_available_gpu_power_profiles().await.expect("get"); assert_eq!( profiles, - HashMap::from([ + &[ (GPUPowerProfile::Capped as u32, String::from("CAPPED")), (GPUPowerProfile::Uncapped as u32, String::from("UNCAPPED")) - ]) + ] ); } diff --git a/src/proxy/manager.rs b/src/proxy/manager.rs index 68b02f0..d6f22a7 100644 --- a/src/proxy/manager.rs +++ b/src/proxy/manager.rs @@ -28,16 +28,6 @@ trait Manager { #[zbus(property)] fn set_gpu_performance_level(&self, value: u32) -> zbus::Result<()>; - /// GpuPowerProfile property - #[zbus(property)] - fn gpu_power_profile(&self) -> zbus::Result; - #[zbus(property)] - fn set_gpu_power_profile(&self, value: u32) -> zbus::Result<()>; - - /// GpuPowerProfiles property - #[zbus(property)] - fn gpu_power_profiles(&self) -> zbus::Result>; - /// ManualGpuClock property #[zbus(property)] fn manual_gpu_clock(&self) -> zbus::Result;