Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -*- coding: utf-8 -*- 

2# This file is part of Xpra. 

3# Copyright (C) 2010-2020 Antoine Martin <antoine@xpra.org> 

4# Copyright (C) 2008 Nathaniel Smith <njs@pobox.com> 

5# Xpra is released under the terms of the GNU GPL v2, or, at your option, any 

6# later version. See the file COPYING for details. 

7 

8import os 

9 

10from xpra.server.mixins.stub_server_mixin import StubServerMixin 

11from xpra.log import Logger 

12 

13log = Logger("rpc") 

14dbuslog = Logger("dbus", "rpc") 

15 

16 

17""" 

18Mixin for servers that handle DBUS and RPC requests. 

19""" 

20class DBUS_RPC_Server(StubServerMixin): 

21 

22 def __init__(self): 

23 self.rpc_handlers = {} 

24 self.supports_dbus_proxy = False 

25 self.dbus_helper = None 

26 

27 def init(self, opts): 

28 self.supports_dbus_proxy = opts.dbus_proxy 

29 

30 def setup(self): 

31 self.init_dbus_helper() 

32 

33 

34 def get_server_features(self, _source=None): 

35 return { 

36 "dbus_proxy" : self.supports_dbus_proxy, 

37 "rpc-types" : tuple(self.rpc_handlers.keys()), 

38 } 

39 

40 

41 def get_info(self, _proto) -> dict: 

42 return {} 

43 

44 

45 def init_dbus_helper(self): 

46 if not self.supports_dbus_proxy: 

47 return 

48 try: 

49 from xpra.dbus.helper import DBusHelper 

50 self.dbus_helper = DBusHelper() 

51 self.rpc_handlers["dbus"] = self._handle_dbus_rpc 

52 except Exception as e: 

53 log("init_dbus_helper()", exc_info=True) 

54 log.warn("Warning: cannot load dbus helper:") 

55 for msg in str(e).split(": "): 

56 log.warn(" %s", msg) 

57 self.dbus_helper = None 

58 self.supports_dbus_proxy = False 

59 

60 

61 def make_dbus_server(self): 

62 from xpra.server.dbus.dbus_server import DBUS_Server 

63 return DBUS_Server(self, os.environ.get("DISPLAY", "").lstrip(":")) 

64 

65 def _handle_dbus_rpc(self, ss, rpcid, _, bus_name, path, interface, function, args, *_extra): 

66 assert self.supports_dbus_proxy, "server does not support dbus proxy calls" 

67 def native(args): 

68 return [self.dbus_helper.dbus_to_native(x) for x in (args or [])] 

69 def ok_back(*args): 

70 log("rpc: ok_back%s", args) 

71 ss.rpc_reply("dbus", rpcid, True, native(args)) 

72 def err_back(*args): 

73 log("rpc: err_back%s", args) 

74 ss.rpc_reply("dbus", rpcid, False, native(args)) 

75 self.dbus_helper.call_function(bus_name, path, interface, function, args, ok_back, err_back) 

76 

77 

78 def _process_rpc(self, proto, packet): 

79 if self.readonly: 

80 return 

81 ss = self.get_server_source(proto) 

82 assert ss is not None 

83 rpc_type = packet[1] 

84 rpcid = packet[2] 

85 handler = self.rpc_handlers.get(rpc_type) 

86 if not handler: 

87 log.error("Error: invalid rpc request of type '%s'", rpc_type) 

88 return 

89 log("rpc handler for %s: %s", rpc_type, handler) 

90 try: 

91 handler(ss, *packet[2:]) 

92 except Exception as e: 

93 log.error("Error: cannot call %s handler %s:", rpc_type, handler, exc_info=True) 

94 ss.rpc_reply(rpc_type, rpcid, False, str(e)) 

95 

96 

97 def init_packet_handlers(self): 

98 if self.supports_dbus_proxy: 

99 self.add_packet_handler("rpc", self._process_rpc)