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/chrome_mock_render_thread.h" 6 7 #include <vector> 8 9 #include "base/values.h" 10 #include "chrome/renderer/printing/mock_printer.h" 11 #include "extensions/common/extension_messages.h" 12 #include "ipc/ipc_sync_message.h" 13 #include "printing/page_range.h" 14 #include "printing/print_job_constants.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 17 #if defined(OS_CHROMEOS) 18 #include <fcntl.h> 19 20 #include "base/files/file_util.h" 21 #endif 22 23 #if defined(ENABLE_PRINTING) 24 #include "chrome/common/print_messages.h" 25 #endif 26 27 ChromeMockRenderThread::ChromeMockRenderThread() 28 #if defined(ENABLE_PRINTING) 29 : printer_(new MockPrinter), 30 print_dialog_user_response_(true), 31 print_preview_cancel_page_number_(-1), 32 print_preview_pages_remaining_(0) 33 #endif 34 { 35 } 36 37 ChromeMockRenderThread::~ChromeMockRenderThread() { 38 } 39 40 scoped_refptr<base::MessageLoopProxy> 41 ChromeMockRenderThread::GetIOMessageLoopProxy() { 42 return io_message_loop_proxy_; 43 } 44 45 void ChromeMockRenderThread::set_io_message_loop_proxy( 46 const scoped_refptr<base::MessageLoopProxy>& proxy) { 47 io_message_loop_proxy_ = proxy; 48 } 49 50 bool ChromeMockRenderThread::OnMessageReceived(const IPC::Message& msg) { 51 if (content::MockRenderThread::OnMessageReceived(msg)) 52 return true; 53 54 // Some messages we do special handling. 55 bool handled = true; 56 IPC_BEGIN_MESSAGE_MAP(ChromeMockRenderThread, msg) 57 IPC_MESSAGE_HANDLER(ExtensionHostMsg_OpenChannelToExtension, 58 OnOpenChannelToExtension) 59 #if defined(ENABLE_PRINTING) 60 IPC_MESSAGE_HANDLER(PrintHostMsg_GetDefaultPrintSettings, 61 OnGetDefaultPrintSettings) 62 IPC_MESSAGE_HANDLER(PrintHostMsg_ScriptedPrint, OnScriptedPrint) 63 IPC_MESSAGE_HANDLER(PrintHostMsg_UpdatePrintSettings, OnUpdatePrintSettings) 64 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount, 65 OnDidGetPrintedPagesCount) 66 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) 67 IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount, 68 OnDidGetPreviewPageCount) 69 IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage) 70 IPC_MESSAGE_HANDLER(PrintHostMsg_CheckForCancel, OnCheckForCancel) 71 #if defined(OS_WIN) 72 IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection) 73 #endif 74 #if defined(OS_CHROMEOS) 75 IPC_MESSAGE_HANDLER(PrintHostMsg_AllocateTempFileForPrinting, 76 OnAllocateTempFileForPrinting) 77 IPC_MESSAGE_HANDLER(PrintHostMsg_TempFileForPrintingWritten, 78 OnTempFileForPrintingWritten) 79 #endif // defined(OS_CHROMEOS) 80 #endif // defined(ENABLE_PRINTING) 81 IPC_MESSAGE_UNHANDLED(handled = false) 82 IPC_END_MESSAGE_MAP() 83 return handled; 84 } 85 86 void ChromeMockRenderThread::OnOpenChannelToExtension( 87 int routing_id, 88 const ExtensionMsg_ExternalConnectionInfo& info, 89 const std::string& channel_name, 90 bool include_tls_channel_id, 91 int* port_id) { 92 *port_id = 0; 93 } 94 95 #if defined(ENABLE_PRINTING) 96 #if defined(OS_CHROMEOS) 97 void ChromeMockRenderThread::OnAllocateTempFileForPrinting( 98 int render_view_id, 99 base::FileDescriptor* renderer_fd, 100 int* browser_fd) { 101 renderer_fd->fd = *browser_fd = -1; 102 renderer_fd->auto_close = false; 103 104 base::FilePath path; 105 if (base::CreateTemporaryFile(&path)) { 106 int fd = open(path.value().c_str(), O_WRONLY); 107 DCHECK_GE(fd, 0); 108 renderer_fd->fd = *browser_fd = fd; 109 } 110 } 111 112 void ChromeMockRenderThread::OnTempFileForPrintingWritten(int render_view_id, 113 int browser_fd) { 114 close(browser_fd); 115 } 116 #endif // defined(OS_CHROMEOS) 117 118 void ChromeMockRenderThread::OnGetDefaultPrintSettings( 119 PrintMsg_Print_Params* params) { 120 printer_->GetDefaultPrintSettings(params); 121 } 122 123 void ChromeMockRenderThread::OnScriptedPrint( 124 const PrintHostMsg_ScriptedPrint_Params& params, 125 PrintMsg_PrintPages_Params* settings) { 126 if (print_dialog_user_response_) { 127 printer_->ScriptedPrint(params.cookie, 128 params.expected_pages_count, 129 params.has_selection, 130 settings); 131 } 132 } 133 134 void ChromeMockRenderThread::OnDidGetPrintedPagesCount( 135 int cookie, int number_pages) { 136 printer_->SetPrintedPagesCount(cookie, number_pages); 137 } 138 139 void ChromeMockRenderThread::OnDidPrintPage( 140 const PrintHostMsg_DidPrintPage_Params& params) { 141 printer_->PrintPage(params); 142 } 143 144 void ChromeMockRenderThread::OnDidGetPreviewPageCount( 145 const PrintHostMsg_DidGetPreviewPageCount_Params& params) { 146 print_preview_pages_remaining_ = params.page_count; 147 } 148 149 void ChromeMockRenderThread::OnDidPreviewPage( 150 const PrintHostMsg_DidPreviewPage_Params& params) { 151 DCHECK_GE(params.page_number, printing::FIRST_PAGE_INDEX); 152 print_preview_pages_remaining_--; 153 } 154 155 void ChromeMockRenderThread::OnCheckForCancel(int32 preview_ui_id, 156 int preview_request_id, 157 bool* cancel) { 158 *cancel = 159 (print_preview_pages_remaining_ == print_preview_cancel_page_number_); 160 } 161 162 void ChromeMockRenderThread::OnUpdatePrintSettings( 163 int document_cookie, 164 const base::DictionaryValue& job_settings, 165 PrintMsg_PrintPages_Params* params, 166 bool* canceled) { 167 if (canceled) 168 *canceled = false; 169 // Check and make sure the required settings are all there. 170 // We don't actually care about the values. 171 std::string dummy_string; 172 int margins_type = 0; 173 if (!job_settings.GetBoolean(printing::kSettingLandscape, NULL) || 174 !job_settings.GetBoolean(printing::kSettingCollate, NULL) || 175 !job_settings.GetInteger(printing::kSettingColor, NULL) || 176 !job_settings.GetBoolean(printing::kSettingPrintToPDF, NULL) || 177 !job_settings.GetBoolean(printing::kIsFirstRequest, NULL) || 178 !job_settings.GetString(printing::kSettingDeviceName, &dummy_string) || 179 !job_settings.GetInteger(printing::kSettingDuplexMode, NULL) || 180 !job_settings.GetInteger(printing::kSettingCopies, NULL) || 181 !job_settings.GetInteger(printing::kPreviewUIID, NULL) || 182 !job_settings.GetInteger(printing::kPreviewRequestID, NULL) || 183 !job_settings.GetInteger(printing::kSettingMarginsType, &margins_type)) { 184 return; 185 } 186 187 // Just return the default settings. 188 const base::ListValue* page_range_array; 189 printing::PageRanges new_ranges; 190 if (job_settings.GetList(printing::kSettingPageRange, &page_range_array)) { 191 for (size_t index = 0; index < page_range_array->GetSize(); ++index) { 192 const base::DictionaryValue* dict; 193 if (!page_range_array->GetDictionary(index, &dict)) 194 continue; 195 printing::PageRange range; 196 if (!dict->GetInteger(printing::kSettingPageRangeFrom, &range.from) || 197 !dict->GetInteger(printing::kSettingPageRangeTo, &range.to)) { 198 continue; 199 } 200 // Page numbers are 1-based in the dictionary. 201 // Page numbers are 0-based for the printing context. 202 range.from--; 203 range.to--; 204 new_ranges.push_back(range); 205 } 206 } 207 std::vector<int> pages(printing::PageRange::GetPages(new_ranges)); 208 printer_->UpdateSettings(document_cookie, params, pages, margins_type); 209 210 job_settings.GetBoolean(printing::kSettingShouldPrintSelectionOnly, 211 ¶ms->params.selection_only); 212 job_settings.GetBoolean(printing::kSettingShouldPrintBackgrounds, 213 ¶ms->params.should_print_backgrounds); 214 } 215 216 MockPrinter* ChromeMockRenderThread::printer() { 217 return printer_.get(); 218 } 219 220 void ChromeMockRenderThread::set_print_dialog_user_response(bool response) { 221 print_dialog_user_response_ = response; 222 } 223 224 void ChromeMockRenderThread::set_print_preview_cancel_page_number(int page) { 225 print_preview_cancel_page_number_ = page; 226 } 227 228 int ChromeMockRenderThread::print_preview_pages_remaining() const { 229 return print_preview_pages_remaining_; 230 } 231 #endif // defined(ENABLE_PRINTING) 232