| Index: chrome/browser/printing/printing_message_filter.cc
|
| diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e1132b41b789dcc35efc7bda9794a61be6d3a740
|
| --- /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();
|
| + }
|
| +}
|
|
|