OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |