diff --git a/src/hardware.rs b/src/hardware.rs index 8f5113e..948bb9f 100644 --- a/src/hardware.rs +++ b/src/hardware.rs @@ -9,9 +9,11 @@ use anyhow::{Error, Result}; use std::fmt; use std::str::FromStr; use tokio::fs; +use zbus::Connection; use crate::path; use crate::process::script_exit_code; +use crate::systemd::SystemdUnit; const BOARD_VENDOR_PATH: &str = "/sys/class/dmi/id/board_vendor"; const BOARD_NAME_PATH: &str = "/sys/class/dmi/id/board_name"; @@ -30,6 +32,13 @@ pub enum HardwareCurrentlySupported { Supported = 1, } +#[derive(PartialEq, Debug, Copy, Clone)] +#[repr(u32)] +pub enum FanControlState { + Bios = 0, + Os = 1, +} + impl FromStr for HardwareVariant { type Err = Error; fn from_str(input: &str) -> Result { @@ -65,6 +74,26 @@ impl fmt::Display for HardwareCurrentlySupported { } } +impl TryFrom for FanControlState { + type Error = &'static str; + fn try_from(v: u32) -> Result { + match v { + x if x == FanControlState::Bios as u32 => Ok(FanControlState::Bios), + x if x == FanControlState::Os as u32 => Ok(FanControlState::Os), + _ => Err("No enum match for value {v}"), + } + } +} + +impl fmt::Display for FanControlState { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + FanControlState::Bios => write!(f, "BIOS"), + FanControlState::Os => write!(f, "OS"), + } + } +} + pub async fn variant() -> Result { let board_vendor = fs::read_to_string(path(BOARD_VENDOR_PATH)).await?; if board_vendor.trim_end() != "Valve" { @@ -86,6 +115,36 @@ pub async fn check_support() -> Result { }) } +pub struct FanControl { + connection: Connection, +} + +impl FanControl { + pub fn new(connection: Connection) -> FanControl { + FanControl { connection } + } + + pub async fn get_state(&self) -> Result { + let jupiter_fan_control = + SystemdUnit::new(self.connection.clone(), "jupiter_2dfan_2dcontrol_2eservice").await?; + let active = jupiter_fan_control.active().await?; + Ok(match active { + true => FanControlState::Os, + false => FanControlState::Bios, + }) + } + + pub async fn set_state(&self, state: FanControlState) -> Result<()> { + // Run what steamos-polkit-helpers/jupiter-fan-control does + let jupiter_fan_control = + SystemdUnit::new(self.connection.clone(), "jupiter_2dfan_2dcontrol_2eservice").await?; + match state { + FanControlState::Os => jupiter_fan_control.start().await, + FanControlState::Bios => jupiter_fan_control.stop().await, + } + } +} + #[cfg(test)] mod test { use super::*; diff --git a/src/manager.rs b/src/manager.rs index 3123b27..5cf1f5f 100644 --- a/src/manager.rs +++ b/src/manager.rs @@ -7,19 +7,17 @@ */ use anyhow::Result; -use std::fmt; use tokio::fs::File; use tracing::error; use zbus::zvariant::Fd; use zbus::{interface, Connection, SignalContext}; -use crate::hardware::{check_support, variant, HardwareVariant}; +use crate::hardware::{check_support, variant, FanControl, FanControlState, HardwareVariant}; use crate::power::{ get_gpu_clocks, get_gpu_performance_level, get_tdp_limit, set_gpu_clocks, set_gpu_performance_level, set_tdp_limit, GPUPerformanceLevel, }; use crate::process::{run_script, script_output}; -use crate::systemd::SystemdUnit; use crate::wifi::{ get_wifi_backend, get_wifi_power_management_state, set_wifi_backend, set_wifi_debug_mode, set_wifi_power_management_state, WifiBackend, WifiDebugMode, WifiPowerManagement, @@ -33,36 +31,10 @@ enum PrepareFactoryReset { RebootRequired = 1, } -#[derive(PartialEq, Debug, Copy, Clone)] -#[repr(u32)] -enum FanControl { - Bios = 0, - Os = 1, -} - -impl TryFrom for FanControl { - type Error = &'static str; - fn try_from(v: u32) -> Result { - match v { - x if x == FanControl::Bios as u32 => Ok(FanControl::Bios), - x if x == FanControl::Os as u32 => Ok(FanControl::Os), - _ => Err("No enum match for value {v}"), - } - } -} - -impl fmt::Display for FanControl { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - FanControl::Bios => write!(f, "BIOS"), - FanControl::Os => write!(f, "OS"), - } - } -} - pub struct SteamOSManager { connection: Connection, wifi_debug_mode: WifiDebugMode, + fan_control: FanControl, // Whether we should use trace-cmd or not. // True on galileo devices, false otherwise should_trace: bool, @@ -71,6 +43,7 @@ pub struct SteamOSManager { impl SteamOSManager { pub async fn new(connection: Connection) -> Result { Ok(SteamOSManager { + fan_control: FanControl::new(connection.clone()), connection, wifi_debug_mode: WifiDebugMode::Off, should_trace: variant().await? == HardwareVariant::Galileo, @@ -114,36 +87,24 @@ impl SteamOSManager { #[zbus(property(emits_changed_signal = "false"))] async fn fan_control_state(&self) -> zbus::fdo::Result { - let jupiter_fan_control = - SystemdUnit::new(self.connection.clone(), "jupiter_2dfan_2dcontrol_2eservice") - .await - .map_err(anyhow_to_zbus_fdo)?; - let active = jupiter_fan_control - .active() + Ok(self + .fan_control + .get_state() .await - .map_err(anyhow_to_zbus_fdo)?; - Ok(match active { - true => FanControl::Os as u32, - false => FanControl::Bios as u32, - }) + .map_err(anyhow_to_zbus_fdo)? as u32) } #[zbus(property)] async fn set_fan_control_state(&self, state: u32) -> zbus::Result<()> { - let state = match FanControl::try_from(state) { + let state = match FanControlState::try_from(state) { Ok(state) => state, Err(err) => return Err(zbus::fdo::Error::InvalidArgs(err.to_string()).into()), }; // Run what steamos-polkit-helpers/jupiter-fan-control does - let jupiter_fan_control = - SystemdUnit::new(self.connection.clone(), "jupiter_2dfan_2dcontrol_2eservice") - .await - .map_err(anyhow_to_zbus)?; - match state { - FanControl::Os => jupiter_fan_control.start().await, - FanControl::Bios => jupiter_fan_control.stop().await, - } - .map_err(anyhow_to_zbus) + self.fan_control + .set_state(state) + .await + .map_err(anyhow_to_zbus) } #[zbus(property(emits_changed_signal = "const"))]