| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); | 125 name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); |
| 121 return name; | 126 return name; |
| 122 } | 127 } |
| 123 | 128 |
| 124 void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie, | 129 void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie, |
| 125 int number_pages) { | 130 int number_pages) { |
| 126 PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); | 131 PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); |
| 127 OpportunisticallyCreatePrintJob(cookie); | 132 OpportunisticallyCreatePrintJob(cookie); |
| 128 } | 133 } |
| 129 | 134 |
| 135 void PrintViewManagerBase::OnComposePdfDone( |
| 136 const PrintHostMsg_DidPrintPage_Params& params, |
| 137 mojom::PdfCompositor::Status status, |
| 138 mojo::ScopedSharedBufferHandle handle) { |
| 139 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 140 if (status != mojom::PdfCompositor::Status::SUCCESS) { |
| 141 NOTREACHED() << "Compositing pdf failed"; |
| 142 return; |
| 143 } |
| 144 |
| 145 UpdateForPrintedPage( |
| 146 params, true, |
| 147 PrintCompositeClient::GetShmFromMojoHandle(std::move(handle))); |
| 148 } |
| 149 |
| 130 void PrintViewManagerBase::OnDidPrintPage( | 150 void PrintViewManagerBase::OnDidPrintPage( |
| 131 const PrintHostMsg_DidPrintPage_Params& params) { | 151 const PrintHostMsg_DidPrintPage_Params& params) { |
| 152 // Ready to composite. Starting a print job. |
| 132 if (!OpportunisticallyCreatePrintJob(params.document_cookie)) | 153 if (!OpportunisticallyCreatePrintJob(params.document_cookie)) |
| 133 return; | 154 return; |
| 134 | 155 |
| 135 PrintedDocument* document = print_job_->document(); | 156 PrintedDocument* document = print_job_->document(); |
| 136 if (!document || params.document_cookie != document->cookie()) { | 157 if (!document || params.document_cookie != document->cookie()) { |
| 137 // Out of sync. It may happen since we are completely asynchronous. Old | 158 // 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. | 159 // spurious messages can be received if one of the processes is overloaded. |
| 139 return; | 160 return; |
| 140 } | 161 } |
| 141 | 162 |
| 142 #if defined(OS_MACOSX) | 163 #if defined(OS_MACOSX) |
| 143 const bool metafile_must_be_valid = true; | 164 const bool metafile_must_be_valid = true; |
| 144 #else | 165 #else |
| 145 const bool metafile_must_be_valid = expecting_first_page_; | 166 const bool metafile_must_be_valid = expecting_first_page_; |
| 146 expecting_first_page_ = false; | 167 expecting_first_page_ = false; |
| 147 #endif | 168 #endif |
| 148 | 169 |
| 149 // Only used when |metafile_must_be_valid| is true. | 170 // Only used when |metafile_must_be_valid| is true. |
| 150 std::unique_ptr<base::SharedMemory> shared_buf; | 171 std::unique_ptr<base::SharedMemory> shared_buf; |
| 151 if (metafile_must_be_valid) { | 172 if (metafile_must_be_valid) { |
| 152 if (!base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { | 173 if (!base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { |
| 153 NOTREACHED() << "invalid memory handle"; | 174 NOTREACHED() << "invalid memory handle"; |
| 154 web_contents()->Stop(); | 175 web_contents()->Stop(); |
| 155 return; | 176 return; |
| 156 } | 177 } |
| 157 shared_buf = | 178 |
| 158 base::MakeUnique<base::SharedMemory>(params.metafile_data_handle, true); | 179 if (IsOopifEnabled()) { |
| 159 if (!shared_buf->Map(params.data_size)) { | 180 if (auto* client = |
| 160 NOTREACHED() << "couldn't map"; | 181 PrintCompositeClient::FromWebContents(web_contents())) { |
| 161 web_contents()->Stop(); | 182 client->DoComposite( |
| 162 return; | 183 params.metafile_data_handle, params.data_size, |
| 184 base::BindOnce(&PrintViewManagerBase::OnComposePdfDone, |
| 185 base::Unretained(this), params), |
| 186 base::ThreadTaskRunnerHandle::Get()); |
| 187 } |
| 188 } else { |
| 189 shared_buf = base::MakeUnique<base::SharedMemory>( |
| 190 params.metafile_data_handle, true); |
| 191 if (!shared_buf->Map(params.data_size)) { |
| 192 NOTREACHED() << "couldn't map"; |
| 193 web_contents()->Stop(); |
| 194 return; |
| 195 } |
| 163 } | 196 } |
| 164 } else { | 197 } else { |
| 165 if (base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { | 198 if (base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { |
| 166 NOTREACHED() << "unexpected valid memory handle"; | 199 NOTREACHED() << "unexpected valid memory handle"; |
| 167 web_contents()->Stop(); | 200 web_contents()->Stop(); |
| 168 base::SharedMemory::CloseHandle(params.metafile_data_handle); | 201 base::SharedMemory::CloseHandle(params.metafile_data_handle); |
| 169 return; | 202 return; |
| 170 } | 203 } |
| 171 } | 204 } |
| 172 | 205 |
| 173 std::unique_ptr<PdfMetafileSkia> metafile( | 206 if (!IsOopifEnabled()) |
| 174 new PdfMetafileSkia(SkiaDocumentType::PDF)); | 207 UpdateForPrintedPage(params, metafile_must_be_valid, std::move(shared_buf)); |
| 175 if (metafile_must_be_valid) { | 208 } |
| 176 if (!metafile->InitFromData(shared_buf->memory(), params.data_size)) { | 209 |
| 177 NOTREACHED() << "Invalid metafile header"; | 210 void PrintViewManagerBase::UpdateForPrintedPage( |
| 178 web_contents()->Stop(); | 211 const PrintHostMsg_DidPrintPage_Params& params, |
| 179 return; | 212 bool has_valid_page_data, |
| 180 } | 213 std::unique_ptr<base::SharedMemory> shared_buf) { |
| 181 } | 214 PrintedDocument* document = print_job_->document(); |
| 215 if (!document) |
| 216 return; |
| 182 | 217 |
| 183 #if defined(OS_WIN) | 218 #if defined(OS_WIN) |
| 184 print_job_->AppendPrintedPage(params.page_number); | 219 print_job_->AppendPrintedPage(params.page_number); |
| 185 if (metafile_must_be_valid) { | 220 if (has_valid_page_data) { |
| 186 scoped_refptr<base::RefCountedBytes> bytes = new base::RefCountedBytes( | 221 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes( |
| 187 reinterpret_cast<const unsigned char*>(shared_buf->memory()), | 222 reinterpret_cast<const unsigned char*>(shared_buf->memory()), |
| 188 params.data_size); | 223 shared_buf->mapped_size())); |
| 224 |
| 189 document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf")); | 225 document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf")); |
| 190 | 226 |
| 191 const auto& settings = document->settings(); | 227 const auto& settings = document->settings(); |
| 192 if (settings.printer_is_textonly()) { | 228 if (settings.printer_is_textonly()) { |
| 193 print_job_->StartPdfToTextConversion(bytes, params.page_size); | 229 print_job_->StartPdfToTextConversion(bytes, params.page_size); |
| 194 } else if ((settings.printer_is_ps2() || settings.printer_is_ps3()) && | 230 } else if ((settings.printer_is_ps2() || settings.printer_is_ps3()) && |
| 195 !base::FeatureList::IsEnabled( | 231 !base::FeatureList::IsEnabled( |
| 196 features::kDisablePostScriptPrinting)) { | 232 features::kDisablePostScriptPrinting)) { |
| 197 print_job_->StartPdfToPostScriptConversion(bytes, params.content_area, | 233 print_job_->StartPdfToPostScriptConversion(bytes, params.content_area, |
| 198 params.physical_offsets, | 234 params.physical_offsets, |
| 199 settings.printer_is_ps2()); | 235 settings.printer_is_ps2()); |
| 200 } else { | 236 } else { |
| 201 // TODO(thestig): Figure out why rendering text with GDI results in random | 237 // TODO(thestig): Figure out why rendering text with GDI results in random |
| 202 // missing characters for some users. https://crbug.com/658606 | 238 // missing characters for some users. https://crbug.com/658606 |
| 203 // Update : The missing letters seem to have been caused by the same | 239 // Update : The missing letters seem to have been caused by the same |
| 204 // problem as https://crbug.com/659604 which was resolved. GDI printing | 240 // problem as https://crbug.com/659604 which was resolved. GDI printing |
| 205 // seems to work with the fix for this bug applied. | 241 // seems to work with the fix for this bug applied. |
| 206 bool print_text_with_gdi = settings.print_text_with_gdi() && | 242 bool print_text_with_gdi = |
| 207 !settings.printer_is_xps() && | 243 settings.print_text_with_gdi() && !settings.printer_is_xps() && |
| 208 base::FeatureList::IsEnabled( | 244 base::FeatureList::IsEnabled(features::kGdiTextPrinting); |
| 209 features::kGdiTextPrinting); | |
| 210 print_job_->StartPdfToEmfConversion( | 245 print_job_->StartPdfToEmfConversion( |
| 211 bytes, params.page_size, params.content_area, print_text_with_gdi); | 246 bytes, params.page_size, params.content_area, print_text_with_gdi); |
| 212 } | 247 } |
| 213 } | 248 } |
| 214 #else | 249 #else |
| 250 std::unique_ptr<PdfMetafileSkia> metafile = |
| 251 base::MakeUnique<PdfMetafileSkia>(SkiaDocumentType::PDF); |
| 252 if (has_valid_page_data) { |
| 253 if (!metafile->InitFromData(shared_buf->memory(), |
| 254 shared_buf->mapped_size())) { |
| 255 NOTREACHED() << "Invalid metafile header"; |
| 256 web_contents()->Stop(); |
| 257 return; |
| 258 } |
| 259 } |
| 260 |
| 215 // Update the rendered document. It will send notifications to the listener. | 261 // Update the rendered document. It will send notifications to the listener. |
| 216 document->SetPage(params.page_number, | 262 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); | 263 params.content_area); |
| 223 | 264 |
| 224 ShouldQuitFromInnerMessageLoop(); | 265 ShouldQuitFromInnerMessageLoop(); |
| 225 #endif | 266 #endif |
| 226 } | 267 } |
| 227 | 268 |
| 228 void PrintViewManagerBase::OnPrintingFailed(int cookie) { | 269 void PrintViewManagerBase::OnPrintingFailed(int cookie) { |
| 229 PrintManager::OnPrintingFailed(cookie); | 270 PrintManager::OnPrintingFailed(cookie); |
| 230 | 271 |
| 231 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) | 272 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 BrowserThread::IO, FROM_HERE, | 636 BrowserThread::IO, FROM_HERE, |
| 596 base::BindOnce(&PrinterQuery::StopWorker, printer_query)); | 637 base::BindOnce(&PrinterQuery::StopWorker, printer_query)); |
| 597 } | 638 } |
| 598 | 639 |
| 599 void PrintViewManagerBase::SendPrintingEnabled(bool enabled, | 640 void PrintViewManagerBase::SendPrintingEnabled(bool enabled, |
| 600 content::RenderFrameHost* rfh) { | 641 content::RenderFrameHost* rfh) { |
| 601 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled)); | 642 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled)); |
| 602 } | 643 } |
| 603 | 644 |
| 604 } // namespace printing | 645 } // namespace printing |
| OLD | NEW |