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

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

Issue 2653963002: [Experimental] Supporting OOPIF printing
Patch Set: Rename service, fix for webview, and connect to DiscardableMemoryManager Created 3 years, 8 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
« no previous file with comments | « chrome/browser/printing/print_view_manager_base.h ('k') | chrome/utility/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/files/file_util.h"
12 #include "base/location.h" 13 #include "base/location.h"
13 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/memory/shared_memory.h"
16 #include "base/memory/shared_memory_handle.h"
14 #include "base/run_loop.h" 17 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h" 18 #include "base/single_thread_task_runner.h"
16 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
17 #include "base/threading/thread_task_runner_handle.h" 20 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/timer/timer.h" 21 #include "base/timer/timer.h"
19 #include "build/build_config.h" 22 #include "build/build_config.h"
20 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chrome_notification_types.h" 24 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/printing/print_composite_client.h"
22 #include "chrome/browser/printing/print_job.h" 26 #include "chrome/browser/printing/print_job.h"
23 #include "chrome/browser/printing/print_job_manager.h" 27 #include "chrome/browser/printing/print_job_manager.h"
24 #include "chrome/browser/printing/printer_query.h" 28 #include "chrome/browser/printing/printer_query.h"
25 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/ui/simple_message_box.h" 30 #include "chrome/browser/ui/simple_message_box.h"
27 #include "chrome/common/pref_names.h" 31 #include "chrome/common/pref_names.h"
28 #include "chrome/grit/generated_resources.h" 32 #include "chrome/grit/generated_resources.h"
29 #include "components/prefs/pref_service.h" 33 #include "components/prefs/pref_service.h"
30 #include "components/printing/common/print_messages.h" 34 #include "components/printing/common/print_messages.h"
31 #include "content/public/browser/browser_thread.h" 35 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/notification_details.h" 36 #include "content/public/browser/notification_details.h"
33 #include "content/public/browser/notification_service.h" 37 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/notification_source.h" 38 #include "content/public/browser/notification_source.h"
35 #include "content/public/browser/render_frame_host.h" 39 #include "content/public/browser/render_frame_host.h"
36 #include "content/public/browser/render_view_host.h" 40 #include "content/public/browser/render_view_host.h"
41 #include "content/public/browser/render_widget_host_view.h"
37 #include "content/public/browser/web_contents.h" 42 #include "content/public/browser/web_contents.h"
43 #include "content/public/common/service_manager_connection.h"
38 #include "printing/features/features.h" 44 #include "printing/features/features.h"
39 #include "printing/pdf_metafile_skia.h" 45 #include "printing/pdf_metafile_skia.h"
40 #include "printing/printed_document.h" 46 #include "printing/printed_document.h"
47 #include "services/pdf_compositor/public/cpp/compositor_data.h"
48 #include "services/service_manager/public/cpp/connector.h"
49 #include "third_party/skia/include/core/SkDocument.h"
50 #include "third_party/skia/include/core/SkStream.h"
41 #include "ui/base/l10n/l10n_util.h" 51 #include "ui/base/l10n/l10n_util.h"
42 52
43 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) 53 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
44 #include "chrome/browser/printing/print_error_dialog.h" 54 #include "chrome/browser/printing/print_error_dialog.h"
45 #endif 55 #endif
46 56
47 #if defined(OS_WIN) 57 #if defined(OS_WIN)
48 #include "base/command_line.h" 58 #include "base/command_line.h"
49 #include "chrome/common/chrome_features.h" 59 #include "chrome/common/chrome_features.h"
50 #endif 60 #endif
(...skipping 27 matching lines...) Expand all
78 expecting_first_page_(true), 88 expecting_first_page_(true),
79 #endif 89 #endif
80 queue_(g_browser_process->print_job_manager()->queue()) { 90 queue_(g_browser_process->print_job_manager()->queue()) {
81 DCHECK(queue_.get()); 91 DCHECK(queue_.get());
82 Profile* profile = 92 Profile* profile =
83 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 93 Profile::FromBrowserContext(web_contents->GetBrowserContext());
84 printing_enabled_.Init( 94 printing_enabled_.Init(
85 prefs::kPrintingEnabled, profile->GetPrefs(), 95 prefs::kPrintingEnabled, profile->GetPrefs(),
86 base::Bind(&PrintViewManagerBase::UpdatePrintingEnabled, 96 base::Bind(&PrintViewManagerBase::UpdatePrintingEnabled,
87 base::Unretained(this))); 97 base::Unretained(this)));
98 composite_client_ = PrintCompositeClient::FromWebContents(web_contents);
99 if (!composite_client_) {
100 PrintCompositeClient::CreateForWebContents(web_contents);
101 composite_client_ = PrintCompositeClient::FromWebContents(web_contents);
102 }
88 } 103 }
89 104
90 PrintViewManagerBase::~PrintViewManagerBase() { 105 PrintViewManagerBase::~PrintViewManagerBase() {
91 ReleasePrinterQuery(); 106 ReleasePrinterQuery();
92 DisconnectFromCurrentPrintJob(); 107 DisconnectFromCurrentPrintJob();
93 } 108 }
94 109
95 #if BUILDFLAG(ENABLE_BASIC_PRINTING) 110 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
96 bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) { 111 bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
97 DisconnectFromCurrentPrintJob(); 112 DisconnectFromCurrentPrintJob();
(...skipping 21 matching lines...) Expand all
119 name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); 134 name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE);
120 return name; 135 return name;
121 } 136 }
122 137
123 void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie, 138 void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie,
124 int number_pages) { 139 int number_pages) {
125 PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); 140 PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages);
126 OpportunisticallyCreatePrintJob(cookie); 141 OpportunisticallyCreatePrintJob(cookie);
127 } 142 }
128 143
144 void PrintViewManagerBase::OnComposePdfDone(
145 mojo::ScopedSharedBufferHandle handle) {
146 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
147 if (!handle.is_valid()) {
148 NOTREACHED() << "Pdf compositor returned invalid handle";
149 return;
150 }
151
152 base::SharedMemoryHandle memory_handle;
153 size_t memory_size = 0;
154 bool read_only_flag = false;
155
156 const MojoResult result = mojo::UnwrapSharedMemoryHandle(
157 std::move(handle), &memory_handle, &memory_size, &read_only_flag);
158 DCHECK_EQ(MOJO_RESULT_OK, result);
159 DCHECK_GT(memory_size, 0u);
160
161 std::unique_ptr<base::SharedMemory> shm(
162 new base::SharedMemory(memory_handle, true /* read_only */));
163 if (!shm->Map(memory_size)) {
164 NOTREACHED() << "Composited handle map error";
165 return;
166 }
167
168 PrintedDocument* document = print_job_->document();
169
170 #if defined(OS_WIN)
171 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(
172 (unsigned char*)shm->memory(), shm->mapped_size()));
173
174 document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
175
176 const auto& settings = document->settings();
177 bool print_text_with_gdi =
178 settings.print_text_with_gdi() && !settings.printer_is_xps() &&
179 base::FeatureList::IsEnabled(features::kGdiTextPrinting);
180 print_job_->StartPdfToEmfConversion(bytes, gfx::Size(), gfx::Rect(),
181 print_text_with_gdi);
182 #endif
183 }
184
129 void PrintViewManagerBase::OnDidPrintPage( 185 void PrintViewManagerBase::OnDidPrintPage(
130 const PrintHostMsg_DidPrintPage_Params& params) { 186 content::RenderFrameHost* render_frame_host,
187 const PrintHostMsg_DidPrintPage_Params& params) {
188 const base::SharedMemoryHandle& handle = params.metafile_data_handle;
189 if (!base::SharedMemory::IsHandleValid(handle)) {
190 NOTREACHED() << "invalid memory handle";
191 web_contents()->Stop();
192 return;
193 }
194
195 if (params.is_subframe) {
196 composite_client_->AddSubFrameContent(render_frame_host->GetRoutingID(),
197 handle, params.data_size);
198 return;
199 }
200
201 // Ready to composite. Starting a print job.
131 if (!OpportunisticallyCreatePrintJob(params.document_cookie)) 202 if (!OpportunisticallyCreatePrintJob(params.document_cookie))
132 return; 203 return;
133 204
134 PrintedDocument* document = print_job_->document(); 205 PrintedDocument* document = print_job_->document();
135 if (!document || params.document_cookie != document->cookie()) { 206 if (!document || params.document_cookie != document->cookie()) {
136 // Out of sync. It may happen since we are completely asynchronous. Old 207 // Out of sync. It may happen since we are completely asynchronous. Old
137 // spurious messages can be received if one of the processes is overloaded. 208 // spurious messages can be received if one of the processes is overloaded.
138 return; 209 return;
139 } 210 }
140 211
141 #if defined(OS_MACOSX) 212 composite_client_->DoComposite(
142 const bool metafile_must_be_valid = true; 213 pdf_compositor::kPageRangeAll, params.metafile_data_handle,
143 #else 214 params.data_size, base::Bind(&PrintViewManagerBase::OnComposePdfDone,
144 const bool metafile_must_be_valid = expecting_first_page_; 215 base::Unretained(this)),
145 expecting_first_page_ = false; 216 base::ThreadTaskRunnerHandle::Get());
146 #endif
147
148 // Only used when |metafile_must_be_valid| is true.
149 std::unique_ptr<base::SharedMemory> shared_buf;
150 if (metafile_must_be_valid) {
151 if (!base::SharedMemory::IsHandleValid(params.metafile_data_handle)) {
152 NOTREACHED() << "invalid memory handle";
153 web_contents()->Stop();
154 return;
155 }
156 shared_buf =
157 base::MakeUnique<base::SharedMemory>(params.metafile_data_handle, true);
158 if (!shared_buf->Map(params.data_size)) {
159 NOTREACHED() << "couldn't map";
160 web_contents()->Stop();
161 return;
162 }
163 } else {
164 if (base::SharedMemory::IsHandleValid(params.metafile_data_handle)) {
165 NOTREACHED() << "unexpected valid memory handle";
166 web_contents()->Stop();
167 base::SharedMemory::CloseHandle(params.metafile_data_handle);
168 return;
169 }
170 }
171
172 std::unique_ptr<PdfMetafileSkia> metafile(
173 new PdfMetafileSkia(PDF_SKIA_DOCUMENT_TYPE));
174 if (metafile_must_be_valid) {
175 if (!metafile->InitFromData(shared_buf->memory(), params.data_size)) {
176 NOTREACHED() << "Invalid metafile header";
177 web_contents()->Stop();
178 return;
179 }
180 }
181
182 #if defined(OS_WIN)
183 print_job_->AppendPrintedPage(params.page_number);
184 if (metafile_must_be_valid) {
185 scoped_refptr<base::RefCountedBytes> bytes = new base::RefCountedBytes(
186 reinterpret_cast<const unsigned char*>(shared_buf->memory()),
187 params.data_size);
188 document->DebugDumpData(bytes.get(), FILE_PATH_LITERAL(".pdf"));
189
190 const auto& settings = document->settings();
191 if ((settings.printer_is_ps2() || settings.printer_is_ps3()) &&
192 base::FeatureList::IsEnabled(features::kPostScriptPrinting)) {
193 print_job_->StartPdfToPostScriptConversion(bytes, params.content_area,
194 params.physical_offsets,
195 settings.printer_is_ps2());
196 } else {
197 // TODO(thestig): Figure out why rendering text with GDI results in random
198 // missing characters for some users. https://crbug.com/658606
199 // Update : The missing letters seem to have been caused by the same
200 // problem as https://crbug.com/659604 which was resolved. GDI printing
201 // seems to work with the fix for this bug applied.
202 bool print_text_with_gdi = settings.print_text_with_gdi() &&
203 !settings.printer_is_xps() &&
204 base::FeatureList::IsEnabled(
205 features::kGdiTextPrinting);
206 print_job_->StartPdfToEmfConversion(
207 bytes, params.page_size, params.content_area, print_text_with_gdi);
208 }
209 }
210 #else
211 // Update the rendered document. It will send notifications to the listener.
212 document->SetPage(params.page_number,
213 std::move(metafile),
214 #if defined(OS_WIN)
215 0.0f /* dummy shrink_factor */,
216 #endif
217 params.page_size,
218 params.content_area);
219
220 ShouldQuitFromInnerMessageLoop();
221 #endif
222 } 217 }
223 218
224 void PrintViewManagerBase::OnPrintingFailed(int cookie) { 219 void PrintViewManagerBase::OnPrintingFailed(int cookie) {
225 PrintManager::OnPrintingFailed(cookie); 220 PrintManager::OnPrintingFailed(cookie);
226 221
227 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) 222 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
228 chrome::ShowPrintErrorDialog(); 223 chrome::ShowPrintErrorDialog();
229 #endif 224 #endif
230 225
231 ReleasePrinterQuery(); 226 ReleasePrinterQuery();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 // Since our renderer is gone, there's nothing to do, cancel it. Otherwise, 262 // Since our renderer is gone, there's nothing to do, cancel it. Otherwise,
268 // the print job may finish without problem. 263 // the print job may finish without problem.
269 TerminatePrintJob(!document->IsComplete()); 264 TerminatePrintJob(!document->IsComplete());
270 } 265 }
271 } 266 }
272 267
273 bool PrintViewManagerBase::OnMessageReceived( 268 bool PrintViewManagerBase::OnMessageReceived(
274 const IPC::Message& message, 269 const IPC::Message& message,
275 content::RenderFrameHost* render_frame_host) { 270 content::RenderFrameHost* render_frame_host) {
276 bool handled = true; 271 bool handled = true;
272 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintViewManagerBase, message,
273 render_frame_host)
274 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
275 IPC_MESSAGE_UNHANDLED(handled = false)
276 IPC_END_MESSAGE_MAP()
277 if (handled)
278 return true;
279
277 IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message) 280 IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message)
278 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
279 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, 281 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError,
280 OnShowInvalidPrinterSettingsError) 282 OnShowInvalidPrinterSettingsError)
281 IPC_MESSAGE_UNHANDLED(handled = false) 283 IPC_MESSAGE_UNHANDLED(handled = false)
282 IPC_END_MESSAGE_MAP() 284 IPC_END_MESSAGE_MAP()
283 return handled || PrintManager::OnMessageReceived(message, render_frame_host); 285 return handled || PrintManager::OnMessageReceived(message, render_frame_host);
284 } 286 }
285 287
286 void PrintViewManagerBase::Observe( 288 void PrintViewManagerBase::Observe(
287 int type, 289 int type,
288 const content::NotificationSource& source, 290 const content::NotificationSource& source,
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 print_job_->StartPrinting(); 544 print_job_->StartPrinting();
543 return true; 545 return true;
544 } 546 }
545 547
546 bool PrintViewManagerBase::PrintNowInternal( 548 bool PrintViewManagerBase::PrintNowInternal(
547 content::RenderFrameHost* rfh, 549 content::RenderFrameHost* rfh,
548 std::unique_ptr<IPC::Message> message) { 550 std::unique_ptr<IPC::Message> message) {
549 // Don't print / print preview interstitials or crashed tabs. 551 // Don't print / print preview interstitials or crashed tabs.
550 if (web_contents()->ShowingInterstitialPage() || web_contents()->IsCrashed()) 552 if (web_contents()->ShowingInterstitialPage() || web_contents()->IsCrashed())
551 return false; 553 return false;
554
552 return rfh->Send(message.release()); 555 return rfh->Send(message.release());
553 } 556 }
554 557
555 void PrintViewManagerBase::SetPrintingRFH(content::RenderFrameHost* rfh) { 558 void PrintViewManagerBase::SetPrintingRFH(content::RenderFrameHost* rfh) {
556 DCHECK(!printing_rfh_); 559 DCHECK(!printing_rfh_);
557 printing_rfh_ = rfh; 560 printing_rfh_ = rfh;
558 } 561 }
559 562
560 void PrintViewManagerBase::ReleasePrinterQuery() { 563 void PrintViewManagerBase::ReleasePrinterQuery() {
561 if (!cookie_) 564 if (!cookie_)
(...skipping 15 matching lines...) Expand all
577 BrowserThread::IO, FROM_HERE, 580 BrowserThread::IO, FROM_HERE,
578 base::Bind(&PrinterQuery::StopWorker, printer_query)); 581 base::Bind(&PrinterQuery::StopWorker, printer_query));
579 } 582 }
580 583
581 void PrintViewManagerBase::SendPrintingEnabled(bool enabled, 584 void PrintViewManagerBase::SendPrintingEnabled(bool enabled,
582 content::RenderFrameHost* rfh) { 585 content::RenderFrameHost* rfh) {
583 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled)); 586 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled));
584 } 587 }
585 588
586 } // namespace printing 589 } // namespace printing
OLDNEW
« no previous file with comments | « chrome/browser/printing/print_view_manager_base.h ('k') | chrome/utility/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698