Anime: refactor power stuff

This commit is contained in:
Luke D. Jones
2023-11-15 14:22:45 +13:00
parent 71ee9e43ba
commit 8eb9b1d4eb
13 changed files with 280 additions and 160 deletions

View File

@@ -21,6 +21,7 @@ rog_platform = { path = "../rog-platform" }
rog_profiles = { path = "../rog-profiles" }
rog_dbus = { path = "../rog-dbus" }
dmi_id = { path = "../dmi-id" }
futures-lite = "*"
async-trait.workspace = true
tokio.workspace = true

View File

@@ -32,25 +32,33 @@ impl From<AnimeConfigV460> for AnimeConfig {
}
#[derive(Deserialize, Serialize, Debug)]
pub struct AnimeConfigV5 {
pub struct AnimeConfigV472 {
pub model_override: Option<AnimeType>,
pub system: Vec<ActionLoader>,
pub boot: Vec<ActionLoader>,
pub wake: Vec<ActionLoader>,
pub sleep: Vec<ActionLoader>,
pub shutdown: Vec<ActionLoader>,
pub brightness: f32,
pub awake_enabled: bool,
pub boot_anim_enabled: bool,
pub display_enabled: bool,
pub display_brightness: Brightness,
pub builtin_anims_enabled: bool,
pub builtin_anims: Animations,
}
impl From<AnimeConfigV5> for AnimeConfig {
fn from(c: AnimeConfigV5) -> AnimeConfig {
impl From<AnimeConfigV472> for AnimeConfig {
fn from(c: AnimeConfigV472) -> AnimeConfig {
AnimeConfig {
system: c.system,
boot: c.boot,
wake: c.wake,
sleep: c.sleep,
shutdown: c.shutdown,
model_override: c.model_override,
display_enabled: c.display_enabled,
display_brightness: c.display_brightness,
builtin_anims_enabled: c.builtin_anims_enabled,
builtin_anims: c.builtin_anims,
..Default::default()
}
}
@@ -113,10 +121,13 @@ pub struct AnimeConfig {
pub wake: Vec<ActionLoader>,
pub sleep: Vec<ActionLoader>,
pub shutdown: Vec<ActionLoader>,
pub brightness: f32,
// pub brightness: f32,
pub display_enabled: bool,
pub display_brightness: Brightness,
pub builtin_anims_enabled: bool,
pub off_when_unplugged: bool,
pub off_when_suspended: bool,
pub off_when_lid_closed: bool,
pub builtin_anims: Animations,
}
@@ -129,10 +140,13 @@ impl Default for AnimeConfig {
wake: Vec::new(),
sleep: Vec::new(),
shutdown: Vec::new(),
brightness: 1.0,
// brightness: 1.0,
display_enabled: true,
display_brightness: Brightness::Med,
builtin_anims_enabled: true,
off_when_unplugged: true,
off_when_suspended: true,
off_when_lid_closed: true,
builtin_anims: Animations::default(),
}
}
@@ -152,7 +166,7 @@ impl StdConfig for AnimeConfig {
}
}
impl StdConfigLoad2<AnimeConfigV460, AnimeConfigV5> for AnimeConfig {}
impl StdConfigLoad2<AnimeConfigV460, AnimeConfigV472> for AnimeConfig {}
impl AnimeConfig {
// fn clamp_config_brightness(mut config: &mut AnimeConfig) {
@@ -209,7 +223,6 @@ impl AnimeConfig {
brightness: 1.0,
time: AnimTime::Infinite,
}],
brightness: 1.0,
..Default::default()
}
}

View File

