Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 # Virtual Me2Me implementation. This script runs and manages the processes | 6 # Virtual Me2Me implementation. This script runs and manages the processes |
| 7 # required for a Virtual Me2Me desktop, which are: X server, X desktop | 7 # required for a Virtual Me2Me desktop, which are: X server, X desktop |
| 8 # session, and Host process. | 8 # session, and Host process. |
| 9 # This script is intended to run continuously as a background daemon | 9 # This script is intended to run continuously as a background daemon |
| 10 # process, running under an ordinary (non-root) user account. | 10 # process, running under an ordinary (non-root) user account. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 import time | 30 import time |
| 31 import uuid | 31 import uuid |
| 32 | 32 |
| 33 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" | 33 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" |
| 34 | 34 |
| 35 # This script has a sensible default for the initial and maximum desktop size, | 35 # This script has a sensible default for the initial and maximum desktop size, |
| 36 # which can be overridden either on the command-line, or via a comma-separated | 36 # which can be overridden either on the command-line, or via a comma-separated |
| 37 # list of sizes in this environment variable. | 37 # list of sizes in this environment variable. |
| 38 DEFAULT_SIZES_ENV_VAR = "CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES" | 38 DEFAULT_SIZES_ENV_VAR = "CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES" |
| 39 | 39 |
| 40 # By default, provide a relatively small size to handle the case where resize- | 40 # By default, provide a maximum size that is large enough to support clients |
| 41 # to-client is disabled, and a much larger size to support clients with large | 41 # with large or multiple monitors. This is a comma-separated list of |
| 42 # or mulitple monitors. These defaults can be overridden in ~/.profile. | 42 # resolutions that will be made available if the X server supports RANDR. These |
| 43 # defaults can be overridden in ~/.profile. | |
| 43 DEFAULT_SIZES = "1600x1200,3840x1600" | 44 DEFAULT_SIZES = "1600x1200,3840x1600" |
| 44 | 45 |
| 46 # If RANDR is not available, use a smaller default size. Only a single | |
| 47 # resolution is supported in this case. | |
| 48 DEFAULT_SIZE_NO_RANDR = "1600x1200" | |
| 49 | |
| 45 SCRIPT_PATH = sys.path[0] | 50 SCRIPT_PATH = sys.path[0] |
| 46 | 51 |
| 47 IS_INSTALLED = (os.path.basename(sys.argv[0]) != 'linux_me2me_host.py') | 52 IS_INSTALLED = (os.path.basename(sys.argv[0]) != 'linux_me2me_host.py') |
| 48 | 53 |
| 49 if IS_INSTALLED: | 54 if IS_INSTALLED: |
| 50 HOST_BINARY_NAME = "chrome-remote-desktop-host" | 55 HOST_BINARY_NAME = "chrome-remote-desktop-host" |
| 51 else: | 56 else: |
| 52 HOST_BINARY_NAME = "remoting_me2me_host" | 57 HOST_BINARY_NAME = "remoting_me2me_host" |
| 53 | 58 |
| 54 CHROME_REMOTING_GROUP_NAME = "chrome-remote-desktop" | 59 CHROME_REMOTING_GROUP_NAME = "chrome-remote-desktop" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 71 | 76 |
| 72 # Thresholds for switching from fast- to slow-restart and for giving up | 77 # Thresholds for switching from fast- to slow-restart and for giving up |
| 73 # trying to restart entirely. | 78 # trying to restart entirely. |
| 74 SHORT_BACKOFF_THRESHOLD = 5 | 79 SHORT_BACKOFF_THRESHOLD = 5 |
| 75 MAX_LAUNCH_FAILURES = SHORT_BACKOFF_THRESHOLD + 10 | 80 MAX_LAUNCH_FAILURES = SHORT_BACKOFF_THRESHOLD + 10 |
| 76 | 81 |
| 77 # Globals needed by the atexit cleanup() handler. | 82 # Globals needed by the atexit cleanup() handler. |
| 78 g_desktops = [] | 83 g_desktops = [] |
| 79 g_host_hash = hashlib.md5(socket.gethostname()).hexdigest() | 84 g_host_hash = hashlib.md5(socket.gethostname()).hexdigest() |
| 80 | 85 |
| 86 | |
| 81 def is_supported_platform(): | 87 def is_supported_platform(): |
| 82 # Always assume that the system is supported if the config directory or | 88 # Always assume that the system is supported if the config directory or |
| 83 # session file exist. | 89 # session file exist. |
| 84 if (os.path.isdir(CONFIG_DIR) or os.path.isfile(SESSION_FILE_PATH) or | 90 if (os.path.isdir(CONFIG_DIR) or os.path.isfile(SESSION_FILE_PATH) or |
| 85 os.path.isfile(SYSTEM_SESSION_FILE_PATH)): | 91 os.path.isfile(SYSTEM_SESSION_FILE_PATH)): |
| 86 return True | 92 return True |
| 87 | 93 |
| 88 # The host has been tested only on Ubuntu. | 94 # The host has been tested only on Ubuntu. |
| 89 distribution = platform.linux_distribution() | 95 distribution = platform.linux_distribution() |
| 90 return (distribution[0]).lower() == 'ubuntu' | 96 return (distribution[0]).lower() == 'ubuntu' |
| 91 | 97 |
| 98 | |
| 99 def get_randr_supporting_x_server(): | |
| 100 """Returns a path to an X server that supports the RANDR extension, if this | |
| 101 is found on the system. Otherwise returns None.""" | |
| 102 try: | |
| 103 xvfb = "/usr/bin/Xvfb-randr" | |
| 104 if not os.path.exists(xvfb): | |
| 105 xvfb = locate_executable("Xvfb-randr") | |
| 106 return xvfb | |
| 107 except Exception: | |
| 108 return None | |
| 109 | |
| 110 | |
| 92 class Config: | 111 class Config: |
| 93 def __init__(self, path): | 112 def __init__(self, path): |
| 94 self.path = path | 113 self.path = path |
| 95 self.data = {} | 114 self.data = {} |
| 96 self.changed = False | 115 self.changed = False |
| 97 | 116 |
| 98 def load(self): | 117 def load(self): |
| 99 """Loads the config from file. | 118 """Loads the config from file. |
| 100 | 119 |
| 101 Raises: | 120 Raises: |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 # Run "xauth add" with |child_env| so that it modifies the same XAUTHORITY | 339 # Run "xauth add" with |child_env| so that it modifies the same XAUTHORITY |
| 321 # file which will be used for the X session. | 340 # file which will be used for the X session. |
| 322 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, | 341 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, |
| 323 env=self.child_env, shell=True) | 342 env=self.child_env, shell=True) |
| 324 if ret_code != 0: | 343 if ret_code != 0: |
| 325 raise Exception("xauth failed with code %d" % ret_code) | 344 raise Exception("xauth failed with code %d" % ret_code) |
| 326 | 345 |
| 327 max_width = max([width for width, height in self.sizes]) | 346 max_width = max([width for width, height in self.sizes]) |
| 328 max_height = max([height for width, height in self.sizes]) | 347 max_height = max([height for width, height in self.sizes]) |
| 329 | 348 |
| 330 try: | 349 xvfb = get_randr_supporting_x_server() |
| 331 # TODO(jamiewalch): This script expects to be installed alongside | 350 if xvfb: |
| 332 # Xvfb-randr, but that's no longer the case. Fix this once we have | |
| 333 # a Xvfb-randr package that installs somewhere sensible. | |
| 334 xvfb = "/usr/bin/Xvfb-randr" | |
| 335 if not os.path.exists(xvfb): | |
| 336 xvfb = locate_executable("Xvfb-randr") | |
| 337 self.server_supports_exact_resize = True | 351 self.server_supports_exact_resize = True |
| 338 except Exception: | 352 else: |
| 339 xvfb = "Xvfb" | 353 xvfb = "Xvfb" |
| 340 self.server_supports_exact_resize = False | 354 self.server_supports_exact_resize = False |
| 341 | 355 |
| 342 # Disable the Composite extension iff the X session is the default | 356 # Disable the Composite extension iff the X session is the default |
| 343 # Unity-2D, since it uses Metacity which fails to generate DAMAGE | 357 # Unity-2D, since it uses Metacity which fails to generate DAMAGE |
| 344 # notifications correctly. See crbug.com/166468. | 358 # notifications correctly. See crbug.com/166468. |
| 345 x_session = choose_x_session() | 359 x_session = choose_x_session() |
| 346 if (len(x_session) == 2 and | 360 if (len(x_session) == 2 and |
| 347 x_session[1] == "/usr/bin/gnome-session --session=ubuntu-2d"): | 361 x_session[1] == "/usr/bin/gnome-session --session=ubuntu-2d"): |
| 348 extra_x_args.extend(["-extension", "Composite"]) | 362 extra_x_args.extend(["-extension", "Composite"]) |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1011 | 1025 |
| 1012 if options.host_version: | 1026 if options.host_version: |
| 1013 # TODO(sergeyu): Also check RPM package version once we add RPM package. | 1027 # TODO(sergeyu): Also check RPM package version once we add RPM package. |
| 1014 return os.system(locate_executable(HOST_BINARY_NAME) + " --version") >> 8 | 1028 return os.system(locate_executable(HOST_BINARY_NAME) + " --version") >> 8 |
| 1015 | 1029 |
| 1016 if not options.start: | 1030 if not options.start: |
| 1017 # If no modal command-line options specified, print an error and exit. | 1031 # If no modal command-line options specified, print an error and exit. |
| 1018 print >> sys.stderr, EPILOG | 1032 print >> sys.stderr, EPILOG |
| 1019 return 1 | 1033 return 1 |
| 1020 | 1034 |
| 1035 # If a RANDR-supporting Xvfb is not available, limit the default size to | |
| 1036 # something more sensible. | |
| 1037 if get_randr_supporting_x_server(): | |
|
Jamie
2014/05/09 16:41:28
Can you just use self.server_supports_exact_resize
Lambros
2014/05/09 19:50:01
Not here, because this is during main() initializa
| |
| 1038 default_sizes = DEFAULT_SIZES | |
| 1039 else: | |
| 1040 default_sizes = DEFAULT_SIZE_NO_RANDR | |
| 1041 | |
| 1021 # Collate the list of sizes that XRANDR should support. | 1042 # Collate the list of sizes that XRANDR should support. |
| 1022 if not options.size: | 1043 if not options.size: |
| 1023 default_sizes = DEFAULT_SIZES | |
| 1024 if os.environ.has_key(DEFAULT_SIZES_ENV_VAR): | 1044 if os.environ.has_key(DEFAULT_SIZES_ENV_VAR): |
| 1025 default_sizes = os.environ[DEFAULT_SIZES_ENV_VAR] | 1045 default_sizes = os.environ[DEFAULT_SIZES_ENV_VAR] |
| 1026 options.size = default_sizes.split(",") | 1046 options.size = default_sizes.split(",") |
| 1027 | 1047 |
| 1028 sizes = [] | 1048 sizes = [] |
| 1029 for size in options.size: | 1049 for size in options.size: |
| 1030 size_components = size.split("x") | 1050 size_components = size.split("x") |
| 1031 if len(size_components) != 2: | 1051 if len(size_components) != 2: |
| 1032 parser.error("Incorrect size format '%s', should be WIDTHxHEIGHT" % size) | 1052 parser.error("Incorrect size format '%s', should be WIDTHxHEIGHT" % size) |
| 1033 | 1053 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1205 else: | 1225 else: |
| 1206 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) | 1226 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) |
| 1207 elif os.WIFSIGNALED(status): | 1227 elif os.WIFSIGNALED(status): |
| 1208 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) | 1228 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) |
| 1209 | 1229 |
| 1210 | 1230 |
| 1211 if __name__ == "__main__": | 1231 if __name__ == "__main__": |
| 1212 logging.basicConfig(level=logging.DEBUG, | 1232 logging.basicConfig(level=logging.DEBUG, |
| 1213 format="%(asctime)s:%(levelname)s:%(message)s") | 1233 format="%(asctime)s:%(levelname)s:%(message)s") |
| 1214 sys.exit(main()) | 1234 sys.exit(main()) |
| OLD | NEW |