Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/cli/src/tunnels/nosleep_linux.rs
3314 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
use zbus::{dbus_proxy, Connection};
7
8
use crate::{
9
constants::APPLICATION_NAME,
10
util::errors::{wrap, AnyError},
11
};
12
13
/// An basically undocumented API, but seems widely implemented, and is what
14
/// browsers use for sleep inhibition. The downside is that it also *may*
15
/// disable the screensaver. A much better and more granular API is available
16
/// on `org.freedesktop.login1.Manager`, but this requires administrative
17
/// permission to request inhibition, which is not possible here.
18
///
19
/// See https://source.chromium.org/chromium/chromium/src/+/main:services/device/wake_lock/power_save_blocker/power_save_blocker_linux.cc;l=54;drc=2e85357a8b76996981cc6f783853a49df2cedc3a
20
#[dbus_proxy(
21
interface = "org.freedesktop.PowerManagement.Inhibit",
22
gen_blocking = false,
23
default_service = "org.freedesktop.PowerManagement.Inhibit",
24
default_path = "/org/freedesktop/PowerManagement/Inhibit"
25
)]
26
trait PMInhibitor {
27
#[dbus_proxy(name = "Inhibit")]
28
fn inhibit(&self, what: &str, why: &str) -> zbus::Result<u32>;
29
}
30
31
/// A slightly better documented version which seems commonly used.
32
#[dbus_proxy(
33
interface = "org.freedesktop.ScreenSaver",
34
gen_blocking = false,
35
default_service = "org.freedesktop.ScreenSaver",
36
default_path = "/org/freedesktop/ScreenSaver"
37
)]
38
trait ScreenSaver {
39
#[dbus_proxy(name = "Inhibit")]
40
fn inhibit(&self, what: &str, why: &str) -> zbus::Result<u32>;
41
}
42
43
pub struct SleepInhibitor {
44
_connection: Connection, // Inhibition is released when the connection is closed
45
}
46
47
impl SleepInhibitor {
48
pub async fn new() -> Result<Self, AnyError> {
49
let connection = Connection::session()
50
.await
51
.map_err(|e| wrap(e, "error creating dbus session"))?;
52
53
macro_rules! try_inhibit {
54
($proxy:ident) => {
55
match $proxy::new(&connection).await {
56
Ok(proxy) => proxy.inhibit(APPLICATION_NAME, "running tunnel").await,
57
Err(e) => Err(e),
58
}
59
};
60
}
61
62
if let Err(e1) = try_inhibit!(PMInhibitorProxy) {
63
if let Err(e2) = try_inhibit!(ScreenSaverProxy) {
64
return Err(wrap(
65
e2,
66
format!(
67
"error requesting sleep inhibition, pminhibitor gave {e1}, screensaver gave"
68
),
69
)
70
.into());
71
}
72
}
73
74
Ok(SleepInhibitor {
75
_connection: connection,
76
})
77
}
78
}
79
80