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