@@ -10,7 +10,10 @@ use std::thread::sleep;
use ::zbus::export::futures_util::lock::Mutex;
use log::{error, info, warn};
use rog_anime::error::AnimeError;
use rog_anime::usb::{get_anime_type, pkt_flush, pkt_set_enable_powersave_anim, pkts_for_init};
use rog_anime::usb::{
get_anime_type, pkt_flush, pkt_set_brightness, pkt_set_enable_display,
pkt_set_enable_powersave_anim, pkts_for_init, Brightness,
};
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType, AnimeType};
use rog_platform::hid_raw::HidRaw;
use rog_platform::supported::AnimeSupportedFunctions;
@@ -50,6 +53,13 @@ impl Node {
}
Ok(())
}
pub fn set_builtins_enabled(&self, enabled: bool, bright: Brightness) -> Result<(), RogError> {
self.write_bytes(&pkt_set_enable_powersave_anim(enabled))?;
self.write_bytes(&pkt_set_enable_display(enabled))?;
self.write_bytes(&pkt_set_brightness(bright))?;
self.write_bytes(&pkt_set_enable_powersave_anim(enabled))
}
}
pub struct CtrlAnime {
@@ -234,6 +244,14 @@ impl CtrlAnime {
})
.ok();
}
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(
lock.config.builtin_anims_enabled,
))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
})
.ok();
}
// Loop ended, set the atmonics
thread_running.store(false, Ordering::SeqCst);
@@ -247,7 +265,7 @@ impl CtrlAnime {
/// global brightness set in config.
fn write_data_buffer(&self, mut buffer: AnimeDataBuffer) -> Result<(), RogError> {
for led in buffer.data_mut().iter_mut() {
let mut bright = *led as f32 * self.config.brightness;
let mut bright = *led as f32;
if bright > 254.0 {
bright = 254.0;
}

View File

@@ -39,25 +39,12 @@ impl CtrlAnimeZbus {
let lock = self.0.lock().await;
lock.thread_exit.store(true, Ordering::SeqCst);
lock.write_data_buffer(input).map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
warn!("ctrl_anime::run_animation:callback {}", err);
err
})?;
Ok(())
}
/// Set the global AniMe brightness
async fn set_image_brightness(&self, bright: f32) {
let mut lock = self.0.lock().await;
let mut bright = bright;
if bright < 0.0 {
bright = 0.0;
} else if bright > 1.0 {
bright = 1.0;
}
lock.config.brightness = bright;
lock.config.write();
}
/// Set base brightness level
// TODO: enum for brightness
async fn set_brightness(
@@ -69,9 +56,17 @@ impl CtrlAnimeZbus {
lock.node
.write_bytes(&pkt_set_brightness(brightness))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
warn!("ctrl_anime::set_brightness {}", err);
})
.ok();
lock.node
.write_bytes(&pkt_set_enable_display(brightness != Brightness::Off))
.map_err(|err| {
warn!("ctrl_anime::set_brightness {}", err);
})
.ok();
lock.config.display_enabled = brightness != Brightness::Off;
lock.config.display_brightness = brightness;
lock.config.write();
@@ -82,6 +77,8 @@ impl CtrlAnimeZbus {
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
off_when_unplugged: lock.config.off_when_unplugged,
off_when_suspended: lock.config.off_when_suspended,
},
)
.await
@@ -97,11 +94,27 @@ impl CtrlAnimeZbus {
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(enabled))
.set_builtins_enabled(enabled, lock.config.display_brightness)
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
warn!("ctrl_anime::set_builtins_enabled {}", err);
})
.ok();
if !enabled {
let data = vec![255u8; lock.anime_type.data_length()];
if let Ok(tmp) = AnimeDataBuffer::from_vec(lock.anime_type, data).map_err(|err| {
warn!("ctrl_anime::set_builtins_enabled {}", err);
}) {
lock.node
.write_bytes(tmp.data())
.map_err(|err| {
warn!("ctrl_anime::set_builtins_enabled {}", err);
})
.ok();
}
}
lock.config.display_enabled = enabled;
lock.config.builtin_anims_enabled = enabled;
lock.config.write();
if enabled {
@@ -115,6 +128,8 @@ impl CtrlAnimeZbus {
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
off_when_unplugged: lock.config.off_when_unplugged,
off_when_suspended: lock.config.off_when_suspended,
},
)
.await
@@ -132,17 +147,18 @@ impl CtrlAnimeZbus {
) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(true))
.write_bytes(&pkt_set_builtin_animations(boot, awake, sleep, shutdown))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
warn!("ctrl_anime::run_animation:callback {}", err);
})
.ok();
lock.node
.write_bytes(&pkt_set_builtin_animations(boot, awake, sleep, shutdown))
.write_bytes(&pkt_set_enable_powersave_anim(true))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
warn!("ctrl_anime::run_animation:callback {}", err);
})
.ok();
lock.config.display_enabled = true;
lock.config.builtin_anims.boot = boot;
lock.config.builtin_anims.sleep = sleep;
lock.config.builtin_anims.awake = awake;
@@ -156,6 +172,8 @@ impl CtrlAnimeZbus {
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
off_when_unplugged: lock.config.off_when_unplugged,
off_when_suspended: lock.config.off_when_suspended,
},
)
.await
@@ -172,7 +190,7 @@ impl CtrlAnimeZbus {
lock.node
.write_bytes(&pkt_set_enable_display(enabled))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
warn!("ctrl_anime::run_animation:callback {}", err);
})
.ok();
lock.config.display_enabled = enabled;
@@ -185,6 +203,8 @@ impl CtrlAnimeZbus {
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
off_when_unplugged: lock.config.off_when_unplugged,
off_when_suspended: lock.config.off_when_suspended,
},
)
.await
@@ -210,6 +230,8 @@ impl CtrlAnimeZbus {
display_brightness: lock.config.display_brightness,
builtin_anims_enabled: lock.config.builtin_anims_enabled,
builtin_anims: lock.config.builtin_anims,
off_when_unplugged: lock.config.off_when_unplugged,
off_when_suspended: lock.config.off_when_suspended,
}
}
@@ -231,36 +253,80 @@ impl crate::CtrlTask for CtrlAnimeZbus {
let inner3 = self.0.clone();
let inner4 = self.0.clone();
self.create_sys_event_tasks(
move || {
move |sleeping| {
// on_sleep
let inner1 = inner1.clone();
let inner = inner1.clone();
async move {
let lock = inner1.lock().await;
CtrlAnime::run_thread(inner1.clone(), lock.cache.sleep.clone(), true).await;
let lock = inner.lock().await;
if lock.config.display_enabled {
if lock.config.off_when_suspended {
lock.node
.write_bytes(&pkt_set_enable_display(!sleeping))
.map_err(|err| {
warn!("create_sys_event_tasks::off_when_suspended {}", err);
})
.ok();
}
if !lock.config.builtin_anims_enabled {
if sleeping {
CtrlAnime::run_thread(
inner.clone(),
lock.cache.sleep.clone(),
true,
)
.await;
} else {
CtrlAnime::run_thread(inner.clone(), lock.cache.wake.clone(), true)
.await;
}
}
}
}
},
move || {
// on_wake
let inner2 = inner2.clone();
async move {
let lock = inner2.lock().await;
CtrlAnime::run_thread(inner2.clone(), lock.cache.wake.clone(), true).await;
}
},
move || {
move |shutting_down| {
// on_shutdown
let inner3 = inner3.clone();
let inner = inner2.clone();
async move {
let lock = inner3.lock().await;
CtrlAnime::run_thread(inner3.clone(), lock.cache.shutdown.clone(), true).await;
let lock = inner.lock().await;
if lock.config.display_enabled && !lock.config.builtin_anims_enabled {
if shutting_down {
CtrlAnime::run_thread(inner.clone(), lock.cache.shutdown.clone(), true)
.await;
} else {
CtrlAnime::run_thread(inner.clone(), lock.cache.boot.clone(), true)
.await;
}
}
}
},
move || {
// on_boot
let inner4 = inner4.clone();
move |lid_closed| {
let inner = inner3.clone();
// on lid change
async move {
let lock = inner4.lock().await;
CtrlAnime::run_thread(inner4.clone(), lock.cache.boot.clone(), true).await;
let lock = inner.lock().await;
if lock.config.off_when_lid_closed {
lock.node
.write_bytes(&pkt_set_enable_display(lid_closed))
.map_err(|err| {
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
})
.ok();
}
}
},
move |power_plugged| {
let inner = inner4.clone();
// on power change
async move {
let lock = inner.lock().await;
if lock.config.off_when_unplugged {
lock.node
.write_bytes(&pkt_set_enable_display(power_plugged))
.map_err(|err| {
warn!("create_sys_event_tasks::off_when_unplugged {}", err);
})
.ok();
}
}
},
)
@@ -275,25 +341,29 @@ impl crate::Reloadable for CtrlAnimeZbus {
async fn reload(&mut self) -> Result<(), RogError> {
if let Some(lock) = self.0.try_lock() {
let anim = &lock.config.builtin_anims;
lock.node
.write_bytes(&pkt_set_enable_display(lock.config.display_enabled))?;
lock.node.write_bytes(&pkt_set_enable_powersave_anim(
// Set builtins
if lock.config.builtin_anims_enabled {
lock.node.write_bytes(&pkt_set_builtin_animations(
anim.boot,
anim.awake,
anim.sleep,
anim.shutdown,
))?;
}
// Builtins enabled or na?
lock.node.set_builtins_enabled(
lock.config.builtin_anims_enabled,
))?;
lock.node.write_bytes(&pkt_set_builtin_animations(
anim.boot,
anim.awake,
anim.sleep,
anim.shutdown,
))?;
lock.config.display_brightness,
)?;
if lock.config.builtin_anims_enabled && !lock.cache.boot.is_empty() {
if !lock.config.builtin_anims_enabled && !lock.cache.boot.is_empty() {
lock.node
.write_bytes(&pkt_set_enable_powersave_anim(false))
.ok();
let action = lock.cache.boot.clone();
CtrlAnime::run_thread(self.0.clone(), action, true).await;
}
let action = lock.cache.boot.clone();
CtrlAnime::run_thread(self.0.clone(), action, true).await;
}
Ok(())
}

View File

@@ -241,39 +241,29 @@ impl CtrlTask for CtrlKbdLedZbus {
};
let inner1 = self.0.clone();
let inner2 = self.0.clone();
let inner3 = self.0.clone();
let inner4 = self.0.clone();
self.create_sys_event_tasks(
// Loop so that we do aquire the lock but also don't block other
// threads (prevents potential deadlocks)
move || {
move |sleeping| {
let inner1 = inner1.clone();
async move {
let lock = inner1.lock().await;
load_save(true, lock);
load_save(sleeping, lock);
}
},
move || {
let inner2 = inner2.clone();
async move {
let lock = inner2.lock().await;
load_save(false, lock);
}
},
move || {
move |_shutting_down| {
let inner3 = inner3.clone();
async move {
let lock = inner3.lock().await;
load_save(false, lock);
}
},
move || {
let inner4 = inner4.clone();
async move {
let lock = inner4.lock().await;
load_save(false, lock);
}
move |_lid_closed| {
// on lid change
async move {}
},
move |_power_plugged| {
// power change
async move {}
},
)
.await;

View File

@@ -360,13 +360,12 @@ impl CtrlTask for CtrlPlatform {
let platform1 = self.clone();
let platform2 = self.clone();
self.create_sys_event_tasks(
move || async { {} },
move || {
move |sleeping| {
let platform1 = platform1.clone();
async move {
info!("CtrlRogBios reloading panel_od");
let lock = platform1.config.lock().await;
if platform1.platform.has_panel_od() {
if !sleeping && platform1.platform.has_panel_od() {
platform1
.set_panel_overdrive(lock.panel_od)
.map_err(|err| {
@@ -377,13 +376,12 @@ impl CtrlTask for CtrlPlatform {
}
}
},
move || async { {} },
move || {
move |shutting_down| {
let platform2 = platform2.clone();
async move {
info!("CtrlRogBios reloading panel_od");
let lock = platform2.config.lock().await;
if platform2.platform.has_panel_od() {
if !shutting_down && platform2.platform.has_panel_od() {
platform2
.set_panel_overdrive(lock.panel_od)
.map_err(|err| {
@@ -394,6 +392,14 @@ impl CtrlTask for CtrlPlatform {
}
}
},
move |_lid_closed| {
// on lid change
async move {}
},
move |_power_plugged| {
// power change
async move {}
},
)
.await;

View File

@@ -163,50 +163,60 @@ impl CtrlTask for CtrlPower {
let power1 = self.clone();
let power2 = self.clone();
self.create_sys_event_tasks(
move || async {},
move || {
move |sleeping| {
let power = power1.clone();
let sysd = sysd1.clone();
async move {
info!("CtrlCharge reloading charge limit");
let lock = power.config.lock().await;
power
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
if !sleeping {
info!("CtrlCharge reloading charge limit");
let lock = power.config.lock().await;
power
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
if lock.disable_nvidia_powerd_on_battery {
if let Ok(value) = power.power.get_online() {
do_nvidia_powerd_action(&sysd, value == 1).await;
if lock.disable_nvidia_powerd_on_battery {
if let Ok(value) = power.power.get_online() {
do_nvidia_powerd_action(&sysd, value == 1).await;
}
}
}
}
},
move || async {},
move || {
move |shutting_down| {
let power = power2.clone();
let sysd = sysd2.clone();
async move {
info!("CtrlCharge reloading charge limit");
let lock = power.config.lock().await;
power
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
if !shutting_down {
info!("CtrlCharge reloading charge limit");
let lock = power.config.lock().await;
power
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
if lock.disable_nvidia_powerd_on_battery {
if let Ok(value) = power.power.get_online() {
do_nvidia_powerd_action(&sysd, value == 1).await;
if lock.disable_nvidia_powerd_on_battery {
if let Ok(value) = power.power.get_online() {
do_nvidia_powerd_action(&sysd, value == 1).await;
}
}
}
}
},
move |_lid_closed| {
// on lid change
async move {}
},
move |_power_plugged| {
// power change
async move {}
},
)
.await;

View File

@@ -18,14 +18,16 @@ pub mod ctrl_supported;
pub mod error;
use std::future::Future;
use std::time::Duration;
use async_trait::async_trait;
use dmi_id::DMIID;
use futures_lite::stream::StreamExt;
use log::{debug, info, warn};
use logind_zbus::manager::ManagerProxy;
use zbus::export::futures_util::StreamExt;
use tokio::time::sleep;
use zbus::zvariant::ObjectPath;
use zbus::{Connection, SignalContext};
use zbus::{CacheProperties, Connection, SignalContext};
use crate::error::RogError;
@@ -161,15 +163,15 @@ pub trait CtrlTask {
F4: Send + 'static,
>(
&self,
mut on_sleep: F1,
mut on_wake: F2,
mut on_shutdown: F3,
mut on_boot: F4,
mut on_prepare_for_sleep: F1,
mut on_prepare_for_shutdown: F2,
mut on_lid_change: F3,
mut on_external_power_change: F4,
) where
F1: FnMut() -> Fut1,
F2: FnMut() -> Fut2,
F3: FnMut() -> Fut3,
F4: FnMut() -> Fut4,
F1: FnMut(bool) -> Fut1,
F2: FnMut(bool) -> Fut2,
F3: FnMut(bool) -> Fut3,
F4: FnMut(bool) -> Fut4,
Fut1: Future<Output = ()> + Send,
Fut2: Future<Output = ()> + Send,
Fut3: Future<Output = ()> + Send,
@@ -179,7 +181,9 @@ pub trait CtrlTask {
.await
.expect("Controller could not create dbus connection");
let manager = ManagerProxy::new(&connection)
let manager = ManagerProxy::builder(&connection)
.cache_properties(CacheProperties::No)
.build()
.await
.expect("Controller could not create ManagerProxy");
@@ -187,35 +191,46 @@ pub trait CtrlTask {
if let Ok(mut notif) = manager.receive_prepare_for_sleep().await {
while let Some(event) = notif.next().await {
if let Ok(args) = event.args() {
if args.start {
debug!("Doing on_sleep()");
on_sleep().await;
} else if !args.start() {
debug!("Doing on_wake()");
on_wake().await;
}
debug!("Doing on_prepare_for_sleep({})", args.start);
on_prepare_for_sleep(args.start).await;
}
}
}
if let Ok(mut notif) = manager.receive_prepare_for_shutdown().await {
while let Some(event) = notif.next().await {
if let Ok(args) = event.args() {
debug!("Doing on_prepare_for_shutdown({})", args.start);
on_prepare_for_shutdown(args.start).await;
}
}
}
});
let manager = ManagerProxy::new(&connection)
let manager = ManagerProxy::builder(&connection)
.cache_properties(CacheProperties::No)
.build()
.await
.expect("Controller could not create ManagerProxy");
tokio::spawn(async move {
if let Ok(mut notif) = manager.receive_prepare_for_shutdown().await {
while let Some(event) = notif.next().await {
if let Ok(args) = event.args() {
if args.start {
debug!("Doing on_shutdown()");
on_shutdown().await;
} else if !args.start() {
debug!("Doing on_boot()");
on_boot().await;
}
let mut last_power = manager.on_external_power().await.unwrap_or_default();
let mut last_lid = manager.lid_closed().await.unwrap_or_default();
// need to loop on these as they don't emit signals
loop {
if let Ok(next) = manager.on_external_power().await {
if next != last_power {
last_power = next;
on_external_power_change(next).await;
}
}
if let Ok(next) = manager.lid_closed().await {
if next != last_lid {
last_lid = next;
on_lid_change(next).await;
}
}
sleep(Duration::from_secs(2)).await;
}
});
}