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