| 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, |
| 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 |