Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / printing / print_preview_message_handler.cc
blobcb755e002ae694079aafd31f926f04141e01296f
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"
7 #include <vector>
9 #include "base/bind.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 "components/printing/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);
32 namespace printing {
34 namespace {
36 void StopWorker(int document_cookie) {
37 if (document_cookie <= 0)
38 return;
39 scoped_refptr<PrintQueriesQueue> queue =
40 g_browser_process->print_job_manager()->queue();
41 scoped_refptr<PrinterQuery> printer_query =
42 queue->PopPrinterQuery(document_cookie);
43 if (printer_query.get()) {
44 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
45 base::Bind(&PrinterQuery::StopWorker,
46 printer_query));
50 base::RefCountedBytes* GetDataFromHandle(base::SharedMemoryHandle handle,
51 uint32_t data_size) {
52 scoped_ptr<base::SharedMemory> shared_buf(
53 new base::SharedMemory(handle, true));
54 if (!shared_buf->Map(data_size)) {
55 NOTREACHED();
56 return nullptr;
59 unsigned char* data_begin = static_cast<unsigned char*>(shared_buf->memory());
60 std::vector<unsigned char> data(data_begin, data_begin + data_size);
61 return base::RefCountedBytes::TakeVector(&data);
64 } // namespace
66 PrintPreviewMessageHandler::PrintPreviewMessageHandler(
67 WebContents* web_contents)
68 : content::WebContentsObserver(web_contents) {
69 DCHECK(web_contents);
72 PrintPreviewMessageHandler::~PrintPreviewMessageHandler() {
75 WebContents* PrintPreviewMessageHandler::GetPrintPreviewDialog() {
76 PrintPreviewDialogController* dialog_controller =
77 PrintPreviewDialogController::GetInstance();
78 if (!dialog_controller)
79 return nullptr;
80 return dialog_controller->GetPrintPreviewForContents(web_contents());
83 PrintPreviewUI* PrintPreviewMessageHandler::GetPrintPreviewUI() {
84 WebContents* dialog = GetPrintPreviewDialog();
85 if (!dialog || !dialog->GetWebUI())
86 return nullptr;
87 return static_cast<PrintPreviewUI*>(dialog->GetWebUI()->GetController());
90 void PrintPreviewMessageHandler::OnRequestPrintPreview(
91 const PrintHostMsg_RequestPrintPreview_Params& params) {
92 if (params.webnode_only)
93 PrintViewManager::FromWebContents(web_contents())->PrintPreviewForWebNode();
94 PrintPreviewDialogController::PrintPreview(web_contents());
95 PrintPreviewUI::SetInitialParams(GetPrintPreviewDialog(), params);
98 void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(
99 const PrintHostMsg_DidGetPreviewPageCount_Params& params) {
100 if (params.page_count <= 0) {
101 NOTREACHED();
102 return;
105 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
106 if (!print_preview_ui)
107 return;
109 if (!params.is_modifiable || params.clear_preview_data)
110 print_preview_ui->ClearAllPreviewData();
112 print_preview_ui->OnDidGetPreviewPageCount(params);
115 void PrintPreviewMessageHandler::OnDidPreviewPage(
116 const PrintHostMsg_DidPreviewPage_Params& params) {
117 int page_number = params.page_number;
118 if (page_number < FIRST_PAGE_INDEX || !params.data_size)
119 return;
121 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
122 if (!print_preview_ui)
123 return;
125 base::RefCountedBytes* data_bytes =
126 GetDataFromHandle(params.metafile_data_handle, params.data_size);
127 DCHECK(data_bytes);
129 print_preview_ui->SetPrintPreviewDataForIndex(page_number, data_bytes);
130 print_preview_ui->OnDidPreviewPage(page_number, params.preview_request_id);
133 void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
134 const PrintHostMsg_DidPreviewDocument_Params& params) {
135 // Always try to stop the worker.
136 StopWorker(params.document_cookie);
138 if (params.expected_pages_count <= 0) {
139 NOTREACHED();
140 return;
143 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
144 if (!print_preview_ui)
145 return;
147 // TODO(joth): This seems like a good match for using RefCountedStaticMemory
148 // to avoid the memory copy, but the SetPrintPreviewData call chain below
149 // needs updating to accept the RefCountedMemory* base class.
150 base::RefCountedBytes* data_bytes =
151 GetDataFromHandle(params.metafile_data_handle, params.data_size);
152 if (!data_bytes || !data_bytes->size())
153 return;
155 print_preview_ui->SetPrintPreviewDataForIndex(COMPLETE_PREVIEW_DOCUMENT_INDEX,
156 data_bytes);
157 print_preview_ui->OnPreviewDataIsAvailable(
158 params.expected_pages_count, params.preview_request_id);
161 void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) {
162 StopWorker(document_cookie);
164 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
165 if (!print_preview_ui)
166 return;
167 print_preview_ui->OnPrintPreviewFailed();
170 void PrintPreviewMessageHandler::OnDidGetDefaultPageLayout(
171 const PageSizeMargins& page_layout_in_points,
172 const gfx::Rect& printable_area_in_points,
173 bool has_custom_page_size_style) {
174 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
175 if (!print_preview_ui)
176 return;
177 print_preview_ui->OnDidGetDefaultPageLayout(page_layout_in_points,
178 printable_area_in_points,
179 has_custom_page_size_style);
182 void PrintPreviewMessageHandler::OnPrintPreviewCancelled(int document_cookie) {
183 // Always need to stop the worker.
184 StopWorker(document_cookie);
187 void PrintPreviewMessageHandler::OnInvalidPrinterSettings(int document_cookie) {
188 StopWorker(document_cookie);
189 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
190 if (!print_preview_ui)
191 return;
192 print_preview_ui->OnInvalidPrinterSettings();
195 void PrintPreviewMessageHandler::OnSetOptionsFromDocument(
196 const PrintHostMsg_SetOptionsFromDocument_Params& params) {
197 PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
198 if (!print_preview_ui)
199 return;
200 print_preview_ui->OnSetOptionsFromDocument(params);
203 bool PrintPreviewMessageHandler::OnMessageReceived(
204 const IPC::Message& message) {
205 bool handled = true;
206 IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message)
207 IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
208 OnRequestPrintPreview)
209 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
210 OnDidGetPreviewPageCount)
211 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage,
212 OnDidPreviewPage)
213 IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
214 OnMetafileReadyForPrinting)
215 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed,
216 OnPrintPreviewFailed)
217 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDefaultPageLayout,
218 OnDidGetDefaultPageLayout)
219 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled,
220 OnPrintPreviewCancelled)
221 IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
222 OnInvalidPrinterSettings)
223 IPC_MESSAGE_HANDLER(PrintHostMsg_SetOptionsFromDocument,
224 OnSetOptionsFromDocument)
225 IPC_MESSAGE_UNHANDLED(handled = false)
226 IPC_END_MESSAGE_MAP()
227 return handled;
230 } // namespace printing