1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/printing/print_preview_message_handler.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/memory/shared_memory.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/printing/print_job_manager.h"
15 #include "chrome/browser/printing/print_preview_dialog_controller.h"
16 #include "chrome/browser/printing/print_view_manager.h"
17 #include "chrome/browser/printing/printer_query.h"
18 #include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
19 #include "chrome/common/print_messages.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/render_view_host.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_ui.h"
24 #include "printing/page_size_margins.h"
25 #include "printing/print_job_constants.h"
27 using content::BrowserThread;
28 using content::WebContents;
30 DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintPreviewMessageHandler);
34 void StopWorker(int document_cookie) {
35 if (document_cookie <= 0)
37 scoped_refptr<printing::PrintQueriesQueue> queue =
38 g_browser_process->print_job_manager()->queue();
39 scoped_refptr<printing::PrinterQuery> printer_query =
40 queue->PopPrinterQuery(document_cookie);
42 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
43 base::Bind(&printing::PrinterQuery::StopWorker,
48 base::RefCountedBytes* GetDataFromHandle(base::SharedMemoryHandle handle,
50 scoped_ptr<base::SharedMemory> shared_buf(
51 new base::SharedMemory(handle, true));
52 if (!shared_buf->Map(data_size)) {
57 unsigned char* data_begin = static_cast<unsigned char*>(shared_buf->memory());
58 std::vector<unsigned char> data(data_begin, data_begin + data_size);
59 return base::RefCountedBytes::TakeVector(&data);
66 PrintPreviewMessageHandler::PrintPreviewMessageHandler(
67 WebContents* web_contents)
68 : content::WebContentsObserver(web_contents) {
72 PrintPreviewMessageHandler::~PrintPreviewMessageHandler() {
75 WebContents* PrintPreviewMessageHandler::GetPrintPreviewDialog() {
76 PrintPreviewDialogController* dialog_controller =
77 PrintPreviewDialogController::GetInstance();
78 if (!dialog_controller)
80 return dialog_controller->GetPrintPreviewForContents(web_contents());
83 PrintPreviewUI* PrintPreviewMessageHandler::GetPrintPreviewUI() {
84 WebContents* dialog = GetPrintPreviewDialog();
85 if (!dialog || !dialog->GetWebUI())
87 return static_cast<PrintPreviewUI*>(dialog->GetWebUI()->GetController());
90 void PrintPreviewMessageHandler::OnRequestPrintPreview(
91 const PrintHostMsg_RequestPrintPreview_Params& params) {
92 if (params.webnode_only) {
93 printing::PrintViewManager::FromWebContents(web_contents())->
94 PrintPreviewForWebNode();
96 PrintPreviewDialogController::PrintPreview(web_contents());
97 PrintPreviewUI::SetInitialParams(GetPrintPreviewDialog(), params);
100 void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(
101 const PrintHostMsg_DidGetPreviewPageCount_Params& params) {
102 if (params.page_count <= 0) {
107 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
108 if (!print_preview_ui)
111 if (!params.is_modifiable || params.clear_preview_data)
112 print_preview_ui->ClearAllPreviewData();
114 print_preview_ui->OnDidGetPreviewPageCount(params);
117 void PrintPreviewMessageHandler::OnDidPreviewPage(
118 const PrintHostMsg_DidPreviewPage_Params& params) {
119 int page_number = params.page_number;
120 if (page_number < FIRST_PAGE_INDEX || !params.data_size)
123 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
124 if (!print_preview_ui)
127 base::RefCountedBytes* data_bytes =
128 GetDataFromHandle(params.metafile_data_handle, params.data_size);
131 print_preview_ui->SetPrintPreviewDataForIndex(page_number, data_bytes);
132 print_preview_ui->OnDidPreviewPage(page_number, params.preview_request_id);
135 void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
136 const PrintHostMsg_DidPreviewDocument_Params& params) {
137 // Always try to stop the worker.
138 StopWorker(params.document_cookie);
140 if (params.expected_pages_count <= 0) {
145 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
146 if (!print_preview_ui)
149 if (params.reuse_existing_data) {
150 // Need to match normal rendering where we are expected to send this.
151 PrintHostMsg_DidGetPreviewPageCount_Params temp_params;
152 temp_params.page_count = params.expected_pages_count;
153 temp_params.document_cookie = params.document_cookie;
154 temp_params.is_modifiable = params.modifiable;
155 temp_params.preview_request_id = params.preview_request_id;
156 print_preview_ui->OnDidGetPreviewPageCount(temp_params);
157 print_preview_ui->OnReusePreviewData(params.preview_request_id);
161 // TODO(joth): This seems like a good match for using RefCountedStaticMemory
162 // to avoid the memory copy, but the SetPrintPreviewData call chain below
163 // needs updating to accept the RefCountedMemory* base class.
164 base::RefCountedBytes* data_bytes =
165 GetDataFromHandle(params.metafile_data_handle, params.data_size);
166 if (!data_bytes || !data_bytes->size())
169 print_preview_ui->SetPrintPreviewDataForIndex(COMPLETE_PREVIEW_DOCUMENT_INDEX,
171 print_preview_ui->OnPreviewDataIsAvailable(
172 params.expected_pages_count, params.preview_request_id);
175 void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) {
176 StopWorker(document_cookie);
178 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
179 if (!print_preview_ui)
181 print_preview_ui->OnPrintPreviewFailed();
184 void PrintPreviewMessageHandler::OnDidGetDefaultPageLayout(
185 const PageSizeMargins& page_layout_in_points,
186 const gfx::Rect& printable_area_in_points,
187 bool has_custom_page_size_style) {
188 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
189 if (!print_preview_ui)
191 print_preview_ui->OnDidGetDefaultPageLayout(page_layout_in_points,
192 printable_area_in_points,
193 has_custom_page_size_style);
196 void PrintPreviewMessageHandler::OnPrintPreviewCancelled(int document_cookie) {
197 // Always need to stop the worker.
198 StopWorker(document_cookie);
201 void PrintPreviewMessageHandler::OnInvalidPrinterSettings(int document_cookie) {
202 StopWorker(document_cookie);
203 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
204 if (!print_preview_ui)
206 print_preview_ui->OnInvalidPrinterSettings();
209 void PrintPreviewMessageHandler::OnPrintPreviewScalingDisabled() {
210 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
211 if (!print_preview_ui)
213 print_preview_ui->OnPrintPreviewScalingDisabled();
216 bool PrintPreviewMessageHandler::OnMessageReceived(
217 const IPC::Message& message) {
219 IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message)
220 IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
221 OnRequestPrintPreview)
222 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
223 OnDidGetPreviewPageCount)
224 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage,
226 IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
227 OnMetafileReadyForPrinting)
228 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed,
229 OnPrintPreviewFailed)
230 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDefaultPageLayout,
231 OnDidGetDefaultPageLayout)
232 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled,
233 OnPrintPreviewCancelled)
234 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
235 OnInvalidPrinterSettings)
236 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewScalingDisabled,
237 OnPrintPreviewScalingDisabled)
238 IPC_MESSAGE_UNHANDLED(handled = false)
239 IPC_END_MESSAGE_MAP()
243 } // namespace printing