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

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

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