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