mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-05 22:20:33 -04:00
daemon/root: Allow DsInhibit to be toggled at runtime
This commit is contained in:
parent
cae5a69e6e
commit
037d418553
2 changed files with 111 additions and 17 deletions
|
@ -8,13 +8,16 @@
|
|||
use anyhow::{bail, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tokio::sync::oneshot;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::error;
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::{fmt, Registry};
|
||||
use zbus::connection::Connection;
|
||||
use zbus::ConnectionBuilder;
|
||||
|
||||
use crate::daemon::{channel, Daemon, DaemonContext};
|
||||
use crate::daemon::{channel, Daemon, DaemonCommand, DaemonContext};
|
||||
use crate::ds_inhibit::Inhibitor;
|
||||
use crate::manager::root::SteamOSManager;
|
||||
use crate::path;
|
||||
|
@ -34,12 +37,61 @@ pub(crate) struct RootState {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, Default, Deserialize, Serialize, Debug)]
|
||||
pub(crate) struct RootServicesState {}
|
||||
pub(crate) struct RootServicesState {
|
||||
pub ds_inhibit: DsInhibit,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum RootCommand {}
|
||||
pub(crate) enum RootCommand {
|
||||
SetDsInhibit(bool),
|
||||
GetDsInhibit(oneshot::Sender<bool>),
|
||||
}
|
||||
|
||||
struct RootContext {}
|
||||
#[derive(Copy, Clone, Deserialize, Serialize, Debug)]
|
||||
pub(crate) struct DsInhibit {
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl Default for DsInhibit {
|
||||
fn default() -> DsInhibit {
|
||||
DsInhibit { enabled: true }
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct RootContext {
|
||||
state: RootState,
|
||||
channel: Sender<Command>,
|
||||
|
||||
ds_inhibit: Option<CancellationToken>,
|
||||
}
|
||||
|
||||
impl RootContext {
|
||||
pub(crate) fn new(channel: Sender<Command>) -> RootContext {
|
||||
RootContext {
|
||||
state: RootState::default(),
|
||||
channel,
|
||||
ds_inhibit: None,
|
||||
}
|
||||
}
|
||||
|
||||
async fn reload_ds_inhibit(&mut self, daemon: &mut Daemon<RootContext>) -> Result<()> {
|
||||
match (
|
||||
self.state.services.ds_inhibit.enabled,
|
||||
self.ds_inhibit.as_ref(),
|
||||
) {
|
||||
(false, Some(handle)) => {
|
||||
handle.cancel();
|
||||
self.ds_inhibit = None;
|
||||
}
|
||||
(true, None) => {
|
||||
let inhibitor = Inhibitor::init().await?;
|
||||
self.ds_inhibit = Some(daemon.add_service(inhibitor));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl DaemonContext for RootContext {
|
||||
type State = RootState;
|
||||
|
@ -79,19 +131,31 @@ impl DaemonContext for RootContext {
|
|||
|
||||
async fn handle_command(
|
||||
&mut self,
|
||||
_cmd: RootCommand,
|
||||
_daemon: &mut Daemon<RootContext>,
|
||||
cmd: RootCommand,
|
||||
daemon: &mut Daemon<RootContext>,
|
||||
) -> Result<()> {
|
||||
match cmd {
|
||||
RootCommand::SetDsInhibit(enable) => {
|
||||
self.state.services.ds_inhibit.enabled = enable;
|
||||
self.reload_ds_inhibit(daemon).await?;
|
||||
self.channel.send(DaemonCommand::WriteState).await?;
|
||||
}
|
||||
RootCommand::GetDsInhibit(sender) => {
|
||||
let _ = sender.send(self.ds_inhibit.is_some());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_connection() -> Result<Connection> {
|
||||
pub(crate) type Command = DaemonCommand<RootCommand>;
|
||||
|
||||
async fn create_connection(channel: Sender<Command>) -> Result<Connection> {
|
||||
let connection = ConnectionBuilder::system()?
|
||||
.name("com.steampowered.SteamOSManager1")?
|
||||
.build()
|
||||
.await?;
|
||||
let manager = SteamOSManager::new(connection.clone()).await?;
|
||||
let manager = SteamOSManager::new(connection.clone(), channel).await?;
|
||||
connection
|
||||
.object_server()
|
||||
.at("/com/steampowered/SteamOSManager1", manager)
|
||||
|
@ -105,9 +169,9 @@ pub async fn daemon() -> Result<()> {
|
|||
|
||||
let stdout_log = fmt::layer();
|
||||
let subscriber = Registry::default().with(stdout_log);
|
||||
let (_tx, rx) = channel::<RootContext>();
|
||||
let (tx, rx) = channel::<RootContext>();
|
||||
|
||||
let connection = match create_connection().await {
|
||||
let connection = match create_connection(tx.clone()).await {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
let _guard = tracing::subscriber::set_default(subscriber);
|
||||
|
@ -116,14 +180,11 @@ pub async fn daemon() -> Result<()> {
|
|||
}
|
||||
};
|
||||
|
||||
let context = RootContext {};
|
||||
let context = RootContext::new(tx);
|
||||
let mut daemon = Daemon::new(subscriber, connection.clone(), rx).await?;
|
||||
|
||||
let ftrace = Ftrace::init(connection.clone()).await?;
|
||||
let ftrace = Ftrace::init(connection).await?;
|
||||
daemon.add_service(ftrace);
|
||||
|
||||
let inhibitor = Inhibitor::init().await?;
|
||||
daemon.add_service(inhibitor);
|
||||
|
||||
daemon.run(context).await
|
||||
}
|
||||
|
|
|
@ -8,10 +8,14 @@
|
|||
|
||||
use anyhow::Result;
|
||||
use tokio::fs::File;
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tokio::sync::oneshot;
|
||||
use tracing::error;
|
||||
use zbus::zvariant::Fd;
|
||||
use zbus::{fdo, interface, Connection, SignalContext};
|
||||
|
||||
use crate::daemon::root::{Command, RootCommand};
|
||||
use crate::daemon::DaemonCommand;
|
||||
use crate::error::{to_zbus_error, to_zbus_fdo_error};
|
||||
use crate::hardware::{variant, FanControl, FanControlState, HardwareVariant};
|
||||
use crate::power::{
|
||||
|
@ -34,6 +38,7 @@ enum PrepareFactoryReset {
|
|||
|
||||
pub struct SteamOSManager {
|
||||
connection: Connection,
|
||||
channel: Sender<Command>,
|
||||
wifi_debug_mode: WifiDebugMode,
|
||||
fan_control: FanControl,
|
||||
// Whether we should use trace-cmd or not.
|
||||
|
@ -43,13 +48,14 @@ pub struct SteamOSManager {
|
|||
}
|
||||
|
||||
impl SteamOSManager {
|
||||
pub async fn new(connection: Connection) -> Result<Self> {
|
||||
pub async fn new(connection: Connection, channel: Sender<Command>) -> Result<Self> {
|
||||
Ok(SteamOSManager {
|
||||
fan_control: FanControl::new(connection.clone()),
|
||||
wifi_debug_mode: WifiDebugMode::Off,
|
||||
should_trace: variant().await? == HardwareVariant::Galileo,
|
||||
process_manager: ProcessManager::new(connection.clone()),
|
||||
connection,
|
||||
channel,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -260,6 +266,30 @@ impl SteamOSManager {
|
|||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn inhibit_ds(&self) -> fdo::Result<bool> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.channel
|
||||
.send(DaemonCommand::ContextCommand(RootCommand::GetDsInhibit(tx)))
|
||||
.await
|
||||
.inspect_err(|message| error!("Error sending GetDsInhibit command: {message}"))
|
||||
.map_err(to_zbus_fdo_error)?;
|
||||
rx.await
|
||||
.inspect_err(|message| error!("Error receiving GetDsInhibit reply: {message}"))
|
||||
.map_err(to_zbus_fdo_error)
|
||||
}
|
||||
|
||||
#[zbus(property)]
|
||||
async fn set_inhibit_ds(&self, enable: bool) -> zbus::Result<()> {
|
||||
self.channel
|
||||
.send(DaemonCommand::ContextCommand(RootCommand::SetDsInhibit(
|
||||
enable,
|
||||
)))
|
||||
.await
|
||||
.inspect_err(|message| error!("Error sending SetDsInhibit command: {message}"))
|
||||
.map_err(to_zbus_error)
|
||||
}
|
||||
|
||||
/// A version property.
|
||||
#[zbus(property(emits_changed_signal = "const"))]
|
||||
async fn version(&self) -> u32 {
|
||||
|
@ -270,6 +300,8 @@ impl SteamOSManager {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::daemon::channel;
|
||||
use crate::daemon::root::RootContext;
|
||||
use crate::power::test::{format_clocks, read_clocks};
|
||||
use crate::power::{self, get_gpu_performance_level};
|
||||
use crate::testing;
|
||||
|
@ -293,8 +325,9 @@ mod test {
|
|||
)
|
||||
.await?;
|
||||
|
||||
let (tx, _rx) = channel::<RootContext>();
|
||||
let connection = ConnectionBuilder::session()?.build().await?;
|
||||
let manager = SteamOSManager::new(connection.clone()).await?;
|
||||
let manager = SteamOSManager::new(connection.clone(), tx).await?;
|
||||
connection
|
||||
.object_server()
|
||||
.at("/com/steampowered/SteamOSManager1", manager)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue