summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-28 17:38:39 +0000
committerkmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-28 17:38:39 +0000
commita22de29f089b3a8d29b45e1c97cb6b397fef71ca (patch)
treee6e3a98725bd8c8820fd96b2c15fc98238f314af /chrome
parent87678d99076f7ba81b868e02165dbe757447b482 (diff)
downloadchromium_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.cc265
-rw-r--r--chrome/browser/printing/printing_message_filter.h76
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc2
-rw-r--r--chrome/chrome_browser.gypi2
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(&params, 0, sizeof(params));
+ } else {
+ RenderParamsFromPrintSettings(printer_query->settings(), &params);
+ 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(&params, 0, sizeof(params));
+ } else {
+ RenderParamsFromPrintSettings(printer_query->settings(), &params.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',