| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/printing/print_job_manager.h" |
| |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/prefs/pref_service.h" |
| #include "chrome/browser/printing/print_job.h" |
| #include "chrome/browser/printing/printer_query.h" |
| #include "chrome/common/pref_names.h" |
| #include "content/common/notification_service.h" |
| #include "printing/printed_document.h" |
| #include "printing/printed_page.h" |
| |
| namespace printing { |
| |
| PrintJobManager::PrintJobManager() { |
| registrar_.Add(this, NotificationType::PRINT_JOB_EVENT, |
| NotificationService::AllSources()); |
| } |
| |
| PrintJobManager::~PrintJobManager() { |
| base::AutoLock lock(lock_); |
| queued_queries_.clear(); |
| } |
| |
| void PrintJobManager::OnQuit() { |
| #if defined(OS_MACOSX) |
| // OnQuit is too late to try to wait for jobs on the Mac, since the runloop |
| // has already been torn down; instead, StopJobs(true) is called earlier in |
| // the shutdown process, and this is just here in case something sneaks |
| // in after that. |
| StopJobs(false); |
| #else |
| StopJobs(true); |
| #endif |
| registrar_.RemoveAll(); |
| } |
| |
| void PrintJobManager::StopJobs(bool wait_for_finish) { |
| if (current_jobs_.empty()) |
| return; |
| { |
| // Copy the array since it can be modified in transit. |
| PrintJobs current_jobs(current_jobs_); |
| // Wait for each job to finish. |
| for (size_t i = 0; i < current_jobs.size(); ++i) { |
| PrintJob* job = current_jobs[i]; |
| if (!job) |
| continue; |
| // Wait for 120 seconds for the print job to be spooled. |
| if (wait_for_finish) |
| job->FlushJob(120000); |
| job->Stop(); |
| } |
| } |
| current_jobs_.clear(); |
| } |
| |
| void PrintJobManager::QueuePrinterQuery(PrinterQuery* job) { |
| base::AutoLock lock(lock_); |
| DCHECK(job); |
| queued_queries_.push_back(make_scoped_refptr(job)); |
| DCHECK(job->is_valid()); |
| } |
| |
| void PrintJobManager::PopPrinterQuery(int document_cookie, |
| scoped_refptr<PrinterQuery>* job) { |
| base::AutoLock lock(lock_); |
| for (PrinterQueries::iterator itr = queued_queries_.begin(); |
| itr != queued_queries_.end(); |
| ++itr) { |
| PrinterQuery* current_query = *itr; |
| if (current_query->cookie() == document_cookie && |
| !current_query->is_callback_pending()) { |
| *job = current_query; |
| queued_queries_.erase(itr); |
| DCHECK(current_query->is_valid()); |
| return; |
| } |
| } |
| } |
| |
| |
| void PrintJobManager::Observe(NotificationType type, |
| const NotificationSource& source, |
| const NotificationDetails& details) { |
| switch (type.value) { |
| case NotificationType::PRINT_JOB_EVENT: { |
| OnPrintJobEvent(Source<PrintJob>(source).ptr(), |
| *Details<JobEventDetails>(details).ptr()); |
| break; |
| } |
| case NotificationType::PREF_CHANGED: { |
| const std::string* pref_name = Details<std::string>(details).ptr(); |
| if (*pref_name == prefs::kPrintingEnabled) { |
| PrefService *local_state = g_browser_process->local_state(); |
| set_printing_enabled(local_state->GetBoolean(prefs::kPrintingEnabled)); |
| } |
| break; |
| } |
| default: { |
| NOTREACHED(); |
| break; |
| } |
| } |
| } |
| |
| void PrintJobManager::OnPrintJobEvent( |
| PrintJob* print_job, |
| const JobEventDetails& event_details) { |
| switch (event_details.type()) { |
| case JobEventDetails::NEW_DOC: { |
| DCHECK(current_jobs_.end() == std::find(current_jobs_.begin(), |
| current_jobs_.end(), |
| print_job)); |
| // Causes a AddRef(). |
| current_jobs_.push_back(make_scoped_refptr(print_job)); |
| break; |
| } |
| case JobEventDetails::JOB_DONE: { |
| PrintJobs::iterator itr = std::find(current_jobs_.begin(), |
| current_jobs_.end(), |
| print_job); |
| DCHECK(current_jobs_.end() != itr); |
| current_jobs_.erase(itr); |
| DCHECK(current_jobs_.end() == std::find(current_jobs_.begin(), |
| current_jobs_.end(), |
| print_job)); |
| break; |
| } |
| case JobEventDetails::FAILED: { |
| PrintJobs::iterator itr = std::find(current_jobs_.begin(), |
| current_jobs_.end(), |
| print_job); |
| // A failed job may have never started. |
| if (current_jobs_.end() != itr) { |
| current_jobs_.erase(itr); |
| DCHECK(current_jobs_.end() == |
| std::find(current_jobs_.begin(), |
| current_jobs_.end(), |
| print_job)); |
| } |
| break; |
| } |
| case JobEventDetails::USER_INIT_DONE: |
| case JobEventDetails::USER_INIT_CANCELED: |
| case JobEventDetails::DEFAULT_INIT_DONE: |
| case JobEventDetails::NEW_PAGE: |
| case JobEventDetails::PAGE_DONE: |
| case JobEventDetails::DOC_DONE: |
| case JobEventDetails::ALL_PAGES_REQUESTED: { |
| // Don't care. |
| break; |
| } |
| default: { |
| NOTREACHED(); |
| break; |
| } |
| } |
| } |
| |
| bool PrintJobManager::printing_enabled() { |
| base::AutoLock lock(enabled_lock_); |
| return printing_enabled_; |
| } |
| |
| void PrintJobManager::set_printing_enabled(bool printing_enabled) { |
| base::AutoLock lock(enabled_lock_); |
| printing_enabled_ = printing_enabled; |
| } |
| |
| } // namespace printing |