| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 |
| 12 #include <algorithm> | 12 #include <algorithm> |
| 13 #include <list> | 13 #include <list> |
| 14 #include <map> | 14 #include <map> |
| 15 | 15 |
| 16 #include "base/bind.h" | 16 #include "base/bind.h" |
| 17 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
| 18 #include "base/json/json_reader.h" | 18 #include "base/json/json_reader.h" |
| 19 #include "base/location.h" |
| 19 #include "base/logging.h" | 20 #include "base/logging.h" |
| 20 #include "base/md5.h" | 21 #include "base/md5.h" |
| 21 #include "base/memory/scoped_ptr.h" | 22 #include "base/memory/scoped_ptr.h" |
| 22 #include "base/message_loop/message_loop.h" | |
| 23 #include "base/rand_util.h" | 23 #include "base/rand_util.h" |
| 24 #include "base/single_thread_task_runner.h" |
| 24 #include "base/strings/string_number_conversions.h" | 25 #include "base/strings/string_number_conversions.h" |
| 25 #include "base/strings/string_util.h" | 26 #include "base/strings/string_util.h" |
| 26 #include "base/strings/utf_string_conversions.h" | 27 #include "base/strings/utf_string_conversions.h" |
| 28 #include "base/thread_task_runner_handle.h" |
| 27 #include "base/values.h" | 29 #include "base/values.h" |
| 28 #include "chrome/common/cloud_print/cloud_print_constants.h" | 30 #include "chrome/common/cloud_print/cloud_print_constants.h" |
| 29 #include "chrome/common/crash_keys.h" | 31 #include "chrome/common/crash_keys.h" |
| 30 #include "chrome/service/cloud_print/cloud_print_service_helpers.h" | 32 #include "chrome/service/cloud_print/cloud_print_service_helpers.h" |
| 31 #include "printing/backend/cups_helper.h" | 33 #include "printing/backend/cups_helper.h" |
| 32 #include "printing/backend/print_backend.h" | 34 #include "printing/backend/print_backend.h" |
| 33 #include "printing/backend/print_backend_consts.h" | 35 #include "printing/backend/print_backend_consts.h" |
| 34 #include "url/gurl.h" | 36 #include "url/gurl.h" |
| 35 | 37 |
| 36 namespace { | 38 namespace { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 explicit PrintServerWatcherCUPS(PrintSystemCUPS* print_system) | 178 explicit PrintServerWatcherCUPS(PrintSystemCUPS* print_system) |
| 177 : print_system_(print_system), | 179 : print_system_(print_system), |
| 178 delegate_(NULL) { | 180 delegate_(NULL) { |
| 179 } | 181 } |
| 180 | 182 |
| 181 // PrintSystem::PrintServerWatcher implementation. | 183 // PrintSystem::PrintServerWatcher implementation. |
| 182 bool StartWatching( | 184 bool StartWatching( |
| 183 PrintSystem::PrintServerWatcher::Delegate* delegate) override { | 185 PrintSystem::PrintServerWatcher::Delegate* delegate) override { |
| 184 delegate_ = delegate; | 186 delegate_ = delegate; |
| 185 printers_hash_ = GetPrintersHash(); | 187 printers_hash_ = GetPrintersHash(); |
| 186 base::MessageLoop::current()->PostDelayedTask( | 188 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 187 FROM_HERE, | 189 FROM_HERE, base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), |
| 188 base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), | |
| 189 print_system_->GetUpdateTimeout()); | 190 print_system_->GetUpdateTimeout()); |
| 190 return true; | 191 return true; |
| 191 } | 192 } |
| 192 | 193 |
| 193 bool StopWatching() override { | 194 bool StopWatching() override { |
| 194 delegate_ = NULL; | 195 delegate_ = NULL; |
| 195 return true; | 196 return true; |
| 196 } | 197 } |
| 197 | 198 |
| 198 void CheckForUpdates() { | 199 void CheckForUpdates() { |
| 199 if (delegate_ == NULL) | 200 if (delegate_ == NULL) |
| 200 return; // Orphan call. We have been stopped already. | 201 return; // Orphan call. We have been stopped already. |
| 201 VLOG(1) << "CP_CUPS: Checking for new printers"; | 202 VLOG(1) << "CP_CUPS: Checking for new printers"; |
| 202 std::string new_hash = GetPrintersHash(); | 203 std::string new_hash = GetPrintersHash(); |
| 203 if (printers_hash_ != new_hash) { | 204 if (printers_hash_ != new_hash) { |
| 204 printers_hash_ = new_hash; | 205 printers_hash_ = new_hash; |
| 205 delegate_->OnPrinterAdded(); | 206 delegate_->OnPrinterAdded(); |
| 206 } | 207 } |
| 207 base::MessageLoop::current()->PostDelayedTask( | 208 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 208 FROM_HERE, | 209 FROM_HERE, base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), |
| 209 base::Bind(&PrintServerWatcherCUPS::CheckForUpdates, this), | |
| 210 print_system_->GetUpdateTimeout()); | 210 print_system_->GetUpdateTimeout()); |
| 211 } | 211 } |
| 212 | 212 |
| 213 protected: | 213 protected: |
| 214 ~PrintServerWatcherCUPS() override { StopWatching(); } | 214 ~PrintServerWatcherCUPS() override { StopWatching(); } |
| 215 | 215 |
| 216 private: | 216 private: |
| 217 std::string GetPrintersHash() { | 217 std::string GetPrintersHash() { |
| 218 printing::PrinterList printer_list; | 218 printing::PrinterList printer_list; |
| 219 print_system_->EnumeratePrinters(&printer_list); | 219 print_system_->EnumeratePrinters(&printer_list); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 bool StartWatching(PrintSystem::PrinterWatcher::Delegate* delegate) override { | 253 bool StartWatching(PrintSystem::PrinterWatcher::Delegate* delegate) override { |
| 254 scoped_refptr<printing::PrintBackend> print_backend( | 254 scoped_refptr<printing::PrintBackend> print_backend( |
| 255 printing::PrintBackend::CreateInstance(NULL)); | 255 printing::PrintBackend::CreateInstance(NULL)); |
| 256 crash_keys::ScopedPrinterInfo crash_key( | 256 crash_keys::ScopedPrinterInfo crash_key( |
| 257 print_backend->GetPrinterDriverInfo(printer_name_)); | 257 print_backend->GetPrinterDriverInfo(printer_name_)); |
| 258 if (delegate_ != NULL) | 258 if (delegate_ != NULL) |
| 259 StopWatching(); | 259 StopWatching(); |
| 260 delegate_ = delegate; | 260 delegate_ = delegate; |
| 261 settings_hash_ = GetSettingsHash(); | 261 settings_hash_ = GetSettingsHash(); |
| 262 // Schedule next job status update. | 262 // Schedule next job status update. |
| 263 base::MessageLoop::current()->PostDelayedTask( | 263 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 264 FROM_HERE, | 264 FROM_HERE, base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), |
| 265 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | |
| 266 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); | 265 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); |
| 267 // Schedule next printer check. | 266 // Schedule next printer check. |
| 268 // TODO(gene): Randomize time for the next printer update. | 267 // TODO(gene): Randomize time for the next printer update. |
| 269 base::MessageLoop::current()->PostDelayedTask( | 268 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 270 FROM_HERE, | 269 FROM_HERE, base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), |
| 271 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | |
| 272 print_system_->GetUpdateTimeout()); | 270 print_system_->GetUpdateTimeout()); |
| 273 return true; | 271 return true; |
| 274 } | 272 } |
| 275 | 273 |
| 276 bool StopWatching() override { | 274 bool StopWatching() override { |
| 277 delegate_ = NULL; | 275 delegate_ = NULL; |
| 278 return true; | 276 return true; |
| 279 } | 277 } |
| 280 | 278 |
| 281 bool GetCurrentPrinterInfo( | 279 bool GetCurrentPrinterInfo( |
| 282 printing::PrinterBasicInfo* printer_info) override { | 280 printing::PrinterBasicInfo* printer_info) override { |
| 283 DCHECK(printer_info); | 281 DCHECK(printer_info); |
| 284 return print_system_->GetPrinterInfo(printer_name_, printer_info); | 282 return print_system_->GetPrinterInfo(printer_name_, printer_info); |
| 285 } | 283 } |
| 286 | 284 |
| 287 void JobStatusUpdate() { | 285 void JobStatusUpdate() { |
| 288 if (delegate_ == NULL) | 286 if (delegate_ == NULL) |
| 289 return; // Orphan call. We have been stopped already. | 287 return; // Orphan call. We have been stopped already. |
| 290 // For CUPS proxy, we are going to fire OnJobChanged notification | 288 // For CUPS proxy, we are going to fire OnJobChanged notification |
| 291 // periodically. Higher level will check if there are any outstanding | 289 // periodically. Higher level will check if there are any outstanding |
| 292 // jobs for this printer and check their status. If printer has no | 290 // jobs for this printer and check their status. If printer has no |
| 293 // outstanding jobs, OnJobChanged() will do nothing. | 291 // outstanding jobs, OnJobChanged() will do nothing. |
| 294 delegate_->OnJobChanged(); | 292 delegate_->OnJobChanged(); |
| 295 base::MessageLoop::current()->PostDelayedTask( | 293 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 296 FROM_HERE, | 294 FROM_HERE, base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), |
| 297 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | |
| 298 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); | 295 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); |
| 299 } | 296 } |
| 300 | 297 |
| 301 void PrinterUpdate() { | 298 void PrinterUpdate() { |
| 302 if (delegate_ == NULL) | 299 if (delegate_ == NULL) |
| 303 return; // Orphan call. We have been stopped already. | 300 return; // Orphan call. We have been stopped already. |
| 304 VLOG(1) << "CP_CUPS: Checking for updates" | 301 VLOG(1) << "CP_CUPS: Checking for updates" |
| 305 << ", printer name: " << printer_name_; | 302 << ", printer name: " << printer_name_; |
| 306 if (print_system_->NotifyDelete() && | 303 if (print_system_->NotifyDelete() && |
| 307 !print_system_->IsValidPrinter(printer_name_)) { | 304 !print_system_->IsValidPrinter(printer_name_)) { |
| 308 delegate_->OnPrinterDeleted(); | 305 delegate_->OnPrinterDeleted(); |
| 309 VLOG(1) << "CP_CUPS: Printer deleted" | 306 VLOG(1) << "CP_CUPS: Printer deleted" |
| 310 << ", printer name: " << printer_name_; | 307 << ", printer name: " << printer_name_; |
| 311 } else { | 308 } else { |
| 312 std::string new_hash = GetSettingsHash(); | 309 std::string new_hash = GetSettingsHash(); |
| 313 if (settings_hash_ != new_hash) { | 310 if (settings_hash_ != new_hash) { |
| 314 settings_hash_ = new_hash; | 311 settings_hash_ = new_hash; |
| 315 delegate_->OnPrinterChanged(); | 312 delegate_->OnPrinterChanged(); |
| 316 VLOG(1) << "CP_CUPS: Printer configuration changed" | 313 VLOG(1) << "CP_CUPS: Printer configuration changed" |
| 317 << ", printer name: " << printer_name_; | 314 << ", printer name: " << printer_name_; |
| 318 } | 315 } |
| 319 } | 316 } |
| 320 base::MessageLoop::current()->PostDelayedTask( | 317 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 321 FROM_HERE, | 318 FROM_HERE, base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), |
| 322 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | |
| 323 print_system_->GetUpdateTimeout()); | 319 print_system_->GetUpdateTimeout()); |
| 324 } | 320 } |
| 325 | 321 |
| 326 protected: | 322 protected: |
| 327 ~PrinterWatcherCUPS() override { StopWatching(); } | 323 ~PrinterWatcherCUPS() override { StopWatching(); } |
| 328 | 324 |
| 329 private: | 325 private: |
| 330 std::string GetSettingsHash() { | 326 std::string GetSettingsHash() { |
| 331 printing::PrinterBasicInfo info; | 327 printing::PrinterBasicInfo info; |
| 332 if (!print_system_->GetPrinterInfo(printer_name_, &info)) | 328 if (!print_system_->GetPrinterInfo(printer_name_, &info)) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 const std::string& print_data_mime_type, | 369 const std::string& print_data_mime_type, |
| 374 const std::string& printer_name, | 370 const std::string& printer_name, |
| 375 const std::string& job_title, | 371 const std::string& job_title, |
| 376 const std::vector<std::string>& tags, | 372 const std::vector<std::string>& tags, |
| 377 JobSpooler::Delegate* delegate) override { | 373 JobSpooler::Delegate* delegate) override { |
| 378 DCHECK(delegate); | 374 DCHECK(delegate); |
| 379 bool dry_run = false; | 375 bool dry_run = false; |
| 380 int job_id = print_system_->SpoolPrintJob( | 376 int job_id = print_system_->SpoolPrintJob( |
| 381 print_ticket, print_data_file_path, print_data_mime_type, | 377 print_ticket, print_data_file_path, print_data_mime_type, |
| 382 printer_name, job_title, tags, &dry_run); | 378 printer_name, job_title, tags, &dry_run); |
| 383 base::MessageLoop::current()->PostTask( | 379 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 384 FROM_HERE, | 380 FROM_HERE, |
| 385 base::Bind(&JobSpoolerCUPS::NotifyDelegate, delegate, job_id, dry_run)); | 381 base::Bind(&JobSpoolerCUPS::NotifyDelegate, delegate, job_id, dry_run)); |
| 386 return true; | 382 return true; |
| 387 } | 383 } |
| 388 | 384 |
| 389 static void NotifyDelegate(JobSpooler::Delegate* delegate, | 385 static void NotifyDelegate(JobSpooler::Delegate* delegate, |
| 390 int job_id, bool dry_run) { | 386 int job_id, bool dry_run) { |
| 391 if (dry_run || job_id) | 387 if (dry_run || job_id) |
| 392 delegate->OnJobSpoolSucceeded(job_id); | 388 delegate->OnJobSpoolSucceeded(job_id); |
| 393 else | 389 else |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 printer_it != it->printers.end(); ++printer_it) { | 487 printer_it != it->printers.end(); ++printer_it) { |
| 492 printer_it->printer_name = MakeFullPrinterName(it->url, | 488 printer_it->printer_name = MakeFullPrinterName(it->url, |
| 493 printer_it->printer_name); | 489 printer_it->printer_name); |
| 494 } | 490 } |
| 495 VLOG(1) << "CP_CUPS: Updated printers list" | 491 VLOG(1) << "CP_CUPS: Updated printers list" |
| 496 << ", server: " << it->url | 492 << ", server: " << it->url |
| 497 << ", # of printers: " << it->printers.size(); | 493 << ", # of printers: " << it->printers.size(); |
| 498 } | 494 } |
| 499 | 495 |
| 500 // Schedule next update. | 496 // Schedule next update. |
| 501 base::MessageLoop::current()->PostDelayedTask( | 497 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 502 FROM_HERE, | 498 FROM_HERE, base::Bind(&PrintSystemCUPS::UpdatePrinters, this), |
| 503 base::Bind(&PrintSystemCUPS::UpdatePrinters, this), | |
| 504 GetUpdateTimeout()); | 499 GetUpdateTimeout()); |
| 505 } | 500 } |
| 506 | 501 |
| 507 PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( | 502 PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( |
| 508 printing::PrinterList* printer_list) { | 503 printing::PrinterList* printer_list) { |
| 509 DCHECK(initialized_); | 504 DCHECK(initialized_); |
| 510 printer_list->clear(); | 505 printer_list->clear(); |
| 511 PrintServerList::iterator it; | 506 PrintServerList::iterator it; |
| 512 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { | 507 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { |
| 513 printer_list->insert(printer_list->end(), | 508 printer_list->insert(printer_list->end(), |
| 514 it->printers.begin(), it->printers.end()); | 509 it->printers.begin(), it->printers.end()); |
| 515 } | 510 } |
| 516 VLOG(1) << "CP_CUPS: Total printers enumerated: " << printer_list->size(); | 511 VLOG(1) << "CP_CUPS: Total printers enumerated: " << printer_list->size(); |
| 517 // TODO(sanjeevr): Maybe some day we want to report the actual server names | 512 // TODO(sanjeevr): Maybe some day we want to report the actual server names |
| 518 // for which the enumeration failed. | 513 // for which the enumeration failed. |
| 519 return PrintSystemResult(printer_enum_succeeded_, std::string()); | 514 return PrintSystemResult(printer_enum_succeeded_, std::string()); |
| 520 } | 515 } |
| 521 | 516 |
| 522 void PrintSystemCUPS::GetPrinterCapsAndDefaults( | 517 void PrintSystemCUPS::GetPrinterCapsAndDefaults( |
| 523 const std::string& printer_name, | 518 const std::string& printer_name, |
| 524 const PrinterCapsAndDefaultsCallback& callback) { | 519 const PrinterCapsAndDefaultsCallback& callback) { |
| 525 printing::PrinterCapsAndDefaults printer_info; | 520 printing::PrinterCapsAndDefaults printer_info; |
| 526 bool succeeded = GetPrinterCapsAndDefaults(printer_name, &printer_info); | 521 bool succeeded = GetPrinterCapsAndDefaults(printer_name, &printer_info); |
| 527 base::MessageLoop::current()->PostTask( | 522 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 528 FROM_HERE, | 523 FROM_HERE, base::Bind(&PrintSystemCUPS::RunCapsCallback, callback, |
| 529 base::Bind(&PrintSystemCUPS::RunCapsCallback, | 524 succeeded, printer_name, printer_info)); |
| 530 callback, | |
| 531 succeeded, | |
| 532 printer_name, | |
| 533 printer_info)); | |
| 534 } | 525 } |
| 535 | 526 |
| 536 bool PrintSystemCUPS::IsValidPrinter(const std::string& printer_name) { | 527 bool PrintSystemCUPS::IsValidPrinter(const std::string& printer_name) { |
| 537 return GetPrinterInfo(printer_name, NULL); | 528 return GetPrinterInfo(printer_name, NULL); |
| 538 } | 529 } |
| 539 | 530 |
| 540 bool PrintSystemCUPS::ValidatePrintTicket( | 531 bool PrintSystemCUPS::ValidatePrintTicket( |
| 541 const std::string& printer_name, | 532 const std::string& printer_name, |
| 542 const std::string& print_ticket_data, | 533 const std::string& print_ticket_data, |
| 543 const std::string& print_ticket_mime_type) { | 534 const std::string& print_ticket_mime_type) { |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 | 857 |
| 867 void PrintSystemCUPS::RunCapsCallback( | 858 void PrintSystemCUPS::RunCapsCallback( |
| 868 const PrinterCapsAndDefaultsCallback& callback, | 859 const PrinterCapsAndDefaultsCallback& callback, |
| 869 bool succeeded, | 860 bool succeeded, |
| 870 const std::string& printer_name, | 861 const std::string& printer_name, |
| 871 const printing::PrinterCapsAndDefaults& printer_info) { | 862 const printing::PrinterCapsAndDefaults& printer_info) { |
| 872 callback.Run(succeeded, printer_name, printer_info); | 863 callback.Run(succeeded, printer_name, printer_info); |
| 873 } | 864 } |
| 874 | 865 |
| 875 } // namespace cloud_print | 866 } // namespace cloud_print |
| OLD | NEW |