Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(365)

Side by Side Diff: chrome/browser/printing/print_view_manager_base.cc

Issue 2920013002: Use pdf compositor service for printing when OOPIF is enabled
Patch Set: fix due to rebase Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698