Home | History | Annotate | Download | only in printing
      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