Chromium Code Reviews| 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..ec36966f873fae4cbc8a8866eed6fe1041634153 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( |
|
Vitaly Buka (NO REVIEWS)
2015/02/17 19:43:54
PostTaskAndReplyWithResult is appropriate here
tbarzic
2015/02/18 02:55:49
Done.
|
| + 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,63 @@ 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, |
|
Vitaly Buka (NO REVIEWS)
2015/02/17 19:43:54
looks like this code is very similar to privet ver
tbarzic
2015/02/18 02:55:49
Yeah, meant to do that before sending the cl for r
|
| + const ExtensionPrinterHandler::RefCountedMemoryCallback& callback) { |
| + |
| + 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)); |
| + |
| +} |
| + |
| +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( |