Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: chrome/service/cloud_print/print_system_cups.cc

Issue 5736004: Added 'dry run' tag to the print job, to test proxy health without wasting pa... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/file_path.h" 16 #include "base/file_path.h"
17 #include "base/json/json_reader.h" 17 #include "base/json/json_reader.h"
18 #include "base/lock.h" 18 #include "base/lock.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/md5.h" 20 #include "base/md5.h"
21 #include "base/message_loop.h" 21 #include "base/message_loop.h"
22 #include "base/rand_util.h" 22 #include "base/rand_util.h"
23 #include "base/scoped_ptr.h" 23 #include "base/scoped_ptr.h"
24 #include "base/string_number_conversions.h" 24 #include "base/string_number_conversions.h"
25 #include "base/string_util.h" 25 #include "base/string_util.h"
26 #include "base/task.h" 26 #include "base/task.h"
27 #include "base/values.h" 27 #include "base/values.h"
28 #include "base/utf_string_conversions.h" 28 #include "base/utf_string_conversions.h"
29 #include "chrome/service/cloud_print/cloud_print_consts.h"
29 #include "googleurl/src/gurl.h" 30 #include "googleurl/src/gurl.h"
30 #include "printing/backend/cups_helper.h" 31 #include "printing/backend/cups_helper.h"
31 #include "printing/backend/print_backend.h" 32 #include "printing/backend/print_backend.h"
32 33
33 namespace { 34 namespace {
34 static const char kCUPSPrinterInfoOpt[] = "printer-info"; 35 static const char kCUPSPrinterInfoOpt[] = "printer-info";
35 static const char kCUPSPrinterStateOpt[] = "printer-state"; 36 static const char kCUPSPrinterStateOpt[] = "printer-state";
36 static const char kCUPSPrintServerURLs[] = "print_server_urls"; 37 static const char kCUPSPrintServerURLs[] = "print_server_urls";
37 static const char kCUPSUpdateTimeoutMs[] = "update_timeout_ms"; 38 static const char kCUPSUpdateTimeoutMs[] = "update_timeout_ms";
38 static const char kCUPSPrintBackendServerURL[] = "print_server_url"; 39 static const char kCUPSPrintBackendServerURL[] = "print_server_url";
39 40
40 // Default port for IPP print servers. 41 // Default port for IPP print servers.
41 static const int kDefaultIPPServerPort = 631; 42 static const int kDefaultIPPServerPort = 631;
42 43
43 // Time interval to check for printer's updates. 44 // Time interval to check for printer's updates.
44 const int kCheckForPrinterUpdatesMs = 6*60*60*1000; 45 const int kCheckForPrinterUpdatesMs = 6*60*60*1000;
45 46
46 // Job update timeput 47 // Job update timeput
47 const int kJobUpdateTimeoutMs = 5000; 48 const int kJobUpdateTimeoutMs = 5000;
48 49
50 // Job id for dry run (it should not affect CUPS job ids, since 0 job-id is
51 // invalid in CUPS.
52 const int kDryRunJobId = 0;
53
49 } // namespace 54 } // namespace
50 55
51 namespace cloud_print { 56 namespace cloud_print {
52 57
53 struct PrintServerInfoCUPS { 58 struct PrintServerInfoCUPS {
54 GURL url; 59 GURL url;
55 scoped_refptr<printing::PrintBackend> backend; 60 scoped_refptr<printing::PrintBackend> backend;
56 printing::PrinterList printers; 61 printing::PrinterList printers;
57 // CapsMap cache PPD until the next update and give a fast access to it by 62 // CapsMap cache PPD until the next update and give a fast access to it by
58 // printer name. PPD request is relatively expensive and this should minimize 63 // printer name. PPD request is relatively expensive and this should minimize
(...skipping 27 matching lines...) Expand all
86 virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher(); 91 virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher();
87 virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher( 92 virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher(
88 const std::string& printer_name); 93 const std::string& printer_name);
89 virtual PrintSystem::JobSpooler* CreateJobSpooler(); 94 virtual PrintSystem::JobSpooler* CreateJobSpooler();
90 95
91 // Helper functions. 96 // Helper functions.
92 PlatformJobId SpoolPrintJob(const std::string& print_ticket, 97 PlatformJobId SpoolPrintJob(const std::string& print_ticket,
93 const FilePath& print_data_file_path, 98 const FilePath& print_data_file_path,
94 const std::string& print_data_mime_type, 99 const std::string& print_data_mime_type,
95 const std::string& printer_name, 100 const std::string& printer_name,
96 const std::string& job_title); 101 const std::string& job_title,
102 const std::vector<std::string>& tags,
103 bool* dry_run);
97 bool GetPrinterInfo(const std::string& printer_name, 104 bool GetPrinterInfo(const std::string& printer_name,
98 printing::PrinterBasicInfo* info); 105 printing::PrinterBasicInfo* info);
99 bool ParsePrintTicket(const std::string& print_ticket, 106 bool ParsePrintTicket(const std::string& print_ticket,
100 std::map<std::string, std::string>* options); 107 std::map<std::string, std::string>* options);
101 108
102 int GetUpdateTimeoutMs() const { 109 int GetUpdateTimeoutMs() const {
103 return update_timeout_; 110 return update_timeout_;
104 } 111 }
105 112
106 private: 113 private:
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 explicit JobSpoolerCUPS(PrintSystemCUPS* print_system) 310 explicit JobSpoolerCUPS(PrintSystemCUPS* print_system)
304 : print_system_(print_system) { 311 : print_system_(print_system) {
305 DCHECK(print_system_.get()); 312 DCHECK(print_system_.get());
306 } 313 }
307 // PrintSystem::JobSpooler implementation. 314 // PrintSystem::JobSpooler implementation.
308 virtual bool Spool(const std::string& print_ticket, 315 virtual bool Spool(const std::string& print_ticket,
309 const FilePath& print_data_file_path, 316 const FilePath& print_data_file_path,
310 const std::string& print_data_mime_type, 317 const std::string& print_data_mime_type,
311 const std::string& printer_name, 318 const std::string& printer_name,
312 const std::string& job_title, 319 const std::string& job_title,
320 const std::vector<std::string>& tags,
313 JobSpooler::Delegate* delegate) { 321 JobSpooler::Delegate* delegate) {
314 DCHECK(delegate); 322 DCHECK(delegate);
323 bool dry_run = false;
315 int job_id = print_system_->SpoolPrintJob( 324 int job_id = print_system_->SpoolPrintJob(
316 print_ticket, print_data_file_path, print_data_mime_type, 325 print_ticket, print_data_file_path, print_data_mime_type,
317 printer_name, job_title); 326 printer_name, job_title, tags, &dry_run);
318 MessageLoop::current()->PostTask(FROM_HERE, 327 MessageLoop::current()->PostTask(FROM_HERE,
319 NewRunnableFunction( 328 NewRunnableFunction(
320 &JobSpoolerCUPS::NotifyDelegate, 329 &JobSpoolerCUPS::NotifyDelegate,
321 delegate, 330 delegate,
322 job_id)); 331 job_id,
332 dry_run));
323 return true; 333 return true;
324 } 334 }
325 335
326 static void NotifyDelegate(JobSpooler::Delegate* delegate, int job_id) { 336 static void NotifyDelegate(JobSpooler::Delegate* delegate,
337 int job_id, bool dry_run) {
338 if (dry_run) {
sanjeevr 2010/12/10 23:50:02 if (dry_run || job_id) ?
339 delegate->OnJobSpoolSucceeded(job_id);
340 return;
341 }
342
327 if (job_id) 343 if (job_id)
328 delegate->OnJobSpoolSucceeded(job_id); 344 delegate->OnJobSpoolSucceeded(job_id);
329 else 345 else
330 delegate->OnJobSpoolFailed(); 346 delegate->OnJobSpoolFailed();
331 } 347 }
332 private: 348 private:
333 scoped_refptr<PrintSystemCUPS> print_system_; 349 scoped_refptr<PrintSystemCUPS> print_system_;
334 DISALLOW_COPY_AND_ASSIGN(JobSpoolerCUPS); 350 DISALLOW_COPY_AND_ASSIGN(JobSpoolerCUPS);
335 }; 351 };
336 352
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 std::string short_printer_name; 502 std::string short_printer_name;
487 PrintServerInfoCUPS* server_info = 503 PrintServerInfoCUPS* server_info =
488 FindServerByFullName(printer_name, &short_printer_name); 504 FindServerByFullName(printer_name, &short_printer_name);
489 if (!server_info) 505 if (!server_info)
490 return false; 506 return false;
491 507
492 cups_job_t* jobs = NULL; 508 cups_job_t* jobs = NULL;
493 int num_jobs = GetJobs(&jobs, server_info->url, 509 int num_jobs = GetJobs(&jobs, server_info->url,
494 short_printer_name.c_str(), 1, -1); 510 short_printer_name.c_str(), 1, -1);
495 511
512
513 // Check if the request is for dummy dry run job.
514 // We check this after calling GetJobs API to see if this printer is actually
515 // accessible through CUPS.
516 if (job_id == kDryRunJobId) {
517 if (num_jobs >= 0) {
518 job_details->status = PRINT_JOB_STATUS_COMPLETED;
519 VLOG(1) << "CP_CUPS: Dry run job succeeded for: " << printer_name;
520 } else {
521 job_details->status = PRINT_JOB_STATUS_ERROR;
522 VLOG(1) << "CP_CUPS: Dry run job faield for: " << printer_name;
523 }
524 return true;
525 }
526
496 bool found = false; 527 bool found = false;
497 for (int i = 0; i < num_jobs; i++) { 528 for (int i = 0; i < num_jobs; i++) {
498 if (jobs[i].id == job_id) { 529 if (jobs[i].id == job_id) {
499 found = true; 530 found = true;
500 switch (jobs[i].state) { 531 switch (jobs[i].state) {
501 case IPP_JOB_PENDING : 532 case IPP_JOB_PENDING :
502 case IPP_JOB_HELD : 533 case IPP_JOB_HELD :
503 case IPP_JOB_PROCESSING : 534 case IPP_JOB_PROCESSING :
504 job_details->status = PRINT_JOB_STATUS_IN_PROGRESS; 535 job_details->status = PRINT_JOB_STATUS_IN_PROGRESS;
505 break; 536 break;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 printing::HttpConnectionCUPS http(url); 639 printing::HttpConnectionCUPS http(url);
609 return cupsGetJobs2(http.http(), jobs, name, myjobs, whichjobs); 640 return cupsGetJobs2(http.http(), jobs, name, myjobs, whichjobs);
610 } 641 }
611 } 642 }
612 643
613 PlatformJobId PrintSystemCUPS::SpoolPrintJob( 644 PlatformJobId PrintSystemCUPS::SpoolPrintJob(
614 const std::string& print_ticket, 645 const std::string& print_ticket,
615 const FilePath& print_data_file_path, 646 const FilePath& print_data_file_path,
616 const std::string& print_data_mime_type, 647 const std::string& print_data_mime_type,
617 const std::string& printer_name, 648 const std::string& printer_name,
618 const std::string& job_title) { 649 const std::string& job_title,
650 const std::vector<std::string>& tags,
651 bool* dry_run) {
619 DCHECK(initialized_); 652 DCHECK(initialized_);
620 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name; 653 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name;
621 654
622 std::string short_printer_name; 655 std::string short_printer_name;
623 PrintServerInfoCUPS* server_info = 656 PrintServerInfoCUPS* server_info =
624 FindServerByFullName(printer_name, &short_printer_name); 657 FindServerByFullName(printer_name, &short_printer_name);
625 if (!server_info) 658 if (!server_info)
626 return false; 659 return false;
627 660
628 // We need to store options as char* string for the duration of the 661 // We need to store options as char* string for the duration of the
629 // cupsPrintFile2 call. We'll use map here to store options, since 662 // cupsPrintFile2 call. We'll use map here to store options, since
630 // Dictionary value from JSON parser returns wchat_t. 663 // Dictionary value from JSON parser returns wchat_t.
631 std::map<std::string, std::string> options; 664 std::map<std::string, std::string> options;
632 bool res = ParsePrintTicket(print_ticket, &options); 665 bool res = ParsePrintTicket(print_ticket, &options);
633 DCHECK(res); // If print ticket is invalid we still print using defaults. 666 DCHECK(res); // If print ticket is invalid we still print using defaults.
634 667
668 // Check if this is a dry run (test) job.
669 *dry_run = false;
670 std::vector<std::string>::const_iterator tags_it;
sanjeevr 2010/12/10 23:50:02 Can you move this loop to CLoudPrintHelpers so we
671 for (tags_it = tags.begin(); tags_it != tags.end(); ++tags_it) {
672 if (*tags_it == kTagDryRunFlag) {
673 *dry_run = true;
674 VLOG(1) << "CP_CUPS: Dry run job spooled.";
675 return kDryRunJobId;
676 }
677 }
678
635 std::vector<cups_option_t> cups_options; 679 std::vector<cups_option_t> cups_options;
636 std::map<std::string, std::string>::iterator it; 680 std::map<std::string, std::string>::iterator it;
681
637 for (it = options.begin(); it != options.end(); ++it) { 682 for (it = options.begin(); it != options.end(); ++it) {
638 cups_option_t opt; 683 cups_option_t opt;
639 opt.name = const_cast<char*>(it->first.c_str()); 684 opt.name = const_cast<char*>(it->first.c_str());
640 opt.value = const_cast<char*>(it->second.c_str()); 685 opt.value = const_cast<char*>(it->second.c_str());
641 cups_options.push_back(opt); 686 cups_options.push_back(opt);
642 } 687 }
643 688
644 int job_id = PrintFile(server_info->url, 689 int job_id = PrintFile(server_info->url,
645 short_printer_name.c_str(), 690 short_printer_name.c_str(),
646 print_data_file_path.value().c_str(), 691 print_data_file_path.value().c_str(),
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 *short_printer_name = full_printer_name.substr(separator + 1); 734 *short_printer_name = full_printer_name.substr(separator + 1);
690 return &(*it); 735 return &(*it);
691 } 736 }
692 } 737 }
693 738
694 LOG(WARNING) << "Server not found for printer: " << full_printer_name; 739 LOG(WARNING) << "Server not found for printer: " << full_printer_name;
695 return NULL; 740 return NULL;
696 } 741 }
697 742
698 } // namespace cloud_print 743 } // namespace cloud_print
OLDNEW
« no previous file with comments | « chrome/service/cloud_print/print_system.h ('k') | chrome/service/cloud_print/print_system_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698