| 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 NOTREACHED() << "Compositing pdf failed"; |
| 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 (!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 |