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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/printing/print_system_task_proxy.h" 6 7 #include <ctype.h> 8 9 #include <string> 10 11 #include "base/bind.h" 12 #include "base/metrics/histogram.h" 13 #include "base/values.h" 14 #include "chrome/browser/ui/webui/print_preview/print_preview_handler.h" 15 #include "chrome/common/child_process_logging.h" 16 #include "printing/backend/print_backend.h" 17 #include "printing/print_job_constants.h" 18 #include "printing/print_settings.h" 19 20 #if defined(USE_CUPS) 21 #include <cups/cups.h> 22 #include <cups/ppd.h> 23 #endif 24 25 using content::BrowserThread; 26 27 namespace { 28 29 const char kPrinterId[] = "printerId"; 30 const char kDisableColorOption[] = "disableColorOption"; 31 const char kSetDuplexAsDefault[] = "setDuplexAsDefault"; 32 const char kPrinterColorModelForBlack[] = "printerColorModelForBlack"; 33 const char kPrinterColorModelForColor[] = "printerColorModelForColor"; 34 const char kPrinterDefaultDuplexValue[] = "printerDefaultDuplexValue"; 35 36 } // namespace 37 38 PrintSystemTaskProxy::PrintSystemTaskProxy( 39 const base::WeakPtr<PrintPreviewHandler>& handler, 40 printing::PrintBackend* print_backend, 41 bool has_logged_printers_count) 42 : handler_(handler), 43 print_backend_(print_backend), 44 has_logged_printers_count_(has_logged_printers_count) { 45 } 46 47 PrintSystemTaskProxy::~PrintSystemTaskProxy() { 48 } 49 50 void PrintSystemTaskProxy::GetDefaultPrinter() { 51 VLOG(1) << "Get default printer start"; 52 53 VLOG(1) << "Get default printer finished, found: " 54 << print_backend_->GetDefaultPrinterName(); 55 56 BrowserThread::PostTask( 57 BrowserThread::UI, FROM_HERE, 58 base::Bind(&PrintSystemTaskProxy::SendDefaultPrinter, this, 59 print_backend_->GetDefaultPrinterName(), 60 std::string())); 61 } 62 63 void PrintSystemTaskProxy::SendDefaultPrinter( 64 const std::string& default_printer, 65 const std::string& cloud_print_data) { 66 if (handler_.get()) 67 handler_->SendInitialSettings(default_printer, cloud_print_data); 68 } 69 70 void PrintSystemTaskProxy::EnumeratePrinters() { 71 VLOG(1) << "Enumerate printers start"; 72 ListValue* printers = new ListValue; 73 printing::PrinterList printer_list; 74 print_backend_->EnumeratePrinters(&printer_list); 75 76 if (!has_logged_printers_count_) { 77 // Record the total number of printers. 78 UMA_HISTOGRAM_COUNTS("PrintPreview.NumberOfPrinters", 79 printer_list.size()); 80 } 81 int i = 0; 82 for (printing::PrinterList::iterator iter = printer_list.begin(); 83 iter != printer_list.end(); ++iter, ++i) { 84 DictionaryValue* printer_info = new DictionaryValue; 85 std::string printerName; 86 #if defined(OS_MACOSX) 87 // On Mac, |iter->printer_description| specifies the printer name and 88 // |iter->printer_name| specifies the device name / printer queue name. 89 printerName = iter->printer_description; 90 #else 91 printerName = iter->printer_name; 92 #endif 93 printer_info->SetString(printing::kSettingPrinterName, printerName); 94 printer_info->SetString(printing::kSettingDeviceName, iter->printer_name); 95 VLOG(1) << "Found printer " << printerName 96 << " with device name " << iter->printer_name; 97 printers->Append(printer_info); 98 } 99 VLOG(1) << "Enumerate printers finished, found " << i << " printers"; 100 101 BrowserThread::PostTask( 102 BrowserThread::UI, FROM_HERE, 103 base::Bind(&PrintSystemTaskProxy::SetupPrinterList, this, printers)); 104 } 105 106 void PrintSystemTaskProxy::SetupPrinterList(ListValue* printers) { 107 if (handler_.get()) 108 handler_->SetupPrinterList(*printers); 109 delete printers; 110 } 111 112 void PrintSystemTaskProxy::GetPrinterCapabilities( 113 const std::string& printer_name) { 114 VLOG(1) << "Get printer capabilities start for " << printer_name; 115 child_process_logging::ScopedPrinterInfoSetter prn_info( 116 print_backend_->GetPrinterDriverInfo(printer_name)); 117 118 if (!print_backend_->IsValidPrinter(printer_name)) { 119 // TODO(gene): Notify explicitly if printer is not valid, instead of 120 // failed to get capabilities. 121 BrowserThread::PostTask( 122 BrowserThread::UI, FROM_HERE, 123 base::Bind(&PrintSystemTaskProxy::SendFailedToGetPrinterCapabilities, 124 this, printer_name)); 125 return; 126 } 127 128 printing::PrinterSemanticCapsAndDefaults info; 129 if (!print_backend_->GetPrinterSemanticCapsAndDefaults(printer_name, &info)) { 130 LOG(WARNING) << "Failed to get capabilities for " << printer_name; 131 BrowserThread::PostTask( 132 BrowserThread::UI, FROM_HERE, 133 base::Bind(&PrintSystemTaskProxy::SendFailedToGetPrinterCapabilities, 134 this, printer_name)); 135 return; 136 } 137 138 DictionaryValue settings_info; 139 settings_info.SetString(kPrinterId, printer_name); 140 settings_info.SetBoolean(kDisableColorOption, !info.color_changeable); 141 settings_info.SetBoolean(printing::kSettingSetColorAsDefault, 142 info.color_default); 143 // TODO(gene): Make new capabilities format for Print Preview 144 // that will suit semantic capabiltities better. 145 // Refactor pld API code below 146 if (info.duplex_capable) { 147 settings_info.SetBoolean(kSetDuplexAsDefault, 148 info.duplex_default != printing::SIMPLEX); 149 settings_info.SetInteger(kPrinterDefaultDuplexValue, 150 printing::LONG_EDGE); 151 } else { 152 settings_info.SetBoolean(kSetDuplexAsDefault, false); 153 settings_info.SetInteger(kPrinterDefaultDuplexValue, 154 printing::UNKNOWN_DUPLEX_MODE); 155 } 156 157 BrowserThread::PostTask( 158 BrowserThread::UI, FROM_HERE, 159 base::Bind(&PrintSystemTaskProxy::SendPrinterCapabilities, this, 160 settings_info.DeepCopy())); 161 } 162 163 void PrintSystemTaskProxy::SendPrinterCapabilities( 164 DictionaryValue* settings_info) { 165 if (handler_.get()) 166 handler_->SendPrinterCapabilities(*settings_info); 167 delete settings_info; 168 } 169 170 void PrintSystemTaskProxy::SendFailedToGetPrinterCapabilities( 171 const std::string& printer_name) { 172 if (handler_.get()) 173 handler_->SendFailedToGetPrinterCapabilities(printer_name); 174 } 175