Added tasks for reload keyboard bright, and for charge control

This commit is contained in:
Luke D. Jones
2022-06-07 11:49:12 +12:00
parent 6a4594466b
commit 561f61116c
13 changed files with 250 additions and 160 deletions

View File

@@ -17,6 +17,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support for G513IC LED modes (Author: dada513)
- Support for G513QM LED modes (Author: Martin Piffault)
- Add side-LED toggle support (Author: Martin Piffault)
- Support reloading keyboard brightness and mode on wake (from sleep/hiber)
- Support reloading charge-level on wake (from sleep/hiber)
- Support running AniMe animation blocks on wake/sleep and boot/shutdown events
# [4.0.7] - 2021-12-19
### Changed

View File

@@ -300,18 +300,18 @@ impl CtrlAnime {
}
pub struct CtrlAnimeTask {
_inner: Arc<Mutex<CtrlAnime>>,
inner: Arc<Mutex<CtrlAnime>>,
}
impl CtrlAnimeTask {
pub async fn new(inner: Arc<Mutex<CtrlAnime>>) -> CtrlAnimeTask {
Self { _inner: inner }
Self { inner }
}
}
#[async_trait]
impl crate::CtrlTask for CtrlAnimeTask {
async fn create_task(&self, executor: &mut Executor) -> Result<(), RogError> {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system()
.await
.expect("CtrlAnimeTask could not create dbus connection");
@@ -320,17 +320,37 @@ impl crate::CtrlTask for CtrlAnimeTask {
.await
.expect("CtrlAnimeTask could not create ManagerProxy");
let x = self._inner.clone();
let inner = self.inner.clone();
executor
.spawn(async move {
if let Ok(p) = manager.receive_prepare_for_sleep().await {
p.for_each(|_| {
if let Ok(_lock) = x.clone().try_lock() {
info!("AniMe received sleep event (this feature is not yet complete)");
// lock.config.system
}
})
.await;
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
if args.start {
if let Ok(lock) = inner.clone().try_lock() {
info!("CtrlAnimeTask running sleep animation");
lock.thread_exit.store(true, Ordering::Relaxed);
CtrlAnime::run_thread(
inner.clone(),
lock.cache.shutdown.clone(),
true,
);
}
} else {
if let Ok(lock) = inner.clone().try_lock() {
info!("CtrlAnimeTask running wake animation");
lock.thread_exit.store(true, Ordering::Relaxed);
CtrlAnime::run_thread(
inner.clone(),
lock.cache.wake.clone(),
true,
);
}
}
}
})
.await;
}
})
.detach();
@@ -339,19 +359,38 @@ impl crate::CtrlTask for CtrlAnimeTask {
.await
.expect("CtrlAnimeTask could not create ManagerProxy");
let x = self._inner.clone();
let inner = self.inner.clone();
executor
.spawn(async move {
if let Ok(p) = manager.receive_prepare_for_shutdown().await {
p.for_each(|_| {
if let Ok(_lock) = x.clone().try_lock() {
info!(
"AniMe received shutdown event (this feature is not yet complete)"
);
// lock.config.system
}
})
.await;
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
if args.start {
if let Ok(lock) = inner.clone().try_lock() {
info!("CtrlAnimeTask running sleep animation");
lock.thread_exit.store(true, Ordering::Relaxed);
CtrlAnime::run_thread(
inner.clone(),
lock.cache.shutdown.clone(),
true,
);
}
} else {
// If waking up - intention is to catch hibernation event
if let Ok(lock) = inner.clone().try_lock() {
info!("CtrlAnimeTask running wake animation");
lock.thread_exit.store(true, Ordering::Relaxed);
CtrlAnime::run_thread(
inner.clone(),
lock.cache.wake.clone(),
true,
);
}
}
}
})
.await;
}
})
.detach();

View File

