Home | History | Annotate | Download | only in renderer
      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/renderer/mock_printer.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/file_util.h"
      9 #include "base/memory/shared_memory.h"
     10 #include "base/strings/string16.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "chrome/common/print_messages.h"
     13 #include "ipc/ipc_message_utils.h"
     14 #include "printing/metafile_impl.h"
     15 #include "printing/units.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 #if defined(OS_MACOSX)
     19 #include "printing/pdf_metafile_cg_mac.h"
     20 #endif
     21 
     22 namespace {
     23 
     24 void UpdateMargins(int margins_type, int dpi, PrintMsg_Print_Params* params) {
     25   if (margins_type == printing::NO_MARGINS) {
     26     params->content_size.SetSize(static_cast<int>((8.5 * dpi)),
     27                                  static_cast<int>((11.0 * dpi)));
     28     params->margin_left = 0;
     29     params->margin_top = 0;
     30   } else if (margins_type == printing::PRINTABLE_AREA_MARGINS) {
     31     params->content_size.SetSize(static_cast<int>((8.0 * dpi)),
     32                                  static_cast<int>((10.5 * dpi)));
     33     params->margin_left = static_cast<int>(0.25 * dpi);
     34     params->margin_top = static_cast<int>(0.25 * dpi);
     35   } else if (margins_type == printing::CUSTOM_MARGINS) {
     36     params->content_size.SetSize(static_cast<int>((7.9 * dpi)),
     37                                  static_cast<int>((10.4 * dpi)));
     38     params->margin_left = static_cast<int>(0.30 * dpi);
     39     params->margin_top = static_cast<int>(0.30 * dpi);
     40   }
     41 }
     42 
     43 } // end
     44 
     45 MockPrinterPage::MockPrinterPage(const void* source_data,
     46                                  uint32 source_size,
     47                                  const printing::Image& image)
     48     : source_size_(source_size),
     49       image_(image) {
     50   // Create copies of the source data
     51   source_data_.reset(new uint8[source_size]);
     52   if (source_data_.get())
     53     memcpy(source_data_.get(), source_data, source_size);
     54 }
     55 
     56 MockPrinterPage::~MockPrinterPage() {}
     57 
     58 MockPrinter::MockPrinter()
     59   : dpi_(printing::kPointsPerInch),
     60     max_shrink_(2.0),
     61     min_shrink_(1.25),
     62     desired_dpi_(printing::kPointsPerInch),
     63     selection_only_(false),
     64     should_print_backgrounds_(false),
     65     document_cookie_(-1),
     66     current_document_cookie_(0),
     67     printer_status_(PRINTER_READY),
     68     number_pages_(0),
     69     page_number_(0),
     70     is_first_request_(true),
     71     print_to_pdf_(false),
     72     preview_request_id_(0),
     73     print_scaling_option_(WebKit::WebPrintScalingOptionSourceSize),
     74     display_header_footer_(false),
     75     date_(ASCIIToUTF16("date")),
     76     title_(ASCIIToUTF16("title")),
     77     url_(ASCIIToUTF16("url")),
     78     use_invalid_settings_(false) {
     79   page_size_.SetSize(static_cast<int>(8.5 * dpi_),
     80                      static_cast<int>(11.0 * dpi_));
     81   content_size_.SetSize(static_cast<int>((7.5 * dpi_)),
     82                           static_cast<int>((10.0 * dpi_)));
     83   margin_left_ = margin_top_ = static_cast<int>(0.5 * dpi_);
     84   printable_area_.SetRect(static_cast<int>(0.25 * dpi_),
     85                           static_cast<int>(0.25 *dpi_),
     86                           static_cast<int>(8 * dpi_),
     87                           static_cast<int>(10.5 * dpi_));
     88 }
     89 
     90 MockPrinter::~MockPrinter() {
     91 }
     92 
     93 void MockPrinter::ResetPrinter() {
     94   printer_status_ = PRINTER_READY;
     95   document_cookie_ = -1;
     96 }
     97 
     98 void MockPrinter::GetDefaultPrintSettings(PrintMsg_Print_Params* params) {
     99   // Verify this printer is not processing a job.
    100   // Sorry, this mock printer is very fragile.
    101   EXPECT_EQ(-1, document_cookie_);
    102 
    103   // Assign a unit document cookie and set the print settings.
    104   document_cookie_ = CreateDocumentCookie();
    105   params->Reset();
    106   SetPrintParams(params);
    107 }
    108 
    109 void MockPrinter::SetDefaultPrintSettings(const PrintMsg_Print_Params& params) {
    110   dpi_ = params.dpi;
    111   max_shrink_ = params.max_shrink;
    112   min_shrink_ = params.min_shrink;
    113   desired_dpi_ = params.desired_dpi;
    114   selection_only_ = params.selection_only;
    115   should_print_backgrounds_ = params.should_print_backgrounds;
    116   page_size_ = params.page_size;
    117   content_size_ = params.content_size;
    118   printable_area_ = params.printable_area;
    119   margin_left_ = params.margin_left;
    120   margin_top_ = params.margin_top;
    121   display_header_footer_ = params.display_header_footer;
    122   date_ = params.date;
    123   title_ = params.title;
    124   url_ = params.url;
    125 }
    126 
    127 void MockPrinter::UseInvalidSettings() {
    128   use_invalid_settings_ = true;
    129   PrintMsg_Print_Params empty_param;
    130   SetDefaultPrintSettings(empty_param);
    131 }
    132 
    133 void MockPrinter::UseInvalidPageSize() {
    134   page_size_.SetSize(0, 0);
    135 }
    136 
    137 void MockPrinter::UseInvalidContentSize() {
    138   content_size_.SetSize(0, 0);
    139 }
    140 
    141 void MockPrinter::ScriptedPrint(int cookie,
    142                                 int expected_pages_count,
    143                                 bool has_selection,
    144                                 PrintMsg_PrintPages_Params* settings) {
    145   // Verify the input parameters.
    146   EXPECT_EQ(document_cookie_, cookie);
    147 
    148   settings->Reset();
    149 
    150   settings->params.dpi = dpi_;
    151   settings->params.max_shrink = max_shrink_;
    152   settings->params.min_shrink = min_shrink_;
    153   settings->params.desired_dpi = desired_dpi_;
    154   settings->params.selection_only = selection_only_;
    155   settings->params.should_print_backgrounds = should_print_backgrounds_;
    156   settings->params.document_cookie = document_cookie_;
    157   settings->params.page_size = page_size_;
    158   settings->params.content_size = content_size_;
    159   settings->params.printable_area = printable_area_;
    160   settings->params.is_first_request = is_first_request_;
    161   settings->params.print_scaling_option = print_scaling_option_;
    162   settings->params.print_to_pdf = print_to_pdf_;
    163   settings->params.preview_request_id = preview_request_id_;
    164   settings->params.display_header_footer = display_header_footer_;
    165   settings->params.date = date_;
    166   settings->params.title = title_;
    167   settings->params.url = url_;
    168   printer_status_ = PRINTER_PRINTING;
    169 }
    170 
    171 void MockPrinter::UpdateSettings(int cookie,
    172                                  PrintMsg_PrintPages_Params* params,
    173                                  const std::vector<int>& pages,
    174                                  int margins_type) {
    175   if (document_cookie_ == -1) {
    176     document_cookie_ = CreateDocumentCookie();
    177   }
    178   params->Reset();
    179   params->pages = pages;
    180   SetPrintParams(&(params->params));
    181   UpdateMargins(margins_type, dpi_, &(params->params));
    182   printer_status_ = PRINTER_PRINTING;
    183 }
    184 
    185 void MockPrinter::SetPrintedPagesCount(int cookie, int number_pages) {
    186   // Verify the input parameter and update the printer status so that the
    187   // RenderViewTest class can verify the this function finishes without errors.
    188   EXPECT_EQ(document_cookie_, cookie);
    189   EXPECT_EQ(PRINTER_PRINTING, printer_status_);
    190   EXPECT_EQ(0, number_pages_);
    191   EXPECT_EQ(0, page_number_);
    192 
    193   // Initialize the job status.
    194   number_pages_ = number_pages;
    195   page_number_ = 0;
    196   pages_.clear();
    197 }
    198 
    199 void MockPrinter::PrintPage(const PrintHostMsg_DidPrintPage_Params& params) {
    200   // Verify the input parameter and update the printer status so that the
    201   // RenderViewTest class can verify the this function finishes without errors.
    202   EXPECT_EQ(PRINTER_PRINTING, printer_status_);
    203   EXPECT_EQ(document_cookie_, params.document_cookie);
    204   EXPECT_EQ(page_number_, params.page_number);
    205   EXPECT_LE(params.page_number, number_pages_);
    206 
    207 #if defined(OS_WIN) || defined(OS_MACOSX)
    208   // Load the data sent from a RenderView object and create a PageData object.
    209   // We duplicate the given file handle when creating a base::SharedMemory
    210   // instance so that its destructor closes the copy.
    211   EXPECT_GT(params.data_size, 0U);
    212 #if defined(OS_WIN)
    213   base::SharedMemory metafile_data(params.metafile_data_handle, true,
    214                                    GetCurrentProcess());
    215 #elif defined(OS_MACOSX)
    216   base::SharedMemory metafile_data(params.metafile_data_handle, true);
    217 #endif
    218   metafile_data.Map(params.data_size);
    219 #if defined(OS_MACOSX)
    220   printing::PdfMetafileCg metafile;
    221 #else
    222   printing::NativeMetafile metafile;
    223 #endif
    224   metafile.InitFromData(metafile_data.memory(), params.data_size);
    225   printing::Image image(metafile);
    226   MockPrinterPage* page_data = new MockPrinterPage(metafile_data.memory(),
    227                                                    params.data_size,
    228                                                    image);
    229   if (!page_data) {
    230     printer_status_ = PRINTER_ERROR;
    231     return;
    232   }
    233 
    234   scoped_refptr<MockPrinterPage> page(page_data);
    235   pages_.push_back(page);
    236 #endif
    237 
    238   // We finish printing a printing job.
    239   // Reset the job status and the printer status.
    240   ++page_number_;
    241   if (number_pages_ == page_number_)
    242     ResetPrinter();
    243 }
    244 
    245 int MockPrinter::GetPrintedPages() const {
    246   if (printer_status_ != PRINTER_READY)
    247     return -1;
    248   return page_number_;
    249 }
    250 
    251 const MockPrinterPage* MockPrinter::GetPrintedPage(unsigned int pageno) const {
    252   if (pages_.size() > pageno)
    253     return pages_[pageno].get();
    254   else
    255     return NULL;
    256 }
    257 
    258 int MockPrinter::GetWidth(unsigned int page) const {
    259   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    260     return -1;
    261   return pages_[page]->width();
    262 }
    263 
    264 int MockPrinter::GetHeight(unsigned int page) const {
    265   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    266     return -1;
    267   return pages_[page]->height();
    268 }
    269 
    270 bool MockPrinter::GetBitmapChecksum(
    271     unsigned int page, std::string* checksum) const {
    272   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    273     return false;
    274   *checksum = pages_[page]->image().checksum();
    275   return true;
    276 }
    277 
    278 bool MockPrinter::SaveSource(
    279     unsigned int page, const base::FilePath& filepath) const {
    280   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    281     return false;
    282   const uint8* source_data = pages_[page]->source_data();
    283   uint32 source_size = pages_[page]->source_size();
    284   file_util::WriteFile(filepath, reinterpret_cast<const char*>(source_data),
    285                        source_size);
    286   return true;
    287 }
    288 
    289 bool MockPrinter::SaveBitmap(
    290     unsigned int page, const base::FilePath& filepath) const {
    291   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    292     return false;
    293 
    294   pages_[page]->image().SaveToPng(filepath);
    295   return true;
    296 }
    297 
    298 int MockPrinter::CreateDocumentCookie() {
    299   return use_invalid_settings_ ? 0 : ++current_document_cookie_;
    300 }
    301 
    302 void MockPrinter::SetPrintParams(PrintMsg_Print_Params* params) {
    303   params->dpi = dpi_;
    304   params->max_shrink = max_shrink_;
    305   params->min_shrink = min_shrink_;
    306   params->desired_dpi = desired_dpi_;
    307   params->selection_only = selection_only_;
    308   params->should_print_backgrounds = should_print_backgrounds_;
    309   params->document_cookie = document_cookie_;
    310   params->page_size = page_size_;
    311   params->content_size = content_size_;
    312   params->printable_area = printable_area_;
    313   params->margin_left = margin_left_;
    314   params->margin_top = margin_top_;
    315   params->is_first_request = is_first_request_;
    316   params->print_scaling_option = print_scaling_option_;
    317   params->print_to_pdf = print_to_pdf_;
    318   params->preview_request_id = preview_request_id_;
    319   params->display_header_footer = display_header_footer_;
    320   params->date = date_;
    321   params->title = title_;
    322   params->url = url_;
    323 }
    324