uconsole_sleep/
power_mode.rs1use crate::hardware::{backlight, drm_panel, framebuffer};
4use crate::{BTConfig, CpuFreqConfig, WifiConfig};
5use log::{debug, info, warn};
6use std::fs;
7
8fn set_display_on(dry_run: bool) -> Result<(), String> {
9 let backlight_path = match backlight::find_backlight() {
10 Ok(Some(p)) => p,
11 Ok(None) => return Err("backlight not found".to_string()),
12 Err(e) => return Err(format!("failed to find backlight: {}", e)),
13 };
14
15 let framebuffer_path = framebuffer::find_framebuffer().ok().flatten();
16 let drm_path = drm_panel::find_drm_panel().ok().flatten();
17
18 info!("Turning display ON");
19 if !dry_run {
20 if let Some(fb) = framebuffer_path {
21 let _ = fs::write(fb.join("blank"), "0");
22 }
23 let _ = fs::write(backlight_path.join("bl_power"), "0");
24 if let Some(drm) = drm_path {
25 let _ = fs::write(drm.join("status"), "detect");
26 }
27 } else {
28 debug!("DRY-RUN: display ON skipped");
29 }
30 Ok(())
31}
32
33fn set_display_off(dry_run: bool) -> Result<(), String> {
34 let backlight_path = match backlight::find_backlight() {
35 Ok(Some(p)) => p,
36 Ok(None) => return Err("backlight not found".to_string()),
37 Err(e) => return Err(format!("failed to find backlight: {}", e)),
38 };
39
40 let framebuffer_path = framebuffer::find_framebuffer().ok().flatten();
41 let drm_path = drm_panel::find_drm_panel().ok().flatten();
42
43 info!("Turning display OFF");
44 if !dry_run {
45 if let Some(drm) = drm_path {
46 let _ = fs::write(drm.join("status"), "off");
47 }
48 if let Some(fb) = framebuffer_path {
49 let _ = fs::write(fb.join("blank"), "1");
50 }
51 let _ = fs::write(backlight_path.join("bl_power"), "4");
52 } else {
53 debug!("DRY-RUN: display OFF skipped");
54 }
55 Ok(())
56}
57
58#[allow(dead_code)]
59fn toggle_display(dry_run: bool) -> Result<(), String> {
61 let backlight_path = match backlight::find_backlight() {
62 Ok(Some(p)) => p,
63 Ok(None) => return Err("backlight not found".to_string()),
64 Err(e) => return Err(format!("failed to find backlight: {}", e)),
65 };
66
67 let bl_state =
68 fs::read_to_string(backlight_path.join("bl_power")).unwrap_or_else(|_| "4".to_string());
69 let bl_state_trim = bl_state.trim();
70
71 if bl_state_trim == "4" {
72 set_display_on(dry_run)
74 } else {
75 set_display_off(dry_run)
77 }
78}
79
80#[derive(Clone, Debug, PartialEq)]
82pub enum PowerMode {
83 Normal,
84 Saving,
85}
86
87pub fn enter_saving_mode(
88 cpu_config: &CpuFreqConfig,
89 dry_run: bool,
90 wifi: Option<&WifiConfig>,
91 bt: Option<&BTConfig>,
92) {
93 info!("Entering power-saving mode");
94 if let Err(e) = set_display_off(dry_run) {
95 warn!("set_display_off failed: {}", e);
96 }
97 cpu_config.apply_saving_mode(dry_run);
98 if let Some(w) = wifi {
99 w.block(dry_run);
100 }
101 if let Some(b) = bt {
102 b.block(dry_run);
103 }
104}
105
106pub fn exit_saving_mode(
108 cpu_config: &CpuFreqConfig,
109 dry_run: bool,
110 wifi: Option<&WifiConfig>,
111 bt: Option<&BTConfig>,
112) {
113 info!("Exiting power-saving mode");
114 cpu_config.apply_normal_mode(dry_run);
115 if let Err(e) = set_display_on(dry_run) {
116 warn!("set_display_on failed: {}", e);
117 }
118 if let Some(w) = wifi {
119 w.unblock(dry_run);
120 }
121 if let Some(b) = bt {
122 b.unblock(dry_run);
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129 use std::env;
130 use std::fs;
131
132 #[test]
133 fn test_enter_exit_saving_mode_dryrun() {
134 let tmp = env::temp_dir().join(format!(
135 "uconsole_pm_test_{}",
136 std::time::SystemTime::now()
137 .duration_since(std::time::UNIX_EPOCH)
138 .unwrap()
139 .as_millis()
140 ));
141 let _ = fs::create_dir_all(&tmp);
142 let cpu = CpuFreqConfig::with_policy_path(tmp.clone(), Some(String::from("100,200")));
143 enter_saving_mode(&cpu, true, None, None);
145 assert!(!tmp.join("scaling_min_freq").exists());
146 assert!(!tmp.join("scaling_max_freq").exists());
147
148 enter_saving_mode(&cpu, false, None, None);
150 assert!(tmp.join("scaling_min_freq").exists());
151 assert!(tmp.join("scaling_max_freq").exists());
152
153 exit_saving_mode(&cpu, false, None, None);
155 }
156}