Fluke/dbus refactor

This commit is contained in:
Luke Jones
2023-12-03 20:44:01 +00:00
parent f6e4cc0626
commit 0a69c23288
143 changed files with 5421 additions and 10343 deletions

View File

@@ -6,34 +6,36 @@ use config_traits::StdConfig;
use log::{debug, error, info, warn};
use rog_aura::advanced::UsbPackets;
use rog_aura::usb::{AuraDevice, AuraPowerDev};
use rog_aura::{AuraEffect, AuraModeNum, LedBrightness};
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
use zbus::export::futures_util::StreamExt;
use zbus::fdo::Error as ZbErr;
use zbus::{dbus_interface, Connection, SignalContext};
use super::controller::CtrlKbdLed;
use crate::error::RogError;
use crate::CtrlTask;
pub(super) const ZBUS_PATH: &str = "/org/asuslinux/Aura";
pub const AURA_ZBUS_NAME: &str = "Aura";
pub const AURA_ZBUS_PATH: &str = "/org/asuslinux/Aura";
#[derive(Clone)]
pub struct CtrlKbdLedZbus(pub Arc<Mutex<CtrlKbdLed>>);
pub struct CtrlAuraZbus(pub Arc<Mutex<CtrlKbdLed>>);
impl CtrlKbdLedZbus {
impl CtrlAuraZbus {
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
let bright = lock.kd_brightness.get_brightness()?;
let bright = lock.sysfs_node.get_brightness()?;
lock.config.read();
lock.config.brightness = (bright as u32).into();
lock.config.brightness = bright.into();
lock.config.write();
Ok(())
}
}
#[async_trait]
impl crate::ZbusRun for CtrlKbdLedZbus {
impl crate::ZbusRun for CtrlAuraZbus {
async fn add_to_server(self, server: &mut Connection) {
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
Self::add_to_server_helper(self, AURA_ZBUS_PATH, server).await;
}
}
@@ -41,25 +43,130 @@ impl crate::ZbusRun for CtrlKbdLedZbus {
///
/// LED commands are split between Brightness, Modes, Per-Key
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl CtrlKbdLedZbus {
/// Set the keyboard brightness level (0-3)
async fn set_brightness(&mut self, brightness: LedBrightness) {
impl CtrlAuraZbus {
/// Return the device type for this Aura keyboard
#[dbus_interface(property)]
async fn device_type(&self) -> AuraDevice {
let ctrl = self.0.lock().await;
ctrl.set_brightness(brightness)
.map_err(|err| warn!("{}", err))
.ok();
ctrl.led_prod
}
/// Return the current LED brightness
#[dbus_interface(property)]
async fn brightness(&self) -> Result<LedBrightness, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.sysfs_node.get_brightness().map(|n| n.into())?)
}
/// Set the keyboard brightness level (0-3)
#[dbus_interface(property)]
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.sysfs_node.set_brightness(brightness.into())?)
}
/// Total levels of brightness available
#[dbus_interface(property)]
async fn supported_brightness(&self) -> Vec<LedBrightness> {
vec![
LedBrightness::Off,
LedBrightness::Low,
LedBrightness::Med,
LedBrightness::High,
]
}
/// The total available modes
#[dbus_interface(property)]
async fn supported_modes(&self) -> Result<Vec<AuraModeNum>, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.config.builtins.keys().cloned().collect())
}
/// The current mode data
#[dbus_interface(property)]
async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> {
let ctrl = self.0.lock().await;
Ok(ctrl.config.current_mode)
}
/// Set an Aura effect if the effect mode or zone is supported.
///
/// On success the aura config file is read to refresh cached values, then
/// the effect is stored and config written to disk.
#[dbus_interface(property)]
async fn set_led_mode(&mut self, num: AuraModeNum) -> Result<(), ZbErr> {
let mut ctrl = self.0.lock().await;
ctrl.config.current_mode = num;
ctrl.write_current_config_mode()?;
if ctrl.config.brightness == LedBrightness::Off {
ctrl.config.brightness = LedBrightness::Med;
}
ctrl.sysfs_node
.set_brightness(ctrl.config.brightness.into())?;
ctrl.config.write();
Ok(())
}
/// The current mode data
#[dbus_interface(property)]
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
let ctrl = self.0.lock().await;
let mode = ctrl.config.current_mode;
match ctrl.config.builtins.get(&mode) {
Some(effect) => Ok(effect.clone()),
None => Err(ZbErr::Failed("Could not get the current effect".into())),
}
}
/// Set an Aura effect if the effect mode or zone is supported.
///
/// On success the aura config file is read to refresh cached values, then
/// the effect is stored and config written to disk.
#[dbus_interface(property)]
async fn set_led_mode_data(&mut self, effect: AuraEffect) -> Result<(), ZbErr> {
let mut ctrl = self.0.lock().await;
if !ctrl.supported_modes.basic_modes.contains(&effect.mode)
|| effect.zone != AuraZone::None
&& !ctrl.supported_modes.basic_zones.contains(&effect.zone)
{
return Err(ZbErr::NotSupported(format!(
"The Aura effect is not supported: {effect:?}"
)));
}
ctrl.write_mode(&effect)?;
if ctrl.config.brightness == LedBrightness::Off {
ctrl.config.brightness = LedBrightness::Med;
}
ctrl.sysfs_node
.set_brightness(ctrl.config.brightness.into())?;
ctrl.config.set_builtin(effect);
ctrl.config.write();
Ok(())
}
/// Get the data set for every mode available
async fn all_mode_data(&self) -> BTreeMap<AuraModeNum, AuraEffect> {
let ctrl = self.0.lock().await;
ctrl.config.builtins.clone()
}
// As property doesn't work for AuraPowerDev (complexity of serialization?)
#[dbus_interface(property)]
async fn led_power(&self) -> AuraPowerDev {
let ctrl = self.0.lock().await;
AuraPowerDev::from(&ctrl.config.enabled)
}
/// Set a variety of states, input is array of enum.
/// `enabled` sets if the sent array should be disabled or enabled
///
/// For Modern ROG devices the "enabled" flag is ignored.
async fn set_led_power(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
options: AuraPowerDev,
enabled: bool,
) -> zbus::fdo::Result<()> {
#[dbus_interface(property)]
async fn set_led_power(&mut self, options: (AuraPowerDev, bool)) -> Result<(), ZbErr> {
let enabled = options.1;
let options = options.0;
let mut ctrl = self.0.lock().await;
for p in options.tuf {
ctrl.config.enabled.set_tuf(p, enabled);
@@ -68,158 +175,27 @@ impl CtrlKbdLedZbus {
ctrl.config.enabled.set_0x1866(p, enabled);
}
ctrl.config.enabled.set_0x19b6(options.rog);
ctrl.config.write();
ctrl.set_power_states().map_err(|e| {
Ok(ctrl.set_power_states().map_err(|e| {
warn!("{}", e);
e
})?;
Self::notify_power_states(&ctxt, &AuraPowerDev::from(&ctrl.config.enabled))
.await
.unwrap_or_else(|err| warn!("{}", err));
Ok(())
}
async fn set_led_mode(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
effect: AuraEffect,
) -> zbus::fdo::Result<()> {
let mut ctrl = self.0.lock().await;
ctrl.set_effect(effect).map_err(|e| {
warn!("{}", e);
e
})?;
ctrl.set_brightness(ctrl.config.brightness).map_err(|e| {
warn!("{}", e);
e
})?;
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
Self::notify_led(&ctxt, mode.clone())
.await
.unwrap_or_else(|err| warn!("{}", err));
}
Ok(())
}
async fn next_led_mode(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
) -> zbus::fdo::Result<()> {
let mut ctrl = self.0.lock().await;
ctrl.toggle_mode(false).map_err(|e| {
warn!("{}", e);
e
})?;
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
Self::notify_led(&ctxt, mode.clone())
.await
.unwrap_or_else(|err| warn!("{}", err));
}
Ok(())
}
async fn prev_led_mode(
&self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
) -> zbus::fdo::Result<()> {
let mut ctrl = self.0.lock().await;
ctrl.toggle_mode(true).map_err(|e| {
warn!("{}", e);
e
})?;
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
Self::notify_led(&ctxt, mode.clone())
.await
.unwrap_or_else(|err| warn!("{}", err));
}
Ok(())
}
async fn next_led_brightness(&self) -> zbus::fdo::Result<()> {
let mut ctrl = self.0.lock().await;
ctrl.next_brightness().map_err(|e| {
warn!("{}", e);
e
})?;
Ok(())
}
async fn prev_led_brightness(&self) -> zbus::fdo::Result<()> {
let mut ctrl = self.0.lock().await;
ctrl.prev_brightness().map_err(|e| {
warn!("{}", e);
e
})?;
Ok(())
}
/// Return the device type for this Aura keyboard
async fn device_type(&self) -> AuraDevice {
let ctrl = self.0.lock().await;
ctrl.led_prod
}
// As property doesn't work for AuraPowerDev (complexity of serialization?)
// #[dbus_interface(property)]
async fn led_power(&self) -> AuraPowerDev {
let ctrl = self.0.lock().await;
AuraPowerDev::from(&ctrl.config.enabled)
}
/// Return the current mode data
async fn led_mode(&self) -> AuraModeNum {
let ctrl = self.0.lock().await;
ctrl.config.current_mode
}
/// Return a list of available modes
async fn led_modes(&self) -> BTreeMap<AuraModeNum, AuraEffect> {
let ctrl = self.0.lock().await;
ctrl.config.builtins.clone()
})?)
}
/// On machine that have some form of either per-key keyboard or per-zone
/// this can be used to write custom effects over dbus. The input is a
/// nested `Vec<Vec<8>>` where `Vec<u8>` is a raw USB packet
async fn direct_addressing_raw(&self, data: UsbPackets) -> zbus::fdo::Result<()> {
async fn direct_addressing_raw(&self, data: UsbPackets) -> Result<(), ZbErr> {
let mut ctrl = self.0.lock().await;
ctrl.write_effect_block(&data)?;
Ok(())
}
/// Return the current LED brightness
#[dbus_interface(property)]
async fn led_brightness(&self) -> i8 {
let ctrl = self.0.lock().await;
ctrl.get_brightness().map(|n| n as i8).unwrap_or(-1)
}
#[dbus_interface(signal)]
async fn notify_led(signal_ctxt: &SignalContext<'_>, data: AuraEffect) -> zbus::Result<()>;
#[dbus_interface(signal)]
async fn notify_power_states(
signal_ctxt: &SignalContext<'_>,
data: &AuraPowerDev,
) -> zbus::Result<()>;
}
#[async_trait]
impl CtrlTask for CtrlKbdLedZbus {
impl CtrlTask for CtrlAuraZbus {
fn zbus_path() -> &'static str {
ZBUS_PATH
AURA_ZBUS_PATH
}
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
@@ -227,7 +203,8 @@ impl CtrlTask for CtrlKbdLedZbus {
// If waking up
if !start {
info!("CtrlKbdLedTask reloading brightness and modes");
lock.set_brightness(lock.config.brightness)
lock.sysfs_node
.set_brightness(lock.config.brightness.into())
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
.ok();
lock.write_current_config_mode()
@@ -270,7 +247,7 @@ impl CtrlTask for CtrlKbdLedZbus {
let ctrl2 = self.0.clone();
let ctrl = self.0.lock().await;
let watch = ctrl.kd_brightness.monitor_brightness()?;
let watch = ctrl.sysfs_node.monitor_brightness()?;
tokio::spawn(async move {
let mut buffer = [0; 32];
watch
@@ -289,7 +266,7 @@ impl CtrlTask for CtrlKbdLedZbus {
}
#[async_trait]
impl crate::Reloadable for CtrlKbdLedZbus {
impl crate::Reloadable for CtrlAuraZbus {
async fn reload(&mut self) -> Result<(), RogError> {
let mut ctrl = self.0.lock().await;
debug!("CtrlKbdLedZbus: reloading keyboard mode");