| 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |