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