| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 class Desktop: | 161 class Desktop: |
| 162 """Manage a single virtual desktop""" | 162 """Manage a single virtual desktop""" |
| 163 | 163 |
| 164 def __init__(self, sizes): | 164 def __init__(self, sizes): |
| 165 self.x_proc = None | 165 self.x_proc = None |
| 166 self.session_proc = None | 166 self.session_proc = None |
| 167 self.host_proc = None | 167 self.host_proc = None |
| 168 self.child_env = None | 168 self.child_env = None |
| 169 self.sizes = sizes | 169 self.sizes = sizes |
| 170 self.pulseaudio_pipe = None | 170 self.pulseaudio_pipe = None |
| 171 self.server_supports_exact_resize = False |
| 171 g_desktops.append(self) | 172 g_desktops.append(self) |
| 172 | 173 |
| 173 @staticmethod | 174 @staticmethod |
| 174 def get_unused_display_number(): | 175 def get_unused_display_number(): |
| 175 """Return a candidate display number for which there is currently no | 176 """Return a candidate display number for which there is currently no |
| 176 X Server lock file""" | 177 X Server lock file""" |
| 177 display = FIRST_X_DISPLAY_NUMBER | 178 display = FIRST_X_DISPLAY_NUMBER |
| 178 while os.path.exists(X_LOCK_FILE_TEMPLATE % display): | 179 while os.path.exists(X_LOCK_FILE_TEMPLATE % display): |
| 179 display += 1 | 180 display += 1 |
| 180 return display | 181 return display |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 display = self.get_unused_display_number() | 247 display = self.get_unused_display_number() |
| 247 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, | 248 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, |
| 248 shell=True) | 249 shell=True) |
| 249 if ret_code != 0: | 250 if ret_code != 0: |
| 250 raise Exception("xauth failed with code %d" % ret_code) | 251 raise Exception("xauth failed with code %d" % ret_code) |
| 251 | 252 |
| 252 max_width = max([width for width, height in self.sizes]) | 253 max_width = max([width for width, height in self.sizes]) |
| 253 max_height = max([height for width, height in self.sizes]) | 254 max_height = max([height for width, height in self.sizes]) |
| 254 | 255 |
| 255 try: | 256 try: |
| 256 xvfb = locate_executable("Xvfb-randr") | 257 # TODO(jamiewalch): This script expects to be installed alongside |
| 258 # Xvfb-randr, but that's no longer the case. Fix this once we have |
| 259 # a Xvfb-randr package that installs somewhere sensible. |
| 260 xvfb = "/usr/bin/Xvfb-randr" |
| 261 if not os.path.exists(xvfb): |
| 262 xvfb = locate_executable("Xvfb-randr") |
| 263 self.server_supports_exact_resize = True |
| 257 except Exception: | 264 except Exception: |
| 258 xvfb = "Xvfb" | 265 xvfb = "Xvfb" |
| 266 self.server_supports_exact_resize = False |
| 259 | 267 |
| 260 logging.info("Starting %s on display :%d" % (xvfb, display)) | 268 logging.info("Starting %s on display :%d" % (xvfb, display)) |
| 261 screen_option = "%dx%dx24" % (max_width, max_height) | 269 screen_option = "%dx%dx24" % (max_width, max_height) |
| 262 self.x_proc = subprocess.Popen([xvfb, ":%d" % display, | 270 self.x_proc = subprocess.Popen([xvfb, ":%d" % display, |
| 263 "-noreset", | 271 "-noreset", |
| 264 "-auth", X_AUTH_FILE, | 272 "-auth", X_AUTH_FILE, |
| 265 "-nolisten", "tcp", | 273 "-nolisten", "tcp", |
| 266 "-screen", "0", screen_option | 274 "-screen", "0", screen_option |
| 267 ] + extra_x_args) | 275 ] + extra_x_args) |
| 268 if not self.x_proc.pid: | 276 if not self.x_proc.pid: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 self._init_child_env() | 348 self._init_child_env() |
| 341 self._setup_pulseaudio() | 349 self._setup_pulseaudio() |
| 342 self._launch_x_server(x_args) | 350 self._launch_x_server(x_args) |
| 343 self._launch_x_session() | 351 self._launch_x_session() |
| 344 | 352 |
| 345 def launch_host(self, host_config): | 353 def launch_host(self, host_config): |
| 346 # Start remoting host | 354 # Start remoting host |
| 347 args = [locate_executable(HOST_BINARY_NAME), "--host-config=/dev/stdin"] | 355 args = [locate_executable(HOST_BINARY_NAME), "--host-config=/dev/stdin"] |
| 348 if self.pulseaudio_pipe: | 356 if self.pulseaudio_pipe: |
| 349 args.append("--audio-pipe-name=%s" % self.pulseaudio_pipe) | 357 args.append("--audio-pipe-name=%s" % self.pulseaudio_pipe) |
| 358 if self.server_supports_exact_resize: |
| 359 args.append("--server-supports-exact-resize") |
| 350 self.host_proc = subprocess.Popen(args, env=self.child_env, | 360 self.host_proc = subprocess.Popen(args, env=self.child_env, |
| 351 stdin=subprocess.PIPE) | 361 stdin=subprocess.PIPE) |
| 352 logging.info(args) | 362 logging.info(args) |
| 353 if not self.host_proc.pid: | 363 if not self.host_proc.pid: |
| 354 raise Exception("Could not start Chrome Remote Desktop host") | 364 raise Exception("Could not start Chrome Remote Desktop host") |
| 355 self.host_proc.stdin.write(json.dumps(host_config.data)) | 365 self.host_proc.stdin.write(json.dumps(host_config.data)) |
| 356 self.host_proc.stdin.close() | 366 self.host_proc.stdin.close() |
| 357 | 367 |
| 358 | 368 |
| 359 class PidFile: | 369 class PidFile: |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 # Exit cleanly so the atexit handler, cleanup(), gets called. | 604 # Exit cleanly so the atexit handler, cleanup(), gets called. |
| 595 raise SystemExit | 605 raise SystemExit |
| 596 | 606 |
| 597 | 607 |
| 598 def relaunch_self(): | 608 def relaunch_self(): |
| 599 cleanup() | 609 cleanup() |
| 600 os.execvp(sys.argv[0], sys.argv) | 610 os.execvp(sys.argv[0], sys.argv) |
| 601 | 611 |
| 602 | 612 |
| 603 def main(): | 613 def main(): |
| 604 DEFAULT_SIZE = "1280x800" | 614 DEFAULT_SIZE = "2560x1600" |
| 605 EPILOG = """This script is not intended for use by end-users. To configure | 615 EPILOG = """This script is not intended for use by end-users. To configure |
| 606 Chrome Remote Desktop, please install the app from the Chrome | 616 Chrome Remote Desktop, please install the app from the Chrome |
| 607 Web Store: https://chrome.google.com/remotedesktop""" | 617 Web Store: https://chrome.google.com/remotedesktop""" |
| 608 parser = optparse.OptionParser( | 618 parser = optparse.OptionParser( |
| 609 usage="Usage: %prog [options] [ -- [ X server options ] ]", | 619 usage="Usage: %prog [options] [ -- [ X server options ] ]", |
| 610 epilog=EPILOG) | 620 epilog=EPILOG) |
| 611 parser.add_option("-s", "--size", dest="size", action="append", | 621 parser.add_option("-s", "--size", dest="size", action="append", |
| 612 help="Dimensions of virtual desktop (default: %s). " | 622 help="Dimensions of virtual desktop (default: %s). " |
| 613 "This can be specified multiple times to make multiple " | 623 "This can be specified multiple times to make multiple " |
| 614 "screen resolutions available (if the Xvfb server " | 624 "screen resolutions available (if the Xvfb server " |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 return 0 | 857 return 0 |
| 848 elif os.WEXITSTATUS(status) == 5: | 858 elif os.WEXITSTATUS(status) == 5: |
| 849 logging.info("Host domain is blocked by policy - exiting.") | 859 logging.info("Host domain is blocked by policy - exiting.") |
| 850 os.remove(host.config_file) | 860 os.remove(host.config_file) |
| 851 return 0 | 861 return 0 |
| 852 # Nothing to do for Mac-only status 6 (login screen unsupported) | 862 # Nothing to do for Mac-only status 6 (login screen unsupported) |
| 853 | 863 |
| 854 if __name__ == "__main__": | 864 if __name__ == "__main__": |
| 855 logging.basicConfig(level=logging.DEBUG) | 865 logging.basicConfig(level=logging.DEBUG) |
| 856 sys.exit(main()) | 866 sys.exit(main()) |
| OLD | NEW |