| OLD | NEW |
| 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 <gcrypt.h> | 10 #include <gcrypt.h> |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 117 } |
| 118 | 118 |
| 119 private: | 119 private: |
| 120 http_t* http_; | 120 http_t* http_; |
| 121 }; | 121 }; |
| 122 | 122 |
| 123 class PrintSystemCUPS : public PrintSystem { | 123 class PrintSystemCUPS : public PrintSystem { |
| 124 public: | 124 public: |
| 125 explicit PrintSystemCUPS(const GURL& print_server_url); | 125 explicit PrintSystemCUPS(const GURL& print_server_url); |
| 126 | 126 |
| 127 // PrintSystem implementation. |
| 127 virtual void EnumeratePrinters(PrinterList* printer_list); | 128 virtual void EnumeratePrinters(PrinterList* printer_list); |
| 128 | 129 |
| 129 virtual bool GetPrinterCapsAndDefaults(const std::string& printer_name, | 130 virtual bool GetPrinterCapsAndDefaults(const std::string& printer_name, |
| 130 PrinterCapsAndDefaults* printer_info); | 131 PrinterCapsAndDefaults* printer_info); |
| 131 | 132 |
| 132 virtual bool ValidatePrintTicket(const std::string& printer_name, | 133 virtual bool ValidatePrintTicket(const std::string& printer_name, |
| 133 const std::string& print_ticket_data); | 134 const std::string& print_ticket_data); |
| 134 | 135 |
| 135 virtual bool SpoolPrintJob(const std::string& print_ticket, | |
| 136 const FilePath& print_data_file_path, | |
| 137 const std::string& print_data_mime_type, | |
| 138 const std::string& printer_name, | |
| 139 const std::string& job_title, | |
| 140 PlatformJobId* job_id_ret); | |
| 141 | |
| 142 virtual bool GetJobDetails(const std::string& printer_name, | 136 virtual bool GetJobDetails(const std::string& printer_name, |
| 143 PlatformJobId job_id, | 137 PlatformJobId job_id, |
| 144 PrintJobDetails *job_details); | 138 PrintJobDetails *job_details); |
| 145 | 139 |
| 146 virtual bool IsValidPrinter(const std::string& printer_name); | 140 virtual bool IsValidPrinter(const std::string& printer_name); |
| 147 | 141 |
| 142 |
| 148 // TODO(gene): Add implementation for CUPS print server watcher. | 143 // TODO(gene): Add implementation for CUPS print server watcher. |
| 149 class PrintServerWatcherCUPS | 144 class PrintServerWatcherCUPS |
| 150 : public PrintSystem::PrintServerWatcher { | 145 : public PrintSystem::PrintServerWatcher { |
| 151 public: | 146 public: |
| 152 PrintServerWatcherCUPS() {} | 147 PrintServerWatcherCUPS() {} |
| 153 | 148 |
| 154 // PrintSystem::PrintServerWatcher interface | 149 // PrintSystem::PrintServerWatcher interface |
| 155 virtual bool StartWatching( | 150 virtual bool StartWatching( |
| 156 PrintSystem::PrintServerWatcher::Delegate* delegate) { | 151 PrintSystem::PrintServerWatcher::Delegate* delegate) { |
| 157 NOTIMPLEMENTED(); | 152 NOTIMPLEMENTED(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 kNotificationTimeout); | 200 kNotificationTimeout); |
| 206 } | 201 } |
| 207 private: | 202 private: |
| 208 static const int kNotificationTimeout = 5000; // in ms | 203 static const int kNotificationTimeout = 5000; // in ms |
| 209 std::string printer_name_; | 204 std::string printer_name_; |
| 210 PrintSystem::PrinterWatcher::Delegate* delegate_; | 205 PrintSystem::PrinterWatcher::Delegate* delegate_; |
| 211 scoped_refptr<PrintSystemCUPS> print_system_; | 206 scoped_refptr<PrintSystemCUPS> print_system_; |
| 212 DISALLOW_COPY_AND_ASSIGN(PrinterWatcherCUPS); | 207 DISALLOW_COPY_AND_ASSIGN(PrinterWatcherCUPS); |
| 213 }; | 208 }; |
| 214 | 209 |
| 210 class JobSpoolerCUPS : public PrintSystem::JobSpooler { |
| 211 public: |
| 212 explicit JobSpoolerCUPS(PrintSystemCUPS* print_system) |
| 213 : print_system_(print_system) { |
| 214 DCHECK(print_system_.get()); |
| 215 } |
| 216 // PrintSystem::JobSpooler implementation. |
| 217 virtual bool Spool(const std::string& print_ticket, |
| 218 const FilePath& print_data_file_path, |
| 219 const std::string& print_data_mime_type, |
| 220 const std::string& printer_name, |
| 221 const std::string& job_title, |
| 222 JobSpooler::Delegate* delegate) { |
| 223 DCHECK(delegate); |
| 224 int job_id = print_system_->SpoolPrintJob( |
| 225 print_ticket, print_data_file_path, print_data_mime_type, |
| 226 printer_name, job_title); |
| 227 MessageLoop::current()->PostTask(FROM_HERE, |
| 228 NewRunnableFunction( |
| 229 &JobSpoolerCUPS::NotifyDelegate, |
| 230 delegate, |
| 231 job_id)); |
| 232 return true; |
| 233 } |
| 234 |
| 235 static void NotifyDelegate(JobSpooler::Delegate* delegate, int job_id) { |
| 236 if (job_id) |
| 237 delegate->OnJobSpoolSucceeded(job_id); |
| 238 else |
| 239 delegate->OnJobSpoolFailed(); |
| 240 } |
| 241 private: |
| 242 scoped_refptr<PrintSystemCUPS> print_system_; |
| 243 DISALLOW_COPY_AND_ASSIGN(JobSpoolerCUPS); |
| 244 }; |
| 245 |
| 215 virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher(); | 246 virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher(); |
| 216 virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher( | 247 virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher( |
| 217 const std::string& printer_name); | 248 const std::string& printer_name); |
| 249 virtual PrintSystem::JobSpooler* CreateJobSpooler(); |
| 218 | 250 |
| 219 // Helper functions. | 251 // Helper functions. |
| 252 PlatformJobId SpoolPrintJob(const std::string& print_ticket, |
| 253 const FilePath& print_data_file_path, |
| 254 const std::string& print_data_mime_type, |
| 255 const std::string& printer_name, |
| 256 const std::string& job_title); |
| 220 bool GetPrinterInfo(const std::string& printer_name, PrinterBasicInfo* info); | 257 bool GetPrinterInfo(const std::string& printer_name, PrinterBasicInfo* info); |
| 221 bool ParsePrintTicket(const std::string& print_ticket, | 258 bool ParsePrintTicket(const std::string& print_ticket, |
| 222 std::map<std::string, std::string>* options); | 259 std::map<std::string, std::string>* options); |
| 223 | 260 |
| 224 private: | 261 private: |
| 225 // Following functions are wrappers around corresponding CUPS functions. | 262 // Following functions are wrappers around corresponding CUPS functions. |
| 226 // <functions>2() are called when print server is specified, and plain | 263 // <functions>2() are called when print server is specified, and plain |
| 227 // version in another case. There is an issue specifing CUPS_HTTP_DEFAULT | 264 // version in another case. There is an issue specifing CUPS_HTTP_DEFAULT |
| 228 // in the <functions>2(), it does not work in CUPS prior to 1.4. | 265 // in the <functions>2(), it does not work in CUPS prior to 1.4. |
| 229 int GetDests(cups_dest_t** dests); | 266 int GetDests(cups_dest_t** dests); |
| 230 FilePath GetPPD(const char* name); | 267 FilePath GetPPD(const char* name); |
| 268 int GetJobs(cups_job_t** jobs, const char* name, |
| 269 int myjobs, int whichjobs); |
| 231 int PrintFile(const char* name, const char* filename, const char* title, | 270 int PrintFile(const char* name, const char* filename, const char* title, |
| 232 int num_options, cups_option_t* options); | 271 int num_options, cups_option_t* options); |
| 233 int GetJobs(cups_job_t** jobs, const char* name, | |
| 234 int myjobs, int whichjobs); | |
| 235 | 272 |
| 236 GURL print_server_url_; | 273 GURL print_server_url_; |
| 237 }; | 274 }; |
| 238 | 275 |
| 239 PrintSystemCUPS::PrintSystemCUPS(const GURL& print_server_url) | 276 PrintSystemCUPS::PrintSystemCUPS(const GURL& print_server_url) |
| 240 : print_server_url_(print_server_url) { | 277 : print_server_url_(print_server_url) { |
| 241 } | 278 } |
| 242 | 279 |
| 243 void PrintSystemCUPS::EnumeratePrinters(PrinterList* printer_list) { | 280 void PrintSystemCUPS::EnumeratePrinters(PrinterList* printer_list) { |
| 244 DCHECK(printer_list); | 281 DCHECK(printer_list); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 std::wstring key = *it; | 366 std::wstring key = *it; |
| 330 std::string value; | 367 std::string value; |
| 331 if (ticket_dict->GetString(key, &value)) { | 368 if (ticket_dict->GetString(key, &value)) { |
| 332 (*options)[WideToUTF8(key.c_str())] = value; | 369 (*options)[WideToUTF8(key.c_str())] = value; |
| 333 } | 370 } |
| 334 } | 371 } |
| 335 | 372 |
| 336 return true; | 373 return true; |
| 337 } | 374 } |
| 338 | 375 |
| 339 bool PrintSystemCUPS::SpoolPrintJob(const std::string& print_ticket, | |
| 340 const FilePath& print_data_file_path, | |
| 341 const std::string& print_data_mime_type, | |
| 342 const std::string& printer_name, | |
| 343 const std::string& job_title, | |
| 344 PlatformJobId* job_id_ret) { | |
| 345 DCHECK(job_id_ret); | |
| 346 | |
| 347 LOG(INFO) << "CP_CUPS: Spooling print job for: " << printer_name; | |
| 348 | |
| 349 // We need to store options as char* string for the duration of the | |
| 350 // cupsPrintFile2 call. We'll use map here to store options, since | |
| 351 // Dictionary value from JSON parser returns wchat_t. | |
| 352 std::map<std::string, std::string> options; | |
| 353 bool res = ParsePrintTicket(print_ticket, &options); | |
| 354 DCHECK(res); // If print ticket is invalid we still print using defaults. | |
| 355 | |
| 356 std::vector<cups_option_t> cups_options; | |
| 357 std::map<std::string, std::string>::iterator it; | |
| 358 for (it = options.begin(); it != options.end(); ++it) { | |
| 359 cups_option_t opt; | |
| 360 opt.name = const_cast<char*>(it->first.c_str()); | |
| 361 opt.value = const_cast<char*>(it->second.c_str()); | |
| 362 cups_options.push_back(opt); | |
| 363 } | |
| 364 | |
| 365 int job_id = PrintFile(printer_name.c_str(), | |
| 366 print_data_file_path.value().c_str(), | |
| 367 job_title.c_str(), | |
| 368 cups_options.size(), | |
| 369 &(cups_options[0])); | |
| 370 | |
| 371 LOG(INFO) << "CP_CUPS: Job spooled, id: " << job_id; | |
| 372 | |
| 373 if (job_id == 0) | |
| 374 return false; | |
| 375 | |
| 376 *job_id_ret = job_id; | |
| 377 return true; | |
| 378 } | |
| 379 | |
| 380 bool PrintSystemCUPS::GetJobDetails(const std::string& printer_name, | 376 bool PrintSystemCUPS::GetJobDetails(const std::string& printer_name, |
| 381 PlatformJobId job_id, | 377 PlatformJobId job_id, |
| 382 PrintJobDetails *job_details) { | 378 PrintJobDetails *job_details) { |
| 383 DCHECK(job_details); | 379 DCHECK(job_details); |
| 384 | 380 |
| 385 cups_job_t* jobs = NULL; | 381 cups_job_t* jobs = NULL; |
| 386 int num_jobs = GetJobs(&jobs, printer_name.c_str(), 1, -1); | 382 int num_jobs = GetJobs(&jobs, printer_name.c_str(), 1, -1); |
| 387 | 383 |
| 388 bool found = false; | 384 bool found = false; |
| 389 for (int i = 0; i < num_jobs; i++) { | 385 for (int i = 0; i < num_jobs; i++) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 PrintSystemCUPS::CreatePrintServerWatcher() { | 451 PrintSystemCUPS::CreatePrintServerWatcher() { |
| 456 return new PrintServerWatcherCUPS(); | 452 return new PrintServerWatcherCUPS(); |
| 457 } | 453 } |
| 458 | 454 |
| 459 PrintSystem::PrinterWatcher* PrintSystemCUPS::CreatePrinterWatcher( | 455 PrintSystem::PrinterWatcher* PrintSystemCUPS::CreatePrinterWatcher( |
| 460 const std::string& printer_name) { | 456 const std::string& printer_name) { |
| 461 DCHECK(!printer_name.empty()); | 457 DCHECK(!printer_name.empty()); |
| 462 return new PrinterWatcherCUPS(this, printer_name); | 458 return new PrinterWatcherCUPS(this, printer_name); |
| 463 } | 459 } |
| 464 | 460 |
| 461 PrintSystem::JobSpooler* PrintSystemCUPS::CreateJobSpooler() { |
| 462 return new JobSpoolerCUPS(this); |
| 463 } |
| 464 |
| 465 std::string PrintSystem::GenerateProxyId() { | 465 std::string PrintSystem::GenerateProxyId() { |
| 466 // TODO(gene): This code should generate a unique id for proxy. ID should be | 466 // TODO(gene): This code should generate a unique id for proxy. ID should be |
| 467 // unique for this user. Rand may return the same number. We'll need to change | 467 // unique for this user. Rand may return the same number. We'll need to change |
| 468 // this in the future. | 468 // this in the future. |
| 469 std::string id("CP_PROXY_"); | 469 std::string id("CP_PROXY_"); |
| 470 id += Uint64ToString(base::RandUint64()); | 470 id += Uint64ToString(base::RandUint64()); |
| 471 return id; | 471 return id; |
| 472 } | 472 } |
| 473 | 473 |
| 474 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( | 474 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 int PrintSystemCUPS::GetJobs(cups_job_t** jobs, const char* name, | 527 int PrintSystemCUPS::GetJobs(cups_job_t** jobs, const char* name, |
| 528 int myjobs, int whichjobs) { | 528 int myjobs, int whichjobs) { |
| 529 if (print_server_url_.is_empty()) { // Use default (local) print server. | 529 if (print_server_url_.is_empty()) { // Use default (local) print server. |
| 530 return cupsGetJobs(jobs, name, myjobs, whichjobs); | 530 return cupsGetJobs(jobs, name, myjobs, whichjobs); |
| 531 } else { | 531 } else { |
| 532 HttpConnectionCUPS http(print_server_url_); | 532 HttpConnectionCUPS http(print_server_url_); |
| 533 return cupsGetJobs2(http.http(), jobs, name, myjobs, whichjobs); | 533 return cupsGetJobs2(http.http(), jobs, name, myjobs, whichjobs); |
| 534 } | 534 } |
| 535 } | 535 } |
| 536 | 536 |
| 537 PlatformJobId PrintSystemCUPS::SpoolPrintJob( |
| 538 const std::string& print_ticket, |
| 539 const FilePath& print_data_file_path, |
| 540 const std::string& print_data_mime_type, |
| 541 const std::string& printer_name, |
| 542 const std::string& job_title) { |
| 543 LOG(INFO) << "CP_CUPS: Spooling print job for: " << printer_name; |
| 544 |
| 545 // We need to store options as char* string for the duration of the |
| 546 // cupsPrintFile2 call. We'll use map here to store options, since |
| 547 // Dictionary value from JSON parser returns wchat_t. |
| 548 std::map<std::string, std::string> options; |
| 549 bool res = ParsePrintTicket(print_ticket, &options); |
| 550 DCHECK(res); // If print ticket is invalid we still print using defaults. |
| 551 |
| 552 std::vector<cups_option_t> cups_options; |
| 553 std::map<std::string, std::string>::iterator it; |
| 554 for (it = options.begin(); it != options.end(); ++it) { |
| 555 cups_option_t opt; |
| 556 opt.name = const_cast<char*>(it->first.c_str()); |
| 557 opt.value = const_cast<char*>(it->second.c_str()); |
| 558 cups_options.push_back(opt); |
| 559 } |
| 560 |
| 561 int job_id = PrintFile(printer_name.c_str(), |
| 562 print_data_file_path.value().c_str(), |
| 563 job_title.c_str(), |
| 564 cups_options.size(), |
| 565 &(cups_options[0])); |
| 566 |
| 567 LOG(INFO) << "CP_CUPS: Job spooled, id: " << job_id; |
| 568 |
| 569 return job_id; |
| 570 } |
| 571 |
| 537 } // namespace cloud_print | 572 } // namespace cloud_print |
| OLD | NEW |