OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/test/chromedriver/chrome_launcher.h" | 5 #include "chrome/test/chromedriver/chrome_launcher.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "base/threading/platform_thread.h" | 25 #include "base/threading/platform_thread.h" |
26 #include "base/time/time.h" | 26 #include "base/time/time.h" |
27 #include "base/values.h" | 27 #include "base/values.h" |
28 #include "chrome/test/chromedriver/chrome/chrome_android_impl.h" | 28 #include "chrome/test/chromedriver/chrome/chrome_android_impl.h" |
29 #include "chrome/test/chromedriver/chrome/chrome_desktop_impl.h" | 29 #include "chrome/test/chromedriver/chrome/chrome_desktop_impl.h" |
30 #include "chrome/test/chromedriver/chrome/chrome_existing_impl.h" | 30 #include "chrome/test/chromedriver/chrome/chrome_existing_impl.h" |
31 #include "chrome/test/chromedriver/chrome/chrome_finder.h" | 31 #include "chrome/test/chromedriver/chrome/chrome_finder.h" |
32 #include "chrome/test/chromedriver/chrome/device_manager.h" | 32 #include "chrome/test/chromedriver/chrome/device_manager.h" |
33 #include "chrome/test/chromedriver/chrome/devtools_http_client.h" | 33 #include "chrome/test/chromedriver/chrome/devtools_http_client.h" |
34 #include "chrome/test/chromedriver/chrome/embedded_automation_extension.h" | 34 #include "chrome/test/chromedriver/chrome/embedded_automation_extension.h" |
35 #include "chrome/test/chromedriver/chrome/log.h" | |
36 #include "chrome/test/chromedriver/chrome/status.h" | 35 #include "chrome/test/chromedriver/chrome/status.h" |
37 #include "chrome/test/chromedriver/chrome/user_data_dir.h" | 36 #include "chrome/test/chromedriver/chrome/user_data_dir.h" |
38 #include "chrome/test/chromedriver/chrome/version.h" | 37 #include "chrome/test/chromedriver/chrome/version.h" |
39 #include "chrome/test/chromedriver/chrome/web_view.h" | 38 #include "chrome/test/chromedriver/chrome/web_view.h" |
40 #include "chrome/test/chromedriver/chrome/zip.h" | 39 #include "chrome/test/chromedriver/chrome/zip.h" |
41 #include "chrome/test/chromedriver/net/net_util.h" | 40 #include "chrome/test/chromedriver/net/net_util.h" |
42 #include "chrome/test/chromedriver/net/url_request_context_getter.h" | 41 #include "chrome/test/chromedriver/net/url_request_context_getter.h" |
43 #include "crypto/sha2.h" | 42 #include "crypto/sha2.h" |
44 | 43 |
45 namespace { | 44 namespace { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 return status; | 139 return status; |
141 switches.AppendToCommandLine(&command); | 140 switches.AppendToCommandLine(&command); |
142 *prepared_command = command; | 141 *prepared_command = command; |
143 return Status(kOk); | 142 return Status(kOk); |
144 } | 143 } |
145 | 144 |
146 Status WaitForDevToolsAndCheckVersion( | 145 Status WaitForDevToolsAndCheckVersion( |
147 const NetAddress& address, | 146 const NetAddress& address, |
148 URLRequestContextGetter* context_getter, | 147 URLRequestContextGetter* context_getter, |
149 const SyncWebSocketFactory& socket_factory, | 148 const SyncWebSocketFactory& socket_factory, |
150 Log* log, | |
151 scoped_ptr<DevToolsHttpClient>* user_client) { | 149 scoped_ptr<DevToolsHttpClient>* user_client) { |
152 scoped_ptr<DevToolsHttpClient> client(new DevToolsHttpClient( | 150 scoped_ptr<DevToolsHttpClient> client(new DevToolsHttpClient( |
153 address, context_getter, socket_factory, log)); | 151 address, context_getter, socket_factory)); |
154 base::TimeTicks deadline = | 152 base::TimeTicks deadline = |
155 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(20); | 153 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(20); |
156 Status status = client->Init(deadline - base::TimeTicks::Now()); | 154 Status status = client->Init(deadline - base::TimeTicks::Now()); |
157 if (status.IsError()) | 155 if (status.IsError()) |
158 return status; | 156 return status; |
159 if (client->build_no() < kMinimumSupportedChromeBuildNo) { | 157 if (client->build_no() < kMinimumSupportedChromeBuildNo) { |
160 return Status(kUnknownError, "Chrome version must be >= " + | 158 return Status(kUnknownError, "Chrome version must be >= " + |
161 GetMinimumSupportedChromeVersion()); | 159 GetMinimumSupportedChromeVersion()); |
162 } | 160 } |
163 | 161 |
164 while (base::TimeTicks::Now() < deadline) { | 162 while (base::TimeTicks::Now() < deadline) { |
165 WebViewsInfo views_info; | 163 WebViewsInfo views_info; |
166 client->GetWebViewsInfo(&views_info); | 164 client->GetWebViewsInfo(&views_info); |
167 for (size_t i = 0; i < views_info.GetSize(); ++i) { | 165 for (size_t i = 0; i < views_info.GetSize(); ++i) { |
168 if (views_info.Get(i).type == WebViewInfo::kPage) { | 166 if (views_info.Get(i).type == WebViewInfo::kPage) { |
169 *user_client = client.Pass(); | 167 *user_client = client.Pass(); |
170 return Status(kOk); | 168 return Status(kOk); |
171 } | 169 } |
172 } | 170 } |
173 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(50)); | 171 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(50)); |
174 } | 172 } |
175 return Status(kUnknownError, "unable to discover open pages"); | 173 return Status(kUnknownError, "unable to discover open pages"); |
176 } | 174 } |
177 | 175 |
178 Status LaunchExistingChromeSession( | 176 Status LaunchExistingChromeSession( |
179 URLRequestContextGetter* context_getter, | 177 URLRequestContextGetter* context_getter, |
180 const SyncWebSocketFactory& socket_factory, | 178 const SyncWebSocketFactory& socket_factory, |
181 Log* log, | |
182 const Capabilities& capabilities, | 179 const Capabilities& capabilities, |
183 ScopedVector<DevToolsEventListener>& devtools_event_listeners, | 180 ScopedVector<DevToolsEventListener>& devtools_event_listeners, |
184 scoped_ptr<Chrome>* chrome) { | 181 scoped_ptr<Chrome>* chrome) { |
185 Status status(kOk); | 182 Status status(kOk); |
186 scoped_ptr<DevToolsHttpClient> devtools_client; | 183 scoped_ptr<DevToolsHttpClient> devtools_client; |
187 status = WaitForDevToolsAndCheckVersion( | 184 status = WaitForDevToolsAndCheckVersion( |
188 capabilities.debugger_address, context_getter, socket_factory, log, | 185 capabilities.debugger_address, context_getter, socket_factory, |
189 &devtools_client); | 186 &devtools_client); |
190 if (status.IsError()) { | 187 if (status.IsError()) { |
191 return Status(kUnknownError, "cannot connect to chrome at " + | 188 return Status(kUnknownError, "cannot connect to chrome at " + |
192 capabilities.debugger_address.ToString(), | 189 capabilities.debugger_address.ToString(), |
193 status); | 190 status); |
194 } | 191 } |
195 chrome->reset(new ChromeExistingImpl(devtools_client.Pass(), | 192 chrome->reset(new ChromeExistingImpl(devtools_client.Pass(), |
196 devtools_event_listeners, | 193 devtools_event_listeners)); |
197 log)); | |
198 return Status(kOk); | 194 return Status(kOk); |
199 } | 195 } |
200 | 196 |
201 Status LaunchDesktopChrome( | 197 Status LaunchDesktopChrome( |
202 URLRequestContextGetter* context_getter, | 198 URLRequestContextGetter* context_getter, |
203 int port, | 199 int port, |
204 const SyncWebSocketFactory& socket_factory, | 200 const SyncWebSocketFactory& socket_factory, |
205 Log* log, | |
206 const Capabilities& capabilities, | 201 const Capabilities& capabilities, |
207 ScopedVector<DevToolsEventListener>& devtools_event_listeners, | 202 ScopedVector<DevToolsEventListener>& devtools_event_listeners, |
208 scoped_ptr<Chrome>* chrome) { | 203 scoped_ptr<Chrome>* chrome) { |
209 CommandLine command(CommandLine::NO_PROGRAM); | 204 CommandLine command(CommandLine::NO_PROGRAM); |
210 base::ScopedTempDir user_data_dir; | 205 base::ScopedTempDir user_data_dir; |
211 base::ScopedTempDir extension_dir; | 206 base::ScopedTempDir extension_dir; |
212 std::vector<std::string> extension_bg_pages; | 207 std::vector<std::string> extension_bg_pages; |
213 Status status = PrepareCommandLine(port, | 208 Status status = PrepareCommandLine(port, |
214 capabilities, | 209 capabilities, |
215 &command, | 210 &command, |
(...skipping 10 matching lines...) Expand all Loading... |
226 options.environ["CHROME_LOG_FILE"] = capabilities.log_path; | 221 options.environ["CHROME_LOG_FILE"] = capabilities.log_path; |
227 if (capabilities.detach) | 222 if (capabilities.detach) |
228 options.new_process_group = true; | 223 options.new_process_group = true; |
229 #endif | 224 #endif |
230 | 225 |
231 #if defined(OS_WIN) | 226 #if defined(OS_WIN) |
232 std::string command_string = base::WideToUTF8(command.GetCommandLineString()); | 227 std::string command_string = base::WideToUTF8(command.GetCommandLineString()); |
233 #else | 228 #else |
234 std::string command_string = command.GetCommandLineString(); | 229 std::string command_string = command.GetCommandLineString(); |
235 #endif | 230 #endif |
236 log->AddEntry(Log::kLog, "Launching chrome: " + command_string); | 231 VLOG(0) << "Launching chrome: " << command_string; |
237 base::ProcessHandle process; | 232 base::ProcessHandle process; |
238 if (!base::LaunchProcess(command, options, &process)) | 233 if (!base::LaunchProcess(command, options, &process)) |
239 return Status(kUnknownError, "chrome failed to start"); | 234 return Status(kUnknownError, "chrome failed to start"); |
240 | 235 |
241 scoped_ptr<DevToolsHttpClient> devtools_client; | 236 scoped_ptr<DevToolsHttpClient> devtools_client; |
242 status = WaitForDevToolsAndCheckVersion( | 237 status = WaitForDevToolsAndCheckVersion( |
243 NetAddress(port), context_getter, socket_factory, log, &devtools_client); | 238 NetAddress(port), context_getter, socket_factory, &devtools_client); |
244 | 239 |
245 if (status.IsError()) { | 240 if (status.IsError()) { |
246 int exit_code; | 241 int exit_code; |
247 base::TerminationStatus chrome_status = | 242 base::TerminationStatus chrome_status = |
248 base::GetTerminationStatus(process, &exit_code); | 243 base::GetTerminationStatus(process, &exit_code); |
249 if (chrome_status != base::TERMINATION_STATUS_STILL_RUNNING) { | 244 if (chrome_status != base::TERMINATION_STATUS_STILL_RUNNING) { |
250 std::string termination_reason; | 245 std::string termination_reason; |
251 switch (chrome_status) { | 246 switch (chrome_status) { |
252 case base::TERMINATION_STATUS_NORMAL_TERMINATION: | 247 case base::TERMINATION_STATUS_NORMAL_TERMINATION: |
253 termination_reason = "exited normally"; | 248 termination_reason = "exited normally"; |
(...skipping 18 matching lines...) Expand all Loading... |
272 int exit_code; | 267 int exit_code; |
273 if (base::GetTerminationStatus(process, &exit_code) == | 268 if (base::GetTerminationStatus(process, &exit_code) == |
274 base::TERMINATION_STATUS_STILL_RUNNING) | 269 base::TERMINATION_STATUS_STILL_RUNNING) |
275 return Status(kUnknownError, "cannot kill Chrome", status); | 270 return Status(kUnknownError, "cannot kill Chrome", status); |
276 } | 271 } |
277 return status; | 272 return status; |
278 } | 273 } |
279 scoped_ptr<ChromeDesktopImpl> chrome_desktop( | 274 scoped_ptr<ChromeDesktopImpl> chrome_desktop( |
280 new ChromeDesktopImpl(devtools_client.Pass(), | 275 new ChromeDesktopImpl(devtools_client.Pass(), |
281 devtools_event_listeners, | 276 devtools_event_listeners, |
282 log, | |
283 process, | 277 process, |
284 &user_data_dir, | 278 &user_data_dir, |
285 &extension_dir)); | 279 &extension_dir)); |
286 for (size_t i = 0; i < extension_bg_pages.size(); ++i) { | 280 for (size_t i = 0; i < extension_bg_pages.size(); ++i) { |
287 scoped_ptr<WebView> web_view; | 281 scoped_ptr<WebView> web_view; |
288 Status status = chrome_desktop->WaitForPageToLoad( | 282 Status status = chrome_desktop->WaitForPageToLoad( |
289 extension_bg_pages[i], base::TimeDelta::FromSeconds(10), &web_view); | 283 extension_bg_pages[i], base::TimeDelta::FromSeconds(10), &web_view); |
290 if (status.IsError()) { | 284 if (status.IsError()) { |
291 return Status(kUnknownError, | 285 return Status(kUnknownError, |
292 "failed to wait for extension background page to load: " + | 286 "failed to wait for extension background page to load: " + |
293 extension_bg_pages[i], | 287 extension_bg_pages[i], |
294 status); | 288 status); |
295 } | 289 } |
296 } | 290 } |
297 *chrome = chrome_desktop.Pass(); | 291 *chrome = chrome_desktop.Pass(); |
298 return Status(kOk); | 292 return Status(kOk); |
299 } | 293 } |
300 | 294 |
301 Status LaunchAndroidChrome( | 295 Status LaunchAndroidChrome( |
302 URLRequestContextGetter* context_getter, | 296 URLRequestContextGetter* context_getter, |
303 int port, | 297 int port, |
304 const SyncWebSocketFactory& socket_factory, | 298 const SyncWebSocketFactory& socket_factory, |
305 Log* log, | |
306 const Capabilities& capabilities, | 299 const Capabilities& capabilities, |
307 ScopedVector<DevToolsEventListener>& devtools_event_listeners, | 300 ScopedVector<DevToolsEventListener>& devtools_event_listeners, |
308 DeviceManager* device_manager, | 301 DeviceManager* device_manager, |
309 scoped_ptr<Chrome>* chrome) { | 302 scoped_ptr<Chrome>* chrome) { |
310 Status status(kOk); | 303 Status status(kOk); |
311 scoped_ptr<Device> device; | 304 scoped_ptr<Device> device; |
312 if (capabilities.android_device_serial.empty()) { | 305 if (capabilities.android_device_serial.empty()) { |
313 status = device_manager->AcquireDevice(&device); | 306 status = device_manager->AcquireDevice(&device); |
314 } else { | 307 } else { |
315 status = device_manager->AcquireSpecificDevice( | 308 status = device_manager->AcquireSpecificDevice( |
(...skipping 13 matching lines...) Expand all Loading... |
329 switches.ToString(), port); | 322 switches.ToString(), port); |
330 if (!status.IsOk()) { | 323 if (!status.IsOk()) { |
331 device->StopApp(); | 324 device->StopApp(); |
332 return status; | 325 return status; |
333 } | 326 } |
334 | 327 |
335 scoped_ptr<DevToolsHttpClient> devtools_client; | 328 scoped_ptr<DevToolsHttpClient> devtools_client; |
336 status = WaitForDevToolsAndCheckVersion(NetAddress(port), | 329 status = WaitForDevToolsAndCheckVersion(NetAddress(port), |
337 context_getter, | 330 context_getter, |
338 socket_factory, | 331 socket_factory, |
339 log, | |
340 &devtools_client); | 332 &devtools_client); |
341 if (status.IsError()) | 333 if (status.IsError()) |
342 return status; | 334 return status; |
343 | 335 |
344 chrome->reset(new ChromeAndroidImpl( | 336 chrome->reset(new ChromeAndroidImpl( |
345 devtools_client.Pass(), devtools_event_listeners, device.Pass(), log)); | 337 devtools_client.Pass(), devtools_event_listeners, device.Pass())); |
346 return Status(kOk); | 338 return Status(kOk); |
347 } | 339 } |
348 | 340 |
349 } // namespace | 341 } // namespace |
350 | 342 |
351 Status LaunchChrome( | 343 Status LaunchChrome( |
352 URLRequestContextGetter* context_getter, | 344 URLRequestContextGetter* context_getter, |
353 const SyncWebSocketFactory& socket_factory, | 345 const SyncWebSocketFactory& socket_factory, |
354 Log* log, | |
355 DeviceManager* device_manager, | 346 DeviceManager* device_manager, |
356 const Capabilities& capabilities, | 347 const Capabilities& capabilities, |
357 ScopedVector<DevToolsEventListener>& devtools_event_listeners, | 348 ScopedVector<DevToolsEventListener>& devtools_event_listeners, |
358 scoped_ptr<Chrome>* chrome) { | 349 scoped_ptr<Chrome>* chrome) { |
359 if (capabilities.IsExistingBrowser()) { | 350 if (capabilities.IsExistingBrowser()) { |
360 return LaunchExistingChromeSession( | 351 return LaunchExistingChromeSession( |
361 context_getter, socket_factory, | 352 context_getter, socket_factory, |
362 log, capabilities, devtools_event_listeners, chrome); | 353 capabilities, devtools_event_listeners, chrome); |
363 } | 354 } |
364 | 355 |
365 int port; | 356 int port; |
366 if (!FindOpenPort(&port)) | 357 if (!FindOpenPort(&port)) |
367 return Status(kUnknownError, "failed to find an open port for Chrome"); | 358 return Status(kUnknownError, "failed to find an open port for Chrome"); |
368 | 359 |
369 if (capabilities.IsAndroid()) { | 360 if (capabilities.IsAndroid()) { |
370 return LaunchAndroidChrome( | 361 return LaunchAndroidChrome( |
371 context_getter, port, socket_factory, log, capabilities, | 362 context_getter, port, socket_factory, capabilities, |
372 devtools_event_listeners, device_manager, chrome); | 363 devtools_event_listeners, device_manager, chrome); |
373 } else { | 364 } else { |
374 return LaunchDesktopChrome( | 365 return LaunchDesktopChrome( |
375 context_getter, port, socket_factory, log, capabilities, | 366 context_getter, port, socket_factory, capabilities, |
376 devtools_event_listeners, chrome); | 367 devtools_event_listeners, chrome); |
377 } | 368 } |
378 } | 369 } |
379 | 370 |
380 namespace internal { | 371 namespace internal { |
381 | 372 |
382 void ConvertHexadecimalToIDAlphabet(std::string* id) { | 373 void ConvertHexadecimalToIDAlphabet(std::string* id) { |
383 for (size_t i = 0; i < id->size(); ++i) { | 374 for (size_t i = 0; i < id->size(); ++i) { |
384 int val; | 375 int val; |
385 if (base::HexStringToInt(base::StringPiece(id->begin() + i, | 376 if (base::HexStringToInt(base::StringPiece(id->begin() + i, |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 // Write empty "First Run" file, otherwise Chrome will wipe the default | 590 // Write empty "First Run" file, otherwise Chrome will wipe the default |
600 // profile that was written. | 591 // profile that was written. |
601 if (file_util::WriteFile( | 592 if (file_util::WriteFile( |
602 user_data_dir.AppendASCII("First Run"), "", 0) != 0) { | 593 user_data_dir.AppendASCII("First Run"), "", 0) != 0) { |
603 return Status(kUnknownError, "failed to write first run file"); | 594 return Status(kUnknownError, "failed to write first run file"); |
604 } | 595 } |
605 return Status(kOk); | 596 return Status(kOk); |
606 } | 597 } |
607 | 598 |
608 } // namespace internal | 599 } // namespace internal |
OLD | NEW |