Make LED power more universal

Closes #219
This commit is contained in:
Luke D. Jones
2022-07-21 14:48:16 +12:00
parent bdbb403a0e
commit 02fb7addf4
9 changed files with 436 additions and 284 deletions

View File

@@ -1,6 +1,6 @@
use crate::laptops::LaptopLedData;
use log::{error, warn};
use rog_aura::usb::AuraControl;
use rog_aura::usb::{AuraDev1866, AuraDev19b6, AuraPowerDev};
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashSet};
@@ -9,6 +9,65 @@ use std::io::{Read, Write};
pub static AURA_CONFIG_PATH: &str = "/etc/asusd/aura.conf";
/// Enable/disable LED control in various states such as
/// when the device is awake, suspended, shutting down or
/// booting.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum AuraPowerConfig {
AuraDev1866(HashSet<AuraDev1866>),
AuraDev19b6(HashSet<AuraDev19b6>),
}
impl AuraPowerConfig {
pub fn to_bytes(control: &Self) -> [u8; 3] {
match control {
AuraPowerConfig::AuraDev1866(c) => {
let c: Vec<AuraDev1866> = c.iter().map(|v| *v).collect();
AuraDev1866::to_bytes(&c)
}
AuraPowerConfig::AuraDev19b6(c) => {
let c: Vec<AuraDev19b6> = c.iter().map(|v| *v).collect();
AuraDev19b6::to_bytes(&c)
}
}
}
pub fn set_0x1866(&mut self, power: AuraDev1866, on: bool) {
if let Self::AuraDev1866(p) = self {
if on {
p.insert(power);
} else {
p.remove(&power);
}
}
}
pub fn set_0x19b6(&mut self, power: AuraDev19b6, on: bool) {
if let Self::AuraDev19b6(p) = self {
if on {
p.insert(power);
} else {
p.remove(&power);
}
}
}
}
impl From<&AuraPowerConfig> for AuraPowerDev {
fn from(config: &AuraPowerConfig) -> Self {
match config {
AuraPowerConfig::AuraDev1866(d) => AuraPowerDev {
x1866: d.iter().map(|o| *o).collect(),
x19b6: vec![],
},
AuraPowerConfig::AuraDev19b6(d) => AuraPowerDev {
x1866: vec![],
x19b6: d.iter().map(|o| *o).collect(),
},
}
}
}
#[derive(Deserialize, Serialize)]
#[serde(default)]
pub struct AuraConfig {
@@ -17,7 +76,7 @@ pub struct AuraConfig {
pub builtins: BTreeMap<AuraModeNum, AuraEffect>,
pub multizone: Option<BTreeMap<AuraModeNum, Vec<AuraEffect>>>,
pub multizone_on: bool,
pub enabled: HashSet<AuraControl>,
pub enabled: AuraPowerConfig,
}
impl Default for AuraConfig {
@@ -28,20 +87,7 @@ impl Default for AuraConfig {
builtins: BTreeMap::new(),
multizone: None,
multizone_on: false,
enabled: HashSet::from([
AuraControl::BootLogo,
AuraControl::BootKeyb,
AuraControl::SleepLogo,
AuraControl::SleepKeyb,
AuraControl::AwakeLogo,
AuraControl::AwakeKeyb,
AuraControl::ShutdownLogo,
AuraControl::ShutdownKeyb,
AuraControl::AwakeBar,
AuraControl::BootBar,
AuraControl::SleepBar,
AuraControl::ShutdownBar,
]),
enabled: AuraPowerConfig::AuraDev1866(HashSet::new()),
}
}
}

View File

