mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Manage add/remove aura
Serialize aura config filename
This commit is contained in:
@@ -1,16 +1,13 @@
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
use config_traits::{StdConfig, StdConfigLoad};
|
||||
use log::{debug, warn};
|
||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
||||
use log::{debug, info};
|
||||
use rog_aura::aura_detection::LaptopLedData;
|
||||
use rog_aura::power::AuraPower;
|
||||
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
const CONFIG_FILE: &str = "aura.ron";
|
||||
|
||||
/// Enable/disable LED control in various states such as
|
||||
/// when the device is awake, suspended, shutting down or
|
||||
/// booting.
|
||||
@@ -107,6 +104,7 @@ impl From<&AuraPowerConfig> for AuraPowerDev {
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
// #[serde(default)]
|
||||
pub struct AuraConfig {
|
||||
pub config_name: String,
|
||||
pub brightness: LedBrightness,
|
||||
pub current_mode: AuraModeNum,
|
||||
pub builtins: BTreeMap<AuraModeNum, AuraEffect>,
|
||||
@@ -115,18 +113,18 @@ pub struct AuraConfig {
|
||||
pub enabled: AuraPowerConfig,
|
||||
}
|
||||
|
||||
impl AuraConfig {
|
||||
/// Detect the keyboard type and load from default DB if data available
|
||||
pub fn new_with(prod_id: AuraDevice) -> Self {
|
||||
info!("creating new AuraConfig");
|
||||
Self::from_default_support(prod_id, &LaptopLedData::get_data())
|
||||
}
|
||||
}
|
||||
|
||||
impl StdConfig for AuraConfig {
|
||||
/// Detect the keyboard type and load from default DB if data available
|
||||
fn new() -> Self {
|
||||
warn!("creating new config");
|
||||
let mut prod_id = AuraDevice::Unknown;
|
||||
for prod in ASUS_KEYBOARD_DEVICES {
|
||||
if HidRaw::new(prod.into()).is_ok() {
|
||||
prod_id = prod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Self::from_default_support(prod_id, &LaptopLedData::get_data())
|
||||
panic!("This should not be used");
|
||||
}
|
||||
|
||||
fn config_dir() -> std::path::PathBuf {
|
||||
@@ -134,13 +132,20 @@ impl StdConfig for AuraConfig {
|
||||
}
|
||||
|
||||
fn file_name(&self) -> String {
|
||||
CONFIG_FILE.to_owned()
|
||||
if self.config_name.is_empty() {
|
||||
panic!("Config file name should not be empty");
|
||||
}
|
||||
self.config_name.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl StdConfigLoad for AuraConfig {}
|
||||
|
||||
impl AuraConfig {
|
||||
pub fn set_filename(&mut self, prod_id: AuraDevice) {
|
||||
self.config_name = format!("aura_{prod_id:?}.ron");
|
||||
}
|
||||
|
||||
pub fn from_default_support(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
|
||||
// create a default config here
|
||||
let enabled = if prod_id.is_new_style() {
|
||||
@@ -162,6 +167,7 @@ impl AuraConfig {
|
||||
]))
|
||||
};
|
||||
let mut config = AuraConfig {
|
||||
config_name: format!("aura_{prod_id:?}.ron"),
|
||||
brightness: LedBrightness::Med,
|
||||
current_mode: AuraModeNum::Static,
|
||||
builtins: BTreeMap::new(),
|
||||
|
||||
@@ -1,37 +1,65 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use config_traits::{StdConfig, StdConfigLoad};
|
||||
use dmi_id::DMIID;
|
||||
use log::{info, warn};
|
||||
use inotify::Inotify;
|
||||
use log::info;
|
||||
use rog_aura::advanced::{LedUsbPackets, UsbPackets};
|
||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
||||
use rog_aura::usb::{AuraDevice, LED_APPLY, LED_SET};
|
||||
use rog_aura::{AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use rog_platform::keyboard_led::KeyboardLed;
|
||||
use zbus::zvariant::OwnedObjectPath;
|
||||
|
||||
use super::config::{AuraConfig, AuraPowerConfig};
|
||||
use crate::ctrl_aura::manager::dbus_path_for_dev;
|
||||
use crate::error::RogError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LEDNode {
|
||||
/// Brightness and/or TUF RGB controls
|
||||
KbdLed(KeyboardLed),
|
||||
Rog(HidRaw),
|
||||
None,
|
||||
/// Raw HID handle
|
||||
Rog(KeyboardLed, HidRaw),
|
||||
}
|
||||
|
||||
impl LEDNode {
|
||||
// TODO: move various methods upwards to this
|
||||
pub fn set_brightness(&self, value: u8) -> Result<(), RogError> {
|
||||
match self {
|
||||
LEDNode::KbdLed(k) => k.set_brightness(value)?,
|
||||
LEDNode::Rog(k, _) => k.set_brightness(value)?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_brightness(&self) -> Result<u8, RogError> {
|
||||
Ok(match self {
|
||||
LEDNode::KbdLed(k) => k.get_brightness()?,
|
||||
LEDNode::Rog(k, _) => k.get_brightness()?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn monitor_brightness(&self) -> Result<Inotify, RogError> {
|
||||
Ok(match self {
|
||||
LEDNode::KbdLed(k) => k.monitor_brightness()?,
|
||||
LEDNode::Rog(k, _) => k.monitor_brightness()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Individual controller for one Aura device
|
||||
pub struct CtrlKbdLed {
|
||||
// TODO: config stores the keyboard type as an AuraPower, use or update this
|
||||
pub led_prod: AuraDevice,
|
||||
pub led_node: LEDNode,
|
||||
pub sysfs_node: KeyboardLed,
|
||||
pub supported_data: LaptopLedData,
|
||||
pub supported_data: LaptopLedData, // TODO: is storing this really required?
|
||||
pub per_key_mode_active: bool,
|
||||
pub config: AuraConfig,
|
||||
pub dbus_path: OwnedObjectPath,
|
||||
}
|
||||
|
||||
impl CtrlKbdLed {
|
||||
pub fn new(supported_basic_modes: LaptopLedData) -> Result<Self, RogError> {
|
||||
pub fn new(data: LaptopLedData) -> Result<Self, RogError> {
|
||||
let mut led_prod = AuraDevice::Unknown;
|
||||
let mut usb_node = None;
|
||||
for prod in ASUS_KEYBOARD_DEVICES {
|
||||
@@ -52,32 +80,63 @@ impl CtrlKbdLed {
|
||||
}
|
||||
}
|
||||
|
||||
let mut dbus_path = Default::default();
|
||||
let rgb_led = KeyboardLed::new()?;
|
||||
|
||||
if usb_node.is_none() && !rgb_led.has_kbd_rgb_mode() {
|
||||
let dmi = DMIID::new().unwrap_or_default();
|
||||
if dmi.dmi_family.contains("TUF") {
|
||||
warn!(
|
||||
"kbd_rgb_mode was not found in the /sys/. You require a minimum 6.1 kernel \
|
||||
and a supported TUF laptop"
|
||||
);
|
||||
}
|
||||
return Err(RogError::NoAuraKeyboard);
|
||||
}
|
||||
|
||||
let led_node = if let Some(rog) = usb_node {
|
||||
info!("Found ROG USB keyboard");
|
||||
LEDNode::Rog(rog)
|
||||
dbus_path = dbus_path_for_dev(rog.1).unwrap_or_default();
|
||||
LEDNode::Rog(rgb_led, rog.0)
|
||||
} else if rgb_led.has_kbd_rgb_mode() {
|
||||
info!("Found TUF keyboard");
|
||||
LEDNode::KbdLed(rgb_led.clone())
|
||||
} else {
|
||||
LEDNode::None
|
||||
return Err(RogError::NoAuraKeyboard);
|
||||
// LEDNode::None
|
||||
};
|
||||
|
||||
// New loads data fromt he DB also
|
||||
let mut config_init = AuraConfig::new();
|
||||
// New loads data from the DB also
|
||||
let config = Self::init_config(led_prod, &data);
|
||||
|
||||
let ctrl = CtrlKbdLed {
|
||||
led_prod,
|
||||
led_node, // on TUF this is the same as rgb_led / kd_brightness
|
||||
supported_data: data,
|
||||
per_key_mode_active: false,
|
||||
config,
|
||||
dbus_path,
|
||||
};
|
||||
Ok(ctrl)
|
||||
}
|
||||
|
||||
pub fn from_device(
|
||||
device: HidRaw,
|
||||
dbus_path: OwnedObjectPath,
|
||||
data: LaptopLedData,
|
||||
) -> Result<Self, RogError> {
|
||||
let rgb_led = KeyboardLed::new()?;
|
||||
let prod_id = AuraDevice::from(device.prod_id());
|
||||
|
||||
// New loads data from the DB also
|
||||
let config = Self::init_config(prod_id, &data);
|
||||
|
||||
let ctrl = CtrlKbdLed {
|
||||
led_prod: prod_id,
|
||||
led_node: LEDNode::Rog(rgb_led, device), /* on TUF this is the same as rgb_led /
|
||||
* kd_brightness */
|
||||
supported_data: data,
|
||||
per_key_mode_active: false,
|
||||
config,
|
||||
dbus_path,
|
||||
};
|
||||
Ok(ctrl)
|
||||
}
|
||||
|
||||
fn init_config(prod_id: AuraDevice, supported_basic_modes: &LaptopLedData) -> AuraConfig {
|
||||
// New loads data from the DB also
|
||||
let mut config_init = AuraConfig::new_with(prod_id);
|
||||
// config_init.set_filename(prod_id);
|
||||
let mut config_loaded = config_init.clone().load();
|
||||
config_loaded.set_filename(prod_id);
|
||||
// update the initialised data with what we loaded from disk
|
||||
for mode in &mut config_init.builtins {
|
||||
// update init values from loaded values if they exist
|
||||
@@ -107,15 +166,7 @@ impl CtrlKbdLed {
|
||||
*multizone_loaded = multizone_init;
|
||||
}
|
||||
|
||||
let ctrl = CtrlKbdLed {
|
||||
led_prod,
|
||||
led_node, // on TUF this is the same as rgb_led / kd_brightness
|
||||
sysfs_node: rgb_led, // If was none then we already returned above
|
||||
supported_data: supported_basic_modes,
|
||||
per_key_mode_active: false,
|
||||
config: config_loaded,
|
||||
};
|
||||
Ok(ctrl)
|
||||
config_loaded
|
||||
}
|
||||
|
||||
/// Set combination state for boot animation/sleep animation/all leds/keys
|
||||
@@ -126,7 +177,7 @@ impl CtrlKbdLed {
|
||||
let buf = [1, pwr[1] as u8, pwr[2] as u8, pwr[3] as u8, pwr[4] as u8];
|
||||
platform.set_kbd_rgb_state(&buf)?;
|
||||
}
|
||||
} else if let LEDNode::Rog(hid_raw) = &self.led_node {
|
||||
} else if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||
let bytes = AuraPowerConfig::to_bytes(&self.config.enabled);
|
||||
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]];
|
||||
|
||||
@@ -152,20 +203,20 @@ impl CtrlKbdLed {
|
||||
|
||||
if pkt_type != PER_KEY_TYPE {
|
||||
self.per_key_mode_active = false;
|
||||
if let LEDNode::Rog(hid_raw) = &self.led_node {
|
||||
if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||
hid_raw.write_bytes(&effect[0])?;
|
||||
hid_raw.write_bytes(&LED_SET)?;
|
||||
// hid_raw.write_bytes(&LED_APPLY)?;
|
||||
}
|
||||
} else {
|
||||
if !self.per_key_mode_active {
|
||||
if let LEDNode::Rog(hid_raw) = &self.led_node {
|
||||
if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||
let init = LedUsbPackets::get_init_msg();
|
||||
hid_raw.write_bytes(&init)?;
|
||||
}
|
||||
self.per_key_mode_active = true;
|
||||
}
|
||||
if let LEDNode::Rog(hid_raw) = &self.led_node {
|
||||
if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||
for row in effect.iter() {
|
||||
hid_raw.write_bytes(row)?;
|
||||
}
|
||||
@@ -192,7 +243,7 @@ impl CtrlKbdLed {
|
||||
mode.speed as u8,
|
||||
];
|
||||
platform.set_kbd_rgb_mode(&buf)?;
|
||||
} else if let LEDNode::Rog(hid_raw) = &self.led_node {
|
||||
} else if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||
let bytes: [u8; LED_MSG_LEN] = mode.into();
|
||||
hid_raw.write_bytes(&bytes)?;
|
||||
hid_raw.write_bytes(&LED_SET)?;
|
||||
@@ -275,7 +326,9 @@ mod tests {
|
||||
use rog_aura::aura_detection::{LaptopLedData, PowerZones};
|
||||
use rog_aura::usb::AuraDevice;
|
||||
use rog_aura::{AuraModeNum, AuraZone};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use rog_platform::keyboard_led::KeyboardLed;
|
||||
use zbus::zvariant::OwnedObjectPath;
|
||||
|
||||
use super::CtrlKbdLed;
|
||||
use crate::ctrl_aura::config::AuraConfig;
|
||||
@@ -295,11 +348,11 @@ mod tests {
|
||||
};
|
||||
let mut controller = CtrlKbdLed {
|
||||
led_prod: AuraDevice::X19b6,
|
||||
led_node: LEDNode::None,
|
||||
sysfs_node: KeyboardLed::default(),
|
||||
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("id_product").unwrap()),
|
||||
supported_data: supported_basic_modes,
|
||||
per_key_mode_active: false,
|
||||
config,
|
||||
dbus_path: OwnedObjectPath::default(),
|
||||
};
|
||||
|
||||
assert!(controller.config.multizone.is_none());
|
||||
@@ -333,11 +386,11 @@ mod tests {
|
||||
};
|
||||
let mut controller = CtrlKbdLed {
|
||||
led_prod: AuraDevice::X19b6,
|
||||
led_node: LEDNode::None,
|
||||
sysfs_node: KeyboardLed::default(),
|
||||
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("id_product").unwrap()),
|
||||
supported_data: supported_basic_modes,
|
||||
per_key_mode_active: false,
|
||||
config,
|
||||
dbus_path: OwnedObjectPath::default(),
|
||||
};
|
||||
|
||||
assert!(controller.config.multizone.is_none());
|
||||
|
||||
203
asusd/src/ctrl_aura/manager.rs
Normal file
203
asusd/src/ctrl_aura/manager.rs
Normal file
@@ -0,0 +1,203 @@
|
||||
// Plan:
|
||||
// - Manager has udev monitor on USB looking for ROG devices
|
||||
// - If a device is found, add it to watch
|
||||
// - Add it to Zbus server
|
||||
// - If udev sees device removed then remove the zbus path
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
use log::{error, info, warn};
|
||||
use mio::{Events, Interest, Poll, Token};
|
||||
use rog_aura::aura_detection::LaptopLedData;
|
||||
use rog_aura::usb::AuraDevice;
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use tokio::sync::Mutex;
|
||||
use udev::{Device, MonitorBuilder};
|
||||
// use zbus::fdo::ObjectManager;
|
||||
use zbus::object_server::SignalContext;
|
||||
use zbus::zvariant::{ObjectPath, OwnedObjectPath};
|
||||
use zbus::Connection;
|
||||
|
||||
use crate::ctrl_aura::controller::CtrlKbdLed;
|
||||
use crate::ctrl_aura::trait_impls::{CtrlAuraZbus, AURA_ZBUS_PATH};
|
||||
use crate::error::RogError;
|
||||
use crate::{CtrlTask, Reloadable};
|
||||
|
||||
pub struct AuraManager {
|
||||
_connection: Connection,
|
||||
_interfaces: Arc<Mutex<HashSet<OwnedObjectPath>>>,
|
||||
}
|
||||
|
||||
impl AuraManager {
|
||||
pub async fn new(mut connection: Connection) -> Result<Self, RogError> {
|
||||
let conn_copy = connection.clone();
|
||||
let data = LaptopLedData::get_data();
|
||||
|
||||
// Do the initial keyboard detection:
|
||||
match CtrlKbdLed::new(data.clone()) {
|
||||
Ok(ctrl) => {
|
||||
let path = ctrl.dbus_path.clone();
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
|
||||
let sig_ctx2 = sig_ctx.clone();
|
||||
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
||||
start_tasks(zbus, &mut connection, sig_ctx2, &path).await?;
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Keyboard control: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// connection.object_server().at("/org/asuslinux",
|
||||
// ObjectManager).await.unwrap();
|
||||
|
||||
let manager = Self {
|
||||
_connection: connection,
|
||||
_interfaces: Default::default(),
|
||||
};
|
||||
|
||||
// detect all plugged in aura devices (eventually)
|
||||
tokio::spawn(async move {
|
||||
let mut monitor = MonitorBuilder::new()?.match_subsystem("hidraw")?.listen()?;
|
||||
let mut poll = Poll::new()?;
|
||||
let mut events = Events::with_capacity(1024);
|
||||
poll.registry()
|
||||
.register(&mut monitor, Token(0), Interest::READABLE)?;
|
||||
|
||||
loop {
|
||||
poll.poll(&mut events, None).unwrap();
|
||||
for event in monitor.iter() {
|
||||
if let Some(parent) =
|
||||
event.parent_with_subsystem_devtype("usb", "usb_device")?
|
||||
{
|
||||
let action = if let Some(action) = event.action() {
|
||||
action
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if action == "remove" {
|
||||
if let Some(path) = dbus_path_for_dev(parent.clone()) {
|
||||
info!("AuraManager removing: {path:?}");
|
||||
let conn_copy = conn_copy.clone();
|
||||
tokio::spawn(async move {
|
||||
let res = conn_copy
|
||||
.object_server()
|
||||
.remove::<CtrlAuraZbus, _>(&path)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("Failed to remove {path:?}, {e:?}");
|
||||
e
|
||||
})?;
|
||||
info!("AuraManager removed: {path:?}, {res}");
|
||||
Ok::<(), RogError>(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let id_product =
|
||||
if let Some(id_product) = parent.attribute_value("idProduct") {
|
||||
id_product
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
if let Some(p2) = event.parent() {
|
||||
if let Some(driver) = p2.driver() {
|
||||
// There is a tree of devices added so filter by driver
|
||||
if driver != "asus" {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// try conversion to known idProduct
|
||||
let aura_device = AuraDevice::from(id_product.to_str().unwrap());
|
||||
if aura_device != AuraDevice::Unknown {
|
||||
if action == "add" {
|
||||
let dev_node = if let Some(dev_node) = event.devnode() {
|
||||
dev_node
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Ok(raw) = HidRaw::from_device(event.device())
|
||||
.map_err(|e| error!("device path error: {e:?}"))
|
||||
{
|
||||
let path = if let Some(path) = dbus_path_for_dev(parent) {
|
||||
path
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
if let Ok(ctrl) =
|
||||
CtrlKbdLed::from_device(raw, path.clone(), data.clone())
|
||||
{
|
||||
info!("AuraManager found device at: {:?}", dev_node);
|
||||
let mut conn_copy = conn_copy.clone();
|
||||
//
|
||||
tokio::spawn(async move {
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
||||
// Now add it to device list
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
start_tasks(zbus, &mut conn_copy, sig_ctx, &path)
|
||||
.await?;
|
||||
Ok::<(), RogError>(())
|
||||
}); // Can't get result from here due to
|
||||
// MonitorSocket
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("idProduct:{id_product:?} is unknown, not using")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Required for return type on tokio::spawn
|
||||
#[allow(unreachable_code)]
|
||||
Ok::<(), RogError>(())
|
||||
});
|
||||
Ok(manager)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn dbus_path_for_dev(parent: Device) -> Option<OwnedObjectPath> {
|
||||
if let Some(id_product) = parent.attribute_value("idProduct") {
|
||||
let id_product = id_product.to_string_lossy();
|
||||
let path = if let Some(devnum) = parent.attribute_value("devnum") {
|
||||
let devnum = devnum.to_string_lossy();
|
||||
if let Some(devpath) = parent.attribute_value("devpath") {
|
||||
let devpath = devpath.to_string_lossy();
|
||||
format!("{AURA_ZBUS_PATH}/{id_product}_{devnum}_{devpath}")
|
||||
} else {
|
||||
format!("{AURA_ZBUS_PATH}/{id_product}_{devnum}")
|
||||
}
|
||||
} else {
|
||||
format!("{AURA_ZBUS_PATH}/{id_product}")
|
||||
};
|
||||
return Some(ObjectPath::from_str_unchecked(&path).into());
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
async fn start_tasks(
|
||||
mut zbus: CtrlAuraZbus,
|
||||
connection: &mut Connection,
|
||||
signal_ctx: SignalContext<'static>,
|
||||
path: &ObjectPath<'static>,
|
||||
) -> Result<(), RogError> {
|
||||
let task = zbus.clone();
|
||||
zbus.reload()
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("Controller error: {}", err));
|
||||
|
||||
connection
|
||||
.object_server()
|
||||
.at(&ObjectPath::from_str_unchecked(path), zbus)
|
||||
.await
|
||||
.unwrap();
|
||||
task.create_tasks(signal_ctx).await.ok();
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod config;
|
||||
pub mod controller;
|
||||
pub mod manager;
|
||||
/// Implements `CtrlTask`, `Reloadable`, `ZbusRun`
|
||||
pub mod trait_impls;
|
||||
|
||||
@@ -10,24 +10,25 @@ 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::{interface, Connection, SignalContext};
|
||||
use zbus::{interface, SignalContext};
|
||||
|
||||
use super::controller::CtrlKbdLed;
|
||||
use crate::error::RogError;
|
||||
use crate::CtrlTask;
|
||||
|
||||
pub const AURA_ZBUS_NAME: &str = "Aura";
|
||||
pub const AURA_ZBUS_PATH: &str = "/org/asuslinux/Aura";
|
||||
pub const AURA_ZBUS_PATH: &str = "/org/asuslinux";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CtrlAuraZbus(
|
||||
pub Arc<Mutex<CtrlKbdLed>>,
|
||||
pub Option<SignalContext<'static>>,
|
||||
);
|
||||
pub struct CtrlAuraZbus(Arc<Mutex<CtrlKbdLed>>, SignalContext<'static>);
|
||||
|
||||
impl CtrlAuraZbus {
|
||||
pub fn new(controller: CtrlKbdLed, signal: SignalContext<'static>) -> Self {
|
||||
Self(Arc::new(Mutex::new(controller)), signal)
|
||||
}
|
||||
|
||||
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
|
||||
let bright = lock.sysfs_node.get_brightness()?;
|
||||
let bright = lock.led_node.get_brightness()?;
|
||||
lock.config.read();
|
||||
lock.config.brightness = bright.into();
|
||||
lock.config.write();
|
||||
@@ -35,16 +36,10 @@ impl CtrlAuraZbus {
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::ZbusRun for CtrlAuraZbus {
|
||||
async fn add_to_server(self, server: &mut Connection) {
|
||||
Self::add_to_server_helper(self, AURA_ZBUS_PATH, server).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// The main interface for changing, reading, or notfying
|
||||
///
|
||||
/// LED commands are split between Brightness, Modes, Per-Key
|
||||
#[interface(name = "org.asuslinux.Daemon")]
|
||||
#[interface(name = "org.asuslinux.Aura")]
|
||||
impl CtrlAuraZbus {
|
||||
/// Return the device type for this Aura keyboard
|
||||
#[zbus(property)]
|
||||
@@ -57,14 +52,14 @@ impl CtrlAuraZbus {
|
||||
#[zbus(property)]
|
||||
async fn brightness(&self) -> Result<LedBrightness, ZbErr> {
|
||||
let ctrl = self.0.lock().await;
|
||||
Ok(ctrl.sysfs_node.get_brightness().map(|n| n.into())?)
|
||||
Ok(ctrl.led_node.get_brightness().map(|n| n.into())?)
|
||||
}
|
||||
|
||||
/// Set the keyboard brightness level (0-3)
|
||||
#[zbus(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())?)
|
||||
Ok(ctrl.led_node.set_brightness(brightness.into())?)
|
||||
}
|
||||
|
||||
/// Total levels of brightness available
|
||||
@@ -116,13 +111,11 @@ impl CtrlAuraZbus {
|
||||
if ctrl.config.brightness == LedBrightness::Off {
|
||||
ctrl.config.brightness = LedBrightness::Med;
|
||||
}
|
||||
ctrl.sysfs_node
|
||||
ctrl.led_node
|
||||
.set_brightness(ctrl.config.brightness.into())?;
|
||||
ctrl.config.write();
|
||||
|
||||
if let Some(ct) = self.1.as_ref() {
|
||||
self.led_mode_data_invalidate(ct).await.ok();
|
||||
}
|
||||
self.led_mode_data_invalidate(&self.1).await.ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -157,14 +150,12 @@ impl CtrlAuraZbus {
|
||||
if ctrl.config.brightness == LedBrightness::Off {
|
||||
ctrl.config.brightness = LedBrightness::Med;
|
||||
}
|
||||
ctrl.sysfs_node
|
||||
ctrl.led_node
|
||||
.set_brightness(ctrl.config.brightness.into())?;
|
||||
ctrl.config.set_builtin(effect);
|
||||
ctrl.config.write();
|
||||
|
||||
if let Some(ct) = self.1.as_ref() {
|
||||
self.led_mode_invalidate(ct).await.ok();
|
||||
}
|
||||
self.led_mode_invalidate(&self.1).await.ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -215,7 +206,7 @@ impl CtrlAuraZbus {
|
||||
|
||||
impl CtrlTask for CtrlAuraZbus {
|
||||
fn zbus_path() -> &'static str {
|
||||
AURA_ZBUS_PATH
|
||||
"/org/asuslinux"
|
||||
}
|
||||
|
||||
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||
@@ -223,7 +214,7 @@ impl CtrlTask for CtrlAuraZbus {
|
||||
// If waking up
|
||||
if !start {
|
||||
info!("CtrlKbdLedTask reloading brightness and modes");
|
||||
lock.sysfs_node
|
||||
lock.led_node
|
||||
.set_brightness(lock.config.brightness.into())
|
||||
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
|
||||
.ok();
|
||||
@@ -267,7 +258,7 @@ impl CtrlTask for CtrlAuraZbus {
|
||||
|
||||
let ctrl2 = self.0.clone();
|
||||
let ctrl = self.0.lock().await;
|
||||
let watch = ctrl.sysfs_node.monitor_brightness()?;
|
||||
let watch = ctrl.led_node.monitor_brightness()?;
|
||||
tokio::spawn(async move {
|
||||
let mut buffer = [0; 32];
|
||||
watch
|
||||
|
||||
Reference in New Issue
Block a user