]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/actions/session_manager.py
debian/control: add Depends on pipewire-pulse | pulseaudio
[waydroid.git] / tools / actions / session_manager.py
1 # Copyright 2021 Erfan Abdi
2 # SPDX-License-Identifier: GPL-3.0-or-later
3 import logging
4 import os
5 import signal
6 import sys
7 import tools.config
8 import tools.helpers.ipc
9 from tools import services
10 import dbus
11 import dbus.service
12 import dbus.exceptions
13 from gi.repository import GLib
14 import copy
15
16 class DbusSessionManager(dbus.service.Object):
17 def __init__(self, looper, bus, object_path, args):
18 self.args = args
19 self.looper = looper
20 dbus.service.Object.__init__(self, bus, object_path)
21
22 @dbus.service.method("id.waydro.SessionManager", in_signature='', out_signature='')
23 def Stop(self):
24 do_stop(self.args, self.looper)
25 stop_container(quit_session=False)
26
27 def handle_disconnect(args, looper):
28 do_stop(args, looper)
29 stop_container(quit_session=False)
30
31 def service(args, looper):
32 bus = dbus.SessionBus()
33 bus.set_exit_on_disconnect(False)
34 bus.add_signal_receiver(lambda: handle_disconnect(args, looper),
35 signal_name='Disconnected',
36 dbus_interface='org.freedesktop.DBus.Local')
37 dbus_obj = DbusSessionManager(looper, dbus.SessionBus(), '/SessionManager', args)
38 looper.run()
39
40 def start(args, unlocked_cb=None, background=True):
41 try:
42 name = dbus.service.BusName("id.waydro.Session", dbus.SessionBus(), do_not_queue=True)
43 except dbus.exceptions.NameExistsException:
44 logging.error("Session is already running")
45 if unlocked_cb:
46 unlocked_cb()
47 return
48
49 session = copy.copy(tools.config.session_defaults)
50
51 # TODO: also support WAYLAND_SOCKET?
52 wayland_display = session["wayland_display"]
53 if wayland_display == "None" or not wayland_display:
54 logging.warning('WAYLAND_DISPLAY is not set, defaulting to "wayland-0"')
55 wayland_display = session["wayland_display"] = "wayland-0"
56
57 if os.path.isabs(wayland_display):
58 wayland_socket_path = wayland_display
59 else:
60 xdg_runtime_dir = session["xdg_runtime_dir"]
61 if xdg_runtime_dir == "None" or not xdg_runtime_dir:
62 logging.error(f"XDG_RUNTIME_DIR is not set; please don't start a Waydroid session with 'sudo'!")
63 sys.exit(1)
64 wayland_socket_path = os.path.join(xdg_runtime_dir, wayland_display)
65 if not os.path.exists(wayland_socket_path):
66 logging.error(f"Wayland socket '{wayland_socket_path}' doesn't exist; are you running a Wayland compositor?")
67 sys.exit(1)
68
69 waydroid_data = session["waydroid_data"]
70 if not os.path.isdir(waydroid_data):
71 os.makedirs(waydroid_data)
72
73 dpi = tools.helpers.props.host_get(args, "ro.sf.lcd_density")
74 if dpi == "":
75 dpi = os.getenv("GRID_UNIT_PX")
76 if dpi is not None:
77 dpi = str(int(dpi) * 20)
78 else:
79 dpi = "0"
80 session["lcd_density"] = dpi
81
82 session["background_start"] = "true" if background else "false"
83
84 mainloop = GLib.MainLoop()
85
86 def sigint_handler(data):
87 do_stop(args, mainloop)
88 stop_container(quit_session=False)
89
90 def sigusr_handler(data):
91 do_stop(args, mainloop)
92
93 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGHUP, sigint_handler, None)
94 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGINT, sigint_handler, None)
95 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGTERM, sigint_handler, None)
96 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGUSR1, sigusr_handler, None)
97 try:
98 tools.helpers.ipc.DBusContainerService().Start(session)
99 except dbus.DBusException as e:
100 logging.debug(e)
101 if e.get_dbus_name().startswith("org.freedesktop.DBus.Python"):
102 logging.error(e.get_dbus_message().splitlines()[-1])
103 else:
104 logging.error("WayDroid container is not listening")
105 sys.exit(0)
106
107 services.user_manager.start(args, session, unlocked_cb)
108 services.clipboard_manager.start(args)
109 service(args, mainloop)
110
111 def do_stop(args, looper):
112 services.user_manager.stop(args)
113 services.clipboard_manager.stop(args)
114 looper.quit()
115
116 def stop(args):
117 try:
118 tools.helpers.ipc.DBusSessionService().Stop()
119 except dbus.DBusException:
120 stop_container(quit_session=True)
121
122 def stop_container(quit_session):
123 try:
124 tools.helpers.ipc.DBusContainerService().Stop(quit_session)
125 except dbus.DBusException:
126 pass