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