diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-18 12:05:09 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-18 12:05:09 +0000 |
commit | a46cb343c359db0241abc2c325f1750fd7ffa80b (patch) | |
tree | 8c224e2f693557f9c1f93e5de0a52eb86b6af034 /chrome/utility | |
parent | cac3776ef7baef58db33c1abcae5d1877fcce615 (diff) | |
download | chromium_src-a46cb343c359db0241abc2c325f1750fd7ffa80b.zip chromium_src-a46cb343c359db0241abc2c325f1750fd7ffa80b.tar.gz chromium_src-a46cb343c359db0241abc2c325f1750fd7ffa80b.tar.bz2 |
Split printing utility IPC messages into its own file.
Review URL: https://codereview.chromium.org/323693002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/utility')
-rw-r--r-- | chrome/utility/chrome_content_utility_client.cc | 523 | ||||
-rw-r--r-- | chrome/utility/chrome_content_utility_client.h | 49 | ||||
-rw-r--r-- | chrome/utility/chrome_content_utility_ipc_whitelist.cc | 4 | ||||
-rw-r--r-- | chrome/utility/chrome_content_utility_ipc_whitelist.h | 4 | ||||
-rw-r--r-- | chrome/utility/image_writer/image_writer_handler.h | 4 | ||||
-rw-r--r-- | chrome/utility/local_discovery/service_discovery_message_handler.h | 2 | ||||
-rw-r--r-- | chrome/utility/media_galleries/ipc_data_source.h | 2 | ||||
-rw-r--r-- | chrome/utility/printing_handler.cc | 536 | ||||
-rw-r--r-- | chrome/utility/printing_handler.h | 76 | ||||
-rw-r--r-- | chrome/utility/profile_import_handler.cc | 15 | ||||
-rw-r--r-- | chrome/utility/profile_import_handler.h | 6 | ||||
-rw-r--r-- | chrome/utility/utility_message_handler.h | 4 |
12 files changed, 636 insertions, 589 deletions
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index e50cede..b41b878 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc @@ -7,21 +7,16 @@ #include "base/base64.h" #include "base/bind.h" #include "base/command_line.h" -#include "base/file_util.h" #include "base/files/file_path.h" #include "base/json/json_reader.h" #include "base/memory/ref_counted.h" #include "base/path_service.h" -#include "base/scoped_native_library.h" #include "base/time/time.h" -#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_utility_messages.h" #include "chrome/common/extensions/chrome_extensions_client.h" #include "chrome/common/extensions/update_manifest.h" #include "chrome/common/safe_browsing/zip_analyzer.h" #include "chrome/utility/chrome_content_utility_ipc_whitelist.h" -#include "chrome/utility/cloud_print/bitmap_image.h" -#include "chrome/utility/cloud_print/pwg_encoder.h" #include "chrome/utility/extensions/unpacker.h" #include "chrome/utility/image_writer/image_writer_handler.h" #include "chrome/utility/profile_import_handler.h" @@ -37,8 +32,6 @@ #include "extensions/common/manifest.h" #include "media/base/media.h" #include "media/base/media_file_checker.h" -#include "printing/page_range.h" -#include "printing/pdf_render_settings.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/zlib/google/zip.h" #include "ui/base/ui_base_switches.h" @@ -47,13 +40,9 @@ #include "ui/gfx/size.h" #if defined(OS_WIN) -#include "base/win/iat_patch_function.h" -#include "base/win/scoped_handle.h" #include "chrome/common/extensions/api/networking_private/networking_private_crypto.h" #include "chrome/utility/media_galleries/itunes_pref_parser_win.h" #include "components/wifi/wifi_service.h" -#include "printing/emf_win.h" -#include "ui/gfx/gdi_util.h" #endif // defined(OS_WIN) #if defined(OS_MACOSX) @@ -75,15 +64,12 @@ #endif // !defined(OS_ANDROID) && !defined(OS_IOS) #if defined(ENABLE_FULL_PRINTING) -#include "chrome/common/crash_keys.h" -#include "printing/backend/print_backend.h" +#include "chrome/utility/printing_handler.h" #endif #if defined(ENABLE_MDNS) #include "chrome/utility/local_discovery/service_discovery_message_handler.h" -#endif // ENABLE_MDNS - -namespace chrome { +#endif namespace { @@ -95,212 +81,6 @@ void ReleaseProcessIfNeeded() { content::UtilityThread::Get()->ReleaseProcessIfNeeded(); } -class PdfFunctionsBase { - public: - PdfFunctionsBase() : render_pdf_to_bitmap_func_(NULL), - get_pdf_doc_info_func_(NULL) {} - - bool Init() { - base::FilePath pdf_module_path; - if (!PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path) || - !base::PathExists(pdf_module_path)) { - return false; - } - - pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); - if (!pdf_lib_.is_valid()) { - LOG(WARNING) << "Couldn't load PDF plugin"; - return false; - } - - render_pdf_to_bitmap_func_ = - reinterpret_cast<RenderPDFPageToBitmapProc>( - pdf_lib_.GetFunctionPointer("RenderPDFPageToBitmap")); - LOG_IF(WARNING, !render_pdf_to_bitmap_func_) << - "Missing RenderPDFPageToBitmap"; - - get_pdf_doc_info_func_ = - reinterpret_cast<GetPDFDocInfoProc>( - pdf_lib_.GetFunctionPointer("GetPDFDocInfo")); - LOG_IF(WARNING, !get_pdf_doc_info_func_) << "Missing GetPDFDocInfo"; - - if (!render_pdf_to_bitmap_func_ || !get_pdf_doc_info_func_ || - !PlatformInit(pdf_module_path, pdf_lib_)) { - Reset(); - } - - return IsValid(); - } - - bool IsValid() const { - return pdf_lib_.is_valid(); - } - - void Reset() { - pdf_lib_.Reset(NULL); - } - - bool RenderPDFPageToBitmap(const void* pdf_buffer, - int pdf_buffer_size, - int page_number, - void* bitmap_buffer, - int bitmap_width, - int bitmap_height, - int dpi_x, - int dpi_y, - bool autorotate) { - if (!render_pdf_to_bitmap_func_) - return false; - return render_pdf_to_bitmap_func_(pdf_buffer, pdf_buffer_size, page_number, - bitmap_buffer, bitmap_width, - bitmap_height, dpi_x, dpi_y, autorotate); - } - - bool GetPDFDocInfo(const void* pdf_buffer, - int buffer_size, - int* page_count, - double* max_page_width) { - if (!get_pdf_doc_info_func_) - return false; - return get_pdf_doc_info_func_(pdf_buffer, buffer_size, page_count, - max_page_width); - } - - protected: - virtual bool PlatformInit( - const base::FilePath& pdf_module_path, - const base::ScopedNativeLibrary& pdf_lib) { - return true; - } - - private: - // Exported by PDF plugin. - typedef bool (*RenderPDFPageToBitmapProc)(const void* pdf_buffer, - int pdf_buffer_size, - int page_number, - void* bitmap_buffer, - int bitmap_width, - int bitmap_height, - int dpi_x, - int dpi_y, - bool autorotate); - typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer, - int buffer_size, int* page_count, - double* max_page_width); - - RenderPDFPageToBitmapProc render_pdf_to_bitmap_func_; - GetPDFDocInfoProc get_pdf_doc_info_func_; - - base::ScopedNativeLibrary pdf_lib_; - DISALLOW_COPY_AND_ASSIGN(PdfFunctionsBase); -}; - -#if defined(OS_WIN) -// The 2 below IAT patch functions are almost identical to the code in -// render_process_impl.cc. This is needed to work around specific Windows APIs -// used by the Chrome PDF plugin that will fail in the sandbox. -static base::win::IATPatchFunction g_iat_patch_createdca; -HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, - LPCSTR device_name, - LPCSTR output, - const DEVMODEA* init_data) { - if (driver_name && (std::string("DISPLAY") == driver_name)) { - // CreateDC fails behind the sandbox, but not CreateCompatibleDC. - return CreateCompatibleDC(NULL); - } - - NOTREACHED(); - return CreateDCA(driver_name, device_name, output, init_data); -} - -static base::win::IATPatchFunction g_iat_patch_get_font_data; -DWORD WINAPI UtilityProcess_GetFontDataPatch( - HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { - int rv = GetFontData(hdc, table, offset, buffer, length); - if (rv == GDI_ERROR && hdc) { - HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); - - LOGFONT logfont; - if (GetObject(font, sizeof(LOGFONT), &logfont)) { - content::UtilityThread::Get()->PreCacheFont(logfont); - rv = GetFontData(hdc, table, offset, buffer, length); - content::UtilityThread::Get()->ReleaseCachedFonts(); - } - } - return rv; -} - -class PdfFunctionsWin : public PdfFunctionsBase { - public: - PdfFunctionsWin() : render_pdf_to_dc_func_(NULL) { - } - - bool PlatformInit( - const base::FilePath& pdf_module_path, - const base::ScopedNativeLibrary& pdf_lib) OVERRIDE { - // Patch the IAT for handling specific APIs known to fail in the sandbox. - if (!g_iat_patch_createdca.is_patched()) { - g_iat_patch_createdca.Patch(pdf_module_path.value().c_str(), - "gdi32.dll", "CreateDCA", - UtilityProcess_CreateDCAPatch); - } - - if (!g_iat_patch_get_font_data.is_patched()) { - g_iat_patch_get_font_data.Patch(pdf_module_path.value().c_str(), - "gdi32.dll", "GetFontData", - UtilityProcess_GetFontDataPatch); - } - render_pdf_to_dc_func_ = - reinterpret_cast<RenderPDFPageToDCProc>( - pdf_lib.GetFunctionPointer("RenderPDFPageToDC")); - LOG_IF(WARNING, !render_pdf_to_dc_func_) << "Missing RenderPDFPageToDC"; - - return render_pdf_to_dc_func_ != NULL; - } - - bool RenderPDFPageToDC(const void* pdf_buffer, - int buffer_size, - int page_number, - HDC dc, - int dpi_x, - int dpi_y, - int bounds_origin_x, - int bounds_origin_y, - int bounds_width, - int bounds_height, - bool fit_to_bounds, - bool stretch_to_bounds, - bool keep_aspect_ratio, - bool center_in_bounds, - bool autorotate) { - if (!render_pdf_to_dc_func_) - return false; - return render_pdf_to_dc_func_(pdf_buffer, buffer_size, page_number, - dc, dpi_x, dpi_y, bounds_origin_x, - bounds_origin_y, bounds_width, bounds_height, - fit_to_bounds, stretch_to_bounds, - keep_aspect_ratio, center_in_bounds, - autorotate); - } - - private: - // Exported by PDF plugin. - typedef bool (*RenderPDFPageToDCProc)( - const void* pdf_buffer, int buffer_size, int page_number, HDC dc, - int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, - int bounds_width, int bounds_height, bool fit_to_bounds, - bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, - bool autorotate); - RenderPDFPageToDCProc render_pdf_to_dc_func_; - - DISALLOW_COPY_AND_ASSIGN(PdfFunctionsWin); -}; - -typedef PdfFunctionsWin PdfFunctions; -#else // OS_WIN -typedef PdfFunctionsBase PdfFunctions; -#endif // OS_WIN - #if !defined(OS_ANDROID) && !defined(OS_IOS) void FinishParseMediaMetadata( metadata::MediaMetadataParser* parser, @@ -312,22 +92,24 @@ void FinishParseMediaMetadata( } #endif // !defined(OS_ANDROID) && !defined(OS_IOS) -static base::LazyInstance<PdfFunctions> g_pdf_lib = LAZY_INSTANCE_INITIALIZER; - } // namespace ChromeContentUtilityClient::ChromeContentUtilityClient() : filter_messages_(false) { #if !defined(OS_ANDROID) handlers_.push_back(new ProfileImportHandler()); -#endif // OS_ANDROID +#endif + +#if defined(ENABLE_FULL_PRINTING) + handlers_.push_back(new PrintingHandler()); +#endif #if defined(ENABLE_MDNS) if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kUtilityProcessEnableMDns)) { handlers_.push_back(new local_discovery::ServiceDiscoveryMessageHandler()); } -#endif // ENABLE_MDNS +#endif handlers_.push_back(new image_writer::ImageWriterHandler()); } @@ -350,11 +132,8 @@ void ChromeContentUtilityClient::UtilityThreadStarted() { bool ChromeContentUtilityClient::OnMessageReceived( const IPC::Message& message) { - if (filter_messages_ && - (message_id_whitelist_.find(message.type()) == - message_id_whitelist_.end())) { + if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type())) return false; - } bool handled = true; IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) @@ -365,17 +144,9 @@ bool ChromeContentUtilityClient::OnMessageReceived( OnParseUpdateManifest) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImage, OnDecodeImage) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImageBase64, OnDecodeImageBase64) - IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles, - OnRenderPDFPagesToMetafile) - IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToPWGRaster, - OnRenderPDFPagesToPWGRaster) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RobustJPEGDecodeImage, OnRobustJPEGDecodeImage) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseJSON, OnParseJSON) - IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterCapsAndDefaults, - OnGetPrinterCapsAndDefaults) - IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterSemanticCapsAndDefaults, - OnGetPrinterSemanticCapsAndDefaults) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileBsdiff, OnPatchFileBsdiff) IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileCourgette, @@ -431,6 +202,10 @@ bool ChromeContentUtilityClient::OnMessageReceived( // static void ChromeContentUtilityClient::PreSandboxStartup() { +#if defined(ENABLE_FULL_PRINTING) + PrintingHandler::PreSandboxStartup(); +#endif + #if defined(ENABLE_MDNS) if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kUtilityProcessEnableMDns)) { @@ -438,8 +213,6 @@ void ChromeContentUtilityClient::PreSandboxStartup() { } #endif // ENABLE_MDNS - g_pdf_lib.Get().Init(); - #if !defined(OS_ANDROID) && !defined(OS_IOS) // Initialize libexif for image metadata parsing. metadata::ImageMetadataExtractor::InitializeLibrary(); @@ -566,229 +339,6 @@ void ChromeContentUtilityClient::OnCreateZipFile( } #endif // defined(OS_CHROMEOS) -void ChromeContentUtilityClient::OnRenderPDFPagesToMetafile( - IPC::PlatformFileForTransit pdf_transit, - const base::FilePath& metafile_path, - const printing::PdfRenderSettings& settings, - const std::vector<printing::PageRange>& page_ranges_const) { - bool succeeded = false; -#if defined(OS_WIN) - base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit); - int highest_rendered_page_number = 0; - double scale_factor = 1.0; - std::vector<printing::PageRange> page_ranges = page_ranges_const; - succeeded = RenderPDFToWinMetafile(pdf_file.Pass(), - metafile_path, - settings, - &page_ranges, - &highest_rendered_page_number, - &scale_factor); - if (succeeded) { - // TODO(vitalybuka|scottmg): http://crbug.com/170859. These could - // potentially be sent as each page is converted so that the spool could - // start sooner. - Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_Succeeded( - page_ranges, scale_factor)); - } -#endif // defined(OS_WIN) - if (!succeeded) { - Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed()); - } - ReleaseProcessIfNeeded(); -} - -void ChromeContentUtilityClient::OnRenderPDFPagesToPWGRaster( - IPC::PlatformFileForTransit pdf_transit, - const printing::PdfRenderSettings& settings, - const printing::PwgRasterSettings& bitmap_settings, - IPC::PlatformFileForTransit bitmap_transit) { - base::File pdf = IPC::PlatformFileForTransitToFile(pdf_transit); - base::File bitmap = IPC::PlatformFileForTransitToFile(bitmap_transit); - if (RenderPDFPagesToPWGRaster(pdf.Pass(), settings, bitmap_settings, - bitmap.Pass())) { - Send(new ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Succeeded()); - } else { - Send(new ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Failed()); - } - ReleaseProcessIfNeeded(); -} - -#if defined(OS_WIN) -bool ChromeContentUtilityClient::RenderPDFToWinMetafile( - base::File pdf_file, - const base::FilePath& metafile_path, - const printing::PdfRenderSettings& settings, - std::vector<printing::PageRange>* page_ranges, - int* highest_rendered_page_number, - double* scale_factor) { - DCHECK(page_ranges); - *highest_rendered_page_number = -1; - *scale_factor = 1.0; - - if (!g_pdf_lib.Get().IsValid()) - return false; - - // TODO(sanjeevr): Add a method to the PDF DLL that takes in a file handle - // and a page range array. That way we don't need to read the entire PDF into - // memory. - int64 length = pdf_file.GetLength(); - if (length < 0) - return false; - - std::vector<char> buffer; - buffer.resize(length); - if (length != pdf_file.Read(0, &buffer.front(), length)) - return false; - - int total_page_count = 0; - if (!g_pdf_lib.Get().GetPDFDocInfo(&buffer.front(), buffer.size(), - &total_page_count, NULL)) { - return false; - } - - // If no range supplied, do all pages. - if (page_ranges->empty()) { - printing::PageRange page_range_all; - page_range_all.from = 0; - page_range_all.to = total_page_count - 1; - page_ranges->push_back(page_range_all); - } - - bool ret = false; - std::vector<printing::PageRange>::const_iterator iter; - for (iter = page_ranges->begin(); iter != page_ranges->end(); ++iter) { - for (int page_number = iter->from; page_number <= iter->to; ++page_number) { - if (page_number >= total_page_count) - break; - - printing::Emf metafile; - metafile.InitToFile(metafile_path.InsertBeforeExtensionASCII( - base::StringPrintf(".%d", page_number))); - - // We need to scale down DC to fit an entire page into DC available area. - // Current metafile is based on screen DC and have current screen size. - // Writing outside of those boundaries will result in the cut-off output. - // On metafiles (this is the case here), scaling down will still record - // original coordinates and we'll be able to print in full resolution. - // Before playback we'll need to counter the scaling up that will happen - // in the service (print_system_win.cc). - *scale_factor = gfx::CalculatePageScale(metafile.context(), - settings.area().right(), - settings.area().bottom()); - gfx::ScaleDC(metafile.context(), *scale_factor); - - // The underlying metafile is of type Emf and ignores the arguments passed - // to StartPage. - metafile.StartPage(gfx::Size(), gfx::Rect(), 1); - if (g_pdf_lib.Get().RenderPDFPageToDC( - &buffer.front(), buffer.size(), page_number, metafile.context(), - settings.dpi(), settings.dpi(), settings.area().x(), - settings.area().y(), settings.area().width(), - settings.area().height(), true, false, true, true, - settings.autorotate())) { - if (*highest_rendered_page_number < page_number) - *highest_rendered_page_number = page_number; - ret = true; - } - metafile.FinishPage(); - metafile.FinishDocument(); - } - } - return ret; -} -#endif // defined(OS_WIN) - -bool ChromeContentUtilityClient::RenderPDFPagesToPWGRaster( - base::File pdf_file, - const printing::PdfRenderSettings& settings, - const printing::PwgRasterSettings& bitmap_settings, - base::File bitmap_file) { - bool autoupdate = true; - if (!g_pdf_lib.Get().IsValid()) - return false; - - base::File::Info info; - if (!pdf_file.GetInfo(&info) || info.size <= 0) - return false; - - std::string data(info.size, 0); - int data_size = pdf_file.Read(0, &data[0], data.size()); - if (data_size != static_cast<int>(data.size())) - return false; - - int total_page_count = 0; - if (!g_pdf_lib.Get().GetPDFDocInfo(data.data(), data.size(), - &total_page_count, NULL)) { - return false; - } - - cloud_print::PwgEncoder encoder; - std::string pwg_header; - encoder.EncodeDocumentHeader(&pwg_header); - int bytes_written = bitmap_file.WriteAtCurrentPos(pwg_header.data(), - pwg_header.size()); - if (bytes_written != static_cast<int>(pwg_header.size())) - return false; - - cloud_print::BitmapImage image(settings.area().size(), - cloud_print::BitmapImage::BGRA); - for (int i = 0; i < total_page_count; ++i) { - int page_number = i; - - if (bitmap_settings.reverse_page_order) { - page_number = total_page_count - 1 - page_number; - } - - if (!g_pdf_lib.Get().RenderPDFPageToBitmap(data.data(), - data.size(), - page_number, - image.pixel_data(), - image.size().width(), - image.size().height(), - settings.dpi(), - settings.dpi(), - autoupdate)) { - return false; - } - - cloud_print::PwgHeaderInfo header_info; - header_info.dpi = settings.dpi(); - header_info.total_pages = total_page_count; - - // Transform odd pages. - if (page_number % 2) { - switch (bitmap_settings.odd_page_transform) { - case printing::TRANSFORM_NORMAL: - break; - case printing::TRANSFORM_ROTATE_180: - header_info.flipx = true; - header_info.flipy = true; - break; - case printing::TRANSFORM_FLIP_HORIZONTAL: - header_info.flipx = true; - break; - case printing::TRANSFORM_FLIP_VERTICAL: - header_info.flipy = true; - break; - } - } - - if (bitmap_settings.rotate_all_pages) { - header_info.flipx = !header_info.flipx; - header_info.flipy = !header_info.flipy; - } - - std::string pwg_page; - if (!encoder.EncodePage(image, header_info, &pwg_page)) - return false; - bytes_written = bitmap_file.WriteAtCurrentPos(pwg_page.data(), - pwg_page.size()); - if (bytes_written != static_cast<int>(pwg_page.size())) - return false; - } - return true; -} - void ChromeContentUtilityClient::OnRobustJPEGDecodeImage( const std::vector<unsigned char>& encoded_data) { // Our robust jpeg decoding is using IJG libjpeg. @@ -821,51 +371,6 @@ void ChromeContentUtilityClient::OnParseJSON(const std::string& json) { ReleaseProcessIfNeeded(); } -void ChromeContentUtilityClient::OnGetPrinterCapsAndDefaults( - const std::string& printer_name) { -#if defined(ENABLE_FULL_PRINTING) - scoped_refptr<printing::PrintBackend> print_backend = - printing::PrintBackend::CreateInstance(NULL); - printing::PrinterCapsAndDefaults printer_info; - - crash_keys::ScopedPrinterInfo crash_key( - print_backend->GetPrinterDriverInfo(printer_name)); - - if (print_backend->GetPrinterCapsAndDefaults(printer_name, &printer_info)) { - Send(new ChromeUtilityHostMsg_GetPrinterCapsAndDefaults_Succeeded( - printer_name, printer_info)); - } else // NOLINT -#endif - { - Send(new ChromeUtilityHostMsg_GetPrinterCapsAndDefaults_Failed( - printer_name)); - } - ReleaseProcessIfNeeded(); -} - -void ChromeContentUtilityClient::OnGetPrinterSemanticCapsAndDefaults( - const std::string& printer_name) { -#if defined(ENABLE_FULL_PRINTING) - scoped_refptr<printing::PrintBackend> print_backend = - printing::PrintBackend::CreateInstance(NULL); - printing::PrinterSemanticCapsAndDefaults printer_info; - - crash_keys::ScopedPrinterInfo crash_key( - print_backend->GetPrinterDriverInfo(printer_name)); - - if (print_backend->GetPrinterSemanticCapsAndDefaults(printer_name, - &printer_info)) { - Send(new ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Succeeded( - printer_name, printer_info)); - } else // NOLINT -#endif - { - Send(new ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Failed( - printer_name)); - } - ReleaseProcessIfNeeded(); -} - void ChromeContentUtilityClient::OnPatchFileBsdiff( const base::FilePath& input_file, const base::FilePath& patch_file, @@ -1034,5 +539,3 @@ void ChromeContentUtilityClient::OnGetAndEncryptWiFiCredentials( success)); } #endif // defined(OS_WIN) - -} // namespace chrome diff --git a/chrome/utility/chrome_content_utility_client.h b/chrome/utility/chrome_content_utility_client.h index fc3a5dd..1e4afcd 100644 --- a/chrome/utility/chrome_content_utility_client.h +++ b/chrome/utility/chrome_content_utility_client.h @@ -6,8 +6,6 @@ #define CHROME_UTILITY_CHROME_CONTENT_UTILITY_CLIENT_H_ #include "base/compiler_specific.h" -#include "base/files/file.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "chrome/common/media_galleries/picasa_types.h" #include "content/public/utility/content_utility_client.h" @@ -18,22 +16,10 @@ class FilePath; struct FileDescriptor; } -namespace gfx { -class Rect; -} - namespace metadata { class MediaMetadataParser; } -namespace printing { -class PdfRenderSettings; -struct PwgRasterSettings; -struct PageRange; -} - -namespace chrome { - class UtilityMessageHandler; class ChromeContentUtilityClient : public content::ContentUtilityClient { @@ -55,16 +41,6 @@ class ChromeContentUtilityClient : public content::ContentUtilityClient { void OnParseUpdateManifest(const std::string& xml); void OnDecodeImage(const std::vector<unsigned char>& encoded_data); void OnDecodeImageBase64(const std::string& encoded_data); - void OnRenderPDFPagesToMetafile( - IPC::PlatformFileForTransit pdf_transit, - const base::FilePath& metafile_path, - const printing::PdfRenderSettings& settings, - const std::vector<printing::PageRange>& page_ranges); - void OnRenderPDFPagesToPWGRaster( - IPC::PlatformFileForTransit pdf_transit, - const printing::PdfRenderSettings& settings, - const printing::PwgRasterSettings& bitmap_settings, - IPC::PlatformFileForTransit bitmap_transit); void OnRobustJPEGDecodeImage( const std::vector<unsigned char>& encoded_data); void OnParseJSON(const std::string& json); @@ -75,29 +51,6 @@ class ChromeContentUtilityClient : public content::ContentUtilityClient { const base::FileDescriptor& dest_fd); #endif // defined(OS_CHROMEOS) -#if defined(OS_WIN) - // Helper method for Windows. - // |highest_rendered_page_number| is set to -1 on failure to render any page. - // |page_ranges| is both input and output. If supplied as input, only the - // specified pages will be rendered. If an empty vector is supplied it will - // be filled with a range of all pages that were rendered. - bool RenderPDFToWinMetafile( - base::File pdf_file, - const base::FilePath& metafile_path, - const printing::PdfRenderSettings& settings, - std::vector<printing::PageRange>* page_ranges, - int* highest_rendered_page_number, - double* scale_factor); -#endif // defined(OS_WIN) - - bool RenderPDFPagesToPWGRaster( - base::File pdf_file, - const printing::PdfRenderSettings& settings, - const printing::PwgRasterSettings& bitmap_settings, - base::File bitmap_file); - - void OnGetPrinterCapsAndDefaults(const std::string& printer_name); - void OnGetPrinterSemanticCapsAndDefaults(const std::string& printer_name); void OnPatchFileBsdiff(const base::FilePath& input_file, const base::FilePath& patch_file, const base::FilePath& output_file); @@ -151,6 +104,4 @@ class ChromeContentUtilityClient : public content::ContentUtilityClient { DISALLOW_COPY_AND_ASSIGN(ChromeContentUtilityClient); }; -} // namespace chrome - #endif // CHROME_UTILITY_CHROME_CONTENT_UTILITY_CLIENT_H_ diff --git a/chrome/utility/chrome_content_utility_ipc_whitelist.cc b/chrome/utility/chrome_content_utility_ipc_whitelist.cc index fddac13..c831d17 100644 --- a/chrome/utility/chrome_content_utility_ipc_whitelist.cc +++ b/chrome/utility/chrome_content_utility_ipc_whitelist.cc @@ -5,8 +5,6 @@ #include "chrome/utility/chrome_content_utility_ipc_whitelist.h" #include "chrome/common/chrome_utility_messages.h" -namespace chrome { - const uint32 kMessageWhitelist[] = { #ifdef OS_WIN ChromeUtilityHostMsg_GetAndEncryptWiFiCredentials::ID, @@ -16,5 +14,3 @@ const uint32 kMessageWhitelist[] = { ChromeUtilityMsg_ImageWriter_Verify::ID}; const size_t kMessageWhitelistSize = arraysize(kMessageWhitelist); - -} // namespace chrome diff --git a/chrome/utility/chrome_content_utility_ipc_whitelist.h b/chrome/utility/chrome_content_utility_ipc_whitelist.h index fcbd36c..1e6ea6a 100644 --- a/chrome/utility/chrome_content_utility_ipc_whitelist.h +++ b/chrome/utility/chrome_content_utility_ipc_whitelist.h @@ -7,8 +7,6 @@ #include "base/basictypes.h" -namespace chrome { - // This array contains the list of IPC messages that the utility process will // accept when running with elevated privileges. When new messages need to run // with elevated privileges, add them here and be sure to add a security @@ -16,6 +14,4 @@ namespace chrome { extern const uint32 kMessageWhitelist[]; extern const size_t kMessageWhitelistSize; -} // namespace chrome - #endif // CHROME_UTILITY_CHROME_CONTENT_UTILITY_IPC_WHITELIST_H_ diff --git a/chrome/utility/image_writer/image_writer_handler.h b/chrome/utility/image_writer/image_writer_handler.h index 4d241cf..cd4816e 100644 --- a/chrome/utility/image_writer/image_writer_handler.h +++ b/chrome/utility/image_writer/image_writer_handler.h @@ -18,8 +18,8 @@ class FilePath; namespace image_writer { // A handler for messages related to writing images. This class is added as a -// handler in chrome::ChromeContentUtilityClient. -class ImageWriterHandler : public chrome::UtilityMessageHandler { +// handler in ChromeContentUtilityClient. +class ImageWriterHandler : public UtilityMessageHandler { public: ImageWriterHandler(); virtual ~ImageWriterHandler(); diff --git a/chrome/utility/local_discovery/service_discovery_message_handler.h b/chrome/utility/local_discovery/service_discovery_message_handler.h index 2064f55..f627432 100644 --- a/chrome/utility/local_discovery/service_discovery_message_handler.h +++ b/chrome/utility/local_discovery/service_discovery_message_handler.h @@ -33,7 +33,7 @@ namespace local_discovery { class ServiceDiscoveryClient; // Handles messages related to local discovery inside utility process. -class ServiceDiscoveryMessageHandler : public chrome::UtilityMessageHandler { +class ServiceDiscoveryMessageHandler : public UtilityMessageHandler { public: ServiceDiscoveryMessageHandler(); virtual ~ServiceDiscoveryMessageHandler(); diff --git a/chrome/utility/media_galleries/ipc_data_source.h b/chrome/utility/media_galleries/ipc_data_source.h index bcf5084..c65c457 100644 --- a/chrome/utility/media_galleries/ipc_data_source.h +++ b/chrome/utility/media_galleries/ipc_data_source.h @@ -24,7 +24,7 @@ namespace metadata { // as a DataSource on a different thread. The utility thread must not be blocked // for read operations to succeed. class IPCDataSource: public media::DataSource, - public chrome::UtilityMessageHandler { + public UtilityMessageHandler { public: // May only be called on the utility thread. explicit IPCDataSource(int64 total_size); diff --git a/chrome/utility/printing_handler.cc b/chrome/utility/printing_handler.cc new file mode 100644 index 0000000..95e0f3ee --- /dev/null +++ b/chrome/utility/printing_handler.cc @@ -0,0 +1,536 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/utility/printing_handler.h" + +#include "base/file_util.h" +#include "base/lazy_instance.h" +#include "base/path_service.h" +#include "base/scoped_native_library.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_utility_printing_messages.h" +#include "chrome/utility/cloud_print/bitmap_image.h" +#include "chrome/utility/cloud_print/pwg_encoder.h" +#include "content/public/utility/utility_thread.h" +#include "printing/page_range.h" +#include "printing/pdf_render_settings.h" + +#if defined(OS_WIN) +#include "base/win/iat_patch_function.h" +#include "printing/emf_win.h" +#include "ui/gfx/gdi_util.h" +#endif + +#if defined(ENABLE_FULL_PRINTING) +#include "chrome/common/crash_keys.h" +#include "printing/backend/print_backend.h" +#endif + +namespace { + +bool Send(IPC::Message* message) { + return content::UtilityThread::Get()->Send(message); +} + +void ReleaseProcessIfNeeded() { + content::UtilityThread::Get()->ReleaseProcessIfNeeded(); +} + +class PdfFunctionsBase { + public: + PdfFunctionsBase() : render_pdf_to_bitmap_func_(NULL), + get_pdf_doc_info_func_(NULL) {} + + bool Init() { + base::FilePath pdf_module_path; + if (!PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_module_path) || + !base::PathExists(pdf_module_path)) { + return false; + } + + pdf_lib_.Reset(base::LoadNativeLibrary(pdf_module_path, NULL)); + if (!pdf_lib_.is_valid()) { + LOG(WARNING) << "Couldn't load PDF plugin"; + return false; + } + + render_pdf_to_bitmap_func_ = + reinterpret_cast<RenderPDFPageToBitmapProc>( + pdf_lib_.GetFunctionPointer("RenderPDFPageToBitmap")); + LOG_IF(WARNING, !render_pdf_to_bitmap_func_) << + "Missing RenderPDFPageToBitmap"; + + get_pdf_doc_info_func_ = + reinterpret_cast<GetPDFDocInfoProc>( + pdf_lib_.GetFunctionPointer("GetPDFDocInfo")); + LOG_IF(WARNING, !get_pdf_doc_info_func_) << "Missing GetPDFDocInfo"; + + if (!render_pdf_to_bitmap_func_ || !get_pdf_doc_info_func_ || + !PlatformInit(pdf_module_path, pdf_lib_)) { + Reset(); + } + + return IsValid(); + } + + bool IsValid() const { + return pdf_lib_.is_valid(); + } + + void Reset() { + pdf_lib_.Reset(NULL); + } + + bool RenderPDFPageToBitmap(const void* pdf_buffer, + int pdf_buffer_size, + int page_number, + void* bitmap_buffer, + int bitmap_width, + int bitmap_height, + int dpi_x, + int dpi_y, + bool autorotate) { + if (!render_pdf_to_bitmap_func_) + return false; + return render_pdf_to_bitmap_func_(pdf_buffer, pdf_buffer_size, page_number, + bitmap_buffer, bitmap_width, + bitmap_height, dpi_x, dpi_y, autorotate); + } + + bool GetPDFDocInfo(const void* pdf_buffer, + int buffer_size, + int* page_count, + double* max_page_width) { + if (!get_pdf_doc_info_func_) + return false; + return get_pdf_doc_info_func_(pdf_buffer, buffer_size, page_count, + max_page_width); + } + + protected: + virtual bool PlatformInit( + const base::FilePath& pdf_module_path, + const base::ScopedNativeLibrary& pdf_lib) { + return true; + } + + private: + // Exported by PDF plugin. + typedef bool (*RenderPDFPageToBitmapProc)(const void* pdf_buffer, + int pdf_buffer_size, + int page_number, + void* bitmap_buffer, + int bitmap_width, + int bitmap_height, + int dpi_x, + int dpi_y, + bool autorotate); + typedef bool (*GetPDFDocInfoProc)(const void* pdf_buffer, + int buffer_size, int* page_count, + double* max_page_width); + + RenderPDFPageToBitmapProc render_pdf_to_bitmap_func_; + GetPDFDocInfoProc get_pdf_doc_info_func_; + + base::ScopedNativeLibrary pdf_lib_; + DISALLOW_COPY_AND_ASSIGN(PdfFunctionsBase); +}; + +#if defined(OS_WIN) +// The 2 below IAT patch functions are almost identical to the code in +// render_process_impl.cc. This is needed to work around specific Windows APIs +// used by the Chrome PDF plugin that will fail in the sandbox. +static base::win::IATPatchFunction g_iat_patch_createdca; +HDC WINAPI UtilityProcess_CreateDCAPatch(LPCSTR driver_name, + LPCSTR device_name, + LPCSTR output, + const DEVMODEA* init_data) { + if (driver_name && (std::string("DISPLAY") == driver_name)) { + // CreateDC fails behind the sandbox, but not CreateCompatibleDC. + return CreateCompatibleDC(NULL); + } + + NOTREACHED(); + return CreateDCA(driver_name, device_name, output, init_data); +} + +static base::win::IATPatchFunction g_iat_patch_get_font_data; +DWORD WINAPI UtilityProcess_GetFontDataPatch( + HDC hdc, DWORD table, DWORD offset, LPVOID buffer, DWORD length) { + int rv = GetFontData(hdc, table, offset, buffer, length); + if (rv == GDI_ERROR && hdc) { + HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); + + LOGFONT logfont; + if (GetObject(font, sizeof(LOGFONT), &logfont)) { + content::UtilityThread::Get()->PreCacheFont(logfont); + rv = GetFontData(hdc, table, offset, buffer, length); + content::UtilityThread::Get()->ReleaseCachedFonts(); + } + } + return rv; +} + +class PdfFunctionsWin : public PdfFunctionsBase { + public: + PdfFunctionsWin() : render_pdf_to_dc_func_(NULL) { + } + + bool PlatformInit( + const base::FilePath& pdf_module_path, + const base::ScopedNativeLibrary& pdf_lib) OVERRIDE { + // Patch the IAT for handling specific APIs known to fail in the sandbox. + if (!g_iat_patch_createdca.is_patched()) { + g_iat_patch_createdca.Patch(pdf_module_path.value().c_str(), + "gdi32.dll", "CreateDCA", + UtilityProcess_CreateDCAPatch); + } + + if (!g_iat_patch_get_font_data.is_patched()) { + g_iat_patch_get_font_data.Patch(pdf_module_path.value().c_str(), + "gdi32.dll", "GetFontData", + UtilityProcess_GetFontDataPatch); + } + render_pdf_to_dc_func_ = + reinterpret_cast<RenderPDFPageToDCProc>( + pdf_lib.GetFunctionPointer("RenderPDFPageToDC")); + LOG_IF(WARNING, !render_pdf_to_dc_func_) << "Missing RenderPDFPageToDC"; + + return render_pdf_to_dc_func_ != NULL; + } + + bool RenderPDFPageToDC(const void* pdf_buffer, + int buffer_size, + int page_number, + HDC dc, + int dpi_x, + int dpi_y, + int bounds_origin_x, + int bounds_origin_y, + int bounds_width, + int bounds_height, + bool fit_to_bounds, + bool stretch_to_bounds, + bool keep_aspect_ratio, + bool center_in_bounds, + bool autorotate) { + if (!render_pdf_to_dc_func_) + return false; + return render_pdf_to_dc_func_(pdf_buffer, buffer_size, page_number, + dc, dpi_x, dpi_y, bounds_origin_x, + bounds_origin_y, bounds_width, bounds_height, + fit_to_bounds, stretch_to_bounds, + keep_aspect_ratio, center_in_bounds, + autorotate); + } + + private: + // Exported by PDF plugin. + typedef bool (*RenderPDFPageToDCProc)( + const void* pdf_buffer, int buffer_size, int page_number, HDC dc, + int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, + int bounds_width, int bounds_height, bool fit_to_bounds, + bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, + bool autorotate); + RenderPDFPageToDCProc render_pdf_to_dc_func_; + + DISALLOW_COPY_AND_ASSIGN(PdfFunctionsWin); +}; + +typedef PdfFunctionsWin PdfFunctions; +#else // OS_WIN +typedef PdfFunctionsBase PdfFunctions; +#endif // OS_WIN + +base::LazyInstance<PdfFunctions> g_pdf_lib = LAZY_INSTANCE_INITIALIZER; + +} // namespace + +PrintingHandler::PrintingHandler() {} + +PrintingHandler::~PrintingHandler() {} + +// static +void PrintingHandler::PreSandboxStartup() { + g_pdf_lib.Get().Init(); +} + +bool PrintingHandler::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PrintingHandler, message) +#if defined(WIN_PDF_METAFILE_FOR_PRINTING) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToMetafiles, + OnRenderPDFPagesToMetafile) +#endif + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RenderPDFPagesToPWGRaster, + OnRenderPDFPagesToPWGRaster) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterCapsAndDefaults, + OnGetPrinterCapsAndDefaults) + IPC_MESSAGE_HANDLER(ChromeUtilityMsg_GetPrinterSemanticCapsAndDefaults, + OnGetPrinterSemanticCapsAndDefaults) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +#if defined(WIN_PDF_METAFILE_FOR_PRINTING) +void PrintingHandler::OnRenderPDFPagesToMetafile( + IPC::PlatformFileForTransit pdf_transit, + const base::FilePath& metafile_path, + const printing::PdfRenderSettings& settings, + const std::vector<printing::PageRange>& page_ranges_const) { + bool succeeded = false; + base::File pdf_file = IPC::PlatformFileForTransitToFile(pdf_transit); + int highest_rendered_page_number = 0; + double scale_factor = 1.0; + std::vector<printing::PageRange> page_ranges = page_ranges_const; + succeeded = RenderPDFToWinMetafile(pdf_file.Pass(), + metafile_path, + settings, + &page_ranges, + &highest_rendered_page_number, + &scale_factor); + if (succeeded) { + // TODO(vitalybuka|scottmg): http://crbug.com/170859. These could + // potentially be sent as each page is converted so that the spool could + // start sooner. + Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafiles_Succeeded( + page_ranges, scale_factor)); + } else { + Send(new ChromeUtilityHostMsg_RenderPDFPagesToMetafile_Failed()); + } + ReleaseProcessIfNeeded(); +} +#endif + +void PrintingHandler::OnRenderPDFPagesToPWGRaster( + IPC::PlatformFileForTransit pdf_transit, + const printing::PdfRenderSettings& settings, + const printing::PwgRasterSettings& bitmap_settings, + IPC::PlatformFileForTransit bitmap_transit) { + base::File pdf = IPC::PlatformFileForTransitToFile(pdf_transit); + base::File bitmap = IPC::PlatformFileForTransitToFile(bitmap_transit); + if (RenderPDFPagesToPWGRaster(pdf.Pass(), settings, bitmap_settings, + bitmap.Pass())) { + Send(new ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Succeeded()); + } else { + Send(new ChromeUtilityHostMsg_RenderPDFPagesToPWGRaster_Failed()); + } + ReleaseProcessIfNeeded(); +} + +#if defined(WIN_PDF_METAFILE_FOR_PRINTING) +bool PrintingHandler::RenderPDFToWinMetafile( + base::File pdf_file, + const base::FilePath& metafile_path, + const printing::PdfRenderSettings& settings, + std::vector<printing::PageRange>* page_ranges, + int* highest_rendered_page_number, + double* scale_factor) { + DCHECK(page_ranges); + *highest_rendered_page_number = -1; + *scale_factor = 1.0; + + if (!g_pdf_lib.Get().IsValid()) + return false; + + // TODO(sanjeevr): Add a method to the PDF DLL that takes in a file handle + // and a page range array. That way we don't need to read the entire PDF into + // memory. + int64 length = pdf_file.GetLength(); + if (length < 0) + return false; + + std::vector<char> buffer; + buffer.resize(length); + if (length != pdf_file.Read(0, &buffer.front(), length)) + return false; + + int total_page_count = 0; + if (!g_pdf_lib.Get().GetPDFDocInfo(&buffer.front(), buffer.size(), + &total_page_count, NULL)) { + return false; + } + + // If no range supplied, do all pages. + if (page_ranges->empty()) { + printing::PageRange page_range_all; + page_range_all.from = 0; + page_range_all.to = total_page_count - 1; + page_ranges->push_back(page_range_all); + } + + bool ret = false; + std::vector<printing::PageRange>::const_iterator iter; + for (iter = page_ranges->begin(); iter != page_ranges->end(); ++iter) { + for (int page_number = iter->from; page_number <= iter->to; ++page_number) { + if (page_number >= total_page_count) + break; + + printing::Emf metafile; + metafile.InitToFile(metafile_path.InsertBeforeExtensionASCII( + base::StringPrintf(".%d", page_number))); + + // We need to scale down DC to fit an entire page into DC available area. + // Current metafile is based on screen DC and have current screen size. + // Writing outside of those boundaries will result in the cut-off output. + // On metafiles (this is the case here), scaling down will still record + // original coordinates and we'll be able to print in full resolution. + // Before playback we'll need to counter the scaling up that will happen + // in the service (print_system_win.cc). + *scale_factor = gfx::CalculatePageScale(metafile.context(), + settings.area().right(), + settings.area().bottom()); + gfx::ScaleDC(metafile.context(), *scale_factor); + + // The underlying metafile is of type Emf and ignores the arguments passed + // to StartPage. + metafile.StartPage(gfx::Size(), gfx::Rect(), 1); + if (g_pdf_lib.Get().RenderPDFPageToDC( + &buffer.front(), buffer.size(), page_number, metafile.context(), + settings.dpi(), settings.dpi(), settings.area().x(), + settings.area().y(), settings.area().width(), + settings.area().height(), true, false, true, true, + settings.autorotate())) { + if (*highest_rendered_page_number < page_number) + *highest_rendered_page_number = page_number; + ret = true; + } + metafile.FinishPage(); + metafile.FinishDocument(); + } + } + return ret; +} +#endif // defined(WIN_PDF_METAFILE_FOR_PRINTING) + +bool PrintingHandler::RenderPDFPagesToPWGRaster( + base::File pdf_file, + const printing::PdfRenderSettings& settings, + const printing::PwgRasterSettings& bitmap_settings, + base::File bitmap_file) { + bool autoupdate = true; + if (!g_pdf_lib.Get().IsValid()) + return false; + + base::File::Info info; + if (!pdf_file.GetInfo(&info) || info.size <= 0) + return false; + + std::string data(info.size, 0); + int data_size = pdf_file.Read(0, &data[0], data.size()); + if (data_size != static_cast<int>(data.size())) + return false; + + int total_page_count = 0; + if (!g_pdf_lib.Get().GetPDFDocInfo(data.data(), data.size(), + &total_page_count, NULL)) { + return false; + } + + cloud_print::PwgEncoder encoder; + std::string pwg_header; + encoder.EncodeDocumentHeader(&pwg_header); + int bytes_written = bitmap_file.WriteAtCurrentPos(pwg_header.data(), + pwg_header.size()); + if (bytes_written != static_cast<int>(pwg_header.size())) + return false; + + cloud_print::BitmapImage image(settings.area().size(), + cloud_print::BitmapImage::BGRA); + for (int i = 0; i < total_page_count; ++i) { + int page_number = i; + + if (bitmap_settings.reverse_page_order) { + page_number = total_page_count - 1 - page_number; + } + + if (!g_pdf_lib.Get().RenderPDFPageToBitmap(data.data(), + data.size(), + page_number, + image.pixel_data(), + image.size().width(), + image.size().height(), + settings.dpi(), + settings.dpi(), + autoupdate)) { + return false; + } + + cloud_print::PwgHeaderInfo header_info; + header_info.dpi = settings.dpi(); + header_info.total_pages = total_page_count; + + // Transform odd pages. + if (page_number % 2) { + switch (bitmap_settings.odd_page_transform) { + case printing::TRANSFORM_NORMAL: + break; + case printing::TRANSFORM_ROTATE_180: + header_info.flipx = true; + header_info.flipy = true; + break; + case printing::TRANSFORM_FLIP_HORIZONTAL: + header_info.flipx = true; + break; + case printing::TRANSFORM_FLIP_VERTICAL: + header_info.flipy = true; + break; + } + } + + if (bitmap_settings.rotate_all_pages) { + header_info.flipx = !header_info.flipx; + header_info.flipy = !header_info.flipy; + } + + std::string pwg_page; + if (!encoder.EncodePage(image, header_info, &pwg_page)) + return false; + bytes_written = bitmap_file.WriteAtCurrentPos(pwg_page.data(), + pwg_page.size()); + if (bytes_written != static_cast<int>(pwg_page.size())) + return false; + } + return true; +} + +void PrintingHandler::OnGetPrinterCapsAndDefaults( + const std::string& printer_name) { + scoped_refptr<printing::PrintBackend> print_backend = + printing::PrintBackend::CreateInstance(NULL); + printing::PrinterCapsAndDefaults printer_info; + + crash_keys::ScopedPrinterInfo crash_key( + print_backend->GetPrinterDriverInfo(printer_name)); + + if (print_backend->GetPrinterCapsAndDefaults(printer_name, &printer_info)) { + Send(new ChromeUtilityHostMsg_GetPrinterCapsAndDefaults_Succeeded( + printer_name, printer_info)); + } else { + Send(new ChromeUtilityHostMsg_GetPrinterCapsAndDefaults_Failed( + printer_name)); + } + ReleaseProcessIfNeeded(); +} + +void PrintingHandler::OnGetPrinterSemanticCapsAndDefaults( + const std::string& printer_name) { + scoped_refptr<printing::PrintBackend> print_backend = + printing::PrintBackend::CreateInstance(NULL); + printing::PrinterSemanticCapsAndDefaults printer_info; + + crash_keys::ScopedPrinterInfo crash_key( + print_backend->GetPrinterDriverInfo(printer_name)); + + if (print_backend->GetPrinterSemanticCapsAndDefaults(printer_name, + &printer_info)) { + Send(new ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Succeeded( + printer_name, printer_info)); + } else { + Send(new ChromeUtilityHostMsg_GetPrinterSemanticCapsAndDefaults_Failed( + printer_name)); + } + ReleaseProcessIfNeeded(); +} diff --git a/chrome/utility/printing_handler.h b/chrome/utility/printing_handler.h new file mode 100644 index 0000000..805c1e3 --- /dev/null +++ b/chrome/utility/printing_handler.h @@ -0,0 +1,76 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_UTILITY_PRINTING_HANDLER_H_ +#define CHROME_UTILITY_PRINTING_HANDLER_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "chrome/utility/utility_message_handler.h" +#include "ipc/ipc_platform_file.h" + +#if !defined(ENABLE_FULL_PRINTING) +#error "Full printing must be enabled" +#endif + +namespace printing { +class PdfRenderSettings; +struct PwgRasterSettings; +struct PageRange; +} + +// Dispatches IPCs for printing. +class PrintingHandler : public UtilityMessageHandler { + public: + PrintingHandler(); + virtual ~PrintingHandler(); + + static void PreSandboxStartup(); + + // IPC::Listener: + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + private: + // IPC message handlers. +#if defined(WIN_PDF_METAFILE_FOR_PRINTING) + void OnRenderPDFPagesToMetafile( + IPC::PlatformFileForTransit pdf_transit, + const base::FilePath& metafile_path, + const printing::PdfRenderSettings& settings, + const std::vector<printing::PageRange>& page_ranges); +#endif + void OnRenderPDFPagesToPWGRaster( + IPC::PlatformFileForTransit pdf_transit, + const printing::PdfRenderSettings& settings, + const printing::PwgRasterSettings& bitmap_settings, + IPC::PlatformFileForTransit bitmap_transit); + +#if defined(WIN_PDF_METAFILE_FOR_PRINTING) + // Helper method for Windows. + // |highest_rendered_page_number| is set to -1 on failure to render any page. + // |page_ranges| is both input and output. If supplied as input, only the + // specified pages will be rendered. If an empty vector is supplied it will + // be filled with a range of all pages that were rendered. + bool RenderPDFToWinMetafile( + base::File pdf_file, + const base::FilePath& metafile_path, + const printing::PdfRenderSettings& settings, + std::vector<printing::PageRange>* page_ranges, + int* highest_rendered_page_number, + double* scale_factor); +#endif + + bool RenderPDFPagesToPWGRaster( + base::File pdf_file, + const printing::PdfRenderSettings& settings, + const printing::PwgRasterSettings& bitmap_settings, + base::File bitmap_file); + + void OnGetPrinterCapsAndDefaults(const std::string& printer_name); + void OnGetPrinterSemanticCapsAndDefaults(const std::string& printer_name); + + DISALLOW_COPY_AND_ASSIGN(PrintingHandler); +}; + +#endif // CHROME_UTILITY_PRINTING_HANDLER_H_ diff --git a/chrome/utility/profile_import_handler.cc b/chrome/utility/profile_import_handler.cc index 457269d..bdc4335 100644 --- a/chrome/utility/profile_import_handler.cc +++ b/chrome/utility/profile_import_handler.cc @@ -14,7 +14,13 @@ #include "chrome/utility/importer/importer_creator.h" #include "content/public/utility/utility_thread.h" -namespace chrome { +namespace { + +bool Send(IPC::Message* message) { + return content::UtilityThread::Get()->Send(message); +} + +} // namespace ProfileImportHandler::ProfileImportHandler() : items_to_import_(0) {} @@ -83,10 +89,3 @@ void ProfileImportHandler::ImporterCleanup() { import_thread_.reset(); content::UtilityThread::Get()->ReleaseProcessIfNeeded(); } - -// static -bool ProfileImportHandler::Send(IPC::Message* message) { - return content::UtilityThread::Get()->Send(message); -} - -} // namespace chrome diff --git a/chrome/utility/profile_import_handler.h b/chrome/utility/profile_import_handler.h index 1fd650e..5a132bf 100644 --- a/chrome/utility/profile_import_handler.h +++ b/chrome/utility/profile_import_handler.h @@ -23,8 +23,6 @@ namespace importer { struct SourceProfile; } -namespace chrome { - // Dispatches IPCs for out of process profile import. class ProfileImportHandler : public UtilityMessageHandler { public: @@ -45,8 +43,6 @@ class ProfileImportHandler : public UtilityMessageHandler { // The following are used with out of process profile import: void ImporterCleanup(); - static bool Send(IPC::Message* message); - // Thread that importer runs on, while ProfileImportThread handles messages // from the browser process. scoped_ptr<base::Thread> import_thread_; @@ -62,6 +58,4 @@ class ProfileImportHandler : public UtilityMessageHandler { scoped_refptr<Importer> importer_; }; -} // namespace chrome - #endif // CHROME_UTILITY_PROFILE_IMPORT_HANDLER_H_ diff --git a/chrome/utility/utility_message_handler.h b/chrome/utility/utility_message_handler.h index 8ade6fe..a862191 100644 --- a/chrome/utility/utility_message_handler.h +++ b/chrome/utility/utility_message_handler.h @@ -9,8 +9,6 @@ namespace IPC { class Message; } -namespace chrome { - class UtilityMessageHandler { public: virtual ~UtilityMessageHandler() {} @@ -20,7 +18,5 @@ class UtilityMessageHandler { virtual bool OnMessageReceived(const IPC::Message& message) = 0; }; -} // namespace chrome - #endif // CHROME_UTILITY_UTILITY_MESSAGE_HANDLER_H_ |