| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <iostream> | 5 #include <iostream> |
| 6 #include <memory> | 6 #include <memory> |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "headless/public/headless_devtools_target.h" | 26 #include "headless/public/headless_devtools_target.h" |
| 27 #include "headless/public/headless_web_contents.h" | 27 #include "headless/public/headless_web_contents.h" |
| 28 #include "headless/public/util/deterministic_dispatcher.h" | 28 #include "headless/public/util/deterministic_dispatcher.h" |
| 29 #include "headless/public/util/deterministic_http_protocol_handler.h" | 29 #include "headless/public/util/deterministic_http_protocol_handler.h" |
| 30 #include "net/base/file_stream.h" | 30 #include "net/base/file_stream.h" |
| 31 #include "net/base/io_buffer.h" | 31 #include "net/base/io_buffer.h" |
| 32 #include "net/base/ip_address.h" | 32 #include "net/base/ip_address.h" |
| 33 #include "net/base/net_errors.h" | 33 #include "net/base/net_errors.h" |
| 34 #include "ui/gfx/geometry/size.h" | 34 #include "ui/gfx/geometry/size.h" |
| 35 | 35 |
| 36 using headless::HeadlessBrowser; | 36 namespace headless { |
| 37 using headless::HeadlessBrowserContext; | |
| 38 using headless::HeadlessDevToolsClient; | |
| 39 using headless::HeadlessWebContents; | |
| 40 namespace emulation = headless::emulation; | |
| 41 namespace page = headless::page; | |
| 42 namespace runtime = headless::runtime; | |
| 43 | |
| 44 namespace { | 37 namespace { |
| 45 // Address where to listen to incoming DevTools connections. | 38 // Address where to listen to incoming DevTools connections. |
| 46 const char kDevToolsHttpServerAddress[] = "127.0.0.1"; | 39 const char kDevToolsHttpServerAddress[] = "127.0.0.1"; |
| 47 // Default file name for screenshot. Can be overriden by "--screenshot" switch. | 40 // Default file name for screenshot. Can be overriden by "--screenshot" switch. |
| 48 const char kDefaultScreenshotFileName[] = "screenshot.png"; | 41 const char kDefaultScreenshotFileName[] = "screenshot.png"; |
| 49 | 42 |
| 50 bool ParseWindowSize(std::string window_size, gfx::Size* parsed_window_size) { | 43 bool ParseWindowSize(std::string window_size, gfx::Size* parsed_window_size) { |
| 51 int width, height = 0; | 44 int width, height = 0; |
| 52 if (sscanf(window_size.c_str(), "%dx%d", &width, &height) >= 2 && | 45 if (sscanf(window_size.c_str(), "%dx%d", &width, &height) >= 2 && |
| 53 width >= 0 && height >= 0) { | 46 width >= 0 && height >= 0) { |
| 54 parsed_window_size->set_width(width); | 47 parsed_window_size->set_width(width); |
| 55 parsed_window_size->set_height(height); | 48 parsed_window_size->set_height(height); |
| 56 return true; | 49 return true; |
| 57 } | 50 } |
| 58 return false; | 51 return false; |
| 59 } | 52 } |
| 60 } // namespace | 53 } // namespace |
| 61 | 54 |
| 62 // A sample application which demonstrates the use of the headless API. | 55 // An application which implements a simple headless browser. |
| 63 class HeadlessShell : public HeadlessWebContents::Observer, | 56 class HeadlessShell : public HeadlessWebContents::Observer, |
| 64 emulation::ExperimentalObserver, | 57 emulation::ExperimentalObserver, |
| 65 page::Observer { | 58 page::Observer { |
| 66 public: | 59 public: |
| 67 HeadlessShell() | 60 HeadlessShell() |
| 68 : browser_(nullptr), | 61 : browser_(nullptr), |
| 69 devtools_client_(HeadlessDevToolsClient::Create()), | 62 devtools_client_(HeadlessDevToolsClient::Create()), |
| 70 web_contents_(nullptr), | 63 web_contents_(nullptr), |
| 71 processed_page_ready_(false), | 64 processed_page_ready_(false), |
| 72 browser_context_(nullptr) {} | 65 browser_context_(nullptr) {} |
| 73 ~HeadlessShell() override {} | 66 ~HeadlessShell() override {} |
| 74 | 67 |
| 75 void OnStart(HeadlessBrowser* browser) { | 68 void OnStart(HeadlessBrowser* browser) { |
| 76 browser_ = browser; | 69 browser_ = browser; |
| 77 | 70 |
| 78 HeadlessBrowserContext::Builder context_builder = | 71 HeadlessBrowserContext::Builder context_builder = |
| 79 browser_->CreateBrowserContextBuilder(); | 72 browser_->CreateBrowserContextBuilder(); |
| 80 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 73 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 81 headless::switches::kDeterministicFetch)) { | 74 switches::kDeterministicFetch)) { |
| 82 deterministic_dispatcher_.reset( | 75 deterministic_dispatcher_.reset( |
| 83 new headless::DeterministicDispatcher(browser_->BrowserIOThread())); | 76 new DeterministicDispatcher(browser_->BrowserIOThread())); |
| 84 | 77 |
| 85 headless::ProtocolHandlerMap protocol_handlers; | 78 ProtocolHandlerMap protocol_handlers; |
| 86 protocol_handlers[url::kHttpScheme] = | 79 protocol_handlers[url::kHttpScheme] = |
| 87 base::MakeUnique<headless::DeterministicHttpProtocolHandler>( | 80 base::MakeUnique<DeterministicHttpProtocolHandler>( |
| 88 deterministic_dispatcher_.get(), browser->BrowserIOThread()); | 81 deterministic_dispatcher_.get(), browser->BrowserIOThread()); |
| 89 protocol_handlers[url::kHttpsScheme] = | 82 protocol_handlers[url::kHttpsScheme] = |
| 90 base::MakeUnique<headless::DeterministicHttpProtocolHandler>( | 83 base::MakeUnique<DeterministicHttpProtocolHandler>( |
| 91 deterministic_dispatcher_.get(), browser->BrowserIOThread()); | 84 deterministic_dispatcher_.get(), browser->BrowserIOThread()); |
| 92 | 85 |
| 93 context_builder.SetProtocolHandlers(std::move(protocol_handlers)); | 86 context_builder.SetProtocolHandlers(std::move(protocol_handlers)); |
| 94 } | 87 } |
| 95 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 88 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 96 headless::switches::kHideScrollbars)) { | 89 switches::kHideScrollbars)) { |
| 97 context_builder.SetOverrideWebPreferencesCallback( | 90 context_builder.SetOverrideWebPreferencesCallback( |
| 98 base::Bind([](headless::WebPreferences* preferences) { | 91 base::Bind([](WebPreferences* preferences) { |
| 99 preferences->hide_scrollbars = true; | 92 preferences->hide_scrollbars = true; |
| 100 })); | 93 })); |
| 101 } | 94 } |
| 102 browser_context_ = context_builder.Build(); | 95 browser_context_ = context_builder.Build(); |
| 103 | 96 |
| 104 HeadlessWebContents::Builder builder( | 97 HeadlessWebContents::Builder builder( |
| 105 browser_context_->CreateWebContentsBuilder()); | 98 browser_context_->CreateWebContentsBuilder()); |
| 106 base::CommandLine::StringVector args = | 99 base::CommandLine::StringVector args = |
| 107 base::CommandLine::ForCurrentProcess()->GetArgs(); | 100 base::CommandLine::ForCurrentProcess()->GetArgs(); |
| 108 | 101 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 return; | 133 return; |
| 141 web_contents_->GetDevToolsTarget()->AttachClient(devtools_client_.get()); | 134 web_contents_->GetDevToolsTarget()->AttachClient(devtools_client_.get()); |
| 142 devtools_client_->GetPage()->AddObserver(this); | 135 devtools_client_->GetPage()->AddObserver(this); |
| 143 devtools_client_->GetPage()->Enable(); | 136 devtools_client_->GetPage()->Enable(); |
| 144 // Check if the document had already finished loading by the time we | 137 // Check if the document had already finished loading by the time we |
| 145 // attached. | 138 // attached. |
| 146 | 139 |
| 147 devtools_client_->GetEmulation()->GetExperimental()->AddObserver(this); | 140 devtools_client_->GetEmulation()->GetExperimental()->AddObserver(this); |
| 148 | 141 |
| 149 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 142 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 150 headless::switches::kVirtualTimeBudget)) { | 143 switches::kVirtualTimeBudget)) { |
| 151 std::string budget_ms_ascii = | 144 std::string budget_ms_ascii = |
| 152 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 145 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 153 headless::switches::kVirtualTimeBudget); | 146 switches::kVirtualTimeBudget); |
| 154 int budget_ms; | 147 int budget_ms; |
| 155 CHECK(base::StringToInt(budget_ms_ascii, &budget_ms)) | 148 CHECK(base::StringToInt(budget_ms_ascii, &budget_ms)) |
| 156 << "Expected an integer value for --virtual-time-budget="; | 149 << "Expected an integer value for --virtual-time-budget="; |
| 157 devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( | 150 devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( |
| 158 emulation::SetVirtualTimePolicyParams::Builder() | 151 emulation::SetVirtualTimePolicyParams::Builder() |
| 159 .SetPolicy(emulation::VirtualTimePolicy:: | 152 .SetPolicy(emulation::VirtualTimePolicy:: |
| 160 PAUSE_IF_NETWORK_FETCHES_PENDING) | 153 PAUSE_IF_NETWORK_FETCHES_PENDING) |
| 161 .SetBudget(budget_ms) | 154 .SetBudget(budget_ms) |
| 162 .Build()); | 155 .Build()); |
| 163 } else { | 156 } else { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 193 | 186 |
| 194 // emulation::Observer implementation: | 187 // emulation::Observer implementation: |
| 195 void OnVirtualTimeBudgetExpired( | 188 void OnVirtualTimeBudgetExpired( |
| 196 const emulation::VirtualTimeBudgetExpiredParams& params) override { | 189 const emulation::VirtualTimeBudgetExpiredParams& params) override { |
| 197 OnPageReady(); | 190 OnPageReady(); |
| 198 } | 191 } |
| 199 | 192 |
| 200 // page::Observer implementation: | 193 // page::Observer implementation: |
| 201 void OnLoadEventFired(const page::LoadEventFiredParams& params) override { | 194 void OnLoadEventFired(const page::LoadEventFiredParams& params) override { |
| 202 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 195 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 203 headless::switches::kVirtualTimeBudget)) { | 196 switches::kVirtualTimeBudget)) { |
| 204 return; | 197 return; |
| 205 } | 198 } |
| 206 OnPageReady(); | 199 OnPageReady(); |
| 207 } | 200 } |
| 208 | 201 |
| 209 void OnPageReady() { | 202 void OnPageReady() { |
| 210 if (processed_page_ready_) | 203 if (processed_page_ready_) |
| 211 return; | 204 return; |
| 212 processed_page_ready_ = true; | 205 processed_page_ready_ = true; |
| 213 | 206 |
| 214 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 207 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpDom)) { |
| 215 headless::switches::kDumpDom)) { | |
| 216 FetchDom(); | 208 FetchDom(); |
| 217 } else if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 209 } else if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 218 headless::switches::kRepl)) { | 210 switches::kRepl)) { |
| 219 std::cout | 211 std::cout |
| 220 << "Type a Javascript expression to evaluate or \"quit\" to exit." | 212 << "Type a Javascript expression to evaluate or \"quit\" to exit." |
| 221 << std::endl; | 213 << std::endl; |
| 222 InputExpression(); | 214 InputExpression(); |
| 223 } else if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 215 } else if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 224 headless::switches::kScreenshot)) { | 216 switches::kScreenshot)) { |
| 225 CaptureScreenshot(); | 217 CaptureScreenshot(); |
| 226 } else { | 218 } else { |
| 227 Shutdown(); | 219 Shutdown(); |
| 228 } | 220 } |
| 229 } | 221 } |
| 230 | 222 |
| 231 void FetchDom() { | 223 void FetchDom() { |
| 232 devtools_client_->GetRuntime()->Evaluate( | 224 devtools_client_->GetRuntime()->Evaluate( |
| 233 "document.body.innerHTML", | 225 "document.body.innerHTML", |
| 234 base::Bind(&HeadlessShell::OnDomFetched, base::Unretained(this))); | 226 base::Bind(&HeadlessShell::OnDomFetched, base::Unretained(this))); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 devtools_client_->GetPage()->GetExperimental()->CaptureScreenshot( | 266 devtools_client_->GetPage()->GetExperimental()->CaptureScreenshot( |
| 275 page::CaptureScreenshotParams::Builder().Build(), | 267 page::CaptureScreenshotParams::Builder().Build(), |
| 276 base::Bind(&HeadlessShell::OnScreenshotCaptured, | 268 base::Bind(&HeadlessShell::OnScreenshotCaptured, |
| 277 base::Unretained(this))); | 269 base::Unretained(this))); |
| 278 } | 270 } |
| 279 | 271 |
| 280 void OnScreenshotCaptured( | 272 void OnScreenshotCaptured( |
| 281 std::unique_ptr<page::CaptureScreenshotResult> result) { | 273 std::unique_ptr<page::CaptureScreenshotResult> result) { |
| 282 base::FilePath file_name = | 274 base::FilePath file_name = |
| 283 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( | 275 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( |
| 284 headless::switches::kScreenshot); | 276 switches::kScreenshot); |
| 285 if (file_name.empty()) { | 277 if (file_name.empty()) { |
| 286 file_name = base::FilePath().AppendASCII(kDefaultScreenshotFileName); | 278 file_name = base::FilePath().AppendASCII(kDefaultScreenshotFileName); |
| 287 } | 279 } |
| 288 | 280 |
| 289 screenshot_file_stream_.reset( | 281 screenshot_file_stream_.reset( |
| 290 new net::FileStream(browser_->BrowserFileThread())); | 282 new net::FileStream(browser_->BrowserFileThread())); |
| 291 const int open_result = screenshot_file_stream_->Open( | 283 const int open_result = screenshot_file_stream_->Open( |
| 292 file_name, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | | 284 file_name, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE | |
| 293 base::File::FLAG_ASYNC, | 285 base::File::FLAG_ASYNC, |
| 294 base::Bind(&HeadlessShell::OnScreenshotFileOpened, | 286 base::Bind(&HeadlessShell::OnScreenshotFileOpened, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 // Operation could not be started. | 335 // Operation could not be started. |
| 344 OnScreenshotFileClosed(close_result); | 336 OnScreenshotFileClosed(close_result); |
| 345 } | 337 } |
| 346 } | 338 } |
| 347 | 339 |
| 348 void OnScreenshotFileClosed(const int close_result) { Shutdown(); } | 340 void OnScreenshotFileClosed(const int close_result) { Shutdown(); } |
| 349 | 341 |
| 350 bool RemoteDebuggingEnabled() const { | 342 bool RemoteDebuggingEnabled() const { |
| 351 const base::CommandLine& command_line = | 343 const base::CommandLine& command_line = |
| 352 *base::CommandLine::ForCurrentProcess(); | 344 *base::CommandLine::ForCurrentProcess(); |
| 353 return command_line.HasSwitch(switches::kRemoteDebuggingPort); | 345 return command_line.HasSwitch(::switches::kRemoteDebuggingPort); |
| 354 } | 346 } |
| 355 | 347 |
| 356 private: | 348 private: |
| 357 GURL url_; | 349 GURL url_; |
| 358 HeadlessBrowser* browser_; // Not owned. | 350 HeadlessBrowser* browser_; // Not owned. |
| 359 std::unique_ptr<HeadlessDevToolsClient> devtools_client_; | 351 std::unique_ptr<HeadlessDevToolsClient> devtools_client_; |
| 360 HeadlessWebContents* web_contents_; | 352 HeadlessWebContents* web_contents_; |
| 361 bool processed_page_ready_; | 353 bool processed_page_ready_; |
| 362 std::unique_ptr<net::FileStream> screenshot_file_stream_; | 354 std::unique_ptr<net::FileStream> screenshot_file_stream_; |
| 363 HeadlessBrowserContext* browser_context_; | 355 HeadlessBrowserContext* browser_context_; |
| 364 std::unique_ptr<headless::DeterministicDispatcher> deterministic_dispatcher_; | 356 std::unique_ptr<DeterministicDispatcher> deterministic_dispatcher_; |
| 365 | 357 |
| 366 DISALLOW_COPY_AND_ASSIGN(HeadlessShell); | 358 DISALLOW_COPY_AND_ASSIGN(HeadlessShell); |
| 367 }; | 359 }; |
| 368 | 360 |
| 369 int main(int argc, const char** argv) { | 361 int HeadlessShellMain(int argc, const char** argv) { |
| 370 headless::RunChildProcessIfNeeded(argc, argv); | 362 RunChildProcessIfNeeded(argc, argv); |
| 371 HeadlessShell shell; | 363 HeadlessShell shell; |
| 372 HeadlessBrowser::Options::Builder builder(argc, argv); | 364 HeadlessBrowser::Options::Builder builder(argc, argv); |
| 373 | 365 |
| 374 // Enable devtools if requested. | 366 // Enable devtools if requested. |
| 375 base::CommandLine command_line(argc, argv); | 367 base::CommandLine command_line(argc, argv); |
| 376 if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) { | 368 if (command_line.HasSwitch(::switches::kRemoteDebuggingPort)) { |
| 377 std::string address = kDevToolsHttpServerAddress; | 369 std::string address = kDevToolsHttpServerAddress; |
| 378 if (command_line.HasSwitch(headless::switches::kRemoteDebuggingAddress)) { | 370 if (command_line.HasSwitch(switches::kRemoteDebuggingAddress)) { |
| 379 address = command_line.GetSwitchValueASCII( | 371 address = |
| 380 headless::switches::kRemoteDebuggingAddress); | 372 command_line.GetSwitchValueASCII(switches::kRemoteDebuggingAddress); |
| 381 net::IPAddress parsed_address; | 373 net::IPAddress parsed_address; |
| 382 if (!net::ParseURLHostnameToAddress(address, &parsed_address)) { | 374 if (!net::ParseURLHostnameToAddress(address, &parsed_address)) { |
| 383 LOG(ERROR) << "Invalid devtools server address"; | 375 LOG(ERROR) << "Invalid devtools server address"; |
| 384 return EXIT_FAILURE; | 376 return EXIT_FAILURE; |
| 385 } | 377 } |
| 386 } | 378 } |
| 387 int parsed_port; | 379 int parsed_port; |
| 388 std::string port_str = | 380 std::string port_str = |
| 389 command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort); | 381 command_line.GetSwitchValueASCII(::switches::kRemoteDebuggingPort); |
| 390 if (!base::StringToInt(port_str, &parsed_port) || | 382 if (!base::StringToInt(port_str, &parsed_port) || |
| 391 !base::IsValueInRangeForNumericType<uint16_t>(parsed_port)) { | 383 !base::IsValueInRangeForNumericType<uint16_t>(parsed_port)) { |
| 392 LOG(ERROR) << "Invalid devtools server port"; | 384 LOG(ERROR) << "Invalid devtools server port"; |
| 393 return EXIT_FAILURE; | 385 return EXIT_FAILURE; |
| 394 } | 386 } |
| 395 net::IPAddress devtools_address; | 387 net::IPAddress devtools_address; |
| 396 bool result = devtools_address.AssignFromIPLiteral(address); | 388 bool result = devtools_address.AssignFromIPLiteral(address); |
| 397 DCHECK(result); | 389 DCHECK(result); |
| 398 builder.EnableDevToolsServer(net::IPEndPoint( | 390 builder.EnableDevToolsServer(net::IPEndPoint( |
| 399 devtools_address, base::checked_cast<uint16_t>(parsed_port))); | 391 devtools_address, base::checked_cast<uint16_t>(parsed_port))); |
| 400 } | 392 } |
| 401 | 393 |
| 402 if (command_line.HasSwitch(headless::switches::kProxyServer)) { | 394 if (command_line.HasSwitch(switches::kProxyServer)) { |
| 403 std::string proxy_server = | 395 std::string proxy_server = |
| 404 command_line.GetSwitchValueASCII(headless::switches::kProxyServer); | 396 command_line.GetSwitchValueASCII(switches::kProxyServer); |
| 405 net::HostPortPair parsed_proxy_server = | 397 net::HostPortPair parsed_proxy_server = |
| 406 net::HostPortPair::FromString(proxy_server); | 398 net::HostPortPair::FromString(proxy_server); |
| 407 if (parsed_proxy_server.host().empty() || !parsed_proxy_server.port()) { | 399 if (parsed_proxy_server.host().empty() || !parsed_proxy_server.port()) { |
| 408 LOG(ERROR) << "Malformed proxy server url"; | 400 LOG(ERROR) << "Malformed proxy server url"; |
| 409 return EXIT_FAILURE; | 401 return EXIT_FAILURE; |
| 410 } | 402 } |
| 411 builder.SetProxyServer(parsed_proxy_server); | 403 builder.SetProxyServer(parsed_proxy_server); |
| 412 } | 404 } |
| 413 | 405 |
| 414 if (command_line.HasSwitch(switches::kHostResolverRules)) { | 406 if (command_line.HasSwitch(::switches::kHostResolverRules)) { |
| 415 builder.SetHostResolverRules( | 407 builder.SetHostResolverRules( |
| 416 command_line.GetSwitchValueASCII(switches::kHostResolverRules)); | 408 command_line.GetSwitchValueASCII(::switches::kHostResolverRules)); |
| 417 } | 409 } |
| 418 | 410 |
| 419 if (command_line.HasSwitch(headless::switches::kUseGL)) { | 411 if (command_line.HasSwitch(switches::kUseGL)) { |
| 420 builder.SetGLImplementation( | 412 builder.SetGLImplementation( |
| 421 command_line.GetSwitchValueASCII(headless::switches::kUseGL)); | 413 command_line.GetSwitchValueASCII(switches::kUseGL)); |
| 422 } | 414 } |
| 423 | 415 |
| 424 if (command_line.HasSwitch(headless::switches::kUserDataDir)) { | 416 if (command_line.HasSwitch(switches::kUserDataDir)) { |
| 425 builder.SetUserDataDir( | 417 builder.SetUserDataDir( |
| 426 command_line.GetSwitchValuePath(headless::switches::kUserDataDir)); | 418 command_line.GetSwitchValuePath(switches::kUserDataDir)); |
| 427 builder.SetIncognitoMode(false); | 419 builder.SetIncognitoMode(false); |
| 428 } | 420 } |
| 429 | 421 |
| 430 if (command_line.HasSwitch(headless::switches::kWindowSize)) { | 422 if (command_line.HasSwitch(switches::kWindowSize)) { |
| 431 std::string window_size = | 423 std::string window_size = |
| 432 command_line.GetSwitchValueASCII(headless::switches::kWindowSize); | 424 command_line.GetSwitchValueASCII(switches::kWindowSize); |
| 433 gfx::Size parsed_window_size; | 425 gfx::Size parsed_window_size; |
| 434 if (!ParseWindowSize(window_size, &parsed_window_size)) { | 426 if (!ParseWindowSize(window_size, &parsed_window_size)) { |
| 435 LOG(ERROR) << "Malformed window size"; | 427 LOG(ERROR) << "Malformed window size"; |
| 436 return EXIT_FAILURE; | 428 return EXIT_FAILURE; |
| 437 } | 429 } |
| 438 builder.SetWindowSize(parsed_window_size); | 430 builder.SetWindowSize(parsed_window_size); |
| 439 } | 431 } |
| 440 | 432 |
| 441 return HeadlessBrowserMain( | 433 return HeadlessBrowserMain( |
| 442 builder.Build(), | 434 builder.Build(), |
| 443 base::Bind(&HeadlessShell::OnStart, base::Unretained(&shell))); | 435 base::Bind(&HeadlessShell::OnStart, base::Unretained(&shell))); |
| 444 } | 436 } |
| 437 |
| 438 } // namespace headless |
| OLD | NEW |