Ticket #2351: skip-clientconnection-mixins.patch
File skip-clientconnection-mixins.patch, 15.7 KB (added by , 16 months ago) |
---|
-
xpra/server/server_base.py
396 396 send_ui = ui_client and not is_request 397 397 self.idle_add(self._process_hello_ui, ss, c, auth_caps, send_ui, share_count) 398 398 399 def get_client_connection_class(self, _caps):400 from xpra.server.source.client_connection import ClientConnection401 return ClientConnection399 def get_client_connection_class(self, caps): 400 from xpra.server.source.client_connection_factory import get_client_connection_class 401 return get_client_connection_class(caps) 402 402 403 403 404 404 def _process_hello_ui(self, ss, c, auth_caps, send_ui, share_count): -
xpra/server/source/client_connection.py
13 13 14 14 from xpra.make_thread import start_thread 15 15 from xpra.os_util import monotonic_time 16 from xpra.util import merge_dicts,notypedict, envbool, envint, typedict, AtomicInteger16 from xpra.util import notypedict, envbool, envint, typedict, AtomicInteger 17 17 from xpra.net.compression import compressed_wrapper, Compressed 18 from xpra.server.source.stub_source_mixin import StubSourceMixin 18 19 from xpra.server.source.source_stats import GlobalPerformanceStatistics 19 from xpra.server.source.clientinfo_mixin import ClientInfoMixin20 from xpra.server import server_features21 20 from xpra.log import Logger 22 21 23 CC_BASES = [ClientInfoMixin]24 #TODO: notifications mixin25 if server_features.clipboard:26 from xpra.server.source.clipboard_connection import ClipboardConnection27 CC_BASES.append(ClipboardConnection)28 if server_features.audio:29 from xpra.server.source.audio_mixin import AudioMixin30 CC_BASES.append(AudioMixin)31 if server_features.webcam:32 from xpra.server.source.webcam_mixin import WebcamMixin33 CC_BASES.append(WebcamMixin)34 if server_features.fileprint:35 from xpra.server.source.fileprint_mixin import FilePrintMixin36 CC_BASES.append(FilePrintMixin)37 if server_features.mmap:38 from xpra.server.source.mmap_connection import MMAP_Connection39 CC_BASES.append(MMAP_Connection)40 if server_features.input_devices:41 from xpra.server.source.input_mixin import InputMixin42 CC_BASES.append(InputMixin)43 if server_features.dbus:44 from xpra.server.source.dbus_mixin import DBUS_Mixin45 CC_BASES.append(DBUS_Mixin)46 if server_features.network_state:47 from xpra.server.source.networkstate_mixin import NetworkStateMixin48 CC_BASES.append(NetworkStateMixin)49 if server_features.display:50 from xpra.server.source.clientdisplay_mixin import ClientDisplayMixin51 CC_BASES.append(ClientDisplayMixin)52 if server_features.windows:53 from xpra.server.source.windows_mixin import WindowsMixin54 CC_BASES.append(WindowsMixin)55 #must be after windows mixin so it can assume "self.send_windows" is set56 if server_features.encoding:57 from xpra.server.source.encodings_mixin import EncodingsMixin58 CC_BASES.append(EncodingsMixin)59 if server_features.audio and server_features.av_sync:60 from xpra.server.source.avsync_mixin import AVSyncMixin61 CC_BASES.append(AVSyncMixin)62 from xpra.server.source.idle_mixin import IdleMixin63 CC_BASES.append(IdleMixin)64 CC_BASES = tuple(CC_BASES)65 ClientConnectionClass = type('ClientConnectionClass', CC_BASES, {})66 67 22 log = Logger("server") 68 23 elog = Logger("encoding") 69 24 proxylog = Logger("proxy") … … 70 25 notifylog = Logger("notify") 71 26 bandwidthlog = Logger("bandwidth") 72 27 73 log("ClientConnectionClass%s", CC_BASES)74 28 75 76 29 BANDWIDTH_DETECTION = envbool("XPRA_BANDWIDTH_DETECTION", True) 77 30 MIN_BANDWIDTH = envint("XPRA_MIN_BANDWIDTH", 5*1024*1024) 78 31 AUTO_BANDWIDTH_PCT = envint("XPRA_AUTO_BANDWIDTH_PCT", 80) … … 100 53 and added to the damage_packet_queue. 101 54 """ 102 55 103 class ClientConnection( ClientConnectionClass):56 class ClientConnection(StubSourceMixin): 104 57 105 58 def __init__(self, protocol, disconnect_cb, session_name, server, 106 idle_add, timeout_add, source_remove,107 59 setting_changed, 108 60 socket_dir, unix_socket_paths, log_disconnect, bandwidth_limit, bandwidth_detection, 109 61 ): … … 115 67 self.disconnect = disconnect_cb 116 68 self.session_name = session_name 117 69 118 for bc in CC_BASES: 119 try: 120 bc.__init__(self) 121 bc.init_from(self, protocol, server) 122 except Exception as e: 123 raise Exception("failed to initialize %s: %s" % (bc, e)) from None 70 self.socket_dir = socket_dir 71 self.unix_socket_paths = unix_socket_paths 72 self.log_disconnect = log_disconnect 124 73 125 for c in CC_BASES: 126 c.init_state(self) 74 self.setting_changed = setting_changed 75 # network constraints: 76 self.server_bandwidth_limit = bandwidth_limit 77 self.bandwidth_detection = bandwidth_detection 127 78 79 def init_state(self): 128 80 #holds actual packets ready for sending (already encoded) 129 81 #these packets are picked off by the "protocol" via 'next_packet()' 130 82 #format: packet, wid, pixels, start_send_cb, end_send_cb … … 138 90 self.encode_work_queue = None 139 91 self.encode_thread = None 140 92 self.ordinary_packets = [] 141 self.socket_dir = socket_dir142 self.unix_socket_paths = unix_socket_paths143 self.log_disconnect = log_disconnect144 self.idle_add = idle_add145 self.timeout_add = timeout_add146 self.source_remove = source_remove147 93 148 self.setting_changed = setting_changed149 # network constraints:150 self.server_bandwidth_limit = bandwidth_limit151 self.bandwidth_detection = bandwidth_detection152 153 94 #these statistics are shared by all WindowSource instances: 154 95 self.statistics = GlobalPerformanceStatistics() 155 96 … … 157 98 158 99 # ready for processing: 159 100 self.queue_encode = self.start_queue_encode 160 protocol.set_packet_source(self.next_packet)101 self.protocol.set_packet_source(self.next_packet) 161 102 162 103 163 104 def __repr__(self): … … 191 132 def is_closed(self): 192 133 return self.close_event.isSet() 193 134 194 def close(self): 195 log("%s.close()", self) 196 for c in CC_BASES: 197 c.cleanup(self) 135 def cleanup(self): 198 136 self.close_event.set() 199 137 self.protocol = None 200 138 … … 254 192 ws.bandwidth_limit = max(MIN_BANDWIDTH//10, bandwidth_limit*weight//total_weight) 255 193 256 194 257 def parse_hello(self, c): 258 self.ui_client = c.boolget("ui_client", True) 259 self.wants_encodings = c.boolget("wants_encodings", self.ui_client) 260 self.wants_display = c.boolget("wants_display", self.ui_client) 261 self.wants_events = c.boolget("wants_events", False) 262 self.wants_aliases = c.boolget("wants_aliases", True) 263 self.wants_versions = c.boolget("wants_versions", True) 264 self.wants_features = c.boolget("wants_features", True) 265 self.wants_default_cursor = c.boolget("wants_default_cursor", False) 266 267 for mixin in CC_BASES: 268 mixin.parse_client_caps(self, c) 269 195 def parse_client_caps(self, c): 270 196 #general features: 271 197 self.info_namespace = c.boolget("info-namespace") 272 198 self.send_notifications = c.boolget("notifications") … … 430 356 self.send(*parts, **kwargs) 431 357 432 358 433 def send_hello(self, server_capabilities):434 capabilities = server_capabilities.copy()435 for bc in CC_BASES:436 merge_dicts(capabilities, bc.get_caps(self))437 self.send("hello", capabilities)438 self.hello_sent = True439 440 441 359 ###################################################################### 442 360 # info: 443 361 def get_info(self) -> dict: … … 459 377 "connection" : p.get_info(), 460 378 }) 461 379 info.update(self.get_features_info()) 462 for bc in CC_BASES:463 try:464 merge_dicts(info, bc.get_info(self))465 except Exception as e:466 log("merge_dicts on %s", bc, exc_info=True)467 log.error("Error: cannot add information from %s:", bc)468 log.error(" %s", e)469 380 return info 470 381 471 382 def get_features_info(self) -> dict: -
xpra/server/source/client_connection_factory.py
1 # -*- coding: utf-8 -*- 2 # This file is part of Xpra. 3 # Copyright (C) 2010-2020 Antoine Martin <antoine@xpra.org> 4 # Xpra is released under the terms of the GNU GPL v2, or, at your option, any 5 # later version. See the file COPYING for details. 6 7 from xpra.server import server_features 8 from xpra.util import merge_dicts 9 10 11 def get_client_connection_class(caps): 12 from xpra.server.source.client_connection import ClientConnection 13 CC = [ClientConnection] 14 from xpra.server.source.clientinfo_mixin import ClientInfoMixin 15 CC.append(ClientInfoMixin) 16 #TODO: notifications mixin 17 if server_features.clipboard: 18 from xpra.server.source.clipboard_connection import ClipboardConnection 19 CC.append(ClipboardConnection) 20 if server_features.audio: 21 from xpra.server.source.audio_mixin import AudioMixin 22 CC.append(AudioMixin) 23 if server_features.webcam: 24 from xpra.server.source.webcam_mixin import WebcamMixin 25 CC.append(WebcamMixin) 26 if server_features.fileprint: 27 from xpra.server.source.fileprint_mixin import FilePrintMixin 28 CC.append(FilePrintMixin) 29 if server_features.mmap: 30 from xpra.server.source.mmap_connection import MMAP_Connection 31 CC.append(MMAP_Connection) 32 if server_features.input_devices: 33 from xpra.server.source.input_mixin import InputMixin 34 CC.append(InputMixin) 35 if server_features.dbus: 36 from xpra.server.source.dbus_mixin import DBUS_Mixin 37 CC.append(DBUS_Mixin) 38 if server_features.network_state: 39 from xpra.server.source.networkstate_mixin import NetworkStateMixin 40 CC.append(NetworkStateMixin) 41 if server_features.display: 42 from xpra.server.source.clientdisplay_mixin import ClientDisplayMixin 43 CC.append(ClientDisplayMixin) 44 if server_features.windows: 45 from xpra.server.source.windows_mixin import WindowsMixin 46 CC.append(WindowsMixin) 47 #must be after windows mixin so it can assume "self.send_windows" is set 48 if server_features.encoding: 49 from xpra.server.source.encodings_mixin import EncodingsMixin 50 CC.append(EncodingsMixin) 51 if server_features.audio and server_features.av_sync: 52 from xpra.server.source.avsync_mixin import AVSyncMixin 53 CC.append(AVSyncMixin) 54 from xpra.server.source.idle_mixin import IdleMixin 55 CC.append(IdleMixin) 56 57 from xpra.log import Logger 58 log = Logger("server") 59 NEEDED_CC_BASES = [] 60 for c in CC: 61 r = c.is_needed(caps) 62 log("%s.is_needed()=%s", c, r) 63 if r: 64 NEEDED_CC_BASES.append(c) 65 CC_BASES = tuple(CC) 66 ClientConnectionClass = type('ClientConnectionClass', CC_BASES, {}) 67 log("get_client_connection_class(..)=%s for base classes %s", 68 ClientConnectionClass, CC_BASES) 69 70 class ClientConnectionMuxer(ClientConnectionClass): 71 72 def __init__(self, protocol, disconnect_cb, session_name, server, 73 idle_add, timeout_add, source_remove, 74 *args): 75 self.idle_add = idle_add 76 self.timeout_add = timeout_add 77 self.source_remove = source_remove 78 for bc in CC_BASES: 79 try: 80 if bc==ClientConnection: 81 initargs = [protocol, disconnect_cb, session_name, server]+list(args) 82 else: 83 initargs = () 84 bc.__init__(self, *initargs) 85 bc.init_from(self, protocol, server) 86 except Exception as e: 87 raise Exception("failed to initialize %s: %s" % (bc, e)) from None 88 89 for c in CC_BASES: 90 c.init_state(self) 91 92 def close(self): 93 log("%s.close()", self) 94 for bc in reversed(CC_BASES): 95 log("%s.cleanup()", bc) 96 c.cleanup(self) 97 98 def send_hello(self, server_capabilities): 99 capabilities = server_capabilities.copy() 100 for bc in CC_BASES: 101 log("%s.get_caps()", bc) 102 merge_dicts(capabilities, bc.get_caps(self)) 103 self.send("hello", capabilities) 104 self.hello_sent = True 105 106 def get_info(self) -> dict: 107 info = {} 108 for bc in CC_BASES: 109 log("%s.get_info()", bc) 110 try: 111 merge_dicts(info, bc.get_info(self)) 112 except Exception as e: 113 log("merge_dicts on %s", bc, exc_info=True) 114 log.error("Error: cannot add information from %s:", bc) 115 log.error(" %s", e) 116 return info 117 118 def parse_hello(self, c): 119 self.ui_client = c.boolget("ui_client", True) 120 self.wants_encodings = c.boolget("wants_encodings", self.ui_client) 121 self.wants_display = c.boolget("wants_display", self.ui_client) 122 self.wants_events = c.boolget("wants_events", False) 123 self.wants_aliases = c.boolget("wants_aliases", True) 124 self.wants_versions = c.boolget("wants_versions", True) 125 self.wants_features = c.boolget("wants_features", True) 126 self.wants_default_cursor = c.boolget("wants_default_cursor", False) 127 for bc in CC_BASES: 128 log("%s.parse_client_caps(..)", bc) 129 bc.parse_client_caps(self, c) 130 131 return ClientConnectionMuxer -
xpra/server/source/mmap_connection.py
16 16 17 17 class MMAP_Connection(StubSourceMixin): 18 18 19 @classmethod 20 def is_needed(cls, caps): 21 #pre 2.3 clients; 22 if caps.strget("mmap_file"): 23 return True 24 v = caps.rawget("mmap") 25 #we should be receiving a dict with mmap attributes 26 #(but pre v4 clients also send a boolean telling us if mmap is supported by the platform..) 27 return isinstance(v, dict) 28 19 29 def __init__(self): 20 30 self.supports_mmap = False 21 31 self.mmap_filename = None -
xpra/server/source/stub_source_mixin.py
1 1 # -*- coding: utf-8 -*- 2 2 # This file is part of Xpra. 3 # Copyright (C) 2018 Antoine Martin <antoine@xpra.org>3 # Copyright (C) 2018-2020 Antoine Martin <antoine@xpra.org> 4 4 # Xpra is released under the terms of the GNU GPL v2, or, at your option, any 5 5 # later version. See the file COPYING for details. 6 6 … … 11 11 class StubSourceMixin: 12 12 13 13 """ 14 Is this mixin needed for the caps given? 15 """ 16 @classmethod 17 def is_needed(cls, caps): 18 return True 19 20 def __init__(self, *_args): 21 pass 22 23 """ 14 24 Initialize state attributes. 15 25 """ 16 26 def init_state(self):