fix(power): freeze if a power daemon was not active or enabled

This commit is contained in:
Jorge Menjivar 2025-05-27 19:52:27 -07:00 committed by GitHub
parent 3152a168b2
commit 7df9700a94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 66 additions and 31 deletions

View file

@ -14,6 +14,7 @@ pub trait GetCurrentPowerProfile {
async fn get_current_power_profile(&self) -> PowerProfile;
}
#[derive(Debug, Clone)]
pub enum PowerBackendEnum {
S76(S76Backend),
PP(PPBackend),
@ -94,6 +95,7 @@ pub fn get_power_profiles() -> Vec<PowerProfile> {
]
}
#[derive(Debug, Clone)]
pub struct S76Backend {}
impl SetPowerProfile for S76Backend {
@ -157,6 +159,7 @@ async fn get_s76power_daemon_proxy<'a>() -> Result<s76powerdaemon::PowerDaemonPr
}
}
#[derive(Debug, Clone)]
pub struct PPBackend {}
impl SetPowerProfile for PPBackend {

View file

@ -58,6 +58,8 @@ pub struct Page {
suspend_labels: Vec<String>,
idle_config: Config,
idle_conf: CosmicIdleConfig,
backend: Option<backend::PowerBackendEnum>,
current_power_profile: Option<PowerProfile>,
}
impl Default for Page {
@ -84,6 +86,8 @@ impl Default for Page {
.collect(),
idle_config,
idle_conf,
backend: None,
current_power_profile: None,
}
}
}
@ -121,6 +125,19 @@ impl page::Page<crate::pages::Message> for Page {
let devices = ConnectedDevice::update_connected_devices().await;
Message::UpdateConnectedDevices(devices)
}),
cosmic::Task::future(async move {
if let Ok(backend) = tokio::time::timeout(
std::time::Duration::from_millis(1000),
backend::get_backend(),
)
.await
{
Message::BackendAvailabilityCheck(backend)
} else {
tracing::warn!("Power backend initialization timed out after 1000ms");
Message::BackendAvailabilityCheck(None)
}
}),
cosmic::Task::run(
async_fn_stream::fn_stream(|emitter| async move {
let span = tracing::span!(tracing::Level::INFO, "power::device_stream task");
@ -193,19 +210,22 @@ pub enum Message {
ScreenOffTimeChange(Option<Duration>),
SuspendOnAcTimeChange(Option<Duration>),
SuspendOnBatteryTimeChange(Option<Duration>),
BackendAvailabilityCheck(Option<backend::PowerBackendEnum>),
CurrentPowerProfileUpdate(PowerProfile),
Surface(surface::Action),
}
impl Page {
pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
let runtime = tokio::runtime::Runtime::new().unwrap();
let backend = runtime.block_on(backend::get_backend());
match message {
Message::PowerProfileChange(p) => {
if let Some(b) = backend {
runtime.block_on(b.set_power_profile(p));
if let Some(ref backend) = self.backend {
self.current_power_profile = Some(p);
let backend = backend.clone();
return cosmic::Task::future(async move {
backend.set_power_profile(p).await;
crate::app::Message::None
});
}
}
Message::UpdateBattery(battery) => self.battery = battery,
@ -245,6 +265,22 @@ impl Page {
Message::Surface(a) => {
return cosmic::task::message(crate::app::Message::Surface(a));
}
Message::BackendAvailabilityCheck(backend) => {
self.backend.clone_from(&backend);
// If backend is available, get the current power profile
if let Some(backend) = backend {
return cosmic::Task::future(async move {
let profile = backend.get_current_power_profile().await;
crate::app::Message::PageMessage(crate::pages::Message::Power(
Message::CurrentPowerProfileUpdate(profile),
))
});
}
}
Message::CurrentPowerProfileUpdate(profile) => {
self.current_power_profile = Some(profile);
}
};
Task::none()
}
@ -368,35 +404,31 @@ fn profiles() -> Section<crate::pages::Message> {
Section::default()
.title(fl!("power-mode"))
.descriptions(descriptions)
.view::<Page>(move |_binder, _page, section| {
.view::<Page>(move |_binder, page, section| {
let mut section = settings::section().title(&section.title);
let runtime = tokio::runtime::Runtime::new().unwrap();
let backend = runtime.block_on(backend::get_backend());
if let Some(b) = backend {
if page.backend.is_some() {
let profiles = backend::get_power_profiles();
let current_profile = runtime.block_on(b.get_current_power_profile());
section = profiles
.into_iter()
.map(|profile| {
settings::item_row(vec![
radio(
widget::column::with_capacity(2)
.push(text::body(profile.title()))
.push(text::caption(profile.description())),
profile,
Some(current_profile),
Message::PowerProfileChange,
)
.width(Length::Fill)
.into(),
])
})
.fold(section, settings::Section::add);
if let Some(current_profile) = page.current_power_profile {
section = profiles
.into_iter()
.map(|profile| {
settings::item_row(vec![
radio(
widget::column::with_capacity(2)
.push(text::body(profile.title()))
.push(text::caption(profile.description())),
profile,
Some(current_profile),
Message::PowerProfileChange,
)
.width(Length::Fill)
.into(),
])
})
.fold(section, settings::Section::add);
}
} else {
let item = text::body(fl!("power-mode", "no-backend"));
section = section.add(item);