@@ -9,11 +9,11 @@ use crate::{
use async_trait::async_trait;
use log::{error, info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_aura::{usb::AuraControl, AuraZone, Direction, Speed, GRADIENT};
use rog_aura::{
usb::{LED_APPLY, LED_SET},
AuraEffect, LedBrightness, LED_MSG_LEN,
};
use rog_aura::{AuraZone, Direction, Speed, GRADIENT};
use rog_supported::LedSupportedFunctions;
use smol::{stream::StreamExt, Executor};
use std::path::Path;
@@ -28,7 +28,7 @@ use zbus::Connection;
use crate::GetSupported;
use super::config::AuraConfig;
use super::config::{AuraConfig, AuraPowerConfig};
impl GetSupported for CtrlKbdLed {
type A = LedSupportedFunctions;
@@ -40,7 +40,16 @@ impl GetSupported for CtrlKbdLed {
let multizone_led_mode = laptop.multizone;
let per_key_led_mode = laptop.per_key;
let mut prod_id = String::new();
for prod in ASUS_KEYBOARD_DEVICES.iter() {
if let Ok(_) = Self::find_led_node(prod) {
prod_id = prod.to_string();
break;
}
}
LedSupportedFunctions {
prod_id,
brightness_set: CtrlKbdLed::get_kbd_bright_path().is_some(),
stock_led_modes,
multizone_led_mode,
@@ -50,6 +59,8 @@ impl GetSupported for CtrlKbdLed {
}
pub struct CtrlKbdLed {
// TODO: config stores the keyboard type as an AuraPower, use or update this
pub led_prod: Option<String>,
pub led_node: Option<String>,
pub bright_node: String,
pub supported_modes: LaptopLedData,
@@ -184,10 +195,12 @@ impl CtrlKbdLedZbus {
impl CtrlKbdLed {
pub fn new(supported_modes: LaptopLedData, config: AuraConfig) -> Result<Self, RogError> {
// TODO: return error if *all* nodes are None
let mut led_prod = None;
let mut led_node = None;
for prod in ASUS_KEYBOARD_DEVICES.iter() {
match Self::find_led_node(prod) {
Ok(node) => {
led_prod = Some(prod.to_string());
led_node = Some(node);
info!("Looked for keyboard controller 0x{prod}: Found");
break;
@@ -209,6 +222,7 @@ impl CtrlKbdLed {
}
let ctrl = CtrlKbdLed {
led_prod,
led_node,
bright_node: bright_node.unwrap(), // If was none then we already returned above
supported_modes,
@@ -282,12 +296,8 @@ impl CtrlKbdLed {
/// Set combination state for boot animation/sleep animation/all leds/keys leds/side leds LED active
pub(super) fn set_power_states(&self, config: &AuraConfig) -> Result<(), RogError> {
let set: Vec<AuraControl> = config.enabled.iter().map(|v| *v).collect();
let bytes = AuraControl::to_bytes(&set);
let message = [
0x5d, 0xbd, 0x01, bytes[0], bytes[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
let bytes = AuraPowerConfig::to_bytes(&config.enabled);
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2]];
self.write_bytes(&message)?;
self.write_bytes(&LED_SET)?;
@@ -511,6 +521,7 @@ mod tests {
per_key: false,
};
let mut controller = CtrlKbdLed {
led_prod: None,
led_node: None,
bright_node: String::new(),
supported_modes,
@@ -572,6 +583,7 @@ mod tests {
per_key: false,
};
let mut controller = CtrlKbdLed {
led_prod: None,
led_node: None,
bright_node: String::new(),
supported_modes,
@@ -608,6 +620,7 @@ mod tests {
per_key: false,
};
let mut controller = CtrlKbdLed {
led_prod: None,
led_node: None,
bright_node: String::new(),
supported_modes,

View File

@@ -1,6 +1,6 @@
use async_trait::async_trait;
use log::warn;
use rog_aura::{usb::AuraControl, AuraEffect, LedBrightness};
use rog_aura::{usb::AuraPowerDev, AuraEffect, LedBrightness};
use zbus::{dbus_interface, Connection, SignalContext};
use super::controller::CtrlKbdLedZbus;
@@ -42,16 +42,21 @@ impl CtrlKbdLedZbus {
/// SleepBar,
/// ShutdownBar,
/// }
async fn set_leds_enabled(
async fn set_leds_power(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
enabled: Vec<AuraControl>,
options: AuraPowerDev,
enabled: bool,
) -> zbus::fdo::Result<()> {
let mut states = None;
if let Ok(mut ctrl) = self.0.try_lock() {
for s in enabled {
ctrl.config.enabled.insert(s);
for p in options.x1866 {
ctrl.config.enabled.set_0x1866(p, enabled);
}
for p in options.x19b6 {
ctrl.config.enabled.set_0x19b6(p, enabled);
}
ctrl.config.write();
ctrl.set_power_states(&ctrl.config).map_err(|e| {
@@ -59,37 +64,7 @@ impl CtrlKbdLedZbus {
e
})?;
let set: Vec<AuraControl> = ctrl.config.enabled.iter().map(|v| *v).collect();
states = Some(set);
}
// Need to pull state out like this due to MutexGuard
if let Some(states) = states {
Self::notify_power_states(&ctxt, &states)
.await
.unwrap_or_else(|err| warn!("{}", err));
}
Ok(())
}
async fn set_leds_disabled(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
disabled: Vec<AuraControl>,
) -> zbus::fdo::Result<()> {
let mut states = None;
if let Ok(mut ctrl) = self.0.try_lock() {
for s in disabled {
ctrl.config.enabled.remove(&s);
}
ctrl.config.write();
ctrl.set_power_states(&ctrl.config).map_err(|e| {
warn!("{}", e);
e
})?;
let set: Vec<AuraControl> = ctrl.config.enabled.iter().map(|v| *v).collect();
states = Some(set);
states = Some(AuraPowerDev::from(&ctrl.config.enabled));
}
// Need to pull state out like this due to MutexGuard
if let Some(states) = states {
@@ -189,13 +164,14 @@ impl CtrlKbdLedZbus {
Ok(())
}
#[dbus_interface(property)]
async fn leds_enabled(&self) -> Vec<u8> {
if let Ok(ctrl) = self.0.try_lock() {
let set: Vec<AuraControl> = ctrl.config.enabled.iter().map(|v| *v).collect();
return AuraControl::to_bytes(&set).to_vec();
// As property doesn't work for AuraPowerDev (complexity of serialization?)
// #[dbus_interface(property)]
async fn leds_power(&self) -> AuraPowerDev {
loop {
if let Ok(ctrl) = self.0.try_lock() {
return AuraPowerDev::from(&ctrl.config.enabled);
}
}
vec![0, 0]
}
/// Return the current mode data
@@ -240,6 +216,6 @@ impl CtrlKbdLedZbus {
#[dbus_interface(signal)]
async fn notify_power_states(
signal_ctxt: &SignalContext<'_>,
data: &[AuraControl],
data: &AuraPowerDev,
) -> zbus::Result<()>;
}