OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/printing/print_view_manager_base.h" | 5 #include "chrome/browser/printing/print_view_manager_base.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/memory/shared_memory.h" |
| 15 #include "base/memory/shared_memory_handle.h" |
14 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
15 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
16 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
17 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
18 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
19 #include "base/timer/timer.h" | 21 #include "base/timer/timer.h" |
20 #include "build/build_config.h" | 22 #include "build/build_config.h" |
21 #include "chrome/browser/browser_process.h" | 23 #include "chrome/browser/browser_process.h" |
22 #include "chrome/browser/chrome_notification_types.h" | 24 #include "chrome/browser/chrome_notification_types.h" |
23 #include "chrome/browser/printing/print_job.h" | 25 #include "chrome/browser/printing/print_job.h" |
24 #include "chrome/browser/printing/print_job_manager.h" | 26 #include "chrome/browser/printing/print_job_manager.h" |
25 #include "chrome/browser/printing/printer_query.h" | 27 #include "chrome/browser/printing/printer_query.h" |
26 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
27 #include "chrome/browser/ui/simple_message_box.h" | 29 #include "chrome/browser/ui/simple_message_box.h" |
28 #include "chrome/common/pref_names.h" | 30 #include "chrome/common/pref_names.h" |
29 #include "chrome/grit/generated_resources.h" | 31 #include "chrome/grit/generated_resources.h" |
30 #include "components/prefs/pref_service.h" | 32 #include "components/prefs/pref_service.h" |
| 33 #include "components/printing/browser/print_composite_client.h" |
| 34 #include "components/printing/browser/print_manager_utils.h" |
31 #include "components/printing/common/print_messages.h" | 35 #include "components/printing/common/print_messages.h" |
32 #include "content/public/browser/browser_thread.h" | 36 #include "content/public/browser/browser_thread.h" |
33 #include "content/public/browser/notification_details.h" | 37 #include "content/public/browser/notification_details.h" |
34 #include "content/public/browser/notification_service.h" | 38 #include "content/public/browser/notification_service.h" |
35 #include "content/public/browser/notification_source.h" | 39 #include "content/public/browser/notification_source.h" |
36 #include "content/public/browser/render_frame_host.h" | 40 #include "content/public/browser/render_frame_host.h" |
37 #include "content/public/browser/render_view_host.h" | 41 #include "content/public/browser/render_view_host.h" |
38 #include "content/public/browser/web_contents.h" | 42 #include "content/public/browser/web_contents.h" |
39 #include "printing/features/features.h" | 43 #include "printing/features/features.h" |
40 #include "printing/pdf_metafile_skia.h" | 44 #include "printing/pdf_metafile_skia.h" |
| 45 #include "printing/print_settings.h" |
41 #include "printing/printed_document.h" | 46 #include "printing/printed_document.h" |
42 #include "ui/base/l10n/l10n_util.h" | 47 #include "ui/base/l10n/l10n_util.h" |
43 | 48 |
44 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) | 49 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) |
45 #include "chrome/browser/printing/print_error_dialog.h" | 50 #include "chrome/browser/printing/print_error_dialog.h" |
46 #endif | 51 #endif |
47 | 52 |
48 #if defined(OS_WIN) | 53 #if defined(OS_WIN) |
49 #include "base/command_line.h" | 54 #include "base/command_line.h" |
50 #include "chrome/common/chrome_features.h" | 55 #include "chrome/common/chrome_features.h" |
(...skipping 20 matching lines...) Expand all Loading... |
71 } // namespace | 76 } // namespace |
72 | 77 |
73 PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents) | 78 PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents) |
74 : PrintManager(web_contents), | 79 : PrintManager(web_contents), |
75 printing_rfh_(nullptr), | 80 printing_rfh_(nullptr), |
76 printing_succeeded_(false), | 81 printing_succeeded_(false), |
77 inside_inner_message_loop_(false), | 82 inside_inner_message_loop_(false), |
78 #if !defined(OS_MACOSX) | 83 #if !defined(OS_MACOSX) |
79 expecting_first_page_(true), | 84 expecting_first_page_(true), |
80 #endif | 85 #endif |
81 queue_(g_browser_process->print_job_manager()->queue()) { | 86 queue_(g_browser_process->print_job_manager()->queue()), |
| 87 weak_ptr_factory_(this) { |
82 DCHECK(queue_.get()); | 88 DCHECK(queue_.get()); |
83 Profile* profile = | 89 Profile* profile = |
84 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 90 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
85 printing_enabled_.Init( | 91 printing_enabled_.Init( |
86 prefs::kPrintingEnabled, profile->GetPrefs(), | 92 prefs::kPrintingEnabled, profile->GetPrefs(), |
87 base::Bind(&PrintViewManagerBase::UpdatePrintingEnabled, | 93 base::Bind(&PrintViewManagerBase::UpdatePrintingEnabled, |
88 base::Unretained(this))); | 94 base::Unretained(this))); |
89 } | 95 } |
90 | 96 |
91 PrintViewManagerBase::~PrintViewManagerBase() { | 97 PrintViewManagerBase::~PrintViewManagerBase() { |
(...skipping 28 matching lines...) Expand all Loading... |
120 name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); | 126 name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); |
121 return name; | 127 return name; |
122 } | 128 } |
123 | 129 |
124 void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie, | 130 void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie, |
125 int number_pages) { | 131 int number_pages) { |
126 PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); | 132 PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); |
127 OpportunisticallyCreatePrintJob(cookie); | 133 OpportunisticallyCreatePrintJob(cookie); |
128 } | 134 } |
129 | 135 |
| 136 void PrintViewManagerBase::OnComposePdfDone( |
| 137 const PrintHostMsg_DidPrintPage_Params& params, |
| 138 mojom::PdfCompositor::Status status, |
| 139 mojo::ScopedSharedBufferHandle handle) { |
| 140 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 141 if (status != mojom::PdfCompositor::Status::SUCCESS) { |
| 142 DLOG(ERROR) << "Compositing pdf failed with error " << status; |
| 143 return; |
| 144 } |
| 145 |
| 146 UpdateForPrintedPage( |
| 147 params, true, |
| 148 PrintCompositeClient::GetShmFromMojoHandle(std::move(handle))); |
| 149 } |
| 150 |
130 void PrintViewManagerBase::OnDidPrintPage( | 151 void PrintViewManagerBase::OnDidPrintPage( |
131 const PrintHostMsg_DidPrintPage_Params& params) { | 152 const PrintHostMsg_DidPrintPage_Params& params) { |
| 153 // Ready to composite. Starting a print job. |
132 if (!OpportunisticallyCreatePrintJob(params.document_cookie)) | 154 if (!OpportunisticallyCreatePrintJob(params.document_cookie)) |
133 return; | 155 return; |
134 | 156 |
135 PrintedDocument* document = print_job_->document(); | 157 PrintedDocument* document = print_job_->document(); |
136 if (!document || params.document_cookie != document->cookie()) { | 158 if (!document || params.document_cookie != document->cookie()) { |
137 // Out of sync. It may happen since we are completely asynchronous. Old | 159 // Out of sync. It may happen since we are completely asynchronous. Old |
138 // spurious messages can be received if one of the processes is overloaded. | 160 // spurious messages can be received if one of the processes is overloaded. |
139 return; | 161 return; |
140 } | 162 } |
141 | 163 |
142 #if defined(OS_MACOSX) | 164 #if defined(OS_MACOSX) |
143 const bool metafile_must_be_valid = true; | 165 const bool metafile_must_be_valid = true; |
144 #else | 166 #else |
145 const bool metafile_must_be_valid = expecting_first_page_; | 167 const bool metafile_must_be_valid = expecting_first_page_; |
146 expecting_first_page_ = false; | 168 expecting_first_page_ = false; |
147 #endif | 169 #endif |
148 | 170 |
149 // Only used when |metafile_must_be_valid| is true. | 171 // Only used when |metafile_must_be_valid| is true. |
150 std::unique_ptr<base::SharedMemory> shared_buf; | 172 std::unique_ptr<base::SharedMemory> shared_buf; |
151 if (metafile_must_be_valid) { | 173 if (metafile_must_be_valid) { |
152 if (!base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { | 174 if (!base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { |
153 NOTREACHED() << "invalid memory handle"; | 175 NOTREACHED() << "invalid memory handle"; |
154 web_contents()->Stop(); | 176 web_contents()->Stop(); |
155 return; | 177 return; |
156 } | 178 } |
157 shared_buf = | 179 |
158 base::MakeUnique<base::SharedMemory>(params.metafile_data_handle, true); | 180 if (IsOopifEnabled()) { |
159 if (!shared_buf->Map(params.data_size)) { | 181 auto* client = PrintCompositeClient::FromWebContents(web_contents()); |
160 NOTREACHED() << "couldn't map"; | 182 DCHECK(client); |
161 web_contents()->Stop(); | 183 client->DoComposite( |
162 return; | 184 params.metafile_data_handle, params.data_size, |
| 185 base::BindOnce(&PrintViewManagerBase::OnComposePdfDone, |
| 186 weak_ptr_factory_.GetWeakPtr(), params)); |
| 187 } else { |
| 188 shared_buf = base::MakeUnique<base::SharedMemory>( |
| 189 params.metafile_data_handle, true); |
| 190 if (!shared_buf->Map(params.data_size)) { |
| 191 NOTREACHED() << "couldn't map"; |
| 192 web_contents()->Stop(); |
| 193 return; |
| 194 } |
163 } | 195 } |
164 } else { | 196 } else { |
165 if (base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { | 197 if (base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { |
166 NOTREACHED() << "unexpected valid memory handle"; | 198 NOTREACHED() << "unexpected valid memory handle"; |
167 web_contents()->Stop(); | 199 web_contents()->Stop(); |
168 base::SharedMemory::CloseHandle(params.metafile_data_handle); | 200 base::SharedMemory::CloseHandle(params.metafile_data_handle); |
169 return; | 201 return; |
170 } | 202 } |
171 } | 203 } |
172 | 204 |
173 std::unique_ptr<PdfMetafileSkia> metafile( | 205 if (!metafile_must_be_valid || !IsOopifEnabled()) |
174 new PdfMetafileSkia(SkiaDocumentType::PDF)); | 206 UpdateForPrintedPage(params, metafile_must_be_valid, std::move(shared_buf)); |
175 if (metafile_must_be_valid) { | 207 } |
176 if (!metafile->InitFromData(shared_buf->memory(), params.data_size)) { | 208 |
177 NOTREACHED() << "Invalid metafile header"; | 209 void PrintViewManagerBase::UpdateForPrintedPage( |
178 web_contents()->Stop(); | 210 const PrintHostMsg_DidPrintPage_Params& params, |
179 return; | 211 bool has_valid_page_data, |
180 } | 212 std::unique_ptr<base::SharedMemory> shared_buf) { |
181 } | 213 PrintedDocument* document = print_job_->document(); |
| 214 if (!document) |
| 215 return; |
182 | 216 |
183 #if defined(OS_WIN) | 217 #if defined(OS_WIN) |
184 print_job_->AppendPrintedPage(params.page_number); | 218 print_job_->AppendPrintedPage(params.page_number); |
185 if (metafile_must_be_valid) { | 219 if (has_valid_page_data) { |
186 scoped_refptr<base::RefCountedBytes> bytes = new base::RefCountedBytes( | 220 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes( |
187 reinterpret_cast<const unsigned char*>(shared_buf->memory()), | 221 reinterpret_cast<const unsigned char*>(shared_buf->memory()), |
188 params.data_size); | 222 shared_buf->mapped_size())); |
| 223 |
189 document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf")); | 224 document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf")); |
190 | 225 |
191 const auto& settings = document->settings(); | 226 const auto& settings = document->settings(); |
192 if (settings.printer_is_textonly()) { | 227 if (settings.printer_is_textonly()) { |
193 print_job_->StartPdfToTextConversion(bytes, params.page_size); | 228 print_job_->StartPdfToTextConversion(bytes, params.page_size); |
194 } else if ((settings.printer_is_ps2() || settings.printer_is_ps3()) && | 229 } else if ((settings.printer_is_ps2() || settings.printer_is_ps3()) && |
195 !base::FeatureList::IsEnabled( | 230 !base::FeatureList::IsEnabled( |
196 features::kDisablePostScriptPrinting)) { | 231 features::kDisablePostScriptPrinting)) { |
197 print_job_->StartPdfToPostScriptConversion(bytes, params.content_area, | 232 print_job_->StartPdfToPostScriptConversion(bytes, params.content_area, |
198 params.physical_offsets, | 233 params.physical_offsets, |
199 settings.printer_is_ps2()); | 234 settings.printer_is_ps2()); |
200 } else { | 235 } else { |
201 // TODO(thestig): Figure out why rendering text with GDI results in random | 236 // TODO(thestig): Figure out why rendering text with GDI results in random |
202 // missing characters for some users. https://crbug.com/658606 | 237 // missing characters for some users. https://crbug.com/658606 |
203 // Update : The missing letters seem to have been caused by the same | 238 // Update : The missing letters seem to have been caused by the same |
204 // problem as https://crbug.com/659604 which was resolved. GDI printing | 239 // problem as https://crbug.com/659604 which was resolved. GDI printing |
205 // seems to work with the fix for this bug applied. | 240 // seems to work with the fix for this bug applied. |
206 bool print_text_with_gdi = settings.print_text_with_gdi() && | 241 bool print_text_with_gdi = |
207 !settings.printer_is_xps() && | 242 settings.print_text_with_gdi() && !settings.printer_is_xps() && |
208 base::FeatureList::IsEnabled( | 243 base::FeatureList::IsEnabled(features::kGdiTextPrinting); |
209 features::kGdiTextPrinting); | |
210 print_job_->StartPdfToEmfConversion( | 244 print_job_->StartPdfToEmfConversion( |
211 bytes, params.page_size, params.content_area, print_text_with_gdi); | 245 bytes, params.page_size, params.content_area, print_text_with_gdi); |
212 } | 246 } |
213 } | 247 } |
214 #else | 248 #else |
| 249 std::unique_ptr<PdfMetafileSkia> metafile = |
| 250 base::MakeUnique<PdfMetafileSkia>(SkiaDocumentType::PDF); |
| 251 if (has_valid_page_data) { |
| 252 if (!metafile->InitFromData(shared_buf->memory(), |
| 253 shared_buf->mapped_size())) { |
| 254 NOTREACHED() << "Invalid metafile header"; |
| 255 web_contents()->Stop(); |
| 256 return; |
| 257 } |
| 258 } |
| 259 |
215 // Update the rendered document. It will send notifications to the listener. | 260 // Update the rendered document. It will send notifications to the listener. |
216 document->SetPage(params.page_number, | 261 document->SetPage(params.page_number, std::move(metafile), params.page_size, |
217 std::move(metafile), | |
218 #if defined(OS_WIN) | |
219 0.0f /* dummy shrink_factor */, | |
220 #endif | |
221 params.page_size, | |
222 params.content_area); | 262 params.content_area); |
223 | 263 |
224 ShouldQuitFromInnerMessageLoop(); | 264 ShouldQuitFromInnerMessageLoop(); |
225 #endif | 265 #endif |
226 } | 266 } |
227 | 267 |
228 void PrintViewManagerBase::OnPrintingFailed(int cookie) { | 268 void PrintViewManagerBase::OnPrintingFailed(int cookie) { |
229 PrintManager::OnPrintingFailed(cookie); | 269 PrintManager::OnPrintingFailed(cookie); |
230 | 270 |
231 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) | 271 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 BrowserThread::IO, FROM_HERE, | 635 BrowserThread::IO, FROM_HERE, |
596 base::BindOnce(&PrinterQuery::StopWorker, printer_query)); | 636 base::BindOnce(&PrinterQuery::StopWorker, printer_query)); |
597 } | 637 } |
598 | 638 |
599 void PrintViewManagerBase::SendPrintingEnabled(bool enabled, | 639 void PrintViewManagerBase::SendPrintingEnabled(bool enabled, |
600 content::RenderFrameHost* rfh) { | 640 content::RenderFrameHost* rfh) { |
601 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled)); | 641 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled)); |
602 } | 642 } |
603 | 643 |
604 } // namespace printing | 644 } // namespace printing |
OLD | NEW |