use std::sync; use tokio::sync::mpsc; use zbus::message::Header; use zbus::{fdo, interface}; pub(crate) struct Login1Session { pub sessions: sync::Arc>, pub requests: mpsc::Sender, } #[interface(name = "org.freedesktop.login1.Session")] impl Login1Session { async fn set_brightness( &self, subsystem: &str, name: &str, brightness: u32, #[zbus(connection)] connection: &zbus::Connection, #[zbus(header)] header: Header<'_>, ) -> fdo::Result<()> { let sender = header .sender() .ok_or_else(|| fdo::Error::Failed("D-Bus call has no sender".to_string()))?; let dbus = fdo::DBusProxy::new(connection) .await .map_err(|err| fdo::Error::Failed(err.to_string()))?; let credentials = dbus .get_connection_credentials(sender.to_owned().into()) .await .map_err(|err| fdo::Error::Failed(err.to_string()))?; let uid = credentials .unix_user_id() .ok_or_else(|| fdo::Error::Failed("caller UID unavailable".to_string()))?; let pid = credentials .process_id() .ok_or_else(|| fdo::Error::Failed("caller PID unavailable".to_string()))?; log::debug!( uid, pid, subsystem, name, brightness; "SetBrightness called", ); if !self .sessions .lock() .map_err(|_| fdo::Error::Failed("session state lock poisoned".to_string()))? .has_active_local_session(uid) { return Err(fdo::Error::AccessDenied(format!( "caller uid {uid} has no active local session", ))); } let (response, result) = tokio::sync::oneshot::channel(); self.requests .send(crate::BacklightRequest { subsystem: subsystem.to_string(), name: name.to_string(), brightness, response, }) .await .map_err(|_| { fdo::Error::Failed("sessiond backlight proxy is unavailable".to_string()) })?; result .await .map_err(|_| fdo::Error::Failed("sessiond backlight proxy disconnected".to_string()))? } }