mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 02:51:10 +00:00
perf: the session's background watchers share two loops and one D-Bus service process (#575)
This commit is contained in:
1 parent
a0d3e03ca0
commit
7ea4efef98
4 files changed
+172
-137
No files matched your search
@@ -5,6 +5,8 @@ Android owns device power. Suspend here pauses the guest through SessionService;
|
||||
the app's Resume action thaws it and completes PrepareForSleep(false). Steam
|
||||
must see this service before startup or it can stay black after its idle timer.
|
||||
"""
|
||||
import importlib.machinery
|
||||
import importlib.util
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
@@ -193,6 +195,15 @@ class LoginManager:
|
||||
self.notify(False)
|
||||
|
||||
|
||||
def load_netmanager():
|
||||
path = Path(__file__).resolve().with_name("droiddeck-netmanager")
|
||||
loader = importlib.machinery.SourceFileLoader("droiddeck_netmanager", str(path))
|
||||
spec = importlib.util.spec_from_loader(loader.name, loader)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
def main():
|
||||
directory = os.environ.get("BL_LAUNCH_DIR")
|
||||
if not directory or not Path(directory).is_dir():
|
||||
@@ -218,6 +229,8 @@ def main():
|
||||
|
||||
owners = [Gio.bus_own_name(Gio.BusType.SYSTEM, name, Gio.BusNameOwnerFlags.NONE, connected, acquired, lost)
|
||||
for name in (NAME, UPOWER)]
|
||||
if "--with-netmanager" in sys.argv[1:]:
|
||||
owners.append(load_netmanager().own(loop))
|
||||
try:
|
||||
loop.run()
|
||||
finally:
|
||||
|
||||
@@ -408,8 +408,7 @@ class NetworkManager:
|
||||
self.bus.emit_signal(None, path, OBJECT_MANAGER, signal, body)
|
||||
|
||||
|
||||
def main():
|
||||
loop = GLib.MainLoop()
|
||||
def own(loop):
|
||||
state = {}
|
||||
|
||||
def acquired(bus, name):
|
||||
@@ -419,7 +418,12 @@ def main():
|
||||
print("== netmanager: the system bus is gone", file=sys.stderr)
|
||||
loop.quit()
|
||||
|
||||
Gio.bus_own_name(Gio.BusType.SYSTEM, NAME, Gio.BusNameOwnerFlags.NONE, acquired, None, lost)
|
||||
return Gio.bus_own_name(Gio.BusType.SYSTEM, NAME, Gio.BusNameOwnerFlags.NONE, acquired, None, lost)
|
||||
|
||||
|
||||
def main():
|
||||
loop = GLib.MainLoop()
|
||||
own(loop)
|
||||
loop.run()
|
||||
|
||||
|
||||
|
||||
@@ -328,23 +328,6 @@ case $mode in
|
||||
fi
|
||||
if [ -n "${BL_CLIENT_CPUS:-}" ]; then
|
||||
step "client cores: $BL_CLIENT_CPUS"
|
||||
(
|
||||
declare -A _bl_pinned=()
|
||||
for ((_i = 0; _i < 720; _i++)); do
|
||||
for _d in /proc/[0-9]*; do
|
||||
IFS= read -r -d '' _c < "$_d/cmdline" 2>/dev/null || continue
|
||||
case $_c in *steamwebhelper*|*steamrtarm64/steam|*gamescope*) ;; *) continue ;; esac
|
||||
_t=("$_d"/task/*)
|
||||
_p=${_d#/proc/}
|
||||
if [ "${_bl_pinned[$_p]:-}" = "${#_t[@]}" ] && client_single_core_matches "$BL_CLIENT_CPUS" "${_t[@]}"; then
|
||||
continue
|
||||
fi
|
||||
taskset -a -cp "$BL_CLIENT_CPUS" "$_p" >/dev/null 2>&1 || true
|
||||
_bl_pinned[$_p]=${#_t[@]}
|
||||
done
|
||||
nap 5
|
||||
done
|
||||
) &
|
||||
fi
|
||||
if [ "${BL_ZRAM:-0}" = 1 ]; then
|
||||
printf 0 > /tmp/.bl-zram
|
||||
@@ -459,105 +442,50 @@ case $mode in
|
||||
) &
|
||||
fi
|
||||
fi
|
||||
[ -z "${BL_DESKTOP:-}" ] && [ "${BL_STRETCHED:-0}" = 1 ] && (
|
||||
while :; do
|
||||
nap 1
|
||||
cur=$(xprop -root GAMESCOPE_NEW_SCALING_SCALER 2>/dev/null) || continue
|
||||
case $cur in *" = "*) cur=${cur##* = } ;; *) cur=0 ;; esac
|
||||
[ "$cur" = 0 ] || continue
|
||||
xprop -root -f GAMESCOPE_NEW_SCALING_SCALER 32c -set GAMESCOPE_NEW_SCALING_SCALER 4 2>/dev/null \
|
||||
&& echo "== stretch 16:9 to panel: the client's scaler was Auto, set to Stretch"
|
||||
done
|
||||
) &
|
||||
[ -z "${BL_DESKTOP:-}" ] && [ "${BL_RESTORE_ON_RESUME:-1}" = 1 ] && (
|
||||
prev=
|
||||
xprop -spy -root GAMESCOPE_FOCUSED_APP 2>/dev/null | while read -r line; do
|
||||
app=${line##*= }
|
||||
case $app in ''|*[!0-9]*) prev=; continue ;; esac
|
||||
if [ "$prev" = 769 ] && [ "$app" != 769 ]; then
|
||||
nap 1
|
||||
bl_xprop_set_all GAMESCOPE_RESTORE_FOCUS_WINDOW 1 \
|
||||
&& echo "== resume: asked gamescope to restore the game window (app $app)"
|
||||
fi
|
||||
prev=$app
|
||||
done
|
||||
) &
|
||||
[ -z "${BL_DESKTOP:-}" ] && (
|
||||
xprop_value() {
|
||||
case $1 in *'not found'*|*=) echo "$2"; return ;; esac
|
||||
local v=${1#*=}
|
||||
v=${v# }
|
||||
echo "${v:-$2}"
|
||||
stretch=0 restore=0
|
||||
[ "${BL_STRETCHED:-0}" = 1 ] && stretch=1
|
||||
[ "${BL_RESTORE_ON_RESUME:-1}" = 1 ] && restore=1
|
||||
atoms=(STEAM_TOUCH_CLICK_MODE GAMESCOPE_FOCUSED_APP)
|
||||
[ "$stretch" = 1 ] && atoms+=(GAMESCOPE_NEW_SCALING_SCALER)
|
||||
prop_value() {
|
||||
case $1 in *'not found'*|*=) pv=$2; return ;; esac
|
||||
pv=${1#*=}
|
||||
pv=${pv# }
|
||||
pv=${pv:-$2}
|
||||
}
|
||||
tmode= app=
|
||||
xprop -spy -root STEAM_TOUCH_CLICK_MODE GAMESCOPE_FOCUSED_APP 2>/dev/null | while read -r line; do
|
||||
tmode= app= prev=
|
||||
while read -r line; do
|
||||
case $line in
|
||||
STEAM_TOUCH_CLICK_MODE*)
|
||||
v=$(xprop_value "$line" unset)
|
||||
[ "$v" = "$tmode" ] && continue
|
||||
tmode=$v
|
||||
prop_value "$line" unset
|
||||
[ "$pv" = "$tmode" ] && continue
|
||||
tmode=$pv
|
||||
echo "== touch mode: $tmode (focused app ${app:-?}) at $(date +%T)"
|
||||
;;
|
||||
GAMESCOPE_FOCUSED_APP*)
|
||||
v=$(xprop_value "$line" none)
|
||||
[ "$v" = "$app" ] && continue
|
||||
app=$v
|
||||
echo "== focused app: $app (touch mode ${tmode:-unset}) at $(date +%T)"
|
||||
prop_value "$line" none
|
||||
if [ "$pv" != "$app" ]; then
|
||||
app=$pv
|
||||
echo "== focused app: $app (touch mode ${tmode:-unset}) at $(date +%T)"
|
||||
fi
|
||||
[ "$restore" = 1 ] || continue
|
||||
case $pv in ''|*[!0-9]*) prev=; continue ;; esac
|
||||
if [ "$prev" = 769 ] && [ "$pv" != 769 ]; then
|
||||
nap 1
|
||||
bl_xprop_set_all GAMESCOPE_RESTORE_FOCUS_WINDOW 1 \
|
||||
&& echo "== resume: asked gamescope to restore the game window (app $pv)"
|
||||
fi
|
||||
prev=$pv
|
||||
;;
|
||||
GAMESCOPE_NEW_SCALING_SCALER*)
|
||||
prop_value "$line" 0
|
||||
[ "$pv" = 0 ] || continue
|
||||
xprop -root -f GAMESCOPE_NEW_SCALING_SCALER 32c -set GAMESCOPE_NEW_SCALING_SCALER 4 2>/dev/null \
|
||||
&& echo "== stretch 16:9 to panel: the client's scaler was Auto, set to Stretch"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
) &
|
||||
(
|
||||
beat=0
|
||||
compat_stamp=$HOME/.bl-compat-beat
|
||||
seed_stamp=$HOME/.bl-seed-beat
|
||||
rm -f "$compat_stamp" "$seed_stamp"
|
||||
changed_since() {
|
||||
local d
|
||||
for d in "${@:2}"; do
|
||||
[ "$d" -nt "$1" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
compat_due() {
|
||||
[ -e "$compat_stamp" ] && [ "$((beat % 60))" -ne 0 ] || return 0
|
||||
changed_since "$compat_stamp" "${libraries[@]}" "$steam_root/steamapps/common" "$steam_root/config" \
|
||||
"$steam_root/compatibilitytools.d"
|
||||
}
|
||||
seed_due() {
|
||||
local reg
|
||||
[ -e "$seed_stamp" ] && [ "$((beat % 60))" -ne 0 ] || return 0
|
||||
changed_since "$seed_stamp" "${libraries[@]}" && return 0
|
||||
for reg in "$steam_root"/steamapps/common/Proton*/files/share/default_pfx*/system.reg \
|
||||
/mnt/droiddeck-sd/steamapps/common/Proton*/files/share/default_pfx*/system.reg \
|
||||
/root/Games/*/steamapps/common/Proton*/files/share/default_pfx*/system.reg \
|
||||
"$steam_root"/compatibilitytools.d/*/files/share/default_pfx*/system.reg \
|
||||
"$steam_root"/steamapps/compatdata/*/pfx/system.reg \
|
||||
/mnt/droiddeck-sd/steamapps/compatdata/*/pfx/system.reg \
|
||||
/root/Games/*/steamapps/compatdata/*/pfx/system.reg; do
|
||||
[ -f "$reg" ] && [ ! -f "${reg%/*}/.droiddeck-redists" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
for ((_i = 0; _i < 720; _i++)); do
|
||||
nap 5
|
||||
beat=$((beat + 1))
|
||||
[ "$((beat % 3))" -eq 0 ] || continue
|
||||
libraries=("$steam_root/steamapps" /mnt/droiddeck/steamapps /mnt/droiddeck-sd/steamapps /root/Games/*/steamapps)
|
||||
seed=; compat=
|
||||
seed_due && seed=1
|
||||
compat_due && compat=1
|
||||
[ -n "$seed$compat" ] || continue
|
||||
pgrep -x wineserver >/dev/null 2>&1 && continue
|
||||
if [ -n "$seed" ]; then
|
||||
: > "$seed_stamp"
|
||||
droiddeck-seed-redists "$steam_root" >/dev/null 2>&1 || true
|
||||
fi
|
||||
if [ -n "$compat" ]; then
|
||||
: > "$compat_stamp"
|
||||
steam-compatibility "$steam_root" >/dev/null 2>&1 || true
|
||||
fi
|
||||
done
|
||||
done < <(xprop -spy -root "${atoms[@]}" 2>/dev/null)
|
||||
) &
|
||||
if [ -n "${BL_LAUNCH_DIR:-}" ] && [ -z "${BL_DESKTOP:-}" ]; then
|
||||
_bl_held=
|
||||
@@ -630,11 +558,9 @@ BUSCONF
|
||||
sleep 0.1
|
||||
done
|
||||
if [ -S /run/dbus/system_bus_socket ]; then
|
||||
droiddeck-netmanager &
|
||||
netmanager=$!
|
||||
echo "== network: system bus up, NetworkManager stand-in running"
|
||||
rm -f "$BL_LAUNCH_DIR/steam-sleep-ready"
|
||||
droiddeck-login1 &
|
||||
droiddeck-login1 --with-netmanager &
|
||||
login_manager=$!
|
||||
for ((_i = 0; _i < 50; _i++)); do
|
||||
[ -f "$BL_LAUNCH_DIR/steam-sleep-ready" ] && break
|
||||
@@ -739,22 +665,6 @@ BUSCONF
|
||||
droiddeck-steam-games watch "$steam_root" "$BL_ADDED_GAMES" &
|
||||
games_watcher=$!
|
||||
fi
|
||||
if [ "${BL_LOSSLESS_OWNED:-0}" != 1 ]; then
|
||||
(
|
||||
owned=$HOME/.config/droiddeck/lossless-owned
|
||||
for ((_i = 0; _i < 60; _i++)); do
|
||||
nap 30
|
||||
[ -e "$owned" ] && exit 0
|
||||
pgrep -x wineserver >/dev/null 2>&1 && continue
|
||||
answer=$(droiddeck-steam-games probe "$steam_root" 993090 2>/dev/null) || continue
|
||||
case $answer in
|
||||
*'"993090": true'*) mkdir -p "${owned%/*}" && : > "$owned" && echo "== Lossless Scaling: owned" ;;
|
||||
*) echo "== Lossless Scaling: not owned by this account" ;;
|
||||
esac
|
||||
exit 0
|
||||
done
|
||||
) &
|
||||
fi
|
||||
echo "== steam args: ${_bl_ui[*]} ${_bl_cdp[*]} ${_bl_lang[*]} -clientbeta $steam_channel -no-cef-sandbox -cef-ozone-platform=x11 ${_bl_cef[*]} $*"
|
||||
steam_updates=0
|
||||
rm -f "$HOME/.bl-stop-requested" "$STEAMOS_STEAM_SHUTDOWN_SENTINEL" "$STEAMOS_STEAM_REBOOT_SENTINEL"
|
||||
@@ -781,10 +691,54 @@ BUSCONF
|
||||
return 0
|
||||
done
|
||||
}
|
||||
requests=
|
||||
if [ -n "${BL_LAUNCH_DIR:-}" ] && [ -d "$BL_LAUNCH_DIR" ]; then
|
||||
rm -f "$BL_LAUNCH_DIR/steam-stop" "$BL_LAUNCH_DIR/steam-game" "$BL_LAUNCH_DIR/steam-game.tmp"
|
||||
(
|
||||
while :; do
|
||||
requests=1
|
||||
fi
|
||||
(
|
||||
tick=0
|
||||
beat=0
|
||||
library_job=
|
||||
lossless_job=
|
||||
lossless_left=0
|
||||
lossless_owned=$HOME/.config/droiddeck/lossless-owned
|
||||
lossless_asked=$HOME/.bl-lossless-asked
|
||||
rm -f "$lossless_asked"
|
||||
[ "${BL_LOSSLESS_OWNED:-0}" != 1 ] && lossless_left=60
|
||||
declare -A _bl_pinned=()
|
||||
compat_stamp=$HOME/.bl-compat-beat
|
||||
seed_stamp=$HOME/.bl-seed-beat
|
||||
rm -f "$compat_stamp" "$seed_stamp"
|
||||
changed_since() {
|
||||
local d
|
||||
for d in "${@:2}"; do
|
||||
[ "$d" -nt "$1" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
compat_due() {
|
||||
[ -e "$compat_stamp" ] && [ "$((beat % 60))" -ne 0 ] || return 0
|
||||
changed_since "$compat_stamp" "${libraries[@]}" "$steam_root/steamapps/common" "$steam_root/config" \
|
||||
"$steam_root/compatibilitytools.d"
|
||||
}
|
||||
seed_due() {
|
||||
local reg
|
||||
[ -e "$seed_stamp" ] && [ "$((beat % 60))" -ne 0 ] || return 0
|
||||
changed_since "$seed_stamp" "${libraries[@]}" && return 0
|
||||
for reg in "$steam_root"/steamapps/common/Proton*/files/share/default_pfx*/system.reg \
|
||||
/mnt/droiddeck-sd/steamapps/common/Proton*/files/share/default_pfx*/system.reg \
|
||||
/root/Games/*/steamapps/common/Proton*/files/share/default_pfx*/system.reg \
|
||||
"$steam_root"/compatibilitytools.d/*/files/share/default_pfx*/system.reg \
|
||||
"$steam_root"/steamapps/compatdata/*/pfx/system.reg \
|
||||
/mnt/droiddeck-sd/steamapps/compatdata/*/pfx/system.reg \
|
||||
/root/Games/*/steamapps/compatdata/*/pfx/system.reg; do
|
||||
[ -f "$reg" ] && [ ! -f "${reg%/*}/.droiddeck-redists" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
while :; do
|
||||
if [ -n "$requests" ]; then
|
||||
if [ -e "$BL_LAUNCH_DIR/steam-stop" ]; then
|
||||
rm -f "$BL_LAUNCH_DIR/steam-stop"
|
||||
: > "$HOME/.bl-stop-requested"
|
||||
@@ -813,11 +767,56 @@ BUSCONF
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
nap 0.5
|
||||
done
|
||||
) &
|
||||
stop_watcher=$!
|
||||
fi
|
||||
fi
|
||||
nap 0.5
|
||||
tick=$((tick + 1))
|
||||
[ "$((tick % 10))" -eq 0 ] || continue
|
||||
beat=$((beat + 1))
|
||||
if [ "$beat" -le 720 ] && [ -n "${BL_CLIENT_CPUS:-}" ]; then
|
||||
for _d in /proc/[0-9]*; do
|
||||
IFS= read -r -d '' _c < "$_d/cmdline" 2>/dev/null || continue
|
||||
case $_c in *steamwebhelper*|*steamrtarm64/steam|*gamescope*) ;; *) continue ;; esac
|
||||
_t=("$_d"/task/*)
|
||||
_p=${_d#/proc/}
|
||||
[ "${_bl_pinned[$_p]:-}" = "${#_t[@]}" ] && client_single_core_matches "$BL_CLIENT_CPUS" "${_t[@]}" && continue
|
||||
taskset -a -cp "$BL_CLIENT_CPUS" "$_p" >/dev/null 2>&1 || true
|
||||
_bl_pinned[$_p]=${#_t[@]}
|
||||
done
|
||||
fi
|
||||
if [ "$beat" -le 720 ] && [ "$((beat % 3))" -eq 0 ] && { [ -z "$library_job" ] || ! kill -0 "$library_job" 2>/dev/null; }; then
|
||||
libraries=("$steam_root/steamapps" /mnt/droiddeck/steamapps /mnt/droiddeck-sd/steamapps /root/Games/*/steamapps)
|
||||
seed=; compat=
|
||||
seed_due && seed=1
|
||||
compat_due && compat=1
|
||||
if [ -n "$seed$compat" ] && ! pgrep -x wineserver >/dev/null 2>&1; then
|
||||
[ -n "$seed" ] && : > "$seed_stamp"
|
||||
[ -n "$compat" ] && : > "$compat_stamp"
|
||||
(
|
||||
[ -z "$seed" ] || droiddeck-seed-redists "$steam_root" >/dev/null 2>&1 || true
|
||||
[ -z "$compat" ] || steam-compatibility "$steam_root" >/dev/null 2>&1 || true
|
||||
) &
|
||||
library_job=$!
|
||||
fi
|
||||
fi
|
||||
if [ "$lossless_left" -gt 0 ] && [ "$((beat % 6))" -eq 0 ] && { [ -z "$lossless_job" ] || ! kill -0 "$lossless_job" 2>/dev/null; }; then
|
||||
lossless_left=$((lossless_left - 1))
|
||||
if [ -e "$lossless_owned" ] || [ -e "$lossless_asked" ]; then
|
||||
lossless_left=0
|
||||
elif ! pgrep -x wineserver >/dev/null 2>&1; then
|
||||
(
|
||||
answer=$(droiddeck-steam-games probe "$steam_root" 993090 2>/dev/null) || exit 0
|
||||
case $answer in
|
||||
*'"993090": true'*) mkdir -p "${lossless_owned%/*}" && : > "$lossless_owned" && echo "== Lossless Scaling: owned" ;;
|
||||
*) echo "== Lossless Scaling: not owned by this account" ;;
|
||||
esac
|
||||
: > "$lossless_asked"
|
||||
) &
|
||||
lossless_job=$!
|
||||
fi
|
||||
fi
|
||||
done
|
||||
) &
|
||||
stop_watcher=$!
|
||||
while :; do
|
||||
rm -f "$HOME/.bl-restart-once"
|
||||
if [ -f "$steam_beta" ] && [ "$(cat "$steam_beta" 2>/dev/null)" != "$steam_channel" ]; then
|
||||
|
||||
@@ -22,6 +22,8 @@ IFACE = NAME + ".Manager"
|
||||
|
||||
@unittest.skipUnless(Gio and os.environ.get("DBUS_SESSION_BUS_ADDRESS"), "requires dbus-run-session and PyGObject")
|
||||
class SleepHandshakeTest(unittest.TestCase):
|
||||
ARGS = []
|
||||
|
||||
def setUp(self):
|
||||
self.directory = tempfile.TemporaryDirectory()
|
||||
self.dir = Path(self.directory.name)
|
||||
@@ -35,7 +37,7 @@ class SleepHandshakeTest(unittest.TestCase):
|
||||
lambda bus, sender, path, interface, name, body: self.signals.append(body.unpack()[0]))
|
||||
env = dict(os.environ, BL_LAUNCH_DIR=str(self.dir),
|
||||
DBUS_SYSTEM_BUS_ADDRESS=os.environ["DBUS_SESSION_BUS_ADDRESS"])
|
||||
self.process = subprocess.Popen(["/usr/bin/python3", str(SCRIPT)], env=env,
|
||||
self.process = subprocess.Popen(["/usr/bin/python3", str(SCRIPT), *self.ARGS], env=env,
|
||||
stdout=subprocess.DEVNULL)
|
||||
self.wait_for(lambda: (self.dir / "steam-sleep-ready").exists())
|
||||
|
||||
@@ -218,5 +220,22 @@ class SleepHandshakeTest(unittest.TestCase):
|
||||
self.call(IFACE, "PowerOff", GLib.Variant("(b)", (True,)))
|
||||
|
||||
|
||||
class WithNetworkManagerTest(SleepHandshakeTest):
|
||||
ARGS = ["--with-netmanager"]
|
||||
|
||||
def owner(self, name):
|
||||
return self.bus.call_sync("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
|
||||
"GetConnectionUnixProcessID", GLib.Variant("(s)", (name,)), None,
|
||||
Gio.DBusCallFlags.NONE, 2000, None).unpack()[0]
|
||||
|
||||
def test_one_process_owns_login1_and_networkmanager(self):
|
||||
self.wait_for(lambda: self.bus.call_sync(
|
||||
"org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameHasOwner",
|
||||
GLib.Variant("(s)", ("org.freedesktop.NetworkManager",)), None,
|
||||
Gio.DBusCallFlags.NONE, 2000, None).unpack()[0])
|
||||
self.assertEqual(self.owner("org.freedesktop.NetworkManager"), self.process.pid)
|
||||
self.assertEqual(self.owner(NAME), self.process.pid)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user