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

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"
30 #include "chrome/service/cloud_print/cloud_print_helpers.h"
29 #include "googleurl/src/gurl.h" 31 #include "googleurl/src/gurl.h"
30 #include "printing/backend/cups_helper.h" 32 #include "printing/backend/cups_helper.h"
31 #include "printing/backend/print_backend.h" 33 #include "printing/backend/print_backend.h"
32 34
33 namespace { 35 namespace {
34 static const char kCUPSPrinterInfoOpt[] = "printer-info"; 36 static const char kCUPSPrinterInfoOpt[] = "printer-info";
35 static const char kCUPSPrinterStateOpt[] = "printer-state"; 37 static const char kCUPSPrinterStateOpt[] = "printer-state";
36 static const char kCUPSPrintServerURLs[] = "print_server_urls"; 38 static const char kCUPSPrintServerURLs[] = "print_server_urls";
37 static const char kCUPSUpdateTimeoutMs[] = "update_timeout_ms"; 39 static const char kCUPSUpdateTimeoutMs[] = "update_timeout_ms";
38 static const char kCUPSPrintBackendServerURL[] = "print_server_url"; 40 static const char kCUPSPrintBackendServerURL[] = "print_server_url";
39 41
40 // Default port for IPP print servers. 42 // Default port for IPP print servers.
41 static const int kDefaultIPPServerPort = 631; 43 static const int kDefaultIPPServerPort = 631;
42 44
43 // Time interval to check for printer's updates. 45 // Time interval to check for printer's updates.
44 const int kCheckForPrinterUpdatesMs = 6*60*60*1000; 46 const int kCheckForPrinterUpdatesMs = 6*60*60*1000;
45 47
46 // Job update timeput 48 // Job update timeput
47 const int kJobUpdateTimeoutMs = 5000; 49 const int kJobUpdateTimeoutMs = 5000;
48 50
51 // Job id for dry run (it should not affect CUPS job ids, since 0 job-id is
52 // invalid in CUPS.
53 const int kDryRunJobId = 0;
54
49 } // namespace 55 } // namespace
50 56
51 namespace cloud_print { 57 namespace cloud_print {
52 58
53 struct PrintServerInfoCUPS { 59 struct PrintServerInfoCUPS {
54 GURL url; 60 GURL url;
55 scoped_refptr<printing::PrintBackend> backend; 61 scoped_refptr<printing::PrintBackend> backend;
56 printing::PrinterList printers; 62 printing::PrinterList printers;
57 // CapsMap cache PPD until the next update and give a fast access to it by 63 // 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 64 // printer name. PPD request is relatively expensive and this should minimize
(...skipping 27 matching lines...) Expand all
86 virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher(); 92 virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher();
87 virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher( 93 virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher(
88 const std::string& printer_name); 94 const std::string& printer_name);
89 virtual PrintSystem::JobSpooler* CreateJobSpooler(); 95 virtual PrintSystem::JobSpooler* CreateJobSpooler();
90 96
91 // Helper functions. 97 // Helper functions.
92 PlatformJobId SpoolPrintJob(const std::string& print_ticket, 98 PlatformJobId SpoolPrintJob(const std::string& print_ticket,
93 const FilePath& print_data_file_path, 99 const FilePath& print_data_file_path,
94 const std::string& print_data_mime_type, 100 const std::string& print_data_mime_type,
95 const std::string& printer_name, 101 const std::string& printer_name,
96 const std::string& job_title); 102 const std::string& job_title,
103 const std::vector<std::string>& tags,
104 bool* dry_run);
97 bool GetPrinterInfo(const std::string& printer_name, 105 bool GetPrinterInfo(const std::string& printer_name,
98 printing::PrinterBasicInfo* info); 106 printing::PrinterBasicInfo* info);
99 bool ParsePrintTicket(const std::string& print_ticket, 107 bool ParsePrintTicket(const std::string& print_ticket,
100 std::map<std::string, std::string>* options); 108 std::map<std::string, std::string>* options);
101 109
102 int GetUpdateTimeoutMs() const { 110 int GetUpdateTimeoutMs() const {
103 return update_timeout_; 111 return update_timeout_;
104 } 112 }
105 113
106 private: 114 private:
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 explicit JobSpoolerCUPS(PrintSystemCUPS* print_system) 311 explicit JobSpoolerCUPS(PrintSystemCUPS* print_system)
304 : print_system_(print_system) { 312 : print_system_(print_system) {
305 DCHECK(print_system_.get()); 313 DCHECK(print_system_.get());
306 } 314 }
307 // PrintSystem::JobSpooler implementation. 315 // PrintSystem::JobSpooler implementation.
308 virtual bool Spool(const std::string& print_ticket, 316 virtual bool Spool(const std::string& print_ticket,
309 const FilePath& print_data_file_path, 317 const FilePath& print_data_file_path,
310 const std::string& print_data_mime_type, 318 const std::string& print_data_mime_type,
311 const std::string& printer_name, 319 const std::string& printer_name,
312 const std::string& job_title, 320 const std::string& job_title,
321 const std::vector<std::string>& tags,
313 JobSpooler::Delegate* delegate) { 322 JobSpooler::Delegate* delegate) {
314 DCHECK(delegate); 323 DCHECK(delegate);
324 bool dry_run = false;
315 int job_id = print_system_->SpoolPrintJob( 325 int job_id = print_system_->SpoolPrintJob(
316 print_ticket, print_data_file_path, print_data_mime_type, 326 print_ticket, print_data_file_path, print_data_mime_type,
317 printer_name, job_title); 327 printer_name, job_title, tags, &dry_run);
318 MessageLoop::current()->PostTask(FROM_HERE, 328 MessageLoop::current()->PostTask(FROM_HERE,
319 NewRunnableFunction( 329 NewRunnableFunction(
320 &JobSpoolerCUPS::NotifyDelegate, 330 &JobSpoolerCUPS::NotifyDelegate,
321 delegate, 331 delegate,
322 job_id)); 332 job_id,
333 dry_run));
323 return true; 334 return true;
324 } 335 }
325 336
326 static void NotifyDelegate(JobSpooler::Delegate* delegate, int job_id) { 337 static void NotifyDelegate(JobSpooler::Delegate* delegate,
327 if (job_id) 338 int job_id, bool dry_run) {
339 if (dry_run || job_id)
328 delegate->OnJobSpoolSucceeded(job_id); 340 delegate->OnJobSpoolSucceeded(job_id);
329 else 341 else
330 delegate->OnJobSpoolFailed(); 342 delegate->OnJobSpoolFailed();
331 } 343 }
332 private: 344 private:
333 scoped_refptr<PrintSystemCUPS> print_system_; 345 scoped_refptr<PrintSystemCUPS> print_system_;
334 DISALLOW_COPY_AND_ASSIGN(JobSpoolerCUPS); 346 DISALLOW_COPY_AND_ASSIGN(JobSpoolerCUPS);
335 }; 347 };
336 348
337 PrintSystemCUPS::PrintSystemCUPS(const DictionaryValue* print_system_settings) 349 PrintSystemCUPS::PrintSystemCUPS(const DictionaryValue* print_system_settings)
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 std::string short_printer_name; 498 std::string short_printer_name;
487 PrintServerInfoCUPS* server_info = 499 PrintServerInfoCUPS* server_info =
488 FindServerByFullName(printer_name, &short_printer_name); 500 FindServerByFullName(printer_name, &short_printer_name);
489 if (!server_info) 501 if (!server_info)
490 return false; 502 return false;
491 503
492 cups_job_t* jobs = NULL; 504 cups_job_t* jobs = NULL;
493 int num_jobs = GetJobs(&jobs, server_info->url, 505 int num_jobs = GetJobs(&jobs, server_info->url,
494 short_printer_name.c_str(), 1, -1); 506 short_printer_name.c_str(), 1, -1);
495 507
508
509 // Check if the request is for dummy dry run job.
510 // We check this after calling GetJobs API to see if this printer is actually
511 // accessible through CUPS.
512 if (job_id == kDryRunJobId) {
513 if (num_jobs >= 0) {
514 job_details->status = PRINT_JOB_STATUS_COMPLETED;
515 VLOG(1) << "CP_CUPS: Dry run job succeeded for: " << printer_name;
516 } else {
517 job_details->status = PRINT_JOB_STATUS_ERROR;
518 VLOG(1) << "CP_CUPS: Dry run job faield for: " << printer_name;
519 }
520 return true;
521 }
522
496 bool found = false; 523 bool found = false;
497 for (int i = 0; i < num_jobs; i++) { 524 for (int i = 0; i < num_jobs; i++) {
498 if (jobs[i].id == job_id) { 525 if (jobs[i].id == job_id) {
499 found = true; 526 found = true;
500 switch (jobs[i].state) { 527 switch (jobs[i].state) {
501 case IPP_JOB_PENDING : 528 case IPP_JOB_PENDING :
502 case IPP_JOB_HELD : 529 case IPP_JOB_HELD :
503 case IPP_JOB_PROCESSING : 530 case IPP_JOB_PROCESSING :
504 job_details->status = PRINT_JOB_STATUS_IN_PROGRESS; 531 job_details->status = PRINT_JOB_STATUS_IN_PROGRESS;
505 break; 532 break;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 printing::HttpConnectionCUPS http(url); 635 printing::HttpConnectionCUPS http(url);
609 return cupsGetJobs2(http.http(), jobs, name, myjobs, whichjobs); 636 return cupsGetJobs2(http.http(), jobs, name, myjobs, whichjobs);
610 } 637 }
611 } 638 }
612 639
613 PlatformJobId PrintSystemCUPS::SpoolPrintJob( 640 PlatformJobId PrintSystemCUPS::SpoolPrintJob(
614 const std::string& print_ticket, 641 const std::string& print_ticket,
615 const FilePath& print_data_file_path, 642 const FilePath& print_data_file_path,
616 const std::string& print_data_mime_type, 643 const std::string& print_data_mime_type,
617 const std::string& printer_name, 644 const std::string& printer_name,
618 const std::string& job_title) { 645 const std::string& job_title,
646 const std::vector<std::string>& tags,
647 bool* dry_run) {
619 DCHECK(initialized_); 648 DCHECK(initialized_);
620 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name; 649 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name;
621 650
622 std::string short_printer_name; 651 std::string short_printer_name;
623 PrintServerInfoCUPS* server_info = 652 PrintServerInfoCUPS* server_info =
624 FindServerByFullName(printer_name, &short_printer_name); 653 FindServerByFullName(printer_name, &short_printer_name);
625 if (!server_info) 654 if (!server_info)
626 return false; 655 return false;
627 656
628 // We need to store options as char* string for the duration of the 657 // 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 658 // cupsPrintFile2 call. We'll use map here to store options, since
630 // Dictionary value from JSON parser returns wchat_t. 659 // Dictionary value from JSON parser returns wchat_t.
631 std::map<std::string, std::string> options; 660 std::map<std::string, std::string> options;
632 bool res = ParsePrintTicket(print_ticket, &options); 661 bool res = ParsePrintTicket(print_ticket, &options);
633 DCHECK(res); // If print ticket is invalid we still print using defaults. 662 DCHECK(res); // If print ticket is invalid we still print using defaults.
634 663
664 // Check if this is a dry run (test) job.
665 *dry_run = CloudPrintHelpers::IsDryRunJob(tags);
666 if (*dry_run) {
667 VLOG(1) << "CP_CUPS: Dry run job spooled.";
668 return kDryRunJobId;
669 }
670
635 std::vector<cups_option_t> cups_options; 671 std::vector<cups_option_t> cups_options;
636 std::map<std::string, std::string>::iterator it; 672 std::map<std::string, std::string>::iterator it;
673
637 for (it = options.begin(); it != options.end(); ++it) { 674 for (it = options.begin(); it != options.end(); ++it) {
638 cups_option_t opt; 675 cups_option_t opt;
639 opt.name = const_cast<char*>(it->first.c_str()); 676 opt.name = const_cast<char*>(it->first.c_str());
640 opt.value = const_cast<char*>(it->second.c_str()); 677 opt.value = const_cast<char*>(it->second.c_str());
641 cups_options.push_back(opt); 678 cups_options.push_back(opt);
642 } 679 }
643 680
644 int job_id = PrintFile(server_info->url, 681 int job_id = PrintFile(server_info->url,
645 short_printer_name.c_str(), 682 short_printer_name.c_str(),
646 print_data_file_path.value().c_str(), 683 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); 726 *short_printer_name = full_printer_name.substr(separator + 1);
690 return &(*it); 727 return &(*it);
691 } 728 }
692 } 729 }
693 730
694 LOG(WARNING) << "Server not found for printer: " << full_printer_name; 731 LOG(WARNING) << "Server not found for printer: " << full_printer_name;
695 return NULL; 732 return NULL;
696 } 733 }
697 734
698 } // namespace cloud_print 735 } // 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