mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-23 01:43:19 +01:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c7dfb4030 | ||
|
|
f855908c82 | ||
|
|
293a087b8a | ||
|
|
fd72a04bb8 | ||
|
|
f131a3fa70 |
15
CHANGELOG.md
15
CHANGELOG.md
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v6.0.6]
|
||||
|
||||
### Added
|
||||
- Add GX650R laptop to aura DB
|
||||
|
||||
### Changed
|
||||
- Further tweaks to aura init
|
||||
- More logging
|
||||
- Fix TUF laptop led power
|
||||
- Sanitize the dbus path for aura devices (remove `.` chars)
|
||||
- Even more error handling (gracefully)
|
||||
- Better checking for dbus interfaces
|
||||
- Remove dbus `supported_interfaces`
|
||||
- dbus ObjectManager is now at root `/`
|
||||
|
||||
## [v6.0.5]
|
||||
|
||||
### Changed
|
||||
|
||||
28
Cargo.lock
generated
28
Cargo.lock
generated
@@ -117,7 +117,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "asusctl"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"asusd",
|
||||
"cargo-husky",
|
||||
@@ -135,7 +135,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asusd"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"concat-idents",
|
||||
@@ -161,7 +161,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asusd-user"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"config-traits",
|
||||
@@ -828,7 +828,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "config-traits"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"log",
|
||||
@@ -934,7 +934,7 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
|
||||
|
||||
[[package]]
|
||||
name = "cpuctl"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
@@ -1134,7 +1134,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dmi_id"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"log",
|
||||
"udev 0.8.0",
|
||||
@@ -3309,7 +3309,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog-control-center"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"asusd",
|
||||
"betrayer",
|
||||
@@ -3341,7 +3341,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_anime"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"dmi_id",
|
||||
@@ -3358,7 +3358,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_aura"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"dmi_id",
|
||||
@@ -3372,7 +3372,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_dbus"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"asusd",
|
||||
"cargo-husky",
|
||||
@@ -3386,7 +3386,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_platform"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"concat-idents",
|
||||
@@ -3401,7 +3401,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_profiles"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"log",
|
||||
@@ -3415,7 +3415,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_simulators"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rog_anime",
|
||||
@@ -3425,7 +3425,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_slash"
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"dmi_id",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[workspace.package]
|
||||
version = "6.0.5"
|
||||
version = "6.0.6"
|
||||
rust-version = "1.77"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
|
||||
@@ -14,6 +14,7 @@ use rog_anime::usb::get_anime_type;
|
||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
||||
use rog_aura::keyboard::{AuraPowerState, LaptopAuraPower};
|
||||
use rog_aura::{self, AuraDeviceType, AuraEffect, PowerZones};
|
||||
use rog_dbus::list_iface_blocking;
|
||||
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
||||
use rog_dbus::zbus_fan_curves::FanCurvesProxyBlocking;
|
||||
@@ -65,7 +66,7 @@ fn main() {
|
||||
}
|
||||
|
||||
let supported_properties = platform_proxy.supported_properties().unwrap();
|
||||
let supported_interfaces = platform_proxy.supported_interfaces().unwrap();
|
||||
let supported_interfaces = list_iface_blocking().unwrap();
|
||||
|
||||
if parsed.version {
|
||||
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
|
||||
@@ -89,7 +90,10 @@ fn print_error_help(
|
||||
print_info();
|
||||
println!();
|
||||
println!("Supported interfaces:\n\n{:#?}\n", supported_interfaces);
|
||||
println!("Supported properties:\n\n{:#?}\n", supported_properties);
|
||||
println!(
|
||||
"Supported properties on Platform:\n\n{:#?}\n",
|
||||
supported_properties
|
||||
);
|
||||
}
|
||||
|
||||
fn print_info() {
|
||||
@@ -120,12 +124,8 @@ fn check_service(name: &str) -> bool {
|
||||
|
||||
fn find_aura_iface() -> Result<Vec<AuraProxyBlocking<'static>>, Box<dyn std::error::Error>> {
|
||||
let conn = zbus::blocking::Connection::system().unwrap();
|
||||
let f = zbus::blocking::fdo::ObjectManagerProxy::new(
|
||||
&conn,
|
||||
"org.asuslinux.Daemon",
|
||||
"/org/asuslinux",
|
||||
)
|
||||
.unwrap();
|
||||
let f =
|
||||
zbus::blocking::fdo::ObjectManagerProxy::new(&conn, "org.asuslinux.Daemon", "/").unwrap();
|
||||
let interfaces = f.get_managed_objects().unwrap();
|
||||
let mut aura_paths = Vec::new();
|
||||
for v in interfaces.iter() {
|
||||
@@ -203,6 +203,31 @@ fn do_parsed(
|
||||
};
|
||||
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
||||
for command in commands.iter().filter(|command| {
|
||||
if command.trim().starts_with("fan-curve")
|
||||
&& !supported_interfaces
|
||||
.contains(&"org.asuslinux.FanCurves".to_string())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if command.trim().starts_with("anime")
|
||||
&& !supported_interfaces.contains(&"org.asuslinux.Anime".to_string())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if command.trim().starts_with("slash")
|
||||
&& !supported_interfaces.contains(&"org.asuslinux.Slash".to_string())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if command.trim().starts_with("bios")
|
||||
&& !supported_interfaces.contains(&"org.asuslinux.Platform".to_string())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if !dev_type.is_old_laptop()
|
||||
&& !dev_type.is_tuf_laptop()
|
||||
&& command.trim().starts_with("led-pow-1")
|
||||
|
||||
@@ -11,8 +11,7 @@ use rog_aura::aura_detection::LedSupportData;
|
||||
use rog_aura::keyboard::KeyLayout;
|
||||
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||
use rog_dbus::zbus_aura::AuraProxyBlocking;
|
||||
use rog_dbus::zbus_platform::PlatformProxyBlocking;
|
||||
use rog_dbus::DBUS_NAME;
|
||||
use rog_dbus::{list_iface_blocking, DBUS_NAME};
|
||||
use smol::Executor;
|
||||
use zbus::Connection;
|
||||
|
||||
@@ -36,18 +35,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("rog-platform v{}", rog_platform::VERSION);
|
||||
|
||||
let conn = zbus::blocking::Connection::system().unwrap();
|
||||
let platform_proxy = PlatformProxyBlocking::new(&conn).unwrap();
|
||||
|
||||
let supported = platform_proxy
|
||||
.supported_interfaces()
|
||||
.unwrap_or_default()
|
||||
.contains(&"Anime".to_string());
|
||||
let supported = list_iface_blocking()?;
|
||||
let config = ConfigBase::new().load();
|
||||
let executor = Executor::new();
|
||||
|
||||
let early_return = Arc::new(AtomicBool::new(false));
|
||||
// Set up the anime data and run loop/thread
|
||||
if supported {
|
||||
if supported.contains(&"org.asuslinux.Anime".to_string()) {
|
||||
if let Some(cfg) = config.active_anime {
|
||||
let anime_type = get_anime_type()?;
|
||||
let anime_config = ConfigAnime::new().set_name(cfg).load();
|
||||
|
||||
@@ -12,11 +12,15 @@ use rog_aura::{
|
||||
};
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use rog_platform::keyboard_led::KeyboardBacklight;
|
||||
use udev::Device;
|
||||
use zbus::zvariant::OwnedObjectPath;
|
||||
use zbus::Connection;
|
||||
|
||||
use super::config::AuraConfig;
|
||||
use crate::ctrl_aura::manager::{dbus_path_for_dev, dbus_path_for_tuf};
|
||||
use crate::ctrl_aura::manager::{dbus_path_for_dev, dbus_path_for_tuf, start_tasks};
|
||||
use crate::ctrl_aura::trait_impls::CtrlAuraZbus;
|
||||
use crate::error::RogError;
|
||||
use crate::CtrlTask;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LEDNode {
|
||||
@@ -99,10 +103,85 @@ pub struct CtrlKbdLed {
|
||||
}
|
||||
|
||||
impl CtrlKbdLed {
|
||||
pub fn add_to_dbus_and_start(
|
||||
self,
|
||||
interfaces: &mut HashSet<OwnedObjectPath>,
|
||||
conn: Connection,
|
||||
) -> Result<(), RogError> {
|
||||
let dbus_path = self.dbus_path.clone();
|
||||
let dbus_path_cpy = self.dbus_path.clone();
|
||||
info!(
|
||||
"AuraManager starting device at: {:?}, {:?}",
|
||||
dbus_path, self.led_type
|
||||
);
|
||||
let conn_copy = conn.clone();
|
||||
let sig_ctx1 = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
let sig_ctx2 = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
let zbus = CtrlAuraZbus::new(self, sig_ctx1);
|
||||
tokio::spawn(
|
||||
async move { start_tasks(zbus, conn_copy.clone(), sig_ctx2, dbus_path).await },
|
||||
);
|
||||
interfaces.insert(dbus_path_cpy);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build and init a `CtrlKbdLed` from a udev device. Maybe.
|
||||
/// This will initialise the config also.
|
||||
pub fn maybe_device(
|
||||
device: Device,
|
||||
interfaces: &mut HashSet<OwnedObjectPath>,
|
||||
) -> Result<Option<Self>, RogError> {
|
||||
// usb_device gives us a product and vendor ID
|
||||
if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? {
|
||||
let dbus_path = dbus_path_for_dev(&usb_device).unwrap_or_default();
|
||||
if interfaces.contains(&dbus_path) {
|
||||
debug!("Already a ctrl at {dbus_path:?}, ignoring this end-point");
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// The asus_wmi driver latches MCU that controls the USB endpoints
|
||||
if let Some(parent) = device.parent() {
|
||||
if let Some(driver) = parent.driver() {
|
||||
// There is a tree of devices added so filter by driver
|
||||
if driver != "asus" {
|
||||
return Ok(None);
|
||||
}
|
||||
} else {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
// Device is something like 002, while its parent is the MCU
|
||||
// Think of it like the device is an endpoint of the USB device attached
|
||||
let mut prod_id = String::new();
|
||||
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
|
||||
prod_id = usb_id.to_string_lossy().to_string();
|
||||
let aura_device = AuraDeviceType::from(prod_id.as_str());
|
||||
if aura_device == AuraDeviceType::Unknown {
|
||||
log::debug!("Unknown or invalid device: {usb_id:?}, skipping");
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
let dev_node = if let Some(dev_node) = usb_device.devnode() {
|
||||
dev_node
|
||||
} else {
|
||||
debug!("Device has no devnode, skipping");
|
||||
return Ok(None);
|
||||
};
|
||||
info!("AuraControl found device at: {:?}", dev_node);
|
||||
let dev = HidRaw::from_device(device)?;
|
||||
let mut controller = Self::from_hidraw(dev, dbus_path.clone())?;
|
||||
controller.config = Self::init_config(&prod_id);
|
||||
interfaces.insert(dbus_path);
|
||||
return Ok(Some(controller));
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn find_all() -> Result<Vec<Self>, RogError> {
|
||||
info!("Searching for all Aura devices");
|
||||
let mut devices = Vec::new();
|
||||
let mut found = HashSet::new(); // track and ensure we use only one hidraw per prod_id
|
||||
let mut interfaces = HashSet::new(); // track and ensure we use only one hidraw per prod_id
|
||||
|
||||
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||
warn!("{}", err);
|
||||
@@ -115,46 +194,9 @@ impl CtrlKbdLed {
|
||||
})?;
|
||||
|
||||
for end_point in enumerator.scan_devices()? {
|
||||
// usb_device gives us a product and vendor ID
|
||||
if let Some(usb_device) =
|
||||
end_point.parent_with_subsystem_devtype("usb", "usb_device")?
|
||||
{
|
||||
// The asus_wmi driver latches MCU that controls the USB endpoints
|
||||
if let Some(parent) = end_point.parent() {
|
||||
if let Some(driver) = parent.driver() {
|
||||
// There is a tree of devices added so filter by driver
|
||||
if driver != "asus" {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Device is something like 002, while its parent is the MCU
|
||||
// Think of it like the device is an endpoint of the USB device attached
|
||||
let mut prod_id = String::new();
|
||||
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
|
||||
prod_id = usb_id.to_string_lossy().to_string();
|
||||
let aura_dev = AuraDeviceType::from(prod_id.as_str());
|
||||
if aura_dev == AuraDeviceType::Unknown || found.contains(&aura_dev) {
|
||||
log::debug!("Unknown or invalid device: {usb_id:?}, skipping");
|
||||
continue;
|
||||
}
|
||||
found.insert(aura_dev);
|
||||
}
|
||||
|
||||
let dev_node = if let Some(dev_node) = usb_device.devnode() {
|
||||
dev_node
|
||||
} else {
|
||||
debug!("Device has no devnode, skipping");
|
||||
continue;
|
||||
};
|
||||
info!("AuraControl found device at: {:?}", dev_node);
|
||||
let dbus_path = dbus_path_for_dev(&usb_device).unwrap_or_default();
|
||||
let dev = HidRaw::from_device(end_point)?;
|
||||
let mut dev = Self::from_hidraw(dev, dbus_path)?;
|
||||
dev.config = Self::init_config(&prod_id);
|
||||
devices.push(dev);
|
||||
// maybe?
|
||||
if let Some(device) = Self::maybe_device(end_point, &mut interfaces)? {
|
||||
devices.push(device);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,13 +306,10 @@ impl CtrlKbdLed {
|
||||
/// Set combination state for boot animation/sleep animation/all leds/keys
|
||||
/// leds/side leds LED active
|
||||
pub(super) fn set_power_states(&mut self) -> Result<(), RogError> {
|
||||
if let LEDNode::KbdLed(_platform) = &mut self.led_node {
|
||||
if let LEDNode::KbdLed(platform) = &mut self.led_node {
|
||||
// TODO: tuf bool array
|
||||
// if let Some(pwr) =
|
||||
// AuraPowerConfig::to_tuf_bool_array(&self.config.enabled) {
|
||||
// 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)?;
|
||||
// }
|
||||
let buf = self.config.enabled.to_bytes(self.led_type);
|
||||
platform.set_kbd_rgb_state(&buf)?;
|
||||
} else if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||
let bytes = self.config.enabled.to_bytes(self.led_type);
|
||||
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]];
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use log::{debug, error, info, warn};
|
||||
use log::{error, info, warn};
|
||||
use mio::{Events, Interest, Poll, Token};
|
||||
use rog_aura::AuraDeviceType;
|
||||
use rog_platform::hid_raw::HidRaw;
|
||||
use tokio::task::spawn_blocking;
|
||||
use udev::{Device, MonitorBuilder};
|
||||
use zbus::object_server::SignalContext;
|
||||
@@ -59,93 +57,42 @@ impl AuraManager {
|
||||
continue;
|
||||
}
|
||||
for event in monitor.iter() {
|
||||
let parent = if let Some(parent) =
|
||||
let action = event.action().unwrap_or_default();
|
||||
|
||||
if let Some(parent) =
|
||||
event.parent_with_subsystem_devtype("usb", "usb_device")?
|
||||
{
|
||||
parent
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let action = if let Some(action) = event.action() {
|
||||
action
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let id_product = if let Some(id_product) = parent.attribute_value("idProduct") {
|
||||
id_product.to_string_lossy()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let path = if let Some(path) = dbus_path_for_dev(&parent) {
|
||||
path
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let aura_device = AuraDeviceType::from(&*id_product);
|
||||
if aura_device == AuraDeviceType::Unknown {
|
||||
warn!("idProduct:{id_product:?} is unknown, not using");
|
||||
continue;
|
||||
}
|
||||
|
||||
if action == "remove" {
|
||||
if interfaces.remove(&path) {
|
||||
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>(())
|
||||
});
|
||||
}
|
||||
} else if action == "add" {
|
||||
if interfaces.contains(&path) {
|
||||
debug!("Already a ctrl at {path:?}");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Need to check the driver is asus to prevent using hid_generic
|
||||
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" {
|
||||
debug!("{id_product:?} driver was not asus, skipping");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(dev_node) = event.devnode() {
|
||||
if let Ok(raw) = HidRaw::from_device(event.device())
|
||||
.map_err(|e| error!("device path error: {e:?}"))
|
||||
{
|
||||
if let Ok(mut ctrl) = CtrlKbdLed::from_hidraw(raw, path.clone()) {
|
||||
ctrl.config = CtrlKbdLed::init_config(&id_product);
|
||||
interfaces.insert(path.clone());
|
||||
info!("AuraManager starting device at: {dev_node:?}, {path:?}");
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||
if action == "remove" {
|
||||
if let Some(path) = dbus_path_for_dev(&parent) {
|
||||
if interfaces.remove(&path) {
|
||||
info!("AuraManager removing: {path:?}");
|
||||
let conn_copy = conn_copy.clone();
|
||||
tokio::spawn(async move {
|
||||
start_tasks(zbus, conn_copy.clone(), sig_ctx, path).await
|
||||
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>(())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} else if action == "add" {
|
||||
if let Ok(Some(ctrl)) =
|
||||
CtrlKbdLed::maybe_device(event.device(), &mut interfaces)
|
||||
{
|
||||
ctrl.add_to_dbus_and_start(&mut interfaces, conn_copy.clone())
|
||||
.map_err(|e| {
|
||||
error!("Couldn't start aura device on dbus: {e:?}")
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
// Required for return type on spawn
|
||||
@@ -169,7 +116,7 @@ pub(crate) fn dbus_path_for_tuf() -> OwnedObjectPath {
|
||||
ObjectPath::from_str_unchecked(&format!("{AURA_ZBUS_PATH}/tuf")).into()
|
||||
}
|
||||
|
||||
async fn start_tasks(
|
||||
pub async fn start_tasks(
|
||||
mut zbus: CtrlAuraZbus,
|
||||
connection: Connection,
|
||||
_signal_ctx: SignalContext<'static>,
|
||||
@@ -180,7 +127,12 @@ async fn start_tasks(
|
||||
zbus.reload()
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("Controller error: {}", err));
|
||||
connection.object_server().at(path, zbus).await.unwrap();
|
||||
connection
|
||||
.object_server()
|
||||
.at(path.clone(), zbus)
|
||||
.await
|
||||
.map_err(|e| error!("Couldn't add server at path: {path}, {e:?}"))
|
||||
.ok();
|
||||
// TODO: skip this until we keep handles to tasks so they can be killed
|
||||
// task.create_tasks(signal_ctx).await
|
||||
Ok(())
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use log::warn;
|
||||
use udev::Device;
|
||||
use zbus::zvariant::{ObjectPath, OwnedObjectPath};
|
||||
|
||||
@@ -12,7 +13,7 @@ pub mod trait_impls;
|
||||
pub(super) fn filename_partial(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 mut 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();
|
||||
@@ -23,6 +24,10 @@ pub(super) fn filename_partial(parent: &Device) -> Option<OwnedObjectPath> {
|
||||
} else {
|
||||
format!("{id_product}")
|
||||
};
|
||||
if path.contains('.') {
|
||||
warn!("dbus path for {id_product} contains `.`, removing");
|
||||
path = path.replace('.', "").to_owned();
|
||||
}
|
||||
return Some(ObjectPath::from_str_unchecked(&path).into());
|
||||
}
|
||||
None
|
||||
|
||||
@@ -279,8 +279,10 @@ impl CtrlTask for CtrlAuraZbus {
|
||||
.unwrap()
|
||||
.for_each(|_| async {
|
||||
if let Some(lock) = ctrl2.try_lock() {
|
||||
load_save(true, lock).unwrap(); // unwrap as we want to
|
||||
// bomb out of the task
|
||||
load_save(true, lock).unwrap(); // unwrap as we want
|
||||
// to
|
||||
// bomb out of the
|
||||
// task
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
||||
@@ -792,6 +792,15 @@ impl ReloadAndNotify for CtrlPlatform {
|
||||
|
||||
impl crate::Reloadable for CtrlPlatform {
|
||||
async fn reload(&mut self) -> Result<(), RogError> {
|
||||
info!("Begin Platform settings restore");
|
||||
if self.power.has_charge_control_end_threshold() {
|
||||
let limit = self.config.lock().await.charge_control_end_threshold;
|
||||
info!("reloading charge_control_end_threshold to {limit}");
|
||||
self.power.set_charge_control_end_threshold(limit)?;
|
||||
} else {
|
||||
warn!("No charge_control_end_threshold found")
|
||||
}
|
||||
|
||||
macro_rules! reload {
|
||||
($property:tt, $prop_name:literal) => {
|
||||
concat_idents::concat_idents!(has = has_, $property {
|
||||
@@ -827,12 +836,6 @@ impl crate::Reloadable for CtrlPlatform {
|
||||
ppt_reload!(nv_dynamic_boost, "nv_dynamic_boost");
|
||||
ppt_reload!(nv_temp_target, "nv_temp_target");
|
||||
|
||||
if self.power.has_charge_control_end_threshold() {
|
||||
let limit = self.config.lock().await.charge_control_end_threshold;
|
||||
info!("reloading charge_control_end_threshold to {limit}");
|
||||
self.power.set_charge_control_end_threshold(limit)?;
|
||||
}
|
||||
|
||||
if let Ok(power_plugged) = self.power.get_online() {
|
||||
self.config.lock().await.last_power_plugged = power_plugged;
|
||||
if self.platform.has_throttle_thermal_policy() {
|
||||
|
||||
@@ -62,7 +62,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
let mut connection = Connection::system().await?;
|
||||
connection
|
||||
.object_server()
|
||||
.at("/org/asuslinux", ObjectManager)
|
||||
.at("/", ObjectManager)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -746,6 +746,15 @@
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
device_name: "GX650R",
|
||||
product_id: "",
|
||||
layout_name: "gx531-per-key",
|
||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
device_name: "GX701",
|
||||
product_id: "",
|
||||
|
||||
@@ -70,7 +70,9 @@ impl LedSupportData {
|
||||
}
|
||||
}
|
||||
info!("Using generic LED control for keyboard brightness only");
|
||||
LedSupportData::default()
|
||||
let mut data = LedSupportData::default();
|
||||
data.power_zones.push(PowerZones::Keyboard);
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,8 @@ impl AuraPowerState {
|
||||
}
|
||||
|
||||
fn tuf_to_bytes(&self) -> Vec<u8> {
|
||||
todo!("0s and 1s for bool array")
|
||||
// &cmd, &boot, &awake, &sleep, &keyboard
|
||||
vec![1, self.boot as u8, self.awake as u8, self.sleep as u8, 1]
|
||||
}
|
||||
|
||||
/// # Bits for older 0x1866 keyboard model
|
||||
|
||||
@@ -6,12 +6,12 @@ pub mod setup_system;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use config_traits::StdConfig;
|
||||
use rog_dbus::zbus_platform::PlatformProxyBlocking;
|
||||
use rog_dbus::has_iface_blocking;
|
||||
use slint::{ComponentHandle, PhysicalSize, SharedString, Weak};
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::ui::setup_anime::setup_anime_page;
|
||||
use crate::ui::setup_aura::{has_aura_iface_blocking, setup_aura_page};
|
||||
use crate::ui::setup_aura::setup_aura_page;
|
||||
use crate::ui::setup_fans::setup_fan_curve_page;
|
||||
use crate::ui::setup_system::{setup_system_page, setup_system_page_callbacks};
|
||||
use crate::{AppSettingsPageData, MainWindow};
|
||||
@@ -108,19 +108,13 @@ pub fn setup_window(config: Arc<Mutex<Config>>) -> MainWindow {
|
||||
}
|
||||
};
|
||||
|
||||
let conn = zbus::blocking::Connection::system().unwrap();
|
||||
let platform = PlatformProxyBlocking::new(&conn).unwrap();
|
||||
|
||||
let interfaces = platform.supported_interfaces().unwrap();
|
||||
log::debug!("Available interfaces: {interfaces:?}");
|
||||
// "Anime", "Aura", "FanCurves", "Platform"
|
||||
ui.set_sidebar_items_avilable(
|
||||
[
|
||||
// Needs to match the order of slint sidebar items
|
||||
interfaces.contains(&"Platform".into()),
|
||||
has_aura_iface_blocking().unwrap_or(false),
|
||||
interfaces.contains(&"Anime".into()),
|
||||
interfaces.contains(&"FanCurves".into()),
|
||||
has_iface_blocking("org.asuslinux.Platform").unwrap_or(false),
|
||||
has_iface_blocking("org.asuslinux.Aura").unwrap_or(false),
|
||||
has_iface_blocking("org.asuslinux.Anime").unwrap_or(false),
|
||||
has_iface_blocking("org.asuslinux.FanCurves").unwrap_or(false),
|
||||
true,
|
||||
true,
|
||||
]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use log::{error, info, warn};
|
||||
use rog_anime::Animations;
|
||||
use rog_dbus::zbus_anime::AnimeProxy;
|
||||
use slint::ComponentHandle;
|
||||
@@ -11,8 +12,13 @@ use crate::{set_ui_callbacks, set_ui_props_async, AnimePageData, MainWindow};
|
||||
pub fn setup_anime_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
let handle = ui.as_weak();
|
||||
tokio::spawn(async move {
|
||||
let conn = zbus::Connection::system().await.unwrap();
|
||||
let anime = AnimeProxy::new(&conn).await.unwrap();
|
||||
let Ok(conn) = zbus::Connection::system().await.map_err(|e| warn!("{e:}")) else {
|
||||
return;
|
||||
};
|
||||
let Ok(anime) = AnimeProxy::new(&conn).await.map_err(|e| warn!("{e:}")) else {
|
||||
info!("This device may not have an AniMe. If not then the error can be ignored");
|
||||
return;
|
||||
};
|
||||
|
||||
set_ui_props_async!(handle, anime, AnimePageData, brightness);
|
||||
set_ui_props_async!(handle, anime, AnimePageData, builtins_enabled);
|
||||
@@ -123,6 +129,7 @@ pub fn setup_anime_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
"Setting Anime off_when_unplugged failed"
|
||||
);
|
||||
})
|
||||
.unwrap();
|
||||
.map_err(|e| error!("setup_anime_page: upgrade_in_event_loop: {e:?}"))
|
||||
.ok();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use log::info;
|
||||
use log::{error, info};
|
||||
use rog_aura::keyboard::LaptopAuraPower;
|
||||
use rog_dbus::zbus_aura::AuraProxy;
|
||||
use slint::{ComponentHandle, Model, RgbaColor, SharedString};
|
||||
@@ -33,31 +33,11 @@ fn decode_hex(s: &str) -> RgbaColor<u8> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_aura_iface_blocking() -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let conn = zbus::blocking::Connection::system()?;
|
||||
let f = zbus::blocking::fdo::ObjectManagerProxy::new(
|
||||
&conn,
|
||||
"org.asuslinux.Daemon",
|
||||
"/org/asuslinux",
|
||||
)?;
|
||||
let interfaces = f.get_managed_objects()?;
|
||||
let mut aura_paths = Vec::new();
|
||||
for v in interfaces.iter() {
|
||||
for k in v.1.keys() {
|
||||
if k.as_str() == "org.asuslinux.Aura" {
|
||||
aura_paths.push(v.0.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(!aura_paths.is_empty())
|
||||
}
|
||||
|
||||
/// Returns the first available Aura interface
|
||||
// TODO: return all
|
||||
async fn find_aura_iface() -> Result<AuraProxy<'static>, Box<dyn std::error::Error>> {
|
||||
let conn = zbus::Connection::system().await?;
|
||||
let f =
|
||||
zbus::fdo::ObjectManagerProxy::new(&conn, "org.asuslinux.Daemon", "/org/asuslinux").await?;
|
||||
let f = zbus::fdo::ObjectManagerProxy::new(&conn, "org.asuslinux.Daemon", "/").await?;
|
||||
let interfaces = f.get_managed_objects().await?;
|
||||
let mut aura_paths = Vec::new();
|
||||
for v in interfaces.iter() {
|
||||
@@ -93,9 +73,7 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
|
||||
let handle = ui.as_weak();
|
||||
tokio::spawn(async move {
|
||||
let aura = if let Ok(aura) = find_aura_iface().await {
|
||||
aura
|
||||
} else {
|
||||
let Ok(aura) = find_aura_iface().await else {
|
||||
info!("This device appears to have no aura interfaces");
|
||||
return;
|
||||
};
|
||||
@@ -138,6 +116,7 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
.global::<AuraPageData>()
|
||||
.set_available_mode_names(res.as_slice().into());
|
||||
})
|
||||
.map_err(|e| error!("{e:}"))
|
||||
.ok();
|
||||
}
|
||||
|
||||
@@ -196,7 +175,8 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
});
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
.map_err(|e| error!("{e:}"))
|
||||
.ok();
|
||||
|
||||
// Need to update the UI if the mode changes
|
||||
let handle_copy = handle.clone();
|
||||
@@ -213,6 +193,7 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
.invoke_update_led_mode_data(out.into());
|
||||
handle.invoke_external_colour_change();
|
||||
})
|
||||
.map_err(|e| error!("{e:}"))
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use log::{error, info};
|
||||
use rog_dbus::zbus_fan_curves::FanCurvesProxy;
|
||||
use rog_platform::platform::ThrottlePolicy;
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
@@ -81,7 +82,8 @@ pub fn update_fan_data(
|
||||
}
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
.map_err(|e| error!("update_fan_data: upgrade_in_event_loop: {e:?}"))
|
||||
.ok();
|
||||
}
|
||||
|
||||
pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
@@ -89,17 +91,44 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
|
||||
tokio::spawn(async move {
|
||||
// Create the connections/proxies here to prevent future delays in process
|
||||
let conn = zbus::Connection::system().await.unwrap();
|
||||
let fans = FanCurvesProxy::new(&conn).await.unwrap();
|
||||
let conn = if let Ok(conn) = zbus::Connection::system().await.map_err(|e| error!("{e:}")) {
|
||||
conn
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let fans = if let Ok(fans) = FanCurvesProxy::new(&conn).await.map_err(|e| error!("{e:}")) {
|
||||
fans
|
||||
} else {
|
||||
info!(
|
||||
"This device may not have an Fan Curve control. If not then the error can be \
|
||||
ignored"
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
let handle_copy = handle.clone();
|
||||
// Do initial setup
|
||||
let balanced = fans.fan_curve_data(ThrottlePolicy::Balanced).await.unwrap();
|
||||
let perf = fans
|
||||
let Ok(balanced) = fans
|
||||
.fan_curve_data(ThrottlePolicy::Balanced)
|
||||
.await
|
||||
.map_err(|e| error!("{e:}"))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Ok(perf) = fans
|
||||
.fan_curve_data(ThrottlePolicy::Performance)
|
||||
.await
|
||||
.unwrap();
|
||||
let quiet = fans.fan_curve_data(ThrottlePolicy::Quiet).await.unwrap();
|
||||
.map_err(|e| error!("{e:}"))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Ok(quiet) = fans
|
||||
.fan_curve_data(ThrottlePolicy::Quiet)
|
||||
.await
|
||||
.map_err(|e| error!("{e:}"))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
update_fan_data(handle, balanced, perf, quiet);
|
||||
|
||||
let handle_next1 = handle_copy.clone();
|
||||
@@ -111,14 +140,30 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
let fans = fans1.clone();
|
||||
let handle_next = handle_next1.clone();
|
||||
tokio::spawn(async move {
|
||||
fans.set_curves_to_defaults(profile.into()).await.unwrap();
|
||||
|
||||
let balanced = fans.fan_curve_data(ThrottlePolicy::Balanced).await.unwrap();
|
||||
let perf = fans
|
||||
if fans.set_curves_to_defaults(profile.into()).await.is_err() {
|
||||
return;
|
||||
}
|
||||
let Ok(balanced) = fans
|
||||
.fan_curve_data(ThrottlePolicy::Balanced)
|
||||
.await
|
||||
.map_err(|e| error!("{e:}"))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Ok(perf) = fans
|
||||
.fan_curve_data(ThrottlePolicy::Performance)
|
||||
.await
|
||||
.unwrap();
|
||||
let quiet = fans.fan_curve_data(ThrottlePolicy::Quiet).await.unwrap();
|
||||
.map_err(|e| error!("{e:}"))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Ok(quiet) = fans
|
||||
.fan_curve_data(ThrottlePolicy::Quiet)
|
||||
.await
|
||||
.map_err(|e| error!("{e:}"))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
update_fan_data(handle_next, balanced, perf, quiet);
|
||||
});
|
||||
});
|
||||
@@ -127,11 +172,15 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
let data: Vec<Node> = data.iter().collect();
|
||||
let data = fan_data_for(fan, enabled, data);
|
||||
tokio::spawn(async move {
|
||||
fans.set_fan_curve(profile.into(), data).await.unwrap();
|
||||
fans.set_fan_curve(profile.into(), data)
|
||||
.await
|
||||
.map_err(|e| error!("{e:}"))
|
||||
.ok()
|
||||
});
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
.map_err(|e| error!("setup_fan_curve_page: upgrade_in_event_loop: {e:?}"))
|
||||
.ok();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -7,3 +7,44 @@ pub mod zbus_platform;
|
||||
pub mod zbus_slash;
|
||||
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
pub fn list_iface_blocking() -> Result<Vec<String>, Box<dyn std::error::Error>> {
|
||||
let conn = zbus::blocking::Connection::system()?;
|
||||
let f = zbus::blocking::fdo::ObjectManagerProxy::new(&conn, "org.asuslinux.Daemon", "/")?;
|
||||
let interfaces = f.get_managed_objects()?;
|
||||
let mut ifaces = Vec::new();
|
||||
for v in interfaces.iter() {
|
||||
for k in v.1.keys() {
|
||||
ifaces.push(k.to_string());
|
||||
}
|
||||
}
|
||||
Ok(ifaces)
|
||||
}
|
||||
|
||||
pub fn has_iface_blocking(iface: &str) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let conn = zbus::blocking::Connection::system()?;
|
||||
let f = zbus::blocking::fdo::ObjectManagerProxy::new(&conn, "org.asuslinux.Daemon", "/")?;
|
||||
let interfaces = f.get_managed_objects()?;
|
||||
for v in interfaces.iter() {
|
||||
for k in v.1.keys() {
|
||||
if k.as_str() == iface {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub async fn has_iface(iface: &str) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let conn = zbus::Connection::system().await?;
|
||||
let f = zbus::fdo::ObjectManagerProxy::new(&conn, "org.asuslinux.Daemon", "/").await?;
|
||||
let interfaces = f.get_managed_objects().await?;
|
||||
for v in interfaces.iter() {
|
||||
for k in v.1.keys() {
|
||||
if k.as_str() == iface {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
@@ -36,9 +36,6 @@ trait Platform {
|
||||
/// NextThrottleThermalPolicy method
|
||||
fn next_throttle_thermal_policy(&self) -> zbus::Result<()>;
|
||||
|
||||
/// SupportedInterfaces method
|
||||
fn supported_interfaces(&self) -> zbus::Result<Vec<String>>;
|
||||
|
||||
/// SupportedProperties method
|
||||
fn supported_properties(&self) -> zbus::Result<Vec<Properties>>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user