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 } // 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_(ASCIIToUTF16("title")), 76 url_(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 file_util::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