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."""
11 from telemetry import decorators
12 from telemetry.core import browser
13 from telemetry.core import platform as core_platform
14 from telemetry.core import possible_browser
15 from telemetry.core import util
16 from telemetry.core.backends.chrome import cros_interface
17 from telemetry.core.backends.chrome import desktop_browser_backend
26 'content-shell-debug',
27 'content-shell-debug_x64',
28 'content-shell-release',
29 'content-shell-release_x64',
32 class PossibleDesktopBrowser(possible_browser.PossibleBrowser):
33 """A desktop browser that can be controlled."""
35 def __init__(self, browser_type, finder_options, executable, flash_path,
36 is_content_shell, browser_directory, is_local_build=False):
37 target_os = sys.platform.lower()
38 super(PossibleDesktopBrowser, self).__init__(browser_type, target_os,
40 assert browser_type in ALL_BROWSER_TYPES, \
41 'Please add %s to ALL_BROWSER_TYPES' % browser_type
42 self._local_executable = executable
43 self._flash_path = flash_path
44 self._is_content_shell = is_content_shell
45 self._browser_directory = browser_directory
46 self.is_local_build = is_local_build
49 return 'PossibleDesktopBrowser(browser_type=%s, executable=%s)' % (
50 self.browser_type, self._local_executable)
54 def _platform_backend(self):
55 return core_platform.CreatePlatformBackendForCurrentOS()
58 backend = desktop_browser_backend.DesktopBrowserBackend(
59 self.finder_options.browser_options, self._local_executable,
60 self._flash_path, self._is_content_shell, self._browser_directory,
61 output_profile_path=self.finder_options.output_profile_path,
62 extensions_to_load=self.finder_options.extensions_to_load)
63 return browser.Browser(backend, self._platform_backend)
65 def SupportsOptions(self, finder_options):
66 if (len(finder_options.extensions_to_load) != 0) and self._is_content_shell:
70 def UpdateExecutableIfNeeded(self):
73 def last_modification_time(self):
74 if os.path.exists(self._local_executable):
75 return os.path.getmtime(self._local_executable)
78 def SelectDefaultBrowser(possible_browsers):
79 local_builds_by_date = [
80 b for b in sorted(possible_browsers,
81 key=lambda b: b.last_modification_time())
83 if local_builds_by_date:
84 return local_builds_by_date[-1]
87 def CanFindAvailableBrowsers():
88 return not cros_interface.IsRunningOnCrosDevice()
90 def FindAllAvailableBrowsers(finder_options):
91 """Finds all the desktop browsers available on this machine."""
94 if not CanFindAvailableBrowsers():
98 if (sys.platform.startswith('linux') and
99 os.getenv('DISPLAY') == None):
102 # Look for a browser in the standard chrome build locations.
103 if finder_options.chrome_root:
104 chrome_root = finder_options.chrome_root
106 chrome_root = util.GetChromiumSrcDir()
108 flash_bin_dir = os.path.join(
109 chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi')
111 chromium_app_names = []
112 if sys.platform == 'darwin':
113 chromium_app_names.append('Chromium.app/Contents/MacOS/Chromium')
114 chromium_app_names.append('Google Chrome.app/Contents/MacOS/Google Chrome')
115 content_shell_app_name = 'Content Shell.app/Contents/MacOS/Content Shell'
116 flash_bin = 'PepperFlashPlayer.plugin'
117 flash_path = os.path.join(flash_bin_dir, 'mac', flash_bin)
118 flash_path_64 = os.path.join(flash_bin_dir, 'mac_64', flash_bin)
119 elif sys.platform.startswith('linux'):
120 chromium_app_names.append('chrome')
121 content_shell_app_name = 'content_shell'
122 flash_bin = 'libpepflashplayer.so'
123 flash_path = os.path.join(flash_bin_dir, 'linux', flash_bin)
124 flash_path_64 = os.path.join(flash_bin_dir, 'linux_x64', flash_bin)
125 elif sys.platform.startswith('win'):
126 chromium_app_names.append('chrome.exe')
127 content_shell_app_name = 'content_shell.exe'
128 flash_bin = 'pepflashplayer.dll'
129 flash_path = os.path.join(flash_bin_dir, 'win', flash_bin)
130 flash_path_64 = os.path.join(flash_bin_dir, 'win_x64', flash_bin)
132 raise Exception('Platform not recognized')
134 def IsExecutable(path):
135 return os.path.isfile(path) and os.access(path, os.X_OK)
137 # Add the explicit browser executable if given.
138 if finder_options.browser_executable:
139 normalized_executable = os.path.expanduser(
140 finder_options.browser_executable)
141 if IsExecutable(normalized_executable):
142 browser_directory = os.path.dirname(finder_options.browser_executable)
143 browsers.append(PossibleDesktopBrowser('exact', finder_options,
144 normalized_executable, flash_path,
145 False, browser_directory))
147 logging.warning('%s specified by browser_executable does not exist',
148 normalized_executable)
150 def AddIfFound(browser_type, build_dir, type_dir, app_name, content_shell):
151 browser_directory = os.path.join(chrome_root, build_dir, type_dir)
152 app = os.path.join(browser_directory, app_name)
153 if IsExecutable(app):
154 is_64 = browser_type.endswith('_x64')
155 browsers.append(PossibleDesktopBrowser(
156 browser_type, finder_options, app,
157 flash_path_64 if is_64 else flash_path,
158 content_shell, browser_directory, is_local_build=True))
163 for build_dir, build_type in util.GetBuildDirectories():
164 for chromium_app_name in chromium_app_names:
165 AddIfFound(build_type.lower(), build_dir, build_type,
166 chromium_app_name, False)
167 AddIfFound('content-shell-' + build_type.lower(), build_dir, build_type,
168 content_shell_app_name, True)
170 # Mac-specific options.
171 if sys.platform == 'darwin':
172 mac_canary_root = '/Applications/Google Chrome Canary.app/'
173 mac_canary = mac_canary_root + 'Contents/MacOS/Google Chrome Canary'
174 mac_system_root = '/Applications/Google Chrome.app'
175 mac_system = mac_system_root + '/Contents/MacOS/Google Chrome'
176 if IsExecutable(mac_canary):
177 browsers.append(PossibleDesktopBrowser('canary', finder_options,
178 mac_canary, None, False,
181 if IsExecutable(mac_system):
182 browsers.append(PossibleDesktopBrowser('system', finder_options,
183 mac_system, None, False,
186 # Linux specific options.
187 if sys.platform.startswith('linux'):
188 # Look for a google-chrome instance.
191 with open(os.devnull, 'w') as devnull:
192 found = subprocess.call(['google-chrome', '--version'],
193 stdout=devnull, stderr=devnull) == 0
197 browsers.append(PossibleDesktopBrowser('system', finder_options,
198 'google-chrome', None, False,
199 '/opt/google/chrome'))
201 # Win32-specific options.
202 if sys.platform.startswith('win'):
203 system_path = os.path.join('Google', 'Chrome', 'Application')
204 canary_path = os.path.join('Google', 'Chrome SxS', 'Application')
206 win_search_paths = [os.getenv('PROGRAMFILES(X86)'),
207 os.getenv('PROGRAMFILES'),
208 os.getenv('LOCALAPPDATA')]
210 def AddIfFoundWin(browser_name, app_path):
211 browser_directory = os.path.join(path, app_path)
212 for chromium_app_name in chromium_app_names:
213 app = os.path.join(browser_directory, chromium_app_name)
214 if IsExecutable(app):
215 browsers.append(PossibleDesktopBrowser(browser_name, finder_options,
221 for path in win_search_paths:
224 if AddIfFoundWin('canary', canary_path):
227 for path in win_search_paths:
230 if AddIfFoundWin('system', system_path):
233 if len(browsers) and not has_display:
235 'Found (%s), but you do not have a DISPLAY environment set.' %
236 ','.join([b.browser_type for b in browsers]))