desktop_browser_finder.py revision 1e9bf3e0803691d0a228da41fc608347b6db4340
1# Copyright 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"""Finds desktop browsers that can be controlled by telemetry.""" 5 6import logging 7import os 8import platform 9import subprocess 10import sys 11 12from telemetry.core import browser 13from telemetry.core import platform as core_platform 14from telemetry.core import possible_browser 15from telemetry.core import util 16from telemetry.core.backends.chrome import cros_interface 17from telemetry.core.backends.chrome import desktop_browser_backend 18 19ALL_BROWSER_TYPES = ','.join([ 20 'exact', 21 'release', 22 'release_x64', 23 'debug', 24 'debug_x64', 25 'canary', 26 'content-shell-debug', 27 'content-shell-release', 28 'system']) 29 30class PossibleDesktopBrowser(possible_browser.PossibleBrowser): 31 """A desktop browser that can be controlled.""" 32 33 def __init__(self, browser_type, finder_options, executable, flash_path, 34 is_content_shell, browser_directory, is_local_build=False): 35 super(PossibleDesktopBrowser, self).__init__(browser_type, finder_options) 36 self._local_executable = executable 37 self._flash_path = flash_path 38 self._is_content_shell = is_content_shell 39 self._browser_directory = browser_directory 40 self.is_local_build = is_local_build 41 42 def __repr__(self): 43 return 'PossibleDesktopBrowser(browser_type=%s, executable=%s)' % ( 44 self.browser_type, self._local_executable) 45 46 def Create(self): 47 backend = desktop_browser_backend.DesktopBrowserBackend( 48 self.finder_options.browser_options, self._local_executable, 49 self._flash_path, self._is_content_shell, self._browser_directory, 50 output_profile_path=self.finder_options.output_profile_path, 51 extensions_to_load=self.finder_options.extensions_to_load) 52 b = browser.Browser(backend, 53 core_platform.CreatePlatformBackendForCurrentOS()) 54 return b 55 56 def SupportsOptions(self, finder_options): 57 if (len(finder_options.extensions_to_load) != 0) and self._is_content_shell: 58 return False 59 return True 60 61 def UpdateExecutableIfNeeded(self): 62 pass 63 64 def last_modification_time(self): 65 if os.path.exists(self._local_executable): 66 return os.path.getmtime(self._local_executable) 67 return -1 68 69def SelectDefaultBrowser(possible_browsers): 70 local_builds_by_date = [ 71 b for b in sorted(possible_browsers, 72 key=lambda b: b.last_modification_time()) 73 if b.is_local_build] 74 if local_builds_by_date: 75 return local_builds_by_date[-1] 76 return None 77 78def CanFindAvailableBrowsers(): 79 return not cros_interface.IsRunningOnCrosDevice() 80 81def FindAllAvailableBrowsers(finder_options): 82 """Finds all the desktop browsers available on this machine.""" 83 browsers = [] 84 85 if not CanFindAvailableBrowsers(): 86 return [] 87 88 has_display = True 89 if (sys.platform.startswith('linux') and 90 os.getenv('DISPLAY') == None): 91 has_display = False 92 93 # Look for a browser in the standard chrome build locations. 94 if finder_options.chrome_root: 95 chrome_root = finder_options.chrome_root 96 else: 97 chrome_root = util.GetChromiumSrcDir() 98 99 chromium_app_names = [] 100 if sys.platform == 'darwin': 101 chromium_app_names.append('Chromium.app/Contents/MacOS/Chromium') 102 chromium_app_names.append('Google Chrome.app/Contents/MacOS/Google Chrome') 103 content_shell_app_name = 'Content Shell.app/Contents/MacOS/Content Shell' 104 mac_dir = 'mac' 105 if platform.architecture()[0] == '64bit': 106 mac_dir = 'mac_64' 107 flash_path = os.path.join( 108 chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi', 109 mac_dir, 'PepperFlashPlayer.plugin') 110 elif sys.platform.startswith('linux'): 111 chromium_app_names.append('chrome') 112 content_shell_app_name = 'content_shell' 113 linux_dir = 'linux' 114 if platform.architecture()[0] == '64bit': 115 linux_dir = 'linux_x64' 116 flash_path = os.path.join( 117 chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi', 118 linux_dir, 'libpepflashplayer.so') 119 elif sys.platform.startswith('win'): 120 chromium_app_names.append('chrome.exe') 121 content_shell_app_name = 'content_shell.exe' 122 win_dir = 'win' 123 if platform.architecture()[0] == '64bit': 124 win_dir = 'win_x64' 125 flash_path = os.path.join( 126 chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi', 127 win_dir, 'pepflashplayer.dll') 128 else: 129 raise Exception('Platform not recognized') 130 131 def IsExecutable(path): 132 return os.path.isfile(path) and os.access(path, os.X_OK) 133 134 # Add the explicit browser executable if given. 135 if finder_options.browser_executable: 136 normalized_executable = os.path.expanduser( 137 finder_options.browser_executable) 138 if IsExecutable(normalized_executable): 139 browser_directory = os.path.dirname(finder_options.browser_executable) 140 browsers.append(PossibleDesktopBrowser('exact', finder_options, 141 normalized_executable, flash_path, 142 False, browser_directory)) 143 else: 144 logging.warning('%s specified by browser_executable does not exist', 145 normalized_executable) 146 147 def AddIfFound(browser_type, build_dir, type_dir, app_name, content_shell): 148 browser_directory = os.path.join(chrome_root, build_dir, type_dir) 149 app = os.path.join(browser_directory, app_name) 150 if IsExecutable(app): 151 browsers.append(PossibleDesktopBrowser(browser_type, finder_options, 152 app, flash_path, content_shell, 153 browser_directory, 154 is_local_build=True)) 155 return True 156 return False 157 158 # Add local builds 159 for build_dir, build_type in util.GetBuildDirectories(): 160 for chromium_app_name in chromium_app_names: 161 AddIfFound(build_type.lower(), build_dir, build_type, 162 chromium_app_name, False) 163 AddIfFound('content-shell-' + build_type.lower(), build_dir, build_type, 164 content_shell_app_name, True) 165 166 # Mac-specific options. 167 if sys.platform == 'darwin': 168 mac_canary_root = '/Applications/Google Chrome Canary.app/' 169 mac_canary = mac_canary_root + 'Contents/MacOS/Google Chrome Canary' 170 mac_system_root = '/Applications/Google Chrome.app' 171 mac_system = mac_system_root + '/Contents/MacOS/Google Chrome' 172 if IsExecutable(mac_canary): 173 browsers.append(PossibleDesktopBrowser('canary', finder_options, 174 mac_canary, None, False, 175 mac_canary_root)) 176 177 if IsExecutable(mac_system): 178 browsers.append(PossibleDesktopBrowser('system', finder_options, 179 mac_system, None, False, 180 mac_system_root)) 181 182 # Linux specific options. 183 if sys.platform.startswith('linux'): 184 # Look for a google-chrome instance. 185 found = False 186 try: 187 with open(os.devnull, 'w') as devnull: 188 found = subprocess.call(['google-chrome', '--version'], 189 stdout=devnull, stderr=devnull) == 0 190 except OSError: 191 pass 192 if found: 193 browsers.append(PossibleDesktopBrowser('system', finder_options, 194 'google-chrome', None, False, 195 '/opt/google/chrome')) 196 197 # Win32-specific options. 198 if sys.platform.startswith('win'): 199 system_path = os.path.join('Google', 'Chrome', 'Application') 200 canary_path = os.path.join('Google', 'Chrome SxS', 'Application') 201 202 win_search_paths = [os.getenv('PROGRAMFILES(X86)'), 203 os.getenv('PROGRAMFILES'), 204 os.getenv('LOCALAPPDATA')] 205 206 def AddIfFoundWin(browser_name, app_path): 207 browser_directory = os.path.join(path, app_path) 208 for chromium_app_name in chromium_app_names: 209 app = os.path.join(browser_directory, chromium_app_name) 210 if IsExecutable(app): 211 browsers.append(PossibleDesktopBrowser(browser_name, finder_options, 212 app, flash_path, False, 213 browser_directory)) 214 return True 215 return False 216 217 for path in win_search_paths: 218 if not path: 219 continue 220 if AddIfFoundWin('canary', canary_path): 221 break 222 223 for path in win_search_paths: 224 if not path: 225 continue 226 if AddIfFoundWin('system', system_path): 227 break 228 229 if len(browsers) and not has_display: 230 logging.warning( 231 'Found (%s), but you do not have a DISPLAY environment set.' % 232 ','.join([b.browser_type for b in browsers])) 233 return [] 234 235 return browsers 236