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

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

Issue 9693064: ScopedPrinterInfoSetter on crash prone blocks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months 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) 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>
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/bind.h" 16 #include "base/bind.h"
17 #include "base/file_path.h" 17 #include "base/file_path.h"
18 #include "base/json/json_reader.h" 18 #include "base/json/json_reader.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/md5.h" 20 #include "base/md5.h"
21 #include "base/memory/scoped_ptr.h" 21 #include "base/memory/scoped_ptr.h"
22 #include "base/message_loop.h" 22 #include "base/message_loop.h"
23 #include "base/rand_util.h" 23 #include "base/rand_util.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/utf_string_conversions.h" 26 #include "base/utf_string_conversions.h"
27 #include "base/values.h" 27 #include "base/values.h"
28 #include "chrome/common/child_process_logging.h"
28 #include "chrome/service/cloud_print/cloud_print_consts.h" 29 #include "chrome/service/cloud_print/cloud_print_consts.h"
29 #include "chrome/service/cloud_print/cloud_print_helpers.h" 30 #include "chrome/service/cloud_print/cloud_print_helpers.h"
30 #include "googleurl/src/gurl.h" 31 #include "googleurl/src/gurl.h"
31 #include "grit/generated_resources.h" 32 #include "grit/generated_resources.h"
32 #include "printing/backend/cups_helper.h" 33 #include "printing/backend/cups_helper.h"
33 #include "printing/backend/print_backend.h" 34 #include "printing/backend/print_backend.h"
34 #include "printing/backend/print_backend_consts.h" 35 #include "printing/backend/print_backend_consts.h"
35 #include "ui/base/l10n/l10n_util.h" 36 #include "ui/base/l10n/l10n_util.h"
36 37
37 namespace { 38 namespace {
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 234
234 DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherCUPS); 235 DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherCUPS);
235 }; 236 };
236 237
237 class PrinterWatcherCUPS 238 class PrinterWatcherCUPS
238 : public PrintSystem::PrinterWatcher { 239 : public PrintSystem::PrinterWatcher {
239 public: 240 public:
240 PrinterWatcherCUPS(PrintSystemCUPS* print_system, 241 PrinterWatcherCUPS(PrintSystemCUPS* print_system,
241 const std::string& printer_name) 242 const std::string& printer_name)
242 : printer_name_(printer_name), 243 : printer_name_(printer_name),
243 delegate_(NULL), 244 delegate_(NULL),
244 print_system_(print_system) { 245 print_system_(print_system) {
245 } 246 }
246 247
247 ~PrinterWatcherCUPS() { 248 ~PrinterWatcherCUPS() {
248 StopWatching(); 249 StopWatching();
249 } 250 }
250 251
251 // PrintSystem::PrinterWatcher implementation. 252 // PrintSystem::PrinterWatcher implementation.
252 virtual bool StartWatching( 253 virtual bool StartWatching(
253 PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE{ 254 PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE{
255 scoped_refptr<printing::PrintBackend> print_backend(
256 printing::PrintBackend::CreateInstance(NULL));
257 child_process_logging::ScopedPrinterInfoSetter prn_info(
258 print_backend->GetPrinterDriverInfo(printer_name_));
254 if (delegate_ != NULL) 259 if (delegate_ != NULL)
255 StopWatching(); 260 StopWatching();
256 delegate_ = delegate; 261 delegate_ = delegate;
257 settings_hash_ = GetSettingsHash(); 262 settings_hash_ = GetSettingsHash();
258 // Schedule next job status update. 263 // Schedule next job status update.
259 MessageLoop::current()->PostDelayedTask( 264 MessageLoop::current()->PostDelayedTask(
260 FROM_HERE, 265 FROM_HERE,
261 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this), 266 base::Bind(&PrinterWatcherCUPS::JobStatusUpdate, this),
262 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds)); 267 base::TimeDelta::FromSeconds(kJobUpdateTimeoutSeconds));
263 // Schedule next printer check. 268 // Schedule next printer check.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 to_hash += it->second; 338 to_hash += it->second;
334 } 339 }
335 340
336 to_hash += caps.printer_capabilities; 341 to_hash += caps.printer_capabilities;
337 to_hash += caps.caps_mime_type; 342 to_hash += caps.caps_mime_type;
338 to_hash += caps.printer_defaults; 343 to_hash += caps.printer_defaults;
339 to_hash += caps.defaults_mime_type; 344 to_hash += caps.defaults_mime_type;
340 345
341 return base::MD5String(to_hash); 346 return base::MD5String(to_hash);
342 } 347 }
343
344 std::string printer_name_; 348 std::string printer_name_;
345 PrintSystem::PrinterWatcher::Delegate* delegate_; 349 PrintSystem::PrinterWatcher::Delegate* delegate_;
346 scoped_refptr<PrintSystemCUPS> print_system_; 350 scoped_refptr<PrintSystemCUPS> print_system_;
347 std::string settings_hash_; 351 std::string settings_hash_;
348 352
349 DISALLOW_COPY_AND_ASSIGN(PrinterWatcherCUPS); 353 DISALLOW_COPY_AND_ASSIGN(PrinterWatcherCUPS);
350 }; 354 };
351 355
352 class JobSpoolerCUPS : public PrintSystem::JobSpooler { 356 class JobSpoolerCUPS : public PrintSystem::JobSpooler {
353 public: 357 public:
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 509
506 bool PrintSystemCUPS::ValidatePrintTicket(const std::string& printer_name, 510 bool PrintSystemCUPS::ValidatePrintTicket(const std::string& printer_name,
507 const std::string& print_ticket_data) { 511 const std::string& print_ticket_data) {
508 DCHECK(initialized_); 512 DCHECK(initialized_);
509 scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket_data, 513 scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket_data,
510 false)); 514 false));
511 return ticket_value != NULL && ticket_value->IsType(Value::TYPE_DICTIONARY); 515 return ticket_value != NULL && ticket_value->IsType(Value::TYPE_DICTIONARY);
512 } 516 }
513 517
514 // Print ticket on linux is a JSON string containing only one dictionary. 518 // Print ticket on linux is a JSON string containing only one dictionary.
515 bool PrintSystemCUPS::ParsePrintTicket(const std::string& print_ticket, 519 bool PrintSystemCUPS::ParsePrintTicket(
516 std::map<std::string, std::string>* options) { 520 const std::string& print_ticket,
521 std::map<std::string, std::string>* options) {
517 DCHECK(options); 522 DCHECK(options);
518 scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket, false)); 523 scoped_ptr<Value> ticket_value(base::JSONReader::Read(print_ticket, false));
519 if (ticket_value == NULL || !ticket_value->IsType(Value::TYPE_DICTIONARY)) 524 if (ticket_value == NULL || !ticket_value->IsType(Value::TYPE_DICTIONARY))
520 return false; 525 return false;
521 526
522 options->clear(); 527 options->clear();
523 DictionaryValue* ticket_dict = 528 DictionaryValue* ticket_dict =
524 static_cast<DictionaryValue*>(ticket_value.get()); 529 static_cast<DictionaryValue*>(ticket_value.get());
525 DictionaryValue::key_iterator it(ticket_dict->begin_keys()); 530 DictionaryValue::key_iterator it(ticket_dict->begin_keys());
526 for (; it != ticket_dict->end_keys(); ++it) { 531 for (; it != ticket_dict->end_keys(); ++it) {
(...skipping 18 matching lines...) Expand all
545 return false; 550 return false;
546 551
547 PrintServerInfoCUPS::CapsMap::iterator caps_it = 552 PrintServerInfoCUPS::CapsMap::iterator caps_it =
548 server_info->caps_cache.find(printer_name); 553 server_info->caps_cache.find(printer_name);
549 if (caps_it != server_info->caps_cache.end()) { 554 if (caps_it != server_info->caps_cache.end()) {
550 *printer_info = caps_it->second; 555 *printer_info = caps_it->second;
551 return true; 556 return true;
552 } 557 }
553 558
554 // TODO(gene): Retry multiple times in case of error. 559 // TODO(gene): Retry multiple times in case of error.
560 child_process_logging::ScopedPrinterInfoSetter prn_info(
561 server_info->backend->GetPrinterDriverInfo(short_printer_name));
555 if (!server_info->backend->GetPrinterCapsAndDefaults(short_printer_name, 562 if (!server_info->backend->GetPrinterCapsAndDefaults(short_printer_name,
556 printer_info) ) { 563 printer_info) ) {
557 return false; 564 return false;
558 } 565 }
559 566
560 server_info->caps_cache[printer_name] = *printer_info; 567 server_info->caps_cache[printer_name] = *printer_info;
561 return true; 568 return true;
562 } 569 }
563 570
564 bool PrintSystemCUPS::GetJobDetails(const std::string& printer_name, 571 bool PrintSystemCUPS::GetJobDetails(const std::string& printer_name,
565 PlatformJobId job_id, 572 PlatformJobId job_id,
566 PrintJobDetails *job_details) { 573 PrintJobDetails *job_details) {
567 DCHECK(initialized_); 574 DCHECK(initialized_);
568 DCHECK(job_details); 575 DCHECK(job_details);
569 576
570 std::string short_printer_name; 577 std::string short_printer_name;
571 PrintServerInfoCUPS* server_info = 578 PrintServerInfoCUPS* server_info =
572 FindServerByFullName(printer_name, &short_printer_name); 579 FindServerByFullName(printer_name, &short_printer_name);
573 if (!server_info) 580 if (!server_info)
574 return false; 581 return false;
575 582
583 child_process_logging::ScopedPrinterInfoSetter prn_info(
584 server_info->backend->GetPrinterDriverInfo(short_printer_name));
576 cups_job_t* jobs = NULL; 585 cups_job_t* jobs = NULL;
577 int num_jobs = GetJobs(&jobs, server_info->url, 586 int num_jobs = GetJobs(&jobs, server_info->url,
578 short_printer_name.c_str(), 1, -1); 587 short_printer_name.c_str(), 1, -1);
579 bool error = (num_jobs == 0) && (cupsLastError() > IPP_OK_EVENTS_COMPLETE); 588 bool error = (num_jobs == 0) && (cupsLastError() > IPP_OK_EVENTS_COMPLETE);
580 if (error) { 589 if (error) {
581 VLOG(1) << "CP_CUPS: Error getting jobs from CUPS server. Printer:" 590 VLOG(1) << "CP_CUPS: Error getting jobs from CUPS server. Printer:"
582 << printer_name 591 << printer_name
583 << " Error: " 592 << " Error: "
584 << static_cast<int>(cupsLastError()); 593 << static_cast<int>(cupsLastError());
585 return false; 594 return false;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 bool* dry_run) { 740 bool* dry_run) {
732 DCHECK(initialized_); 741 DCHECK(initialized_);
733 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name; 742 VLOG(1) << "CP_CUPS: Spooling print job for: " << printer_name;
734 743
735 std::string short_printer_name; 744 std::string short_printer_name;
736 PrintServerInfoCUPS* server_info = 745 PrintServerInfoCUPS* server_info =
737 FindServerByFullName(printer_name, &short_printer_name); 746 FindServerByFullName(printer_name, &short_printer_name);
738 if (!server_info) 747 if (!server_info)
739 return false; 748 return false;
740 749
750 child_process_logging::ScopedPrinterInfoSetter prn_info(
751 server_info->backend->GetPrinterDriverInfo(printer_name));
752
741 // We need to store options as char* string for the duration of the 753 // We need to store options as char* string for the duration of the
742 // cupsPrintFile2 call. We'll use map here to store options, since 754 // cupsPrintFile2 call. We'll use map here to store options, since
743 // Dictionary value from JSON parser returns wchat_t. 755 // Dictionary value from JSON parser returns wchat_t.
744 std::map<std::string, std::string> options; 756 std::map<std::string, std::string> options;
745 bool res = ParsePrintTicket(print_ticket, &options); 757 bool res = ParsePrintTicket(print_ticket, &options);
746 DCHECK(res); // If print ticket is invalid we still print using defaults. 758 DCHECK(res); // If print ticket is invalid we still print using defaults.
747 759
748 // Check if this is a dry run (test) job. 760 // Check if this is a dry run (test) job.
749 *dry_run = CloudPrintHelpers::IsDryRunJob(tags); 761 *dry_run = CloudPrintHelpers::IsDryRunJob(tags);
750 if (*dry_run) { 762 if (*dry_run) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 830
819 void PrintSystemCUPS::RunCapsCallback( 831 void PrintSystemCUPS::RunCapsCallback(
820 const PrinterCapsAndDefaultsCallback& callback, 832 const PrinterCapsAndDefaultsCallback& callback,
821 bool succeeded, 833 bool succeeded,
822 const std::string& printer_name, 834 const std::string& printer_name,
823 const printing::PrinterCapsAndDefaults& printer_info) { 835 const printing::PrinterCapsAndDefaults& printer_info) {
824 callback.Run(succeeded, printer_name, printer_info); 836 callback.Run(succeeded, printer_name, printer_info);
825 } 837 }
826 838
827 } // namespace cloud_print 839 } // namespace cloud_print
OLDNEW
« no previous file with comments | « chrome/browser/printing/print_system_task_proxy.cc ('k') | chrome/service/cloud_print/print_system_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698