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