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