Skip to content

Commit 90d038e

Browse files
Merge pull request #44 from Staphylococcus/centralized-suspend-rail
Centralize system suspend rail
2 parents 5004d52 + 01cd05e commit 90d038e

14 files changed

Lines changed: 1387 additions & 147 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ chmod +x ./install.sh
9797
./install.sh
9898
```
9999

100-
The installer will prompt for your TV IP, MAC address, HDMI input, and session idle blanking details, then install the required services. System sleep/wake handling uses the default lifecycle service plus NetworkManager pre-down gate unless you opt out in `config.env`.
100+
The installer will prompt for your TV IP, MAC address, HDMI input, and session idle blanking details, then install the required services. System sleep/wake handling uses the lifecycle service plus NetworkManager pre-down gate as cooperating suspend sources unless you opt out in `config.env`.
101101

102102
On first use, you may need to accept a pairing prompt on the TV:
103103

crates/lg-buddy/src/commands.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ use std::time::Duration;
99

1010
use crate::auth::resolve_bscpylgtv_auth_context_from_env;
1111
use crate::config::{load_config, resolve_config_path_from_env, Config};
12+
use crate::events::RuntimeEvent;
1213
use crate::lifecycle::ThreadSleeper;
1314
use crate::lifecycle::{self, JournalctlSleepDetector, NmOnlineNetworkWaiter};
1415
use crate::notifications::{FreedesktopNotifier, Notification, NotificationError, Notifier};
15-
use crate::state::{ScreenOwnershipMarker, StateScope, SystemSleepAttemptState};
16+
use crate::state::{
17+
ScreenOwnershipMarker, StateScope, SystemSleepAttemptState, SystemSleepCycleState,
18+
};
1619
use crate::tv::{
1720
BscpylgtvCommandClient, OledBrightness, TvClient, TvDevice, UserScopedBscpylgtvCommandLauncher,
1821
};
@@ -242,14 +245,35 @@ pub fn run_screen_off<W: Write>(writer: &mut W) -> Result<(), RunError> {
242245
}
243246

244247
pub fn run_sleep_pre<W: Write>(writer: &mut W) -> Result<(), RunError> {
248+
run_sleep_pre_for_event(
249+
writer,
250+
RuntimeEvent::from_command(crate::Command::SleepPre)
251+
.expect("sleep-pre should map to a runtime event"),
252+
)
253+
}
254+
255+
pub fn run_sleep_pre_for_event<W: Write>(
256+
writer: &mut W,
257+
event: RuntimeEvent,
258+
) -> Result<(), RunError> {
245259
let config_path = resolve_config_path_from_env().map_err(RunError::ConfigPath)?;
246260
let config = load_config(&config_path).map_err(RunError::Config)?;
247261
let marker = ScreenOwnershipMarker::from_env(StateScope::System).map_err(RunError::StateDir)?;
262+
let cycle_state =
263+
SystemSleepCycleState::from_env(StateScope::System).map_err(RunError::StateDir)?;
248264
let tv_client =
249265
build_tv_client(&config_path)?.with_command_timeout(SYSTEM_PRE_SLEEP_TV_COMMAND_TIMEOUT);
250266
let sleeper = ThreadSleeper;
251267

252-
lifecycle::attempt_system_sleep_power_off_with(writer, &config, &marker, &tv_client, &sleeper)
268+
lifecycle::handle_system_suspend_with(
269+
writer,
270+
&config,
271+
&marker,
272+
&cycle_state,
273+
&tv_client,
274+
&sleeper,
275+
event,
276+
)
253277
}
254278

255279
pub fn run_sleep<W: Write>(writer: &mut W) -> Result<(), RunError> {
@@ -360,12 +384,28 @@ pub fn run_system_resume<W: Write>(writer: &mut W) -> Result<(), RunError> {
360384
&network_waiter,
361385
);
362386

387+
let mut cleanup_error = None;
388+
363389
if let Err(err) = attempt_state.clear() {
364390
writeln!(
365391
writer,
366392
"LG Buddy System Resume: could not clear system sleep attempt marker after resume. {err}"
367393
)?;
368-
if result.is_ok() {
394+
cleanup_error = Some(err);
395+
}
396+
397+
if let Err(err) = attempt_state.clear_outcome() {
398+
writeln!(
399+
writer,
400+
"LG Buddy System Resume: could not clear system sleep cycle state after resume. {err}"
401+
)?;
402+
if cleanup_error.is_none() {
403+
cleanup_error = Some(err);
404+
}
405+
}
406+
407+
if result.is_ok() {
408+
if let Some(err) = cleanup_error {
369409
return Err(RunError::Io(err));
370410
}
371411
}

0 commit comments

Comments
 (0)