Skip to content

Commit b4ac783

Browse files
committed
fix: emit ActiveProfile changed signals on system76-power profile changes
1 parent 86130f6 commit b4ac783

File tree

1 file changed

+114
-36
lines changed

1 file changed

+114
-36
lines changed

src/daemon/mod.rs

Lines changed: 114 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use tokio::{
1919
sync::Mutex,
2020
time::sleep,
2121
};
22+
use zbus::Interface;
2223

2324
use crate::{
2425
charge_thresholds::{get_charge_profiles, get_charge_thresholds, set_charge_thresholds},
@@ -38,6 +39,8 @@ use self::profiles::{balanced, battery, performance};
3839
use system76_power_zbus::ChargeProfile;
3940

4041
const THRESHOLD_POLICY: &str = "com.system76.powerdaemon.set-charge-thresholds";
42+
const NET_HADES_POWER_PROFILES_DBUS_NAME: &str = "net.hadess.PowerProfiles";
43+
const NET_HADES_POWER_PROFILES_DBUS_PATH: &str = "/net/hadess/PowerProfiles";
4144
const POWER_PROFILES_DBUS_NAME: &str = "org.freedesktop.UPower.PowerProfiles";
4245
const POWER_PROFILES_DBUS_PATH: &str = "/org/freedesktop/UPower/PowerProfiles";
4346

@@ -73,6 +76,7 @@ struct PowerDaemon {
7376
held_profiles: Vec<(u32, &'static str, String, String)>,
7477
profile_ids: u32,
7578
connection: zbus::Connection,
79+
connections: Option<(zbus::Connection, zbus::Connection)>,
7680
}
7781

7882
impl PowerDaemon {
@@ -87,6 +91,7 @@ impl PowerDaemon {
8791
held_profiles: Vec::new(),
8892
profile_ids: 0,
8993
connection,
94+
connections: None,
9095
})
9196
}
9297

@@ -120,44 +125,108 @@ impl PowerDaemon {
120125
}
121126
}
122127

128+
#[derive(Clone)]
123129
struct System76Power(Arc<Mutex<PowerDaemon>>);
124130

