| 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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 337 |
| 338 def __init__(self, sizes): | 338 def __init__(self, sizes): |
| 339 self.x_proc = None | 339 self.x_proc = None |
| 340 self.session_proc = None | 340 self.session_proc = None |
| 341 self.host_proc = None | 341 self.host_proc = None |
| 342 self.child_env = None | 342 self.child_env = None |
| 343 self.sizes = sizes | 343 self.sizes = sizes |
| 344 self.xorg_conf = None | 344 self.xorg_conf = None |
| 345 self.pulseaudio_pipe = None | 345 self.pulseaudio_pipe = None |
| 346 self.server_supports_exact_resize = False | 346 self.server_supports_exact_resize = False |
| 347 self.server_supports_randr = False |
| 348 self.randr_add_sizes = False |
| 347 self.host_ready = False | 349 self.host_ready = False |
| 348 self.ssh_auth_sockname = None | 350 self.ssh_auth_sockname = None |
| 349 g_desktops.append(self) | 351 g_desktops.append(self) |
| 350 | 352 |
| 351 @staticmethod | 353 @staticmethod |
| 352 def get_unused_display_number(): | 354 def get_unused_display_number(): |
| 353 """Return a candidate display number for which there is currently no | 355 """Return a candidate display number for which there is currently no |
| 354 X Server lock file""" | 356 X Server lock file""" |
| 355 display = FIRST_X_DISPLAY_NUMBER | 357 display = FIRST_X_DISPLAY_NUMBER |
| 356 while os.path.exists(X_LOCK_FILE_TEMPLATE % display): | 358 while os.path.exists(X_LOCK_FILE_TEMPLATE % display): |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 self.ssh_auth_sockname = ("/tmp/chromoting.%s.ssh_auth_sock" % | 462 self.ssh_auth_sockname = ("/tmp/chromoting.%s.ssh_auth_sock" % |
| 461 os.environ["USER"]) | 463 os.environ["USER"]) |
| 462 | 464 |
| 463 def _launch_xvfb(self, display, x_auth_file, extra_x_args): | 465 def _launch_xvfb(self, display, x_auth_file, extra_x_args): |
| 464 max_width = max([width for width, height in self.sizes]) | 466 max_width = max([width for width, height in self.sizes]) |
| 465 max_height = max([height for width, height in self.sizes]) | 467 max_height = max([height for width, height in self.sizes]) |
| 466 | 468 |
| 467 xvfb = locate_xvfb_randr() | 469 xvfb = locate_xvfb_randr() |
| 468 if xvfb: | 470 if xvfb: |
| 469 self.server_supports_exact_resize = True | 471 self.server_supports_exact_resize = True |
| 472 self.server_supports_randr = True |
| 473 self.randr_add_sizes = True |
| 470 else: | 474 else: |
| 471 xvfb = "Xvfb" | 475 xvfb = "Xvfb" |
| 472 self.server_supports_exact_resize = False | 476 self.server_supports_exact_resize = False |
| 477 self.server_supports_randr = False |
| 473 | 478 |
| 474 logging.info("Starting %s on display :%d" % (xvfb, display)) | 479 logging.info("Starting %s on display :%d" % (xvfb, display)) |
| 475 screen_option = "%dx%dx24" % (max_width, max_height) | 480 screen_option = "%dx%dx24" % (max_width, max_height) |
| 476 self.x_proc = subprocess.Popen( | 481 self.x_proc = subprocess.Popen( |
| 477 [xvfb, ":%d" % display, | 482 [xvfb, ":%d" % display, |
| 478 "-auth", x_auth_file, | 483 "-auth", x_auth_file, |
| 479 "-nolisten", "tcp", | 484 "-nolisten", "tcp", |
| 480 "-noreset", | 485 "-noreset", |
| 481 "-screen", "0", screen_option | 486 "-screen", "0", screen_option |
| 482 ] + extra_x_args) | 487 ] + extra_x_args) |
| 483 if not self.x_proc.pid: | 488 if not self.x_proc.pid: |
| 484 raise Exception("Could not start Xvfb.") | 489 raise Exception("Could not start Xvfb.") |
| 485 | 490 |
| 486 def _launch_xorg(self, display, x_auth_file, extra_x_args): | 491 def _launch_xorg(self, display, x_auth_file, extra_x_args): |
| 487 with tempfile.NamedTemporaryFile( | 492 with tempfile.NamedTemporaryFile( |
| 488 prefix="chrome_remote_desktop_", | 493 prefix="chrome_remote_desktop_", |
| 489 suffix=".conf", delete=False) as config_file: | 494 suffix=".conf", delete=False) as config_file: |
| 490 config_file.write(gen_xorg_config(self.sizes)) | 495 config_file.write(gen_xorg_config(self.sizes)) |
| 491 | 496 |
| 492 # For now, we don't support exact resize with Xorg+dummy | 497 # We can't support exact resize with the current Xorg dummy driver. |
| 493 self.server_supports_exact_resize = False | 498 self.server_supports_exact_resize = False |
| 499 # But dummy does support RandR 1.0. |
| 500 self.server_supports_randr = True |
| 494 self.xorg_conf = config_file.name | 501 self.xorg_conf = config_file.name |
| 495 | 502 |
| 496 logging.info("Starting Xorg on display :%d" % display) | 503 logging.info("Starting Xorg on display :%d" % display) |
| 497 # We use the child environment so the Xorg server picks up the Mesa libGL | 504 # We use the child environment so the Xorg server picks up the Mesa libGL |
| 498 # instead of any proprietary versions that may be installed, thanks to | 505 # instead of any proprietary versions that may be installed, thanks to |
| 499 # LD_LIBRARY_PATH. | 506 # LD_LIBRARY_PATH. |
| 500 # Note: This prevents any environment variable the user has set from | 507 # Note: This prevents any environment variable the user has set from |
| 501 # affecting the Xorg server. | 508 # affecting the Xorg server. |
| 502 self.x_proc = subprocess.Popen( | 509 self.x_proc = subprocess.Popen( |
| 503 ["Xorg", ":%d" % display, | 510 ["Xorg", ":%d" % display, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 # starts configured to use the "base" ruleset, resulting in XKB configuring | 574 # starts configured to use the "base" ruleset, resulting in XKB configuring |
| 568 # for "xfree86" keycodes, and screwing up some keys. See crbug.com/119013. | 575 # for "xfree86" keycodes, and screwing up some keys. See crbug.com/119013. |
| 569 # Reconfigure the X server to use "evdev" keymap rules. The X server must | 576 # Reconfigure the X server to use "evdev" keymap rules. The X server must |
| 570 # be started with -noreset otherwise it'll reset as soon as the command | 577 # be started with -noreset otherwise it'll reset as soon as the command |
| 571 # completes, since there are no other X clients running yet. | 578 # completes, since there are no other X clients running yet. |
| 572 retcode = subprocess.call("setxkbmap -rules evdev", env=self.child_env, | 579 retcode = subprocess.call("setxkbmap -rules evdev", env=self.child_env, |
| 573 shell=True) | 580 shell=True) |
| 574 if retcode != 0: | 581 if retcode != 0: |
| 575 logging.error("Failed to set XKB to 'evdev'") | 582 logging.error("Failed to set XKB to 'evdev'") |
| 576 | 583 |
| 577 if not self.server_supports_exact_resize: | 584 if not self.server_supports_randr: |
| 578 return | 585 return |
| 579 | 586 |
| 580 # Register the screen sizes if the X server's RANDR extension supports it. | 587 # Register the screen sizes with RandR, if needed. Errors here are |
| 581 # Errors here are non-fatal; the X server will continue to run with the | 588 # non-fatal; the X server will continue to run with the dimensions from the |
| 582 # dimensions from the "-screen" option. | 589 # "-screen" option. |
| 583 for width, height in self.sizes: | 590 if self.randr_add_sizes: |
| 584 label = "%dx%d" % (width, height) | 591 for width, height in self.sizes: |
| 585 args = ["xrandr", "--newmode", label, "0", str(width), "0", "0", "0", | 592 label = "%dx%d" % (width, height) |
| 586 str(height), "0", "0", "0"] | 593 args = ["xrandr", "--newmode", label, "0", str(width), "0", "0", "0", |
| 587 subprocess.call(args, env=self.child_env, stdout=devnull, stderr=devnull) | 594 str(height), "0", "0", "0"] |
| 588 args = ["xrandr", "--addmode", "screen", label] | 595 subprocess.call(args, env=self.child_env, stdout=devnull, |
| 589 subprocess.call(args, env=self.child_env, stdout=devnull, stderr=devnull) | 596 stderr=devnull) |
| 597 args = ["xrandr", "--addmode", "screen", label] |
| 598 subprocess.call(args, env=self.child_env, stdout=devnull, |
| 599 stderr=devnull) |
| 590 | 600 |
| 591 # Set the initial mode to the first size specified, otherwise the X server | 601 # Set the initial mode to the first size specified, otherwise the X server |
| 592 # would default to (max_width, max_height), which might not even be in the | 602 # would default to (max_width, max_height), which might not even be in the |
| 593 # list. | 603 # list. |
| 594 initial_size = self.sizes[0] | 604 initial_size = self.sizes[0] |
| 595 label = "%dx%d" % initial_size | 605 label = "%dx%d" % initial_size |
| 596 args = ["xrandr", "-s", label] | 606 args = ["xrandr", "-s", label] |
| 597 subprocess.call(args, env=self.child_env, stdout=devnull, stderr=devnull) | 607 subprocess.call(args, env=self.child_env, stdout=devnull, stderr=devnull) |
| 598 | 608 |
| 599 # Set the physical size of the display so that the initial mode is running | 609 # Set the physical size of the display so that the initial mode is running |
| (...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 else: | 1528 else: |
| 1519 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) | 1529 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) |
| 1520 elif os.WIFSIGNALED(status): | 1530 elif os.WIFSIGNALED(status): |
| 1521 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) | 1531 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) |
| 1522 | 1532 |
| 1523 | 1533 |
| 1524 if __name__ == "__main__": | 1534 if __name__ == "__main__": |
| 1525 logging.basicConfig(level=logging.DEBUG, | 1535 logging.basicConfig(level=logging.DEBUG, |
| 1526 format="%(asctime)s:%(levelname)s:%(message)s") | 1536 format="%(asctime)s:%(levelname)s:%(message)s") |
| 1527 sys.exit(main()) | 1537 sys.exit(main()) |
| OLD | NEW |