OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/service/cloud_print/print_system.h" | 5 #include "chrome/service/cloud_print/print_system.h" |
6 | 6 |
7 #include <cups/cups.h> | 7 #include <cups/cups.h> |
8 #include <dlfcn.h> | 8 #include <dlfcn.h> |
9 #include <errno.h> | 9 #include <errno.h> |
10 #include <pthread.h> | 10 #include <pthread.h> |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 | 42 |
43 // Print system config options. | 43 // Print system config options. |
44 const char kCUPSPrintServerURLs[] = "print_server_urls"; | 44 const char kCUPSPrintServerURLs[] = "print_server_urls"; |
45 const char kCUPSUpdateTimeoutMs[] = "update_timeout_ms"; | 45 const char kCUPSUpdateTimeoutMs[] = "update_timeout_ms"; |
46 const char kCUPSNotifyDelete[] = "notify_delete"; | 46 const char kCUPSNotifyDelete[] = "notify_delete"; |
47 | 47 |
48 // Default port for IPP print servers. | 48 // Default port for IPP print servers. |
49 const int kDefaultIPPServerPort = 631; | 49 const int kDefaultIPPServerPort = 631; |
50 | 50 |
51 // Time interval to check for printer's updates. | 51 // Time interval to check for printer's updates. |
52 const int kCheckForPrinterUpdatesMs = 5*60*1000; | 52 const int kCheckForPrinterUpdatesMinutes = 5; |
53 | 53 |
54 // Job update timeout | 54 // Job update timeout |
55 const int kJobUpdateTimeoutMs = 5000; | 55 const int kJobUpdateTimeoutSeconds = 5; |
56 | 56 |
57 // Job id for dry run (it should not affect CUPS job ids, since 0 job-id is | 57 // Job id for dry run (it should not affect CUPS job ids, since 0 job-id is |
58 // invalid in CUPS. | 58 // invalid in CUPS. |
59 const int kDryRunJobId = 0; | 59 const int kDryRunJobId = 0; |
60 | 60 |
61 } // namespace | 61 } // namespace |
62 | 62 |
63 namespace cloud_print { | 63 namespace cloud_print { |
64 | 64 |
65 struct PrintServerInfoCUPS { | 65 struct PrintServerInfoCUPS { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 bool GetPrinterInfo(const std::string& printer_name, | 108 bool GetPrinterInfo(const std::string& printer_name, |
109 printing::PrinterBasicInfo* info); | 109 printing::PrinterBasicInfo* info); |
110 bool ParsePrintTicket(const std::string& print_ticket, | 110 bool ParsePrintTicket(const std::string& print_ticket, |
111 std::map<std::string, std::string>* options); | 111 std::map<std::string, std::string>* options); |
112 | 112 |
113 // Synchronous version of GetPrinterCapsAndDefaults. | 113 // Synchronous version of GetPrinterCapsAndDefaults. |
114 bool GetPrinterCapsAndDefaults( | 114 bool GetPrinterCapsAndDefaults( |
115 const std::string& printer_name, | 115 const std::string& printer_name, |
116 printing::PrinterCapsAndDefaults* printer_info); | 116 printing::PrinterCapsAndDefaults* printer_info); |
117 | 117 |
118 int GetUpdateTimeoutMs() const { | 118 base::TimeDelta GetUpdateTimeout() const { |
119 return update_timeout_; | 119 return update_timeout_; |
120 } | 120 } |
121 | 121 |
122 bool NotifyDelete() const { | 122 bool NotifyDelete() const { |
123 // Notify about deleted printers only when we | 123 // Notify about deleted printers only when we |
124 // fetched printers list without errors. | 124 // fetched printers list without errors. |
125 return notify_delete_ && printer_enum_succeeded_; | 125 return notify_delete_ && printer_enum_succeeded_; |
126 } | 126 } |
127 | 127 |
128 private: | 128 private: |
(...skipping 23 matching lines...) Expand all Loading... |
152 const PrinterCapsAndDefaultsCallback& callback, | 152 const PrinterCapsAndDefaultsCallback& callback, |
153 bool succeeded, | 153 bool succeeded, |
154 const std::string& printer_name, | 154 const std::string& printer_name, |
155 const printing::PrinterCapsAndDefaults& printer_info); | 155 const printing::PrinterCapsAndDefaults& printer_info); |
156 | 156 |
157 // PrintServerList contains information about all print servers and backends | 157 // PrintServerList contains information about all print servers and backends |
158 // this proxy is connected to. | 158 // this proxy is connected to. |
159 typedef std::list<PrintServerInfoCUPS> PrintServerList; | 159 typedef std::list<PrintServerInfoCUPS> PrintServerList; |
160 PrintServerList print_servers_; | 160 PrintServerList print_servers_; |
161 | 161 |
162 int update_timeout_; | 162 base::TimeDelta update_timeout_; |
163 bool initialized_; | 163 bool initialized_; |
164 bool printer_enum_succeeded_; | 164 bool printer_enum_succeeded_; |
165 bool notify_delete_; | 165 bool notify_delete_; |
166 }; | 166 }; |
167 | 167 |
168 class PrintServerWatcherCUPS | 168 class PrintServerWatcherCUPS |
169 : public PrintSystem::PrintServerWatcher { | 169 : public PrintSystem::PrintServerWatcher { |
170 public: | 170 public: |
171 explicit PrintServerWatcherCUPS(PrintSystemCUPS* print_system) | 171 explicit PrintServerWatcherCUPS(PrintSystemCUPS* print_system) |
172 : print_system_(print_system), | 172 : print_system_(print_system), |
173 delegate_(NULL) { | 173 delegate_(NULL) { |
174 } | 174 } |
175 ~PrintServerWatcherCUPS() { | 175 ~PrintServerWatcherCUPS() { |
176 StopWatching(); | 176 StopWatching(); |
177 } | 177 } |
178 | 178 |
179 // PrintSystem::PrintServerWatcher implementation. | 179 // PrintSystem::PrintServerWatcher implementation. |
180 virtual bool StartWatching( | 180 virtual bool StartWatching( |
181 PrintSystem::PrintServerWatcher::Delegate* delegate) OVERRIDE { | 181 PrintSystem::PrintServerWatcher::Delegate* delegate) OVERRIDE { |
182 delegate_ = delegate; | 182 delegate_ = delegate; |
183 printers_hash_ = GetPrintersHash(); | 183 printers_hash_ = GetPrintersHash(); |
184 MessageLoop::current()->PostDelayedTask( | 184 MessageLoop::current()->PostDelayedTask( |
185 FROM_HERE, | 185 FROM_HERE, |
186 base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), | 186 base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), |
187 print_system_->GetUpdateTimeoutMs()); | 187 print_system_->GetUpdateTimeout()); |
188 return true; | 188 return true; |
189 } | 189 } |
190 | 190 |
191 virtual bool StopWatching() OVERRIDE { | 191 virtual bool StopWatching() OVERRIDE { |
192 delegate_ = NULL; | 192 delegate_ = NULL; |
193 return true; | 193 return true; |
194 } | 194 } |
195 | 195 |
196 void CheckForUpdates() { | 196 void CheckForUpdates() { |
197 if (delegate_ == NULL) | 197 if (delegate_ == NULL) |
198 return; // Orphan call. We have been stopped already. | 198 return; // Orphan call. We have been stopped already. |
199 VLOG(1) << "CP_CUPS: Checking for new printers"; | 199 VLOG(1) << "CP_CUPS: Checking for new printers"; |
200 std::string new_hash = GetPrintersHash(); | 200 std::string new_hash = GetPrintersHash(); |
201 if (printers_hash_ != new_hash) { | 201 if (printers_hash_ != new_hash) { |
202 printers_hash_ = new_hash; | 202 printers_hash_ = new_hash; |
203 delegate_->OnPrinterAdded(); | 203 delegate_->OnPrinterAdded(); |
204 } | 204 } |
205 MessageLoop::current()->PostDelayedTask( | 205 MessageLoop::current()->PostDelayedTask( |
206 FROM_HERE, | 206 FROM_HERE, |
207 base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), | 207 base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), |
208 print_system_->GetUpdateTimeoutMs()); | 208 print_system_->GetUpdateTimeout()); |
209 } | 209 } |
210 | 210 |
211 private: | 211 private: |
212 std::string GetPrintersHash() { | 212 std::string GetPrintersHash() { |
213 printing::PrinterList printer_list; | 213 printing::PrinterList printer_list; |
214 print_system_->EnumeratePrinters(&printer_list); | 214 print_system_->EnumeratePrinters(&printer_list); |
215 | 215 |
216 // Sort printer names. | 216 // Sort printer names. |
217 std::vector<std::string> printers; | 217 std::vector<std::string> printers; |
218 printing::PrinterList::iterator it; | 218 printing::PrinterList::iterator it; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 virtual bool StartWatching( | 252 virtual bool StartWatching( |
253 PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE{ | 253 PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE{ |
254 if (delegate_ != NULL) | 254 if (delegate_ != NULL) |
255 StopWatching(); | 255 StopWatching(); |
256 delegate_ = delegate; | 256 delegate_ = delegate; |
257 settings_hash_ = GetSettingsHash(); | 257 settings_hash_ = GetSettingsHash(); |
258 // Schedule next job status update. | 258 // Schedule next job status update. |
259 MessageLoop::current()->PostDelayedTask( | 259 MessageLoop::current()->PostDelayedTask( |
260 FROM_HERE, | 260 FROM_HERE, |
261 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | 261 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), |
262 kJobUpdateTimeoutMs); | 262 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); |
263 // Schedule next printer check. | 263 // Schedule next printer check. |
264 // TODO(gene): Randomize time for the next printer update. | 264 // TODO(gene): Randomize time for the next printer update. |
265 MessageLoop::current()->PostDelayedTask( | 265 MessageLoop::current()->PostDelayedTask( |
266 FROM_HERE, | 266 FROM_HERE, |
267 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | 267 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), |
268 print_system_->GetUpdateTimeoutMs()); | 268 print_system_->GetUpdateTimeout()); |
269 return true; | 269 return true; |
270 } | 270 } |
271 | 271 |
272 virtual bool StopWatching() OVERRIDE{ | 272 virtual bool StopWatching() OVERRIDE{ |
273 delegate_ = NULL; | 273 delegate_ = NULL; |
274 return true; | 274 return true; |
275 } | 275 } |
276 | 276 |
277 bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) { | 277 bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) { |
278 DCHECK(printer_info); | 278 DCHECK(printer_info); |
279 return print_system_->GetPrinterInfo(printer_name_, printer_info); | 279 return print_system_->GetPrinterInfo(printer_name_, printer_info); |
280 } | 280 } |
281 | 281 |
282 void JobStatusUpdate() { | 282 void JobStatusUpdate() { |
283 if (delegate_ == NULL) | 283 if (delegate_ == NULL) |
284 return; // Orphan call. We have been stopped already. | 284 return; // Orphan call. We have been stopped already. |
285 // For CUPS proxy, we are going to fire OnJobChanged notification | 285 // For CUPS proxy, we are going to fire OnJobChanged notification |
286 // periodically. Higher level will check if there are any outstanding | 286 // periodically. Higher level will check if there are any outstanding |
287 // jobs for this printer and check their status. If printer has no | 287 // jobs for this printer and check their status. If printer has no |
288 // outstanding jobs, OnJobChanged() will do nothing. | 288 // outstanding jobs, OnJobChanged() will do nothing. |
289 delegate_->OnJobChanged(); | 289 delegate_->OnJobChanged(); |
290 MessageLoop::current()->PostDelayedTask( | 290 MessageLoop::current()->PostDelayedTask( |
291 FROM_HERE, | 291 FROM_HERE, |
292 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | 292 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), |
293 kJobUpdateTimeoutMs); | 293 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); |
294 } | 294 } |
295 | 295 |
296 void PrinterUpdate() { | 296 void PrinterUpdate() { |
297 if (delegate_ == NULL) | 297 if (delegate_ == NULL) |
298 return; // Orphan call. We have been stopped already. | 298 return; // Orphan call. We have been stopped already. |
299 VLOG(1) << "CP_CUPS: Checking for printer updates: " << printer_name_; | 299 VLOG(1) << "CP_CUPS: Checking for printer updates: " << printer_name_; |
300 if (print_system_->NotifyDelete() && | 300 if (print_system_->NotifyDelete() && |
301 !print_system_->IsValidPrinter(printer_name_)) { | 301 !print_system_->IsValidPrinter(printer_name_)) { |
302 delegate_->OnPrinterDeleted(); | 302 delegate_->OnPrinterDeleted(); |
303 VLOG(1) << "CP_CUPS: Printer deleted: " << printer_name_; | 303 VLOG(1) << "CP_CUPS: Printer deleted: " << printer_name_; |
304 } else { | 304 } else { |
305 std::string new_hash = GetSettingsHash(); | 305 std::string new_hash = GetSettingsHash(); |
306 if (settings_hash_ != new_hash) { | 306 if (settings_hash_ != new_hash) { |
307 settings_hash_ = new_hash; | 307 settings_hash_ = new_hash; |
308 delegate_->OnPrinterChanged(); | 308 delegate_->OnPrinterChanged(); |
309 VLOG(1) << "CP_CUPS: Printer update detected for: " << printer_name_; | 309 VLOG(1) << "CP_CUPS: Printer update detected for: " << printer_name_; |
310 } | 310 } |
311 } | 311 } |
312 MessageLoop::current()->PostDelayedTask( | 312 MessageLoop::current()->PostDelayedTask( |
313 FROM_HERE, | 313 FROM_HERE, |
314 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | 314 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), |
315 print_system_->GetUpdateTimeoutMs()); | 315 print_system_->GetUpdateTimeout()); |
316 } | 316 } |
317 | 317 |
318 private: | 318 private: |
319 std::string GetSettingsHash() { | 319 std::string GetSettingsHash() { |
320 printing::PrinterBasicInfo info; | 320 printing::PrinterBasicInfo info; |
321 if (!print_system_->GetPrinterInfo(printer_name_, &info)) | 321 if (!print_system_->GetPrinterInfo(printer_name_, &info)) |
322 return std::string(); | 322 return std::string(); |
323 | 323 |
324 printing::PrinterCapsAndDefaults caps; | 324 printing::PrinterCapsAndDefaults caps; |
325 if (!print_system_->GetPrinterCapsAndDefaults(printer_name_, &caps)) | 325 if (!print_system_->GetPrinterCapsAndDefaults(printer_name_, &caps)) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 delegate->OnJobSpoolFailed(); | 383 delegate->OnJobSpoolFailed(); |
384 } | 384 } |
385 | 385 |
386 private: | 386 private: |
387 scoped_refptr<PrintSystemCUPS> print_system_; | 387 scoped_refptr<PrintSystemCUPS> print_system_; |
388 | 388 |
389 DISALLOW_COPY_AND_ASSIGN(JobSpoolerCUPS); | 389 DISALLOW_COPY_AND_ASSIGN(JobSpoolerCUPS); |
390 }; | 390 }; |
391 | 391 |
392 PrintSystemCUPS::PrintSystemCUPS(const DictionaryValue* print_system_settings) | 392 PrintSystemCUPS::PrintSystemCUPS(const DictionaryValue* print_system_settings) |
393 : update_timeout_(kCheckForPrinterUpdatesMs), | 393 : update_timeout_(base::TimeDelta::FromMinutes( |
| 394 kCheckForPrinterUpdatesMinutes)), |
394 initialized_(false), | 395 initialized_(false), |
395 printer_enum_succeeded_(false), | 396 printer_enum_succeeded_(false), |
396 notify_delete_(true) { | 397 notify_delete_(true) { |
397 if (print_system_settings) { | 398 if (print_system_settings) { |
398 int timeout; | 399 int timeout; |
399 if (print_system_settings->GetInteger(kCUPSUpdateTimeoutMs, &timeout)) | 400 if (print_system_settings->GetInteger(kCUPSUpdateTimeoutMs, &timeout)) |
400 update_timeout_ = timeout; | 401 update_timeout_ = base::TimeDelta::FromMilliseconds(timeout); |
401 | 402 |
402 bool notify_delete = true; | 403 bool notify_delete = true; |
403 if (print_system_settings->GetBoolean(kCUPSNotifyDelete, ¬ify_delete)) | 404 if (print_system_settings->GetBoolean(kCUPSNotifyDelete, ¬ify_delete)) |
404 notify_delete_ = notify_delete; | 405 notify_delete_ = notify_delete; |
405 } | 406 } |
406 | 407 |
407 InitPrintBackends(print_system_settings); | 408 InitPrintBackends(print_system_settings); |
408 } | 409 } |
409 | 410 |
410 void PrintSystemCUPS::InitPrintBackends( | 411 void PrintSystemCUPS::InitPrintBackends( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 printer_it->printer_name = MakeFullPrinterName(it->url, | 463 printer_it->printer_name = MakeFullPrinterName(it->url, |
463 printer_it->printer_name); | 464 printer_it->printer_name); |
464 } | 465 } |
465 VLOG(1) << "CUPS: Updated printer list for url: " << it->url | 466 VLOG(1) << "CUPS: Updated printer list for url: " << it->url |
466 << " Number of printers: " << it->printers.size(); | 467 << " Number of printers: " << it->printers.size(); |
467 } | 468 } |
468 | 469 |
469 // Schedule next update. | 470 // Schedule next update. |
470 MessageLoop::current()->PostDelayedTask( | 471 MessageLoop::current()->PostDelayedTask( |
471 FROM_HERE, | 472 FROM_HERE, |
472 base::Bind(&PrintSystemCUPS::UpdatePrinters, this), GetUpdateTimeoutMs()); | 473 base::Bind(&PrintSystemCUPS::UpdatePrinters, this), GetUpdateTimeout()); |
473 } | 474 } |
474 | 475 |
475 PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( | 476 PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( |
476 printing::PrinterList* printer_list) { | 477 printing::PrinterList* printer_list) { |
477 DCHECK(initialized_); | 478 DCHECK(initialized_); |
478 printer_list->clear(); | 479 printer_list->clear(); |
479 PrintServerList::iterator it; | 480 PrintServerList::iterator it; |
480 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { | 481 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { |
481 printer_list->insert(printer_list->end(), | 482 printer_list->insert(printer_list->end(), |
482 it->printers.begin(), it->printers.end()); | 483 it->printers.begin(), it->printers.end()); |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 | 818 |
818 void PrintSystemCUPS::RunCapsCallback( | 819 void PrintSystemCUPS::RunCapsCallback( |
819 const PrinterCapsAndDefaultsCallback& callback, | 820 const PrinterCapsAndDefaultsCallback& callback, |
820 bool succeeded, | 821 bool succeeded, |
821 const std::string& printer_name, | 822 const std::string& printer_name, |
822 const printing::PrinterCapsAndDefaults& printer_info) { | 823 const printing::PrinterCapsAndDefaults& printer_info) { |
823 callback.Run(succeeded, printer_name, printer_info); | 824 callback.Run(succeeded, printer_name, printer_info); |
824 } | 825 } |
825 | 826 |
826 } // namespace cloud_print | 827 } // namespace cloud_print |
OLD | NEW |