mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-04 13:46:58 -04:00
platform: Split out DeviceConfig from PlatformConfig
This commit is contained in:
parent
d5d2d2c9a3
commit
e3ce1853e9
12 changed files with 269 additions and 179 deletions
4
Makefile
4
Makefile
|
@ -24,9 +24,11 @@ install: target/release/steamos-manager target/release/steamosctl
|
||||||
|
|
||||||
install -Ds -m755 "target/release/steamos-manager" "$(DESTDIR)/usr/lib/steamos-manager"
|
install -Ds -m755 "target/release/steamos-manager" "$(DESTDIR)/usr/lib/steamos-manager"
|
||||||
install -D -m755 "target/release/steamosctl" "$(DESTDIR)/usr/bin/steamosctl"
|
install -D -m755 "target/release/steamosctl" "$(DESTDIR)/usr/bin/steamosctl"
|
||||||
install -D -m644 -t "$(DESTDIR)/usr/share/steamos-manager/platforms" "data/platforms/"*
|
install -D -m644 -t "$(DESTDIR)/usr/share/steamos-manager/devices" "data/devices/"*
|
||||||
install -D -m644 LICENSE "$(DESTDIR)/usr/share/licenses/steamos-manager/LICENSE"
|
install -D -m644 LICENSE "$(DESTDIR)/usr/share/licenses/steamos-manager/LICENSE"
|
||||||
|
|
||||||
|
install -m644 "data/platform.toml" "$(DESTDIR)/usr/share/steamos-manager/"
|
||||||
|
|
||||||
install -m644 "data/system/com.steampowered.SteamOSManager1.service" "$(DESTDIR)/usr/share/dbus-1/system-services/"
|
install -m644 "data/system/com.steampowered.SteamOSManager1.service" "$(DESTDIR)/usr/share/dbus-1/system-services/"
|
||||||
install -m644 "data/system/com.steampowered.SteamOSManager1.conf" "$(DESTDIR)/usr/share/dbus-1/system.d/"
|
install -m644 "data/system/com.steampowered.SteamOSManager1.conf" "$(DESTDIR)/usr/share/dbus-1/system.d/"
|
||||||
install -m644 "data/system/steamos-manager.service" "$(DESTDIR)/usr/lib/systemd/system/"
|
install -m644 "data/system/steamos-manager.service" "$(DESTDIR)/usr/lib/systemd/system/"
|
||||||
|
|
16
data/devices/jupiter.toml
Normal file
16
data/devices/jupiter.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[tdp_limit]
|
||||||
|
method = "gpu_hwmon"
|
||||||
|
download_mode_limit = 6
|
||||||
|
|
||||||
|
[tdp_limit.range]
|
||||||
|
min = 3
|
||||||
|
max = 15
|
||||||
|
|
||||||
|
[gpu_clocks]
|
||||||
|
min = 200
|
||||||
|
max = 1600
|
||||||
|
|
||||||
|
[battery_charge_limit]
|
||||||
|
suggested_minimum_limit = 10
|
||||||
|
hwmon_name = "steamdeck_hwmon"
|
||||||
|
attribute = "max_battery_charge_level"
|
|
@ -28,20 +28,3 @@ no_validate_flag = "--skip-validation"
|
||||||
|
|
||||||
[fan_control]
|
[fan_control]
|
||||||
systemd = "jupiter-fan-control.service"
|
systemd = "jupiter-fan-control.service"
|
||||||
|
|
||||||
[tdp_limit]
|
|
||||||
method = "gpu_hwmon"
|
|
||||||
download_mode_limit = 6
|
|
||||||
|
|
||||||
[tdp_limit.range]
|
|
||||||
min = 3
|
|
||||||
max = 15
|
|
||||||
|
|
||||||
[gpu_clocks]
|
|
||||||
min = 200
|
|
||||||
max = 1600
|
|
||||||
|
|
||||||
[battery_charge_limit]
|
|
||||||
suggested_minimum_limit = 10
|
|
||||||
hwmon_name = "steamdeck_hwmon"
|
|
||||||
attribute = "max_battery_charge_level"
|
|
|
@ -483,19 +483,11 @@ pub mod test {
|
||||||
|
|
||||||
sleep(Duration::from_millis(10)).await;
|
sleep(Duration::from_millis(10)).await;
|
||||||
|
|
||||||
h.test.platform_config.replace(Some(PlatformConfig {
|
let mut platform_config = PlatformConfig::default();
|
||||||
factory_reset: None,
|
platform_config.fan_control = Some(ServiceConfig::Systemd(String::from(
|
||||||
update_bios: None,
|
"jupiter-fan-control.service",
|
||||||
update_dock: None,
|
)));
|
||||||
storage: None,
|
h.test.platform_config.replace(Some(platform_config));
|
||||||
fan_control: Some(ServiceConfig::Systemd(String::from(
|
|
||||||
"jupiter-fan-control.service",
|
|
||||||
))),
|
|
||||||
tdp_limit: None,
|
|
||||||
gpu_clocks: None,
|
|
||||||
battery_charge_limit: None,
|
|
||||||
performance_profile: None,
|
|
||||||
}));
|
|
||||||
|
|
||||||
let fan_control = FanControl::new(connection);
|
let fan_control = FanControl::new(connection);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::hardware::{
|
||||||
steam_deck_variant, FactoryResetKind, FanControl, FanControlState, SteamDeckVariant,
|
steam_deck_variant, FactoryResetKind, FanControl, FanControlState, SteamDeckVariant,
|
||||||
};
|
};
|
||||||
use crate::job::JobManager;
|
use crate::job::JobManager;
|
||||||
use crate::platform::platform_config;
|
use crate::platform::{device_config, platform_config};
|
||||||
use crate::power::{
|
use crate::power::{
|
||||||
set_cpu_scaling_governor, set_gpu_clocks, set_gpu_performance_level, set_gpu_power_profile,
|
set_cpu_scaling_governor, set_gpu_clocks, set_gpu_performance_level, set_gpu_power_profile,
|
||||||
set_max_charge_level, set_platform_profile, tdp_limit_manager, CPUScalingGovernor,
|
set_max_charge_level, set_platform_profile, tdp_limit_manager, CPUScalingGovernor,
|
||||||
|
@ -450,7 +450,7 @@ impl SteamOSManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_performance_profile(&self, profile: &str) -> fdo::Result<()> {
|
async fn set_performance_profile(&self, profile: &str) -> fdo::Result<()> {
|
||||||
let config = platform_config().await.map_err(to_zbus_fdo_error)?;
|
let config = device_config().await.map_err(to_zbus_fdo_error)?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.performance_profile.as_ref())
|
.and_then(|config| config.performance_profile.as_ref())
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::hardware::{
|
||||||
device_type, device_variant, steam_deck_variant, DeviceType, SteamDeckVariant,
|
device_type, device_variant, steam_deck_variant, DeviceType, SteamDeckVariant,
|
||||||
};
|
};
|
||||||
use crate::job::JobManagerCommand;
|
use crate::job::JobManagerCommand;
|
||||||
use crate::platform::platform_config;
|
use crate::platform::{device_config, platform_config};
|
||||||
use crate::power::{
|
use crate::power::{
|
||||||
get_available_cpu_scaling_governors, get_available_gpu_performance_levels,
|
get_available_cpu_scaling_governors, get_available_gpu_performance_levels,
|
||||||
get_available_gpu_power_profiles, get_available_platform_profiles, get_cpu_scaling_governor,
|
get_available_gpu_power_profiles, get_available_platform_profiles, get_cpu_scaling_governor,
|
||||||
|
@ -286,7 +286,7 @@ impl BatteryChargeLimit1 {
|
||||||
|
|
||||||
#[zbus(property(emits_changed_signal = "const"))]
|
#[zbus(property(emits_changed_signal = "const"))]
|
||||||
async fn suggested_minimum_limit(&self) -> i32 {
|
async fn suggested_minimum_limit(&self) -> i32 {
|
||||||
let Ok(Some(ref config)) = platform_config().await else {
|
let Ok(Some(ref config)) = device_config().await else {
|
||||||
return BatteryChargeLimit1::DEFAULT_SUGGESTED_MINIMUM_LIMIT;
|
return BatteryChargeLimit1::DEFAULT_SUGGESTED_MINIMUM_LIMIT;
|
||||||
};
|
};
|
||||||
let Some(ref config) = config.battery_charge_limit else {
|
let Some(ref config) = config.battery_charge_limit else {
|
||||||
|
@ -552,7 +552,7 @@ impl Manager2 {
|
||||||
impl PerformanceProfile1 {
|
impl PerformanceProfile1 {
|
||||||
#[zbus(property(emits_changed_signal = "const"))]
|
#[zbus(property(emits_changed_signal = "const"))]
|
||||||
async fn available_performance_profiles(&self) -> fdo::Result<Vec<String>> {
|
async fn available_performance_profiles(&self) -> fdo::Result<Vec<String>> {
|
||||||
let config = platform_config().await.map_err(to_zbus_fdo_error)?;
|
let config = device_config().await.map_err(to_zbus_fdo_error)?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.performance_profile.as_ref())
|
.and_then(|config| config.performance_profile.as_ref())
|
||||||
|
@ -566,7 +566,7 @@ impl PerformanceProfile1 {
|
||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn performance_profile(&self) -> fdo::Result<String> {
|
async fn performance_profile(&self) -> fdo::Result<String> {
|
||||||
let config = platform_config().await.map_err(to_zbus_fdo_error)?;
|
let config = device_config().await.map_err(to_zbus_fdo_error)?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.performance_profile.as_ref())
|
.and_then(|config| config.performance_profile.as_ref())
|
||||||
|
@ -614,7 +614,7 @@ impl PerformanceProfile1 {
|
||||||
|
|
||||||
#[zbus(property(emits_changed_signal = "const"))]
|
#[zbus(property(emits_changed_signal = "const"))]
|
||||||
async fn suggested_default_performance_profile(&self) -> fdo::Result<String> {
|
async fn suggested_default_performance_profile(&self) -> fdo::Result<String> {
|
||||||
let config = platform_config().await.map_err(to_zbus_fdo_error)?;
|
let config = device_config().await.map_err(to_zbus_fdo_error)?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.performance_profile.as_ref())
|
.and_then(|config| config.performance_profile.as_ref())
|
||||||
|
@ -852,12 +852,11 @@ impl WifiPowerManagement1 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_config_interfaces(
|
async fn create_platform_interfaces(
|
||||||
proxy: &Proxy<'static>,
|
proxy: &Proxy<'static>,
|
||||||
object_server: &ObjectServer,
|
object_server: &ObjectServer,
|
||||||
connection: &Connection,
|
connection: &Connection,
|
||||||
job_manager: &UnboundedSender<JobManagerCommand>,
|
job_manager: &UnboundedSender<JobManagerCommand>,
|
||||||
tdp_manager: Option<UnboundedSender<TdpManagerCommand>>,
|
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let Some(config) = platform_config().await? else {
|
let Some(config) = platform_config().await? else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -869,10 +868,6 @@ async fn create_config_interfaces(
|
||||||
let fan_control = FanControl1 {
|
let fan_control = FanControl1 {
|
||||||
proxy: proxy.clone(),
|
proxy: proxy.clone(),
|
||||||
};
|
};
|
||||||
let performance_profile = PerformanceProfile1 {
|
|
||||||
proxy: proxy.clone(),
|
|
||||||
tdp_limit_manager: tdp_manager.clone(),
|
|
||||||
};
|
|
||||||
let storage = Storage1 {
|
let storage = Storage1 {
|
||||||
proxy: proxy.clone(),
|
proxy: proxy.clone(),
|
||||||
job_manager: job_manager.clone(),
|
job_manager: job_manager.clone(),
|
||||||
|
@ -906,41 +901,6 @@ async fn create_config_interfaces(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(manager) = tdp_manager {
|
|
||||||
let low_power_mode = LowPowerMode1 {
|
|
||||||
manager: manager.clone(),
|
|
||||||
};
|
|
||||||
if config
|
|
||||||
.tdp_limit
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|config| config.download_mode_limit)
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
object_server.at(MANAGER_PATH, low_power_mode).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(config) = config.performance_profile.as_ref() {
|
|
||||||
if !get_available_platform_profiles(&config.platform_profile_name)
|
|
||||||
.await
|
|
||||||
.unwrap_or_default()
|
|
||||||
.is_empty()
|
|
||||||
{
|
|
||||||
object_server.at(MANAGER_PATH, performance_profile).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(config) = config.storage.as_ref() {
|
if let Some(config) = config.storage.as_ref() {
|
||||||
match config.is_valid(true).await {
|
match config.is_valid(true).await {
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
|
@ -974,7 +934,58 @@ async fn create_config_interfaces(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
async fn create_device_interfaces(
|
||||||
|
proxy: &Proxy<'static>,
|
||||||
|
object_server: &ObjectServer,
|
||||||
|
tdp_manager: Option<UnboundedSender<TdpManagerCommand>>,
|
||||||
|
) -> Result<()> {
|
||||||
|
let Some(config) = device_config().await? else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
let performance_profile = PerformanceProfile1 {
|
||||||
|
proxy: proxy.clone(),
|
||||||
|
tdp_limit_manager: tdp_manager.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(manager) = tdp_manager {
|
||||||
|
let low_power_mode = LowPowerMode1 {
|
||||||
|
manager: manager.clone(),
|
||||||
|
};
|
||||||
|
if config
|
||||||
|
.tdp_limit
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|config| config.download_mode_limit)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
object_server.at(MANAGER_PATH, low_power_mode).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(config) = config.performance_profile.as_ref() {
|
||||||
|
if !get_available_platform_profiles(&config.platform_profile_name)
|
||||||
|
.await
|
||||||
|
.unwrap_or_default()
|
||||||
|
.is_empty()
|
||||||
|
{
|
||||||
|
object_server.at(MANAGER_PATH, performance_profile).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) async fn create_interfaces(
|
pub(crate) async fn create_interfaces(
|
||||||
session: Connection,
|
session: Connection,
|
||||||
system: Connection,
|
system: Connection,
|
||||||
|
@ -1026,7 +1037,8 @@ pub(crate) async fn create_interfaces(
|
||||||
let object_server = session.object_server();
|
let object_server = session.object_server();
|
||||||
object_server.at(MANAGER_PATH, manager).await?;
|
object_server.at(MANAGER_PATH, manager).await?;
|
||||||
|
|
||||||
create_config_interfaces(&proxy, object_server, &system, &job_manager, tdp_manager).await?;
|
create_device_interfaces(&proxy, object_server, tdp_manager).await?;
|
||||||
|
create_platform_interfaces(&proxy, object_server, &system, &job_manager).await?;
|
||||||
|
|
||||||
if device_type().await.unwrap_or_default() == DeviceType::SteamDeck {
|
if device_type().await.unwrap_or_default() == DeviceType::SteamDeck {
|
||||||
object_server.at(MANAGER_PATH, als).await?;
|
object_server.at(MANAGER_PATH, als).await?;
|
||||||
|
@ -1088,8 +1100,9 @@ mod test {
|
||||||
use crate::hardware::test::fake_model;
|
use crate::hardware::test::fake_model;
|
||||||
use crate::hardware::SteamDeckVariant;
|
use crate::hardware::SteamDeckVariant;
|
||||||
use crate::platform::{
|
use crate::platform::{
|
||||||
BatteryChargeLimitConfig, FormatDeviceConfig, PerformanceProfileConfig, PlatformConfig,
|
BatteryChargeLimitConfig, DeviceConfig, FormatDeviceConfig, PerformanceProfileConfig,
|
||||||
RangeConfig, ResetConfig, ScriptConfig, ServiceConfig, StorageConfig, TdpLimitConfig,
|
PlatformConfig, RangeConfig, ResetConfig, ScriptConfig, ServiceConfig, StorageConfig,
|
||||||
|
TdpLimitConfig,
|
||||||
};
|
};
|
||||||
use crate::power::TdpLimitingMethod;
|
use crate::power::TdpLimitingMethod;
|
||||||
use crate::systemd::test::{MockManager, MockUnit};
|
use crate::systemd::test::{MockManager, MockUnit};
|
||||||
|
@ -1112,7 +1125,7 @@ mod test {
|
||||||
rx_tdp: Option<UnboundedReceiver<TdpManagerCommand>>,
|
rx_tdp: Option<UnboundedReceiver<TdpManagerCommand>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_config() -> Option<PlatformConfig> {
|
fn all_platform_config() -> Option<PlatformConfig> {
|
||||||
Some(PlatformConfig {
|
Some(PlatformConfig {
|
||||||
factory_reset: Some(ResetConfig::default()),
|
factory_reset: Some(ResetConfig::default()),
|
||||||
update_bios: Some(ScriptConfig::default()),
|
update_bios: Some(ScriptConfig::default()),
|
||||||
|
@ -1121,6 +1134,11 @@ mod test {
|
||||||
fan_control: Some(ServiceConfig::Systemd(String::from(
|
fan_control: Some(ServiceConfig::Systemd(String::from(
|
||||||
"jupiter-fan-control.service",
|
"jupiter-fan-control.service",
|
||||||
))),
|
))),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn all_device_config() -> Option<DeviceConfig> {
|
||||||
|
Some(DeviceConfig {
|
||||||
tdp_limit: Some(TdpLimitConfig {
|
tdp_limit: Some(TdpLimitConfig {
|
||||||
method: TdpLimitingMethod::GpuHwmon,
|
method: TdpLimitingMethod::GpuHwmon,
|
||||||
range: Some(RangeConfig::new(3, 15)),
|
range: Some(RangeConfig::new(3, 15)),
|
||||||
|
@ -1140,12 +1158,15 @@ mod test {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start(mut platform_config: Option<PlatformConfig>) -> Result<TestHandle> {
|
async fn start(
|
||||||
|
mut platform_config: Option<PlatformConfig>,
|
||||||
|
device_config: Option<DeviceConfig>,
|
||||||
|
) -> Result<TestHandle> {
|
||||||
let mut handle = testing::start();
|
let mut handle = testing::start();
|
||||||
let (tx_ctx, _rx_ctx) = channel::<UserContext>();
|
let (tx_ctx, _rx_ctx) = channel::<UserContext>();
|
||||||
let (tx_job, rx_job) = unbounded_channel::<JobManagerCommand>();
|
let (tx_job, rx_job) = unbounded_channel::<JobManagerCommand>();
|
||||||
let (tx_tdp, rx_tdp) = {
|
let (tx_tdp, rx_tdp) = {
|
||||||
if platform_config
|
if device_config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.tdp_limit.as_ref())
|
.and_then(|config| config.tdp_limit.as_ref())
|
||||||
.is_some()
|
.is_some()
|
||||||
|
@ -1162,6 +1183,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
handle.test.platform_config.replace(platform_config);
|
handle.test.platform_config.replace(platform_config);
|
||||||
|
handle.test.device_config.replace(device_config);
|
||||||
let connection = handle.new_dbus().await?;
|
let connection = handle.new_dbus().await?;
|
||||||
connection.request_name("org.freedesktop.systemd1").await?;
|
connection.request_name("org.freedesktop.systemd1").await?;
|
||||||
sleep(Duration::from_millis(10)).await;
|
sleep(Duration::from_millis(10)).await;
|
||||||
|
@ -1212,7 +1234,7 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches() {
|
async fn interface_matches() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
let remote = testing::InterfaceIntrospection::from_remote::<SteamOSManager, _>(
|
let remote = testing::InterfaceIntrospection::from_remote::<SteamOSManager, _>(
|
||||||
&test.connection,
|
&test.connection,
|
||||||
|
@ -1248,7 +1270,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_ambient_light_sensor1() {
|
async fn interface_matches_ambient_light_sensor1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
test_interface_matches::<AmbientLightSensor1>(&test.connection)
|
test_interface_matches::<AmbientLightSensor1>(&test.connection)
|
||||||
|
@ -1259,7 +1283,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_battery_charge_limit() {
|
async fn interface_matches_battery_charge_limit() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
test_interface_matches::<BatteryChargeLimit1>(&test.connection)
|
test_interface_matches::<BatteryChargeLimit1>(&test.connection)
|
||||||
|
@ -1270,7 +1296,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_cpu_scaling1() {
|
async fn interface_matches_cpu_scaling1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<CpuScaling1>(&test.connection)
|
assert!(test_interface_matches::<CpuScaling1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1279,7 +1307,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_factory_reset1() {
|
async fn interface_matches_factory_reset1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<FactoryReset1>(&test.connection)
|
assert!(test_interface_matches::<FactoryReset1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1288,50 +1318,52 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_factory_reset1() {
|
async fn interface_missing_factory_reset1() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<FactoryReset1>(&test.connection).await);
|
assert!(test_interface_missing::<FactoryReset1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_invalid_all_factory_reset1() {
|
async fn interface_missing_invalid_all_factory_reset1() {
|
||||||
let mut config = all_config().unwrap();
|
let mut config = all_platform_config().unwrap();
|
||||||
config.factory_reset.as_mut().unwrap().all = ScriptConfig {
|
config.factory_reset.as_mut().unwrap().all = ScriptConfig {
|
||||||
script: PathBuf::from("oxo"),
|
script: PathBuf::from("oxo"),
|
||||||
script_args: Vec::new(),
|
script_args: Vec::new(),
|
||||||
};
|
};
|
||||||
let test = start(Some(config)).await.expect("start");
|
let test = start(Some(config), None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<FactoryReset1>(&test.connection).await);
|
assert!(test_interface_missing::<FactoryReset1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_invalid_os_factory_reset1() {
|
async fn interface_missing_invalid_os_factory_reset1() {
|
||||||
let mut config = all_config().unwrap();
|
let mut config = all_platform_config().unwrap();
|
||||||
config.factory_reset.as_mut().unwrap().os = ScriptConfig {
|
config.factory_reset.as_mut().unwrap().os = ScriptConfig {
|
||||||
script: PathBuf::from("oxo"),
|
script: PathBuf::from("oxo"),
|
||||||
script_args: Vec::new(),
|
script_args: Vec::new(),
|
||||||
};
|
};
|
||||||
let test = start(Some(config)).await.expect("start");
|
let test = start(Some(config), None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<FactoryReset1>(&test.connection).await);
|
assert!(test_interface_missing::<FactoryReset1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_invalid_user_factory_reset1() {
|
async fn interface_missing_invalid_user_factory_reset1() {
|
||||||
let mut config = all_config().unwrap();
|
let mut config = all_platform_config().unwrap();
|
||||||
config.factory_reset.as_mut().unwrap().user = ScriptConfig {
|
config.factory_reset.as_mut().unwrap().user = ScriptConfig {
|
||||||
script: PathBuf::from("oxo"),
|
script: PathBuf::from("oxo"),
|
||||||
script_args: Vec::new(),
|
script_args: Vec::new(),
|
||||||
};
|
};
|
||||||
let test = start(Some(config)).await.expect("start");
|
let test = start(Some(config), None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<FactoryReset1>(&test.connection).await);
|
assert!(test_interface_missing::<FactoryReset1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_fan_control1() {
|
async fn interface_matches_fan_control1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<FanControl1>(&test.connection)
|
assert!(test_interface_matches::<FanControl1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1340,14 +1372,16 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_fan_control1() {
|
async fn interface_missing_fan_control1() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<FanControl1>(&test.connection).await);
|
assert!(test_interface_missing::<FanControl1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_gpu_performance_level1() {
|
async fn interface_matches_gpu_performance_level1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
test_interface_matches::<GpuPerformanceLevel1>(&test.connection)
|
test_interface_matches::<GpuPerformanceLevel1>(&test.connection)
|
||||||
|
@ -1358,7 +1392,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_gpu_power_profile1() {
|
async fn interface_matches_gpu_power_profile1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<GpuPowerProfile1>(&test.connection)
|
assert!(test_interface_matches::<GpuPowerProfile1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1367,7 +1403,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_tdp_limit1() {
|
async fn interface_matches_tdp_limit1() {
|
||||||
let mut test = start(all_config()).await.expect("start");
|
let mut test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
let TdpManagerCommand::IsActive(reply) =
|
let TdpManagerCommand::IsActive(reply) =
|
||||||
test.rx_tdp.as_mut().unwrap().recv().await.unwrap()
|
test.rx_tdp.as_mut().unwrap().recv().await.unwrap()
|
||||||
|
@ -1384,14 +1422,16 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_tdp_limit1() {
|
async fn interface_missing_tdp_limit1() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<TdpLimit1>(&test.connection).await);
|
assert!(test_interface_missing::<TdpLimit1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_inactive_tdp_limit1() {
|
async fn interface_inactive_tdp_limit1() {
|
||||||
let mut test = start(all_config()).await.expect("start");
|
let mut test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
let TdpManagerCommand::IsActive(reply) =
|
let TdpManagerCommand::IsActive(reply) =
|
||||||
test.rx_tdp.as_mut().unwrap().recv().await.unwrap()
|
test.rx_tdp.as_mut().unwrap().recv().await.unwrap()
|
||||||
|
@ -1406,7 +1446,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_hdmi_cec1() {
|
async fn interface_matches_hdmi_cec1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<HdmiCec1>(&test.connection)
|
assert!(test_interface_matches::<HdmiCec1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1415,7 +1457,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_low_power_mode1() {
|
async fn interface_matches_low_power_mode1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<LowPowerMode1>(&test.connection)
|
assert!(test_interface_matches::<LowPowerMode1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1424,14 +1468,16 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_low_power_mode1() {
|
async fn interface_missing_low_power_mode1() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<LowPowerMode1>(&test.connection).await);
|
assert!(test_interface_missing::<LowPowerMode1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_manager2() {
|
async fn interface_matches_manager2() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<Manager2>(&test.connection)
|
assert!(test_interface_matches::<Manager2>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1440,7 +1486,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_performance_profile1() {
|
async fn interface_matches_performance_profile1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
test_interface_matches::<PerformanceProfile1>(&test.connection)
|
test_interface_matches::<PerformanceProfile1>(&test.connection)
|
||||||
|
@ -1451,14 +1499,16 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_performance_profile1() {
|
async fn interface_missing_performance_profile1() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<PerformanceProfile1>(&test.connection).await);
|
assert!(test_interface_missing::<PerformanceProfile1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_storage1() {
|
async fn interface_matches_storage1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<Storage1>(&test.connection)
|
assert!(test_interface_matches::<Storage1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1467,37 +1517,43 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_storage1() {
|
async fn interface_missing_storage1() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<Storage1>(&test.connection).await);
|
assert!(test_interface_missing::<Storage1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_invalid_trim_storage1() {
|
async fn interface_missing_invalid_trim_storage1() {
|
||||||
let mut config = all_config().unwrap();
|
let mut config = all_platform_config().unwrap();
|
||||||
config.storage.as_mut().unwrap().trim_devices = ScriptConfig {
|
config.storage.as_mut().unwrap().trim_devices = ScriptConfig {
|
||||||
script: PathBuf::from("oxo"),
|
script: PathBuf::from("oxo"),
|
||||||
script_args: Vec::new(),
|
script_args: Vec::new(),
|
||||||
};
|
};
|
||||||
let test = start(Some(config)).await.expect("start");
|
let test = start(Some(config), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<Storage1>(&test.connection).await);
|
assert!(test_interface_missing::<Storage1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_invalid_format_storage1() {
|
async fn interface_missing_invalid_format_storage1() {
|
||||||
let mut config = all_config().unwrap();
|
let mut config = all_platform_config().unwrap();
|
||||||
let mut format_config = FormatDeviceConfig::default();
|
let mut format_config = FormatDeviceConfig::default();
|
||||||
format_config.script = PathBuf::from("oxo");
|
format_config.script = PathBuf::from("oxo");
|
||||||
config.storage.as_mut().unwrap().format_device = format_config;
|
config.storage.as_mut().unwrap().format_device = format_config;
|
||||||
let test = start(Some(config)).await.expect("start");
|
let test = start(Some(config), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<Storage1>(&test.connection).await);
|
assert!(test_interface_missing::<Storage1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_update_bios1() {
|
async fn interface_matches_update_bios1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<UpdateBios1>(&test.connection)
|
assert!(test_interface_matches::<UpdateBios1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1506,26 +1562,30 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_update_bios1() {
|
async fn interface_missing_update_bios1() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<UpdateBios1>(&test.connection).await);
|
assert!(test_interface_missing::<UpdateBios1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_invalid_update_bios1() {
|
async fn interface_missing_invalid_update_bios1() {
|
||||||
let mut config = all_config().unwrap();
|
let mut config = all_platform_config().unwrap();
|
||||||
config.update_bios = Some(ScriptConfig {
|
config.update_bios = Some(ScriptConfig {
|
||||||
script: PathBuf::from("oxo"),
|
script: PathBuf::from("oxo"),
|
||||||
script_args: Vec::new(),
|
script_args: Vec::new(),
|
||||||
});
|
});
|
||||||
let test = start(Some(config)).await.expect("start");
|
let test = start(Some(config), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<UpdateBios1>(&test.connection).await);
|
assert!(test_interface_missing::<UpdateBios1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_update_dock1() {
|
async fn interface_matches_update_dock1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<UpdateDock1>(&test.connection)
|
assert!(test_interface_matches::<UpdateDock1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1534,26 +1594,30 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_update_dock1() {
|
async fn interface_missing_update_dock1() {
|
||||||
let test = start(None).await.expect("start");
|
let test = start(None, None).await.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<UpdateDock1>(&test.connection).await);
|
assert!(test_interface_missing::<UpdateDock1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_missing_invalid_update_dock1() {
|
async fn interface_missing_invalid_update_dock1() {
|
||||||
let mut config = all_config().unwrap();
|
let mut config = all_platform_config().unwrap();
|
||||||
config.update_dock = Some(ScriptConfig {
|
config.update_dock = Some(ScriptConfig {
|
||||||
script: PathBuf::from("oxo"),
|
script: PathBuf::from("oxo"),
|
||||||
script_args: Vec::new(),
|
script_args: Vec::new(),
|
||||||
});
|
});
|
||||||
let test = start(Some(config)).await.expect("start");
|
let test = start(Some(config), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_missing::<UpdateDock1>(&test.connection).await);
|
assert!(test_interface_missing::<UpdateDock1>(&test.connection).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_wifi_power_management1() {
|
async fn interface_matches_wifi_power_management1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
test_interface_matches::<WifiPowerManagement1>(&test.connection)
|
test_interface_matches::<WifiPowerManagement1>(&test.connection)
|
||||||
|
@ -1564,7 +1628,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_wifi_debug() {
|
async fn interface_matches_wifi_debug() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<WifiDebug1>(&test.connection)
|
assert!(test_interface_matches::<WifiDebug1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
@ -1573,7 +1639,9 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_wifi_debug_dump() {
|
async fn interface_matches_wifi_debug_dump() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_platform_config(), all_device_config())
|
||||||
|
.await
|
||||||
|
.expect("start");
|
||||||
|
|
||||||
assert!(test_interface_matches::<WifiDebugDump1>(&test.connection)
|
assert!(test_interface_matches::<WifiDebugDump1>(&test.connection)
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -23,11 +23,15 @@ use zbus::Connection;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use crate::hardware::{device_type, DeviceType};
|
use crate::hardware::{device_type, DeviceType};
|
||||||
|
#[cfg(test)]
|
||||||
|
use crate::path;
|
||||||
use crate::power::TdpLimitingMethod;
|
use crate::power::TdpLimitingMethod;
|
||||||
use crate::systemd::SystemdUnit;
|
use crate::systemd::SystemdUnit;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
static CONFIG: OnceCell<Option<PlatformConfig>> = OnceCell::const_new();
|
static PLATFORM_CONFIG: OnceCell<Option<PlatformConfig>> = OnceCell::const_new();
|
||||||
|
#[cfg(not(test))]
|
||||||
|
static DEVICE_CONFIG: OnceCell<Option<DeviceConfig>> = OnceCell::const_new();
|
||||||
|
|
||||||
#[derive(Clone, Default, Deserialize, Debug)]
|
#[derive(Clone, Default, Deserialize, Debug)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
@ -37,6 +41,11 @@ pub(crate) struct PlatformConfig {
|
||||||
pub update_dock: Option<ScriptConfig>,
|
pub update_dock: Option<ScriptConfig>,
|
||||||
pub storage: Option<StorageConfig>,
|
pub storage: Option<StorageConfig>,
|
||||||
pub fan_control: Option<ServiceConfig>,
|
pub fan_control: Option<ServiceConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Default, Deserialize, Debug)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub(crate) struct DeviceConfig {
|
||||||
pub tdp_limit: Option<TdpLimitConfig>,
|
pub tdp_limit: Option<TdpLimitConfig>,
|
||||||
pub gpu_clocks: Option<RangeConfig<u32>>,
|
pub gpu_clocks: Option<RangeConfig<u32>>,
|
||||||
pub battery_charge_limit: Option<BatteryChargeLimitConfig>,
|
pub battery_charge_limit: Option<BatteryChargeLimitConfig>,
|
||||||
|
@ -224,26 +233,12 @@ impl<T: Clone> RangeConfig<T> {
|
||||||
impl PlatformConfig {
|
impl PlatformConfig {
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
async fn load() -> Result<Option<PlatformConfig>> {
|
async fn load() -> Result<Option<PlatformConfig>> {
|
||||||
let platform = match device_type().await? {
|
let config = read_to_string("/usr/share/steamos-manager/platform.toml").await?;
|
||||||
DeviceType::SteamDeck => "jupiter",
|
|
||||||
DeviceType::LegionGo => "legion-go-series",
|
|
||||||
DeviceType::LegionGoS => "legion-go-series",
|
|
||||||
DeviceType::RogAlly => "rog-ally-series",
|
|
||||||
DeviceType::RogAllyX => "rog-ally-series",
|
|
||||||
DeviceType::ZotacGamingZone => "zotac-gaming-zone",
|
|
||||||
_ => return Ok(None),
|
|
||||||
};
|
|
||||||
let config = read_to_string(format!(
|
|
||||||
"/usr/share/steamos-manager/platforms/{platform}.toml"
|
|
||||||
))
|
|
||||||
.await?;
|
|
||||||
Ok(Some(toml::from_str(config.as_ref())?))
|
Ok(Some(toml::from_str(config.as_ref())?))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn set_test_paths(&mut self) {
|
pub(crate) fn set_test_paths(&mut self) {
|
||||||
use crate::path;
|
|
||||||
|
|
||||||
if let Some(ref mut factory_reset) = self.factory_reset {
|
if let Some(ref mut factory_reset) = self.factory_reset {
|
||||||
if factory_reset.all.script.as_os_str().is_empty() {
|
if factory_reset.all.script.as_os_str().is_empty() {
|
||||||
factory_reset.all.script = path("exe");
|
factory_reset.all.script = path("exe");
|
||||||
|
@ -276,6 +271,26 @@ impl PlatformConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DeviceConfig {
|
||||||
|
#[cfg(not(test))]
|
||||||
|
async fn load() -> Result<Option<DeviceConfig>> {
|
||||||
|
let platform = match device_type().await? {
|
||||||
|
DeviceType::SteamDeck => "jupiter",
|
||||||
|
DeviceType::LegionGo => "legion-go-series",
|
||||||
|
DeviceType::LegionGoS => "legion-go-series",
|
||||||
|
DeviceType::RogAlly => "rog-ally-series",
|
||||||
|
DeviceType::RogAllyX => "rog-ally-series",
|
||||||
|
DeviceType::ZotacGamingZone => "zotac-gaming-zone",
|
||||||
|
_ => return Ok(None),
|
||||||
|
};
|
||||||
|
let config = read_to_string(format!(
|
||||||
|
"/usr/share/steamos-manager/devices/{platform}.toml"
|
||||||
|
))
|
||||||
|
.await?;
|
||||||
|
Ok(Some(toml::from_str(config.as_ref())?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn de_tdp_limiter_method<'de, D>(deserializer: D) -> Result<TdpLimitingMethod, D::Error>
|
fn de_tdp_limiter_method<'de, D>(deserializer: D) -> Result<TdpLimitingMethod, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
|
@ -288,7 +303,12 @@ where
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
pub(crate) async fn platform_config() -> Result<&'static Option<PlatformConfig>> {
|
pub(crate) async fn platform_config() -> Result<&'static Option<PlatformConfig>> {
|
||||||
CONFIG.get_or_try_init(PlatformConfig::load).await
|
PLATFORM_CONFIG.get_or_try_init(PlatformConfig::load).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
pub(crate) async fn device_config() -> Result<&'static Option<DeviceConfig>> {
|
||||||
|
DEVICE_CONFIG.get_or_try_init(DeviceConfig::load).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -298,6 +318,13 @@ pub(crate) async fn platform_config() -> Result<Option<PlatformConfig>> {
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) async fn device_config() -> Result<Option<DeviceConfig>> {
|
||||||
|
let test = crate::testing::current();
|
||||||
|
let config = test.device_config.borrow().clone();
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -411,7 +438,7 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn jupiter_valid() {
|
async fn jupiter_valid() {
|
||||||
let config = read_to_string("data/platforms/jupiter.toml")
|
let config = read_to_string("data/devices/jupiter.toml")
|
||||||
.await
|
.await
|
||||||
.expect("read_to_string");
|
.expect("read_to_string");
|
||||||
let res = toml::from_str::<PlatformConfig>(config.as_ref());
|
let res = toml::from_str::<PlatformConfig>(config.as_ref());
|
||||||
|
|
64
src/power.rs
64
src/power.rs
|
@ -30,7 +30,7 @@ use zbus::Connection;
|
||||||
use crate::hardware::{device_type, DeviceType};
|
use crate::hardware::{device_type, DeviceType};
|
||||||
use crate::manager::root::RootManagerProxy;
|
use crate::manager::root::RootManagerProxy;
|
||||||
use crate::manager::user::{TdpLimit1, MANAGER_PATH};
|
use crate::manager::user::{TdpLimit1, MANAGER_PATH};
|
||||||
use crate::platform::platform_config;
|
use crate::platform::device_config;
|
||||||
use crate::Service;
|
use crate::Service;
|
||||||
use crate::{path, write_synced};
|
use crate::{path, write_synced};
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ pub(crate) trait TdpLimitManager: Send + Sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn tdp_limit_manager() -> Result<Box<dyn TdpLimitManager>> {
|
pub(crate) async fn tdp_limit_manager() -> Result<Box<dyn TdpLimitManager>> {
|
||||||
let config = platform_config().await?;
|
let config = device_config().await?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.tdp_limit.as_ref())
|
.and_then(|config| config.tdp_limit.as_ref())
|
||||||
|
@ -340,7 +340,7 @@ pub(crate) async fn set_cpu_scaling_governor(governor: CPUScalingGovernor) -> Re
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_gpu_clocks_range() -> Result<RangeInclusive<u32>> {
|
pub(crate) async fn get_gpu_clocks_range() -> Result<RangeInclusive<u32>> {
|
||||||
if let Some(range) = platform_config()
|
if let Some(range) = device_config()
|
||||||
.await?
|
.await?
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.gpu_clocks)
|
.and_then(|config| config.gpu_clocks)
|
||||||
|
@ -490,7 +490,7 @@ impl TdpLimitManager for GpuHwmonTdpLimitManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_tdp_limit_range(&self) -> Result<RangeInclusive<u32>> {
|
async fn get_tdp_limit_range(&self) -> Result<RangeInclusive<u32>> {
|
||||||
let config = platform_config().await?;
|
let config = device_config().await?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.tdp_limit.as_ref())
|
.and_then(|config| config.tdp_limit.as_ref())
|
||||||
|
@ -578,7 +578,7 @@ impl TdpLimitManager for FirmwareAttributeLimitManager {
|
||||||
let Some(ref performance_profile) = self.performance_profile else {
|
let Some(ref performance_profile) = self.performance_profile else {
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
};
|
};
|
||||||
let config = platform_config().await?;
|
let config = device_config().await?;
|
||||||
if let Some(config) = config
|
if let Some(config) = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.performance_profile.as_ref())
|
.and_then(|config| config.performance_profile.as_ref())
|
||||||
|
@ -591,7 +591,7 @@ impl TdpLimitManager for FirmwareAttributeLimitManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_max_charge_level() -> Result<i32> {
|
pub(crate) async fn get_max_charge_level() -> Result<i32> {
|
||||||
let config = platform_config().await?;
|
let config = device_config().await?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.battery_charge_limit.as_ref())
|
.and_then(|config| config.battery_charge_limit.as_ref())
|
||||||
|
@ -609,7 +609,7 @@ pub(crate) async fn get_max_charge_level() -> Result<i32> {
|
||||||
pub(crate) async fn set_max_charge_level(limit: i32) -> Result<()> {
|
pub(crate) async fn set_max_charge_level(limit: i32) -> Result<()> {
|
||||||
ensure!((0..=100).contains(&limit), "Invalid limit");
|
ensure!((0..=100).contains(&limit), "Invalid limit");
|
||||||
let data = limit.to_string();
|
let data = limit.to_string();
|
||||||
let config = platform_config().await?;
|
let config = device_config().await?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.battery_charge_limit.as_ref())
|
.and_then(|config| config.battery_charge_limit.as_ref())
|
||||||
|
@ -654,7 +654,7 @@ impl TdpManagerService {
|
||||||
system: &Connection,
|
system: &Connection,
|
||||||
session: &Connection,
|
session: &Connection,
|
||||||
) -> Result<TdpManagerService> {
|
) -> Result<TdpManagerService> {
|
||||||
let config = platform_config().await?;
|
let config = device_config().await?;
|
||||||
let config = config
|
let config = config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|config| config.tdp_limit.as_ref())
|
.and_then(|config| config.tdp_limit.as_ref())
|
||||||
|
@ -858,8 +858,8 @@ pub(crate) mod test {
|
||||||
use crate::hardware::test::fake_model;
|
use crate::hardware::test::fake_model;
|
||||||
use crate::hardware::SteamDeckVariant;
|
use crate::hardware::SteamDeckVariant;
|
||||||
use crate::platform::{
|
use crate::platform::{
|
||||||
BatteryChargeLimitConfig, FirmwareAttributeConfig, PerformanceProfileConfig,
|
BatteryChargeLimitConfig, DeviceConfig, FirmwareAttributeConfig, PerformanceProfileConfig,
|
||||||
PlatformConfig, RangeConfig, TdpLimitConfig,
|
RangeConfig, TdpLimitConfig,
|
||||||
};
|
};
|
||||||
use crate::{enum_roundtrip, testing};
|
use crate::{enum_roundtrip, testing};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
@ -1041,14 +1041,14 @@ CCLK_RANGE in Core0:
|
||||||
async fn test_gpu_hwmon_get_tdp_limit() {
|
async fn test_gpu_hwmon_get_tdp_limit() {
|
||||||
let handle = testing::start();
|
let handle = testing::start();
|
||||||
|
|
||||||
let mut platform_config = PlatformConfig::default();
|
let mut config = DeviceConfig::default();
|
||||||
platform_config.tdp_limit = Some(TdpLimitConfig {
|
config.tdp_limit = Some(TdpLimitConfig {
|
||||||
method: TdpLimitingMethod::GpuHwmon,
|
method: TdpLimitingMethod::GpuHwmon,
|
||||||
range: Some(RangeConfig { min: 3, max: 15 }),
|
range: Some(RangeConfig { min: 3, max: 15 }),
|
||||||
download_mode_limit: None,
|
download_mode_limit: None,
|
||||||
firmware_attribute: None,
|
firmware_attribute: None,
|
||||||
});
|
});
|
||||||
handle.test.platform_config.replace(Some(platform_config));
|
handle.test.device_config.replace(Some(config));
|
||||||
let manager = tdp_limit_manager().await.unwrap();
|
let manager = tdp_limit_manager().await.unwrap();
|
||||||
|
|
||||||
setup().await.expect("setup");
|
setup().await.expect("setup");
|
||||||
|
@ -1066,14 +1066,14 @@ CCLK_RANGE in Core0:
|
||||||
async fn test_gpu_hwmon_set_tdp_limit() {
|
async fn test_gpu_hwmon_set_tdp_limit() {
|
||||||
let handle = testing::start();
|
let handle = testing::start();
|
||||||
|
|
||||||
let mut platform_config = PlatformConfig::default();
|
let mut config = DeviceConfig::default();
|
||||||
platform_config.tdp_limit = Some(TdpLimitConfig {
|
config.tdp_limit = Some(TdpLimitConfig {
|
||||||
method: TdpLimitingMethod::GpuHwmon,
|
method: TdpLimitingMethod::GpuHwmon,
|
||||||
range: Some(RangeConfig { min: 3, max: 15 }),
|
range: Some(RangeConfig { min: 3, max: 15 }),
|
||||||
download_mode_limit: None,
|
download_mode_limit: None,
|
||||||
firmware_attribute: None,
|
firmware_attribute: None,
|
||||||
});
|
});
|
||||||
handle.test.platform_config.replace(Some(platform_config));
|
handle.test.device_config.replace(Some(config));
|
||||||
let manager = tdp_limit_manager().await.unwrap();
|
let manager = tdp_limit_manager().await.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -1550,13 +1550,13 @@ CCLK_RANGE in Core0:
|
||||||
async fn read_max_charge_level() {
|
async fn read_max_charge_level() {
|
||||||
let handle = testing::start();
|
let handle = testing::start();
|
||||||
|
|
||||||
let mut platform_config = PlatformConfig::default();
|
let mut config = DeviceConfig::default();
|
||||||
platform_config.battery_charge_limit = Some(BatteryChargeLimitConfig {
|
config.battery_charge_limit = Some(BatteryChargeLimitConfig {
|
||||||
suggested_minimum_limit: Some(10),
|
suggested_minimum_limit: Some(10),
|
||||||
hwmon_name: String::from("steamdeck_hwmon"),
|
hwmon_name: String::from("steamdeck_hwmon"),
|
||||||
attribute: String::from("max_battery_charge_level"),
|
attribute: String::from("max_battery_charge_level"),
|
||||||
});
|
});
|
||||||
handle.test.platform_config.replace(Some(platform_config));
|
handle.test.device_config.replace(Some(config));
|
||||||
|
|
||||||
let base = path(HWMON_PREFIX).join("hwmon6");
|
let base = path(HWMON_PREFIX).join("hwmon6");
|
||||||
create_dir_all(&base).await.expect("create_dir_all");
|
create_dir_all(&base).await.expect("create_dir_all");
|
||||||
|
@ -1650,14 +1650,14 @@ CCLK_RANGE in Core0:
|
||||||
|
|
||||||
let iface = MockTdpLimit { queue: reply_tx };
|
let iface = MockTdpLimit { queue: reply_tx };
|
||||||
|
|
||||||
let mut platform_config = PlatformConfig::default();
|
let mut config = DeviceConfig::default();
|
||||||
platform_config.tdp_limit = Some(TdpLimitConfig {
|
config.tdp_limit = Some(TdpLimitConfig {
|
||||||
method: TdpLimitingMethod::GpuHwmon,
|
method: TdpLimitingMethod::GpuHwmon,
|
||||||
range: Some(RangeConfig { min: 3, max: 15 }),
|
range: Some(RangeConfig { min: 3, max: 15 }),
|
||||||
download_mode_limit: NonZeroU32::new(6),
|
download_mode_limit: NonZeroU32::new(6),
|
||||||
firmware_attribute: None,
|
firmware_attribute: None,
|
||||||
});
|
});
|
||||||
h.test.platform_config.replace(Some(platform_config));
|
h.test.device_config.replace(Some(config));
|
||||||
let manager = tdp_limit_manager().await.unwrap();
|
let manager = tdp_limit_manager().await.unwrap();
|
||||||
|
|
||||||
connection
|
connection
|
||||||
|
@ -1746,14 +1746,14 @@ CCLK_RANGE in Core0:
|
||||||
|
|
||||||
let iface = MockTdpLimit { queue: reply_tx };
|
let iface = MockTdpLimit { queue: reply_tx };
|
||||||
|
|
||||||
let mut platform_config = PlatformConfig::default();
|
let mut config = DeviceConfig::default();
|
||||||
platform_config.tdp_limit = Some(TdpLimitConfig {
|
config.tdp_limit = Some(TdpLimitConfig {
|
||||||
method: TdpLimitingMethod::GpuHwmon,
|
method: TdpLimitingMethod::GpuHwmon,
|
||||||
range: Some(RangeConfig { min: 3, max: 15 }),
|
range: Some(RangeConfig { min: 3, max: 15 }),
|
||||||
download_mode_limit: None,
|
download_mode_limit: None,
|
||||||
firmware_attribute: None,
|
firmware_attribute: None,
|
||||||
});
|
});
|
||||||
h.test.platform_config.replace(Some(platform_config));
|
h.test.device_config.replace(Some(config));
|
||||||
let manager = tdp_limit_manager().await.unwrap();
|
let manager = tdp_limit_manager().await.unwrap();
|
||||||
|
|
||||||
connection
|
connection
|
||||||
|
@ -1808,12 +1808,12 @@ CCLK_RANGE in Core0:
|
||||||
let h = testing::start();
|
let h = testing::start();
|
||||||
setup().await.expect("setup");
|
setup().await.expect("setup");
|
||||||
|
|
||||||
let mut platform_config = PlatformConfig::default();
|
let mut config = DeviceConfig::default();
|
||||||
platform_config.performance_profile = Some(PerformanceProfileConfig {
|
config.performance_profile = Some(PerformanceProfileConfig {
|
||||||
platform_profile_name: String::from("platform-profile0"),
|
platform_profile_name: String::from("platform-profile0"),
|
||||||
suggested_default: String::from("custom"),
|
suggested_default: String::from("custom"),
|
||||||
});
|
});
|
||||||
platform_config.tdp_limit = Some(TdpLimitConfig {
|
config.tdp_limit = Some(TdpLimitConfig {
|
||||||
method: TdpLimitingMethod::FirmwareAttribute,
|
method: TdpLimitingMethod::FirmwareAttribute,
|
||||||
range: Some(RangeConfig { min: 3, max: 15 }),
|
range: Some(RangeConfig { min: 3, max: 15 }),
|
||||||
download_mode_limit: None,
|
download_mode_limit: None,
|
||||||
|
@ -1822,7 +1822,7 @@ CCLK_RANGE in Core0:
|
||||||
performance_profile: Some(String::from("custom")),
|
performance_profile: Some(String::from("custom")),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
h.test.platform_config.replace(Some(platform_config));
|
h.test.device_config.replace(Some(config));
|
||||||
|
|
||||||
let attributes_base = path(FirmwareAttributeLimitManager::PREFIX)
|
let attributes_base = path(FirmwareAttributeLimitManager::PREFIX)
|
||||||
.join("tdp0")
|
.join("tdp0")
|
||||||
|
@ -1903,8 +1903,8 @@ CCLK_RANGE in Core0:
|
||||||
let h = testing::start();
|
let h = testing::start();
|
||||||
setup().await.expect("setup");
|
setup().await.expect("setup");
|
||||||
|
|
||||||
let mut platform_config = PlatformConfig::default();
|
let mut config = DeviceConfig::default();
|
||||||
platform_config.tdp_limit = Some(TdpLimitConfig {
|
config.tdp_limit = Some(TdpLimitConfig {
|
||||||
method: TdpLimitingMethod::FirmwareAttribute,
|
method: TdpLimitingMethod::FirmwareAttribute,
|
||||||
range: Some(RangeConfig { min: 3, max: 15 }),
|
range: Some(RangeConfig { min: 3, max: 15 }),
|
||||||
download_mode_limit: None,
|
download_mode_limit: None,
|
||||||
|
@ -1913,7 +1913,7 @@ CCLK_RANGE in Core0:
|
||||||
performance_profile: None,
|
performance_profile: None,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
h.test.platform_config.replace(Some(platform_config));
|
h.test.device_config.replace(Some(config));
|
||||||
|
|
||||||
let attributes_base = path(FirmwareAttributeLimitManager::PREFIX)
|
let attributes_base = path(FirmwareAttributeLimitManager::PREFIX)
|
||||||
.join("tdp0")
|
.join("tdp0")
|
||||||
|
|
|
@ -23,7 +23,7 @@ use zbus::zvariant::ObjectPath;
|
||||||
use zbus::Address;
|
use zbus::Address;
|
||||||
use zbus_xml::{Method, Node, Property, Signal};
|
use zbus_xml::{Method, Node, Property, Signal};
|
||||||
|
|
||||||
use crate::platform::PlatformConfig;
|
use crate::platform::{DeviceConfig, PlatformConfig};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static TEST: RefCell<Option<Rc<Test>>> = const { RefCell::new(None) };
|
static TEST: RefCell<Option<Rc<Test>>> = const { RefCell::new(None) };
|
||||||
|
@ -70,6 +70,7 @@ pub fn start() -> TestHandle {
|
||||||
mock_dbus: Cell::new(None),
|
mock_dbus: Cell::new(None),
|
||||||
dbus_address: Mutex::new(None),
|
dbus_address: Mutex::new(None),
|
||||||
platform_config: RefCell::new(None),
|
platform_config: RefCell::new(None),
|
||||||
|
device_config: RefCell::new(None),
|
||||||
});
|
});
|
||||||
*lock.borrow_mut() = Some(test.clone());
|
*lock.borrow_mut() = Some(test.clone());
|
||||||
TestHandle { test }
|
TestHandle { test }
|
||||||
|
@ -103,6 +104,7 @@ pub struct Test {
|
||||||
pub mock_dbus: Cell<Option<MockDBus>>,
|
pub mock_dbus: Cell<Option<MockDBus>>,
|
||||||
pub dbus_address: Mutex<Option<Address>>,
|
pub dbus_address: Mutex<Option<Address>>,
|
||||||
pub platform_config: RefCell<Option<PlatformConfig>>,
|
pub platform_config: RefCell<Option<PlatformConfig>>,
|
||||||
|
pub device_config: RefCell<Option<DeviceConfig>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TestHandle {
|
pub struct TestHandle {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue