Home | History | Annotate | Download | only in printing
      1 // Copyright 2014 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/printing/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 }  // namespace
     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_(blink::WebPrintScalingOptionSourceSize),
     74     display_header_footer_(false),
     75     title_(base::ASCIIToUTF16("title")),
     76     url_(base::ASCIIToUTF16("url")),
     77     use_invalid_settings_(false) {
     78   page_size_.SetSize(static_cast<int>(8.5 * dpi_),
     79                      static_cast<int>(11.0 * dpi_));
     80   content_size_.SetSize(static_cast<int>((7.5 * dpi_)),
     81                           static_cast<int>((10.0 * dpi_)));
     82   margin_left_ = margin_top_ = static_cast<int>(0.5 * dpi_);
     83   printable_area_.SetRect(static_cast<int>(0.25 * dpi_),
     84                           static_cast<int>(0.25 *dpi_),
     85                           static_cast<int>(8 * dpi_),
     86                           static_cast<int>(10.5 * dpi_));
     87 }
     88 
     89 MockPrinter::~MockPrinter() {
     90 }
     91 
     92 void MockPrinter::ResetPrinter() {
     93   printer_status_ = PRINTER_READY;
     94   document_cookie_ = -1;
     95 }
     96 
     97 void MockPrinter::GetDefaultPrintSettings(PrintMsg_Print_Params* params) {
     98   // Verify this printer is not processing a job.
     99   // Sorry, this mock printer is very fragile.
    100   EXPECT_EQ(-1, document_cookie_);
    101 
    102   // Assign a unit document cookie and set the print settings.
    103   document_cookie_ = CreateDocumentCookie();
    104   params->Reset();
    105   SetPrintParams(params);
    106 }
    107 
    108 void MockPrinter::SetDefaultPrintSettings(const PrintMsg_Print_Params& params) {
    109   dpi_ = params.dpi;
    110   max_shrink_ = params.max_shrink;
    111   min_shrink_ = params.min_shrink;
    112   desired_dpi_ = params.desired_dpi;
    113   selection_only_ = params.selection_only;
    114   should_print_backgrounds_ = params.should_print_backgrounds;
    115   page_size_ = params.page_size;
    116   content_size_ = params.content_size;
    117   printable_area_ = params.printable_area;
    118   margin_left_ = params.margin_left;
    119   margin_top_ = params.margin_top;
    120   display_header_footer_ = params.display_header_footer;
    121   title_ = params.title;
    122   url_ = params.url;
    123 }
    124 
    125 void MockPrinter::UseInvalidSettings() {
    126   use_invalid_settings_ = true;
    127   PrintMsg_Print_Params empty_param;
    128   SetDefaultPrintSettings(empty_param);
    129 }
    130 
    131 void MockPrinter::UseInvalidPageSize() {
    132   page_size_.SetSize(0, 0);
    133 }
    134 
    135 void MockPrinter::UseInvalidContentSize() {
    136   content_size_.SetSize(0, 0);
    137 }
    138 
    139 void MockPrinter::ScriptedPrint(int cookie,
    140                                 int expected_pages_count,
    141                                 bool has_selection,
    142                                 PrintMsg_PrintPages_Params* settings) {
    143   // Verify the input parameters.
    144   EXPECT_EQ(document_cookie_, cookie);
    145 
    146   settings->Reset();
    147 
    148   settings->params.dpi = dpi_;
    149   settings->params.max_shrink = max_shrink_;
    150   settings->params.min_shrink = min_shrink_;
    151   settings->params.desired_dpi = desired_dpi_;
    152   settings->params.selection_only = selection_only_;
    153   settings->params.should_print_backgrounds = should_print_backgrounds_;
    154   settings->params.document_cookie = document_cookie_;
    155   settings->params.page_size = page_size_;
    156   settings->params.content_size = content_size_;
    157   settings->params.printable_area = printable_area_;
    158   settings->params.is_first_request = is_first_request_;
    159   settings->params.print_scaling_option = print_scaling_option_;
    160   settings->params.print_to_pdf = print_to_pdf_;
    161   settings->params.preview_request_id = preview_request_id_;
    162   settings->params.display_header_footer = display_header_footer_;
    163   settings->params.title = title_;
    164   settings->params.url = url_;
    165   printer_status_ = PRINTER_PRINTING;
    166 }
    167 
    168 void MockPrinter::UpdateSettings(int cookie,
    169                                  PrintMsg_PrintPages_Params* params,
    170                                  const std::vector<int>& pages,
    171                                  int margins_type) {
    172   if (document_cookie_ == -1) {
    173     document_cookie_ = CreateDocumentCookie();
    174   }
    175   params->Reset();
    176   params->pages = pages;
    177   SetPrintParams(&(params->params));
    178   UpdateMargins(margins_type, dpi_, &(params->params));
    179   printer_status_ = PRINTER_PRINTING;
    180 }
    181 
    182 void MockPrinter::SetPrintedPagesCount(int cookie, int number_pages) {
    183   // Verify the input parameter and update the printer status so that the
    184   // RenderViewTest class can verify the this function finishes without errors.
    185   EXPECT_EQ(document_cookie_, cookie);
    186   EXPECT_EQ(PRINTER_PRINTING, printer_status_);
    187   EXPECT_EQ(0, number_pages_);
    188   EXPECT_EQ(0, page_number_);
    189 
    190   // Initialize the job status.
    191   number_pages_ = number_pages;
    192   page_number_ = 0;
    193   pages_.clear();
    194 }
    195 
    196 void MockPrinter::PrintPage(const PrintHostMsg_DidPrintPage_Params& params) {
    197   // Verify the input parameter and update the printer status so that the
    198   // RenderViewTest class can verify the this function finishes without errors.
    199   EXPECT_EQ(PRINTER_PRINTING, printer_status_);
    200   EXPECT_EQ(document_cookie_, params.document_cookie);
    201   EXPECT_EQ(page_number_, params.page_number);
    202   EXPECT_LE(params.page_number, number_pages_);
    203 
    204 #if defined(OS_WIN) || defined(OS_MACOSX)
    205   // Load the data sent from a RenderView object and create a PageData object.
    206   // We duplicate the given file handle when creating a base::SharedMemory
    207   // instance so that its destructor closes the copy.
    208   EXPECT_GT(params.data_size, 0U);
    209 #if defined(OS_WIN)
    210   base::SharedMemory metafile_data(params.metafile_data_handle, true,
    211                                    GetCurrentProcess());
    212 #elif defined(OS_MACOSX)
    213   base::SharedMemory metafile_data(params.metafile_data_handle, true);
    214 #endif
    215   metafile_data.Map(params.data_size);
    216 #if defined(OS_MACOSX)
    217   printing::PdfMetafileCg metafile;
    218 #else
    219   printing::NativeMetafile metafile;
    220 #endif
    221   metafile.InitFromData(metafile_data.memory(), params.data_size);
    222   printing::Image image(metafile);
    223   MockPrinterPage* page_data = new MockPrinterPage(metafile_data.memory(),
    224                                                    params.data_size,
    225                                                    image);
    226   scoped_refptr<MockPrinterPage> page(page_data);
    227   pages_.push_back(page);
    228 #endif
    229 
    230   // We finish printing a printing job.
    231   // Reset the job status and the printer status.
    232   ++page_number_;
    233   if (number_pages_ == page_number_)
    234     ResetPrinter();
    235 }
    236 
    237 int MockPrinter::GetPrintedPages() const {
    238   if (printer_status_ != PRINTER_READY)
    239     return -1;
    240   return page_number_;
    241 }
    242 
    243 const MockPrinterPage* MockPrinter::GetPrintedPage(unsigned int pageno) const {
    244   if (pages_.size() > pageno)
    245     return pages_[pageno].get();
    246   else
    247     return NULL;
    248 }
    249 
    250 int MockPrinter::GetWidth(unsigned int page) const {
    251   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    252     return -1;
    253   return pages_[page]->width();
    254 }
    255 
    256 int MockPrinter::GetHeight(unsigned int page) const {
    257   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    258     return -1;
    259   return pages_[page]->height();
    260 }
    261 
    262 bool MockPrinter::GetBitmapChecksum(
    263     unsigned int page, std::string* checksum) const {
    264   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    265     return false;
    266   *checksum = pages_[page]->image().checksum();
    267   return true;
    268 }
    269 
    270 bool MockPrinter::SaveSource(
    271     unsigned int page, const base::FilePath& filepath) const {
    272   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    273     return false;
    274   const uint8* source_data = pages_[page]->source_data();
    275   uint32 source_size = pages_[page]->source_size();
    276   base::WriteFile(filepath, reinterpret_cast<const char*>(source_data),
    277                   source_size);
    278   return true;
    279 }
    280 
    281 bool MockPrinter::SaveBitmap(
    282     unsigned int page, const base::FilePath& filepath) const {
    283   if (printer_status_ != PRINTER_READY || page >= pages_.size())
    284     return false;
    285 
    286   pages_[page]->image().SaveToPng(filepath);
    287   return true;
    288 }
    289 
    290 int MockPrinter::CreateDocumentCookie() {
    291   return use_invalid_settings_ ? 0 : ++current_document_cookie_;
    292 }
    293 
    294 void MockPrinter::SetPrintParams(PrintMsg_Print_Params* params) {
    295   params->dpi = dpi_;
    296   params->max_shrink = max_shrink_;
    297   params->min_shrink = min_shrink_;
    298   params->desired_dpi = desired_dpi_;
    299   params->selection_only = selection_only_;
    300   params->should_print_backgrounds = should_print_backgrounds_;
    301   params->document_cookie = document_cookie_;
    302   params->page_size = page_size_;
    303   params->content_size = content_size_;
    304   params->printable_area = printable_area_;
    305   params->margin_left = margin_left_;
    306   params->margin_top = margin_top_;
    307   params->is_first_request = is_first_request_;
    308   params->print_scaling_option = print_scaling_option_;
    309   params->print_to_pdf = print_to_pdf_;
    310   params->preview_request_id = preview_request_id_;
    311   params->display_header_footer = display_header_footer_;
    312   params->title = title_;
    313   params->url = url_;
    314 }
    315