mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 19:11:08 +00:00
fix: Steam no longer sleeps again right after a paused session resumes (#1162)
This commit is contained in:
1 parent
64b966af49
commit
3a8d6aaabb
5 files changed
+261
-19
No files matched your search
@@ -80,6 +80,7 @@ class SessionService : Service() {
|
||||
private var nativeSleepToken: String? = null
|
||||
private var nativeSleepReady = false
|
||||
private var nativeSleepFallback = false
|
||||
private var nativeSleepIdle = false
|
||||
private var nativeSleepTimeout: Runnable? = null
|
||||
private var suspendOperationPending = false
|
||||
private var pipTask = false
|
||||
@@ -1019,7 +1020,7 @@ class SessionService : Service() {
|
||||
screenOn = (getSystemService(Context.POWER_SERVICE) as? PowerManager)?.isInteractive ?: screenOn
|
||||
manualPauseRequested = false
|
||||
suspendDownloadNow = false
|
||||
if (steamSleepToken == null && (nativeSleepToken == null || nativeSleepFallback)) requestSteamWake()
|
||||
if (steamSleepToken == null && (nativeSleepToken == null || nativeSleepFallback || nativeSleepIdle)) requestSteamWake()
|
||||
completeNativeSleep()
|
||||
completeSteamSleep()
|
||||
suspendAttemptFailed = false
|
||||
@@ -1219,16 +1220,22 @@ class SessionService : Service() {
|
||||
val downloadsBlockingSuspend = steamDownloadsInBackground && SessionState.mode == MODE_STEAM &&
|
||||
suspendPolicy != SessionPrefs.SUSPEND_NEVER && hidden && downloadActive && !suspendDownloadNow
|
||||
if (downloadsBlockingSuspend) acquireLocks()
|
||||
if (suspendPolicy != SessionPrefs.SUSPEND_NATIVE || !hidden || downloadsBlockingSuspend) {
|
||||
val steamPause = SessionState.mode == MODE_STEAM && !downloadsBlockingSuspend && when (suspendPolicy) {
|
||||
SessionPrefs.SUSPEND_AUTO, SessionPrefs.SUSPEND_NATIVE -> hidden
|
||||
SessionPrefs.SUSPEND_MANUAL -> manualPauseRequested
|
||||
else -> false
|
||||
}
|
||||
if (!steamPause) {
|
||||
completeNativeSleep()
|
||||
} else if (nativeSleepToken == null && steamSleepToken == null &&
|
||||
!SessionState.suspended && !suspendAttemptFailed) {
|
||||
prepareNativeSleep()
|
||||
}
|
||||
val prepared = SessionState.mode != MODE_STEAM || nativeSleepReady
|
||||
val shouldSuspend = steamSleepToken != null || when (suspendPolicy) {
|
||||
SessionPrefs.SUSPEND_AUTO -> hidden && !downloadsBlockingSuspend
|
||||
SessionPrefs.SUSPEND_AUTO -> hidden && prepared && !downloadsBlockingSuspend
|
||||
SessionPrefs.SUSPEND_NATIVE -> hidden && nativeSleepReady && !downloadsBlockingSuspend
|
||||
SessionPrefs.SUSPEND_MANUAL -> manualPauseRequested && !downloadsBlockingSuspend
|
||||
SessionPrefs.SUSPEND_MANUAL -> manualPauseRequested && prepared && !downloadsBlockingSuspend
|
||||
else -> false
|
||||
}
|
||||
if (suspendOperationPending || suspendAttemptFailed || shouldSuspend == SessionState.suspended) return
|
||||
@@ -1296,7 +1303,7 @@ class SessionService : Service() {
|
||||
|
||||
private fun resumeSteamSleepOnReturn() {
|
||||
if (suspendPolicy in setOf(SessionPrefs.SUSPEND_AUTO, SessionPrefs.SUSPEND_NATIVE) && hasVisibleSurface) {
|
||||
if (steamSleepToken == null && (nativeSleepToken == null || nativeSleepFallback)) requestSteamWake()
|
||||
if (steamSleepToken == null && (nativeSleepToken == null || nativeSleepFallback || nativeSleepIdle)) requestSteamWake()
|
||||
completeNativeSleep()
|
||||
completeSteamSleep()
|
||||
}
|
||||
@@ -1307,13 +1314,14 @@ class SessionService : Service() {
|
||||
nativeSleepToken = token
|
||||
nativeSleepReady = false
|
||||
nativeSleepFallback = false
|
||||
nativeSleepIdle = suspendPolicy != SessionPrefs.SUSPEND_NATIVE
|
||||
val dir = LinuxRuntime.sessionRoot(this)
|
||||
runCatching {
|
||||
val staged = File(dir, "steam-native-sleep.tmp")
|
||||
staged.writeText("$token\n")
|
||||
staged.writeText(if (nativeSleepIdle) "$token idle\n" else "$token\n")
|
||||
check(staged.renameTo(File(dir, "steam-native-sleep")))
|
||||
}.onFailure { Log.w(TAG, "could not request Native sleep; using timed pause", it) }
|
||||
SessionEvents.record("steam.native_sleep_requested")
|
||||
SessionEvents.record("steam.native_sleep_requested", mapOf("idle" to nativeSleepIdle))
|
||||
val gen = sessionGen
|
||||
val timeout = Runnable {
|
||||
if (gen != sessionGen || !SessionState.running || nativeSleepToken != token) return@Runnable
|
||||
@@ -1339,6 +1347,7 @@ class SessionService : Service() {
|
||||
nativeSleepToken = null
|
||||
nativeSleepReady = false
|
||||
nativeSleepFallback = false
|
||||
nativeSleepIdle = false
|
||||
}
|
||||
|
||||
private fun requestSteamWake() {
|
||||
|
||||
@@ -532,6 +532,46 @@ def cdp_eval(agent_dir, expression, target=None, await_promise=True, timeout=15)
|
||||
ws.close()
|
||||
|
||||
|
||||
def steam_idle_inhibit(agent_dir, inhibit):
|
||||
expression = """(async want => {
|
||||
const toggle = () => new Promise(done => {
|
||||
let handle = null;
|
||||
let timer = null;
|
||||
const finish = value => {
|
||||
clearTimeout(timer);
|
||||
handle?.unregister?.();
|
||||
done(value);
|
||||
};
|
||||
timer = setTimeout(() => finish(null), 2500);
|
||||
handle = SteamClient.Console.RegisterForSpewOutput(entry => {
|
||||
const found = /Suspend inhibit: ([01])/.exec(entry?.spew || "");
|
||||
if (found) finish(found[1] === "1");
|
||||
});
|
||||
SteamClient.Console.ExecCommand("toggle_idle_suspend_inhibit 1");
|
||||
});
|
||||
let state = await toggle();
|
||||
if (state === !want) state = await toggle();
|
||||
return state === want;
|
||||
})(%s)""" % ("true" if inhibit else "false")
|
||||
return cdp_eval(agent_dir, expression, timeout=12).get("value") is True
|
||||
|
||||
|
||||
def steam_idle_suspend_seconds(agent_dir, vpower=Path("/run/vpower/ac_status")):
|
||||
expression = """(() => {
|
||||
const settings = globalThis.settingsStore?.clientSettings;
|
||||
return settings ? [settings.system_idle_suspend_ac_sec, settings.system_idle_suspend_battery_sec] : null;
|
||||
})()"""
|
||||
seconds = cdp_eval(agent_dir, expression, await_promise=False, timeout=5).get("value")
|
||||
if not isinstance(seconds, list) or len(seconds) != 2:
|
||||
return None
|
||||
try:
|
||||
on_ac = vpower.read_text().strip() != "Disconnected"
|
||||
except OSError:
|
||||
on_ac = True
|
||||
value = seconds[0 if on_ac else 1]
|
||||
return max(0, int(value)) if isinstance(value, (int, float)) else None
|
||||
|
||||
|
||||
def steam_selection(agent_dir, timeout=5):
|
||||
result = cdp_eval(
|
||||
agent_dir,
|
||||
@@ -923,6 +963,26 @@ def main(argv):
|
||||
state = "unknown"
|
||||
print(state)
|
||||
return {"yes": 0, "no": 5}.get(state, 1)
|
||||
if argv and argv[0] == "--steam-idle-inhibit":
|
||||
if len(argv) != 2 or argv[1] not in ("on", "off"):
|
||||
print("usage: droiddeck-agent --steam-idle-inhibit on|off", file=sys.stderr)
|
||||
return 2
|
||||
try:
|
||||
done = steam_idle_inhibit(Path(base) / "agent", argv[1] == "on")
|
||||
except (AgentError, OSError, ValueError) as error:
|
||||
print("droiddeck-agent: could not reach the client's idle sleep: %s" % error, file=sys.stderr)
|
||||
return 1
|
||||
return 0 if done else 1
|
||||
if argv and argv[0] == "--steam-idle-suspend-seconds":
|
||||
try:
|
||||
seconds = steam_idle_suspend_seconds(Path(base) / "agent")
|
||||
except (AgentError, OSError, ValueError) as error:
|
||||
print("droiddeck-agent: could not read the client's idle sleep: %s" % error, file=sys.stderr)
|
||||
return 1
|
||||
if seconds is None:
|
||||
return 1
|
||||
print(seconds)
|
||||
return 0
|
||||
if argv and argv[0] == "--steam-shortcut-state":
|
||||
if len(argv) not in (2, 3):
|
||||
print("usage: droiddeck-agent --steam-shortcut-state <cgameid> [timeout-seconds]", file=sys.stderr)
|
||||
|
||||
@@ -28,6 +28,8 @@ UPOWER_ROOT = "/org/freedesktop/UPower"
|
||||
NATIVE_PREPARE_MS = 1500
|
||||
AGENT = Path(__file__).resolve().with_name("droiddeck-agent")
|
||||
ASLEEP_WAIT = 6
|
||||
INHIBIT_WAIT = 12
|
||||
RELEASE_RETRIES = 8
|
||||
INTROSPECTION = """
|
||||
<node>
|
||||
<interface name="org.freedesktop.login1.Manager">
|
||||
@@ -58,8 +60,14 @@ class LoginManager:
|
||||
self.native_request = self.directory / "steam-native-sleep"
|
||||
self.native_ready = self.directory / "steam-native-ready"
|
||||
self.pending = None
|
||||
self.pending_idle = False
|
||||
self.waiting = set()
|
||||
self.timeout = None
|
||||
self.preparation = None
|
||||
self.inhibited = False
|
||||
self.inhibit_lock = threading.Lock()
|
||||
self.release = None
|
||||
self.generation = 0
|
||||
info = Gio.DBusNodeInfo.new_for_xml(INTROSPECTION).interfaces[0]
|
||||
self.registration = bus.register_object(ROOT, info, self.method, self.property, None)
|
||||
upower_info = Gio.DBusNodeInfo.new_for_xml(UPOWER_INTROSPECTION).interfaces[0]
|
||||
@@ -89,6 +97,7 @@ class LoginManager:
|
||||
reply.return_dbus_error(NAME + ".OperationInProgress", "The session is already pausing")
|
||||
return
|
||||
self.pending = uuid.uuid4().hex
|
||||
self.pending_idle = False
|
||||
self.notify(True)
|
||||
reply.return_value(None)
|
||||
self.bus.flush(None, self.publish_after_flush, self.pending)
|
||||
@@ -101,7 +110,7 @@ class LoginManager:
|
||||
self.resume()
|
||||
return
|
||||
if self.pending == token:
|
||||
self.publish(self.request)
|
||||
self.hold(token, self.publish, self.request)
|
||||
|
||||
def publish(self, request):
|
||||
self.check_state()
|
||||
@@ -119,15 +128,21 @@ class LoginManager:
|
||||
|
||||
def prepare_native(self):
|
||||
try:
|
||||
token = self.native_request.read_text().strip()
|
||||
words = self.native_request.read_text().split()
|
||||
self.native_request.unlink(missing_ok=True)
|
||||
except OSError:
|
||||
return
|
||||
if not re.fullmatch(r"[a-f0-9]{32}", token) or self.pending is not None:
|
||||
token = words[0] if words else ""
|
||||
if not re.fullmatch(r"[a-f0-9]{32}", token) or words[1:] not in ([], ["idle"]) or self.pending is not None:
|
||||
return
|
||||
if self.read_state() == token + ":awake":
|
||||
return
|
||||
self.pending = token
|
||||
self.pending_idle = words[1:] == ["idle"]
|
||||
self.waiting = {"hold"} if self.pending_idle else {"hold", "prepare"}
|
||||
self.hold(token, self.prepared, token, "hold")
|
||||
if self.pending_idle:
|
||||
return
|
||||
self.notify(True)
|
||||
self.bus.flush(None, self.prepare_after_flush, token)
|
||||
|
||||
@@ -144,10 +159,73 @@ class LoginManager:
|
||||
|
||||
def finish_preparation(self, token):
|
||||
self.preparation = None
|
||||
if self.pending == token:
|
||||
self.prepared(token, "prepare")
|
||||
return False
|
||||
|
||||
def prepared(self, token, step):
|
||||
if self.pending != token:
|
||||
return False
|
||||
self.waiting.discard(step)
|
||||
if not self.waiting:
|
||||
self.publish(self.native_ready)
|
||||
return False
|
||||
|
||||
def hold(self, token, then, *args):
|
||||
self.cancel_release()
|
||||
|
||||
def work():
|
||||
self.set_inhibit(True)
|
||||
GLib.idle_add(self.after_hold, token, then, args)
|
||||
|
||||
threading.Thread(target=work, daemon=True).start()
|
||||
|
||||
def after_hold(self, token, then, args):
|
||||
if self.pending == token:
|
||||
then(*args)
|
||||
elif self.pending is None:
|
||||
self.release_later()
|
||||
return False
|
||||
|
||||
def set_inhibit(self, inhibit, generation=None):
|
||||
with self.inhibit_lock:
|
||||
if (generation is not None and generation != self.generation) or self.inhibited == inhibit:
|
||||
return
|
||||
if steam_idle_inhibit(inhibit):
|
||||
self.inhibited = inhibit
|
||||
print("== login1: Steam idle sleep " + ("held" if inhibit else "released"), flush=True)
|
||||
else:
|
||||
self.inhibited = None
|
||||
|
||||
def cancel_release(self):
|
||||
self.generation += 1
|
||||
if self.release is not None:
|
||||
GLib.source_remove(self.release)
|
||||
self.release = None
|
||||
|
||||
def release_later(self):
|
||||
self.cancel_release()
|
||||
if self.inhibited is False:
|
||||
return
|
||||
generation = self.generation
|
||||
threading.Thread(target=lambda: GLib.idle_add(self.schedule_release, generation, steam_idle_suspend_seconds()),
|
||||
daemon=True).start()
|
||||
|
||||
def schedule_release(self, generation, seconds, attempt=0):
|
||||
if generation == self.generation and self.pending is None:
|
||||
self.release = GLib.timeout_add_seconds(seconds or 0, self.release_now, generation, attempt)
|
||||
return False
|
||||
|
||||
def release_now(self, generation, attempt):
|
||||
self.release = None
|
||||
|
||||
def work():
|
||||
self.set_inhibit(False, generation)
|
||||
if self.inhibited is not False and attempt < RELEASE_RETRIES:
|
||||
GLib.idle_add(self.schedule_release, generation, 1 << attempt, attempt + 1)
|
||||
|
||||
threading.Thread(target=work, daemon=True).start()
|
||||
return False
|
||||
|
||||
def changed(self, monitor, file, other, event):
|
||||
if file.get_basename() == self.native_request.name or (other and other.get_basename() == self.native_request.name):
|
||||
self.prepare_native()
|
||||
@@ -178,8 +256,10 @@ class LoginManager:
|
||||
|
||||
def woken(self):
|
||||
if self.pending is not None:
|
||||
idle = self.pending_idle
|
||||
self.resume(force=True)
|
||||
return
|
||||
if not idle:
|
||||
return
|
||||
threading.Thread(target=lambda: GLib.idle_add(self.replay_unless_awake, steam_asleep()), daemon=True).start()
|
||||
|
||||
def replay_unless_awake(self, asleep):
|
||||
@@ -195,14 +275,18 @@ class LoginManager:
|
||||
self.notify(True)
|
||||
self.bus.flush(None, self.finish_recovery, None)
|
||||
return
|
||||
idle = self.pending_idle
|
||||
self.pending = None
|
||||
self.pending_idle = False
|
||||
if self.preparation is not None:
|
||||
GLib.source_remove(self.preparation)
|
||||
self.preparation = None
|
||||
if self.timeout is not None:
|
||||
GLib.source_remove(self.timeout)
|
||||
self.timeout = None
|
||||
self.notify(False)
|
||||
if not idle:
|
||||
self.notify(False)
|
||||
self.release_later()
|
||||
|
||||
def finish_recovery(self, connection, result, _data):
|
||||
try:
|
||||
@@ -213,13 +297,26 @@ class LoginManager:
|
||||
self.notify(False)
|
||||
|
||||
|
||||
def steam_asleep():
|
||||
def agent(*args, timeout=ASLEEP_WAIT):
|
||||
try:
|
||||
code = subprocess.run([str(AGENT), "--steam-asleep"], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL, timeout=ASLEEP_WAIT).returncode
|
||||
done = subprocess.run([str(AGENT), *args], stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL, text=True, timeout=timeout)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return None
|
||||
return {0: True, 5: False}.get(code)
|
||||
return None, ""
|
||||
return done.returncode, done.stdout
|
||||
|
||||
|
||||
def steam_asleep():
|
||||
return {0: True, 5: False}.get(agent("--steam-asleep")[0])
|
||||
|
||||
|
||||
def steam_idle_inhibit(inhibit):
|
||||
return agent("--steam-idle-inhibit", "on" if inhibit else "off", timeout=INHIBIT_WAIT)[0] == 0
|
||||
|
||||
|
||||
def steam_idle_suspend_seconds():
|
||||
code, output = agent("--steam-idle-suspend-seconds")
|
||||
return int(output) if code == 0 and output.strip().isdigit() else None
|
||||
|
||||
|
||||
def load_netmanager():
|
||||
|
||||
@@ -338,6 +338,33 @@ class AgentTest(unittest.TestCase):
|
||||
with patch.object(agent, "cdp_eval", side_effect=agent.AgentError("NO_DEVTOOLS", "down")):
|
||||
self.assertEqual(1, agent.main(["--steam-asleep"]))
|
||||
|
||||
def test_idle_inhibit_command_reports_whether_steam_reached_the_state(self):
|
||||
with patch.dict(os.environ, {"BL_LAUNCH_DIR": str(self.dir.parent)}):
|
||||
for value, code in ((True, 0), (False, 1), (None, 1)):
|
||||
with self.subTest(value=value), patch.object(agent, "cdp_eval", return_value={"value": value}) as ask:
|
||||
self.assertEqual(code, agent.main(["--steam-idle-inhibit", "on"]))
|
||||
self.assertIn("toggle_idle_suspend_inhibit 1", ask.call_args.args[1])
|
||||
self.assertTrue(ask.call_args.args[1].rstrip().endswith("(true)"))
|
||||
with patch.object(agent, "cdp_eval", return_value={"value": True}) as ask:
|
||||
self.assertEqual(0, agent.main(["--steam-idle-inhibit", "off"]))
|
||||
self.assertTrue(ask.call_args.args[1].rstrip().endswith("(false)"))
|
||||
with patch.object(agent, "cdp_eval", side_effect=agent.AgentError("NO_DEVTOOLS", "down")):
|
||||
self.assertEqual(1, agent.main(["--steam-idle-inhibit", "on"]))
|
||||
self.assertEqual(2, agent.main(["--steam-idle-inhibit", "maybe"]))
|
||||
|
||||
def test_idle_suspend_seconds_follow_the_power_source(self):
|
||||
vpower = self.dir / "ac_status"
|
||||
with patch.object(agent, "cdp_eval", return_value={"value": [3600, 900]}):
|
||||
vpower.write_text("Connected\n")
|
||||
self.assertEqual(3600, agent.steam_idle_suspend_seconds(self.dir, vpower))
|
||||
vpower.write_text("Disconnected\n")
|
||||
self.assertEqual(900, agent.steam_idle_suspend_seconds(self.dir, vpower))
|
||||
with patch.object(agent, "cdp_eval", return_value={"value": None}):
|
||||
self.assertIsNone(agent.steam_idle_suspend_seconds(self.dir, vpower))
|
||||
with patch.dict(os.environ, {"BL_LAUNCH_DIR": str(self.dir.parent)}), \
|
||||
patch.object(agent, "steam_idle_suspend_seconds", return_value=None):
|
||||
self.assertEqual(1, agent.main(["--steam-idle-suspend-seconds"]))
|
||||
|
||||
def test_cdp_exception(self):
|
||||
server = FakeDevTools({"result": {"result": {"type": "object"}, "exceptionDetails": {
|
||||
"text": "Uncaught", "exception": {"description": "ReferenceError: SteamClient is not defined"}}}})
|
||||
|
||||
@@ -77,6 +77,7 @@ class SleepHandshakeTest(unittest.TestCase):
|
||||
GLib.Variant("(ss)", (IFACE, "PreparingForSleep")))[0]
|
||||
|
||||
def suspend(self):
|
||||
(self.dir / "steam-sleep").unlink(missing_ok=True)
|
||||
self.call(IFACE, "Suspend", GLib.Variant("(b)", (True,)))
|
||||
self.wait_for(lambda: (self.dir / "steam-sleep").exists())
|
||||
self.wait_for(lambda: self.signals == [True])
|
||||
@@ -239,6 +240,7 @@ class FakeAgentCase(unittest.TestCase):
|
||||
suspend = SleepHandshakeTest.suspend
|
||||
state = SleepHandshakeTest.state
|
||||
request_wake = SleepHandshakeTest.request_wake
|
||||
request_native = SleepHandshakeTest.request_native
|
||||
|
||||
def asked(self):
|
||||
path = self.dir / "agent-calls"
|
||||
@@ -264,7 +266,7 @@ class AwakeSteamTest(FakeAgentCase):
|
||||
self.state(token, "paused")
|
||||
self.request_wake()
|
||||
self.wait_for(lambda: self.signals == [True, False])
|
||||
self.assertEqual([], self.asked())
|
||||
self.assertNotIn("--steam-asleep", self.asked())
|
||||
|
||||
|
||||
@unittest.skipUnless(Gio and os.environ.get("DBUS_SESSION_BUS_ADDRESS"), "requires dbus-run-session and PyGObject")
|
||||
@@ -276,6 +278,53 @@ class AsleepSteamTest(FakeAgentCase):
|
||||
self.wait_for(lambda: self.signals == [True, False])
|
||||
self.assertEqual(["--steam-asleep"], self.asked())
|
||||
|
||||
def test_steam_sleep_request_holds_idle_sleep_before_the_host_pauses(self):
|
||||
token = self.suspend()
|
||||
self.assertEqual(["--steam-idle-inhibit", "on"], self.asked())
|
||||
self.state(token, "paused")
|
||||
self.state(token, "awake")
|
||||
self.wait_for(lambda: self.signals == [True, False])
|
||||
self.wait_for(lambda: self.asked()[-1:] == ["off"])
|
||||
self.assertEqual(["--steam-idle-inhibit", "on", "--steam-idle-suspend-seconds",
|
||||
"--steam-idle-inhibit", "off"], self.asked())
|
||||
|
||||
def test_idle_pause_holds_idle_sleep_without_a_sleep_wake_pair(self):
|
||||
token = self.request_native("2" * 32 + " idle").split()[0]
|
||||
self.wait_for(lambda: (self.dir / "steam-native-ready").exists())
|
||||
self.assertEqual(token, (self.dir / "steam-native-ready").read_text().strip())
|
||||
self.assertEqual(["--steam-idle-inhibit", "on"], self.asked())
|
||||
self.state(token, "paused")
|
||||
self.state(token, "awake")
|
||||
self.wait_for(lambda: self.asked()[-1:] == ["off"])
|
||||
self.assertEqual([], self.signals)
|
||||
self.assertEqual(["--steam-idle-inhibit", "on", "--steam-idle-suspend-seconds",
|
||||
"--steam-idle-inhibit", "off"], self.asked())
|
||||
|
||||
def test_a_failed_release_is_tried_again(self):
|
||||
failed = self.dir / "release-failed"
|
||||
(self.dir / "bin/droiddeck-agent").write_text(
|
||||
"#!/bin/sh\necho \"$@\" >> \"%s\"\n"
|
||||
"if [ \"$2\" = off ] && [ ! -e \"%s\" ]; then : > \"%s\"; exit 1; fi\nexit 0\n"
|
||||
% (self.dir / "agent-calls", failed, failed))
|
||||
token = self.suspend()
|
||||
self.state(token, "paused")
|
||||
self.state(token, "awake")
|
||||
self.wait_for(lambda: self.asked().count("off") == 2)
|
||||
time.sleep(2.5)
|
||||
self.assertEqual(["--steam-idle-inhibit", "on", "--steam-idle-suspend-seconds",
|
||||
"--steam-idle-inhibit", "off", "--steam-idle-inhibit", "off"], self.asked())
|
||||
|
||||
def test_a_hold_steam_did_not_confirm_is_still_released(self):
|
||||
(self.dir / "bin/droiddeck-agent").write_text(
|
||||
"#!/bin/sh\necho \"$@\" >> \"%s\"\n[ \"$2\" = on ] && exit 1\nexit 0\n" % (self.dir / "agent-calls"))
|
||||
token = self.suspend()
|
||||
self.state(token, "paused")
|
||||
self.state(token, "awake")
|
||||
self.wait_for(lambda: self.signals == [True, False])
|
||||
self.wait_for(lambda: self.asked()[-1:] == ["off"])
|
||||
self.assertEqual(["--steam-idle-inhibit", "on", "--steam-idle-suspend-seconds",
|
||||
"--steam-idle-inhibit", "off"], self.asked())
|
||||
|
||||
|
||||
class WithNetworkManagerTest(SleepHandshakeTest):
|
||||
ARGS = ["--with-netmanager"]
|
||||
|
||||
Reference in new issue
Block a user