From 7939b00aa3811b3b34326fc646e38ccc0936f496 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Sat, 24 Sep 2022 14:34:15 +1200 Subject: [PATCH] Check inotify paths are valid. Add dgu/egpu/ac_online checks --- CHANGELOG.md | 9 ++++ Cargo.lock | 2 +- asus-notify/src/main.rs | 2 +- daemon/Cargo.toml | 2 +- daemon/src/ctrl_platform.rs | 73 ++++++++++++++++++++++++++++++- daemon/src/ctrl_power.rs | 37 +++++++++++++++- daemon/src/daemon.rs | 2 +- daemon/src/lib.rs | 22 ++++++---- rog-control-center/src/mocking.rs | 6 +-- rog-control-center/src/notify.rs | 2 +- rog-dbus/src/zbus_platform.rs | 44 ++++++++++++++----- rog-dbus/src/zbus_power.rs | 7 +++ rog-platform/src/error.rs | 12 ++++- rog-platform/src/hid_raw.rs | 10 +++-- rog-platform/src/lib.rs | 6 +-- rog-platform/src/macros.rs | 16 +++++-- rog-platform/src/power.rs | 1 + 17 files changed, 210 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a203535..c4df0bcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `platform_profile` - keyboard brightness - These allow for updating any associated config and sending dbus notifications. +- New dbus methods + - `DgpuDisable` + - `SetDgpuDisable` + - `NotifyDgpuDisable` + - `EgpuEnable` + - `SetEgpuEnable` + - `NotifyEgpuEnable` + - `MainsOnline` (This is AC, check if plugged in or not) + - `NotifyMainsOnline` ### Changed - Use loops to ensure that mutex is gained for LED changes. - asusctl now uses tokio for async runtime. This helps simplify some code. diff --git a/Cargo.lock b/Cargo.lock index ac355b19..ca9e659b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -572,7 +572,7 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" [[package]] name = "daemon" -version = "4.5.0-rc2" +version = "4.5.0-rc3" dependencies = [ "async-trait", "concat-idents", diff --git a/asus-notify/src/main.rs b/asus-notify/src/main.rs index 3d0016d1..bfd64f18 100644 --- a/asus-notify/src/main.rs +++ b/asus-notify/src/main.rs @@ -54,7 +54,7 @@ fn main() -> Result<(), Box> { p.for_each(|e| { if let Ok(out) = e.args() { if let Ok(ref mut lock) = x.try_lock() { - notify!(do_post_sound_notif, lock, &out.sound()); + notify!(do_post_sound_notif, lock, &out.on()); } } future::ready(()) diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index d1f69bcf..5177b65a 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "daemon" -version = "4.5.0-rc2" +version = "4.5.0-rc3" license = "MPL-2.0" readme = "README.md" authors = ["Luke "] diff --git a/daemon/src/ctrl_platform.rs b/daemon/src/ctrl_platform.rs index 27c00e7d..77063d30 100644 --- a/daemon/src/ctrl_platform.rs +++ b/daemon/src/ctrl_platform.rs @@ -225,7 +225,7 @@ impl CtrlPlatform { .platform .get_panel_od() .map_err(|err| { - warn!("CtrlRogBios: get panel overdrive {}", err); + warn!("CtrlRogBios: get_panel_od {}", err); err }) .unwrap_or(false); @@ -239,6 +239,73 @@ impl CtrlPlatform { #[dbus_interface(signal)] async fn notify_panel_od(signal_ctxt: &SignalContext<'_>, overdrive: bool) -> zbus::Result<()> { } + + async fn set_dgpu_disable( + &mut self, + #[zbus(signal_context)] ctxt: SignalContext<'_>, + disable: bool, + ) { + if self + .platform + .set_dgpu_disable(disable) + .map_err(|err| { + warn!("CtrlRogBios: set_dgpu_disable {}", err); + err + }) + .is_ok() + { + Self::notify_dgpu_disable(&ctxt, disable).await.ok(); + } + } + + fn dgpu_disable(&self) -> bool { + self.platform + .get_dgpu_disable() + .map_err(|err| { + warn!("CtrlRogBios: get_dgpu_disable {}", err); + err + }) + .unwrap_or(false) + } + + #[dbus_interface(signal)] + async fn notify_dgpu_disable( + signal_ctxt: &SignalContext<'_>, + disable: bool, + ) -> zbus::Result<()> { + } + + async fn set_egpu_enable( + &mut self, + #[zbus(signal_context)] ctxt: SignalContext<'_>, + enable: bool, + ) { + if self + .platform + .set_egpu_enable(enable) + .map_err(|err| { + warn!("CtrlRogBios: set_egpu_enable {}", err); + err + }) + .is_ok() + { + Self::notify_egpu_enable(&ctxt, enable).await.ok(); + } + } + + fn egpu_enable(&self) -> bool { + self.platform + .get_egpu_enable() + .map_err(|err| { + warn!("CtrlRogBios: get_egpu_enable {}", err); + err + }) + .unwrap_or(false) + } + + #[dbus_interface(signal)] + async fn notify_egpu_enable(signal_ctxt: &SignalContext<'_>, enable: bool) -> zbus::Result<()> { + } } #[async_trait] @@ -265,6 +332,8 @@ impl crate::Reloadable for CtrlPlatform { impl CtrlPlatform { task_watch_item!(panel_od platform); + task_watch_item!(dgpu_disable platform); + task_watch_item!(egpu_enable platform); task_watch_item!(gpu_mux_mode platform); } @@ -312,6 +381,8 @@ impl CtrlTask for CtrlPlatform { .await; self.watch_panel_od(signal_ctxt.clone()).await?; + self.watch_dgpu_disable(signal_ctxt.clone()).await?; + self.watch_egpu_enable(signal_ctxt.clone()).await?; self.watch_gpu_mux_mode(signal_ctxt.clone()).await?; Ok(()) diff --git a/daemon/src/ctrl_power.rs b/daemon/src/ctrl_power.rs index 268a3c0b..dab60300 100644 --- a/daemon/src/ctrl_power.rs +++ b/daemon/src/ctrl_power.rs @@ -7,6 +7,7 @@ use rog_platform::supported::ChargeSupportedFunctions; use std::sync::Arc; use zbus::dbus_interface; use zbus::export::futures_util::lock::Mutex; +use zbus::export::futures_util::StreamExt; use zbus::Connection; use zbus::SignalContext; @@ -74,11 +75,23 @@ impl CtrlPower { } } + fn mains_online(&self) -> bool { + if self.power.has_online() { + if let Ok(v) = self.power.get_online() { + return v == 1; + } + } + false + } + #[dbus_interface(signal)] async fn notify_charge_control_end_threshold( ctxt: &SignalContext<'_>, limit: u8, ) -> zbus::Result<()>; + + #[dbus_interface(signal)] + async fn notify_mains_online(ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()>; } #[async_trait] @@ -167,7 +180,29 @@ impl CtrlTask for CtrlPower { ) .await; - self.watch_charge_control_end_threshold(signal_ctxt).await?; + self.watch_charge_control_end_threshold(signal_ctxt.clone()) + .await?; + + let ctrl = self.clone(); + match ctrl.power.monitor_online() { + Ok(mut watch) => { + tokio::spawn(async move { + let mut buffer = [0; 32]; + watch + .event_stream(&mut buffer) + .unwrap() + .for_each(|_| async { + if let Ok(value) = ctrl.power.get_online() { + Self::notify_mains_online(&signal_ctxt, value == 1) + .await + .unwrap(); + } + }) + .await; + }); + } + Err(e) => info!("inotify watch failed: {}", e), + } Ok(()) } diff --git a/daemon/src/daemon.rs b/daemon/src/daemon.rs index e093dc1e..b9ced919 100644 --- a/daemon/src/daemon.rs +++ b/daemon/src/daemon.rs @@ -115,7 +115,7 @@ async fn start_daemon() -> Result<(), Box> { start_tasks(zbus, &mut connection).await?; } Err(err) => { - error!("AniMe control: {}", err); + info!("AniMe control: {}", err); } } diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index 31881edd..281e8d3c 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -56,16 +56,20 @@ macro_rules! task_watch_item { let ctrl = self.clone(); concat_idents::concat_idents!(watch_fn = monitor_, $name { - let mut watch = self.$self_inner.watch_fn()?; - tokio::spawn(async move { - let mut buffer = [0; 32]; - watch.event_stream(&mut buffer).unwrap().for_each(|_| async { - let value = ctrl.$name(); - concat_idents::concat_idents!(notif_fn = notify_, $name { - Self::notif_fn(&signal_ctxt, value).await.unwrap(); + match self.$self_inner.watch_fn() { + Ok(mut watch) => { + tokio::spawn(async move { + let mut buffer = [0; 32]; + watch.event_stream(&mut buffer).unwrap().for_each(|_| async { + let value = ctrl.$name(); + concat_idents::concat_idents!(notif_fn = notify_, $name { + Self::notif_fn(&signal_ctxt, value).await.unwrap(); + }); + }).await; }); - }).await; - }); + } + Err(e) => info!("inotify watch failed: {}. You can ignore this if your device does not support the feature", e), + } }); Ok(()) } diff --git a/rog-control-center/src/mocking.rs b/rog-control-center/src/mocking.rs index f6cd60b8..7291c44c 100644 --- a/rog-control-center/src/mocking.rs +++ b/rog-control-center/src/mocking.rs @@ -65,7 +65,7 @@ impl Bios { pub fn gpu_mux_mode(&self) -> Result { Ok(1) } - pub fn panel_overdrive(&self) -> Result { + pub fn panel_od(&self) -> Result { Ok(1) } pub fn set_post_boot_sound(&self, _b: bool) -> Result<()> { @@ -74,7 +74,7 @@ impl Bios { pub fn set_gpu_mux_mode(&self, _b: bool) -> Result<()> { Ok(()) } - pub fn set_panel_overdrive(&self, _b: bool) -> Result<()> { + pub fn set_panel_od(&self, _b: bool) -> Result<()> { Ok(()) } } @@ -217,7 +217,7 @@ impl Supported { rog_bios_ctrl: RogBiosSupportedFunctions { post_sound: true, dedicated_gfx: true, - panel_overdrive: true, + panel_od: true, dgpu_disable: true, egpu_enable: true, }, diff --git a/rog-control-center/src/notify.rs b/rog-control-center/src/notify.rs index 8c6fc275..a8cb83f7 100644 --- a/rog-control-center/src/notify.rs +++ b/rog-control-center/src/notify.rs @@ -70,7 +70,7 @@ pub fn start_notifications( if let Ok(out) = e.args() { if notifs_enabled1.load(Ordering::SeqCst) { if let Ok(ref mut lock) = last_notif.try_lock() { - notify!(do_post_sound_notif, lock, &out.sound()); + notify!(do_post_sound_notif, lock, &out.on()); } } bios_notified1.store(true, Ordering::SeqCst); diff --git a/rog-dbus/src/zbus_platform.rs b/rog-dbus/src/zbus_platform.rs index 404f3f37..b7824995 100644 --- a/rog-dbus/src/zbus_platform.rs +++ b/rog-dbus/src/zbus_platform.rs @@ -27,33 +27,53 @@ use zbus_macros::dbus_proxy; default_path = "/org/asuslinux/Platform" )] trait RogBios { - /// DedicatedGraphicMode method + /// DgpuDisable method + fn dgpu_disable(&self) -> zbus::Result; + + /// EgpuEnable method + fn egpu_enable(&self) -> zbus::Result; + + /// GpuMuxMode method fn gpu_mux_mode(&self) -> zbus::Result; + /// PanelOd method + fn panel_od(&self) -> zbus::Result; + /// PostBootSound method fn post_boot_sound(&self) -> zbus::Result; - /// SetDedicatedGraphicMode method + /// SetDgpuDisable method + fn set_dgpu_disable(&self, disable: bool) -> zbus::Result<()>; + + /// SetEgpuEnable method + fn set_egpu_enable(&self, enable: bool) -> zbus::Result<()>; + + /// SetGpuMuxMode method fn set_gpu_mux_mode(&self, mode: GpuMode) -> zbus::Result<()>; + /// SetPanelOd method + fn set_panel_od(&self, overdrive: bool) -> zbus::Result<()>; + /// SetPostBootSound method fn set_post_boot_sound(&self, on: bool) -> zbus::Result<()>; - /// PanelOverdrive method - fn panel_od(&self) -> zbus::Result; + /// NotifyDgpuDisable signal + #[dbus_proxy(signal)] + fn notify_dgpu_disable(&self, disable: bool) -> zbus::Result<()>; - /// SetPanelOverdrive method - fn set_panel_od(&self, overdrive: bool) -> zbus::Result<()>; + /// NotifyEgpuEnable signal + #[dbus_proxy(signal)] + fn notify_egpu_enable(&self, enable: bool) -> zbus::Result<()>; - /// NotifyDedicatedGraphicMode signal + /// NotifyGpuMuxMode signal #[dbus_proxy(signal)] fn notify_gpu_mux_mode(&self, mode: GpuMode) -> zbus::Result<()>; - /// NotifyPostBootSound signal - #[dbus_proxy(signal)] - fn notify_post_boot_sound(&self, sound: bool) -> zbus::Result<()>; - - /// NotifyPanelOverdrive signal + /// NotifyPanelOd signal #[dbus_proxy(signal)] fn notify_panel_od(&self, overdrive: bool) -> zbus::Result<()>; + + /// NotifyPostBootSound signal + #[dbus_proxy(signal)] + fn notify_post_boot_sound(&self, on: bool) -> zbus::Result<()>; } diff --git a/rog-dbus/src/zbus_power.rs b/rog-dbus/src/zbus_power.rs index 4b242d83..37359c92 100644 --- a/rog-dbus/src/zbus_power.rs +++ b/rog-dbus/src/zbus_power.rs @@ -29,10 +29,17 @@ trait Power { /// charge_control_end_threshold method fn charge_control_end_threshold(&self) -> zbus::Result; + /// MainsOnline method + fn mains_online(&self) -> zbus::Result; + /// set_charge_control_end_threshold method fn set_charge_control_end_threshold(&self, limit: u8) -> zbus::Result<()>; /// NotifyCharge signal #[dbus_proxy(signal)] fn notify_charge_control_end_threshold(&self, limit: u8) -> zbus::Result; + + /// NotifyMainsOnline signal + #[dbus_proxy(signal)] + fn notify_mains_online(&self, on: bool) -> zbus::Result<()>; } diff --git a/rog-platform/src/error.rs b/rog-platform/src/error.rs index 9be403da..08be205b 100644 --- a/rog-platform/src/error.rs +++ b/rog-platform/src/error.rs @@ -15,7 +15,8 @@ pub enum PlatformError { AttrNotFound(String), MissingFunction(String), MissingLedBrightNode(String, std::io::Error), - Io(String, std::io::Error), + IoPath(String, std::io::Error), + Io(std::io::Error), NoAuraKeyboard, NoAuraNode, } @@ -33,9 +34,10 @@ impl fmt::Display for PlatformError { PlatformError::Write(path, error) => write!(f, "Write {}: {}", path, error), PlatformError::NotSupported => write!(f, "Not supported"), PlatformError::AttrNotFound(deets) => write!(f, "Attribute not found: {}", deets), + PlatformError::Io(deets) => write!(f, "std::io error: {}", deets), PlatformError::MissingFunction(deets) => write!(f, "Missing functionality: {}", deets), PlatformError::MissingLedBrightNode(path, error) => write!(f, "Led node at {} is missing, please check you have the required patch or dkms module installed: {}", path, error), - PlatformError::Io(path, detail) => write!(f, "std::io error: {} {}", path, detail), + PlatformError::IoPath(path, detail) => write!(f, "{} {}", path, detail), PlatformError::NoAuraKeyboard => write!(f, "No supported Aura keyboard"), PlatformError::NoAuraNode => write!(f, "No Aura keyboard node found"), } @@ -49,3 +51,9 @@ impl From for PlatformError { PlatformError::USB(err) } } + +impl From for PlatformError { + fn from(err: std::io::Error) -> Self { + PlatformError::Io(err) + } +} diff --git a/rog-platform/src/hid_raw.rs b/rog-platform/src/hid_raw.rs index d332bb8a..a793b852 100644 --- a/rog-platform/src/hid_raw.rs +++ b/rog-platform/src/hid_raw.rs @@ -21,11 +21,13 @@ impl HidRaw { for device in enumerator .scan_devices() - .map_err(|e| PlatformError::Io("enumerator".to_owned(), e))? + .map_err(|e| PlatformError::IoPath("enumerator".to_owned(), e))? { if let Some(parent) = device .parent_with_subsystem_devtype("usb", "usb_device") - .map_err(|e| PlatformError::Io(device.devpath().to_string_lossy().to_string(), e))? + .map_err(|e| { + PlatformError::IoPath(device.devpath().to_string_lossy().to_string(), e) + })? { if let Some(parent) = parent.attribute_value("idProduct") { if parent == id_product { @@ -47,9 +49,9 @@ impl HidRaw { let mut file = OpenOptions::new() .write(true) .open(&self.0) - .map_err(|e| PlatformError::Io(self.0.to_string_lossy().to_string(), e))?; + .map_err(|e| PlatformError::IoPath(self.0.to_string_lossy().to_string(), e))?; // println!("write: {:02x?}", &message); file.write_all(message) - .map_err(|e| PlatformError::Io(self.0.to_string_lossy().to_string(), e)) + .map_err(|e| PlatformError::IoPath(self.0.to_string_lossy().to_string(), e)) } } diff --git a/rog-platform/src/lib.rs b/rog-platform/src/lib.rs index 88962bc8..8c118860 100644 --- a/rog-platform/src/lib.rs +++ b/rog-platform/src/lib.rs @@ -45,7 +45,7 @@ pub fn read_attr_bool(device: &Device, attr_name: &str) -> Result { pub fn write_attr_bool(device: &mut Device, attr: &str, value: bool) -> Result<()> { device .set_attribute_value(attr, &(value as u8).to_string()) - .map_err(|e| PlatformError::Io(attr.into(), e)) + .map_err(|e| PlatformError::IoPath(attr.into(), e)) } pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result { @@ -59,7 +59,7 @@ pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result { pub fn write_attr_u8(device: &mut Device, attr: &str, value: u8) -> Result<()> { device .set_attribute_value(attr, &(value).to_string()) - .map_err(|e| PlatformError::Io(attr.into(), e)) + .map_err(|e| PlatformError::IoPath(attr.into(), e)) } pub fn read_attr_u8_array(device: &Device, attr_name: &str) -> Result> { @@ -79,7 +79,7 @@ pub fn write_attr_u8_array(device: &mut Device, attr: &str, values: &[u8]) -> Re let tmp = tmp.trim(); device .set_attribute_value(attr, &tmp) - .map_err(|e| PlatformError::Io(attr.into(), e)) + .map_err(|e| PlatformError::IoPath(attr.into(), e)) } #[cfg(test)] diff --git a/rog-platform/src/macros.rs b/rog-platform/src/macros.rs index e9bf431a..0989b290 100644 --- a/rog-platform/src/macros.rs +++ b/rog-platform/src/macros.rs @@ -21,9 +21,19 @@ macro_rules! watch_attr { pub fn fn_name(&self) -> Result { let mut path = self.$item.clone(); path.push($attr_name); - let mut inotify = inotify::Inotify::init().unwrap(); - inotify.add_watch(path.to_str().unwrap(), inotify::WatchMask::MODIFY).unwrap(); - Ok(inotify) + if let Some(path) = path.to_str() { + let mut inotify = inotify::Inotify::init()?; + inotify.add_watch(path, inotify::WatchMask::MODIFY) + .map_err(|e| { + if e.kind() == std::io::ErrorKind::NotFound { + PlatformError::AttrNotFound(format!("{}", $attr_name)) + } else { + PlatformError::IoPath(format!("{}", path), e) + } + })?; + return Ok(inotify); + } + Err(PlatformError::AttrNotFound(format!("{}", $attr_name))) } }); }; diff --git a/rog-platform/src/power.rs b/rog-platform/src/power.rs index d74633ff..ce25b525 100644 --- a/rog-platform/src/power.rs +++ b/rog-platform/src/power.rs @@ -102,4 +102,5 @@ impl AsusPower { } attr_u8!("charge_control_end_threshold", battery); + attr_u8!("online", mains); }