mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-05 14:10:34 -04:00
power: Add interface for accessing platform-profiles
This commit is contained in:
parent
b26cc0f45c
commit
45edfe2c7c
10 changed files with 305 additions and 12 deletions
|
@ -230,6 +230,38 @@
|
|||
|
||||
</interface>
|
||||
|
||||
<!--
|
||||
com.steampowered.SteamOSManager1.PerformanceProfile1
|
||||
@short_description: Optional interface for platform power properties.
|
||||
-->
|
||||
<interface name="com.steampowered.SteamOSManager1.PerformanceProfile1">
|
||||
|
||||
<!--
|
||||
AvailablePerformanceProfiles:
|
||||
|
||||
Enumerate the supported performance profiles available on the system.
|
||||
|
||||
A list of supported profiles.
|
||||
-->
|
||||
<property name="AvailablePerformanceProfiles" type="as" access="read"/>
|
||||
|
||||
<!--
|
||||
PerformanceProfile:
|
||||
|
||||
The current perrormance profile. Valid values come from the
|
||||
AvailablePerformanceProfiles property.
|
||||
-->
|
||||
<property name="PerformanceProfile" type="s" access="readwrite"/>
|
||||
|
||||
<!--
|
||||
SuggestedDefaultPerformanceProfile:
|
||||
|
||||
The suggested default performance profile for the system.
|
||||
-->
|
||||
<property name="SuggestedDefaultPerformanceProfile" type="s" access="read"/>
|
||||
|
||||
</interface>
|
||||
|
||||
<!--
|
||||
com.steampowered.SteamOSManager1.Storage1
|
||||
@short_description: Optional interface for managing storage devices
|
||||
|
|
3
data/platforms/legion-go-s.toml
Normal file
3
data/platforms/legion-go-s.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
[performance_profile]
|
||||
platform_profile_name = "lenovo-wmi-gamezone"
|
||||
suggested_default = "custom"
|
|
@ -16,8 +16,8 @@ use steamos_manager::power::{CPUScalingGovernor, GPUPerformanceLevel, GPUPowerPr
|
|||
use steamos_manager::proxy::{
|
||||
AmbientLightSensor1Proxy, BatteryChargeLimit1Proxy, CpuScaling1Proxy, FactoryReset1Proxy,
|
||||
FanControl1Proxy, GpuPerformanceLevel1Proxy, GpuPowerProfile1Proxy, HdmiCec1Proxy,
|
||||
Manager2Proxy, Storage1Proxy, TdpLimit1Proxy, UpdateBios1Proxy, UpdateDock1Proxy,
|
||||
WifiDebug1Proxy, WifiDebugDump1Proxy, WifiPowerManagement1Proxy,
|
||||
Manager2Proxy, PerformanceProfile1Proxy, Storage1Proxy, TdpLimit1Proxy, UpdateBios1Proxy,
|
||||
UpdateDock1Proxy, WifiDebug1Proxy, WifiDebugDump1Proxy, WifiPowerManagement1Proxy,
|
||||
};
|
||||
use steamos_manager::wifi::{WifiBackend, WifiDebugMode, WifiPowerManagement};
|
||||
use zbus::fdo::{IntrospectableProxy, PropertiesProxy};
|
||||
|
@ -111,6 +111,21 @@ enum Commands {
|
|||
/// Get the minimum allowed TDP limit
|
||||
GetTDPLimitMin,
|
||||
|
||||
/// Get the performance profiles supported on this device
|
||||
GetAvailablePerformanceProfiles,
|
||||
|
||||
/// Get the current performance profile
|
||||
GetPerformanceProfile,
|
||||
|
||||
/// Set the performance profile
|
||||
SetPerformanceProfile {
|
||||
/// Valid profiles can be found using get-available-performance-profiles.
|
||||
profile: String,
|
||||
},
|
||||
|
||||
/// Get the suggested default performance profile
|
||||
SuggestedDefaultPerformanceProfile,
|
||||
|
||||
/// Set the Wi-Fi backend, if possible
|
||||
SetWifiBackend {
|
||||
/// Supported backends are `iwd`, `wpa_supplicant`
|
||||
|
@ -348,6 +363,28 @@ async fn main() -> Result<()> {
|
|||
let value = proxy.manual_gpu_clock_min().await?;
|
||||
println!("Manual GPU Clock Min: {value}");
|
||||
}
|
||||
Commands::GetAvailablePerformanceProfiles => {
|
||||
let proxy = PerformanceProfile1Proxy::new(&conn).await?;
|
||||
let profiles = proxy.available_performance_profiles().await?;
|
||||
println!("Profiles:\n");
|
||||
for name in profiles.into_iter().sorted() {
|
||||
println!("- {name}");
|
||||
}
|
||||
}
|
||||
Commands::GetPerformanceProfile => {
|
||||
let proxy = PerformanceProfile1Proxy::new(&conn).await?;
|
||||
let profile = proxy.performance_profile().await?;
|
||||
println!("Performance Profile: {profile}");
|
||||
}
|
||||
Commands::SetPerformanceProfile { profile } => {
|
||||
let proxy = PerformanceProfile1Proxy::new(&conn).await?;
|
||||
proxy.set_performance_profile(profile.as_str()).await?;
|
||||
}
|
||||
Commands::SuggestedDefaultPerformanceProfile => {
|
||||
let proxy = PerformanceProfile1Proxy::new(&conn).await?;
|
||||
let profile = proxy.suggested_default_performance_profile().await?;
|
||||
println!("Suggested Default Performance Profile: {profile}");
|
||||
}
|
||||
Commands::SetTDPLimit { limit } => {
|
||||
let proxy = TdpLimit1Proxy::new(&conn).await?;
|
||||
proxy.set_tdp_limit(*limit).await?;
|
||||
|
|
|
@ -390,6 +390,7 @@ pub mod test {
|
|||
tdp_limit: None,
|
||||
gpu_clocks: None,
|
||||
battery_charge_limit: None,
|
||||
performance_profile: None,
|
||||
}));
|
||||
|
||||
let fan_control = FanControl::new(connection);
|
||||
|
|
|
@ -27,7 +27,8 @@ use crate::job::JobManager;
|
|||
use crate::platform::platform_config;
|
||||
use crate::power::{
|
||||
set_cpu_scaling_governor, set_gpu_clocks, set_gpu_performance_level, set_gpu_power_profile,
|
||||
set_max_charge_level, set_tdp_limit, CPUScalingGovernor, GPUPerformanceLevel, GPUPowerProfile,
|
||||
set_max_charge_level, set_platform_profile, set_tdp_limit, CPUScalingGovernor,
|
||||
GPUPerformanceLevel, GPUPowerProfile,
|
||||
};
|
||||
use crate::process::{run_script, script_output};
|
||||
use crate::wifi::{
|
||||
|
@ -429,6 +430,19 @@ impl SteamOSManager {
|
|||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
async fn set_performance_profile(&self, profile: &str) -> fdo::Result<()> {
|
||||
let config = platform_config().await.map_err(to_zbus_fdo_error)?;
|
||||
let config = config
|
||||
.as_ref()
|
||||
.and_then(|config| config.performance_profile.as_ref())
|
||||
.ok_or(fdo::Error::Failed(String::from(
|
||||
"No performance platform-profile configured",
|
||||
)))?;
|
||||
set_platform_profile(&config.platform_profile_name, profile)
|
||||
.await
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
/// A version property.
|
||||
#[zbus(property(emits_changed_signal = "const"))]
|
||||
async fn version(&self) -> u32 {
|
||||
|
|
|
@ -26,9 +26,9 @@ use crate::job::JobManagerCommand;
|
|||
use crate::platform::platform_config;
|
||||
use crate::power::{
|
||||
get_available_cpu_scaling_governors, get_available_gpu_performance_levels,
|
||||
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_max_charge_level,
|
||||
get_tdp_limit, get_tdp_limit_range,
|
||||
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, get_tdp_limit, get_tdp_limit_range,
|
||||
};
|
||||
use crate::wifi::{
|
||||
get_wifi_backend, get_wifi_power_management_state, list_wifi_interfaces, WifiBackend,
|
||||
|
@ -143,6 +143,10 @@ struct Manager2 {
|
|||
channel: Sender<Command>,
|
||||
}
|
||||
|
||||
struct PerformanceProfile1 {
|
||||
proxy: Proxy<'static>,
|
||||
}
|
||||
|
||||
struct Storage1 {
|
||||
proxy: Proxy<'static>,
|
||||
job_manager: UnboundedSender<JobManagerCommand>,
|
||||
|
@ -456,6 +460,54 @@ impl Manager2 {
|
|||
}
|
||||
}
|
||||
|
||||
#[interface(name = "com.steampowered.SteamOSManager1.PerformanceProfile1")]
|
||||
impl PerformanceProfile1 {
|
||||
#[zbus(property(emits_changed_signal = "false"))]
|
||||
async fn available_performance_profiles(&self) -> fdo::Result<Vec<String>> {
|
||||
let config = platform_config().await.map_err(to_zbus_fdo_error)?;
|
||||
let config = config
|
||||
.as_ref()
|
||||
.and_then(|config| config.performance_profile.as_ref())
|
||||
.ok_or(fdo::Error::Failed(String::from(
|
||||
"No performance platform-profile configured",
|
||||
)))?;
|
||||
get_available_platform_profiles(&config.platform_profile_name)
|
||||
.await
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
#[zbus(property(emits_changed_signal = "false"))]
|
||||
async fn performance_profile(&self) -> fdo::Result<String> {
|
||||
let config = platform_config().await.map_err(to_zbus_fdo_error)?;
|
||||
let config = config
|
||||
.as_ref()
|
||||
.and_then(|config| config.performance_profile.as_ref())
|
||||
.ok_or(fdo::Error::Failed(String::from(
|
||||
"No performance platform-profile configured",
|
||||
)))?;
|
||||
get_platform_profile(&config.platform_profile_name)
|
||||
.await
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn set_performance_profile(&self, profile: &str) -> zbus::Result<()> {
|
||||
self.proxy.call("SetPerformanceProfile", &(profile)).await
|
||||
}
|
||||
|
||||
#[zbus(property(emits_changed_signal = "const"))]
|
||||
async fn suggested_default_performance_profile(&self) -> fdo::Result<String> {
|
||||
let config = platform_config().await.map_err(to_zbus_fdo_error)?;
|
||||
let config = config
|
||||
.as_ref()
|
||||
.and_then(|config| config.performance_profile.as_ref())
|
||||
.ok_or(fdo::Error::Failed(String::from(
|
||||
"No performance platform-profile configured",
|
||||
)))?;
|
||||
Ok(config.suggested_default.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[interface(name = "com.steampowered.SteamOSManager1.Storage1")]
|
||||
impl Storage1 {
|
||||
async fn format_device(
|
||||
|
@ -591,6 +643,9 @@ async fn create_config_interfaces(
|
|||
let fan_control = FanControl1 {
|
||||
proxy: proxy.clone(),
|
||||
};
|
||||
let performance_profile = PerformanceProfile1 {
|
||||
proxy: proxy.clone(),
|
||||
};
|
||||
let storage = Storage1 {
|
||||
proxy: proxy.clone(),
|
||||
job_manager: job_manager.clone(),
|
||||
|
@ -612,6 +667,16 @@ async fn create_config_interfaces(
|
|||
object_server.at(MANAGER_PATH, fan_control).await?;
|
||||
}
|
||||
|
||||
if let Some(ref config) = config.performance_profile {
|
||||
if !get_available_platform_profiles(&config.platform_profile_name)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.is_empty()
|
||||
{
|
||||
object_server.at(MANAGER_PATH, performance_profile).await?;
|
||||
}
|
||||
}
|
||||
|
||||
if config.storage.is_some() {
|
||||
object_server.at(MANAGER_PATH, storage).await?;
|
||||
}
|
||||
|
@ -756,8 +821,8 @@ mod test {
|
|||
use crate::hardware::test::fake_model;
|
||||
use crate::hardware::SteamDeckVariant;
|
||||
use crate::platform::{
|
||||
BatteryChargeLimitConfig, PlatformConfig, RangeConfig, ResetConfig, ScriptConfig,
|
||||
ServiceConfig, StorageConfig,
|
||||
BatteryChargeLimitConfig, PerformanceProfileConfig, PlatformConfig, RangeConfig,
|
||||
ResetConfig, ScriptConfig, ServiceConfig, StorageConfig,
|
||||
};
|
||||
use crate::systemd::test::{MockManager, MockUnit};
|
||||
use crate::{path, power, testing};
|
||||
|
@ -791,6 +856,10 @@ mod test {
|
|||
hwmon_name: String::from("steamdeck_hwmon"),
|
||||
attribute: String::from("max_battery_charge_level"),
|
||||
}),
|
||||
performance_profile: Some(PerformanceProfileConfig {
|
||||
platform_profile_name: String::from("power-driver"),
|
||||
suggested_default: String::from("balanced"),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -989,6 +1058,24 @@ mod test {
|
|||
.unwrap());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn interface_matches_performance_profile1() {
|
||||
let test = start(all_config()).await.expect("start");
|
||||
|
||||
assert!(
|
||||
test_interface_matches::<PerformanceProfile1>(&test.connection)
|
||||
.await
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn interface_missing_performance_profile1() {
|
||||
let test = start(None).await.expect("start");
|
||||
|
||||
assert!(test_interface_missing::<PerformanceProfile1>(&test.connection).await);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn interface_matches_storage1() {
|
||||
let test = start(all_config()).await.expect("start");
|
||||
|
|
|
@ -34,6 +34,7 @@ pub(crate) struct PlatformConfig {
|
|||
pub tdp_limit: Option<RangeConfig<u32>>,
|
||||
pub gpu_clocks: Option<RangeConfig<u32>>,
|
||||
pub battery_charge_limit: Option<BatteryChargeLimitConfig>,
|
||||
pub performance_profile: Option<PerformanceProfileConfig>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Debug)]
|
||||
|
@ -113,6 +114,12 @@ pub(crate) struct BatteryChargeLimitConfig {
|
|||
pub attribute: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Debug)]
|
||||
pub(crate) struct PerformanceProfileConfig {
|
||||
pub suggested_default: String,
|
||||
pub platform_profile_name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Deserialize, Debug)]
|
||||
pub(crate) struct FormatDeviceConfig {
|
||||
pub script: PathBuf,
|
||||
|
@ -139,6 +146,7 @@ impl PlatformConfig {
|
|||
async fn load() -> Result<Option<PlatformConfig>> {
|
||||
let platform = match device_type().await? {
|
||||
DeviceType::SteamDeck => "jupiter",
|
||||
DeviceType::LegionGoS => "legion-go-s",
|
||||
_ => return Ok(None),
|
||||
};
|
||||
let config = read_to_string(format!(
|
||||
|
|
82
src/power.rs
82
src/power.rs
|
@ -37,6 +37,8 @@ const GPU_CLOCK_LEVELS_SUFFIX: &str = "device/pp_dpm_sclk";
|
|||
const CPU_SCALING_GOVERNOR_SUFFIX: &str = "scaling_governor";
|
||||
const CPU_SCALING_AVAILABLE_GOVERNORS_SUFFIX: &str = "scaling_available_governors";
|
||||
|
||||
const PLATFORM_PROFILE_PREFIX: &str = "/sys/class/platform-profile";
|
||||
|
||||
const TDP_LIMIT1: &str = "power1_cap";
|
||||
const TDP_LIMIT2: &str = "power2_cap";
|
||||
|
||||
|
@ -346,24 +348,32 @@ pub(crate) async fn get_gpu_clocks() -> Result<u32> {
|
|||
Ok(0)
|
||||
}
|
||||
|
||||
async fn find_hwmon(hwmon: &str) -> Result<PathBuf> {
|
||||
let mut dir = fs::read_dir(path(HWMON_PREFIX)).await?;
|
||||
async fn find_sysdir(prefix: impl AsRef<Path>, expected: &str) -> Result<PathBuf> {
|
||||
let mut dir = fs::read_dir(prefix.as_ref()).await?;
|
||||
loop {
|
||||
let base = match dir.next_entry().await? {
|
||||
Some(entry) => entry.path(),
|
||||
None => bail!("hwmon not found"),
|
||||
None => bail!("prefix not found"),
|
||||
};
|
||||
let file_name = base.join("name");
|
||||
let name = fs::read_to_string(file_name.as_path())
|
||||
.await?
|
||||
.trim()
|
||||
.to_string();
|
||||
if name == hwmon {
|
||||
if name == expected {
|
||||
return Ok(base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn find_hwmon(hwmon: &str) -> Result<PathBuf> {
|
||||
find_sysdir(path(HWMON_PREFIX), hwmon).await
|
||||
}
|
||||
|
||||
async fn find_platform_profile(name: &str) -> Result<PathBuf> {
|
||||
find_sysdir(path(PLATFORM_PROFILE_PREFIX), name).await
|
||||
}
|
||||
|
||||
pub(crate) async fn get_tdp_limit() -> Result<u32> {
|
||||
let base = find_hwmon(GPU_HWMON_NAME).await?;
|
||||
let power1cap = fs::read_to_string(base.join(TDP_LIMIT1)).await?;
|
||||
|
@ -435,6 +445,33 @@ pub(crate) async fn set_max_charge_level(limit: i32) -> Result<()> {
|
|||
.inspect_err(|message| error!("Error writing to sysfs file: {message}"))
|
||||
}
|
||||
|
||||
pub(crate) async fn get_available_platform_profiles(name: &str) -> Result<Vec<String>> {
|
||||
let base = find_platform_profile(name).await?;
|
||||
Ok(fs::read_to_string(base.join("choices"))
|
||||
.await
|
||||
.map_err(|message| anyhow!("Error reading sysfs: {message}"))?
|
||||
.trim()
|
||||
.split(' ')
|
||||
.map(ToString::to_string)
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub(crate) async fn get_platform_profile(name: &str) -> Result<String> {
|
||||
let base = find_platform_profile(name).await?;
|
||||
Ok(fs::read_to_string(base.join("profile"))
|
||||
.await
|
||||
.map_err(|message| anyhow!("Error reading sysfs: {message}"))?
|
||||
.trim()
|
||||
.to_string())
|
||||
}
|
||||
|
||||
pub(crate) async fn set_platform_profile(name: &str, profile: &str) -> Result<()> {
|
||||
let base = find_platform_profile(name).await?;
|
||||
fs::write(base.join("profile"), profile.as_bytes())
|
||||
.await
|
||||
.map_err(|message| anyhow!("Error writing to sysfs: {message}"))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test {
|
||||
use super::*;
|
||||
|
@ -484,6 +521,11 @@ pub(crate) mod test {
|
|||
|
||||
write(base.join("max_battery_charge_level"), "10\n").await?;
|
||||
|
||||
let base = path(PLATFORM_PROFILE_PREFIX).join("platform-profile0");
|
||||
create_dir_all(&base).await?;
|
||||
write_synced(base.join("name"), b"power-driver\n").await?;
|
||||
write_synced(base.join("choices"), b"a b c\n").await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1140,4 +1182,36 @@ CCLK_RANGE in Core0:
|
|||
assert!(set_max_charge_level(101).await.is_err());
|
||||
assert!(set_max_charge_level(-1).await.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_available_performance_profiles() {
|
||||
let _h = testing::start();
|
||||
|
||||
assert!(get_available_platform_profiles("power-driver")
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
let base = path(PLATFORM_PROFILE_PREFIX).join("platform-profile0");
|
||||
create_dir_all(&base).await.unwrap();
|
||||
assert!(get_available_platform_profiles("power-driver")
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
write_synced(base.join("name"), b"power-driver\n")
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(get_available_platform_profiles("power-driver")
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
write_synced(base.join("choices"), b"a b c\n")
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
get_available_platform_profiles("power-driver")
|
||||
.await
|
||||
.unwrap(),
|
||||
&["a", "b", "c"]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ mod gpu_performance_level1;
|
|||
mod gpu_power_profile1;
|
||||
mod hdmi_cec1;
|
||||
mod manager2;
|
||||
mod performance_profile1;
|
||||
mod storage1;
|
||||
mod tdp_limit1;
|
||||
mod update_bios1;
|
||||
|
@ -39,6 +40,7 @@ pub use crate::proxy::gpu_performance_level1::GpuPerformanceLevel1Proxy;
|
|||
pub use crate::proxy::gpu_power_profile1::GpuPowerProfile1Proxy;
|
||||
pub use crate::proxy::hdmi_cec1::HdmiCec1Proxy;
|
||||
pub use crate::proxy::manager2::Manager2Proxy;
|
||||
pub use crate::proxy::performance_profile1::PerformanceProfile1Proxy;
|
||||
pub use crate::proxy::storage1::Storage1Proxy;
|
||||
pub use crate::proxy::tdp_limit1::TdpLimit1Proxy;
|
||||
pub use crate::proxy::update_bios1::UpdateBios1Proxy;
|
||||
|
|
35
src/proxy/performance_profile1.rs
Normal file
35
src/proxy/performance_profile1.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
//! # D-Bus interface proxy for: `com.steampowered.SteamOSManager1.PerformanceProfile1`
|
||||
//!
|
||||
//! This code was generated by `zbus-xmlgen` `5.1.0` from D-Bus introspection data.
|
||||
//! Source: `com.steampowered.SteamOSManager1.xml`.
|
||||
//!
|
||||
//! You may prefer to adapt it, instead of using it verbatim.
|
||||
//!
|
||||
//! More information can be found in the [Writing a client proxy] section of the zbus
|
||||
//! documentation.
|
||||
//!
|
||||
//!
|
||||
//! [Writing a client proxy]: https://dbus2.github.io/zbus/client.html
|
||||
//! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces,
|
||||
use zbus::proxy;
|
||||
#[proxy(
|
||||
interface = "com.steampowered.SteamOSManager1.PerformanceProfile1",
|
||||
default_service = "com.steampowered.SteamOSManager1",
|
||||
default_path = "/com/steampowered/SteamOSManager1",
|
||||
assume_defaults = true
|
||||
)]
|
||||
pub trait PerformanceProfile1 {
|
||||
/// AvailablePerformanceProfiles property
|
||||
#[zbus(property)]
|
||||
fn available_performance_profiles(&self) -> zbus::Result<Vec<String>>;
|
||||
|
||||
/// PerformanceProfile property
|
||||
#[zbus(property)]
|
||||
fn performance_profile(&self) -> zbus::Result<String>;
|
||||
#[zbus(property)]
|
||||
fn set_performance_profile(&self, value: &str) -> zbus::Result<()>;
|
||||
|
||||
/// SuggestedDefaultPerformanceProfile property
|
||||
#[zbus(property)]
|
||||
fn suggested_default_performance_profile(&self) -> zbus::Result<String>;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue