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

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

Issue 2426503002: Make printing work better with OOPIF. (Closed)
Patch Set: Better plumbing in AwPrintManager Created 4 years, 1 month 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"
(...skipping 14 matching lines...) Expand all
25 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/ui/simple_message_box.h" 26 #include "chrome/browser/ui/simple_message_box.h"
27 #include "chrome/common/pref_names.h" 27 #include "chrome/common/pref_names.h"
28 #include "chrome/grit/generated_resources.h" 28 #include "chrome/grit/generated_resources.h"
29 #include "components/prefs/pref_service.h" 29 #include "components/prefs/pref_service.h"
30 #include "components/printing/common/print_messages.h" 30 #include "components/printing/common/print_messages.h"
31 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/notification_details.h" 32 #include "content/public/browser/notification_details.h"
33 #include "content/public/browser/notification_service.h" 33 #include "content/public/browser/notification_service.h"
34 #include "content/public/browser/notification_source.h" 34 #include "content/public/browser/notification_source.h"
35 #include "content/public/browser/render_frame_host.h"
35 #include "content/public/browser/render_view_host.h" 36 #include "content/public/browser/render_view_host.h"
36 #include "content/public/browser/web_contents.h" 37 #include "content/public/browser/web_contents.h"
37 #include "printing/features/features.h" 38 #include "printing/features/features.h"
38 #include "printing/pdf_metafile_skia.h" 39 #include "printing/pdf_metafile_skia.h"
39 #include "printing/printed_document.h" 40 #include "printing/printed_document.h"
40 #include "ui/base/l10n/l10n_util.h" 41 #include "ui/base/l10n/l10n_util.h"
41 42
42 #if BUILDFLAG(ENABLE_PRINT_PREVIEW) 43 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
43 #include "chrome/browser/printing/print_error_dialog.h" 44 #include "chrome/browser/printing/print_error_dialog.h"
44 #endif 45 #endif
(...skipping 18 matching lines...) Expand all
63 // Block opening dialog from nested task. 64 // Block opening dialog from nested task.
64 base::AutoReset<bool> auto_reset(&is_dialog_shown, true); 65 base::AutoReset<bool> auto_reset(&is_dialog_shown, true);
65 66
66 chrome::ShowWarningMessageBox(nullptr, base::string16(), message); 67 chrome::ShowWarningMessageBox(nullptr, base::string16(), message);
67 } 68 }
68 69
69 } // namespace 70 } // namespace
70 71
71 PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents) 72 PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
72 : PrintManager(web_contents), 73 : PrintManager(web_contents),
74 printing_rfh_(nullptr),
73 printing_succeeded_(false), 75 printing_succeeded_(false),
74 inside_inner_message_loop_(false), 76 inside_inner_message_loop_(false),
75 #if !defined(OS_MACOSX) 77 #if !defined(OS_MACOSX)
76 expecting_first_page_(true), 78 expecting_first_page_(true),
77 #endif 79 #endif
78 queue_(g_browser_process->print_job_manager()->queue()) { 80 queue_(g_browser_process->print_job_manager()->queue()) {
79 DCHECK(queue_.get()); 81 DCHECK(queue_.get());
80 Profile* profile = 82 Profile* profile =
81 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 83 Profile::FromBrowserContext(web_contents->GetBrowserContext());
82 printing_enabled_.Init( 84 printing_enabled_.Init(
83 prefs::kPrintingEnabled, 85 prefs::kPrintingEnabled, profile->GetPrefs(),
84 profile->GetPrefs(), 86 base::Bind(&PrintViewManagerBase::UpdatePrintingEnabled,
85 base::Bind(&PrintViewManagerBase::UpdateScriptedPrintingBlocked,
86 base::Unretained(this))); 87 base::Unretained(this)));
87 } 88 }
88 89
89 PrintViewManagerBase::~PrintViewManagerBase() { 90 PrintViewManagerBase::~PrintViewManagerBase() {
90 ReleasePrinterQuery(); 91 ReleasePrinterQuery();
91 DisconnectFromCurrentPrintJob(); 92 DisconnectFromCurrentPrintJob();
92 } 93 }
93 94
94 #if BUILDFLAG(ENABLE_BASIC_PRINTING) 95 #if BUILDFLAG(ENABLE_BASIC_PRINTING)
95 bool PrintViewManagerBase::PrintNow() { 96 bool PrintViewManagerBase::PrintNow(content::RenderFrameHost* rfh) {
96 return PrintNowInternal(new PrintMsg_PrintPages(routing_id())); 97 DisconnectFromCurrentPrintJob();
98
99 SetPrintingRFH(rfh);
100 int32_t id = rfh->GetRoutingID();
101 return PrintNowInternal(rfh, base::MakeUnique<PrintMsg_PrintPages>(id));
97 } 102 }
98 #endif 103 #endif
99 104
100 void PrintViewManagerBase::UpdateScriptedPrintingBlocked() { 105 void PrintViewManagerBase::UpdatePrintingEnabled() {
101 Send(new PrintMsg_SetScriptedPrintingBlocked( 106 web_contents()->ForEachFrame(
102 routing_id(), 107 base::Bind(&PrintViewManagerBase::SendPrintingEnabled,
103 !printing_enabled_.GetValue())); 108 base::Unretained(this), printing_enabled_.GetValue()));
104 } 109 }
105 110
106 void PrintViewManagerBase::NavigationStopped() { 111 void PrintViewManagerBase::NavigationStopped() {
107 // Cancel the current job, wait for the worker to finish. 112 // Cancel the current job, wait for the worker to finish.
108 TerminatePrintJob(true); 113 TerminatePrintJob(true);
109 } 114 }
110 115
111 void PrintViewManagerBase::RenderProcessGone(base::TerminationStatus status) {
112 PrintManager::RenderProcessGone(status);
113 ReleasePrinterQuery();
114
115 if (!print_job_.get())
116 return;
117
118 scoped_refptr<PrintedDocument> document(print_job_->document());
119 if (document.get()) {
120 // If IsComplete() returns false, the document isn't completely rendered.
121 // Since our renderer is gone, there's nothing to do, cancel it. Otherwise,
122 // the print job may finish without problem.
123 TerminatePrintJob(!document->IsComplete());
124 }
125 }
126
127 base::string16 PrintViewManagerBase::RenderSourceName() { 116 base::string16 PrintViewManagerBase::RenderSourceName() {
128 base::string16 name(web_contents()->GetTitle()); 117 base::string16 name(web_contents()->GetTitle());
129 if (name.empty()) 118 if (name.empty())
130 name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE); 119 name = l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE);
131 return name; 120 return name;
132 } 121 }
133 122
134 void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie, 123 void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie,
135 int number_pages) { 124 int number_pages) {
136 PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); 125 PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 218 }
230 219
231 void PrintViewManagerBase::OnShowInvalidPrinterSettingsError() { 220 void PrintViewManagerBase::OnShowInvalidPrinterSettingsError() {
232 base::ThreadTaskRunnerHandle::Get()->PostTask( 221 base::ThreadTaskRunnerHandle::Get()->PostTask(
233 FROM_HERE, base::Bind(&ShowWarningMessageBox, 222 FROM_HERE, base::Bind(&ShowWarningMessageBox,
234 l10n_util::GetStringUTF16( 223 l10n_util::GetStringUTF16(
235 IDS_PRINT_INVALID_PRINTER_SETTINGS))); 224 IDS_PRINT_INVALID_PRINTER_SETTINGS)));
236 } 225 }
237 226
238 void PrintViewManagerBase::DidStartLoading() { 227 void PrintViewManagerBase::DidStartLoading() {
239 UpdateScriptedPrintingBlocked(); 228 UpdatePrintingEnabled();
240 } 229 }
241 230
242 bool PrintViewManagerBase::OnMessageReceived(const IPC::Message& message) { 231 void PrintViewManagerBase::RenderFrameDeleted(
232 content::RenderFrameHost* render_frame_host) {
233 // Terminates or cancels the print job if one was pending.
234 if (render_frame_host != printing_rfh_)
235 return;
236
237 printing_rfh_ = nullptr;
238
239 PrintManager::PrintingRenderFrameDeleted();
240 ReleasePrinterQuery();
241
242 if (!print_job_.get())
243 return;
244
245 scoped_refptr<PrintedDocument> document(print_job_->document());
246 if (document.get()) {
247 // If IsComplete() returns false, the document isn't completely rendered.
248 // Since our renderer is gone, there's nothing to do, cancel it. Otherwise,
249 // the print job may finish without problem.
250 TerminatePrintJob(!document->IsComplete());
251 }
252 }
253
254 bool PrintViewManagerBase::OnMessageReceived(
255 const IPC::Message& message,
256 content::RenderFrameHost* render_frame_host) {
243 bool handled = true; 257 bool handled = true;
244 IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message) 258 IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message)
245 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) 259 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
246 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, 260 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError,
247 OnShowInvalidPrinterSettingsError) 261 OnShowInvalidPrinterSettingsError)
248 IPC_MESSAGE_UNHANDLED(handled = false) 262 IPC_MESSAGE_UNHANDLED(handled = false)
249 IPC_END_MESSAGE_MAP() 263 IPC_END_MESSAGE_MAP()
250 return handled || PrintManager::OnMessageReceived(message); 264 return handled || PrintManager::OnMessageReceived(message, render_frame_host);
251 } 265 }
252 266
253 void PrintViewManagerBase::Observe( 267 void PrintViewManagerBase::Observe(
254 int type, 268 int type,
255 const content::NotificationSource& source, 269 const content::NotificationSource& source,
256 const content::NotificationDetails& details) { 270 const content::NotificationDetails& details) {
257 DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type); 271 DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type);
258 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr()); 272 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
259 } 273 }
260 274
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 // We are in a message loop created by RenderAllMissingPagesNow. Quit from 366 // We are in a message loop created by RenderAllMissingPagesNow. Quit from
353 // it. 367 // it.
354 base::MessageLoop::current()->QuitWhenIdle(); 368 base::MessageLoop::current()->QuitWhenIdle();
355 inside_inner_message_loop_ = false; 369 inside_inner_message_loop_ = false;
356 } 370 }
357 } 371 }
358 372
359 bool PrintViewManagerBase::CreateNewPrintJob(PrintJobWorkerOwner* job) { 373 bool PrintViewManagerBase::CreateNewPrintJob(PrintJobWorkerOwner* job) {
360 DCHECK(!inside_inner_message_loop_); 374 DCHECK(!inside_inner_message_loop_);
361 375
362 // Disconnect the current print_job_. 376 // Disconnect the current |print_job_|.
363 DisconnectFromCurrentPrintJob(); 377 DisconnectFromCurrentPrintJob();
364 378
365 // We can't print if there is no renderer. 379 // We can't print if there is no renderer.
366 if (!web_contents()->GetRenderViewHost() || 380 if (!web_contents()->GetRenderViewHost() ||
367 !web_contents()->GetRenderViewHost()->IsRenderViewLive()) { 381 !web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
368 return false; 382 return false;
369 } 383 }
370 384
371 // Ask the renderer to generate the print preview, create the print preview 385 // Ask the renderer to generate the print preview, create the print preview
372 // view and switch to it, initialize the printer and show the print dialog. 386 // view and switch to it, initialize the printer and show the print dialog.
(...skipping 24 matching lines...) Expand all
397 TerminatePrintJob(true); 411 TerminatePrintJob(true);
398 } else { 412 } else {
399 // DO NOT wait for the job to finish. 413 // DO NOT wait for the job to finish.
400 ReleasePrintJob(); 414 ReleasePrintJob();
401 } 415 }
402 #if !defined(OS_MACOSX) 416 #if !defined(OS_MACOSX)
403 expecting_first_page_ = true; 417 expecting_first_page_ = true;
404 #endif 418 #endif
405 } 419 }
406 420
407 void PrintViewManagerBase::PrintingDone(bool success) {
408 if (!print_job_.get())
409 return;
410 Send(new PrintMsg_PrintingDone(routing_id(), success));
411 }
412
413 void PrintViewManagerBase::TerminatePrintJob(bool cancel) { 421 void PrintViewManagerBase::TerminatePrintJob(bool cancel) {
414 if (!print_job_.get()) 422 if (!print_job_.get())
415 return; 423 return;
416 424
417 if (cancel) { 425 if (cancel) {
418 // We don't need the metafile data anymore because the printing is canceled. 426 // We don't need the metafile data anymore because the printing is canceled.
419 print_job_->Cancel(); 427 print_job_->Cancel();
420 inside_inner_message_loop_ = false; 428 inside_inner_message_loop_ = false;
421 } else { 429 } else {
422 DCHECK(!inside_inner_message_loop_); 430 DCHECK(!inside_inner_message_loop_);
423 DCHECK(!print_job_->document() || print_job_->document()->IsComplete()); 431 DCHECK(!print_job_->document() || print_job_->document()->IsComplete());
424 432
425 // WebContents is either dying or navigating elsewhere. We need to render 433 // WebContents is either dying or navigating elsewhere. We need to render
426 // all the pages in an hurry if a print job is still pending. This does the 434 // all the pages in an hurry if a print job is still pending. This does the
427 // trick since it runs a blocking message loop: 435 // trick since it runs a blocking message loop:
428 print_job_->Stop(); 436 print_job_->Stop();
429 } 437 }
430 ReleasePrintJob(); 438 ReleasePrintJob();
431 } 439 }
432 440
433 void PrintViewManagerBase::ReleasePrintJob() { 441 void PrintViewManagerBase::ReleasePrintJob() {
442 content::RenderFrameHost* rfh = printing_rfh_;
443 printing_rfh_ = nullptr;
444
434 if (!print_job_.get()) 445 if (!print_job_.get())
435 return; 446 return;
436 447
437 PrintingDone(printing_succeeded_); 448 if (rfh) {
449 auto msg = base::MakeUnique<PrintMsg_PrintingDone>(rfh->GetRoutingID(),
450 printing_succeeded_);
451 rfh->Send(msg.release());
452 }
438 453
439 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, 454 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
440 content::Source<PrintJob>(print_job_.get())); 455 content::Source<PrintJob>(print_job_.get()));
441 print_job_->DisconnectSource(); 456 print_job_->DisconnectSource();
442 // Don't close the worker thread. 457 // Don't close the worker thread.
443 print_job_ = NULL; 458 print_job_ = nullptr;
444 } 459 }
445 460
446 bool PrintViewManagerBase::RunInnerMessageLoop() { 461 bool PrintViewManagerBase::RunInnerMessageLoop() {
447 // This value may actually be too low: 462 // This value may actually be too low:
448 // 463 //
449 // - If we're looping because of printer settings initialization, the premise 464 // - If we're looping because of printer settings initialization, the premise
450 // here is that some poor users have their print server away on a VPN over a 465 // here is that some poor users have their print server away on a VPN over a
451 // slow connection. In this situation, the simple fact of opening the printer 466 // slow connection. In this situation, the simple fact of opening the printer
452 // can be dead slow. On the other side, we don't want to die infinitely for a 467 // can be dead slow. On the other side, we don't want to die infinitely for a
453 // real network error. Give the printer 60 seconds to comply. 468 // real network error. Give the printer 60 seconds to comply.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 // Don't kill anything. 517 // Don't kill anything.
503 return false; 518 return false;
504 } 519 }
505 520
506 // Settings are already loaded. Go ahead. This will set 521 // Settings are already loaded. Go ahead. This will set
507 // print_job_->is_job_pending() to true. 522 // print_job_->is_job_pending() to true.
508 print_job_->StartPrinting(); 523 print_job_->StartPrinting();
509 return true; 524 return true;
510 } 525 }
511 526
512 bool PrintViewManagerBase::PrintNowInternal(IPC::Message* message) { 527 bool PrintViewManagerBase::PrintNowInternal(
528 content::RenderFrameHost* rfh,
529 std::unique_ptr<IPC::Message> message) {
513 // Don't print / print preview interstitials or crashed tabs. 530 // Don't print / print preview interstitials or crashed tabs.
514 if (web_contents()->ShowingInterstitialPage() || 531 if (web_contents()->ShowingInterstitialPage() || web_contents()->IsCrashed())
515 web_contents()->IsCrashed()) {
516 delete message;
517 return false; 532 return false;
518 } 533 return rfh->Send(message.release());
519 return Send(message); 534 }
535
536 void PrintViewManagerBase::SetPrintingRFH(content::RenderFrameHost* rfh) {
537 DCHECK(!printing_rfh_);
538 printing_rfh_ = rfh;
520 } 539 }
521 540
522 void PrintViewManagerBase::ReleasePrinterQuery() { 541 void PrintViewManagerBase::ReleasePrinterQuery() {
523 if (!cookie_) 542 if (!cookie_)
524 return; 543 return;
525 544
526 int cookie = cookie_; 545 int cookie = cookie_;
527 cookie_ = 0; 546 cookie_ = 0;
528 547
529 PrintJobManager* print_job_manager = g_browser_process->print_job_manager(); 548 PrintJobManager* print_job_manager = g_browser_process->print_job_manager();
530 // May be NULL in tests. 549 // May be NULL in tests.
531 if (!print_job_manager) 550 if (!print_job_manager)
532 return; 551 return;
533 552
534 scoped_refptr<PrinterQuery> printer_query; 553 scoped_refptr<PrinterQuery> printer_query;
535 printer_query = queue_->PopPrinterQuery(cookie); 554 printer_query = queue_->PopPrinterQuery(cookie);
536 if (!printer_query.get()) 555 if (!printer_query.get())
537 return; 556 return;
538 BrowserThread::PostTask( 557 BrowserThread::PostTask(
539 BrowserThread::IO, FROM_HERE, 558 BrowserThread::IO, FROM_HERE,
540 base::Bind(&PrinterQuery::StopWorker, printer_query)); 559 base::Bind(&PrinterQuery::StopWorker, printer_query));
541 } 560 }
542 561
562 void PrintViewManagerBase::SendPrintingEnabled(bool enabled,
563 content::RenderFrameHost* rfh) {
564 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled));
565 }
566
543 } // namespace printing 567 } // namespace printing
OLDNEW
« no previous file with comments | « chrome/browser/printing/print_view_manager_base.h ('k') | chrome/browser/printing/print_view_manager_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698