diff options
author | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 17:38:39 +0000 |
---|---|---|
committer | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 17:38:39 +0000 |
commit | a22de29f089b3a8d29b45e1c97cb6b397fef71ca (patch) | |
tree | e6e3a98725bd8c8820fd96b2c15fc98238f314af /chrome | |
parent | 87678d99076f7ba81b868e02165dbe757447b482 (diff) | |
download | chromium_src-a22de29f089b3a8d29b45e1c97cb6b397fef71ca.zip chromium_src-a22de29f089b3a8d29b45e1c97cb6b397fef71ca.tar.gz chromium_src-a22de29f089b3a8d29b45e1c97cb6b397fef71ca.tar.bz2 |
Move print related IPC message handlers from render_message_filter to printing_message_filter.
Created a new BrowserMessageFilter to handle print related IPC messages.
Associated review at: http://codereview.chromium.org/6546051/
BUG=none
TEST=printing works after code changes.
Review URL: http://codereview.chromium.org/6592018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76229 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/printing/printing_message_filter.cc | 265 | ||||
-rw-r--r-- | chrome/browser/printing/printing_message_filter.h | 76 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.cc | 2 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 |
4 files changed, 345 insertions, 0 deletions
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc new file mode 100644 index 0000000..e1132b4 --- /dev/null +++ b/chrome/browser/printing/printing_message_filter.cc @@ -0,0 +1,265 @@ +// Copyright (c) 2011 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/browser/printing/printing_message_filter.h" + +#include "base/process_util.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/printing/printer_query.h" +#include "chrome/browser/printing/print_job_manager.h" +#include "chrome/common/render_messages.h" +#include "chrome/common/render_messages_params.h" + +#if defined(OS_CHROMEOS) +#include <fcntl.h> + +#include "base/file_util.h" +#include "base/lazy_instance.h" +#include "chrome/browser/printing/print_dialog_cloud.h" +#else +#include "base/command_line.h" +#include "chrome/common/chrome_switches.h" +#endif + +namespace { + +#if defined(OS_CHROMEOS) +typedef std::map<int, FilePath> SequenceToPathMap; + +struct PrintingSequencePathMap { + SequenceToPathMap map; + int sequence; +}; + +// No locking, only access on the FILE thread. +static base::LazyInstance<PrintingSequencePathMap> + g_printing_file_descriptor_map(base::LINKER_INITIALIZED); +#endif + +void RenderParamsFromPrintSettings(const printing::PrintSettings& settings, + ViewMsg_Print_Params* params) { + params->page_size = settings.page_setup_device_units().physical_size(); + params->printable_size.SetSize( + settings.page_setup_device_units().content_area().width(), + settings.page_setup_device_units().content_area().height()); + params->margin_top = settings.page_setup_device_units().content_area().x(); + params->margin_left = settings.page_setup_device_units().content_area().y(); + params->dpi = settings.dpi(); + // Currently hardcoded at 1.25. See PrintSettings' constructor. + params->min_shrink = settings.min_shrink; + // Currently hardcoded at 2.0. See PrintSettings' constructor. + params->max_shrink = settings.max_shrink; + // Currently hardcoded at 72dpi. See PrintSettings' constructor. + params->desired_dpi = settings.desired_dpi; + // Always use an invalid cookie. + params->document_cookie = 0; + params->selection_only = settings.selection_only; + params->supports_alpha_blend = settings.supports_alpha_blend(); +} + +} // namespace + +PrintingMessageFilter::PrintingMessageFilter() + : print_job_manager_(g_browser_process->print_job_manager()) { +#if defined(OS_CHROMEOS) + cloud_print_enabled_ = true; +#else + cloud_print_enabled_ = CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableCloudPrint); +#endif +} + +PrintingMessageFilter::~PrintingMessageFilter() { +} + +void PrintingMessageFilter::OverrideThreadForMessage( + const IPC::Message& message, BrowserThread::ID* thread) { +#if defined(OS_CHROMEOS) + if (message.type() == ViewHostMsg_AllocateTempFileForPrinting::ID || + message.type() == ViewHostMsg_TempFileForPrintingWritten::ID) { + *thread = BrowserThread::FILE; + } +#endif +} + +bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message, + bool* message_was_ok) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(PrintingMessageFilter, message, *message_was_ok) +#if defined(OS_WIN) + IPC_MESSAGE_HANDLER(ViewHostMsg_DuplicateSection, OnDuplicateSection) +#endif +#if defined(OS_CHROMEOS) + IPC_MESSAGE_HANDLER(ViewHostMsg_AllocateTempFileForPrinting, + OnAllocateTempFileForPrinting) + IPC_MESSAGE_HANDLER(ViewHostMsg_TempFileForPrintingWritten, + OnTempFileForPrintingWritten) +#endif + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetDefaultPrintSettings, + OnGetDefaultPrintSettings) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ScriptedPrint, OnScriptedPrint) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +#if defined(OS_WIN) +void PrintingMessageFilter::OnDuplicateSection( + base::SharedMemoryHandle renderer_handle, + base::SharedMemoryHandle* browser_handle) { + // Duplicate the handle in this process right now so the memory is kept alive + // (even if it is not mapped) + base::SharedMemory shared_buf(renderer_handle, true, peer_handle()); + shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), browser_handle); +} +#endif + +#if defined(OS_CHROMEOS) +void PrintingMessageFilter::OnAllocateTempFileForPrinting( + base::FileDescriptor* temp_file_fd, int* sequence_number) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + temp_file_fd->fd = *sequence_number = -1; + temp_file_fd->auto_close = false; + + SequenceToPathMap* map = &g_printing_file_descriptor_map.Get().map; + *sequence_number = g_printing_file_descriptor_map.Get().sequence++; + + FilePath path; + if (file_util::CreateTemporaryFile(&path)) { + int fd = open(path.value().c_str(), O_WRONLY); + if (fd >= 0) { + SequenceToPathMap::iterator it = map->find(*sequence_number); + if (it != map->end()) { + NOTREACHED() << "Sequence number already in use. seq=" << + *sequence_number; + } else { + (*map)[*sequence_number] = path; + temp_file_fd->fd = fd; + temp_file_fd->auto_close = true; + } + } + } +} + +void PrintingMessageFilter::OnTempFileForPrintingWritten(int sequence_number) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + SequenceToPathMap* map = &g_printing_file_descriptor_map.Get().map; + SequenceToPathMap::iterator it = map->find(sequence_number); + if (it == map->end()) { + NOTREACHED() << "Got a sequence that we didn't pass to the " + "renderer: " << sequence_number; + return; + } + + if (cloud_print_enabled_) + PrintDialogCloud::CreatePrintDialogForPdf(it->second, string16(), true); + else + NOTIMPLEMENTED(); + + // Erase the entry in the map. + map->erase(it); +} +#endif // defined(OS_CHROMEOS) + +void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) { + scoped_refptr<printing::PrinterQuery> printer_query; + if (!print_job_manager_->printing_enabled()) { + // Reply with NULL query. + OnGetDefaultPrintSettingsReply(printer_query, reply_msg); + return; + } + + print_job_manager_->PopPrinterQuery(0, &printer_query); + if (!printer_query.get()) { + printer_query = new printing::PrinterQuery; + } + + CancelableTask* task = NewRunnableMethod( + this, + &PrintingMessageFilter::OnGetDefaultPrintSettingsReply, + printer_query, + reply_msg); + // Loads default settings. This is asynchronous, only the IPC message sender + // will hang until the settings are retrieved. + printer_query->GetSettings(printing::PrinterQuery::DEFAULTS, + NULL, + 0, + false, + true, + task); +} + +void PrintingMessageFilter::OnGetDefaultPrintSettingsReply( + scoped_refptr<printing::PrinterQuery> printer_query, + IPC::Message* reply_msg) { + ViewMsg_Print_Params params; + if (!printer_query.get() || + printer_query->last_status() != printing::PrintingContext::OK) { + memset(¶ms, 0, sizeof(params)); + } else { + RenderParamsFromPrintSettings(printer_query->settings(), ¶ms); + params.document_cookie = printer_query->cookie(); + } + ViewHostMsg_GetDefaultPrintSettings::WriteReplyParams(reply_msg, params); + Send(reply_msg); + // If printing was enabled. + if (printer_query.get()) { + // If user hasn't cancelled. + if (printer_query->cookie() && printer_query->settings().dpi()) { + print_job_manager_->QueuePrinterQuery(printer_query.get()); + } else { + printer_query->StopWorker(); + } + } +} + +void PrintingMessageFilter::OnScriptedPrint( + const ViewHostMsg_ScriptedPrint_Params& params, + IPC::Message* reply_msg) { + gfx::NativeView host_view = + gfx::NativeViewFromIdInBrowser(params.host_window_id); + + scoped_refptr<printing::PrinterQuery> printer_query; + print_job_manager_->PopPrinterQuery(params.cookie, &printer_query); + if (!printer_query.get()) { + printer_query = new printing::PrinterQuery; + } + + CancelableTask* task = NewRunnableMethod( + this, + &PrintingMessageFilter::OnScriptedPrintReply, + printer_query, + params.routing_id, + reply_msg); + + printer_query->GetSettings(printing::PrinterQuery::ASK_USER, + host_view, + params.expected_pages_count, + params.has_selection, + params.use_overlays, + task); +} + +void PrintingMessageFilter::OnScriptedPrintReply( + scoped_refptr<printing::PrinterQuery> printer_query, + int routing_id, + IPC::Message* reply_msg) { + ViewMsg_PrintPages_Params params; + if (printer_query->last_status() != printing::PrintingContext::OK || + !printer_query->settings().dpi()) { + memset(¶ms, 0, sizeof(params)); + } else { + RenderParamsFromPrintSettings(printer_query->settings(), ¶ms.params); + params.params.document_cookie = printer_query->cookie(); + params.pages = + printing::PageRange::GetPages(printer_query->settings().ranges); + } + ViewHostMsg_ScriptedPrint::WriteReplyParams(reply_msg, params); + Send(reply_msg); + if (params.params.dpi && params.params.document_cookie) { + print_job_manager_->QueuePrinterQuery(printer_query.get()); + } else { + printer_query->StopWorker(); + } +} diff --git a/chrome/browser/printing/printing_message_filter.h b/chrome/browser/printing/printing_message_filter.h new file mode 100644 index 0000000..6a41742 --- /dev/null +++ b/chrome/browser/printing/printing_message_filter.h @@ -0,0 +1,76 @@ +// Copyright (c) 2011 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_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_ +#define CHROME_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_ +#pragma once + +#include "chrome/browser/browser_message_filter.h" + +#if defined(OS_WIN) +#include "base/shared_memory.h" +#endif + +struct ViewHostMsg_ScriptedPrint_Params; + +namespace printing { +class PrinterQuery; +class PrintJobManager; +} + +// This class filters out incoming printing related IPC messages for the +// renderer process on the IPC thread. +class PrintingMessageFilter : public BrowserMessageFilter { + public: + PrintingMessageFilter(); + + // BrowserMessageFilter methods. + virtual void OverrideThreadForMessage(const IPC::Message& message, + BrowserThread::ID* thread); + virtual bool OnMessageReceived(const IPC::Message& message, + bool* message_was_ok); + + private: + virtual ~PrintingMessageFilter(); + +#if defined(OS_WIN) + // Used to pass resulting EMF from renderer to browser in printing. + void OnDuplicateSection(base::SharedMemoryHandle renderer_handle, + base::SharedMemoryHandle* browser_handle); +#endif + +#if defined(OS_CHROMEOS) + // Used to ask the browser allocate a temporary file for the renderer + // to fill in resulting PDF in renderer. + void OnAllocateTempFileForPrinting(base::FileDescriptor* temp_file_fd, + int* sequence_number); + void OnTempFileForPrintingWritten(int sequence_number); +#endif + + // A javascript code requested to print the current page. This is done in two + // steps and this is the first step. Get the print setting right here + // synchronously. It will hang the I/O completely. + void OnGetDefaultPrintSettings(IPC::Message* reply_msg); + void OnGetDefaultPrintSettingsReply( + scoped_refptr<printing::PrinterQuery> printer_query, + IPC::Message* reply_msg); + + // A javascript code requested to print the current page. The renderer host + // have to show to the user the print dialog and returns the selected print + // settings. + void OnScriptedPrint(const ViewHostMsg_ScriptedPrint_Params& params, + IPC::Message* reply_msg); + void OnScriptedPrintReply( + scoped_refptr<printing::PrinterQuery> printer_query, + int routing_id, + IPC::Message* reply_msg); + + printing::PrintJobManager* print_job_manager_; + + bool cloud_print_enabled_; + + DISALLOW_COPY_AND_ASSIGN(PrintingMessageFilter); +}; + +#endif // CHROME_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_ diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index b127cdb..09c5ba9 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -37,6 +37,7 @@ #include "chrome/browser/io_thread.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/platform_util.h" +#include "chrome/browser/printing/printing_message_filter.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/web_cache_manager.h" #include "chrome/browser/safe_browsing/client_side_detection_service.h" @@ -458,6 +459,7 @@ void BrowserRenderProcessHost::CreateMessageFilters() { channel_->AddFilter(new GpuMessageFilter(id())); channel_->AddFilter(new PepperFileMessageFilter(id(), profile())); channel_->AddFilter(new PepperMessageFilter(profile())); + channel_->AddFilter(new PrintingMessageFilter()); channel_->AddFilter(new speech_input::SpeechInputDispatcherHost(id())); channel_->AddFilter( new SearchProviderInstallStateMessageFilter(id(), profile())); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 744e8e9..74ddd52 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1638,6 +1638,8 @@ 'browser/printing/print_view_manager.h', 'browser/printing/printer_query.cc', 'browser/printing/printer_query.h', + 'browser/printing/printing_message_filter.cc', + 'browser/printing/printing_message_filter.h', 'browser/process_info_snapshot.h', 'browser/process_info_snapshot_mac.cc', 'browser/process_singleton.h', |