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

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: rebase and resolve conflict 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 if (auto* client =
Lei Zhang 2017/08/30 02:00:35 Can this also DCHECK(client), like print_preview_m
Wei Li 2017/08/31 21:00:25 Done.
160 NOTREACHED() << "couldn't map"; 182 PrintCompositeClient::FromWebContents(web_contents())) {
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 base::ThreadTaskRunnerHandle::Get());
188 }
189 } else {
190 shared_buf = base::MakeUnique<base::SharedMemory>(
191 params.metafile_data_handle, true);
192 if (!shared_buf->Map(params.data_size)) {
193 NOTREACHED() << "couldn't map";
194 web_contents()->Stop();
195 return;
196 }
163 } 197 }
164 } else { 198 } else {
165 if (base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { 199 if (base::SharedMemory::IsHandleValid(params.metafile_data_handle)) {
166 NOTREACHED() << "unexpected valid memory handle"; 200 NOTREACHED() << "unexpected valid memory handle";
167 web_contents()->Stop(); 201 web_contents()->Stop();
168 base::SharedMemory::CloseHandle(params.metafile_data_handle); 202 base::SharedMemory::CloseHandle(params.metafile_data_handle);
169 return; 203 return;
170 } 204 }
171 } 205 }
172 206
173 std::unique_ptr<PdfMetafileSkia> metafile( 207 if (!IsOopifEnabled())
174 new PdfMetafileSkia(SkiaDocumentType::PDF)); 208 UpdateForPrintedPage(params, metafile_must_be_valid, std::move(shared_buf));
175 if (metafile_must_be_valid) { 209 }
176 if (!metafile->InitFromData(shared_buf->memory(), params.data_size)) { 210
177 NOTREACHED() << "Invalid metafile header"; 211 void PrintViewManagerBase::UpdateForPrintedPage(
178 web_contents()->Stop(); 212 const PrintHostMsg_DidPrintPage_Params& params,
179 return; 213 bool has_valid_page_data,
180 } 214 std::unique_ptr<base::SharedMemory> shared_buf) {
181 } 215 PrintedDocument* document = print_job_->document();
216 if (!document)
217 return;
182 218
183 #if defined(OS_WIN) 219 #if defined(OS_WIN)
184 print_job_->AppendPrintedPage(params.page_number); 220 print_job_->AppendPrintedPage(params.page_number);
185 if (metafile_must_be_valid) { 221 if (has_valid_page_data) {
186 scoped_refptr<base::RefCountedBytes> bytes = new base::RefCountedBytes( 222 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(
187 reinterpret_cast<const unsigned char*>(shared_buf->memory()), 223 reinterpret_cast<const unsigned char*>(shared_buf->memory()),
188 params.data_size); 224 shared_buf->mapped_size()));
225
189 document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf")); 226 document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
190 227
191 const auto& settings = document->settings(); 228 const auto& settings = document->settings();
192 if (settings.printer_is_textonly()) { 229 if (settings.printer_is_textonly()) {
193 print_job_->StartPdfToTextConversion(bytes, params.page_size); 230 print_job_->StartPdfToTextConversion(bytes, params.page_size);
194 } else if ((settings.printer_is_ps2() || settings.printer_is_ps3()) && 231 } else if ((settings.printer_is_ps2() || settings.printer_is_ps3()) &&
195 !base::FeatureList::IsEnabled( 232 !base::FeatureList::IsEnabled(
196 features::kDisablePostScriptPrinting)) { 233 features::kDisablePostScriptPrinting)) {
197 print_job_->StartPdfToPostScriptConversion(bytes, params.content_area, 234 print_job_->StartPdfToPostScriptConversion(bytes, params.content_area,
198 params.physical_offsets, 235 params.physical_offsets,
199 settings.printer_is_ps2()); 236 settings.printer_is_ps2());
200 } else { 237 } else {
201 // TODO(thestig): Figure out why rendering text with GDI results in random 238 // TODO(thestig): Figure out why rendering text with GDI results in random
202 // missing characters for some users. https://crbug.com/658606 239 // missing characters for some users. https://crbug.com/658606
203 // Update : The missing letters seem to have been caused by the same 240 // Update : The missing letters seem to have been caused by the same
204 // problem as https://crbug.com/659604 which was resolved. GDI printing 241 // problem as https://crbug.com/659604 which was resolved. GDI printing
205 // seems to work with the fix for this bug applied. 242 // seems to work with the fix for this bug applied.
206 bool print_text_with_gdi = settings.print_text_with_gdi() && 243 bool print_text_with_gdi =
207 !settings.printer_is_xps() && 244 settings.print_text_with_gdi() && !settings.printer_is_xps() &&
208 base::FeatureList::IsEnabled( 245 base::FeatureList::IsEnabled(features::kGdiTextPrinting);
209 features::kGdiTextPrinting);
210 print_job_->StartPdfToEmfConversion( 246 print_job_->StartPdfToEmfConversion(
211 bytes, params.page_size, params.content_area, print_text_with_gdi); 247 bytes, params.page_size, params.content_area, print_text_with_gdi);
212 } 248 }
213 } 249 }
214 #else 250 #else
251 std::unique_ptr<PdfMetafileSkia> metafile =
252 base::MakeUnique<PdfMetafileSkia>(SkiaDocumentType::PDF);
253 if (has_valid_page_data) {
254 if (!metafile->InitFromData(shared_buf->memory(),
255 shared_buf->mapped_size())) {
256 NOTREACHED() << "Invalid metafile header";
257 web_contents()->Stop();
258 return;
259 }
260 }
261
215 // Update the rendered document. It will send notifications to the listener. 262 // Update the rendered document. It will send notifications to the listener.
216 document->SetPage(params.page_number, 263 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); 264 params.content_area);
223 265
224 ShouldQuitFromInnerMessageLoop(); 266 ShouldQuitFromInnerMessageLoop();
225 #endif 267 #endif
226 } 268 }
227 269
228 void PrintViewManagerBase::OnPrintingFailed(int cookie) { 270 void PrintViewManagerBase::OnPrintingFailed(int cookie) {
229 PrintManager::OnPrintingFailed(cookie); 271 PrintManager::OnPrintingFailed(cookie);
230 272
231 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) 273 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 BrowserThread::IO, FROM_HERE, 637 BrowserThread::IO, FROM_HERE,
596 base::BindOnce(&PrinterQuery::StopWorker, printer_query)); 638 base::BindOnce(&PrinterQuery::StopWorker, printer_query));
597 } 639 }
598 640
599 void PrintViewManagerBase::SendPrintingEnabled(bool enabled, 641 void PrintViewManagerBase::SendPrintingEnabled(bool enabled,
600 content::RenderFrameHost* rfh) { 642 content::RenderFrameHost* rfh) {
601 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled)); 643 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled));
602 } 644 }
603 645
604 } // namespace printing 646 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698