• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/printing/print_job_manager.h"
6 
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/prefs/pref_service.h"
9 #include "chrome/browser/printing/print_job.h"
10 #include "chrome/browser/printing/printer_query.h"
11 #include "chrome/common/pref_names.h"
12 #include "content/common/notification_service.h"
13 #include "printing/printed_document.h"
14 #include "printing/printed_page.h"
15 
16 namespace printing {
17 
PrintJobManager()18 PrintJobManager::PrintJobManager() {
19   registrar_.Add(this, NotificationType::PRINT_JOB_EVENT,
20                  NotificationService::AllSources());
21 }
22 
~PrintJobManager()23 PrintJobManager::~PrintJobManager() {
24   base::AutoLock lock(lock_);
25   queued_queries_.clear();
26 }
27 
OnQuit()28 void PrintJobManager::OnQuit() {
29 #if defined(OS_MACOSX)
30   // OnQuit is too late to try to wait for jobs on the Mac, since the runloop
31   // has already been torn down; instead, StopJobs(true) is called earlier in
32   // the shutdown process, and this is just here in case something sneaks
33   // in after that.
34   StopJobs(false);
35 #else
36   StopJobs(true);
37 #endif
38   registrar_.RemoveAll();
39 }
40 
StopJobs(bool wait_for_finish)41 void PrintJobManager::StopJobs(bool wait_for_finish) {
42   if (current_jobs_.empty())
43     return;
44   {
45     // Copy the array since it can be modified in transit.
46     PrintJobs current_jobs(current_jobs_);
47     // Wait for each job to finish.
48     for (size_t i = 0; i < current_jobs.size(); ++i) {
49       PrintJob* job = current_jobs[i];
50       if (!job)
51         continue;
52       // Wait for 120 seconds for the print job to be spooled.
53       if (wait_for_finish)
54         job->FlushJob(120000);
55       job->Stop();
56     }
57   }
58   current_jobs_.clear();
59 }
60 
QueuePrinterQuery(PrinterQuery * job)61 void PrintJobManager::QueuePrinterQuery(PrinterQuery* job) {
62   base::AutoLock lock(lock_);
63   DCHECK(job);
64   queued_queries_.push_back(make_scoped_refptr(job));
65   DCHECK(job->is_valid());
66 }
67 
PopPrinterQuery(int document_cookie,scoped_refptr<PrinterQuery> * job)68 void PrintJobManager::PopPrinterQuery(int document_cookie,
69                                       scoped_refptr<PrinterQuery>* job) {
70   base::AutoLock lock(lock_);
71   for (PrinterQueries::iterator itr = queued_queries_.begin();
72        itr != queued_queries_.end();
73        ++itr) {
74     PrinterQuery* current_query = *itr;
75     if (current_query->cookie() == document_cookie &&
76         !current_query->is_callback_pending()) {
77       *job = current_query;
78       queued_queries_.erase(itr);
79       DCHECK(current_query->is_valid());
80       return;
81     }
82   }
83 }
84 
85 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)86 void PrintJobManager::Observe(NotificationType type,
87                               const NotificationSource& source,
88                               const NotificationDetails& details) {
89   switch (type.value) {
90     case NotificationType::PRINT_JOB_EVENT: {
91       OnPrintJobEvent(Source<PrintJob>(source).ptr(),
92                       *Details<JobEventDetails>(details).ptr());
93       break;
94     }
95     case NotificationType::PREF_CHANGED: {
96       const std::string* pref_name = Details<std::string>(details).ptr();
97       if (*pref_name == prefs::kPrintingEnabled) {
98         PrefService *local_state = g_browser_process->local_state();
99         set_printing_enabled(local_state->GetBoolean(prefs::kPrintingEnabled));
100       }
101       break;
102     }
103     default: {
104       NOTREACHED();
105       break;
106     }
107   }
108 }
109 
OnPrintJobEvent(PrintJob * print_job,const JobEventDetails & event_details)110 void PrintJobManager::OnPrintJobEvent(
111     PrintJob* print_job,
112     const JobEventDetails& event_details) {
113   switch (event_details.type()) {
114     case JobEventDetails::NEW_DOC: {
115       DCHECK(current_jobs_.end() == std::find(current_jobs_.begin(),
116                                               current_jobs_.end(),
117                                               print_job));
118       // Causes a AddRef().
119       current_jobs_.push_back(make_scoped_refptr(print_job));
120       break;
121     }
122     case JobEventDetails::JOB_DONE: {
123       PrintJobs::iterator itr = std::find(current_jobs_.begin(),
124                                           current_jobs_.end(),
125                                           print_job);
126       DCHECK(current_jobs_.end() != itr);
127       current_jobs_.erase(itr);
128       DCHECK(current_jobs_.end() == std::find(current_jobs_.begin(),
129                                               current_jobs_.end(),
130                                               print_job));
131       break;
132     }
133     case JobEventDetails::FAILED: {
134       PrintJobs::iterator itr = std::find(current_jobs_.begin(),
135                                           current_jobs_.end(),
136                                           print_job);
137       // A failed job may have never started.
138       if (current_jobs_.end() != itr) {
139         current_jobs_.erase(itr);
140         DCHECK(current_jobs_.end() ==
141                   std::find(current_jobs_.begin(),
142                             current_jobs_.end(),
143                             print_job));
144       }
145       break;
146     }
147     case JobEventDetails::USER_INIT_DONE:
148     case JobEventDetails::USER_INIT_CANCELED:
149     case JobEventDetails::DEFAULT_INIT_DONE:
150     case JobEventDetails::NEW_PAGE:
151     case JobEventDetails::PAGE_DONE:
152     case JobEventDetails::DOC_DONE:
153     case JobEventDetails::ALL_PAGES_REQUESTED: {
154       // Don't care.
155       break;
156     }
157     default: {
158       NOTREACHED();
159       break;
160     }
161   }
162 }
163 
printing_enabled()164 bool PrintJobManager::printing_enabled() {
165   base::AutoLock lock(enabled_lock_);
166   return printing_enabled_;
167 }
168 
set_printing_enabled(bool printing_enabled)169 void PrintJobManager::set_printing_enabled(bool printing_enabled) {
170   base::AutoLock lock(enabled_lock_);
171   printing_enabled_ = printing_enabled;
172 }
173 
174 }  // namespace printing
175