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 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 delegate_->OnJobChanged(); | 297 delegate_->OnJobChanged(); |
298 MessageLoop::current()->PostDelayedTask( | 298 MessageLoop::current()->PostDelayedTask( |
299 FROM_HERE, | 299 FROM_HERE, |
300 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), | 300 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), |
301 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); | 301 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); |
302 } | 302 } |
303 | 303 |
304 void PrinterUpdate() { | 304 void PrinterUpdate() { |
305 if (delegate_ == NULL) | 305 if (delegate_ == NULL) |
306 return; // Orphan call. We have been stopped already. | 306 return; // Orphan call. We have been stopped already. |
307 VLOG(1) << "CP_CUPS: Checking for printer updates: " << printer_name_; | 307 VLOG(1) << "CP_CUPS: Checking for updates" |
| 308 << ", printer name: " << printer_name_; |
308 if (print_system_->NotifyDelete() && | 309 if (print_system_->NotifyDelete() && |
309 !print_system_->IsValidPrinter(printer_name_)) { | 310 !print_system_->IsValidPrinter(printer_name_)) { |
310 delegate_->OnPrinterDeleted(); | 311 delegate_->OnPrinterDeleted(); |
311 VLOG(1) << "CP_CUPS: Printer deleted: " << printer_name_; | 312 VLOG(1) << "CP_CUPS: Printer deleted" |
| 313 << ", printer name: " << printer_name_; |
312 } else { | 314 } else { |
313 std::string new_hash = GetSettingsHash(); | 315 std::string new_hash = GetSettingsHash(); |
314 if (settings_hash_ != new_hash) { | 316 if (settings_hash_ != new_hash) { |
315 settings_hash_ = new_hash; | 317 settings_hash_ = new_hash; |
316 delegate_->OnPrinterChanged(); | 318 delegate_->OnPrinterChanged(); |
317 VLOG(1) << "CP_CUPS: Printer update detected for: " << printer_name_; | 319 VLOG(1) << "CP_CUPS: Printer configuration changed" |
| 320 << ", printer name: " << printer_name_; |
318 } | 321 } |
319 } | 322 } |
320 MessageLoop::current()->PostDelayedTask( | 323 MessageLoop::current()->PostDelayedTask( |
321 FROM_HERE, | 324 FROM_HERE, |
322 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), | 325 base::Bind(&PrinterWatcherCUPS::PrinterUpdate, this), |
323 print_system_->GetUpdateTimeout()); | 326 print_system_->GetUpdateTimeout()); |
324 } | 327 } |
325 | 328 |
326 protected: | 329 protected: |
327 virtual ~PrinterWatcherCUPS() { | 330 virtual ~PrinterWatcherCUPS() { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { | 483 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { |
481 if (!it->backend->EnumeratePrinters(&it->printers)) | 484 if (!it->backend->EnumeratePrinters(&it->printers)) |
482 printer_enum_succeeded_ = false; | 485 printer_enum_succeeded_ = false; |
483 it->caps_cache.clear(); | 486 it->caps_cache.clear(); |
484 printing::PrinterList::iterator printer_it; | 487 printing::PrinterList::iterator printer_it; |
485 for (printer_it = it->printers.begin(); | 488 for (printer_it = it->printers.begin(); |
486 printer_it != it->printers.end(); ++printer_it) { | 489 printer_it != it->printers.end(); ++printer_it) { |
487 printer_it->printer_name = MakeFullPrinterName(it->url, | 490 printer_it->printer_name = MakeFullPrinterName(it->url, |
488 printer_it->printer_name); | 491 printer_it->printer_name); |
489 } | 492 } |
490 VLOG(1) << "CUPS: Updated printer list for url: " << it->url | 493 VLOG(1) << "CP_CUPS: Updated printers list" |
491 << " Number of printers: " << it->printers.size(); | 494 << ", server: " << it->url |
| 495 << ", # of printers: " << it->printers.size(); |
492 } | 496 } |
493 | 497 |
494 // Schedule next update. | 498 // Schedule next update. |
495 MessageLoop::current()->PostDelayedTask( | 499 MessageLoop::current()->PostDelayedTask( |
496 FROM_HERE, | 500 FROM_HERE, |
497 base::Bind(&PrintSystemCUPS::UpdatePrinters, this), GetUpdateTimeout()); | 501 base::Bind(&PrintSystemCUPS::UpdatePrinters, this), GetUpdateTimeout()); |
498 } | 502 } |
499 | 503 |
500 PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( | 504 PrintSystem::PrintSystemResult PrintSystemCUPS::EnumeratePrinters( |
501 printing::PrinterList* printer_list) { | 505 printing::PrinterList* printer_list) { |
502 DCHECK(initialized_); | 506 DCHECK(initialized_); |
503 printer_list->clear(); | 507 printer_list->clear(); |
504 PrintServerList::iterator it; | 508 PrintServerList::iterator it; |
505 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { | 509 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { |
506 printer_list->insert(printer_list->end(), | 510 printer_list->insert(printer_list->end(), |
507 it->printers.begin(), it->printers.end()); | 511 it->printers.begin(), it->printers.end()); |
508 } | 512 } |
509 VLOG(1) << "CUPS: Total " << printer_list->size() << " printers enumerated."; | 513 VLOG(1) << "CP_CUPS: Total printers enumerated: " << printer_list->size(); |
510 // TODO(sanjeevr): Maybe some day we want to report the actual server names | 514 // TODO(sanjeevr): Maybe some day we want to report the actual server names |
511 // for which the enumeration failed. | 515 // for which the enumeration failed. |
512 return PrintSystemResult(printer_enum_succeeded_, std::string()); | 516 return PrintSystemResult(printer_enum_succeeded_, std::string()); |
513 } | 517 } |
514 | 518 |
515 void PrintSystemCUPS::GetPrinterCapsAndDefaults( | 519 void PrintSystemCUPS::GetPrinterCapsAndDefaults( |
516 const std::string& printer_name, | 520 const std::string& printer_name, |
517 const PrinterCapsAndDefaultsCallback& callback) { | 521 const PrinterCapsAndDefaultsCallback& callback) { |
518 printing::PrinterCapsAndDefaults printer_info; | 522 printing::PrinterCapsAndDefaults printer_info; |
519 bool succeeded = GetPrinterCapsAndDefaults(printer_name, &printer_info); | 523 bool succeeded = GetPrinterCapsAndDefaults(printer_name, &printer_info); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 if (!server_info) | 603 if (!server_info) |
600 return false; | 604 return false; |
601 | 605 |
602 child_process_logging::ScopedPrinterInfoSetter prn_info( | 606 child_process_logging::ScopedPrinterInfoSetter prn_info( |
603 server_info->backend->GetPrinterDriverInfo(short_printer_name)); | 607 server_info->backend->GetPrinterDriverInfo(short_printer_name)); |
604 cups_job_t* jobs = NULL; | 608 cups_job_t* jobs = NULL; |
605 int num_jobs = GetJobs(&jobs, server_info->url, cups_encryption_, | 609 int num_jobs = GetJobs(&jobs, server_info->url, cups_encryption_, |
606 short_printer_name.c_str(), 1, -1); | 610 short_printer_name.c_str(), 1, -1); |
607 bool error = (num_jobs == 0) && (cupsLastError() > IPP_OK_EVENTS_COMPLETE); | 611 bool error = (num_jobs == 0) && (cupsLastError() > IPP_OK_EVENTS_COMPLETE); |
608 if (error) { | 612 if (error) { |
609 VLOG(1) << "CP_CUPS: Error getting jobs from CUPS server. Printer:" | 613 VLOG(1) << "CP_CUPS: Error getting jobs from CUPS server" |
610 << printer_name | 614 << ", printer name:" << printer_name |
611 << " Error: " | 615 << ", error: " << static_cast<int>(cupsLastError()); |
612 << static_cast<int>(cupsLastError()); | |
613 return false; | 616 return false; |
614 } | 617 } |
615 | 618 |
616 // Check if the request is for dummy dry run job. | 619 // Check if the request is for dummy dry run job. |
617 // We check this after calling GetJobs API to see if this printer is actually | 620 // We check this after calling GetJobs API to see if this printer is actually |
618 // accessible through CUPS. | 621 // accessible through CUPS. |
619 if (job_id == kDryRunJobId) { | 622 if (job_id == kDryRunJobId) { |
620 job_details->status = PRINT_JOB_STATUS_COMPLETED; | 623 job_details->status = PRINT_JOB_STATUS_COMPLETED; |
621 VLOG(1) << "CP_CUPS: Dry run job succeeded for: " << printer_name; | 624 VLOG(1) << "CP_CUPS: Dry run job succeeded" |
| 625 << ", printer name: " << printer_name; |
622 return true; | 626 return true; |
623 } | 627 } |
624 | 628 |
625 bool found = false; | 629 bool found = false; |
626 for (int i = 0; i < num_jobs; i++) { | 630 for (int i = 0; i < num_jobs; i++) { |
627 if (jobs[i].id == job_id) { | 631 if (jobs[i].id == job_id) { |
628 found = true; | 632 found = true; |
629 switch (jobs[i].state) { | 633 switch (jobs[i].state) { |
630 case IPP_JOB_PENDING : | 634 case IPP_JOB_PENDING : |
631 case IPP_JOB_HELD : | 635 case IPP_JOB_HELD : |
(...skipping 12 matching lines...) Expand all Loading... |
644 job_details->status = PRINT_JOB_STATUS_INVALID; | 648 job_details->status = PRINT_JOB_STATUS_INVALID; |
645 } | 649 } |
646 job_details->platform_status_flags = jobs[i].state; | 650 job_details->platform_status_flags = jobs[i].state; |
647 | 651 |
648 // We don't have any details on the number of processed pages here. | 652 // We don't have any details on the number of processed pages here. |
649 break; | 653 break; |
650 } | 654 } |
651 } | 655 } |
652 | 656 |
653 if (found) | 657 if (found) |
654 VLOG(1) << "CP_CUPS: Job details for: " << printer_name | 658 VLOG(1) << "CP_CUPS: Job found" |
655 << " job_id: " << job_id << " job status: " << job_details->status; | 659 << ", printer name: " << printer_name |
| 660 << ", cups job id: " << job_id |
| 661 << ", cups job status: " << job_details->status; |
656 else | 662 else |
657 LOG(WARNING) << "CP_CUPS: Job not found for: " << printer_name | 663 LOG(WARNING) << "CP_CUPS: Job not found" |
658 << " job_id: " << job_id; | 664 << ", printer name: " << printer_name |
| 665 << ", cups job id: " << job_id; |
659 | 666 |
660 cupsFreeJobs(num_jobs, jobs); | 667 cupsFreeJobs(num_jobs, jobs); |
661 return found; | 668 return found; |
662 } | 669 } |
663 | 670 |
664 bool PrintSystemCUPS::GetPrinterInfo(const std::string& printer_name, | 671 bool PrintSystemCUPS::GetPrinterInfo(const std::string& printer_name, |
665 printing::PrinterBasicInfo* info) { | 672 printing::PrinterBasicInfo* info) { |
666 DCHECK(initialized_); | 673 DCHECK(initialized_); |
667 if (info) | 674 if (info) |
668 VLOG(1) << "CP_CUPS: Getting printer info for: " << printer_name; | 675 VLOG(1) << "CP_CUPS: Getting printer info" |
| 676 << ", printer name: " << printer_name; |
669 | 677 |
670 std::string short_printer_name; | 678 std::string short_printer_name; |
671 PrintServerInfoCUPS* server_info = | 679 PrintServerInfoCUPS* server_info = |
672 FindServerByFullName(printer_name, &short_printer_name); | 680 FindServerByFullName(printer_name, &short_printer_name); |
673 if (!server_info) | 681 if (!server_info) |
674 return false; | 682 return false; |
675 | 683 |
676 printing::PrinterList::iterator it; | 684 printing::PrinterList::iterator it; |
677 for (it = server_info->printers.begin(); | 685 for (it = server_info->printers.begin(); |
678 it != server_info->printers.end(); ++it) { | 686 it != server_info->printers.end(); ++it) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 | 761 |
754 PlatformJobId PrintSystemCUPS::SpoolPrintJob( | 762 PlatformJobId PrintSystemCUPS::SpoolPrintJob( |
755 const std::string& print_ticket, | 763 const std::string& print_ticket, |
756 const FilePath& print_data_file_path, | 764 const FilePath& print_data_file_path, |
757 const std::string& print_data_mime_type, | 765 const std::string& print_data_mime_type, |
758 const std::string& printer_name, | 766 const std::string& printer_name, |
759 const std::string& job_title, | 767 const std::string& job_title, |
760 const std::vector<std::string>& tags, | 768 const std::vector<std::string>& tags, |
761 bool* dry_run) { | 769 bool* dry_run) { |
762 DCHECK(initialized_); | 770 DCHECK(initialized_); |
763 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name; | 771 VLOG(1) << "CP_CUPS: Spooling print job, printer name: " << printer_name; |
764 | 772 |
765 std::string short_printer_name; | 773 std::string short_printer_name; |
766 PrintServerInfoCUPS* server_info = | 774 PrintServerInfoCUPS* server_info = |
767 FindServerByFullName(printer_name, &short_printer_name); | 775 FindServerByFullName(printer_name, &short_printer_name); |
768 if (!server_info) | 776 if (!server_info) |
769 return false; | 777 return false; |
770 | 778 |
771 child_process_logging::ScopedPrinterInfoSetter prn_info( | 779 child_process_logging::ScopedPrinterInfoSetter prn_info( |
772 server_info->backend->GetPrinterDriverInfo(printer_name)); | 780 server_info->backend->GetPrinterDriverInfo(printer_name)); |
773 | 781 |
774 // We need to store options as char* string for the duration of the | 782 // We need to store options as char* string for the duration of the |
775 // cupsPrintFile2 call. We'll use map here to store options, since | 783 // cupsPrintFile2 call. We'll use map here to store options, since |
776 // Dictionary value from JSON parser returns wchat_t. | 784 // Dictionary value from JSON parser returns wchat_t. |
777 std::map<std::string, std::string> options; | 785 std::map<std::string, std::string> options; |
778 bool res = ParsePrintTicket(print_ticket, &options); | 786 bool res = ParsePrintTicket(print_ticket, &options); |
779 DCHECK(res); // If print ticket is invalid we still print using defaults. | 787 DCHECK(res); // If print ticket is invalid we still print using defaults. |
780 | 788 |
781 // Check if this is a dry run (test) job. | 789 // Check if this is a dry run (test) job. |
782 *dry_run = CloudPrintHelpers::IsDryRunJob(tags); | 790 *dry_run = CloudPrintHelpers::IsDryRunJob(tags); |
783 if (*dry_run) { | 791 if (*dry_run) { |
784 VLOG(1) << "CP_CUPS: Dry run job spooled."; | 792 VLOG(1) << "CP_CUPS: Dry run job spooled"; |
785 return kDryRunJobId; | 793 return kDryRunJobId; |
786 } | 794 } |
787 | 795 |
788 std::vector<cups_option_t> cups_options; | 796 std::vector<cups_option_t> cups_options; |
789 std::map<std::string, std::string>::iterator it; | 797 std::map<std::string, std::string>::iterator it; |
790 | 798 |
791 for (it = options.begin(); it != options.end(); ++it) { | 799 for (it = options.begin(); it != options.end(); ++it) { |
792 cups_option_t opt; | 800 cups_option_t opt; |
793 opt.name = const_cast<char*>(it->first.c_str()); | 801 opt.name = const_cast<char*>(it->first.c_str()); |
794 opt.value = const_cast<char*>(it->second.c_str()); | 802 opt.value = const_cast<char*>(it->second.c_str()); |
795 cups_options.push_back(opt); | 803 cups_options.push_back(opt); |
796 } | 804 } |
797 | 805 |
798 int job_id = PrintFile(server_info->url, | 806 int job_id = PrintFile(server_info->url, |
799 cups_encryption_, | 807 cups_encryption_, |
800 short_printer_name.c_str(), | 808 short_printer_name.c_str(), |
801 print_data_file_path.value().c_str(), | 809 print_data_file_path.value().c_str(), |
802 job_title.c_str(), | 810 job_title.c_str(), |
803 cups_options.size(), | 811 cups_options.size(), |
804 &(cups_options[0])); | 812 &(cups_options[0])); |
805 | 813 |
806 VLOG(1) << "CP_CUPS: Job spooled, id: " << job_id; | 814 // TODO(alexyu): Output printer id. |
| 815 VLOG(1) << "CP_CUPS: Job spooled" |
| 816 << ", printer name: " << printer_name |
| 817 << ", cups job id: " << job_id; |
807 | 818 |
808 return job_id; | 819 return job_id; |
809 } | 820 } |
810 | 821 |
811 std::string PrintSystemCUPS::MakeFullPrinterName( | 822 std::string PrintSystemCUPS::MakeFullPrinterName( |
812 const GURL& url, const std::string& short_printer_name) { | 823 const GURL& url, const std::string& short_printer_name) { |
813 std::string full_name; | 824 std::string full_name; |
814 full_name += "\\\\"; | 825 full_name += "\\\\"; |
815 full_name += url.host(); | 826 full_name += url.host(); |
816 if (!url.port().empty()) { | 827 if (!url.port().empty()) { |
817 full_name += ":"; | 828 full_name += ":"; |
818 full_name += url.port(); | 829 full_name += url.port(); |
819 } | 830 } |
820 full_name += "\\"; | 831 full_name += "\\"; |
821 full_name += short_printer_name; | 832 full_name += short_printer_name; |
822 return full_name; | 833 return full_name; |
823 } | 834 } |
824 | 835 |
825 PrintServerInfoCUPS* PrintSystemCUPS::FindServerByFullName( | 836 PrintServerInfoCUPS* PrintSystemCUPS::FindServerByFullName( |
826 const std::string& full_printer_name, std::string* short_printer_name) { | 837 const std::string& full_printer_name, std::string* short_printer_name) { |
827 size_t front = full_printer_name.find("\\\\"); | 838 size_t front = full_printer_name.find("\\\\"); |
828 size_t separator = full_printer_name.find("\\", 2); | 839 size_t separator = full_printer_name.find("\\", 2); |
829 if (front == std::string::npos || separator == std::string::npos) { | 840 if (front == std::string::npos || separator == std::string::npos) { |
830 LOG(WARNING) << "Invalid UNC printer name: " << full_printer_name; | 841 LOG(WARNING) << "CP_CUPS: Invalid UNC" |
| 842 << ", printer name: " << full_printer_name; |
831 return NULL; | 843 return NULL; |
832 } | 844 } |
833 std::string server = full_printer_name.substr(2, separator - 2); | 845 std::string server = full_printer_name.substr(2, separator - 2); |
834 | 846 |
835 PrintServerList::iterator it; | 847 PrintServerList::iterator it; |
836 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { | 848 for (it = print_servers_.begin(); it != print_servers_.end(); ++it) { |
837 std::string cur_server; | 849 std::string cur_server; |
838 cur_server += it->url.host(); | 850 cur_server += it->url.host(); |
839 if (!it->url.port().empty()) { | 851 if (!it->url.port().empty()) { |
840 cur_server += ":"; | 852 cur_server += ":"; |
841 cur_server += it->url.port(); | 853 cur_server += it->url.port(); |
842 } | 854 } |
843 if (cur_server == server) { | 855 if (cur_server == server) { |
844 *short_printer_name = full_printer_name.substr(separator + 1); | 856 *short_printer_name = full_printer_name.substr(separator + 1); |
845 return &(*it); | 857 return &(*it); |
846 } | 858 } |
847 } | 859 } |
848 | 860 |
849 LOG(WARNING) << "Server not found for printer: " << full_printer_name; | 861 LOG(WARNING) << "CP_CUPS: Server not found" |
| 862 << ", printer name: " << full_printer_name; |
850 return NULL; | 863 return NULL; |
851 } | 864 } |
852 | 865 |
853 void PrintSystemCUPS::RunCapsCallback( | 866 void PrintSystemCUPS::RunCapsCallback( |
854 const PrinterCapsAndDefaultsCallback& callback, | 867 const PrinterCapsAndDefaultsCallback& callback, |
855 bool succeeded, | 868 bool succeeded, |
856 const std::string& printer_name, | 869 const std::string& printer_name, |
857 const printing::PrinterCapsAndDefaults& printer_info) { | 870 const printing::PrinterCapsAndDefaults& printer_info) { |
858 callback.Run(succeeded, printer_name, printer_info); | 871 callback.Run(succeeded, printer_name, printer_info); |
859 } | 872 } |
860 | 873 |
861 } // namespace cloud_print | 874 } // namespace cloud_print |
OLD | NEW |