• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/printing/print_preview_message_handler.h"
6 
7 #include <vector>
8 
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 "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"
26 
27 using content::BrowserThread;
28 using content::WebContents;
29 
30 DEFINE_WEB_CONTENTS_USER_DATA_KEY(printing::PrintPreviewMessageHandler);
31 
32 namespace {
33 
StopWorker(int document_cookie)34 void StopWorker(int document_cookie) {
35   if (document_cookie <= 0)
36     return;
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);
41   if (printer_query) {
42     BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
43                             base::Bind(&printing::PrinterQuery::StopWorker,
44                                        printer_query));
45   }
46 }
47 
GetDataFromHandle(base::SharedMemoryHandle handle,uint32 data_size)48 base::RefCountedBytes* GetDataFromHandle(base::SharedMemoryHandle handle,
49                                          uint32 data_size) {
50   scoped_ptr<base::SharedMemory> shared_buf(
51       new base::SharedMemory(handle, true));
52   if (!shared_buf->Map(data_size)) {
53     NOTREACHED();
54     return NULL;
55   }
56 
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);
60 }
61 
62 }  // namespace
63 
64 namespace printing {
65 
PrintPreviewMessageHandler(WebContents * web_contents)66 PrintPreviewMessageHandler::PrintPreviewMessageHandler(
67     WebContents* web_contents)
68     : content::WebContentsObserver(web_contents) {
69   DCHECK(web_contents);
70 }
71 
~PrintPreviewMessageHandler()72 PrintPreviewMessageHandler::~PrintPreviewMessageHandler() {
73 }
74 
GetPrintPreviewDialog()75 WebContents* PrintPreviewMessageHandler::GetPrintPreviewDialog() {
76   PrintPreviewDialogController* dialog_controller =
77       PrintPreviewDialogController::GetInstance();
78   if (!dialog_controller)
79     return NULL;
80   return dialog_controller->GetPrintPreviewForContents(web_contents());
81 }
82 
GetPrintPreviewUI()83 PrintPreviewUI* PrintPreviewMessageHandler::GetPrintPreviewUI() {
84   WebContents* dialog = GetPrintPreviewDialog();
85   if (!dialog || !dialog->GetWebUI())
86     return NULL;
87   return static_cast<PrintPreviewUI*>(dialog->GetWebUI()->GetController());
88 }
89 
OnRequestPrintPreview(const PrintHostMsg_RequestPrintPreview_Params & params)90 void PrintPreviewMessageHandler::OnRequestPrintPreview(
91     const PrintHostMsg_RequestPrintPreview_Params& params) {
92   if (params.webnode_only) {
93     printing::PrintViewManager::FromWebContents(web_contents())->
94         PrintPreviewForWebNode();
95   }
96   PrintPreviewDialogController::PrintPreview(web_contents());
97   PrintPreviewUI::SetInitialParams(GetPrintPreviewDialog(), params);
98 }
99 
OnDidGetPreviewPageCount(const PrintHostMsg_DidGetPreviewPageCount_Params & params)100 void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(
101     const PrintHostMsg_DidGetPreviewPageCount_Params& params) {
102   if (params.page_count <= 0) {
103     NOTREACHED();
104     return;
105   }
106 
107   PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
108   if (!print_preview_ui)
109     return;
110 
111   if (!params.is_modifiable || params.clear_preview_data)
112     print_preview_ui->ClearAllPreviewData();
113 
114   print_preview_ui->OnDidGetPreviewPageCount(params);
115 }
116 
OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params & 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)
121     return;
122 
123   PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
124   if (!print_preview_ui)
125     return;
126 
127   base::RefCountedBytes* data_bytes =
128       GetDataFromHandle(params.metafile_data_handle, params.data_size);
129   DCHECK(data_bytes);
130 
131   print_preview_ui->SetPrintPreviewDataForIndex(page_number, data_bytes);
132   print_preview_ui->OnDidPreviewPage(page_number, params.preview_request_id);
133 }
134 
OnMetafileReadyForPrinting(const PrintHostMsg_DidPreviewDocument_Params & params)135 void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
136     const PrintHostMsg_DidPreviewDocument_Params& params) {
137   // Always try to stop the worker.
138   StopWorker(params.document_cookie);
139 
140   if (params.expected_pages_count <= 0) {
141     NOTREACHED();
142     return;
143   }
144 
145   PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
146   if (!print_preview_ui)
147     return;
148 
149   // TODO(joth): This seems like a good match for using RefCountedStaticMemory
150   // to avoid the memory copy, but the SetPrintPreviewData call chain below
151   // needs updating to accept the RefCountedMemory* base class.
152   base::RefCountedBytes* data_bytes =
153       GetDataFromHandle(params.metafile_data_handle, params.data_size);
154   if (!data_bytes || !data_bytes->size())
155     return;
156 
157   print_preview_ui->SetPrintPreviewDataForIndex(COMPLETE_PREVIEW_DOCUMENT_INDEX,
158                                                 data_bytes);
159   print_preview_ui->OnPreviewDataIsAvailable(
160       params.expected_pages_count, params.preview_request_id);
161 }
162 
OnPrintPreviewFailed(int document_cookie)163 void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) {
164   StopWorker(document_cookie);
165 
166   PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
167   if (!print_preview_ui)
168     return;
169   print_preview_ui->OnPrintPreviewFailed();
170 }
171 
OnDidGetDefaultPageLayout(const PageSizeMargins & page_layout_in_points,const gfx::Rect & printable_area_in_points,bool has_custom_page_size_style)172 void PrintPreviewMessageHandler::OnDidGetDefaultPageLayout(
173     const PageSizeMargins& page_layout_in_points,
174     const gfx::Rect& printable_area_in_points,
175     bool has_custom_page_size_style) {
176   PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
177   if (!print_preview_ui)
178     return;
179   print_preview_ui->OnDidGetDefaultPageLayout(page_layout_in_points,
180                                               printable_area_in_points,
181                                               has_custom_page_size_style);
182 }
183 
OnPrintPreviewCancelled(int document_cookie)184 void PrintPreviewMessageHandler::OnPrintPreviewCancelled(int document_cookie) {
185   // Always need to stop the worker.
186   StopWorker(document_cookie);
187 }
188 
OnInvalidPrinterSettings(int document_cookie)189 void PrintPreviewMessageHandler::OnInvalidPrinterSettings(int document_cookie) {
190   StopWorker(document_cookie);
191   PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
192   if (!print_preview_ui)
193     return;
194   print_preview_ui->OnInvalidPrinterSettings();
195 }
196 
OnPrintPreviewScalingDisabled()197 void PrintPreviewMessageHandler::OnPrintPreviewScalingDisabled() {
198   PrintPreviewUI* print_preview_ui = GetPrintPreviewUI();
199   if (!print_preview_ui)
200     return;
201   print_preview_ui->OnPrintPreviewScalingDisabled();
202 }
203 
OnMessageReceived(const IPC::Message & message)204 bool PrintPreviewMessageHandler::OnMessageReceived(
205     const IPC::Message& message) {
206   bool handled = true;
207   IPC_BEGIN_MESSAGE_MAP(PrintPreviewMessageHandler, message)
208     IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
209                         OnRequestPrintPreview)
210     IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount,
211                         OnDidGetPreviewPageCount)
212     IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage,
213                         OnDidPreviewPage)
214     IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting,
215                         OnMetafileReadyForPrinting)
216     IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed,
217                         OnPrintPreviewFailed)
218     IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDefaultPageLayout,
219                         OnDidGetDefaultPageLayout)
220     IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled,
221                         OnPrintPreviewCancelled)
222     IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewInvalidPrinterSettings,
223                         OnInvalidPrinterSettings)
224     IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewScalingDisabled,
225                         OnPrintPreviewScalingDisabled)
226     IPC_MESSAGE_UNHANDLED(handled = false)
227   IPC_END_MESSAGE_MAP()
228   return handled;
229 }
230 
231 }  // namespace printing
232