blob: 7baed5271575f5eee99a814c61cf724dbdf725ca [file] [log] [blame]
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Finds desktop browsers that can be controlled by telemetry."""
import logging
from operator import attrgetter
import os
import platform
import subprocess
import sys
from telemetry.core import browser
from telemetry.core import platform as core_platform
from telemetry.core import possible_browser
from telemetry.core import util
from telemetry.core.backends.chrome import cros_interface
from telemetry.core.backends.chrome import desktop_browser_backend
ALL_BROWSER_TYPES = ','.join([
'exact',
'release',
'release_x64',
'debug',
'debug_x64',
'canary',
'content-shell-debug',
'content-shell-release',
'system'])
class PossibleDesktopBrowser(possible_browser.PossibleBrowser):
"""A desktop browser that can be controlled."""
def __init__(self, browser_type, finder_options, executable, flash_path,
is_content_shell, browser_directory, is_local_build=False):
super(PossibleDesktopBrowser, self).__init__(browser_type, finder_options)
self._local_executable = executable
self._flash_path = flash_path
self._is_content_shell = is_content_shell
self._browser_directory = browser_directory
self.is_local_build = is_local_build
def __repr__(self):
return 'PossibleDesktopBrowser(browser_type=%s)' % self.browser_type
def Create(self):
backend = desktop_browser_backend.DesktopBrowserBackend(
self.finder_options.browser_options, self._local_executable,
self._flash_path, self._is_content_shell, self._browser_directory,
output_profile_path=self.finder_options.output_profile_path,
extensions_to_load=self.finder_options.extensions_to_load)
b = browser.Browser(backend,
core_platform.CreatePlatformBackendForCurrentOS())
return b
def SupportsOptions(self, finder_options):
if (len(finder_options.extensions_to_load) != 0) and self._is_content_shell:
return False
return True
def UpdateExecutableIfNeeded(self):
pass
@property
def last_modification_time(self):
if os.path.exists(self._local_executable):
return os.path.getmtime(self._local_executable)
return -1
def SelectDefaultBrowser(possible_browsers):
local_builds_by_date = [
b for b in sorted(possible_browsers,
key=attrgetter('last_modification_time'))
if b.is_local_build]
if local_builds_by_date:
return local_builds_by_date[-1]
return None
def CanFindAvailableBrowsers():
return not cros_interface.IsRunningOnCrosDevice()
def FindAllAvailableBrowsers(finder_options):
"""Finds all the desktop browsers available on this machine."""
browsers = []
if not CanFindAvailableBrowsers():
return []
has_display = True
if (sys.platform.startswith('linux') and
os.getenv('DISPLAY') == None):
has_display = False
# Look for a browser in the standard chrome build locations.
if finder_options.chrome_root:
chrome_root = finder_options.chrome_root
else:
chrome_root = util.GetChromiumSrcDir()
if sys.platform == 'darwin':
chromium_app_name = 'Chromium.app/Contents/MacOS/Chromium'
content_shell_app_name = 'Content Shell.app/Contents/MacOS/Content Shell'
mac_dir = 'mac'
if platform.architecture()[0] == '64bit':
mac_dir = 'mac_64'
flash_path = os.path.join(
chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi',
mac_dir, 'PepperFlashPlayer.plugin')
elif sys.platform.startswith('linux'):
chromium_app_name = 'chrome'
content_shell_app_name = 'content_shell'
linux_dir = 'linux'
if platform.architecture()[0] == '64bit':
linux_dir = 'linux_x64'
flash_path = os.path.join(
chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi',
linux_dir, 'libpepflashplayer.so')
elif sys.platform.startswith('win'):
chromium_app_name = 'chrome.exe'
content_shell_app_name = 'content_shell.exe'
win_dir = 'win'
if platform.architecture()[0] == '64bit':
win_dir = 'win_x64'
flash_path = os.path.join(
chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi',
win_dir, 'pepflashplayer.dll')
else:
raise Exception('Platform not recognized')
def IsExecutable(path):
return os.path.isfile(path) and os.access(path, os.X_OK)
# Add the explicit browser executable if given.
if finder_options.browser_executable:
normalized_executable = os.path.expanduser(
finder_options.browser_executable)
if IsExecutable(normalized_executable):
browser_directory = os.path.dirname(finder_options.browser_executable)
browsers.append(PossibleDesktopBrowser('exact', finder_options,
normalized_executable, flash_path,
False, browser_directory))
else:
logging.warning('%s specified by browser_executable does not exist',
normalized_executable)
def AddIfFound(browser_type, build_dir, type_dir, app_name, content_shell):
browser_directory = os.path.join(chrome_root, build_dir, type_dir)
app = os.path.join(browser_directory, app_name)
if IsExecutable(app):
browsers.append(PossibleDesktopBrowser(browser_type, finder_options,
app, flash_path, content_shell,
browser_directory,
is_local_build=True))
return True
return False
# Add local builds
for build_dir, build_type in util.GetBuildDirectories():
AddIfFound(build_type.lower(), build_dir, build_type,
chromium_app_name, False)
AddIfFound('content-shell-' + build_type.lower(), build_dir, build_type,
content_shell_app_name, True)
# Mac-specific options.
if sys.platform == 'darwin':
mac_canary_root = '/Applications/Google Chrome Canary.app/'
mac_canary = mac_canary_root + 'Contents/MacOS/Google Chrome Canary'
mac_system_root = '/Applications/Google Chrome.app'
mac_system = mac_system_root + '/Contents/MacOS/Google Chrome'
if IsExecutable(mac_canary):
browsers.append(PossibleDesktopBrowser('canary', finder_options,
mac_canary, None, False,
mac_canary_root))
if IsExecutable(mac_system):
browsers.append(PossibleDesktopBrowser('system', finder_options,
mac_system, None, False,
mac_system_root))
# Linux specific options.
if sys.platform.startswith('linux'):
# Look for a google-chrome instance.
found = False
try:
with open(os.devnull, 'w') as devnull:
found = subprocess.call(['google-chrome', '--version'],
stdout=devnull, stderr=devnull) == 0
except OSError:
pass
if found:
browsers.append(PossibleDesktopBrowser('system', finder_options,
'google-chrome', None, False,
'/opt/google/chrome'))
# Win32-specific options.
if sys.platform.startswith('win'):
system_path = os.path.join('Google', 'Chrome', 'Application')
canary_path = os.path.join('Google', 'Chrome SxS', 'Application')
win_search_paths = [os.getenv('PROGRAMFILES(X86)'),
os.getenv('PROGRAMFILES'),
os.getenv('LOCALAPPDATA')]
def AddIfFoundWin(browser_name, app_path):
browser_directory = os.path.join(path, app_path)
app = os.path.join(browser_directory, chromium_app_name)
if IsExecutable(app):
browsers.append(PossibleDesktopBrowser(browser_name, finder_options,
app, flash_path, False,
browser_directory))
return True
return False
for path in win_search_paths:
if not path:
continue
if AddIfFoundWin('canary', canary_path):
break
for path in win_search_paths:
if not path:
continue
if AddIfFoundWin('system', system_path):
break
if len(browsers) and not has_display:
logging.warning(
'Found (%s), but you do not have a DISPLAY environment set.' %
','.join([b.browser_type for b in browsers]))
return []
return browsers