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."""
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
19 desktop_browser_finder
,
20 android_browser_finder
,
26 def FindAllBrowserTypes(options
):
27 return reduce(operator
.add
,
28 [bf
.FindAllBrowserTypes(options
) for bf
in BROWSER_FINDERS
])
32 def FindBrowser(options
):
33 """Finds the best PossibleBrowser object given a BrowserOptions object.
36 A BrowserOptions object.
39 A PossibleBrowser object.
42 BrowserFinderException: Options improperly set, or an error occurred.
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
)
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
)):
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:
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()
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
)
102 browsers
.sort(CompareBrowsersOnTypePriority
)
103 if len(browsers
) >= 1:
104 browsers
[0].UpdateExecutableIfNeeded()
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]
123 logging
.info('Chose browser: %s' % (repr(chosen_browser
)))
124 chosen_browser
.UpdateExecutableIfNeeded()
126 return chosen_browser
130 def GetAllAvailableBrowsers(options
, device
):
131 """Returns a list of available browsers on the device.
134 options: A BrowserOptions object.
135 device: The target device, which can be None.
138 A list of browser instances.
141 BrowserFinderException: Options are improperly set, or an error occurred.
145 possible_browsers
= []
146 for browser_finder
in BROWSER_FINDERS
:
147 possible_browsers
.extend(
148 browser_finder
.FindAllAvailableBrowsers(options
, device
))
149 return possible_browsers
153 def GetAllAvailableBrowserTypes(options
):
154 """Returns a list of available browser types.
157 options: A BrowserOptions object.
160 A list of browser type strings.
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')
177 type_list
= list(type_list
)