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 |