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> |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
233 | 233 |
234 DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherCUPS); | 234 DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherCUPS); |
235 }; | 235 }; |
236 | 236 |
237 class PrinterWatcherCUPS | 237 class PrinterWatcherCUPS |
238 : public PrintSystem::PrinterWatcher { | 238 : public PrintSystem::PrinterWatcher { |
239 public: | 239 public: |
240 PrinterWatcherCUPS(PrintSystemCUPS* print_system, | 240 PrinterWatcherCUPS(PrintSystemCUPS* print_system, |
241 const std::string& printer_name) | 241 const std::string& printer_name) |
242 : printer_name_(printer_name), | 242 : printer_name_(printer_name), |
243 delegate_(NULL), | 243 delegate_(NULL), |
Albert Bodenhamer
2012/03/13 23:57:39
why is this changed?
Vitaly Buka (NO REVIEWS)
2012/03/14 00:11:20
It was attempt to fix style, but still incorrectly
| |
244 print_system_(print_system) { | 244 print_system_(print_system) { |
245 } | 245 } |
246 | 246 |
247 ~PrinterWatcherCUPS() { | 247 ~PrinterWatcherCUPS() { |
248 StopWatching(); | 248 StopWatching(); |
249 } | 249 } |
250 | 250 |
251 // PrintSystem::PrinterWatcher implementation. | 251 // PrintSystem::PrinterWatcher implementation. |
252 virtual bool StartWatching( | 252 virtual bool StartWatching( |
253 PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE{ | 253 PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE{ |
254 scoped_refptr<printing::PrintBackend> print_backend( | |
255 printing::PrintBackend::CreateInstance(NULL)); | |
256 child_process_logging::ScopedPrinterInfoSetter prn_info( | |
257 print_backend->GetPrinterDriverInfo(printer_name)); | |
254 if (delegate_ != NULL) | 258 if (delegate_ != NULL) |
255 StopWatching(); | 259 StopWatching(); |
256 delegate_ = delegate; | 260 delegate_ = delegate; |
257 settings_hash_ = GetSettingsHash(); | 261 settings_hash_ = GetSettingsHash(); |
258 // Schedule next job status update. | 262 // Schedule next job status update. |
259 MessageLoop::current()->PostDelayedTask( | 263 MessageLoop::current()->PostDelayedTask( |
260 FROM_HERE, | 264 FROM_HERE, |
261 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | 265 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), |
262 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); | 266 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); |
263 // Schedule next printer check. | 267 // Schedule next printer check. |
264 // TODO(gene): Randomize time for the next printer update. | 268 // TODO(gene): Randomize time for the next printer update. |
265 MessageLoop::current()->PostDelayedTask( | 269 MessageLoop::current()->PostDelayedTask( |
266 FROM_HERE, | 270 FROM_HERE, |
267 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | 271 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), |
268 print_system_->GetUpdateTimeout()); | 272 print_system_->GetUpdateTimeout()); |
269 return true; | 273 return true; |
270 } | 274 } |
271 | 275 |
272 virtual bool StopWatching() OVERRIDE{ | 276 virtual bool StopWatching() OVERRIDE{ |
273 delegate_ = NULL; | 277 delegate_ = NULL; |
274 return true; | 278 return true; |
275 } | 279 } |
276 | 280 |
277 bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) { | 281 bool GetCurrentPrinterInfo(printing::PrinterBasicInfo* printer_info) { |
278 DCHECK(printer_info); | 282 DCHECK(printer_info); |
279 return print_system_->GetPrinterInfo(printer_name_, printer_info); | 283 return print_system_->GetPrinterInfo(printer_name_, printer_info); |
280 } | 284 } |
281 | 285 |
282 void JobStatusUpdate() { | |
283 if (delegate_ == NULL) | |
284 return; // Orphan call. We have been stopped already. | |
285 // For CUPS proxy, we are going to fire OnJobChanged notification | |
286 // periodically. Higher level will check if there are any outstanding | |
287 // jobs for this printer and check their status. If printer has no | |
288 // outstanding jobs, OnJobChanged() will do nothing. | |
289 delegate_->OnJobChanged(); | |
290 MessageLoop::current()->PostDelayedTask( | |
291 FROM_HERE, | |
292 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | |
293 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); | |
294 } | |
295 | |
296 void PrinterUpdate() { | |
297 if (delegate_ == NULL) | |
298 return; // Orphan call. We have been stopped already. | |
299 VLOG(1) << "CP_CUPS: Checking for printer updates: " << printer_name_; | |
300 if (print_system_->NotifyDelete() && | |
301 !print_system_->IsValidPrinter(printer_name_)) { | |
302 delegate_->OnPrinterDeleted(); | |
303 VLOG(1) << "CP_CUPS: Printer deleted: " << printer_name_; | |
304 } else { | |
305 std::string new_hash = GetSettingsHash(); | |
306 if (settings_hash_ != new_hash) { | |
307 settings_hash_ = new_hash; | |
308 delegate_->OnPrinterChanged(); | |
309 VLOG(1) << "CP_CUPS: Printer update detected for: " << printer_name_; | |
310 } | |
311 } | |
312 MessageLoop::current()->PostDelayedTask( | |
313 FROM_HERE, | |
314 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | |
315 print_system_->GetUpdateTimeout()); | |
316 } | |
317 | |
318 private: | 286 private: |
319 std::string GetSettingsHash() { | 287 std::string GetSettingsHash() { |
320 printing::PrinterBasicInfo info; | 288 printing::PrinterBasicInfo info; |
321 if (!print_system_->GetPrinterInfo(printer_name_, &info)) | 289 if (!print_system_->GetPrinterInfo(printer_name_, &info)) |
322 return std::string(); | 290 return std::string(); |
323 | 291 |
324 printing::PrinterCapsAndDefaults caps; | 292 printing::PrinterCapsAndDefaults caps; |
325 if (!print_system_->GetPrinterCapsAndDefaults(printer_name_, &caps)) | 293 if (!print_system_->GetPrinterCapsAndDefaults(printer_name_, &caps)) |
326 return std::string(); | 294 return std::string(); |
327 | 295 |
328 std::string to_hash(info.printer_name); | 296 std::string to_hash(info.printer_name); |
329 to_hash += info.printer_description; | 297 to_hash += info.printer_description; |
330 std::map<std::string, std::string>::const_iterator it; | 298 std::map<std::string, std::string>::const_iterator it; |
331 for (it = info.options.begin(); it != info.options.end(); ++it) { | 299 for (it = info.options.begin(); it != info.options.end(); ++it) { |
332 to_hash += it->first; | 300 to_hash += it->first; |
333 to_hash += it->second; | 301 to_hash += it->second; |
334 } | 302 } |
335 | 303 |
336 to_hash += caps.printer_capabilities; | 304 to_hash += caps.printer_capabilities; |
337 to_hash += caps.caps_mime_type; | 305 to_hash += caps.caps_mime_type; |
338 to_hash += caps.printer_defaults; | 306 to_hash += caps.printer_defaults; |
339 to_hash += caps.defaults_mime_type; | 307 to_hash += caps.defaults_mime_type; |
340 | 308 |
341 return base::MD5String(to_hash); | 309 return base::MD5String(to_hash); |
342 } | 310 } |
343 | |
344 std::string printer_name_; | 311 std::string printer_name_; |
345 PrintSystem::PrinterWatcher::Delegate* delegate_; | 312 PrintSystem::PrinterWatcher::Delegate* delegate_; |
346 scoped_refptr<PrintSystemCUPS> print_system_; | 313 scoped_refptr<PrintSystemCUPS> print_system_; |
347 std::string settings_hash_; | 314 std::string settings_hash_; |
348 | 315 |
349 DISALLOW_COPY_AND_ASSIGN(PrinterWatcherCUPS); | 316 DISALLOW_COPY_AND_ASSIGN(PrinterWatcherCUPS); |
350 }; | 317 }; |
351 | 318 |
352 class JobSpoolerCUPS : public PrintSystem::JobSpooler { | 319 class JobSpoolerCUPS : public PrintSystem::JobSpooler { |
353 public: | 320 public: |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 | 472 |
506 bool PrintSystemCUPS::ValidatePrintTicket(const std::string& printer_name, | 473 bool PrintSystemCUPS::ValidatePrintTicket(const std::string& printer_name, |
507 const std::string& print_ticket_data) { | 474 const std::string& print_ticket_data) { |
508 DCHECK(initialized_); | 475 DCHECK(initialized_); |
509 scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket_data, | 476 scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket_data, |
510 false)); | 477 false)); |
511 return ticket_value != NULL && ticket_value->IsType(Value::TYPE_DICTIONARY); | 478 return ticket_value != NULL && ticket_value->IsType(Value::TYPE_DICTIONARY); |
512 } | 479 } |
513 | 480 |
514 // Print ticket on linux is a JSON string containing only one dictionary. | 481 // Print ticket on linux is a JSON string containing only one dictionary. |
515 bool PrintSystemCUPS::ParsePrintTicket(const std::string& print_ticket, | 482 bool PrintSystemCUPS::ParsePrintTicket( |
516 std::map<std::string, std::string>* options) { | 483 const std::string& print_ticket, |
484 std::map<std::string, std::string>* options) { | |
517 DCHECK(options); | 485 DCHECK(options); |
518 scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket, false)); | 486 scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket, false)); |
519 if (ticket_value == NULL || !ticket_value->IsType(Value::TYPE_DICTIONARY)) | 487 if (ticket_value == NULL || !ticket_value->IsType(Value::TYPE_DICTIONARY)) |
520 return false; | 488 return false; |
521 | 489 |
522 options->clear(); | 490 options->clear(); |
523 DictionaryValue* ticket_dict = | 491 DictionaryValue* ticket_dict = |
524 static_cast<DictionaryValue*>(ticket_value.get()); | 492 static_cast<DictionaryValue*>(ticket_value.get()); |
525 DictionaryValue::key_iterator it(ticket_dict->begin_keys()); | 493 DictionaryValue::key_iterator it(ticket_dict->begin_keys()); |
526 for (; it != ticket_dict->end_keys(); ++it) { | 494 for (; it != ticket_dict->end_keys(); ++it) { |
(...skipping 18 matching lines...) Expand all Loading... | |
545 return false; | 513 return false; |
546 | 514 |
547 PrintServerInfoCUPS::CapsMap::iterator caps_it = | 515 PrintServerInfoCUPS::CapsMap::iterator caps_it = |
548 server_info->caps_cache.find(printer_name); | 516 server_info->caps_cache.find(printer_name); |
549 if (caps_it != server_info->caps_cache.end()) { | 517 if (caps_it != server_info->caps_cache.end()) { |
550 *printer_info = caps_it->second; | 518 *printer_info = caps_it->second; |
551 return true; | 519 return true; |
552 } | 520 } |
553 | 521 |
554 // TODO(gene): Retry multiple times in case of error. | 522 // TODO(gene): Retry multiple times in case of error. |
523 child_process_logging::ScopedPrinterInfoSetter prn_info(server_info->backend-> GetPrinterDriverInfo()); | |
Albert Bodenhamer
2012/03/13 23:57:39
80 chars
Vitaly Buka (NO REVIEWS)
2012/03/14 00:11:20
Done.
| |
555 if (!server_info->backend->GetPrinterCapsAndDefaults(short_printer_name, | 524 if (!server_info->backend->GetPrinterCapsAndDefaults(short_printer_name, |
556 printer_info) ) { | 525 printer_info) ) { |
557 return false; | 526 return false; |
558 } | 527 } |
559 | 528 |
560 server_info->caps_cache[printer_name] = *printer_info; | 529 server_info->caps_cache[printer_name] = *printer_info; |
561 return true; | 530 return true; |
562 } | 531 } |
563 | 532 |
564 bool PrintSystemCUPS::GetJobDetails(const std::string& printer_name, | 533 bool PrintSystemCUPS::GetJobDetails(const std::string& printer_name, |
565 PlatformJobId job_id, | 534 PlatformJobId job_id, |
566 PrintJobDetails *job_details) { | 535 PrintJobDetails *job_details) { |
567 DCHECK(initialized_); | 536 DCHECK(initialized_); |
568 DCHECK(job_details); | 537 DCHECK(job_details); |
569 | 538 |
570 std::string short_printer_name; | 539 std::string short_printer_name; |
571 PrintServerInfoCUPS* server_info = | 540 PrintServerInfoCUPS* server_info = |
572 FindServerByFullName(printer_name, &short_printer_name); | 541 FindServerByFullName(printer_name, &short_printer_name); |
573 if (!server_info) | 542 if (!server_info) |
574 return false; | 543 return false; |
575 | 544 |
545 child_process_logging::ScopedPrinterInfoSetter prn_info( | |
546 server_info->backend->GetPrinterDriverInfo()); | |
576 cups_job_t* jobs = NULL; | 547 cups_job_t* jobs = NULL; |
577 int num_jobs = GetJobs(&jobs, server_info->url, | 548 int num_jobs = GetJobs(&jobs, server_info->url, |
578 short_printer_name.c_str(), 1, -1); | 549 short_printer_name.c_str(), 1, -1); |
579 bool error = (num_jobs == 0) && (cupsLastError() > IPP_OK_EVENTS_COMPLETE); | 550 bool error = (num_jobs == 0) && (cupsLastError() > IPP_OK_EVENTS_COMPLETE); |
580 if (error) { | 551 if (error) { |
581 VLOG(1) << "CP_CUPS: Error getting jobs from CUPS server. Printer:" | 552 VLOG(1) << "CP_CUPS: Error getting jobs from CUPS server. Printer:" |
582 << printer_name | 553 << printer_name |
583 << " Error: " | 554 << " Error: " |
584 << static_cast<int>(cupsLastError()); | 555 << static_cast<int>(cupsLastError()); |
585 return false; | 556 return false; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
731 bool* dry_run) { | 702 bool* dry_run) { |
732 DCHECK(initialized_); | 703 DCHECK(initialized_); |
733 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name; | 704 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name; |
734 | 705 |
735 std::string short_printer_name; | 706 std::string short_printer_name; |
736 PrintServerInfoCUPS* server_info = | 707 PrintServerInfoCUPS* server_info = |
737 FindServerByFullName(printer_name, &short_printer_name); | 708 FindServerByFullName(printer_name, &short_printer_name); |
738 if (!server_info) | 709 if (!server_info) |
739 return false; | 710 return false; |
740 | 711 |
712 child_process_logging::ScopedPrinterInfoSetter prn_info( | |
713 server_info->backend->GetPrinterDriverInfo(printer_name)); | |
714 | |
741 // We need to store options as char* string for the duration of the | 715 // We need to store options as char* string for the duration of the |
742 // cupsPrintFile2 call. We'll use map here to store options, since | 716 // cupsPrintFile2 call. We'll use map here to store options, since |
743 // Dictionary value from JSON parser returns wchat_t. | 717 // Dictionary value from JSON parser returns wchat_t. |
744 std::map<std::string, std::string> options; | 718 std::map<std::string, std::string> options; |
745 bool res = ParsePrintTicket(print_ticket, &options); | 719 bool res = ParsePrintTicket(print_ticket, &options); |
746 DCHECK(res); // If print ticket is invalid we still print using defaults. | 720 DCHECK(res); // If print ticket is invalid we still print using defaults. |
747 | 721 |
748 // Check if this is a dry run (test) job. | 722 // Check if this is a dry run (test) job. |
749 *dry_run = CloudPrintHelpers::IsDryRunJob(tags); | 723 *dry_run = CloudPrintHelpers::IsDryRunJob(tags); |
750 if (*dry_run) { | 724 if (*dry_run) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
818 | 792 |
819 void PrintSystemCUPS::RunCapsCallback( | 793 void PrintSystemCUPS::RunCapsCallback( |
820 const PrinterCapsAndDefaultsCallback& callback, | 794 const PrinterCapsAndDefaultsCallback& callback, |
821 bool succeeded, | 795 bool succeeded, |
822 const std::string& printer_name, | 796 const std::string& printer_name, |
823 const printing::PrinterCapsAndDefaults& printer_info) { | 797 const printing::PrinterCapsAndDefaults& printer_info) { |
824 callback.Run(succeeded, printer_name, printer_info); | 798 callback.Run(succeeded, printer_name, printer_info); |
825 } | 799 } |
826 | 800 |
827 } // namespace cloud_print | 801 } // namespace cloud_print |
OLD | NEW |