• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2012 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
5"""Finds browsers that can be controlled by telemetry."""
6
7import logging
8import operator
9
10from telemetry import decorators
11from telemetry.core.backends.chrome import android_browser_finder
12from telemetry.core.backends.chrome import cros_browser_finder
13from telemetry.core.backends.chrome import desktop_browser_finder
14from telemetry.core.backends.webdriver import webdriver_desktop_browser_finder
15
16
17BROWSER_FINDERS = [
18  desktop_browser_finder,
19  android_browser_finder,
20  cros_browser_finder,
21  webdriver_desktop_browser_finder,
22  ]
23
24ALL_BROWSER_TYPES = reduce(operator.add,
25                           [bf.ALL_BROWSER_TYPES for bf in BROWSER_FINDERS])
26
27
28class BrowserTypeRequiredException(Exception):
29  pass
30
31
32class BrowserFinderException(Exception):
33  pass
34
35
36@decorators.Cache
37def FindBrowser(options):
38  """Finds the best PossibleBrowser object given a BrowserOptions object.
39
40  Args:
41    A BrowserOptions object.
42
43  Returns:
44    A PossibleBrowser object.
45
46  Raises:
47    BrowserFinderException: Options improperly set, or an error occurred.
48  """
49  if options.browser_type == 'exact' and options.browser_executable == None:
50    raise BrowserFinderException(
51        '--browser=exact requires --browser-executable to be set.')
52  if options.browser_type != 'exact' and options.browser_executable != None:
53    raise BrowserFinderException(
54        '--browser-executable requires --browser=exact.')
55
56  if options.browser_type == 'cros-chrome' and options.cros_remote == None:
57    raise BrowserFinderException(
58        'browser_type=cros-chrome requires cros_remote be set.')
59  if (options.browser_type != 'cros-chrome' and
60      options.browser_type != 'cros-chrome-guest' and
61      options.cros_remote != None):
62    raise BrowserFinderException(
63        '--remote requires --browser=cros-chrome or cros-chrome-guest.')
64
65  browsers = []
66  default_browsers = []
67  for finder in BROWSER_FINDERS:
68    if (options.browser_type and options.browser_type != 'any' and
69        options.browser_type not in finder.ALL_BROWSER_TYPES):
70      continue
71    curr_browsers = finder.FindAllAvailableBrowsers(options)
72    new_default_browser = finder.SelectDefaultBrowser(curr_browsers)
73    if new_default_browser:
74      default_browsers.append(new_default_browser)
75    browsers.extend(curr_browsers)
76
77  if options.browser_type == None:
78    if default_browsers:
79      default_browser = sorted(default_browsers,
80                               key=lambda b: b.last_modification_time())[-1]
81
82      logging.warning('--browser omitted. Using most recent local build: %s' %
83                      default_browser.browser_type)
84      default_browser.UpdateExecutableIfNeeded()
85      return default_browser
86
87    if len(browsers) == 1:
88      logging.warning('--browser omitted. Using only available browser: %s' %
89                      browsers[0].browser_type)
90      browsers[0].UpdateExecutableIfNeeded()
91      return browsers[0]
92
93    raise BrowserTypeRequiredException(
94        '--browser must be specified. Available browsers:\n%s' %
95        '\n'.join(sorted(set([b.browser_type for b in browsers]))))
96
97  if options.browser_type == 'any':
98    types = ALL_BROWSER_TYPES
99    def CompareBrowsersOnTypePriority(x, y):
100      x_idx = types.index(x.browser_type)
101      y_idx = types.index(y.browser_type)
102      return x_idx - y_idx
103    browsers.sort(CompareBrowsersOnTypePriority)
104    if len(browsers) >= 1:
105      browsers[0].UpdateExecutableIfNeeded()
106      return browsers[0]
107    else:
108      return None
109
110  matching_browsers = [b for b in browsers
111      if b.browser_type == options.browser_type and b.SupportsOptions(options)]
112
113  chosen_browser = None
114  if len(matching_browsers) == 1:
115    chosen_browser = matching_browsers[0]
116  elif len(matching_browsers) > 1:
117    logging.warning('Multiple browsers of the same type found: %s' % (
118                    repr(matching_browsers)))
119    chosen_browser = sorted(matching_browsers,
120                            key=lambda b: b.last_modification_time())[-1]
121
122  if chosen_browser:
123    logging.info('Chose browser: %s' % (repr(chosen_browser)))
124    chosen_browser.UpdateExecutableIfNeeded()
125
126  return chosen_browser
127
128
129@decorators.Cache
130def GetAllAvailableBrowserTypes(options):
131  """Returns a list of available browser types.
132
133  Args:
134    options: A BrowserOptions object.
135
136  Returns:
137    A list of browser type strings.
138
139  Raises:
140    BrowserFinderException: Options are improperly set, or an error occurred.
141  """
142  browsers = []
143  for finder in BROWSER_FINDERS:
144    browsers.extend(finder.FindAllAvailableBrowsers(options))
145
146  type_list = set([browser.browser_type for browser in browsers])
147  type_list = list(type_list)
148  type_list.sort()
149  return type_list
150