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.core import browser
12 from telemetry.core import possible_browser
13 from telemetry.core import util
14 from telemetry.core.backends.chrome import cros_interface
15 from telemetry.core.backends.chrome import desktop_browser_backend
16 from telemetry.core.platform import factory
25 'content-shell-debug',
26 'content-shell-debug_x64',
27 'content-shell-release',
28 'content-shell-release_x64',
31 class PossibleDesktopBrowser(possible_browser.PossibleBrowser):
32 """A desktop browser that can be controlled."""
34 def __init__(self, browser_type, finder_options, executable, flash_path,
35 is_content_shell, browser_directory, is_local_build=False):
36 target_os = sys.platform.lower()
37 super(PossibleDesktopBrowser, self).__init__(browser_type, target_os,
39 assert browser_type in ALL_BROWSER_TYPES, \
40 'Please add %s to ALL_BROWSER_TYPES' % browser_type
41 self._local_executable = executable
42 self._flash_path = flash_path
43 self._is_content_shell = is_content_shell
44 self._browser_directory = browser_directory
45 self.is_local_build = is_local_build
48 return 'PossibleDesktopBrowser(browser_type=%s, executable=%s)' % (
49 self.browser_type, self._local_executable)
52 def _platform_backend(self):
53 return factory.GetPlatformBackendForCurrentOS()
56 backend = desktop_browser_backend.DesktopBrowserBackend(
57 self.finder_options.browser_options, self._local_executable,
58 self._flash_path, self._is_content_shell, self._browser_directory,
59 output_profile_path=self.finder_options.output_profile_path,
60 extensions_to_load=self.finder_options.extensions_to_load)
61 return browser.Browser(backend, self._platform_backend)
63 def SupportsOptions(self, finder_options):
64 if (len(finder_options.extensions_to_load) != 0) and self._is_content_shell:
68 def UpdateExecutableIfNeeded(self):
71 def last_modification_time(self):
72 if os.path.exists(self._local_executable):
73 return os.path.getmtime(self._local_executable)
76 def SelectDefaultBrowser(possible_browsers):
77 local_builds_by_date = [
78 b for b in sorted(possible_browsers,
79 key=lambda b: b.last_modification_time())
81 if local_builds_by_date:
82 return local_builds_by_date[-1]
85 def CanFindAvailableBrowsers():
86 return not cros_interface.IsRunningOnCrosDevice()
88 def FindAllAvailableBrowsers(finder_options):
89 """Finds all the desktop browsers available on this machine."""
92 if not CanFindAvailableBrowsers():
96 if (sys.platform.startswith('linux') and
97 os.getenv('DISPLAY') == None):
100 # Look for a browser in the standard chrome build locations.
101 if finder_options.chrome_root:
102 chrome_root = finder_options.chrome_root
104 chrome_root = util.GetChromiumSrcDir()
106 flash_bin_dir = os.path.join(
107 chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi')
109 chromium_app_names = []
110 if sys.platform == 'darwin':
111 chromium_app_names.append('Chromium.app/Contents/MacOS/Chromium')
112 chromium_app_names.append('Google Chrome.app/Contents/MacOS/Google Chrome')
113 content_shell_app_name = 'Content Shell.app/Contents/MacOS/Content Shell'
114 flash_bin = 'PepperFlashPlayer.plugin'
115 flash_path = os.path.join(flash_bin_dir, 'mac', flash_bin)
116 flash_path_64 = os.path.join(flash_bin_dir, 'mac_64', flash_bin)
117 elif sys.platform.startswith('linux'):
118 chromium_app_names.append('chrome')
119 content_shell_app_name = 'content_shell'
120 flash_bin = 'libpepflashplayer.so'
121 flash_path = os.path.join(flash_bin_dir, 'linux', flash_bin)
122 flash_path_64 = os.path.join(flash_bin_dir, 'linux_x64', flash_bin)
123 elif sys.platform.startswith('win'):
124 chromium_app_names.append('chrome.exe')
125 content_shell_app_name = 'content_shell.exe'
126 flash_bin = 'pepflashplayer.dll'
127 flash_path = os.path.join(flash_bin_dir, 'win', flash_bin)
128 flash_path_64 = os.path.join(flash_bin_dir, 'win_x64', flash_bin)
130 raise Exception('Platform not recognized')
132 def IsExecutable(path):
133 return os.path.isfile(path) and os.access(path, os.X_OK)
135 # Add the explicit browser executable if given.
136 if finder_options.browser_executable:
137 normalized_executable = os.path.expanduser(
138 finder_options.browser_executable)
139 if IsExecutable(normalized_executable):
140 browser_directory = os.path.dirname(finder_options.browser_executable)
141 browsers.append(PossibleDesktopBrowser('exact', finder_options,
142 normalized_executable, flash_path,
143 False, browser_directory))
145 raise Exception('%s specified by --browser-executable does not exist',
146 normalized_executable)
148 def AddIfFound(browser_type, build_dir, type_dir, app_name, content_shell):
149 browser_directory = os.path.join(chrome_root, build_dir, type_dir)
150 app = os.path.join(browser_directory, app_name)
151 if IsExecutable(app):
152 is_64 = browser_type.endswith('_x64')
153 browsers.append(PossibleDesktopBrowser(
154 browser_type, finder_options, app,
155 flash_path_64 if is_64 else flash_path,
156 content_shell, browser_directory, is_local_build=True))
161 for build_dir, build_type in util.GetBuildDirectories():
162 for chromium_app_name in chromium_app_names:
163 AddIfFound(build_type.lower(), build_dir, build_type,
164 chromium_app_name, False)
165 AddIfFound('content-shell-' + build_type.lower(), build_dir, build_type,
166 content_shell_app_name, True)
168 # Mac-specific options.
169 if sys.platform == 'darwin':
170 mac_canary_root = '/Applications/Google Chrome Canary.app/'
171 mac_canary = mac_canary_root + 'Contents/MacOS/Google Chrome Canary'
172 mac_system_root = '/Applications/Google Chrome.app'
173 mac_system = mac_system_root + '/Contents/MacOS/Google Chrome'
174 if IsExecutable(mac_canary):
175 browsers.append(PossibleDesktopBrowser('canary', finder_options,
176 mac_canary, None, False,
179 if IsExecutable(mac_system):
180 browsers.append(PossibleDesktopBrowser('system', finder_options,
181 mac_system, None, False,
184 # Linux specific options.
185 if sys.platform.startswith('linux'):
186 # Look for a google-chrome instance.
189 with open(os.devnull, 'w') as devnull:
190 found = subprocess.call(['google-chrome', '--version'],
191 stdout=devnull, stderr=devnull) == 0
195 browsers.append(PossibleDesktopBrowser('system', finder_options,
196 'google-chrome', None, False,
197 '/opt/google/chrome'))
199 # Win32-specific options.
200 if sys.platform.startswith('win'):
201 system_path = os.path.join('Google', 'Chrome', 'Application')
202 canary_path = os.path.join('Google', 'Chrome SxS', 'Application')
204 win_search_paths = [os.getenv('PROGRAMFILES(X86)'),
205 os.getenv('PROGRAMFILES'),
206 os.getenv('LOCALAPPDATA')]
208 def AddIfFoundWin(browser_name, search_path, app_path):
209 browser_directory = os.path.join(search_path, app_path)
210 for chromium_app_name in chromium_app_names:
211 app = os.path.join(browser_directory, chromium_app_name)
212 if IsExecutable(app):
213 browsers.append(PossibleDesktopBrowser(browser_name, finder_options,
219 for path in win_search_paths:
222 if AddIfFoundWin('canary', path, canary_path):
225 for path in win_search_paths:
228 if AddIfFoundWin('system', path, system_path):
231 if len(browsers) and not has_display:
233 'Found (%s), but you do not have a DISPLAY environment set.' %
234 ','.join([b.browser_type for b in browsers]))