| 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 <stddef.h> |
| 8 #include <stdint.h> |
| 9 |
| 7 #include <algorithm> | 10 #include <algorithm> |
| 8 #include <vector> | 11 #include <vector> |
| 9 | 12 |
| 10 #include "base/base64.h" | 13 #include "base/base64.h" |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/bind.h" | 14 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 14 #include "base/files/file_path.h" | 16 #include "base/files/file_path.h" |
| 15 #include "base/files/file_util.h" | 17 #include "base/files/file_util.h" |
| 16 #include "base/files/scoped_file.h" | 18 #include "base/files/scoped_file.h" |
| 17 #include "base/format_macros.h" | 19 #include "base/format_macros.h" |
| 18 #include "base/json/json_reader.h" | 20 #include "base/json/json_reader.h" |
| 19 #include "base/json/json_writer.h" | 21 #include "base/json/json_writer.h" |
| 20 #include "base/logging.h" | 22 #include "base/logging.h" |
| 21 #include "base/process/kill.h" | 23 #include "base/process/kill.h" |
| 22 #include "base/process/launch.h" | 24 #include "base/process/launch.h" |
| 23 #include "base/process/process.h" | 25 #include "base/process/process.h" |
| 24 #include "base/strings/string_number_conversions.h" | 26 #include "base/strings/string_number_conversions.h" |
| 25 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
| 26 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
| 27 #include "base/strings/utf_string_conversions.h" | 29 #include "base/strings/utf_string_conversions.h" |
| 28 #include "base/threading/platform_thread.h" | 30 #include "base/threading/platform_thread.h" |
| 29 #include "base/time/time.h" | 31 #include "base/time/time.h" |
| 30 #include "base/values.h" | 32 #include "base/values.h" |
| 33 #include "build/build_config.h" |
| 31 #include "chrome/common/chrome_constants.h" | 34 #include "chrome/common/chrome_constants.h" |
| 32 #include "chrome/test/chromedriver/chrome/chrome_android_impl.h" | 35 #include "chrome/test/chromedriver/chrome/chrome_android_impl.h" |
| 33 #include "chrome/test/chromedriver/chrome/chrome_desktop_impl.h" | 36 #include "chrome/test/chromedriver/chrome/chrome_desktop_impl.h" |
| 34 #include "chrome/test/chromedriver/chrome/chrome_finder.h" | 37 #include "chrome/test/chromedriver/chrome/chrome_finder.h" |
| 35 #include "chrome/test/chromedriver/chrome/chrome_remote_impl.h" | 38 #include "chrome/test/chromedriver/chrome/chrome_remote_impl.h" |
| 36 #include "chrome/test/chromedriver/chrome/device_manager.h" | 39 #include "chrome/test/chromedriver/chrome/device_manager.h" |
| 37 #include "chrome/test/chromedriver/chrome/devtools_client_impl.h" | 40 #include "chrome/test/chromedriver/chrome/devtools_client_impl.h" |
| 38 #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" | 41 #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" |
| 39 #include "chrome/test/chromedriver/chrome/devtools_http_client.h" | 42 #include "chrome/test/chromedriver/chrome/devtools_http_client.h" |
| 40 #include "chrome/test/chromedriver/chrome/embedded_automation_extension.h" | 43 #include "chrome/test/chromedriver/chrome/embedded_automation_extension.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 } | 109 } |
| 107 | 110 |
| 108 base::FilePath extension_dir = temp_dir.AppendASCII("internal"); | 111 base::FilePath extension_dir = temp_dir.AppendASCII("internal"); |
| 109 if (!zip::Unzip(extension_zip, extension_dir)) | 112 if (!zip::Unzip(extension_zip, extension_dir)) |
| 110 return Status(kUnknownError, "failed to unzip automation extension"); | 113 return Status(kUnknownError, "failed to unzip automation extension"); |
| 111 | 114 |
| 112 *automation_extension = extension_dir; | 115 *automation_extension = extension_dir; |
| 113 return Status(kOk); | 116 return Status(kOk); |
| 114 } | 117 } |
| 115 | 118 |
| 116 Status PrepareCommandLine(uint16 port, | 119 Status PrepareCommandLine(uint16_t port, |
| 117 const Capabilities& capabilities, | 120 const Capabilities& capabilities, |
| 118 base::CommandLine* prepared_command, | 121 base::CommandLine* prepared_command, |
| 119 base::ScopedTempDir* user_data_dir, | 122 base::ScopedTempDir* user_data_dir, |
| 120 base::ScopedTempDir* extension_dir, | 123 base::ScopedTempDir* extension_dir, |
| 121 std::vector<std::string>* extension_bg_pages) { | 124 std::vector<std::string>* extension_bg_pages) { |
| 122 base::FilePath program = capabilities.binary; | 125 base::FilePath program = capabilities.binary; |
| 123 if (program.empty()) { | 126 if (program.empty()) { |
| 124 if (!FindChrome(&program)) | 127 if (!FindChrome(&program)) |
| 125 return Status(kUnknownError, "cannot find Chrome binary"); | 128 return Status(kUnknownError, "cannot find Chrome binary"); |
| 126 } else if (!base::PathExists(program)) { | 129 } else if (!base::PathExists(program)) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 } | 291 } |
| 289 | 292 |
| 290 chrome->reset(new ChromeRemoteImpl(devtools_http_client.Pass(), | 293 chrome->reset(new ChromeRemoteImpl(devtools_http_client.Pass(), |
| 291 devtools_websocket_client.Pass(), | 294 devtools_websocket_client.Pass(), |
| 292 *devtools_event_listeners)); | 295 *devtools_event_listeners)); |
| 293 return Status(kOk); | 296 return Status(kOk); |
| 294 } | 297 } |
| 295 | 298 |
| 296 Status LaunchDesktopChrome( | 299 Status LaunchDesktopChrome( |
| 297 URLRequestContextGetter* context_getter, | 300 URLRequestContextGetter* context_getter, |
| 298 uint16 port, | 301 uint16_t port, |
| 299 scoped_ptr<PortReservation> port_reservation, | 302 scoped_ptr<PortReservation> port_reservation, |
| 300 const SyncWebSocketFactory& socket_factory, | 303 const SyncWebSocketFactory& socket_factory, |
| 301 const Capabilities& capabilities, | 304 const Capabilities& capabilities, |
| 302 ScopedVector<DevToolsEventListener>* devtools_event_listeners, | 305 ScopedVector<DevToolsEventListener>* devtools_event_listeners, |
| 303 scoped_ptr<Chrome>* chrome) { | 306 scoped_ptr<Chrome>* chrome) { |
| 304 base::CommandLine command(base::CommandLine::NO_PROGRAM); | 307 base::CommandLine command(base::CommandLine::NO_PROGRAM); |
| 305 base::ScopedTempDir user_data_dir; | 308 base::ScopedTempDir user_data_dir; |
| 306 base::ScopedTempDir extension_dir; | 309 base::ScopedTempDir extension_dir; |
| 307 std::vector<std::string> extension_bg_pages; | 310 std::vector<std::string> extension_bg_pages; |
| 308 Status status = PrepareCommandLine(port, | 311 Status status = PrepareCommandLine(port, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 extension_bg_pages[i], | 446 extension_bg_pages[i], |
| 444 status); | 447 status); |
| 445 } | 448 } |
| 446 } | 449 } |
| 447 *chrome = chrome_desktop.Pass(); | 450 *chrome = chrome_desktop.Pass(); |
| 448 return Status(kOk); | 451 return Status(kOk); |
| 449 } | 452 } |
| 450 | 453 |
| 451 Status LaunchAndroidChrome( | 454 Status LaunchAndroidChrome( |
| 452 URLRequestContextGetter* context_getter, | 455 URLRequestContextGetter* context_getter, |
| 453 uint16 port, | 456 uint16_t port, |
| 454 scoped_ptr<PortReservation> port_reservation, | 457 scoped_ptr<PortReservation> port_reservation, |
| 455 const SyncWebSocketFactory& socket_factory, | 458 const SyncWebSocketFactory& socket_factory, |
| 456 const Capabilities& capabilities, | 459 const Capabilities& capabilities, |
| 457 ScopedVector<DevToolsEventListener>* devtools_event_listeners, | 460 ScopedVector<DevToolsEventListener>* devtools_event_listeners, |
| 458 DeviceManager* device_manager, | 461 DeviceManager* device_manager, |
| 459 scoped_ptr<Chrome>* chrome) { | 462 scoped_ptr<Chrome>* chrome) { |
| 460 Status status(kOk); | 463 Status status(kOk); |
| 461 scoped_ptr<Device> device; | 464 scoped_ptr<Device> device; |
| 462 if (capabilities.android_device_serial.empty()) { | 465 if (capabilities.android_device_serial.empty()) { |
| 463 status = device_manager->AcquireDevice(&device); | 466 status = device_manager->AcquireDevice(&device); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 PortManager* port_manager, | 525 PortManager* port_manager, |
| 523 const Capabilities& capabilities, | 526 const Capabilities& capabilities, |
| 524 ScopedVector<DevToolsEventListener>* devtools_event_listeners, | 527 ScopedVector<DevToolsEventListener>* devtools_event_listeners, |
| 525 scoped_ptr<Chrome>* chrome) { | 528 scoped_ptr<Chrome>* chrome) { |
| 526 if (capabilities.IsRemoteBrowser()) { | 529 if (capabilities.IsRemoteBrowser()) { |
| 527 return LaunchRemoteChromeSession( | 530 return LaunchRemoteChromeSession( |
| 528 context_getter, socket_factory, | 531 context_getter, socket_factory, |
| 529 capabilities, devtools_event_listeners, chrome); | 532 capabilities, devtools_event_listeners, chrome); |
| 530 } | 533 } |
| 531 | 534 |
| 532 uint16 port = 0; | 535 uint16_t port = 0; |
| 533 scoped_ptr<PortReservation> port_reservation; | 536 scoped_ptr<PortReservation> port_reservation; |
| 534 Status port_status(kOk); | 537 Status port_status(kOk); |
| 535 | 538 |
| 536 if (capabilities.IsAndroid()) { | 539 if (capabilities.IsAndroid()) { |
| 537 if (port_server) | 540 if (port_server) |
| 538 port_status = port_server->ReservePort(&port, &port_reservation); | 541 port_status = port_server->ReservePort(&port, &port_reservation); |
| 539 else | 542 else |
| 540 port_status = port_manager->ReservePortFromPool(&port, &port_reservation); | 543 port_status = port_manager->ReservePortFromPool(&port, &port_reservation); |
| 541 if (port_status.IsError()) | 544 if (port_status.IsError()) |
| 542 return Status(kUnknownError, "cannot reserve port for Chrome", | 545 return Status(kUnknownError, "cannot reserve port for Chrome", |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 id->begin() + i + 1), | 579 id->begin() + i + 1), |
| 577 &val)) { | 580 &val)) { |
| 578 (*id)[i] = val + 'a'; | 581 (*id)[i] = val + 'a'; |
| 579 } else { | 582 } else { |
| 580 (*id)[i] = 'a'; | 583 (*id)[i] = 'a'; |
| 581 } | 584 } |
| 582 } | 585 } |
| 583 } | 586 } |
| 584 | 587 |
| 585 std::string GenerateExtensionId(const std::string& input) { | 588 std::string GenerateExtensionId(const std::string& input) { |
| 586 uint8 hash[16]; | 589 uint8_t hash[16]; |
| 587 crypto::SHA256HashString(input, hash, sizeof(hash)); | 590 crypto::SHA256HashString(input, hash, sizeof(hash)); |
| 588 std::string output = base::ToLowerASCII(base::HexEncode(hash, sizeof(hash))); | 591 std::string output = base::ToLowerASCII(base::HexEncode(hash, sizeof(hash))); |
| 589 ConvertHexadecimalToIDAlphabet(&output); | 592 ConvertHexadecimalToIDAlphabet(&output); |
| 590 return output; | 593 return output; |
| 591 } | 594 } |
| 592 | 595 |
| 593 Status GetExtensionBackgroundPage(const base::DictionaryValue* manifest, | 596 Status GetExtensionBackgroundPage(const base::DictionaryValue* manifest, |
| 594 const std::string& id, | 597 const std::string& id, |
| 595 std::string* bg_page) { | 598 std::string* bg_page) { |
| 596 std::string bg_page_name; | 599 std::string bg_page_name; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 if (magic_header.size() != 4) | 631 if (magic_header.size() != 4) |
| 629 return Status(kUnknownError, "cannot extract magic number"); | 632 return Status(kUnknownError, "cannot extract magic number"); |
| 630 | 633 |
| 631 const bool is_crx_file = magic_header == "Cr24"; | 634 const bool is_crx_file = magic_header == "Cr24"; |
| 632 | 635 |
| 633 if (is_crx_file) { | 636 if (is_crx_file) { |
| 634 // Assume a CRX v2 file - see https://developer.chrome.com/extensions/crx. | 637 // Assume a CRX v2 file - see https://developer.chrome.com/extensions/crx. |
| 635 std::string key_len_str = decoded_extension.substr(8, 4); | 638 std::string key_len_str = decoded_extension.substr(8, 4); |
| 636 if (key_len_str.size() != 4) | 639 if (key_len_str.size() != 4) |
| 637 return Status(kUnknownError, "cannot extract public key length"); | 640 return Status(kUnknownError, "cannot extract public key length"); |
| 638 uint32 key_len = *reinterpret_cast<const uint32*>(key_len_str.c_str()); | 641 uint32_t key_len = *reinterpret_cast<const uint32_t*>(key_len_str.c_str()); |
| 639 public_key = decoded_extension.substr(16, key_len); | 642 public_key = decoded_extension.substr(16, key_len); |
| 640 if (key_len != public_key.size()) | 643 if (key_len != public_key.size()) |
| 641 return Status(kUnknownError, "invalid public key length"); | 644 return Status(kUnknownError, "invalid public key length"); |
| 642 } else { | 645 } else { |
| 643 // Not a CRX file. Generate RSA keypair to get a valid extension id. | 646 // Not a CRX file. Generate RSA keypair to get a valid extension id. |
| 644 scoped_ptr<crypto::RSAPrivateKey> key_pair( | 647 scoped_ptr<crypto::RSAPrivateKey> key_pair( |
| 645 crypto::RSAPrivateKey::Create(2048)); | 648 crypto::RSAPrivateKey::Create(2048)); |
| 646 if (!key_pair) | 649 if (!key_pair) |
| 647 return Status(kUnknownError, "cannot generate RSA key pair"); | 650 return Status(kUnknownError, "cannot generate RSA key pair"); |
| 648 std::vector<uint8> public_key_vector; | 651 std::vector<uint8_t> public_key_vector; |
| 649 if (!key_pair->ExportPublicKey(&public_key_vector)) | 652 if (!key_pair->ExportPublicKey(&public_key_vector)) |
| 650 return Status(kUnknownError, "cannot extract public key"); | 653 return Status(kUnknownError, "cannot extract public key"); |
| 651 public_key = | 654 public_key = |
| 652 std::string(reinterpret_cast<char*>(&public_key_vector.front()), | 655 std::string(reinterpret_cast<char*>(&public_key_vector.front()), |
| 653 public_key_vector.size()); | 656 public_key_vector.size()); |
| 654 } | 657 } |
| 655 std::string public_key_base64; | 658 std::string public_key_base64; |
| 656 base::Base64Encode(public_key, &public_key_base64); | 659 base::Base64Encode(public_key, &public_key_base64); |
| 657 std::string id = GenerateExtensionId(public_key); | 660 std::string id = GenerateExtensionId(public_key); |
| 658 | 661 |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 // Write empty "First Run" file, otherwise Chrome will wipe the default | 856 // Write empty "First Run" file, otherwise Chrome will wipe the default |
| 854 // profile that was written. | 857 // profile that was written. |
| 855 if (base::WriteFile( | 858 if (base::WriteFile( |
| 856 user_data_dir.Append(chrome::kFirstRunSentinel), "", 0) != 0) { | 859 user_data_dir.Append(chrome::kFirstRunSentinel), "", 0) != 0) { |
| 857 return Status(kUnknownError, "failed to write first run file"); | 860 return Status(kUnknownError, "failed to write first run file"); |
| 858 } | 861 } |
| 859 return Status(kOk); | 862 return Status(kOk); |
| 860 } | 863 } |
| 861 | 864 |
| 862 } // namespace internal | 865 } // namespace internal |
| OLD | NEW |