@@ -1,13 +1,11 @@
use std::sync::{Arc, Mutex};
use async_trait::async_trait;
use log::warn;
use rog_anime::{
usb::{pkt_for_apply, pkt_for_set_boot, pkt_for_set_on},
AnimeDataBuffer, AnimePowerStates,
};
use zbus::{dbus_interface, Connection, SignalContext};
use zvariant::ObjectPath;
use std::sync::atomic::Ordering;
@@ -19,18 +17,7 @@ pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
#[async_trait]
impl crate::ZbusAdd for CtrlAnimeZbus {
async fn add_to_server(self, server: &mut Connection) {
server
.object_server()
.at(
&ObjectPath::from_str_unchecked("/org/asuslinux/Anime"),
self,
)
.await
.map_err(|err| {
warn!("CtrlAnimeDisplay: add_to_server {}", err);
err
})
.ok();
Self::add_to_server_helper(self, "/org/asuslinux/Anime", server).await;
}
}

View File

@@ -7,7 +7,7 @@ use crate::{
CtrlTask,
};
use async_trait::async_trait;
use log::{info, warn};
use log::{error, info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_aura::{
usb::{
@@ -92,7 +92,7 @@ impl CtrlKbdLedTask {
#[async_trait]
impl CtrlTask for CtrlKbdLedTask {
async fn create_task(&self, executor: &mut Executor) -> Result<(), RogError> {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system()
.await
.expect("CtrlKbdLedTask could not create dbus connection");
@@ -104,14 +104,32 @@ impl CtrlTask for CtrlKbdLedTask {
let inner = self.inner.clone();
executor
.spawn(async move {
if let Ok(p) = manager.receive_prepare_for_sleep().await {
p.for_each(|_| {
if let Ok(_lock) = inner.clone().try_lock() {
info!("CtrlKbdLedTask received sleep event (this feature is not yet complete)");
// lock.config.system
}
})
.await;
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
// If waking up
if !args.start {
info!("CtrlKbdLedTask reloading brightness and modes");
if let Ok(lock) = inner.clone().try_lock() {
lock.set_brightness(lock.config.brightness)
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
.ok();
lock.set_side_leds_states(lock.config.side_leds_enabled)
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
.ok();
if let Some(mode) =
lock.config.builtins.get(&lock.config.current_mode)
{
lock.write_mode(mode)
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
.ok();
}
}
}
}
})
.await;
}
})
.detach();
@@ -138,11 +156,11 @@ impl crate::Reloadable for CtrlKbdLedReloader {
}
ctrl.set_states_enabled(ctrl.config.awake_enabled, ctrl.config.sleep_anim_enabled)
.map_err(|err| warn!("{}", err))
.map_err(|err| warn!("{err}"))
.ok();
ctrl.set_side_leds_states(ctrl.config.side_leds_enabled)
.map_err(|err| warn!("{}", err))
.map_err(|err| warn!("{err}"))
.ok();
}
Ok(())
@@ -166,9 +184,10 @@ impl CtrlKbdLed {
match Self::find_led_node(prod) {
Ok(node) => {
led_node = Some(node);
info!("Found keyboard controller 0x{prod}");
break;
}
Err(err) => warn!("led_node: {}", err),
Err(err) => info!("Looked for keyboard controller 0x{prod}: {err}"),
}
}

View File

@@ -1,22 +1,14 @@
use async_trait::async_trait;
use log::{error, warn};
use log::warn;
use rog_aura::{AuraEffect, LedBrightness, LedPowerStates};
use zbus::{dbus_interface, Connection, SignalContext};
use zvariant::ObjectPath;
use super::controller::CtrlKbdLedZbus;
#[async_trait]
impl crate::ZbusAdd for CtrlKbdLedZbus {
async fn add_to_server(self, server: &mut Connection) {
server
.object_server()
.at(&ObjectPath::from_str_unchecked("/org/asuslinux/Led"), self)
.await
.map_err(|err| {
error!("DbusKbdLed: add_to_server {}", err);
})
.ok();
Self::add_to_server_helper(self, "/org/asuslinux/Led", server).await;
}
}

View File

@@ -1,7 +1,11 @@
use crate::CtrlTask;
use crate::{config::Config, error::RogError, GetSupported};
use async_trait::async_trait;
use log::{info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_supported::ChargeSupportedFunctions;
use smol::stream::StreamExt;
use smol::Executor;
use std::fs::OpenOptions;
use std::io::Write;
use std::path::Path;
@@ -10,7 +14,6 @@ use std::sync::Mutex;
use zbus::dbus_interface;
use zbus::Connection;
use zbus::SignalContext;
use zvariant::ObjectPath;
static BAT_CHARGE_PATH0: &str = "/sys/class/power_supply/BAT0/charge_control_end_threshold";
static BAT_CHARGE_PATH1: &str = "/sys/class/power_supply/BAT1/charge_control_end_threshold";
@@ -41,7 +44,7 @@ impl CtrlCharge {
return Err(RogError::ChargeLimit(limit))?;
}
if let Ok(mut config) = self.config.try_lock() {
self.set(limit, &mut config)
Self::set(limit, &mut config)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
@@ -66,18 +69,7 @@ impl CtrlCharge {
#[async_trait]
impl crate::ZbusAdd for CtrlCharge {
async fn add_to_server(self, server: &mut Connection) {
server
.object_server()
.at(
&ObjectPath::from_str_unchecked("/org/asuslinux/Charge"),
self,
)
.await
.map_err(|err| {
warn!("CtrlCharge: add_to_server {}", err);
err
})
.ok();
Self::add_to_server_helper(self, "/org/asuslinux/Charge", server).await;
}
}
@@ -85,7 +77,7 @@ impl crate::Reloadable for CtrlCharge {
fn reload(&mut self) -> Result<(), RogError> {
if let Ok(mut config) = self.config.try_lock() {
config.read();
self.set(config.bat_charge_limit, &mut config)?;
Self::set(config.bat_charge_limit, &mut config)?;
}
Ok(())
}
@@ -112,7 +104,7 @@ impl CtrlCharge {
}
}
pub(super) fn set(&self, limit: u8, config: &mut Config) -> Result<(), RogError> {
pub(super) fn set(limit: u8, config: &mut Config) -> Result<(), RogError> {
if !(20..=100).contains(&limit) {
return Err(RogError::ChargeLimit(limit));
}
@@ -134,3 +126,73 @@ impl CtrlCharge {
Ok(())
}
}
#[async_trait]
impl CtrlTask for CtrlCharge {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system()
.await
.expect("CtrlCharge could not create dbus connection");
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlCharge could not create ManagerProxy");
let config1 = self.config.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
// If waking up
if !args.start {
info!("CtrlCharge reloading charge limit");
if let Ok(mut lock) = config1.try_lock() {
Self::set(lock.bat_charge_limit, &mut lock)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
}
}
}
})
.await;
}
})
.detach();
let manager = ManagerProxy::new(&connection)
.await
.expect("CtrlCharge could not create ManagerProxy");
let config = self.config.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
notif
.for_each(|event| {
if let Ok(args) = event.args() {
// If waking up - intention is to catch hibernation event
if !args.start {
info!("CtrlCharge reloading charge limit");
if let Ok(mut lock) = config.clone().try_lock() {
Self::set(lock.bat_charge_limit, &mut lock)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
}
}
}
})
.await;
}
})
.detach();
Ok(())
}
}

