| Index: headless/app/headless_shell.cc
|
| diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc
|
| index d6d6adeb758a5ef06ce2821d3973911297b22c74..49cfd282a9e4d39db662064bd6d2f2eb560da880 100644
|
| --- a/headless/app/headless_shell.cc
|
| +++ b/headless/app/headless_shell.cc
|
| @@ -32,6 +32,8 @@ namespace {
|
| const char kDevToolsHttpServerAddress[] = "127.0.0.1";
|
| // Default file name for screenshot. Can be overriden by "--screenshot" switch.
|
| const char kDefaultScreenshotFileName[] = "screenshot.png";
|
| +// Default file name for pdf. Can be overriden by "--print-to-pdf" switch.
|
| +const char kDefaultPDFFileName[] = "output.pdf";
|
|
|
| bool ParseWindowSize(std::string window_size, gfx::Size* parsed_window_size) {
|
| int width, height = 0;
|
| @@ -255,6 +257,9 @@ void HeadlessShell::OnPageReady() {
|
| } else if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| switches::kScreenshot)) {
|
| CaptureScreenshot();
|
| + } else if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kPrintToPDF)) {
|
| + PrintToPDF();
|
| } else {
|
| Shutdown();
|
| }
|
| @@ -319,73 +324,89 @@ void HeadlessShell::CaptureScreenshot() {
|
|
|
| void HeadlessShell::OnScreenshotCaptured(
|
| std::unique_ptr<page::CaptureScreenshotResult> result) {
|
| + WriteFile(switches::kScreenshot, kDefaultScreenshotFileName,
|
| + result->GetData());
|
| +}
|
| +
|
| +void HeadlessShell::PrintToPDF() {
|
| + devtools_client_->GetPage()->GetExperimental()->PrintToPDF(
|
| + page::PrintToPDFParams::Builder().Build(),
|
| + base::Bind(&HeadlessShell::OnPDFCreated, weak_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void HeadlessShell::OnPDFCreated(
|
| + std::unique_ptr<page::PrintToPDFResult> result) {
|
| + if (!result) {
|
| + LOG(ERROR) << "Print to PDF failed";
|
| + Shutdown();
|
| + return;
|
| + }
|
| + WriteFile(switches::kPrintToPDF, kDefaultPDFFileName, result->GetData());
|
| +}
|
| +
|
| +void HeadlessShell::WriteFile(const std::string& switch_string,
|
| + const std::string& default_file_name,
|
| + const std::string& data) {
|
| base::FilePath file_name =
|
| - base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
|
| - switches::kScreenshot);
|
| + base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(switch_string);
|
| if (file_name.empty()) {
|
| - file_name = base::FilePath().AppendASCII(kDefaultScreenshotFileName);
|
| + file_name = base::FilePath().AppendASCII(default_file_name);
|
| }
|
|
|
| - screenshot_file_proxy_.reset(
|
| - new base::FileProxy(browser_->BrowserFileThread().get()));
|
| - if (!screenshot_file_proxy_->CreateOrOpen(
|
| + file_proxy_.reset(new base::FileProxy(browser_->BrowserFileThread().get()));
|
| + if (!file_proxy_->CreateOrOpen(
|
| file_name, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE,
|
| - base::Bind(&HeadlessShell::OnScreenshotFileOpened,
|
| - weak_factory_.GetWeakPtr(),
|
| - base::Passed(std::move(result)), file_name))) {
|
| + base::Bind(&HeadlessShell::OnFileOpened, weak_factory_.GetWeakPtr(),
|
| + data, file_name))) {
|
| // Operation could not be started.
|
| - OnScreenshotFileOpened(nullptr, file_name, base::File::FILE_ERROR_FAILED);
|
| + OnFileOpened("", file_name, base::File::FILE_ERROR_FAILED);
|
| }
|
| }
|
|
|
| -void HeadlessShell::OnScreenshotFileOpened(
|
| - std::unique_ptr<page::CaptureScreenshotResult> result,
|
| - const base::FilePath file_name,
|
| - base::File::Error error_code) {
|
| - if (!screenshot_file_proxy_->IsValid()) {
|
| - LOG(ERROR) << "Writing screenshot to file " << file_name.value()
|
| +void HeadlessShell::OnFileOpened(const std::string& data,
|
| + const base::FilePath file_name,
|
| + base::File::Error error_code) {
|
| + if (!file_proxy_->IsValid()) {
|
| + LOG(ERROR) << "Writing to file " << file_name.value()
|
| << " was unsuccessful, could not open file: "
|
| << base::File::ErrorToString(error_code);
|
| return;
|
| }
|
|
|
| - std::string decoded_png;
|
| - base::Base64Decode(result->GetData(), &decoded_png);
|
| + std::string decoded_data;
|
| + base::Base64Decode(data, &decoded_data);
|
| scoped_refptr<net::IOBufferWithSize> buf =
|
| - new net::IOBufferWithSize(decoded_png.size());
|
| - memcpy(buf->data(), decoded_png.data(), decoded_png.size());
|
| + new net::IOBufferWithSize(decoded_data.size());
|
| + memcpy(buf->data(), decoded_data.data(), decoded_data.size());
|
|
|
| - if (!screenshot_file_proxy_->Write(
|
| + if (!file_proxy_->Write(
|
| 0, buf->data(), buf->size(),
|
| - base::Bind(&HeadlessShell::OnScreenshotFileWritten,
|
| - weak_factory_.GetWeakPtr(), file_name, buf->size()))) {
|
| + base::Bind(&HeadlessShell::OnFileWritten, weak_factory_.GetWeakPtr(),
|
| + file_name, buf->size()))) {
|
| // Operation may have completed successfully or failed.
|
| - OnScreenshotFileWritten(file_name, buf->size(),
|
| - base::File::FILE_ERROR_FAILED, 0);
|
| + OnFileWritten(file_name, buf->size(), base::File::FILE_ERROR_FAILED, 0);
|
| }
|
| }
|
|
|
| -void HeadlessShell::OnScreenshotFileWritten(const base::FilePath file_name,
|
| - const int length,
|
| - base::File::Error error_code,
|
| - int write_result) {
|
| +void HeadlessShell::OnFileWritten(const base::FilePath file_name,
|
| + const int length,
|
| + base::File::Error error_code,
|
| + int write_result) {
|
| if (write_result < length) {
|
| // TODO(eseckler): Support recovering from partial writes.
|
| - LOG(ERROR) << "Writing screenshot to file " << file_name.value()
|
| + LOG(ERROR) << "Writing to file " << file_name.value()
|
| << " was unsuccessful: " << net::ErrorToString(write_result);
|
| } else {
|
| - LOG(INFO) << "Screenshot written to file " << file_name.value() << "."
|
| - << std::endl;
|
| + LOG(INFO) << "Written to file " << file_name.value() << ".";
|
| }
|
| - if (!screenshot_file_proxy_->Close(
|
| - base::Bind(&HeadlessShell::OnScreenshotFileClosed,
|
| - weak_factory_.GetWeakPtr()))) {
|
| + if (!file_proxy_->Close(base::Bind(&HeadlessShell::OnFileClosed,
|
| + weak_factory_.GetWeakPtr()))) {
|
| // Operation could not be started.
|
| - OnScreenshotFileClosed(base::File::FILE_ERROR_FAILED);
|
| + OnFileClosed(base::File::FILE_ERROR_FAILED);
|
| }
|
| }
|
|
|
| -void HeadlessShell::OnScreenshotFileClosed(base::File::Error error_code) {
|
| +void HeadlessShell::OnFileClosed(base::File::Error error_code) {
|
| Shutdown();
|
| }
|
|
|
| @@ -417,6 +438,11 @@ bool ValidateCommandLine(const base::CommandLine& command_line) {
|
| << "when remote debugging is enabled.";
|
| return false;
|
| }
|
| + if (command_line.HasSwitch(switches::kPrintToPDF)) {
|
| + LOG(ERROR) << "Print to PDF is disabled "
|
| + << "when remote debugging is enabled.";
|
| + return false;
|
| + }
|
| if (command_line.HasSwitch(switches::kTimeout)) {
|
| LOG(ERROR) << "Navigation timeout is disabled "
|
| << "when remote debugging is enabled.";
|
|
|