mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Convert chunk of daemon to use async mutex
This commit is contained in:
@@ -17,10 +17,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Use loops to ensure that mutex is gained for LED changes.
|
- Use loops to ensure that mutex is gained for LED changes.
|
||||||
- asusctl now uses tokio for async runtime. This helps simplify some code.
|
- asusctl now uses tokio for async runtime. This helps simplify some code.
|
||||||
### Breaking
|
### Breaking
|
||||||
- DBUS: all charge control methods renamed:
|
- DBUS: all charge control methods renamed to:
|
||||||
- `ChargeControlEndThreshold`
|
- `ChargeControlEndThreshold`
|
||||||
- `SetChargeControlEndThreshold`
|
- `SetChargeControlEndThreshold`
|
||||||
- `NotifyChargeControlEndThreshold`
|
- `NotifyChargeControlEndThreshold`
|
||||||
|
- `PanelOd` (form PanelOverdrive)
|
||||||
|
- `SetPanelOd`
|
||||||
|
- `NotifyPanelOd`
|
||||||
|
|
||||||
## [v4.4.0] - 2022-08-29
|
## [v4.4.0] - 2022-08-29
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -572,12 +572,11 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "daemon"
|
name = "daemon"
|
||||||
version = "4.4.0"
|
version = "4.5.0-rc1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"concat-idents",
|
"concat-idents",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"inotify",
|
|
||||||
"log",
|
"log",
|
||||||
"logind-zbus",
|
"logind-zbus",
|
||||||
"rog_anime",
|
"rog_anime",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "daemon"
|
name = "daemon"
|
||||||
version = "4.4.0"
|
version = "4.5.0-rc1"
|
||||||
license = "MPL-2.0"
|
license = "MPL-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = ["Luke <luke@ljones.dev>"]
|
authors = ["Luke <luke@ljones.dev>"]
|
||||||
@@ -44,5 +44,4 @@ toml = "^0.5.8"
|
|||||||
# Device control
|
# Device control
|
||||||
sysfs-class = "^0.1.2" # used for backlight control and baord ID
|
sysfs-class = "^0.1.2" # used for backlight control and baord ID
|
||||||
|
|
||||||
inotify = { version = "0.10.0", default-features = false }
|
|
||||||
concat-idents = "1.1.3"
|
concat-idents = "1.1.3"
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod zbus;
|
pub mod zbus;
|
||||||
|
|
||||||
|
use ::zbus::export::futures_util::lock::{Mutex, MutexGuard};
|
||||||
use ::zbus::SignalContext;
|
use ::zbus::SignalContext;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
@@ -14,12 +15,7 @@ use rog_anime::{
|
|||||||
};
|
};
|
||||||
use rog_platform::{hid_raw::HidRaw, supported::AnimeSupportedFunctions, usb_raw::USBRaw};
|
use rog_platform::{hid_raw::HidRaw, supported::AnimeSupportedFunctions, usb_raw::USBRaw};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::{
|
use std::{convert::TryFrom, error::Error, sync::Arc, thread::sleep};
|
||||||
convert::TryFrom,
|
|
||||||
error::Error,
|
|
||||||
sync::{Arc, Mutex, MutexGuard},
|
|
||||||
thread::sleep,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{error::RogError, GetSupported};
|
use crate::{error::RogError, GetSupported};
|
||||||
|
|
||||||
@@ -85,6 +81,7 @@ impl CtrlAnime {
|
|||||||
|
|
||||||
// The only reason for this outer thread is to prevent blocking while waiting for the
|
// The only reason for this outer thread is to prevent blocking while waiting for the
|
||||||
// next spawned thread to exit
|
// next spawned thread to exit
|
||||||
|
// TODO: turn this in to async task (maybe? COuld still risk blocking main thread)
|
||||||
std::thread::Builder::new()
|
std::thread::Builder::new()
|
||||||
.name("AniMe system thread start".into())
|
.name("AniMe system thread start".into())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
@@ -95,7 +92,7 @@ impl CtrlAnime {
|
|||||||
let thread_running;
|
let thread_running;
|
||||||
let anime_type;
|
let anime_type;
|
||||||
loop {
|
loop {
|
||||||
if let Ok(lock) = inner.try_lock() {
|
if let Some(lock) = inner.try_lock() {
|
||||||
thread_exit = lock.thread_exit.clone();
|
thread_exit = lock.thread_exit.clone();
|
||||||
thread_running = lock.thread_running.clone();
|
thread_running = lock.thread_running.clone();
|
||||||
anime_type = lock.anime_type;
|
anime_type = lock.anime_type;
|
||||||
@@ -139,9 +136,10 @@ impl CtrlAnime {
|
|||||||
.ok();
|
.ok();
|
||||||
false // Don't exit yet
|
false // Don't exit yet
|
||||||
})
|
})
|
||||||
.map_err(|err| {
|
.map(|r| Ok(r))
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
.unwrap_or_else(|| {
|
||||||
AnimeError::NoFrames
|
warn!("rog_anime::run_animation:callback failed");
|
||||||
|
Err(AnimeError::NoFrames)
|
||||||
})
|
})
|
||||||
}) {
|
}) {
|
||||||
warn!("rog_anime::run_animation:Animation {}", err);
|
warn!("rog_anime::run_animation:Animation {}", err);
|
||||||
@@ -150,7 +148,7 @@ impl CtrlAnime {
|
|||||||
}
|
}
|
||||||
ActionData::Image(image) => {
|
ActionData::Image(image) => {
|
||||||
once = false;
|
once = false;
|
||||||
if let Ok(lock) = inner.try_lock() {
|
if let Some(lock) = inner.try_lock() {
|
||||||
lock.write_data_buffer(image.as_ref().clone())
|
lock.write_data_buffer(image.as_ref().clone())
|
||||||
.map_err(|e| error!("{}", e))
|
.map_err(|e| error!("{}", e))
|
||||||
.ok();
|
.ok();
|
||||||
@@ -171,7 +169,7 @@ impl CtrlAnime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clear the display on exit
|
// Clear the display on exit
|
||||||
if let Ok(lock) = inner.try_lock() {
|
if let Some(lock) = inner.try_lock() {
|
||||||
if let Ok(data) =
|
if let Ok(data) =
|
||||||
AnimeDataBuffer::from_vec(anime_type, vec![0u8; anime_type.data_length()])
|
AnimeDataBuffer::from_vec(anime_type, vec![0u8; anime_type.data_length()])
|
||||||
.map_err(|e| error!("{}", e))
|
.map_err(|e| error!("{}", e))
|
||||||
@@ -249,25 +247,25 @@ impl crate::CtrlTask for CtrlAnimeTask {
|
|||||||
// Loop is required to try an attempt to get the mutex *without* blocking
|
// Loop is required to try an attempt to get the mutex *without* blocking
|
||||||
// other threads - it is possible to end up with deadlocks otherwise.
|
// other threads - it is possible to end up with deadlocks otherwise.
|
||||||
move || loop {
|
move || loop {
|
||||||
if let Ok(lock) = inner1.clone().try_lock() {
|
if let Some(lock) = inner1.try_lock() {
|
||||||
run_action(true, lock, inner1.clone());
|
run_action(true, lock, inner1.clone());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || loop {
|
move || loop {
|
||||||
if let Ok(lock) = inner2.clone().try_lock() {
|
if let Some(lock) = inner2.try_lock() {
|
||||||
run_action(false, lock, inner2.clone());
|
run_action(false, lock, inner2.clone());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || loop {
|
move || loop {
|
||||||
if let Ok(lock) = inner3.clone().try_lock() {
|
if let Some(lock) = inner3.try_lock() {
|
||||||
run_action(true, lock, inner3.clone());
|
run_action(true, lock, inner3.clone());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || loop {
|
move || loop {
|
||||||
if let Ok(lock) = inner4.clone().try_lock() {
|
if let Some(lock) = inner4.try_lock() {
|
||||||
run_action(false, lock, inner4.clone());
|
run_action(false, lock, inner4.clone());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -281,9 +279,10 @@ impl crate::CtrlTask for CtrlAnimeTask {
|
|||||||
|
|
||||||
pub struct CtrlAnimeReloader(pub Arc<Mutex<CtrlAnime>>);
|
pub struct CtrlAnimeReloader(pub Arc<Mutex<CtrlAnime>>);
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl crate::Reloadable for CtrlAnimeReloader {
|
impl crate::Reloadable for CtrlAnimeReloader {
|
||||||
fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if let Ok(lock) = self.0.try_lock() {
|
if let Some(lock) = self.0.try_lock() {
|
||||||
lock.node
|
lock.node
|
||||||
.write_bytes(&pkt_for_set_on(lock.config.awake_enabled))?;
|
.write_bytes(&pkt_for_set_on(lock.config.awake_enabled))?;
|
||||||
lock.node.write_bytes(&pkt_for_apply())?;
|
lock.node.write_bytes(&pkt_for_apply())?;
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use rog_anime::{
|
use rog_anime::{
|
||||||
usb::{pkt_for_apply, pkt_for_set_boot, pkt_for_set_on},
|
usb::{pkt_for_apply, pkt_for_set_boot, pkt_for_set_on},
|
||||||
AnimeDataBuffer, AnimePowerStates,
|
AnimeDataBuffer, AnimePowerStates,
|
||||||
};
|
};
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
use zbus::{dbus_interface, export::futures_util::lock::Mutex, Connection, SignalContext};
|
||||||
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::{atomic::Ordering, Arc};
|
||||||
|
|
||||||
use super::CtrlAnime;
|
use super::CtrlAnime;
|
||||||
|
|
||||||
@@ -16,7 +14,7 @@ pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
|
|||||||
|
|
||||||
/// The struct with the main dbus methods requires this trait
|
/// The struct with the main dbus methods requires this trait
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusAdd for CtrlAnimeZbus {
|
impl crate::ZbusRun for CtrlAnimeZbus {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, "/org/asuslinux/Anime", server).await;
|
Self::add_to_server_helper(self, "/org/asuslinux/Anime", server).await;
|
||||||
}
|
}
|
||||||
@@ -28,127 +26,105 @@ impl crate::ZbusAdd for CtrlAnimeZbus {
|
|||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||||
impl CtrlAnimeZbus {
|
impl CtrlAnimeZbus {
|
||||||
/// Writes a data stream of length. Will force system thread to exit until it is restarted
|
/// Writes a data stream of length. Will force system thread to exit until it is restarted
|
||||||
fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
|
async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
|
||||||
'outer: loop {
|
let lock = self.0.lock().await;
|
||||||
if let Ok(lock) = self.0.try_lock() {
|
lock.thread_exit.store(true, Ordering::SeqCst);
|
||||||
lock.thread_exit.store(true, Ordering::SeqCst);
|
lock.write_data_buffer(input).map_err(|err| {
|
||||||
lock.write_data_buffer(input).map_err(|err| {
|
warn!("rog_anime::run_animation:callback {}", err);
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
err
|
||||||
err
|
})?;
|
||||||
})?;
|
|
||||||
break 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the global AniMe brightness
|
/// Set the global AniMe brightness
|
||||||
fn set_brightness(&self, bright: f32) {
|
async fn set_brightness(&self, bright: f32) {
|
||||||
'outer: loop {
|
let mut lock = self.0.lock().await;
|
||||||
if let Ok(mut lock) = self.0.try_lock() {
|
let mut bright = bright;
|
||||||
let mut bright = bright;
|
if bright < 0.0 {
|
||||||
if bright < 0.0 {
|
bright = 0.0
|
||||||
bright = 0.0
|
} else if bright > 1.0 {
|
||||||
} else if bright > 1.0 {
|
bright = 1.0;
|
||||||
bright = 1.0;
|
|
||||||
}
|
|
||||||
lock.config.brightness = bright;
|
|
||||||
lock.config.write();
|
|
||||||
break 'outer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
lock.config.brightness = bright;
|
||||||
|
lock.config.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set whether the AniMe is displaying images/data
|
/// Set whether the AniMe is displaying images/data
|
||||||
async fn set_on_off(&self, #[zbus(signal_context)] ctxt: SignalContext<'_>, status: bool) {
|
async fn set_on_off(&self, #[zbus(signal_context)] ctxt: SignalContext<'_>, status: bool) {
|
||||||
let states;
|
let mut lock = self.0.lock().await;
|
||||||
'outer: loop {
|
lock.node
|
||||||
if let Ok(mut lock) = self.0.try_lock() {
|
.write_bytes(&pkt_for_set_on(status))
|
||||||
lock.node
|
.map_err(|err| {
|
||||||
.write_bytes(&pkt_for_set_on(status))
|
warn!("rog_anime::run_animation:callback {}", err);
|
||||||
.map_err(|err| {
|
})
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
.ok();
|
||||||
})
|
lock.config.awake_enabled = status;
|
||||||
.ok();
|
lock.config.write();
|
||||||
lock.config.awake_enabled = status;
|
|
||||||
lock.config.write();
|
|
||||||
|
|
||||||
states = Some(AnimePowerStates {
|
Self::notify_power_states(
|
||||||
brightness: lock.config.brightness.floor() as u8,
|
&ctxt,
|
||||||
enabled: lock.config.awake_enabled,
|
AnimePowerStates {
|
||||||
boot_anim_enabled: lock.config.boot_anim_enabled,
|
brightness: lock.config.brightness.floor() as u8,
|
||||||
});
|
enabled: lock.config.awake_enabled,
|
||||||
break 'outer;
|
boot_anim_enabled: lock.config.boot_anim_enabled,
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
if let Some(state) = states {
|
.await
|
||||||
Self::notify_power_states(&ctxt, state).await.ok();
|
.ok();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set whether the AniMe will show boot, suspend, or off animations
|
/// Set whether the AniMe will show boot, suspend, or off animations
|
||||||
async fn set_boot_on_off(&self, #[zbus(signal_context)] ctxt: SignalContext<'_>, on: bool) {
|
async fn set_boot_on_off(&self, #[zbus(signal_context)] ctxt: SignalContext<'_>, on: bool) {
|
||||||
let states;
|
let mut lock = self.0.lock().await;
|
||||||
'outer: loop {
|
lock.node
|
||||||
if let Ok(mut lock) = self.0.try_lock() {
|
.write_bytes(&pkt_for_set_boot(on))
|
||||||
lock.node
|
.map_err(|err| {
|
||||||
.write_bytes(&pkt_for_set_boot(on))
|
warn!("rog_anime::run_animation:callback {}", err);
|
||||||
.map_err(|err| {
|
})
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
.ok();
|
||||||
})
|
lock.node
|
||||||
.ok();
|
.write_bytes(&pkt_for_apply())
|
||||||
lock.node
|
.map_err(|err| {
|
||||||
.write_bytes(&pkt_for_apply())
|
warn!("rog_anime::run_animation:callback {}", err);
|
||||||
.map_err(|err| {
|
})
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
.ok();
|
||||||
})
|
lock.config.boot_anim_enabled = on;
|
||||||
.ok();
|
lock.config.write();
|
||||||
lock.config.boot_anim_enabled = on;
|
|
||||||
lock.config.write();
|
|
||||||
|
|
||||||
states = Some(AnimePowerStates {
|
Self::notify_power_states(
|
||||||
brightness: lock.config.brightness.floor() as u8,
|
&ctxt,
|
||||||
enabled: lock.config.awake_enabled,
|
AnimePowerStates {
|
||||||
boot_anim_enabled: lock.config.boot_anim_enabled,
|
brightness: lock.config.brightness.floor() as u8,
|
||||||
});
|
enabled: lock.config.awake_enabled,
|
||||||
break 'outer;
|
boot_anim_enabled: lock.config.boot_anim_enabled,
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
if let Some(state) = states {
|
.await
|
||||||
Self::notify_power_states(&ctxt, state).await.ok();
|
.ok();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The main loop is the base system set action if the user isn't running
|
/// The main loop is the base system set action if the user isn't running
|
||||||
/// the user daemon
|
/// the user daemon
|
||||||
fn run_main_loop(&self, start: bool) {
|
async fn run_main_loop(&self, start: bool) {
|
||||||
if start {
|
if start {
|
||||||
'outer: loop {
|
let lock = self.0.lock().await;
|
||||||
if let Ok(lock) = self.0.try_lock() {
|
lock.thread_exit.store(true, Ordering::SeqCst);
|
||||||
lock.thread_exit.store(true, Ordering::SeqCst);
|
CtrlAnime::run_thread(self.0.clone(), lock.cache.system.clone(), false);
|
||||||
CtrlAnime::run_thread(self.0.clone(), lock.cache.system.clone(), false);
|
|
||||||
break 'outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get status of if the AniMe LEDs are on/displaying while system is awake
|
/// Get status of if the AniMe LEDs are on/displaying while system is awake
|
||||||
#[dbus_interface(property)]
|
#[dbus_interface(property)]
|
||||||
fn awake_enabled(&self) -> bool {
|
async fn awake_enabled(&self) -> bool {
|
||||||
if let Ok(ctrl) = self.0.try_lock() {
|
let lock = self.0.lock().await;
|
||||||
return ctrl.config.awake_enabled;
|
return lock.config.awake_enabled;
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the status of if factory system-status animations are enabled
|
/// Get the status of if factory system-status animations are enabled
|
||||||
#[dbus_interface(property)]
|
#[dbus_interface(property)]
|
||||||
fn boot_enabled(&self) -> bool {
|
async fn boot_enabled(&self) -> bool {
|
||||||
if let Ok(ctrl) = self.0.try_lock() {
|
let lock = self.0.lock().await;
|
||||||
return ctrl.config.boot_anim_enabled;
|
return lock.config.boot_anim_enabled;
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Notify listeners of the status of AniMe LED power and factory system-status animations
|
/// Notify listeners of the status of AniMe LED power and factory system-status animations
|
||||||
|
|||||||
@@ -13,9 +13,13 @@ use rog_aura::{AuraZone, Direction, Speed, GRADIENT};
|
|||||||
use rog_platform::{hid_raw::HidRaw, keyboard_led::KeyboardLed, supported::LedSupportedFunctions};
|
use rog_platform::{hid_raw::HidRaw, keyboard_led::KeyboardLed, supported::LedSupportedFunctions};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use zbus::{
|
||||||
use std::sync::MutexGuard;
|
export::futures_util::{
|
||||||
use zbus::{export::futures_util::StreamExt, SignalContext};
|
lock::{Mutex, MutexGuard},
|
||||||
|
StreamExt,
|
||||||
|
},
|
||||||
|
SignalContext,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::GetSupported;
|
use crate::GetSupported;
|
||||||
|
|
||||||
@@ -121,25 +125,25 @@ impl CtrlTask for CtrlKbdLedTask {
|
|||||||
// Loop so that we do aquire the lock but also don't block other
|
// Loop so that we do aquire the lock but also don't block other
|
||||||
// threads (prevents potential deadlocks)
|
// threads (prevents potential deadlocks)
|
||||||
move || loop {
|
move || loop {
|
||||||
if let Ok(lock) = inner1.clone().try_lock() {
|
if let Some(lock) = inner1.try_lock() {
|
||||||
load_save(true, lock);
|
load_save(true, lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || loop {
|
move || loop {
|
||||||
if let Ok(lock) = inner2.clone().try_lock() {
|
if let Some(lock) = inner2.try_lock() {
|
||||||
load_save(false, lock);
|
load_save(false, lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || loop {
|
move || loop {
|
||||||
if let Ok(lock) = inner3.clone().try_lock() {
|
if let Some(lock) = inner3.try_lock() {
|
||||||
load_save(true, lock);
|
load_save(true, lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || loop {
|
move || loop {
|
||||||
if let Ok(lock) = inner4.clone().try_lock() {
|
if let Some(lock) = inner4.try_lock() {
|
||||||
load_save(false, lock);
|
load_save(false, lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -148,21 +152,20 @@ impl CtrlTask for CtrlKbdLedTask {
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
let ctrl2 = self.inner.clone();
|
let ctrl2 = self.inner.clone();
|
||||||
if let Ok(ctrl) = self.inner.lock() {
|
let ctrl = self.inner.lock().await;
|
||||||
let mut watch = ctrl.kd_brightness.monitor_brightness()?;
|
let mut watch = ctrl.kd_brightness.monitor_brightness()?;
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
watch
|
watch
|
||||||
.event_stream(&mut buffer)
|
.event_stream(&mut buffer)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.for_each(|_| async {
|
.for_each(|_| async {
|
||||||
if let Ok(lock) = ctrl2.try_lock() {
|
if let Some(lock) = ctrl2.try_lock() {
|
||||||
load_save(true, lock);
|
load_save(true, lock);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -170,12 +173,12 @@ impl CtrlTask for CtrlKbdLedTask {
|
|||||||
|
|
||||||
pub struct CtrlKbdLedReloader(pub Arc<Mutex<CtrlKbdLed>>);
|
pub struct CtrlKbdLedReloader(pub Arc<Mutex<CtrlKbdLed>>);
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl crate::Reloadable for CtrlKbdLedReloader {
|
impl crate::Reloadable for CtrlKbdLedReloader {
|
||||||
fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.write_current_config_mode()?;
|
ctrl.write_current_config_mode()?;
|
||||||
ctrl.set_power_states().map_err(|err| warn!("{err}")).ok();
|
ctrl.set_power_states().map_err(|err| warn!("{err}")).ok();
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use zbus::{dbus_interface, Connection, SignalContext};
|
|||||||
use super::controller::CtrlKbdLedZbus;
|
use super::controller::CtrlKbdLedZbus;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusAdd for CtrlKbdLedZbus {
|
impl crate::ZbusRun for CtrlKbdLedZbus {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, "/org/asuslinux/Aura", server).await;
|
Self::add_to_server_helper(self, "/org/asuslinux/Aura", server).await;
|
||||||
}
|
}
|
||||||
@@ -21,11 +21,10 @@ impl crate::ZbusAdd for CtrlKbdLedZbus {
|
|||||||
impl CtrlKbdLedZbus {
|
impl CtrlKbdLedZbus {
|
||||||
/// Set the keyboard brightness level (0-3)
|
/// Set the keyboard brightness level (0-3)
|
||||||
async fn set_brightness(&mut self, brightness: LedBrightness) {
|
async fn set_brightness(&mut self, brightness: LedBrightness) {
|
||||||
if let Ok(ctrl) = self.0.try_lock() {
|
let ctrl = self.0.lock().await;
|
||||||
ctrl.set_brightness(brightness)
|
ctrl.set_brightness(brightness)
|
||||||
.map_err(|err| warn!("{}", err))
|
.map_err(|err| warn!("{}", err))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a variety of states, input is array of enum.
|
/// Set a variety of states, input is array of enum.
|
||||||
@@ -64,36 +63,27 @@ impl CtrlKbdLedZbus {
|
|||||||
options: AuraPowerDev,
|
options: AuraPowerDev,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
let mut states = None;
|
let mut ctrl = self.0.lock().await;
|
||||||
loop {
|
for p in options.tuf {
|
||||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
ctrl.config.enabled.set_tuf(p, enabled);
|
||||||
for p in options.tuf {
|
|
||||||
ctrl.config.enabled.set_tuf(p, enabled);
|
|
||||||
}
|
|
||||||
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().map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
|
|
||||||
states = Some(AuraPowerDev::from(&ctrl.config.enabled));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// Need to pull state out like this due to MutexGuard
|
for p in options.x1866 {
|
||||||
if let Some(states) = states {
|
ctrl.config.enabled.set_0x1866(p, enabled);
|
||||||
Self::notify_power_states(&ctxt, &states)
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
|
||||||
}
|
}
|
||||||
|
for p in options.x19b6 {
|
||||||
|
ctrl.config.enabled.set_0x19b6(p, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl.config.write();
|
||||||
|
|
||||||
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,21 +92,15 @@ impl CtrlKbdLedZbus {
|
|||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||||
effect: AuraEffect,
|
effect: AuraEffect,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
let mut led = None;
|
let mut ctrl = self.0.lock().await;
|
||||||
loop {
|
|
||||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
ctrl.set_effect(effect).map_err(|e| {
|
||||||
ctrl.set_effect(effect).map_err(|e| {
|
warn!("{}", e);
|
||||||
warn!("{}", e);
|
e
|
||||||
e
|
})?;
|
||||||
})?;
|
|
||||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||||
led = Some(mode.clone());
|
Self::notify_led(&ctxt, mode.clone())
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(led) = led {
|
|
||||||
Self::notify_led(&ctxt, led)
|
|
||||||
.await
|
.await
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
.unwrap_or_else(|err| warn!("{}", err));
|
||||||
}
|
}
|
||||||
@@ -127,22 +111,15 @@ impl CtrlKbdLedZbus {
|
|||||||
&self,
|
&self,
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
let mut led = None;
|
let mut ctrl = self.0.lock().await;
|
||||||
loop {
|
|
||||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
||||||
ctrl.toggle_mode(false).map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
ctrl.toggle_mode(false).map_err(|e| {
|
||||||
led = Some(mode.clone());
|
warn!("{}", e);
|
||||||
}
|
e
|
||||||
break;
|
})?;
|
||||||
}
|
|
||||||
}
|
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||||
if let Some(led) = led {
|
Self::notify_led(&ctxt, mode.clone())
|
||||||
Self::notify_led(&ctxt, led)
|
|
||||||
.await
|
.await
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
.unwrap_or_else(|err| warn!("{}", err));
|
||||||
}
|
}
|
||||||
@@ -154,100 +131,70 @@ impl CtrlKbdLedZbus {
|
|||||||
&self,
|
&self,
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
let mut led = None;
|
let mut ctrl = self.0.lock().await;
|
||||||
loop {
|
|
||||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
||||||
ctrl.toggle_mode(true).map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
ctrl.toggle_mode(true).map_err(|e| {
|
||||||
led = Some(mode.clone());
|
warn!("{}", e);
|
||||||
}
|
e
|
||||||
break;
|
})?;
|
||||||
}
|
|
||||||
}
|
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||||
if let Some(led) = led {
|
Self::notify_led(&ctxt, mode.clone())
|
||||||
Self::notify_led(&ctxt, led)
|
|
||||||
.await
|
.await
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
.unwrap_or_else(|err| warn!("{}", err));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn next_led_brightness(&self) -> zbus::fdo::Result<()> {
|
async fn next_led_brightness(&self) -> zbus::fdo::Result<()> {
|
||||||
loop {
|
let mut ctrl = self.0.lock().await;
|
||||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
ctrl.next_brightness().map_err(|e| {
|
||||||
ctrl.next_brightness().map_err(|e| {
|
warn!("{}", e);
|
||||||
warn!("{}", e);
|
e
|
||||||
e
|
})?;
|
||||||
})?;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn prev_led_brightness(&self) -> zbus::fdo::Result<()> {
|
async fn prev_led_brightness(&self) -> zbus::fdo::Result<()> {
|
||||||
loop {
|
let mut ctrl = self.0.lock().await;
|
||||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
ctrl.prev_brightness().map_err(|e| {
|
||||||
ctrl.prev_brightness().map_err(|e| {
|
warn!("{}", e);
|
||||||
warn!("{}", e);
|
e
|
||||||
e
|
})?;
|
||||||
})?;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// As property doesn't work for AuraPowerDev (complexity of serialization?)
|
// As property doesn't work for AuraPowerDev (complexity of serialization?)
|
||||||
// #[dbus_interface(property)]
|
// #[dbus_interface(property)]
|
||||||
async fn leds_enabled(&self) -> AuraPowerDev {
|
async fn leds_enabled(&self) -> AuraPowerDev {
|
||||||
loop {
|
let ctrl = self.0.lock().await;
|
||||||
if let Ok(ctrl) = self.0.try_lock() {
|
return AuraPowerDev::from(&ctrl.config.enabled);
|
||||||
return AuraPowerDev::from(&ctrl.config.enabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the current mode data
|
/// Return the current mode data
|
||||||
async fn led_mode(&self) -> AuraModeNum {
|
async fn led_mode(&self) -> AuraModeNum {
|
||||||
loop {
|
let ctrl = self.0.lock().await;
|
||||||
if let Ok(ctrl) = self.0.try_lock() {
|
return ctrl.config.current_mode;
|
||||||
return ctrl.config.current_mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a list of available modes
|
/// Return a list of available modes
|
||||||
async fn led_modes(&self) -> BTreeMap<AuraModeNum, AuraEffect> {
|
async fn led_modes(&self) -> BTreeMap<AuraModeNum, AuraEffect> {
|
||||||
loop {
|
let ctrl = self.0.lock().await;
|
||||||
if let Ok(ctrl) = self.0.try_lock() {
|
return ctrl.config.builtins.clone();
|
||||||
return ctrl.config.builtins.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn per_key_raw(&self, data: PerKeyRaw) -> zbus::fdo::Result<()> {
|
async fn per_key_raw(&self, data: PerKeyRaw) -> zbus::fdo::Result<()> {
|
||||||
loop {
|
let mut ctrl = self.0.lock().await;
|
||||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
ctrl.write_effect_block(&data)?;
|
||||||
ctrl.write_effect_block(&data)?;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the current LED brightness
|
/// Return the current LED brightness
|
||||||
#[dbus_interface(property)]
|
#[dbus_interface(property)]
|
||||||
async fn led_brightness(&self) -> i8 {
|
async fn led_brightness(&self) -> i8 {
|
||||||
loop {
|
let ctrl = self.0.lock().await;
|
||||||
if let Ok(ctrl) = self.0.try_lock() {
|
ctrl.get_brightness().map(|n| n as i8).unwrap_or(-1)
|
||||||
return ctrl.get_brightness().map(|n| n as i8).unwrap_or(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
#[dbus_interface(signal)]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use std::io::{Read, Write};
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
use zbus::{dbus_interface, SignalContext};
|
use zbus::{dbus_interface, SignalContext};
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ impl CtrlRogBios {
|
|||||||
})
|
})
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
if let Ok(mut lock) = self.config.try_lock() {
|
if let Some(mut lock) = self.config.try_lock() {
|
||||||
lock.panel_od = overdrive;
|
lock.panel_od = overdrive;
|
||||||
lock.write();
|
lock.write();
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@ impl CtrlRogBios {
|
|||||||
err
|
err
|
||||||
})
|
})
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if let Ok(mut lock) = self.config.try_lock() {
|
if let Some(mut lock) = self.config.try_lock() {
|
||||||
lock.panel_od = od;
|
lock.panel_od = od;
|
||||||
lock.write();
|
lock.write();
|
||||||
}
|
}
|
||||||
@@ -241,16 +241,17 @@ impl CtrlRogBios {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusAdd for CtrlRogBios {
|
impl crate::ZbusRun for CtrlRogBios {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, "/org/asuslinux/Platform", server).await;
|
Self::add_to_server_helper(self, "/org/asuslinux/Platform", server).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl crate::Reloadable for CtrlRogBios {
|
impl crate::Reloadable for CtrlRogBios {
|
||||||
fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if self.platform.has_panel_od() {
|
if self.platform.has_panel_od() {
|
||||||
let p = if let Ok(lock) = self.config.try_lock() {
|
let p = if let Some(lock) = self.config.try_lock() {
|
||||||
lock.panel_od
|
lock.panel_od
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@@ -275,7 +276,7 @@ impl CtrlTask for CtrlRogBios {
|
|||||||
move || {},
|
move || {},
|
||||||
move || {
|
move || {
|
||||||
info!("CtrlRogBios reloading panel_od");
|
info!("CtrlRogBios reloading panel_od");
|
||||||
if let Ok(lock) = platform1.config.try_lock() {
|
if let Some(lock) = platform1.config.try_lock() {
|
||||||
if platform1.platform.has_panel_od() {
|
if platform1.platform.has_panel_od() {
|
||||||
platform1
|
platform1
|
||||||
.set_panel_overdrive(lock.panel_od)
|
.set_panel_overdrive(lock.panel_od)
|
||||||
@@ -290,7 +291,7 @@ impl CtrlTask for CtrlRogBios {
|
|||||||
move || {},
|
move || {},
|
||||||
move || {
|
move || {
|
||||||
info!("CtrlRogBios reloading panel_od");
|
info!("CtrlRogBios reloading panel_od");
|
||||||
if let Ok(lock) = platform2.config.try_lock() {
|
if let Some(lock) = platform2.config.try_lock() {
|
||||||
if platform2.platform.has_panel_od() {
|
if platform2.platform.has_panel_od() {
|
||||||
platform2
|
platform2
|
||||||
.set_panel_overdrive(lock.panel_od)
|
.set_panel_overdrive(lock.panel_od)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use log::{info, warn};
|
|||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
use rog_platform::supported::ChargeSupportedFunctions;
|
use rog_platform::supported::ChargeSupportedFunctions;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
|
||||||
use zbus::dbus_interface;
|
use zbus::dbus_interface;
|
||||||
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
use zbus::SignalContext;
|
use zbus::SignalContext;
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ impl CtrlPower {
|
|||||||
|
|
||||||
fn charge_control_end_threshold(&self) -> u8 {
|
fn charge_control_end_threshold(&self) -> u8 {
|
||||||
loop {
|
loop {
|
||||||
if let Ok(config) = self.config.try_lock() {
|
if let Some(config) = self.config.try_lock() {
|
||||||
let limit = self
|
let limit = self
|
||||||
.power
|
.power
|
||||||
.get_charge_control_end_threshold()
|
.get_charge_control_end_threshold()
|
||||||
@@ -61,7 +61,7 @@ impl CtrlPower {
|
|||||||
err
|
err
|
||||||
})
|
})
|
||||||
.unwrap_or(100);
|
.unwrap_or(100);
|
||||||
if let Ok(mut config) = self.config.try_lock() {
|
if let Some(mut config) = self.config.try_lock() {
|
||||||
config.read();
|
config.read();
|
||||||
config.bat_charge_limit = limit;
|
config.bat_charge_limit = limit;
|
||||||
config.write();
|
config.write();
|
||||||
@@ -80,15 +80,16 @@ impl CtrlPower {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusAdd for CtrlPower {
|
impl crate::ZbusRun for CtrlPower {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, "/org/asuslinux/Charge", server).await;
|
Self::add_to_server_helper(self, "/org/asuslinux/Charge", server).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl crate::Reloadable for CtrlPower {
|
impl crate::Reloadable for CtrlPower {
|
||||||
fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if let Ok(mut config) = self.config.try_lock() {
|
if let Some(mut config) = self.config.try_lock() {
|
||||||
config.read();
|
config.read();
|
||||||
self.set(config.bat_charge_limit)?;
|
self.set(config.bat_charge_limit)?;
|
||||||
}
|
}
|
||||||
@@ -113,7 +114,7 @@ impl CtrlPower {
|
|||||||
|
|
||||||
info!("Battery charge limit: {}", limit);
|
info!("Battery charge limit: {}", limit);
|
||||||
|
|
||||||
if let Ok(mut config) = self.config.try_lock() {
|
if let Some(mut config) = self.config.try_lock() {
|
||||||
config.read();
|
config.read();
|
||||||
config.bat_charge_limit = limit;
|
config.bat_charge_limit = limit;
|
||||||
config.write();
|
config.write();
|
||||||
@@ -134,7 +135,7 @@ impl CtrlTask for CtrlPower {
|
|||||||
move || {},
|
move || {},
|
||||||
move || {
|
move || {
|
||||||
info!("CtrlCharge reloading charge limit");
|
info!("CtrlCharge reloading charge limit");
|
||||||
if let Ok(lock) = power1.config.try_lock() {
|
if let Some(lock) = power1.config.try_lock() {
|
||||||
power1
|
power1
|
||||||
.set(lock.bat_charge_limit)
|
.set(lock.bat_charge_limit)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -147,7 +148,7 @@ impl CtrlTask for CtrlPower {
|
|||||||
move || {},
|
move || {},
|
||||||
move || {
|
move || {
|
||||||
info!("CtrlCharge reloading charge limit");
|
info!("CtrlCharge reloading charge limit");
|
||||||
if let Ok(lock) = power2.config.try_lock() {
|
if let Some(lock) = power2.config.try_lock() {
|
||||||
power2
|
power2
|
||||||
.set(lock.bat_charge_limit)
|
.set(lock.bat_charge_limit)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::GetSupported;
|
use crate::GetSupported;
|
||||||
|
use async_trait::async_trait;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
use rog_platform::platform::AsusPlatform;
|
||||||
use rog_platform::supported::PlatformProfileFunctions;
|
use rog_platform::supported::PlatformProfileFunctions;
|
||||||
use rog_profiles::error::ProfileError;
|
use rog_profiles::error::ProfileError;
|
||||||
use rog_profiles::{FanCurveProfiles, Profile};
|
use rog_profiles::{FanCurveProfiles, Profile};
|
||||||
@@ -9,6 +11,7 @@ use super::config::ProfileConfig;
|
|||||||
|
|
||||||
pub struct CtrlPlatformProfile {
|
pub struct CtrlPlatformProfile {
|
||||||
pub config: ProfileConfig,
|
pub config: ProfileConfig,
|
||||||
|
pub platform: AsusPlatform,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetSupported for CtrlPlatformProfile {
|
impl GetSupported for CtrlPlatformProfile {
|
||||||
@@ -36,9 +39,10 @@ impl GetSupported for CtrlPlatformProfile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl crate::Reloadable for CtrlPlatformProfile {
|
impl crate::Reloadable for CtrlPlatformProfile {
|
||||||
/// Fetch the active profile and use that to set all related components up
|
/// Fetch the active profile and use that to set all related components up
|
||||||
fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if let Some(curves) = &mut self.config.fan_curves {
|
if let Some(curves) = &mut self.config.fan_curves {
|
||||||
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
||||||
// There is a possibility that the curve was default zeroed, so this call initialises
|
// There is a possibility that the curve was default zeroed, so this call initialises
|
||||||
@@ -53,10 +57,11 @@ impl crate::Reloadable for CtrlPlatformProfile {
|
|||||||
|
|
||||||
impl CtrlPlatformProfile {
|
impl CtrlPlatformProfile {
|
||||||
pub fn new(config: ProfileConfig) -> Result<Self, RogError> {
|
pub fn new(config: ProfileConfig) -> Result<Self, RogError> {
|
||||||
if Profile::is_platform_profile_supported() {
|
let platform = AsusPlatform::new()?;
|
||||||
|
if platform.has_platform_profile() || platform.has_throttle_thermal_policy() {
|
||||||
info!("Device has profile control available");
|
info!("Device has profile control available");
|
||||||
|
|
||||||
let mut controller = CtrlPlatformProfile { config };
|
let mut controller = CtrlPlatformProfile { config, platform };
|
||||||
if FanCurveProfiles::get_device().is_ok() {
|
if FanCurveProfiles::get_device().is_ok() {
|
||||||
info!("Device has fan curves available");
|
info!("Device has fan curves available");
|
||||||
if controller.config.fan_curves.is_none() {
|
if controller.config.fan_curves.is_none() {
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use inotify::Inotify;
|
|
||||||
use inotify::WatchMask;
|
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use rog_profiles::fan_curve_set::CurveData;
|
use rog_profiles::fan_curve_set::CurveData;
|
||||||
use rog_profiles::fan_curve_set::FanCurveSet;
|
use rog_profiles::fan_curve_set::FanCurveSet;
|
||||||
use rog_profiles::Profile;
|
use rog_profiles::Profile;
|
||||||
use rog_profiles::PLATFORM_PROFILE;
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::export::futures_util::StreamExt;
|
use zbus::export::futures_util::StreamExt;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
use zbus::SignalContext;
|
use zbus::SignalContext;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
|
||||||
use zbus::{dbus_interface, fdo::Error};
|
use zbus::{dbus_interface, fdo::Error};
|
||||||
|
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
@@ -47,27 +44,21 @@ impl ProfileZbus {
|
|||||||
/// Toggle to next platform_profile. Names provided by `Profiles`.
|
/// Toggle to next platform_profile. Names provided by `Profiles`.
|
||||||
/// If fan-curves are supported will also activate a fan curve for profile.
|
/// If fan-curves are supported will also activate a fan curve for profile.
|
||||||
async fn next_profile(&mut self, #[zbus(signal_context)] ctxt: SignalContext<'_>) {
|
async fn next_profile(&mut self, #[zbus(signal_context)] ctxt: SignalContext<'_>) {
|
||||||
let mut profile = None;
|
let mut ctrl = self.inner.lock().await;
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
ctrl.set_next_profile()
|
||||||
ctrl.set_next_profile()
|
.unwrap_or_else(|err| warn!("{}", err));
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
ctrl.save_config();
|
||||||
ctrl.save_config();
|
|
||||||
profile = Some(ctrl.config.active_profile);
|
Self::notify_profile(&ctxt, ctrl.config.active_profile)
|
||||||
}
|
.await
|
||||||
if let Some(profile) = profile {
|
.ok();
|
||||||
Self::notify_profile(&ctxt, profile).await.ok();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the active profile name
|
/// Fetch the active profile name
|
||||||
fn active_profile(&mut self) -> zbus::fdo::Result<Profile> {
|
async fn active_profile(&mut self) -> zbus::fdo::Result<Profile> {
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
let mut ctrl = self.inner.lock().await;
|
||||||
ctrl.config.read();
|
ctrl.config.read();
|
||||||
return Ok(ctrl.config.active_profile);
|
Ok(ctrl.config.active_profile)
|
||||||
}
|
|
||||||
Err(Error::Failed(
|
|
||||||
"Failed to get active profile name".to_string(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set this platform_profile name as active
|
/// Set this platform_profile name as active
|
||||||
@@ -76,93 +67,85 @@ impl ProfileZbus {
|
|||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||||
profile: Profile,
|
profile: Profile,
|
||||||
) {
|
) {
|
||||||
let mut tmp = None;
|
let mut ctrl = self.inner.lock().await;
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
// Read first just incase the user has modified the config before calling this
|
||||||
// Read first just incase the user has modified the config before calling this
|
ctrl.config.read();
|
||||||
ctrl.config.read();
|
Profile::set_profile(profile)
|
||||||
Profile::set_profile(profile)
|
.map_err(|e| warn!("set_profile, {}", e))
|
||||||
.map_err(|e| warn!("set_profile, {}", e))
|
.ok();
|
||||||
.ok();
|
ctrl.config.active_profile = profile;
|
||||||
ctrl.config.active_profile = profile;
|
ctrl.write_profile_curve_to_platform()
|
||||||
|
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
ctrl.save_config();
|
||||||
|
|
||||||
|
Self::notify_profile(&ctxt, ctrl.config.active_profile)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list of profiles that have fan-curves enabled.
|
||||||
|
async fn enabled_fan_profiles(&mut self) -> zbus::fdo::Result<Vec<Profile>> {
|
||||||
|
let mut ctrl = self.inner.lock().await;
|
||||||
|
ctrl.config.read();
|
||||||
|
if let Some(curves) = &ctrl.config.fan_curves {
|
||||||
|
return Ok(curves.get_enabled_curve_profiles().to_vec());
|
||||||
|
}
|
||||||
|
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set a profile fan curve enabled status. Will also activate a fan curve if in the
|
||||||
|
/// same profile mode
|
||||||
|
async fn set_fan_curve_enabled(
|
||||||
|
&mut self,
|
||||||
|
profile: Profile,
|
||||||
|
enabled: bool,
|
||||||
|
) -> zbus::fdo::Result<()> {
|
||||||
|
let mut ctrl = self.inner.lock().await;
|
||||||
|
ctrl.config.read();
|
||||||
|
return if let Some(curves) = &mut ctrl.config.fan_curves {
|
||||||
|
curves.set_profile_curve_enabled(profile, enabled);
|
||||||
|
|
||||||
ctrl.write_profile_curve_to_platform()
|
ctrl.write_profile_curve_to_platform()
|
||||||
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
tmp = Some(ctrl.config.active_profile);
|
Ok(())
|
||||||
}
|
} else {
|
||||||
if let Some(profile) = tmp {
|
Err(Error::Failed(UNSUPPORTED_MSG.to_string()))
|
||||||
Self::notify_profile(&ctxt, profile).await.ok();
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a list of profiles that have fan-curves enabled.
|
|
||||||
fn enabled_fan_profiles(&mut self) -> zbus::fdo::Result<Vec<Profile>> {
|
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
|
||||||
ctrl.config.read();
|
|
||||||
if let Some(curves) = &ctrl.config.fan_curves {
|
|
||||||
return Ok(curves.get_enabled_curve_profiles().to_vec());
|
|
||||||
}
|
|
||||||
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
|
|
||||||
}
|
|
||||||
Err(Error::Failed(
|
|
||||||
"Failed to get enabled fan curve names".to_string(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set a profile fan curve enabled status. Will also activate a fan curve if in the
|
|
||||||
/// same profile mode
|
|
||||||
fn set_fan_curve_enabled(&mut self, profile: Profile, enabled: bool) -> zbus::fdo::Result<()> {
|
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
|
||||||
ctrl.config.read();
|
|
||||||
return if let Some(curves) = &mut ctrl.config.fan_curves {
|
|
||||||
curves.set_profile_curve_enabled(profile, enabled);
|
|
||||||
|
|
||||||
ctrl.write_profile_curve_to_platform()
|
|
||||||
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
ctrl.save_config();
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(Error::Failed(UNSUPPORTED_MSG.to_string()))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Err(Error::Failed(
|
|
||||||
"Failed to get enabled fan curve names".to_string(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the fan-curve data for the currently active Profile
|
/// Get the fan-curve data for the currently active Profile
|
||||||
fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<FanCurveSet> {
|
async fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<FanCurveSet> {
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
let mut ctrl = self.inner.lock().await;
|
||||||
ctrl.config.read();
|
ctrl.config.read();
|
||||||
if let Some(curves) = &ctrl.config.fan_curves {
|
if let Some(curves) = &ctrl.config.fan_curves {
|
||||||
let curve = curves.get_fan_curves_for(profile);
|
let curve = curves.get_fan_curves_for(profile);
|
||||||
return Ok(curve.clone());
|
return Ok(curve.clone());
|
||||||
}
|
|
||||||
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
|
|
||||||
}
|
}
|
||||||
Err(Error::Failed("Failed to get fan curve data".to_string()))
|
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the fan curve for the specified profile.
|
/// Set the fan curve for the specified profile.
|
||||||
/// Will also activate the fan curve if the user is in the same mode.
|
/// Will also activate the fan curve if the user is in the same mode.
|
||||||
fn set_fan_curve(&self, profile: Profile, curve: CurveData) -> zbus::fdo::Result<()> {
|
async fn set_fan_curve(&self, profile: Profile, curve: CurveData) -> zbus::fdo::Result<()> {
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
let mut ctrl = self.inner.lock().await;
|
||||||
ctrl.config.read();
|
ctrl.config.read();
|
||||||
if let Some(curves) = &mut ctrl.config.fan_curves {
|
if let Some(curves) = &mut ctrl.config.fan_curves {
|
||||||
curves
|
curves
|
||||||
.save_fan_curve(curve, profile)
|
.save_fan_curve(curve, profile)
|
||||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
|
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
|
||||||
}
|
|
||||||
ctrl.write_profile_curve_to_platform()
|
|
||||||
.map_err(|e| warn!("Profile::set_profile, {}", e))
|
|
||||||
.ok();
|
|
||||||
ctrl.save_config();
|
|
||||||
}
|
}
|
||||||
|
ctrl.write_profile_curve_to_platform()
|
||||||
|
.map_err(|e| warn!("Profile::set_profile, {}", e))
|
||||||
|
.ok();
|
||||||
|
ctrl.save_config();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,14 +153,13 @@ impl ProfileZbus {
|
|||||||
///
|
///
|
||||||
/// Each platform_profile has a different default and the defualt can be read
|
/// Each platform_profile has a different default and the defualt can be read
|
||||||
/// only for the currently active profile.
|
/// only for the currently active profile.
|
||||||
fn set_active_curve_to_defaults(&self) -> zbus::fdo::Result<()> {
|
async fn set_active_curve_to_defaults(&self) -> zbus::fdo::Result<()> {
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
let mut ctrl = self.inner.lock().await;
|
||||||
ctrl.config.read();
|
ctrl.config.read();
|
||||||
ctrl.set_active_curve_to_defaults()
|
ctrl.set_active_curve_to_defaults()
|
||||||
.map_err(|e| warn!("Profile::set_active_curve_to_defaults, {}", e))
|
.map_err(|e| warn!("Profile::set_active_curve_to_defaults, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,23 +167,22 @@ impl ProfileZbus {
|
|||||||
///
|
///
|
||||||
/// Each platform_profile has a different default and the defualt can be read
|
/// Each platform_profile has a different default and the defualt can be read
|
||||||
/// only for the currently active profile.
|
/// only for the currently active profile.
|
||||||
fn reset_profile_curves(&self, profile: Profile) -> zbus::fdo::Result<()> {
|
async fn reset_profile_curves(&self, profile: Profile) -> zbus::fdo::Result<()> {
|
||||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
let mut ctrl = self.inner.lock().await;
|
||||||
ctrl.config.read();
|
ctrl.config.read();
|
||||||
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
||||||
|
|
||||||
Profile::set_profile(profile)
|
Profile::set_profile(profile)
|
||||||
.map_err(|e| warn!("set_profile, {}", e))
|
.map_err(|e| warn!("set_profile, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
ctrl.set_active_curve_to_defaults()
|
ctrl.set_active_curve_to_defaults()
|
||||||
.map_err(|e| warn!("Profile::set_active_curve_to_defaults, {}", e))
|
.map_err(|e| warn!("Profile::set_active_curve_to_defaults, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
Profile::set_profile(active)
|
Profile::set_profile(active)
|
||||||
.map_err(|e| warn!("set_profile, {}", e))
|
.map_err(|e| warn!("set_profile, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +192,7 @@ impl ProfileZbus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusAdd for ProfileZbus {
|
impl crate::ZbusRun for ProfileZbus {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, "/org/asuslinux/Profile", server).await;
|
Self::add_to_server_helper(self, "/org/asuslinux/Profile", server).await;
|
||||||
}
|
}
|
||||||
@@ -221,36 +202,32 @@ impl crate::ZbusAdd for ProfileZbus {
|
|||||||
impl CtrlTask for ProfileZbus {
|
impl CtrlTask for ProfileZbus {
|
||||||
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
let ctrl = self.inner.clone();
|
let ctrl = self.inner.clone();
|
||||||
let mut watch = Inotify::init()?;
|
let mut watch = self
|
||||||
watch.add_watch(PLATFORM_PROFILE, WatchMask::CLOSE_WRITE)?;
|
.inner
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.platform
|
||||||
|
.monitor_platform_profile()?;
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
loop {
|
watch
|
||||||
watch
|
.event_stream(&mut buffer)
|
||||||
.event_stream(&mut buffer)
|
.unwrap()
|
||||||
.unwrap()
|
.for_each(|_| async {
|
||||||
.for_each(|_| async {
|
let mut lock = ctrl.lock().await;
|
||||||
let mut active_profile = None;
|
let new_profile = Profile::get_active_profile().unwrap();
|
||||||
|
if new_profile != lock.config.active_profile {
|
||||||
|
lock.config.active_profile = new_profile;
|
||||||
|
lock.write_profile_curve_to_platform().unwrap();
|
||||||
|
lock.save_config();
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(ref mut lock) = ctrl.try_lock() {
|
Self::notify_profile(&signal_ctxt.clone(), lock.config.active_profile)
|
||||||
let new_profile = Profile::get_active_profile().unwrap();
|
.await
|
||||||
if new_profile != lock.config.active_profile {
|
.ok();
|
||||||
lock.config.active_profile = new_profile;
|
})
|
||||||
lock.write_profile_curve_to_platform().unwrap();
|
.await;
|
||||||
lock.save_config();
|
|
||||||
active_profile = Some(lock.config.active_profile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(active_profile) = active_profile {
|
|
||||||
Self::notify_profile(&signal_ctxt.clone(), active_profile)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ impl SupportedFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusAdd for SupportedFunctions {
|
impl crate::ZbusRun for SupportedFunctions {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, "/org/asuslinux/Supported", server).await;
|
Self::add_to_server_helper(self, "/org/asuslinux/Supported", server).await;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use ::zbus::export::futures_util::lock::Mutex;
|
||||||
use ::zbus::{Connection, SignalContext};
|
use ::zbus::{Connection, SignalContext};
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
@@ -26,7 +27,7 @@ use daemon::{
|
|||||||
ctrl_profiles::{controller::CtrlPlatformProfile, zbus::ProfileZbus},
|
ctrl_profiles::{controller::CtrlPlatformProfile, zbus::ProfileZbus},
|
||||||
laptops::LaptopLedData,
|
laptops::LaptopLedData,
|
||||||
};
|
};
|
||||||
use daemon::{CtrlTask, Reloadable, ZbusAdd};
|
use daemon::{CtrlTask, Reloadable, ZbusRun};
|
||||||
use rog_dbus::DBUS_NAME;
|
use rog_dbus::DBUS_NAME;
|
||||||
use rog_profiles::Profile;
|
use rog_profiles::Profile;
|
||||||
|
|
||||||
@@ -84,6 +85,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(mut ctrl) => {
|
Ok(mut ctrl) => {
|
||||||
// Do a reload of any settings
|
// Do a reload of any settings
|
||||||
ctrl.reload()
|
ctrl.reload()
|
||||||
|
.await
|
||||||
.unwrap_or_else(|err| warn!("CtrlRogBios: {}", err));
|
.unwrap_or_else(|err| warn!("CtrlRogBios: {}", err));
|
||||||
// Then register to dbus server
|
// Then register to dbus server
|
||||||
ctrl.add_to_server(&mut connection).await;
|
ctrl.add_to_server(&mut connection).await;
|
||||||
@@ -101,6 +103,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(mut ctrl) => {
|
Ok(mut ctrl) => {
|
||||||
// Do a reload of any settings
|
// Do a reload of any settings
|
||||||
ctrl.reload()
|
ctrl.reload()
|
||||||
|
.await
|
||||||
.unwrap_or_else(|err| warn!("CtrlPower: {}", err));
|
.unwrap_or_else(|err| warn!("CtrlPower: {}", err));
|
||||||
// Then register to dbus server
|
// Then register to dbus server
|
||||||
ctrl.add_to_server(&mut connection).await;
|
ctrl.add_to_server(&mut connection).await;
|
||||||
@@ -119,14 +122,12 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
match CtrlPlatformProfile::new(profile_config) {
|
match CtrlPlatformProfile::new(profile_config) {
|
||||||
Ok(mut ctrl) => {
|
Ok(mut ctrl) => {
|
||||||
ctrl.reload()
|
ctrl.reload()
|
||||||
|
.await
|
||||||
.unwrap_or_else(|err| warn!("Profile control: {}", err));
|
.unwrap_or_else(|err| warn!("Profile control: {}", err));
|
||||||
|
|
||||||
let tmp = Arc::new(Mutex::new(ctrl));
|
|
||||||
//let task = CtrlProfileTask::new(tmp.clone());
|
|
||||||
//task.create_tasks(executor).await.ok();
|
|
||||||
let sig = SignalContext::new(&connection, "/org/asuslinux/Profile")?;
|
let sig = SignalContext::new(&connection, "/org/asuslinux/Profile")?;
|
||||||
|
|
||||||
let task = ProfileZbus::new(tmp.clone());
|
let task = ProfileZbus::new(Arc::new(Mutex::new(ctrl)));
|
||||||
task.create_tasks(sig).await.ok();
|
task.create_tasks(sig).await.ok();
|
||||||
task.add_to_server(&mut connection).await;
|
task.add_to_server(&mut connection).await;
|
||||||
}
|
}
|
||||||
@@ -145,6 +146,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
let mut reload = CtrlAnimeReloader(inner.clone());
|
let mut reload = CtrlAnimeReloader(inner.clone());
|
||||||
reload
|
reload
|
||||||
.reload()
|
.reload()
|
||||||
|
.await
|
||||||
.unwrap_or_else(|err| warn!("AniMe: {}", err));
|
.unwrap_or_else(|err| warn!("AniMe: {}", err));
|
||||||
|
|
||||||
let zbus = CtrlAnimeZbus(inner.clone());
|
let zbus = CtrlAnimeZbus(inner.clone());
|
||||||
@@ -168,6 +170,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
let mut reload = CtrlKbdLedReloader(inner.clone());
|
let mut reload = CtrlKbdLedReloader(inner.clone());
|
||||||
reload
|
reload
|
||||||
.reload()
|
.reload()
|
||||||
|
.await
|
||||||
.unwrap_or_else(|err| warn!("Keyboard LED control: {}", err));
|
.unwrap_or_else(|err| warn!("Keyboard LED control: {}", err));
|
||||||
|
|
||||||
CtrlKbdLedZbus::new(inner.clone())
|
CtrlKbdLedZbus::new(inner.clone())
|
||||||
|
|||||||
@@ -19,24 +19,22 @@ pub mod ctrl_supported;
|
|||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use logind_zbus::manager::ManagerProxy;
|
use logind_zbus::manager::ManagerProxy;
|
||||||
use tokio::time;
|
|
||||||
use zbus::{export::futures_util::StreamExt, Connection, SignalContext};
|
use zbus::{export::futures_util::StreamExt, Connection, SignalContext};
|
||||||
use zvariant::ObjectPath;
|
use zvariant::ObjectPath;
|
||||||
|
|
||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
pub trait Reloadable {
|
pub trait Reloadable {
|
||||||
fn reload(&mut self) -> Result<(), RogError>;
|
async fn reload(&mut self) -> Result<(), RogError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait ZbusAdd {
|
pub trait ZbusRun {
|
||||||
async fn add_to_server(self, server: &mut Connection);
|
async fn add_to_server(self, server: &mut Connection);
|
||||||
|
|
||||||
async fn add_to_server_helper(
|
async fn add_to_server_helper(
|
||||||
@@ -110,14 +108,16 @@ pub trait CtrlTask {
|
|||||||
/// No blocking loops are allowed, or they must be run on a separate thread.
|
/// No blocking loops are allowed, or they must be run on a separate thread.
|
||||||
async fn create_tasks(&self, signal: SignalContext<'static>) -> Result<(), RogError>;
|
async fn create_tasks(&self, signal: SignalContext<'static>) -> Result<(), RogError>;
|
||||||
|
|
||||||
/// Create a timed repeating task
|
// /// Create a timed repeating task
|
||||||
async fn repeating_task(&self, millis: u64, mut task: impl FnMut() + Send + 'static) {
|
// async fn repeating_task(&self, millis: u64, mut task: impl FnMut() + Send + 'static) {
|
||||||
let mut timer = time::interval(Duration::from_millis(millis));
|
// use std::time::Duration;
|
||||||
tokio::spawn(async move {
|
// use tokio::time;
|
||||||
timer.tick().await;
|
// let mut timer = time::interval(Duration::from_millis(millis));
|
||||||
task();
|
// tokio::spawn(async move {
|
||||||
});
|
// timer.tick().await;
|
||||||
}
|
// task();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
/// Free helper method to create tasks to run on: sleep, wake, shutdown, boot
|
/// Free helper method to create tasks to run on: sleep, wake, shutdown, boot
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -19,80 +19,103 @@ Then for each trait that is required a new struct is required that can have the
|
|||||||
Main controller:
|
Main controller:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
/// For a very simple controller that doesn't need exclusive access you can clone across threads
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CtrlAnime {
|
||||||
|
<things the controller requires>
|
||||||
|
config: Arc<Mutex<Config>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::CtrlTask for CtrlAnime {}
|
||||||
|
impl crate::ZbusAdd for CtrlAnime {}
|
||||||
|
|
||||||
|
impl CtrlAnime {}
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
/// Otherwise, you will need to share the controller via mutex
|
||||||
pub struct CtrlAnime {
|
pub struct CtrlAnime {
|
||||||
<things the controller requires>
|
<things the controller requires>
|
||||||
}
|
}
|
||||||
|
// Like this
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CtrlAnimeTask(Arc<Mutex<CtrlAnime>>);
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CtrlAnimeZbus(Arc<Mutex<CtrlAnime>>);
|
||||||
|
|
||||||
impl CtrlAnime {
|
impl CtrlAnime {}
|
||||||
<functions the controller exposes>
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The task trait. There are three ways to implement this:
|
The task trait. There are three ways to implement this:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
// Mutex should always be async mutex
|
||||||
pub struct CtrlAnimeTask(Arc<Mutex<CtrlAnime>>);
|
pub struct CtrlAnimeTask(Arc<Mutex<CtrlAnime>>);
|
||||||
|
|
||||||
impl crate::CtrlTask for CtrlAnimeTask {
|
impl crate::CtrlTask for CtrlAnimeTask {
|
||||||
// This will run once only
|
// This will run once only
|
||||||
fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
|
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
if let Ok(lock) = self.inner.try_lock() {
|
let lock self.inner.lock().await;
|
||||||
<some action>
|
<some action>
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will run until the notification stream closes (which in most cases will be never)
|
// This will run until the notification stream closes (which in most cases will be never)
|
||||||
fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
|
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
let connection = Connection::system().await.unwrap();
|
let inner1 = self.inner.clone();
|
||||||
let manager = ManagerProxy::new(&connection).await.unwrap();
|
let inner2 = self.inner.clone();
|
||||||
|
let inner3 = self.inner.clone();
|
||||||
let inner = self.inner.clone();
|
let inner4 = self.inner.clone();
|
||||||
executor
|
// This is a free method on CtrlTask trait
|
||||||
.spawn(async move {
|
self.create_sys_event_tasks(
|
||||||
// A notification from logind dbus interface
|
// Loop is required to try an attempt to get the mutex *without* blocking
|
||||||
if let Ok(p) = manager.receive_prepare_for_sleep().await {
|
// other threads - it is possible to end up with deadlocks otherwise.
|
||||||
// A stream that will continuously output events
|
move || loop {
|
||||||
p.for_each(|_| {
|
if let Some(lock) = inner1.try_lock() {
|
||||||
if let Ok(lock) = inner.try_lock() {
|
run_action(true, lock, inner1.clone());
|
||||||
// Do stuff here
|
break;
|
||||||
}
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
.detach();
|
move || loop {
|
||||||
}
|
if let Some(lock) = inner2.try_lock() {
|
||||||
|
run_action(false, lock, inner2.clone());
|
||||||
// This task will run every 500 milliseconds
|
break;
|
||||||
fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
|
}
|
||||||
let inner = self.inner.clone();
|
},
|
||||||
// This is a provided free trait to help set up a repeating task
|
move || loop {
|
||||||
self.repeating_task(500, executor, move || {
|
if let Some(lock) = inner3.try_lock() {
|
||||||
if let Ok(lock) = inner.try_lock() {
|
run_action(true, lock, inner3.clone());
|
||||||
// Do stuff here
|
break;
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
move || loop {
|
||||||
|
if let Some(lock) = inner4.try_lock() {
|
||||||
|
run_action(false, lock, inner4.clone());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The reloader trait
|
The reloader trait
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
pub struct CtrlAnimeReloader(Arc<Mutex<CtrlAnime>>);
|
pub struct CtrlAnimeReloader(Arc<Mutex<CtrlAnime>>);
|
||||||
|
|
||||||
impl crate::Reloadable for CtrlAnimeReloader {
|
impl crate::Reloadable for CtrlAnimeReloader {
|
||||||
fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if let Ok(lock) = self.inner.try_lock() {
|
let lock = self.inner.lock().await;
|
||||||
<some action>
|
<some action>
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The Zbus requirements:
|
The Zbus requirements:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
pub struct CtrlAnimeZbus(Arc<Mutex<CtrlAnime>>);
|
pub struct CtrlAnimeZbus(Arc<Mutex<CtrlAnime>>);
|
||||||
|
|
||||||
@@ -106,10 +129,9 @@ impl crate::ZbusAdd for CtrlAnimeZbus {
|
|||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||||
impl CtrlAnimeZbus {
|
impl CtrlAnimeZbus {
|
||||||
fn <zbus method>() {
|
async fn <zbus method>() {
|
||||||
if let Ok(lock) = self.inner.try_lock() {
|
let lock = self.inner.lock().await;
|
||||||
<some action>
|
<some action>
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ impl AsusPlatform {
|
|||||||
attr_bool!("egpu_enable", path);
|
attr_bool!("egpu_enable", path);
|
||||||
attr_bool!("panel_od", path);
|
attr_bool!("panel_od", path);
|
||||||
attr_u8!("gpu_mux_mode", path);
|
attr_u8!("gpu_mux_mode", path);
|
||||||
|
// This is technically the same as `platform_profile` since both are tied in-kernel
|
||||||
attr_u8!("throttle_thermal_policy", path);
|
attr_u8!("throttle_thermal_policy", path);
|
||||||
|
|
||||||
// The acpi platform_profile support
|
// The acpi platform_profile support
|
||||||
attr_u8!("platform_profile", pp_path);
|
attr_u8!("platform_profile", pp_path);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user