Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / telemetry / telemetry / internal / browser / browser_finder.py
blob242f491e96fbc21d75476b3f84dfe1dcff219167
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.
5 """Finds browsers that can be controlled by telemetry."""
7 import logging
8 import operator
10 from telemetry import decorators
11 from telemetry.internal.backends.chrome import android_browser_finder
12 from telemetry.internal.backends.chrome import cros_browser_finder
13 from telemetry.internal.backends.chrome import desktop_browser_finder
14 from telemetry.internal.backends.chrome import ios_browser_finder
15 from telemetry.internal.browser import browser_finder_exceptions
16 from telemetry.internal.platform import device_finder
18 BROWSER_FINDERS = [
19 desktop_browser_finder,
20 android_browser_finder,
21 cros_browser_finder,
22 ios_browser_finder,
26 def FindAllBrowserTypes(options):
27 return reduce(operator.add,
28 [bf.FindAllBrowserTypes(options) for bf in BROWSER_FINDERS])
31 @decorators.Cache
32 def FindBrowser(options):
33 """Finds the best PossibleBrowser object given a BrowserOptions object.
35 Args:
36 A BrowserOptions object.
38 Returns:
39 A PossibleBrowser object.
41 Raises:
42 BrowserFinderException: Options improperly set, or an error occurred.
43 """
44 if options.__class__.__name__ == '_FakeBrowserFinderOptions':
45 return options.fake_possible_browser
46 if options.browser_type == 'exact' and options.browser_executable == None:
47 raise browser_finder_exceptions.BrowserFinderException(
48 '--browser=exact requires --browser-executable to be set.')
49 if options.browser_type != 'exact' and options.browser_executable != None:
50 raise browser_finder_exceptions.BrowserFinderException(
51 '--browser-executable requires --browser=exact.')
53 if options.browser_type == 'cros-chrome' and options.cros_remote == None:
54 raise browser_finder_exceptions.BrowserFinderException(
55 'browser_type=cros-chrome requires cros_remote be set.')
56 if (options.browser_type != 'cros-chrome' and
57 options.browser_type != 'cros-chrome-guest' and
58 options.cros_remote != None):
59 raise browser_finder_exceptions.BrowserFinderException(
60 '--remote requires --browser=cros-chrome or cros-chrome-guest.')
62 devices = device_finder.GetDevicesMatchingOptions(options)
63 browsers = []
64 default_browsers = []
65 for device in devices:
66 for finder in BROWSER_FINDERS:
67 if(options.browser_type and options.browser_type != 'any' and
68 options.browser_type not in finder.FindAllBrowserTypes(options)):
69 continue
70 curr_browsers = finder.FindAllAvailableBrowsers(options, device)
71 new_default_browser = finder.SelectDefaultBrowser(curr_browsers)
72 if new_default_browser:
73 default_browsers.append(new_default_browser)
74 browsers.extend(curr_browsers)
76 if options.browser_type == None:
77 if default_browsers:
78 default_browser = sorted(default_browsers,
79 key=lambda b: b.last_modification_time())[-1]
81 logging.warning('--browser omitted. Using most recent local build: %s' %
82 default_browser.browser_type)
83 default_browser.UpdateExecutableIfNeeded()
84 return default_browser
86 if len(browsers) == 1:
87 logging.warning('--browser omitted. Using only available browser: %s' %
88 browsers[0].browser_type)
89 browsers[0].UpdateExecutableIfNeeded()
90 return browsers[0]
92 raise browser_finder_exceptions.BrowserTypeRequiredException(
93 '--browser must be specified. Available browsers:\n%s' %
94 '\n'.join(sorted(set([b.browser_type for b in browsers]))))
96 if options.browser_type == 'any':
97 types = FindAllBrowserTypes(options)
98 def CompareBrowsersOnTypePriority(x, y):
99 x_idx = types.index(x.browser_type)
100 y_idx = types.index(y.browser_type)
101 return x_idx - y_idx
102 browsers.sort(CompareBrowsersOnTypePriority)
103 if len(browsers) >= 1:
104 browsers[0].UpdateExecutableIfNeeded()
105 return browsers[0]
106 else:
107 return None
109 matching_browsers = [b for b in browsers
110 if b.browser_type == options.browser_type and
111 b.SupportsOptions(options.browser_options)]
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]
122 if chosen_browser:
123 logging.info('Chose browser: %s' % (repr(chosen_browser)))
124 chosen_browser.UpdateExecutableIfNeeded()
126 return chosen_browser
129 @decorators.Cache
130 def GetAllAvailableBrowsers(options, device):
131 """Returns a list of available browsers on the device.
133 Args:
134 options: A BrowserOptions object.
135 device: The target device, which can be None.
137 Returns:
138 A list of browser instances.
140 Raises:
141 BrowserFinderException: Options are improperly set, or an error occurred.
143 if not device:
144 return []
145 possible_browsers = []
146 for browser_finder in BROWSER_FINDERS:
147 possible_browsers.extend(
148 browser_finder.FindAllAvailableBrowsers(options, device))
149 return possible_browsers
152 @decorators.Cache
153 def GetAllAvailableBrowserTypes(options):
154 """Returns a list of available browser types.
156 Args:
157 options: A BrowserOptions object.
159 Returns:
160 A list of browser type strings.
162 Raises:
163 BrowserFinderException: Options are improperly set, or an error occurred.
165 devices = device_finder.GetDevicesMatchingOptions(options)
166 possible_browsers = []
167 for device in devices:
168 possible_browsers.extend(GetAllAvailableBrowsers(options, device))
169 type_list = set([browser.browser_type for browser in possible_browsers])
170 # The reference build should be available for mac, linux and win, but the
171 # desktop browser finder won't return it in the list of browsers.
172 for browser in possible_browsers:
173 if (browser.target_os == 'darwin' or browser.target_os.startswith('linux')
174 or browser.target_os.startswith('win')):
175 type_list.add('reference')
176 break
177 type_list = list(type_list)
178 type_list.sort()
179 return type_list