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

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

Issue 2426503002: Make printing work better with OOPIF. (Closed)
Patch Set: Check GetFrameToPrint and remove another TODO 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(content::RenderFrameHost* rfh) {
232 // Terminates or cancels the print job if one was pending.
233 if (rfh != printing_rfh_)
234 return;
235
236 printing_rfh_ = nullptr;
237
238 PrintManager::PrintingRenderFrameDeleted();
239 ReleasePrinterQuery();
240
241 if (!print_job_.get())
242 return;
243
244 scoped_refptr<PrintedDocument> document(print_job_->document());
245 if (document.get()) {
246 // If IsComplete() returns false, the document isn't completely rendered.
247 // Since our renderer is gone, there's nothing to do, cancel it. Otherwise,
248 // the print job may finish without problem.
249 TerminatePrintJob(!document->IsComplete());
250 }
251 }
252
253 bool PrintViewManagerBase::OnMessageReceived(
254 const IPC::Message& message,
255 content::RenderFrameHost* render_frame_host) {
243 bool handled = true; 256 bool handled = true;
244 IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message) 257 IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBase, message)
245 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) 258 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage)
246 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, 259 IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError,
247 OnShowInvalidPrinterSettingsError) 260 OnShowInvalidPrinterSettingsError)
248 IPC_MESSAGE_UNHANDLED(handled = false) 261 IPC_MESSAGE_UNHANDLED(handled = false)
249 IPC_END_MESSAGE_MAP() 262 IPC_END_MESSAGE_MAP()
250 return handled || PrintManager::OnMessageReceived(message); 263 return handled || PrintManager::OnMessageReceived(message, render_frame_host);
251 } 264 }
252 265
253 void PrintViewManagerBase::Observe( 266 void PrintViewManagerBase::Observe(
254 int type, 267 int type,
255 const content::NotificationSource& source, 268 const content::NotificationSource& source,
256 const content::NotificationDetails& details) { 269 const content::NotificationDetails& details) {
257 DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type); 270 DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type);
258 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr()); 271 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
259 } 272 }
260 273
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 // We are in a message loop created by RenderAllMissingPagesNow. Quit from 365 // We are in a message loop created by RenderAllMissingPagesNow. Quit from
353 // it. 366 // it.
354 base::MessageLoop::current()->QuitWhenIdle(); 367 base::MessageLoop::current()->QuitWhenIdle();
355 inside_inner_message_loop_ = false; 368 inside_inner_message_loop_ = false;
356 } 369 }
357 } 370 }
358 371
359 bool PrintViewManagerBase::CreateNewPrintJob(PrintJobWorkerOwner* job) { 372 bool PrintViewManagerBase::CreateNewPrintJob(PrintJobWorkerOwner* job) {
360 DCHECK(!inside_inner_message_loop_); 373 DCHECK(!inside_inner_message_loop_);
361 374
362 // Disconnect the current print_job_. 375 // Disconnect the current |print_job_|.
363 DisconnectFromCurrentPrintJob(); 376 DisconnectFromCurrentPrintJob();
364 377
365 // We can't print if there is no renderer. 378 // We can't print if there is no renderer.
366 if (!web_contents()->GetRenderViewHost() || 379 if (!web_contents()->GetRenderViewHost() ||
367 !web_contents()->GetRenderViewHost()->IsRenderViewLive()) { 380 !web_contents()->GetRenderViewHost()->IsRenderViewLive()) {
368 return false; 381 return false;
369 } 382 }
370 383
371 // Ask the renderer to generate the print preview, create the print preview 384 // 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. 385 // view and switch to it, initialize the printer and show the print dialog.
(...skipping 24 matching lines...) Expand all
397 TerminatePrintJob(true); 410 TerminatePrintJob(true);
398 } else { 411 } else {
399 // DO NOT wait for the job to finish. 412 // DO NOT wait for the job to finish.
400 ReleasePrintJob(); 413 ReleasePrintJob();
401 } 414 }
402 #if !defined(OS_MACOSX) 415 #if !defined(OS_MACOSX)
403 expecting_first_page_ = true; 416 expecting_first_page_ = true;
404 #endif 417 #endif
405 } 418 }
406 419
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) { 420 void PrintViewManagerBase::TerminatePrintJob(bool cancel) {
414 if (!print_job_.get()) 421 if (!print_job_.get())
415 return; 422 return;
416 423
417 if (cancel) { 424 if (cancel) {
418 // We don't need the metafile data anymore because the printing is canceled. 425 // We don't need the metafile data anymore because the printing is canceled.
419 print_job_->Cancel(); 426 print_job_->Cancel();
420 inside_inner_message_loop_ = false; 427 inside_inner_message_loop_ = false;
421 } else { 428 } else {
422 DCHECK(!inside_inner_message_loop_); 429 DCHECK(!inside_inner_message_loop_);
423 DCHECK(!print_job_->document() || print_job_->document()->IsComplete()); 430 DCHECK(!print_job_->document() || print_job_->document()->IsComplete());
424 431
425 // WebContents is either dying or navigating elsewhere. We need to render 432 // 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 433 // 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: 434 // trick since it runs a blocking message loop:
428 print_job_->Stop(); 435 print_job_->Stop();
429 } 436 }
430 ReleasePrintJob(); 437 ReleasePrintJob();
431 } 438 }
432 439
433 void PrintViewManagerBase::ReleasePrintJob() { 440 void PrintViewManagerBase::ReleasePrintJob() {
441 content::RenderFrameHost* rfh = printing_rfh_;
442 printing_rfh_ = nullptr;
443
434 if (!print_job_.get()) 444 if (!print_job_.get())
435 return; 445 return;
436 446
437 PrintingDone(printing_succeeded_); 447 if (rfh) {
448 auto msg = base::MakeUnique<PrintMsg_PrintingDone>(rfh->GetRoutingID(),
449 printing_succeeded_);
450 rfh->Send(msg.release());
451 }
438 452
439 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, 453 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
440 content::Source<PrintJob>(print_job_.get())); 454 content::Source<PrintJob>(print_job_.get()));
441 print_job_->DisconnectSource(); 455 print_job_->DisconnectSource();
442 // Don't close the worker thread. 456 // Don't close the worker thread.
443 print_job_ = NULL; 457 print_job_ = nullptr;
444 } 458 }
445 459
446 bool PrintViewManagerBase::RunInnerMessageLoop() { 460 bool PrintViewManagerBase::RunInnerMessageLoop() {
447 // This value may actually be too low: 461 // This value may actually be too low:
448 // 462 //
449 // - If we're looping because of printer settings initialization, the premise 463 // - 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 464 // 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 465 // 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 466 // 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. 467 // 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. 516 // Don't kill anything.
503 return false; 517 return false;
504 } 518 }
505 519
506 // Settings are already loaded. Go ahead. This will set 520 // Settings are already loaded. Go ahead. This will set
507 // print_job_->is_job_pending() to true. 521 // print_job_->is_job_pending() to true.
508 print_job_->StartPrinting(); 522 print_job_->StartPrinting();
509 return true; 523 return true;
510 } 524 }
511 525
512 bool PrintViewManagerBase::PrintNowInternal(IPC::Message* message) { 526 bool PrintViewManagerBase::PrintNowInternal(
527 content::RenderFrameHost* rfh,
528 std::unique_ptr<IPC::Message> message) {
513 // Don't print / print preview interstitials or crashed tabs. 529 // Don't print / print preview interstitials or crashed tabs.
514 if (web_contents()->ShowingInterstitialPage() || 530 if (web_contents()->ShowingInterstitialPage() || web_contents()->IsCrashed())
515 web_contents()->IsCrashed()) {
516 delete message;
517 return false; 531 return false;
518 } 532 return rfh->Send(message.release());
519 return Send(message); 533 }
534
535 void PrintViewManagerBase::SetPrintingRFH(content::RenderFrameHost* rfh) {
536 DCHECK(!printing_rfh_);
537 printing_rfh_ = rfh;
520 } 538 }
521 539
522 void PrintViewManagerBase::ReleasePrinterQuery() { 540 void PrintViewManagerBase::ReleasePrinterQuery() {
523 if (!cookie_) 541 if (!cookie_)
524 return; 542 return;
525 543
526 int cookie = cookie_; 544 int cookie = cookie_;
527 cookie_ = 0; 545 cookie_ = 0;
528 546
529 PrintJobManager* print_job_manager = g_browser_process->print_job_manager(); 547 PrintJobManager* print_job_manager = g_browser_process->print_job_manager();
530 // May be NULL in tests. 548 // May be NULL in tests.
531 if (!print_job_manager) 549 if (!print_job_manager)
532 return; 550 return;
533 551
534 scoped_refptr<PrinterQuery> printer_query; 552 scoped_refptr<PrinterQuery> printer_query;
535 printer_query = queue_->PopPrinterQuery(cookie); 553 printer_query = queue_->PopPrinterQuery(cookie);
536 if (!printer_query.get()) 554 if (!printer_query.get())
537 return; 555 return;
538 BrowserThread::PostTask( 556 BrowserThread::PostTask(
539 BrowserThread::IO, FROM_HERE, 557 BrowserThread::IO, FROM_HERE,
540 base::Bind(&PrinterQuery::StopWorker, printer_query)); 558 base::Bind(&PrinterQuery::StopWorker, printer_query));
541 } 559 }
542 560
561 void PrintViewManagerBase::SendPrintingEnabled(bool enabled,
562 content::RenderFrameHost* rfh) {
563 rfh->Send(new PrintMsg_SetPrintingEnabled(rfh->GetRoutingID(), enabled));
564 }
565
543 } // namespace printing 566 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698