View File

@@ -139,7 +139,7 @@ impl CtrlProfileTask {
#[async_trait]
impl CtrlTask for CtrlProfileTask {
async fn create_task(&self, executor: &mut Executor) -> Result<(), RogError> {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let ctrl = self.ctrl.clone();
self.repeating_task(666, executor, move || {
if let Ok(ref mut lock) = ctrl.try_lock() {

View File

@@ -3,17 +3,12 @@ use log::warn;
use rog_profiles::fan_curve_set::CurveData;
use rog_profiles::fan_curve_set::FanCurveSet;
use rog_profiles::Profile;
use smol::Executor;
use zbus::Connection;
use zbus::SignalContext;
use std::sync::Arc;
use std::sync::Mutex;
use zbus::{dbus_interface, fdo::Error};
use zvariant::ObjectPath;
use crate::error::RogError;
use crate::CtrlTask;
use super::controller::CtrlPlatformProfile;
@@ -187,36 +182,6 @@ impl ProfileZbus {
#[async_trait]
impl crate::ZbusAdd for ProfileZbus {
async fn add_to_server(self, server: &mut Connection) {
server
.object_server()
.at(
&ObjectPath::from_str_unchecked("/org/asuslinux/Profile"),
self,
)
.await
.map_err(|err| {
warn!("DbusFanAndCpu: add_to_server {}", err);
err
})
.ok();
}
}
#[async_trait]
impl CtrlTask for ProfileZbus {
async fn create_task(&self, executor: &mut Executor) -> Result<(), RogError> {
let inner = self.inner.clone();
self.repeating_task(500, executor, move || {
if let Ok(ref mut lock) = inner.try_lock() {
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();
}
}
})
.await;
Ok(())
Self::add_to_server_helper(self, "/org/asuslinux/Profile", server).await;
}
}

View File

@@ -11,7 +11,6 @@ use std::sync::Arc;
use std::sync::Mutex;
use zbus::Connection;
use zbus::{dbus_interface, SignalContext};
use zvariant::ObjectPath;
const INITRAMFS_PATH: &str = "/usr/sbin/update-initramfs";
const DRACUT_PATH: &str = "/usr/bin/dracut";
@@ -100,18 +99,7 @@ impl CtrlRogBios {
#[async_trait]
impl crate::ZbusAdd for CtrlRogBios {
async fn add_to_server(self, server: &mut Connection) {
server
.object_server()
.at(
&ObjectPath::from_str_unchecked("/org/asuslinux/RogBios"),
self,
)
.await
.map_err(|err| {
warn!("CtrlRogBios: add_to_server {}", err);
err
})
.ok();
Self::add_to_server_helper(self, "/org/asuslinux/RogBios", server).await;
}
}

View File

@@ -1,9 +1,7 @@
use async_trait::async_trait;
use log::warn;
use serde_derive::{Deserialize, Serialize};
use zbus::dbus_interface;
use zbus::Connection;
use zvariant::ObjectPath;
use zvariant::Type;
use crate::{
@@ -35,18 +33,7 @@ impl SupportedFunctions {
#[async_trait]
impl crate::ZbusAdd for SupportedFunctions {
async fn add_to_server(self, server: &mut Connection) {
server
.object_server()
.at(
&ObjectPath::from_str_unchecked("/org/asuslinux/Supported"),
self,
)
.await
.map_err(|err| {
warn!("SupportedFunctions: add_to_server {}", err);
err
})
.ok();
Self::add_to_server_helper(self, "/org/asuslinux/Supported", server).await;
}
}

View File

@@ -94,13 +94,16 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
}
}
match CtrlCharge::new(config) {
match CtrlCharge::new(config.clone()) {
Ok(mut ctrl) => {
// Do a reload of any settings
ctrl.reload()
.unwrap_or_else(|err| warn!("Battery charge limit: {}", err));
// Then register to dbus server
ctrl.add_to_server(&mut connection).await;
let task = CtrlCharge::new(config)?;
task.create_tasks(executor).await.ok();
}
Err(err) => {
error!("charge_control: {}", err);
@@ -116,11 +119,9 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
let tmp = Arc::new(Mutex::new(ctrl));
let task = CtrlProfileTask::new(tmp.clone());
task.create_task(executor).await.ok();
task.create_tasks(executor).await.ok();
let task = ProfileZbus::new(tmp.clone());
task.create_task(executor).await.ok();
task.add_to_server(&mut connection).await;
}
Err(err) => {
@@ -144,7 +145,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
zbus.add_to_server(&mut connection).await;
let task = CtrlAnimeTask::new(inner).await;
task.create_task(executor).await.ok();
task.create_tasks(executor).await.ok();
}
Err(err) => {
error!("AniMe control: {}", err);
@@ -167,7 +168,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
.await;
let task = CtrlKbdLedTask::new(inner);
task.create_task(executor).await.ok();
task.create_tasks(executor).await.ok();
}
Err(err) => {
error!("Keyboard control: {}", err);
@@ -176,7 +177,6 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
// Request dbus name after finishing initalizing all functions
connection.request_name(DBUS_NAME).await?;
dbg!();
loop {
smol::block_on(executor.tick());
}

View File

@@ -34,8 +34,10 @@ use std::time::Duration;
use crate::error::RogError;
use async_trait::async_trait;
use config::Config;
use log::warn;
use smol::{stream::StreamExt, Executor, Timer};
use zbus::Connection;
use zvariant::ObjectPath;
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -46,12 +48,30 @@ pub trait Reloadable {
#[async_trait]
pub trait ZbusAdd {
async fn add_to_server(self, server: &mut Connection);
async fn add_to_server_helper(
iface: impl zbus::Interface,
path: &str,
server: &mut Connection,
) {
server
.object_server()
.at(&ObjectPath::from_str_unchecked(path), iface)
.await
.map_err(|err| {
warn!("{}: add_to_server {}", path, err);
err
})
.ok();
}
}
/// Set up a task to run on the async executor
#[async_trait]
pub trait CtrlTask {
async fn create_task(&self, executor: &mut Executor) -> Result<(), RogError>;
/// Implement to set up various tasks that may be required, using the `Executor`.
/// No blocking loops are allowed, or they must be run on a separate thread.
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError>;
/// Create a timed repeating task
async fn repeating_task(

View File

@@ -28,18 +28,53 @@ impl CtrlAnime {
}
```
The task trait:
The task trait. There are three ways to implement this:
```rust
pub struct CtrlAnimeTask(Arc<Mutex<CtrlAnime>>);
impl crate::CtrlTask for CtrlAnimeTask {
fn create_task(&self, executor: &mut Executor) -> Result<(), RogError> {
// This will run once only
fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
if let Ok(lock) = self.inner.try_lock() {
<some action>
}
Ok(())
}
// This will run until the notification stream closes (which in most cases will be never)
fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system().await.unwrap();
let manager = ManagerProxy::new(&connection).await.unwrap();
let inner = self.inner.clone();
executor
.spawn(async move {
// A notification from logind dbus interface
if let Ok(p) = manager.receive_prepare_for_sleep().await {
// A stream that will continuously output events
p.for_each(|_| {
if let Ok(lock) = inner.try_lock() {
// Do stuff here
}
})
.await;
}
})
.detach();
}
// This task will run every 500 milliseconds
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
self.repeating_task(500, executor, move || {
if let Ok(lock) = inner.try_lock() {
// Do stuff here
}
})
.await;
}
}
```
@@ -61,18 +96,11 @@ The Zbus requirements:
```rust
pub struct CtrlAnimeZbus(Arc<Mutex<CtrlAnime>>);
#[async_trait]
impl crate::ZbusAdd for CtrlAnimeZbus {
fn add_to_server(self, server: &mut zbus::ObjectServer) {
server
.at(
&ObjectPath::from_str_unchecked("/org/asuslinux/Anime"),
self,
)
.map_err(|err| {
warn!("CtrlAnimeDisplay: add_to_server {}", err);
err
})
.ok();
// This is a provided free helper trait with pre-set body. It will move self in-to.
Self::add_to_server_helper(self, "/org/asuslinux/Anime", server).await;
}
}