Home | History | Annotate | Download | only in utils
      1 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 # pylint: disable=W0702
      6 
      7 import os
      8 import signal
      9 import subprocess
     10 import sys
     11 import time
     12 
     13 
     14 def _IsLinux():
     15   """Return True if on Linux; else False."""
     16   return sys.platform.startswith('linux')
     17 
     18 
     19 class Xvfb(object):
     20   """Class to start and stop Xvfb if relevant.  Nop if not Linux."""
     21 
     22   def __init__(self):
     23     self._pid = 0
     24 
     25   def Start(self):
     26     """Start Xvfb and set an appropriate DISPLAY environment.  Linux only.
     27 
     28     Copied from tools/code_coverage/coverage_posix.py
     29     """
     30     if not _IsLinux():
     31       return
     32     proc = subprocess.Popen(['Xvfb', ':9', '-screen', '0', '1024x768x24',
     33                              '-ac'],
     34                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
     35     self._pid = proc.pid
     36     if not self._pid:
     37       raise Exception('Could not start Xvfb')
     38     os.environ['DISPLAY'] = ':9'
     39 
     40     # Now confirm, giving a chance for it to start if needed.
     41     for _ in range(10):
     42       proc = subprocess.Popen('xdpyinfo >/dev/null', shell=True)
     43       _, retcode = os.waitpid(proc.pid, 0)
     44       if retcode == 0:
     45         break
     46       time.sleep(0.25)
     47     if retcode != 0:
     48       raise Exception('Could not confirm Xvfb happiness')
     49 
     50   def Stop(self):
     51     """Stop Xvfb if needed.  Linux only."""
     52     if self._pid:
     53       try:
     54         os.kill(self._pid, signal.SIGKILL)
     55       except:
     56         pass
     57       del os.environ['DISPLAY']
     58       self._pid = 0
     59