131+
impl System76Power {
132+
pub async fn emit_active_profile_changed(&self) {
133+
let (upp_connection, hadess_connection, profile) = {
134+
let this = self.0.lock().await;
135+
let Some((upp, hadess)) = this.connections.clone() else { return };
136+
137+
let profile = system76_profile_to_upp_str(&this.power_profile);
138+
(upp, hadess, profile)
139+
};
140+
141+
let value = zvariant::Value::Str(zvariant::Str::from(profile));
142+
let changed = HashMap::from_iter(std::iter::once(("ActiveProfile", &value)));
143+
let invalidated = &[];
144+
145+
if let Ok(context) = zbus::SignalContext::new(&upp_connection, POWER_PROFILES_DBUS_PATH) {
146+
let _res = dbg!(
147+
zbus::fdo::Properties::properties_changed(
148+
&context,
149+
UPowerPowerProfiles::name(),
150+
&changed,
151+
invalidated,
152+
)
153+
.await
154+
);
155+
}
156+
157+
if let Ok(context) =
158+
zbus::SignalContext::new(&hadess_connection, NET_HADES_POWER_PROFILES_DBUS_PATH)
159+
{
160+
let _res = dbg!(
161+
zbus::fdo::Properties::properties_changed(
162+
&context,
163+
NetHadessPowerProfiles::name(),
164+
&changed,
165+
invalidated
166+
)
167+
.await
168+
);
169+
}
170+
}
171+
}
172+
125173
#[zbus::dbus_interface(name = "com.system76.PowerDaemon")]
126174
impl System76Power {
127175
async fn battery(
128176
&mut self,
129177
#[zbus(signal_context)] context: zbus::SignalContext<'_>,
130178
) -> zbus::fdo::Result<()> {
131-
self.0
179+
let result = self
180+
.0
132181
.lock()
133182
.await
134183
.apply_profile(&context, battery, "Battery")
135184
.await
136-
.map_err(zbus_error_from_display)
185+
.map_err(zbus_error_from_display);
186+
187+
if result.is_ok() {
188+
self.emit_active_profile_changed().await
189+
}
190+
191+
result
137192
}
138193

139194
async fn balanced(
140195
&mut self,
141196
#[zbus(signal_context)] context: zbus::SignalContext<'_>,
142197
) -> zbus::fdo::Result<()> {
143-
self.0
198+
let result = self
199+
.0
144200
.lock()
145201
.await
146202
.apply_profile(&context, balanced, "Balanced")
147203
.await
148-
.map_err(zbus_error_from_display)
204+
.map_err(zbus_error_from_display);
205+
206+
if result.is_ok() {
207+
self.emit_active_profile_changed().await
208+
}
209+
210+
result
149211
}
150212

151213
async fn performance(
152214
&mut self,
153215
#[zbus(signal_context)] context: zbus::SignalContext<'_>,
154216
) -> zbus::fdo::Result<()> {
155-
self.0
217+
let result = self
218+
.0
156219
.lock()
157220
.await
158221
.apply_profile(&context, performance, "Performance")
159222
.await
160-
.map_err(zbus_error_from_display)
223+
.map_err(zbus_error_from_display);
224+
225+
if result.is_ok() {
226+
self.emit_active_profile_changed().await
227+
}
228+
229+
result
161230
}
162231

163232
#[dbus_interface(out_args("profile"))]
@@ -358,12 +427,7 @@ impl UPowerPowerProfiles {
358427

359428
#[dbus_interface(property)]
360429
async fn active_profile(&self) -> &str {
361-
match self.0.lock().await.power_profile.as_str() {
362-
"Battery" => "power-saver",
363-
"Balanced" => "balanced",
364-
"Performance" => "performance",
365-
_ => "unknown",
366-
}
430+
system76_profile_to_upp_str(self.0.lock().await.power_profile.as_str())
367431
}
368432

369433
#[dbus_interface(property)]
@@ -455,9 +519,6 @@ pub async fn daemon() -> anyhow::Result<()> {
455519
let connection =
456520
zbus::Connection::system().await.context("failed to create zbus connection")?;
457521

458-
let context = zbus::SignalContext::new(&connection, DBUS_PATH)
459-
.context("unable to create signal context")?;
460-
461522
let daemon = PowerDaemon::new(connection)?;
462523

463524
let nvidia_exists = !daemon.graphics.nvidia.is_empty();
@@ -488,26 +549,9 @@ pub async fn daemon() -> anyhow::Result<()> {
488549
}
489550
}
490551

491-
if let Err(why) = system76_daemon.balanced(context.clone()).await {
492-
log::warn!("Failed to set initial profile: {}", why);
493-
}
494-
495-
system76_daemon.0.lock().await.initial_set = true;
496-
497-
// Register DBus interface for com.system76.PowerDaemon.
498-
let _connection = zbus::ConnectionBuilder::system()
499-
.context("failed to create zbus connection builder")?
500-
.name(DBUS_NAME)
501-
.context("unable to register name")?
502-
.serve_at(DBUS_PATH, system76_daemon)
503-
.context("unable to serve")?
504-
.build()
505-
.await
506-
.context("unable to create system service for com.system76.PowerDaemon")?;
507-
508552
// Register DBus interface for org.freedesktop.UPower.PowerProfiles.
509553
// This is used by powerprofilesctl
510-
let _connection = zbus::ConnectionBuilder::system()
554+
let upp_connection = zbus::ConnectionBuilder::system()
511555
.context("failed to create zbus connection builder")?
512556
.name(POWER_PROFILES_DBUS_NAME)
513557
.context("unable to register name")?
@@ -519,16 +563,41 @@ pub async fn daemon() -> anyhow::Result<()> {
519563

520564
// Register DBus interface for net.hadess.PowerProfiles.
521565
// This is used by gnome-shell
522-
let _connection = zbus::ConnectionBuilder::system()
566+
let hadess_connection = zbus::ConnectionBuilder::system()
523567
.context("failed to create zbus connection builder")?
524-
.name("net.hadess.PowerProfiles")
568+
.name(NET_HADES_POWER_PROFILES_DBUS_NAME)
525569
.context("unable to register name")?
526-
.serve_at("/net/hadess/PowerProfiles", NetHadessPowerProfiles(UPowerPowerProfiles(daemon)))
570+
.serve_at(
571+
NET_HADES_POWER_PROFILES_DBUS_PATH,
572+
NetHadessPowerProfiles(UPowerPowerProfiles(daemon)),
573+
)
527574
.context("unable to serve")?
528575
.build()
529576
.await
530577
.context("unable to create system service for net.hadess.PowerProfiles")?;
531578

579+
// Register DBus interface for com.system76.PowerDaemon.
580+
let connection = zbus::ConnectionBuilder::system()
581+
.context("failed to create zbus connection builder")?
582+
.name(DBUS_NAME)
583+
.context("unable to register name")?
584+
.serve_at(DBUS_PATH, system76_daemon.clone())
585+
.context("unable to serve")?
586+
.build()
587+
.await
588+
.context("unable to create system service for com.system76.PowerDaemon")?;
589+
590+
system76_daemon.0.lock().await.connections = Some((upp_connection, hadess_connection));
591+
592+
let context = zbus::SignalContext::new(&connection, DBUS_PATH)
593+
.context("unable to create signal context")?;
594+
595+
if let Err(why) = system76_daemon.balanced(context.clone()).await {
596+
log::warn!("Failed to set initial profile: {}", why);
597+
}
598+
599+
system76_daemon.0.lock().await.initial_set = true;
600+
532601
// Spawn hid backlight daemon
533602
let _hid_backlight = thread::spawn(hid_backlight::daemon);
534603
let mut fan_daemon = FanDaemon::new(nvidia_exists);
@@ -575,6 +644,15 @@ pub async fn daemon() -> anyhow::Result<()> {
575644
Ok(())
576645
}
577646

647+
fn system76_profile_to_upp_str(system76_profile: &str) -> &'static str {
648+
match system76_profile {
649+
"Battery" => "power-saver",
650+
"Balanced" => "balanced",
651+
"Performance" => "performance",
652+
_ => "unknown",
653+
}
654+
}
655+
578656
fn zbus_error_from_display<E: Display>(why: E) -> zbus::fdo::Error {
579657
zbus::fdo::Error::Failed(format!("{}", why))
580658
}

0 commit comments

Comments
 (0)