| # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # pylint: disable=W0702 |
| |
| import os |
| import signal |
| import subprocess |
| import sys |
| import time |
| |
| |
| def _IsLinux(): |
| """Return True if on Linux; else False.""" |
| return sys.platform.startswith('linux') |
| |
| |
| class Xvfb(object): |
| """Class to start and stop Xvfb if relevant. Nop if not Linux.""" |
| |
| def __init__(self): |
| self._pid = 0 |
| |
| def Start(self): |
| """Start Xvfb and set an appropriate DISPLAY environment. Linux only. |
| |
| Copied from tools/code_coverage/coverage_posix.py |
| """ |
| if not _IsLinux(): |
| return |
| proc = subprocess.Popen(['Xvfb', ':9', '-screen', '0', '1024x768x24', |
| '-ac'], |
| stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| self._pid = proc.pid |
| if not self._pid: |
| raise Exception('Could not start Xvfb') |
| os.environ['DISPLAY'] = ':9' |
| |
| # Now confirm, giving a chance for it to start if needed. |
| for _ in range(10): |
| proc = subprocess.Popen('xdpyinfo >/dev/null', shell=True) |
| _, retcode = os.waitpid(proc.pid, 0) |
| if retcode == 0: |
| break |
| time.sleep(0.25) |
| if retcode != 0: |
| raise Exception('Could not confirm Xvfb happiness') |
| |
| def Stop(self): |
| """Stop Xvfb if needed. Linux only.""" |
| if self._pid: |
| try: |
| os.kill(self._pid, signal.SIGKILL) |
| except: |
| pass |
| del os.environ['DISPLAY'] |
| self._pid = 0 |