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