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