| 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 25 matching lines...) Expand all Loading... |
| 36 #include "chrome/test/chromedriver/chrome/status.h" | 36 #include "chrome/test/chromedriver/chrome/status.h" |
| 37 #include "chrome/test/chromedriver/chrome/user_data_dir.h" | 37 #include "chrome/test/chromedriver/chrome/user_data_dir.h" |
| 38 #include "chrome/test/chromedriver/chrome/version.h" | 38 #include "chrome/test/chromedriver/chrome/version.h" |
| 39 #include "chrome/test/chromedriver/chrome/web_view.h" | 39 #include "chrome/test/chromedriver/chrome/web_view.h" |
| 40 #include "chrome/test/chromedriver/chrome/zip.h" | 40 #include "chrome/test/chromedriver/chrome/zip.h" |
| 41 #include "chrome/test/chromedriver/net/url_request_context_getter.h" | 41 #include "chrome/test/chromedriver/net/url_request_context_getter.h" |
| 42 #include "crypto/sha2.h" | 42 #include "crypto/sha2.h" |
| 43 | 43 |
| 44 namespace { | 44 namespace { |
| 45 | 45 |
| 46 const char* kCommonSwitches[] = { | |
| 47 "ignore-certificate-errors", "metrics-recording-only"}; | |
| 48 | |
| 49 Status UnpackAutomationExtension(const base::FilePath& temp_dir, | 46 Status UnpackAutomationExtension(const base::FilePath& temp_dir, |
| 50 base::FilePath* automation_extension) { | 47 base::FilePath* automation_extension) { |
| 51 std::string decoded_extension; | 48 std::string decoded_extension; |
| 52 if (!base::Base64Decode(kAutomationExtension, &decoded_extension)) | 49 if (!base::Base64Decode(kAutomationExtension, &decoded_extension)) |
| 53 return Status(kUnknownError, "failed to base64decode automation extension"); | 50 return Status(kUnknownError, "failed to base64decode automation extension"); |
| 54 | 51 |
| 55 base::FilePath extension_zip = temp_dir.AppendASCII("internal.zip"); | 52 base::FilePath extension_zip = temp_dir.AppendASCII("internal.zip"); |
| 56 int size = static_cast<int>(decoded_extension.length()); | 53 int size = static_cast<int>(decoded_extension.length()); |
| 57 if (file_util::WriteFile(extension_zip, decoded_extension.c_str(), size) | 54 if (file_util::WriteFile(extension_zip, decoded_extension.c_str(), size) |
| 58 != size) { | 55 != size) { |
| 59 return Status(kUnknownError, "failed to write automation extension zip"); | 56 return Status(kUnknownError, "failed to write automation extension zip"); |
| 60 } | 57 } |
| 61 | 58 |
| 62 base::FilePath extension_dir = temp_dir.AppendASCII("internal"); | 59 base::FilePath extension_dir = temp_dir.AppendASCII("internal"); |
| 63 if (!zip::Unzip(extension_zip, extension_dir)) | 60 if (!zip::Unzip(extension_zip, extension_dir)) |
| 64 return Status(kUnknownError, "failed to unzip automation extension"); | 61 return Status(kUnknownError, "failed to unzip automation extension"); |
| 65 | 62 |
| 66 *automation_extension = extension_dir; | 63 *automation_extension = extension_dir; |
| 67 return Status(kOk); | 64 return Status(kOk); |
| 68 } | 65 } |
| 69 | 66 |
| 70 void AddSwitches(CommandLine* command, | |
| 71 const char* switches[], | |
| 72 size_t switch_count, | |
| 73 const std::set<std::string>& exclude_switches) { | |
| 74 for (size_t i = 0; i < switch_count; ++i) { | |
| 75 if (exclude_switches.find(switches[i]) == exclude_switches.end()) | |
| 76 command->AppendSwitch(switches[i]); | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 Status PrepareCommandLine(int port, | 67 Status PrepareCommandLine(int port, |
| 81 const Capabilities& capabilities, | 68 const Capabilities& capabilities, |
| 69 Switches* switches, |
| 82 CommandLine* prepared_command, | 70 CommandLine* prepared_command, |
| 83 base::ScopedTempDir* user_data_dir, | 71 base::ScopedTempDir* user_data_dir, |
| 84 base::ScopedTempDir* extension_dir, | 72 base::ScopedTempDir* extension_dir, |
| 85 std::vector<std::string>* extension_bg_pages) { | 73 std::vector<std::string>* extension_bg_pages) { |
| 86 CommandLine command = capabilities.command; | 74 base::FilePath program = capabilities.binary; |
| 87 base::FilePath program = command.GetProgram(); | |
| 88 if (program.empty()) { | 75 if (program.empty()) { |
| 89 if (!FindChrome(&program)) | 76 if (!FindChrome(&program)) |
| 90 return Status(kUnknownError, "cannot find Chrome binary"); | 77 return Status(kUnknownError, "cannot find Chrome binary"); |
| 91 command.SetProgram(program); | |
| 92 } else if (!base::PathExists(program)) { | 78 } else if (!base::PathExists(program)) { |
| 93 return Status(kUnknownError, | 79 return Status(kUnknownError, |
| 94 base::StringPrintf("no chrome binary at %" PRFilePath, | 80 base::StringPrintf("no chrome binary at %" PRFilePath, |
| 95 program.value().c_str())); | 81 program.value().c_str())); |
| 96 } | 82 } |
| 83 CommandLine command(program); |
| 97 | 84 |
| 98 const char* excludable_switches[] = { | 85 // TODO(chrisgao): Add "disable-sync" when chrome 30- is not supported. |
| 99 "disable-hang-monitor", | 86 // For chrome 30-, it leads to crash when opening chrome://settings. |
| 100 "disable-prompt-on-repost", | 87 switches->SetSwitch("disable-hang-monitor"); |
| 101 "full-memory-crash-report", | 88 switches->SetSwitch("disable-prompt-on-repost"); |
| 102 "no-first-run", | 89 switches->SetSwitch("full-memory-crash-report"); |
| 103 "disable-background-networking", | 90 switches->SetSwitch("no-first-run"); |
| 104 // TODO(chrisgao): Add "disable-sync" when chrome 30- is not supported. | 91 switches->SetSwitch("disable-background-networking"); |
| 105 // For chrome 30-, it leads to crash when opening chrome://settings. | 92 switches->SetSwitch("disable-web-resources"); |
| 106 "disable-web-resources", | 93 switches->SetSwitch("safebrowsing-disable-auto-update"); |
| 107 "safebrowsing-disable-auto-update", | 94 switches->SetSwitch("safebrowsing-disable-download-protection"); |
| 108 "safebrowsing-disable-download-protection", | 95 switches->SetSwitch("disable-client-side-phishing-detection"); |
| 109 "disable-client-side-phishing-detection", | 96 switches->SetSwitch("disable-component-update"); |
| 110 "disable-component-update", | 97 switches->SetSwitch("disable-default-apps"); |
| 111 "disable-default-apps", | 98 switches->SetSwitch("enable-logging"); |
| 112 }; | 99 switches->SetSwitch("logging-level", "1"); |
| 100 switches->SetSwitch("password-store", "basic"); |
| 101 switches->SetSwitch("use-mock-keychain"); |
| 102 switches->SetSwitch("remote-debugging-port", base::IntToString(port)); |
| 113 | 103 |
| 114 AddSwitches(&command, excludable_switches, arraysize(excludable_switches), | 104 if (!switches->HasSwitch("user-data-dir")) { |
| 115 capabilities.exclude_switches); | |
| 116 AddSwitches(&command, kCommonSwitches, arraysize(kCommonSwitches), | |
| 117 capabilities.exclude_switches); | |
| 118 | |
| 119 command.AppendSwitch("enable-logging"); | |
| 120 command.AppendSwitchASCII("logging-level", "1"); | |
| 121 command.AppendSwitchASCII("password-store", "basic"); | |
| 122 command.AppendSwitch("use-mock-keychain"); | |
| 123 command.AppendSwitchASCII("remote-debugging-port", base::IntToString(port)); | |
| 124 | |
| 125 if (!command.HasSwitch("user-data-dir")) { | |
| 126 command.AppendArg("about:blank"); | 105 command.AppendArg("about:blank"); |
| 127 if (!user_data_dir->CreateUniqueTempDir()) | 106 if (!user_data_dir->CreateUniqueTempDir()) |
| 128 return Status(kUnknownError, "cannot create temp dir for user data dir"); | 107 return Status(kUnknownError, "cannot create temp dir for user data dir"); |
| 129 command.AppendSwitchPath("user-data-dir", user_data_dir->path()); | 108 command.AppendSwitchPath("user-data-dir", user_data_dir->path()); |
| 130 Status status = internal::PrepareUserDataDir( | 109 Status status = internal::PrepareUserDataDir( |
| 131 user_data_dir->path(), capabilities.prefs.get(), | 110 user_data_dir->path(), capabilities.prefs.get(), |
| 132 capabilities.local_state.get()); | 111 capabilities.local_state.get()); |
| 133 if (status.IsError()) | 112 if (status.IsError()) |
| 134 return status; | 113 return status; |
| 135 } | 114 } |
| 136 | 115 |
| 137 if (!extension_dir->CreateUniqueTempDir()) { | 116 if (!extension_dir->CreateUniqueTempDir()) { |
| 138 return Status(kUnknownError, | 117 return Status(kUnknownError, |
| 139 "cannot create temp dir for unpacking extensions"); | 118 "cannot create temp dir for unpacking extensions"); |
| 140 } | 119 } |
| 141 Status status = internal::ProcessExtensions(capabilities.extensions, | 120 Status status = internal::ProcessExtensions(capabilities.extensions, |
| 142 extension_dir->path(), | 121 extension_dir->path(), |
| 143 true, | 122 true, |
| 144 &command, | 123 switches, |
| 145 extension_bg_pages); | 124 extension_bg_pages); |
| 146 if (status.IsError()) | 125 if (status.IsError()) |
| 147 return status; | 126 return status; |
| 148 | 127 |
| 128 switches->AppendToCommandLine(&command); |
| 149 *prepared_command = command; | 129 *prepared_command = command; |
| 150 return Status(kOk); | 130 return Status(kOk); |
| 151 } | 131 } |
| 152 | 132 |
| 153 Status WaitForDevToolsAndCheckVersion( | 133 Status WaitForDevToolsAndCheckVersion( |
| 154 int port, | 134 int port, |
| 155 URLRequestContextGetter* context_getter, | 135 URLRequestContextGetter* context_getter, |
| 156 const SyncWebSocketFactory& socket_factory, | 136 const SyncWebSocketFactory& socket_factory, |
| 157 Log* log, | 137 Log* log, |
| 158 scoped_ptr<DevToolsHttpClient>* user_client) { | 138 scoped_ptr<DevToolsHttpClient>* user_client) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 log)); | 179 log)); |
| 200 return Status(kOk); | 180 return Status(kOk); |
| 201 } | 181 } |
| 202 | 182 |
| 203 Status LaunchDesktopChrome( | 183 Status LaunchDesktopChrome( |
| 204 URLRequestContextGetter* context_getter, | 184 URLRequestContextGetter* context_getter, |
| 205 int port, | 185 int port, |
| 206 const SyncWebSocketFactory& socket_factory, | 186 const SyncWebSocketFactory& socket_factory, |
| 207 Log* log, | 187 Log* log, |
| 208 const Capabilities& capabilities, | 188 const Capabilities& capabilities, |
| 189 Switches* switches, |
| 209 ScopedVector<DevToolsEventListener>& devtools_event_listeners, | 190 ScopedVector<DevToolsEventListener>& devtools_event_listeners, |
| 210 scoped_ptr<Chrome>* chrome) { | 191 scoped_ptr<Chrome>* chrome) { |
| 211 CommandLine command(CommandLine::NO_PROGRAM); | 192 CommandLine command(CommandLine::NO_PROGRAM); |
| 212 base::ScopedTempDir user_data_dir; | 193 base::ScopedTempDir user_data_dir; |
| 213 base::ScopedTempDir extension_dir; | 194 base::ScopedTempDir extension_dir; |
| 214 std::vector<std::string> extension_bg_pages; | 195 std::vector<std::string> extension_bg_pages; |
| 215 Status status = PrepareCommandLine(port, | 196 Status status = PrepareCommandLine(port, |
| 216 capabilities, | 197 capabilities, |
| 198 switches, |
| 217 &command, | 199 &command, |
| 218 &user_data_dir, | 200 &user_data_dir, |
| 219 &extension_dir, | 201 &extension_dir, |
| 220 &extension_bg_pages); | 202 &extension_bg_pages); |
| 221 if (status.IsError()) | 203 if (status.IsError()) |
| 222 return status; | 204 return status; |
| 223 | 205 |
| 224 base::LaunchOptions options; | 206 base::LaunchOptions options; |
| 225 | 207 |
| 226 #if !defined(OS_WIN) | 208 #if !defined(OS_WIN) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 *chrome = chrome_desktop.Pass(); | 286 *chrome = chrome_desktop.Pass(); |
| 305 return Status(kOk); | 287 return Status(kOk); |
| 306 } | 288 } |
| 307 | 289 |
| 308 Status LaunchAndroidChrome( | 290 Status LaunchAndroidChrome( |
| 309 URLRequestContextGetter* context_getter, | 291 URLRequestContextGetter* context_getter, |
| 310 int port, | 292 int port, |
| 311 const SyncWebSocketFactory& socket_factory, | 293 const SyncWebSocketFactory& socket_factory, |
| 312 Log* log, | 294 Log* log, |
| 313 const Capabilities& capabilities, | 295 const Capabilities& capabilities, |
| 296 Switches* switches, |
| 314 ScopedVector<DevToolsEventListener>& devtools_event_listeners, | 297 ScopedVector<DevToolsEventListener>& devtools_event_listeners, |
| 315 DeviceManager* device_manager, | 298 DeviceManager* device_manager, |
| 316 scoped_ptr<Chrome>* chrome) { | 299 scoped_ptr<Chrome>* chrome) { |
| 317 Status status(kOk); | 300 Status status(kOk); |
| 318 scoped_ptr<Device> device; | 301 scoped_ptr<Device> device; |
| 319 if (capabilities.android_device_serial.empty()) { | 302 if (capabilities.android_device_serial.empty()) { |
| 320 status = device_manager->AcquireDevice(&device); | 303 status = device_manager->AcquireDevice(&device); |
| 321 } else { | 304 } else { |
| 322 status = device_manager->AcquireSpecificDevice( | 305 status = device_manager->AcquireSpecificDevice( |
| 323 capabilities.android_device_serial, &device); | 306 capabilities.android_device_serial, &device); |
| 324 } | 307 } |
| 325 if (!status.IsOk()) | 308 if (!status.IsOk()) |
| 326 return status; | 309 return status; |
| 327 | 310 |
| 328 std::string args(capabilities.android_args); | 311 switches->SetSwitch("disable-fre"); |
| 329 for (size_t i = 0; i < arraysize(kCommonSwitches); i++) | 312 switches->SetSwitch("enable-remote-debugging"); |
| 330 args += "--" + std::string(kCommonSwitches[i]) + " "; | |
| 331 args += "--disable-fre --enable-remote-debugging"; | |
| 332 | |
| 333 status = device->StartApp(capabilities.android_package, | 313 status = device->StartApp(capabilities.android_package, |
| 334 capabilities.android_activity, | 314 capabilities.android_activity, |
| 335 capabilities.android_process, | 315 capabilities.android_process, |
| 336 args, port); | 316 switches->ToString(), port); |
| 337 if (!status.IsOk()) { | 317 if (!status.IsOk()) { |
| 338 device->StopApp(); | 318 device->StopApp(); |
| 339 return status; | 319 return status; |
| 340 } | 320 } |
| 341 | 321 |
| 342 scoped_ptr<DevToolsHttpClient> devtools_client; | 322 scoped_ptr<DevToolsHttpClient> devtools_client; |
| 343 status = WaitForDevToolsAndCheckVersion(port, | 323 status = WaitForDevToolsAndCheckVersion(port, |
| 344 context_getter, | 324 context_getter, |
| 345 socket_factory, | 325 socket_factory, |
| 346 log, | 326 log, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 362 Log* log, | 342 Log* log, |
| 363 DeviceManager* device_manager, | 343 DeviceManager* device_manager, |
| 364 const Capabilities& capabilities, | 344 const Capabilities& capabilities, |
| 365 ScopedVector<DevToolsEventListener>& devtools_event_listeners, | 345 ScopedVector<DevToolsEventListener>& devtools_event_listeners, |
| 366 scoped_ptr<Chrome>* chrome) { | 346 scoped_ptr<Chrome>* chrome) { |
| 367 | 347 |
| 368 if (capabilities.IsExistingBrowser()) { | 348 if (capabilities.IsExistingBrowser()) { |
| 369 return LaunchExistingChromeSession( | 349 return LaunchExistingChromeSession( |
| 370 context_getter, capabilities.existing_browser_port, socket_factory, | 350 context_getter, capabilities.existing_browser_port, socket_factory, |
| 371 log, capabilities, devtools_event_listeners, chrome); | 351 log, capabilities, devtools_event_listeners, chrome); |
| 372 } else if (capabilities.IsAndroid()) { | 352 } |
| 353 |
| 354 |
| 355 Switches switches = capabilities.switches; |
| 356 const char* kCommonSwitches[] = { |
| 357 "ignore-certificate-errors", "metrics-recording-only"}; |
| 358 for (size_t i = 0; i < arraysize(kCommonSwitches); i++) |
| 359 switches.SetSwitch(kCommonSwitches[i]); |
| 360 |
| 361 if (capabilities.IsAndroid()) { |
| 373 return LaunchAndroidChrome( | 362 return LaunchAndroidChrome( |
| 374 context_getter, port, socket_factory, log, capabilities, | 363 context_getter, port, socket_factory, log, capabilities, |
| 375 devtools_event_listeners, device_manager, chrome); | 364 &switches, devtools_event_listeners, device_manager, chrome); |
| 376 } else { | 365 } else { |
| 377 return LaunchDesktopChrome( | 366 return LaunchDesktopChrome( |
| 378 context_getter, port, socket_factory, log, capabilities, | 367 context_getter, port, socket_factory, log, capabilities, |
| 379 devtools_event_listeners, chrome); | 368 &switches, devtools_event_listeners, chrome); |
| 380 } | 369 } |
| 381 } | 370 } |
| 382 | 371 |
| 383 namespace internal { | 372 namespace internal { |
| 384 | 373 |
| 385 void ConvertHexadecimalToIDAlphabet(std::string* id) { | 374 void ConvertHexadecimalToIDAlphabet(std::string* id) { |
| 386 for (size_t i = 0; i < id->size(); ++i) { | 375 for (size_t i = 0; i < id->size(); ++i) { |
| 387 int val; | 376 int val; |
| 388 if (base::HexStringToInt(base::StringPiece(id->begin() + i, | 377 if (base::HexStringToInt(base::StringPiece(id->begin() + i, |
| 389 id->begin() + i + 1), | 378 id->begin() + i + 1), |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 Status status = GetExtensionBackgroundPage(manifest, id, &bg_page_tmp); | 475 Status status = GetExtensionBackgroundPage(manifest, id, &bg_page_tmp); |
| 487 if (status.IsError()) | 476 if (status.IsError()) |
| 488 return status; | 477 return status; |
| 489 | 478 |
| 490 *path = extension_dir; | 479 *path = extension_dir; |
| 491 if (bg_page_tmp.size()) | 480 if (bg_page_tmp.size()) |
| 492 *bg_page = bg_page_tmp; | 481 *bg_page = bg_page_tmp; |
| 493 return Status(kOk); | 482 return Status(kOk); |
| 494 } | 483 } |
| 495 | 484 |
| 485 void UpdateExtensionSwitch(Switches* switches, |
| 486 const char name[], |
| 487 const base::FilePath::StringType& extension) { |
| 488 base::FilePath::StringType value = switches->GetSwitchValueNative(name); |
| 489 if (value.length()) |
| 490 value += FILE_PATH_LITERAL(","); |
| 491 value += extension; |
| 492 switches->SetSwitch(name, value); |
| 493 } |
| 494 |
| 496 Status ProcessExtensions(const std::vector<std::string>& extensions, | 495 Status ProcessExtensions(const std::vector<std::string>& extensions, |
| 497 const base::FilePath& temp_dir, | 496 const base::FilePath& temp_dir, |
| 498 bool include_automation_extension, | 497 bool include_automation_extension, |
| 499 CommandLine* command, | 498 Switches* switches, |
| 500 std::vector<std::string>* bg_pages) { | 499 std::vector<std::string>* bg_pages) { |
| 501 std::vector<std::string> bg_pages_tmp; | 500 std::vector<std::string> bg_pages_tmp; |
| 502 std::vector<base::FilePath::StringType> extension_paths; | 501 std::vector<base::FilePath::StringType> extension_paths; |
| 503 for (size_t i = 0; i < extensions.size(); ++i) { | 502 for (size_t i = 0; i < extensions.size(); ++i) { |
| 504 base::FilePath path; | 503 base::FilePath path; |
| 505 std::string bg_page; | 504 std::string bg_page; |
| 506 Status status = ProcessExtension(extensions[i], temp_dir, &path, &bg_page); | 505 Status status = ProcessExtension(extensions[i], temp_dir, &path, &bg_page); |
| 507 if (status.IsError()) { | 506 if (status.IsError()) { |
| 508 return Status( | 507 return Status( |
| 509 kUnknownError, | 508 kUnknownError, |
| 510 base::StringPrintf("cannot process extension #%" PRIuS, i + 1), | 509 base::StringPrintf("cannot process extension #%" PRIuS, i + 1), |
| 511 status); | 510 status); |
| 512 } | 511 } |
| 513 extension_paths.push_back(path.value()); | 512 extension_paths.push_back(path.value()); |
| 514 if (bg_page.length()) | 513 if (bg_page.length()) |
| 515 bg_pages_tmp.push_back(bg_page); | 514 bg_pages_tmp.push_back(bg_page); |
| 516 } | 515 } |
| 517 | 516 |
| 518 if (include_automation_extension) { | 517 if (include_automation_extension) { |
| 519 base::FilePath automation_extension; | 518 base::FilePath automation_extension; |
| 520 Status status = UnpackAutomationExtension(temp_dir, &automation_extension); | 519 Status status = UnpackAutomationExtension(temp_dir, &automation_extension); |
| 521 if (status.IsError()) | 520 if (status.IsError()) |
| 522 return status; | 521 return status; |
| 523 if (command->HasSwitch("disable-extensions")) { | 522 if (switches->HasSwitch("disable-extensions")) { |
| 524 command->AppendSwitchNative("load-component-extension", | 523 UpdateExtensionSwitch(switches, "load-component-extension", |
| 525 automation_extension.value()); | 524 automation_extension.value()); |
| 526 } else { | 525 } else { |
| 527 extension_paths.push_back(automation_extension.value()); | 526 extension_paths.push_back(automation_extension.value()); |
| 528 } | 527 } |
| 529 } | 528 } |
| 530 | 529 |
| 531 if (extension_paths.size()) { | 530 if (extension_paths.size()) { |
| 532 base::FilePath::StringType extension_paths_value = JoinString( | 531 base::FilePath::StringType extension_paths_value = JoinString( |
| 533 extension_paths, FILE_PATH_LITERAL(',')); | 532 extension_paths, FILE_PATH_LITERAL(',')); |
| 534 command->AppendSwitchNative("load-extension", extension_paths_value); | 533 UpdateExtensionSwitch(switches, "load-extension", extension_paths_value); |
| 535 } | 534 } |
| 536 bg_pages->swap(bg_pages_tmp); | 535 bg_pages->swap(bg_pages_tmp); |
| 537 return Status(kOk); | 536 return Status(kOk); |
| 538 } | 537 } |
| 539 | 538 |
| 540 Status WritePrefsFile( | 539 Status WritePrefsFile( |
| 541 const std::string& template_string, | 540 const std::string& template_string, |
| 542 const base::DictionaryValue* custom_prefs, | 541 const base::DictionaryValue* custom_prefs, |
| 543 const base::FilePath& path) { | 542 const base::FilePath& path) { |
| 544 int code; | 543 int code; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 // Write empty "First Run" file, otherwise Chrome will wipe the default | 591 // Write empty "First Run" file, otherwise Chrome will wipe the default |
| 593 // profile that was written. | 592 // profile that was written. |
| 594 if (file_util::WriteFile( | 593 if (file_util::WriteFile( |
| 595 user_data_dir.AppendASCII("First Run"), "", 0) != 0) { | 594 user_data_dir.AppendASCII("First Run"), "", 0) != 0) { |
| 596 return Status(kUnknownError, "failed to write first run file"); | 595 return Status(kUnknownError, "failed to write first run file"); |
| 597 } | 596 } |
| 598 return Status(kOk); | 597 return Status(kOk); |
| 599 } | 598 } |
| 600 | 599 |
| 601 } // namespace internal | 600 } // namespace internal |
| OLD | NEW |