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