| Index: chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
|
| diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
|
| index 4f032c87704de7027e234e2b21efe1641a1b0b95..39880f9a51f73be91ac3b8d5db6c03e8efec329c 100644
|
| --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
|
| +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
|
| @@ -4,21 +4,74 @@
|
|
|
| #include "chrome/browser/ui/webui/print_preview/extension_printer_handler.h"
|
|
|
| +#include <algorithm>
|
| +
|
| #include "base/bind.h"
|
| #include "base/callback.h"
|
| -#include "base/values.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/file_util.h"
|
| +#include "base/location.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/ref_counted_memory.h"
|
| +#include "base/single_thread_task_runner.h"
|
| +#include "base/thread_task_runner_handle.h"
|
| +#include "base/threading/worker_pool.h"
|
| +#include "chrome/browser/local_discovery/pwg_raster_converter.h"
|
| #include "components/cloud_devices/common/cloud_device_description.h"
|
| #include "components/cloud_devices/common/printer_description.h"
|
| #include "extensions/browser/api/printer_provider/printer_provider_api.h"
|
| -#include "printing/print_job_constants.h"
|
| -
|
| +#include "printing/pdf_render_settings.h"
|
| +#include "printing/pwg_raster_settings.h"
|
| +#include "printing/units.h"
|
| +#include "ui/gfx/geometry/rect.h"
|
| +#include "ui/gfx/geometry/size.h"
|
| namespace {
|
|
|
| const char kContentTypePdf[] = "application/pdf";
|
| +const char kContentTypePWGRaster[] = "image/pwg-raster";
|
| const char kContentTypeAll[] = "*/*";
|
|
|
| const char kInvalidDataPrintError[] = "INVALID_DATA";
|
|
|
| +// Reads raster data from file path |raster_path| to a RefCountedMemory object,
|
| +// which is then passed to |callback| on |response_task_runner|.
|
| +void ReadConvertedPWGRasterFileOnWorkerThread(
|
| + const base::FilePath& raster_path,
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& response_task_runner,
|
| + const ExtensionPrinterHandler::RefCountedMemoryCallback& callback) {
|
| + scoped_refptr<base::RefCountedMemory> result;
|
| + int64 file_size;
|
| + if (base::GetFileSize(raster_path, &file_size) &&
|
| + file_size <= extensions::PrinterProviderAPI::kMaxDocumentSize) {
|
| + scoped_ptr<std::string> data(new std::string());
|
| + data->reserve(file_size);
|
| +
|
| + if (base::ReadFileToString(raster_path, data.get()))
|
| + result = base::RefCountedString::TakeString(data.release());
|
| + } else {
|
| + LOG(ERROR) << "Invalid raster file size.";
|
| + }
|
| +
|
| + response_task_runner->PostTask(FROM_HERE, base::Bind(callback, result));
|
| +}
|
| +
|
| +// Posts a task to read a file containing converted PWG raster data to the
|
| +// worker pool.
|
| +void ReadConvertedPWGRasterFile(
|
| + const ExtensionPrinterHandler::RefCountedMemoryCallback& callback,
|
| + bool success,
|
| + const base::FilePath& pwg_file_path) {
|
| + if (!success) {
|
| + callback.Run(scoped_refptr<base::RefCountedMemory>());
|
| + return;
|
| + }
|
| +
|
| + base::WorkerPool::GetTaskRunner(true)->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&ReadConvertedPWGRasterFileOnWorkerThread, pwg_file_path,
|
| + base::ThreadTaskRunnerHandle::Get(), callback));
|
| +}
|
| +
|
| } // namespace
|
|
|
| ExtensionPrinterHandler::ExtensionPrinterHandler(
|
| @@ -59,11 +112,13 @@ void ExtensionPrinterHandler::StartPrint(
|
| const std::string& destination_id,
|
| const std::string& capability,
|
| const std::string& ticket_json,
|
| + const gfx::Size& size,
|
| const scoped_refptr<base::RefCountedMemory>& print_data,
|
| const PrinterHandler::PrintCallback& callback) {
|
| - extensions::PrinterProviderAPI::PrintJob print_job;
|
| - print_job.printer_id = destination_id;
|
| - print_job.ticket_json = ticket_json;
|
| + scoped_ptr<extensions::PrinterProviderAPI::PrintJob> print_job(
|
| + new extensions::PrinterProviderAPI::PrintJob());
|
| + print_job->printer_id = destination_id;
|
| + print_job->ticket_json = ticket_json;
|
|
|
| cloud_devices::CloudDeviceDescription printer_description;
|
| printer_description.InitFromString(capability);
|
| @@ -74,20 +129,65 @@ void ExtensionPrinterHandler::StartPrint(
|
| const bool kUsePdf = content_types.Contains(kContentTypePdf) ||
|
| content_types.Contains(kContentTypeAll);
|
|
|
| - if (!kUsePdf) {
|
| - // TODO(tbarzic): Convert data to PWG raster if the printer does not support
|
| - // PDF.
|
| + if (kUsePdf) {
|
| + print_job->content_type = kContentTypePdf;
|
| + DispatchPrintJob(callback, print_job.Pass(), print_data);
|
| + return;
|
| + }
|
| +
|
| + print_job->content_type = kContentTypePWGRaster;
|
| + ConvertToPWGRaster(print_data, printer_description, size,
|
| + base::Bind(&ExtensionPrinterHandler::DispatchPrintJob,
|
| + weak_ptr_factory_.GetWeakPtr(), callback,
|
| + base::Passed(&print_job)));
|
| +}
|
| +
|
| +void ExtensionPrinterHandler::ConvertToPWGRaster(
|
| + const scoped_refptr<base::RefCountedMemory>& data,
|
| + const cloud_devices::CloudDeviceDescription& printer_description,
|
| + const gfx::Size& size,
|
| + const ExtensionPrinterHandler::RefCountedMemoryCallback& callback) {
|
| +#if defined(ENABLE_SERVICE_DISCOVERY)
|
| + int dpi = printing::kDefaultPdfDpi;
|
| + cloud_devices::printer::DpiCapability dpis;
|
| + if (dpis.LoadFrom(printer_description))
|
| + dpi = std::max(dpis.GetDefault().horizontal, dpis.GetDefault().vertical);
|
| +
|
| + double scale = dpi;
|
| + scale /= printing::kPointsPerInch;
|
| +
|
| + gfx::Rect area(std::min(size.width(), size.height()) * scale,
|
| + std::max(size.width(), size.height()) * scale);
|
| +
|
| + if (!pwg_raster_converter_) {
|
| + pwg_raster_converter_ =
|
| + local_discovery::PWGRasterConverter::CreateDefault();
|
| + }
|
| + pwg_raster_converter_->Start(
|
| + data.get(), printing::PdfRenderSettings(area, dpi, true),
|
| + printing::PwgRasterSettings(),
|
| + base::Bind(&ReadConvertedPWGRasterFile, callback));
|
| +#else // if !defined(ENABLE_SERVICE_DISCOVERY)
|
| + SendPrintRequest(scoped_ptr<base::RefCountedMemory>());
|
| +#endif // defined(ENABLE_SERVICE_DISCOVERY)
|
| +}
|
| +
|
| +void ExtensionPrinterHandler::DispatchPrintJob(
|
| + const PrinterHandler::PrintCallback& callback,
|
| + scoped_ptr<extensions::PrinterProviderAPI::PrintJob> print_job,
|
| + const scoped_refptr<base::RefCountedMemory>& print_data) {
|
| + if (!print_data) {
|
| WrapPrintCallback(callback, false, kInvalidDataPrintError);
|
| return;
|
| }
|
|
|
| - print_job.content_type = kContentTypePdf;
|
| - print_job.document_bytes = print_data;
|
| + print_job->document_bytes = print_data;
|
| +
|
| extensions::PrinterProviderAPI::GetFactoryInstance()
|
| ->Get(browser_context_)
|
| ->DispatchPrintRequested(
|
| - print_job, base::Bind(&ExtensionPrinterHandler::WrapPrintCallback,
|
| - weak_ptr_factory_.GetWeakPtr(), callback));
|
| + *print_job, base::Bind(&ExtensionPrinterHandler::WrapPrintCallback,
|
| + weak_ptr_factory_.GetWeakPtr(), callback));
|
| }
|
|
|
| void ExtensionPrinterHandler::WrapGetPrintersCallback(
|
|
|