Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: chrome/renderer/print_web_view_helper.cc

Issue 7365003: Print Preview: Make preview generation event driven to eliminate synchronous messages. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix broken test, add more DCHECKs Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/print_web_view_helper.h" 5 #include "chrome/renderer/print_web_view_helper.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/process_util.h" 12 #include "base/process_util.h"
13 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
14 #include "chrome/common/chrome_switches.h" 14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/print_messages.h" 15 #include "chrome/common/print_messages.h"
16 #include "chrome/common/render_messages.h" 16 #include "chrome/common/render_messages.h"
17 #include "chrome/common/url_constants.h" 17 #include "chrome/common/url_constants.h"
18 #include "chrome/renderer/prerender/prerender_helper.h" 18 #include "chrome/renderer/prerender/prerender_helper.h"
19 #include "content/renderer/render_view.h" 19 #include "content/renderer/render_view.h"
20 #include "grit/generated_resources.h" 20 #include "grit/generated_resources.h"
21 #include "printing/metafile.h" 21 #include "printing/metafile_impl.h"
22 #include "printing/print_job_constants.h" 22 #include "printing/print_job_constants.h"
23 #include "printing/units.h" 23 #include "printing/units.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h" 24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h"
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 web_view_->resize(prev_view_size_); 147 web_view_->resize(prev_view_size_);
148 if (WebFrame* web_frame = web_view_->mainFrame()) 148 if (WebFrame* web_frame = web_view_->mainFrame())
149 web_frame->setScrollOffset(prev_scroll_offset_); 149 web_frame->setScrollOffset(prev_scroll_offset_);
150 } 150 }
151 } 151 }
152 152
153 PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view) 153 PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view)
154 : RenderViewObserver(render_view), 154 : RenderViewObserver(render_view),
155 RenderViewObserverTracker<PrintWebViewHelper>(render_view), 155 RenderViewObserverTracker<PrintWebViewHelper>(render_view),
156 print_web_view_(NULL), 156 print_web_view_(NULL),
157 script_initiated_preview_frame_(NULL),
158 context_menu_preview_node_(NULL),
159 user_cancelled_scripted_print_count_(0), 157 user_cancelled_scripted_print_count_(0),
160 notify_browser_of_print_failure_(true), 158 notify_browser_of_print_failure_(true) {
161 preview_page_count_(0) {
162 is_preview_ = switches::IsPrintPreviewEnabled(); 159 is_preview_ = switches::IsPrintPreviewEnabled();
163 } 160 }
164 161
165 PrintWebViewHelper::~PrintWebViewHelper() {} 162 PrintWebViewHelper::~PrintWebViewHelper() {}
166 163
167 // Prints |frame| which called window.print(). 164 // Prints |frame| which called window.print().
168 void PrintWebViewHelper::PrintPage(WebKit::WebFrame* frame) { 165 void PrintWebViewHelper::PrintPage(WebKit::WebFrame* frame) {
169 DCHECK(frame); 166 DCHECK(frame);
170 167
171 // Allow Prerendering to cancel this print request if necessary. 168 // Allow Prerendering to cancel this print request if necessary.
172 if (prerender::PrerenderHelper::IsPrerendering(render_view())) { 169 if (prerender::PrerenderHelper::IsPrerendering(render_view())) {
173 Send(new ViewHostMsg_CancelPrerenderForPrinting(routing_id())); 170 Send(new ViewHostMsg_CancelPrerenderForPrinting(routing_id()));
174 return; 171 return;
175 } 172 }
176 173
177 if (IsScriptInitiatedPrintTooFrequent(frame)) 174 if (IsScriptInitiatedPrintTooFrequent(frame))
178 return; 175 return;
179 IncrementScriptedPrintCount(); 176 IncrementScriptedPrintCount();
180 177
181 if (is_preview_) { 178 if (is_preview_) {
182 script_initiated_preview_frame_ = frame; 179 print_preview_context_.InitWithFrame(frame);
183 context_menu_preview_node_.reset();
184 RequestPrintPreview(); 180 RequestPrintPreview();
185 } else { 181 } else {
186 Print(frame, NULL); 182 Print(frame, NULL);
187 } 183 }
188 } 184 }
189 185
190 bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { 186 bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) {
191 bool handled = true; 187 bool handled = true;
192 IPC_BEGIN_MESSAGE_MAP(PrintWebViewHelper, message) 188 IPC_BEGIN_MESSAGE_MAP(PrintWebViewHelper, message)
193 IPC_MESSAGE_HANDLER(PrintMsg_PrintPages, OnPrintPages) 189 IPC_MESSAGE_HANDLER(PrintMsg_PrintPages, OnPrintPages)
194 IPC_MESSAGE_HANDLER(PrintMsg_InitiatePrintPreview, 190 IPC_MESSAGE_HANDLER(PrintMsg_InitiatePrintPreview,
195 OnInitiatePrintPreview) 191 OnInitiatePrintPreview)
196 IPC_MESSAGE_HANDLER(PrintMsg_PrintNodeUnderContextMenu, 192 IPC_MESSAGE_HANDLER(PrintMsg_PrintNodeUnderContextMenu,
197 OnPrintNodeUnderContextMenu) 193 OnPrintNodeUnderContextMenu)
198 IPC_MESSAGE_HANDLER(PrintMsg_PrintPreview, OnPrintPreview) 194 IPC_MESSAGE_HANDLER(PrintMsg_PrintPreview, OnPrintPreview)
199 IPC_MESSAGE_HANDLER(PrintMsg_PrintForPrintPreview, 195 IPC_MESSAGE_HANDLER(PrintMsg_PrintForPrintPreview,
200 OnPrintForPrintPreview) 196 OnPrintForPrintPreview)
201 IPC_MESSAGE_HANDLER(PrintMsg_PrintingDone, OnPrintingDone) 197 IPC_MESSAGE_HANDLER(PrintMsg_PrintingDone, OnPrintingDone)
202 IPC_MESSAGE_HANDLER(PrintMsg_ResetScriptedPrintCount, 198 IPC_MESSAGE_HANDLER(PrintMsg_ResetScriptedPrintCount,
203 ResetScriptedPrintCount) 199 ResetScriptedPrintCount)
200 IPC_MESSAGE_HANDLER(PrintMsg_ContinuePreview,
201 OnContinuePreview)
kmadhusu 2011/07/15 01:22:46 nit: This argument will fit in the previous line.
Lei Zhang 2011/07/15 01:48:02 Done.
202 IPC_MESSAGE_HANDLER(PrintMsg_CancelPreview,
203 OnCancelPreview)
kmadhusu 2011/07/15 01:22:46 same here
Lei Zhang 2011/07/15 01:48:02 Done.
204 IPC_MESSAGE_HANDLER(PrintMsg_AbortPreview,
205 OnAbortPreview)
kmadhusu 2011/07/15 01:22:46 same here
Lei Zhang 2011/07/15 01:48:02 Done.
204 IPC_MESSAGE_HANDLER(PrintMsg_PreviewPrintingRequestCancelled, 206 IPC_MESSAGE_HANDLER(PrintMsg_PreviewPrintingRequestCancelled,
205 DisplayPrintJobError) 207 DisplayPrintJobError)
206 IPC_MESSAGE_UNHANDLED(handled = false) 208 IPC_MESSAGE_UNHANDLED(handled = false)
207 IPC_END_MESSAGE_MAP() 209 IPC_END_MESSAGE_MAP()
208 return handled; 210 return handled;
209 } 211 }
210 212
211 void PrintWebViewHelper::OnPrintForPrintPreview( 213 void PrintWebViewHelper::OnPrintForPrintPreview(
212 const DictionaryValue& job_settings) { 214 const DictionaryValue& job_settings) {
213 DCHECK(is_preview_); 215 DCHECK(is_preview_);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 } 263 }
262 264
263 void PrintWebViewHelper::OnPrintPages() { 265 void PrintWebViewHelper::OnPrintPages() {
264 WebFrame* frame; 266 WebFrame* frame;
265 if (GetPrintFrame(&frame)) 267 if (GetPrintFrame(&frame))
266 Print(frame, NULL); 268 Print(frame, NULL);
267 } 269 }
268 270
269 void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) { 271 void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) {
270 DCHECK(is_preview_); 272 DCHECK(is_preview_);
271 DCHECK(!context_menu_preview_node_.get() || !script_initiated_preview_frame_); 273 print_preview_context_.OnPrintPreview();
272 274
273 if (script_initiated_preview_frame_) { 275 if (!InitPrintSettings(print_preview_context_.frame(),
274 // Script initiated print preview. 276 print_preview_context_.node())) {
275 PrintPreview(script_initiated_preview_frame_, NULL, settings); 277 NOTREACHED();
276 } else if (context_menu_preview_node_.get()) { 278 return;
277 // User initiated - print node under context menu.
278 PrintPreview(context_menu_preview_node_->document().frame(),
279 context_menu_preview_node_.get(), settings);
280 } else {
281 // User initiated - normal print preview.
282 WebFrame* frame;
283 if (GetPrintFrame(&frame))
284 PrintPreview(frame, NULL, settings);
285 } 279 }
280
281 if (!UpdatePrintSettings(settings)) {
282 DidFinishPrinting(FAIL_PREVIEW);
283 return;
284 }
285
286 if (print_pages_params_->params.preview_request_id != 0 &&
287 old_print_pages_params_.get() &&
288 PrintMsg_Print_Params_IsEqual(*old_print_pages_params_,
289 *print_pages_params_)) {
290 PrintHostMsg_DidPreviewDocument_Params preview_params;
291 preview_params.reuse_existing_data = true;
292 preview_params.data_size = 0;
293 preview_params.document_cookie =
294 print_pages_params_->params.document_cookie;
295 preview_params.expected_pages_count = print_preview_context_.page_count();
296 preview_params.modifiable = print_preview_context_.IsModifiable();
297 preview_params.preview_request_id =
298 print_pages_params_->params.preview_request_id;
299
300 Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
301 return;
302 }
303
304 // PDF printer device supports alpha blending.
305 print_pages_params_->params.supports_alpha_blend = true;
306 if (!CreatePreviewDocument())
307 DidFinishPrinting(FAIL_PREVIEW);
308 }
309
310 bool PrintWebViewHelper::CreatePreviewDocument() {
311 PrintMsg_Print_Params printParams = print_pages_params_->params;
312 UpdatePrintableSizeInPrintParameters(print_preview_context_.frame(),
313 print_preview_context_.node(),
314 &printParams);
315
316 const std::vector<int>& pages = print_pages_params_->pages;
317 if (!print_preview_context_.CreatePreviewDocument(printParams, pages))
318 return false;
319 int page_count = print_preview_context_.page_count();
320 Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), page_count));
321 PreviewPageRendered(-1);
322 return true;
323 }
324
325 void PrintWebViewHelper::OnContinuePreview() {
326 // Spurious message. We already finished/cancelled/aborted the print preview.
327 if (!print_preview_context_.IsBusy())
328 return;
329
330 int page_number = -1;
331 if (!print_preview_context_.GetNextPage(&page_number)) {
332 // Continue generating the print preview.
333 RenderPreviewPage(page_number);
334 return;
335 }
336
337 // Finished generating preview. Finalize the document.
338 if (!FinalizePreviewDocument())
339 DidFinishPrinting(FAIL_PREVIEW);
340 }
341
342 void PrintWebViewHelper::OnCancelPreview() {
343 DidFinishPrinting(CANCEL_PREVIEW);
344 return;
345 }
346
347 void PrintWebViewHelper::OnAbortPreview() {
348 DidFinishPrinting(ABORT_PREVIEW);
349 return;
350 }
351
352 bool PrintWebViewHelper::FinalizePreviewDocument() {
353 print_preview_context_.FinalizePreviewDocument();
354
355 // Get the size of the resulting metafile.
356 printing::Metafile* metafile = print_preview_context_.metafile();
357 uint32 buf_size = metafile->GetDataSize();
358 DCHECK_GT(buf_size, 0u);
kmadhusu 2011/07/15 01:22:46 http://codereview.chromium.org/7365003/diff/9001/c
Lei Zhang 2011/07/15 01:48:02 That was a copy and paste from the Windows EMF pri
359
360 PrintHostMsg_DidPreviewDocument_Params preview_params;
361 preview_params.reuse_existing_data = false;
362 preview_params.data_size = buf_size;
363 preview_params.document_cookie = print_pages_params_->params.document_cookie;
364 preview_params.expected_pages_count = print_preview_context_.page_count();
365 preview_params.modifiable = print_preview_context_.IsModifiable();
366 preview_params.preview_request_id =
367 print_pages_params_->params.preview_request_id;
368
369 // Ask the browser to create the shared memory for us.
370 if (!CopyMetafileDataToSharedMem(metafile,
371 &(preview_params.metafile_data_handle))) {
372 return false;
373 }
374 #if defined(OS_WIN)
375 Send(new PrintHostMsg_DuplicateSection(routing_id(),
376 preview_params.metafile_data_handle,
377 &preview_params.metafile_data_handle));
378 #endif
379 Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
380 return true;
286 } 381 }
287 382
288 void PrintWebViewHelper::OnPrintingDone(bool success) { 383 void PrintWebViewHelper::OnPrintingDone(bool success) {
289 notify_browser_of_print_failure_ = false; 384 notify_browser_of_print_failure_ = false;
290 DidFinishPrinting(success ? OK : FAIL_PRINT); 385 DidFinishPrinting(success ? OK : FAIL_PRINT);
291 } 386 }
292 387
293 void PrintWebViewHelper::OnPrintNodeUnderContextMenu() { 388 void PrintWebViewHelper::OnPrintNodeUnderContextMenu() {
294 const WebNode& context_menu_node = render_view()->context_menu_node(); 389 const WebNode& context_menu_node = render_view()->context_menu_node();
295 if (context_menu_node.isNull()) { 390 if (context_menu_node.isNull()) {
296 NOTREACHED(); 391 NOTREACHED();
297 return; 392 return;
298 } 393 }
299 394
300 // Make a copy of the node, in case RenderView::OnContextMenuClosed resets 395 // Make a copy of the node, in case RenderView::OnContextMenuClosed resets
301 // its |context_menu_node_|. 396 // its |context_menu_node_|.
302 if (is_preview_) { 397 if (is_preview_) {
303 context_menu_preview_node_.reset(new WebNode(context_menu_node)); 398 print_preview_context_.InitWithNode(context_menu_node);
304 script_initiated_preview_frame_ = NULL;
305 RequestPrintPreview(); 399 RequestPrintPreview();
306 } else { 400 } else {
307 WebNode duplicate_node(context_menu_node); 401 WebNode duplicate_node(context_menu_node);
308 Print(duplicate_node.document().frame(), &duplicate_node); 402 Print(duplicate_node.document().frame(), &duplicate_node);
309 } 403 }
310 } 404 }
311 405
312 void PrintWebViewHelper::OnInitiatePrintPreview() { 406 void PrintWebViewHelper::OnInitiatePrintPreview() {
313 DCHECK(is_preview_); 407 DCHECK(is_preview_);
314 script_initiated_preview_frame_ = NULL; 408 WebFrame* frame;
315 context_menu_preview_node_.reset(); 409 if (GetPrintFrame(&frame))
kmadhusu 2011/07/15 01:22:46 Handle the else case.
Lei Zhang 2011/07/15 01:48:02 The else case is to do nothing. I changed this to
410 print_preview_context_.InitWithFrame(frame);
316 RequestPrintPreview(); 411 RequestPrintPreview();
317 } 412 }
318 413
319 void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) { 414 void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) {
320 // If still not finished with earlier print request simply ignore. 415 // If still not finished with earlier print request simply ignore.
321 if (print_web_view_) 416 if (print_web_view_)
322 return; 417 return;
323 418
324 // Initialize print settings. 419 // Initialize print settings.
325 if (!InitPrintSettings(frame, node)) 420 if (!InitPrintSettings(frame, node))
(...skipping 24 matching lines...) Expand all
350 DidFinishPrinting(OK); // Release resources and fail silently. 445 DidFinishPrinting(OK); // Release resources and fail silently.
351 return; 446 return;
352 } 447 }
353 448
354 // Render Pages for printing. 449 // Render Pages for printing.
355 if (!RenderPagesForPrint(frame, node)) 450 if (!RenderPagesForPrint(frame, node))
356 DidFinishPrinting(FAIL_PRINT); 451 DidFinishPrinting(FAIL_PRINT);
357 ResetScriptedPrintCount(); 452 ResetScriptedPrintCount();
358 } 453 }
359 454
360 void PrintWebViewHelper::PrintPreview(WebKit::WebFrame* frame,
361 WebKit::WebNode* node,
362 const DictionaryValue& settings) {
363 DCHECK(is_preview_);
364
365 if (!InitPrintSettings(frame, node)) {
366 NOTREACHED() << "Failed to initialize print page settings";
367 return;
368 }
369
370 if (!UpdatePrintSettings(settings)) {
371 DidFinishPrinting(FAIL_PREVIEW);
372 return;
373 }
374
375 if (print_pages_params_->params.preview_request_id != 0 &&
376 old_print_pages_params_.get() &&
377 PrintMsg_Print_Params_IsEqual(*old_print_pages_params_,
378 *print_pages_params_)) {
379 PrintHostMsg_DidPreviewDocument_Params preview_params;
380 preview_params.reuse_existing_data = true;
381 preview_params.data_size = 0;
382 preview_params.document_cookie =
383 print_pages_params_->params.document_cookie;
384 preview_params.expected_pages_count = preview_page_count_;
385 preview_params.modifiable = IsModifiable(frame, node);
386 preview_params.preview_request_id =
387 print_pages_params_->params.preview_request_id;
388
389 Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
390 return;
391 }
392
393 // Render Pages for preview.
394 if (!RenderPagesForPreview(frame, node))
395 DidFinishPrinting(FAIL_PREVIEW);
396 }
397
398 void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) { 455 void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) {
399 bool store_print_pages_params = true; 456 bool store_print_pages_params = true;
400 if (result == FAIL_PRINT) { 457 if (result == FAIL_PRINT) {
401 DisplayPrintJobError(); 458 DisplayPrintJobError();
402 459
403 if (notify_browser_of_print_failure_) { 460 if (notify_browser_of_print_failure_) {
404 int cookie = print_pages_params_->params.document_cookie; 461 int cookie = print_pages_params_->params.document_cookie;
405 Send(new PrintHostMsg_PrintingFailed(routing_id(), cookie)); 462 Send(new PrintHostMsg_PrintingFailed(routing_id(), cookie));
406 } 463 }
407 } else if (result == FAIL_PREVIEW) { 464 } else if (result == FAIL_PREVIEW) {
465 DCHECK(is_preview_);
466 store_print_pages_params = false;
408 int cookie = print_pages_params_->params.document_cookie; 467 int cookie = print_pages_params_->params.document_cookie;
468 Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie));
469 print_preview_context_.Abort();
470 } else if (result == CANCEL_PREVIEW) {
471 DCHECK(is_preview_);
409 store_print_pages_params = false; 472 store_print_pages_params = false;
410 if (notify_browser_of_print_failure_) { 473 print_preview_context_.Cancel();
411 Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie)); 474 } else if (result == ABORT_PREVIEW) {
412 } else { 475 DCHECK(is_preview_);
413 Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie)); 476 store_print_pages_params = false;
414 } 477 print_preview_context_.Abort();
478 } else if (result == OK && is_preview_) {
479 print_preview_context_.Finished();
415 } 480 }
416 481
417 if (print_web_view_) { 482 if (print_web_view_) {
418 print_web_view_->close(); 483 print_web_view_->close();
419 print_web_view_ = NULL; 484 print_web_view_ = NULL;
420 } 485 }
421 486
422 if (store_print_pages_params) { 487 if (store_print_pages_params) {
423 old_print_pages_params_.reset(print_pages_params_.release()); 488 old_print_pages_params_.reset(print_pages_params_.release());
424 } else { 489 } else {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 *margin_right_in_points = 633 *margin_right_in_points =
569 ConvertPixelsToPointDouble(margin_right_in_pixels); 634 ConvertPixelsToPointDouble(margin_right_in_pixels);
570 if (margin_bottom_in_points) 635 if (margin_bottom_in_points)
571 *margin_bottom_in_points = 636 *margin_bottom_in_points =
572 ConvertPixelsToPointDouble(margin_bottom_in_pixels); 637 ConvertPixelsToPointDouble(margin_bottom_in_pixels);
573 if (margin_left_in_points) 638 if (margin_left_in_points)
574 *margin_left_in_points = 639 *margin_left_in_points =
575 ConvertPixelsToPointDouble(margin_left_in_pixels); 640 ConvertPixelsToPointDouble(margin_left_in_pixels);
576 } 641 }
577 642
578 bool PrintWebViewHelper::IsModifiable(WebKit::WebFrame* frame,
579 WebKit::WebNode* node) {
580 if (node)
581 return false;
582 std::string mime(frame->dataSource()->response().mimeType().utf8());
583 if (mime == "application/pdf")
584 return false;
585 return true;
586 }
587
588 void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters( 643 void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
589 WebFrame* frame, 644 WebFrame* frame,
590 WebNode* node, 645 WebNode* node,
591 PrintMsg_Print_Params* params) { 646 PrintMsg_Print_Params* params) {
592 double content_width_in_points; 647 double content_width_in_points;
593 double content_height_in_points; 648 double content_height_in_points;
594 double margin_top_in_points; 649 double margin_top_in_points;
595 double margin_right_in_points; 650 double margin_right_in_points;
596 double margin_bottom_in_points; 651 double margin_bottom_in_points;
597 double margin_left_in_points; 652 double margin_left_in_points;
(...skipping 20 matching lines...) Expand all
618 static_cast<int>(ConvertUnitDouble( 673 static_cast<int>(ConvertUnitDouble(
619 page_height_in_points, printing::kPointsPerInch, dpi))); 674 page_height_in_points, printing::kPointsPerInch, dpi)));
620 675
621 params->margin_top = static_cast<int>(ConvertUnitDouble( 676 params->margin_top = static_cast<int>(ConvertUnitDouble(
622 margin_top_in_points, printing::kPointsPerInch, dpi)); 677 margin_top_in_points, printing::kPointsPerInch, dpi));
623 params->margin_left = static_cast<int>(ConvertUnitDouble( 678 params->margin_left = static_cast<int>(ConvertUnitDouble(
624 margin_left_in_points, printing::kPointsPerInch, dpi)); 679 margin_left_in_points, printing::kPointsPerInch, dpi));
625 } 680 }
626 681
627 bool PrintWebViewHelper::InitPrintSettings(WebKit::WebFrame* frame, 682 bool PrintWebViewHelper::InitPrintSettings(WebKit::WebFrame* frame,
628 WebKit::WebNode* node) { 683 WebKit::WebNode* node) {
kmadhusu 2011/07/15 01:22:46 Add DCHECK(frame) here.
Lei Zhang 2011/07/15 01:48:02 Done.
629 PrintMsg_PrintPages_Params settings; 684 PrintMsg_PrintPages_Params settings;
630 685
631 // TODO(abodenha@chromium.org) It doesn't make sense to do this if our 686 // TODO(abodenha@chromium.org) It doesn't make sense to do this if our
632 // "default" is a cloud based printer. Split InitPrintSettings up 687 // "default" is a cloud based printer. Split InitPrintSettings up
633 // so that we can avoid the overhead of unneeded calls into the native 688 // so that we can avoid the overhead of unneeded calls into the native
634 // print system. 689 // print system.
635 Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(), 690 Send(new PrintHostMsg_GetDefaultPrintSettings(routing_id(),
636 &settings.params)); 691 &settings.params));
637 // Check if the printer returned any settings, if the settings is empty, we 692 // Check if the printer returned any settings, if the settings is empty, we
638 // can safely assume there are no printer drivers configured. So we safely 693 // can safely assume there are no printer drivers configured. So we safely
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 WebKit::WebNode* node) { 799 WebKit::WebNode* node) {
745 PrintMsg_PrintPages_Params print_settings = *print_pages_params_; 800 PrintMsg_PrintPages_Params print_settings = *print_pages_params_;
746 if (print_settings.params.selection_only) { 801 if (print_settings.params.selection_only) {
747 return CopyAndPrint(frame); 802 return CopyAndPrint(frame);
748 } else { 803 } else {
749 // TODO: Always copy before printing. 804 // TODO: Always copy before printing.
750 return PrintPages(print_settings, frame, node); 805 return PrintPages(print_settings, frame, node);
751 } 806 }
752 } 807 }
753 808
754 bool PrintWebViewHelper::RenderPagesForPreview(WebKit::WebFrame* frame,
755 WebKit::WebNode* node) {
756 PrintMsg_PrintPages_Params print_settings = *print_pages_params_;
757 // PDF printer device supports alpha blending.
758 print_settings.params.supports_alpha_blend = true;
759 // TODO(kmadhusu): Handle print selection.
760 return CreatePreviewDocument(print_settings, frame, node);
761 }
762
763 base::TimeTicks PrintWebViewHelper::ReportPreviewPageRenderTime(
764 base::TimeTicks start_time) {
765 base::TimeTicks now = base::TimeTicks::Now();
766 UMA_HISTOGRAM_TIMES("PrintPreview.RenderPDFPageTime", now - start_time);
767 return now;
768 }
769
770 void PrintWebViewHelper::ReportTotalPreviewGenerationTime(
771 int selected_pages_length, int total_pages,
772 base::TimeDelta render_time, base::TimeDelta total_time) {
773 if (selected_pages_length == 0)
774 selected_pages_length = total_pages;
775
776 if (selected_pages_length <= 0) {
777 // This shouldn't happen, but this makes sure it doesn't affect the
778 // statistics if it does.
779 return;
780 }
781
782 UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderToPDFTime",
783 render_time);
784 UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime",
785 total_time);
786 UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage",
787 total_time / selected_pages_length);
788 }
789
790 #if defined(OS_POSIX) 809 #if defined(OS_POSIX)
791 bool PrintWebViewHelper::CopyMetafileDataToSharedMem( 810 bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
792 printing::Metafile* metafile, 811 printing::Metafile* metafile,
793 base::SharedMemoryHandle* shared_mem_handle) { 812 base::SharedMemoryHandle* shared_mem_handle) {
794 uint32 buf_size = metafile->GetDataSize(); 813 uint32 buf_size = metafile->GetDataSize();
795 base::SharedMemoryHandle mem_handle; 814 base::SharedMemoryHandle mem_handle;
796 Send(new ViewHostMsg_AllocateSharedMemoryBuffer(buf_size, &mem_handle)); 815 Send(new ViewHostMsg_AllocateSharedMemoryBuffer(buf_size, &mem_handle));
797 if (base::SharedMemory::IsHandleValid(mem_handle)) { 816 if (base::SharedMemory::IsHandleValid(mem_handle)) {
798 base::SharedMemory shared_buf(mem_handle, false); 817 base::SharedMemory shared_buf(mem_handle, false);
799 if (shared_buf.Map(buf_size)) { 818 if (shared_buf.Map(buf_size)) {
800 metafile->GetData(shared_buf.memory(), buf_size); 819 metafile->GetData(shared_buf.memory(), buf_size);
801 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), 820 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(),
802 shared_mem_handle); 821 shared_mem_handle);
803 return true; 822 return true;
804 } 823 }
805 } 824 }
806 NOTREACHED(); 825 NOTREACHED();
807 return false; 826 return false;
808 } 827 }
809 #endif // defined(OS_POSIX) 828 #endif // defined(OS_POSIX)
810 829
811 bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent( 830 bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent(
812 WebKit::WebFrame* frame) { 831 WebKit::WebFrame* frame) {
813 const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2; 832 const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2;
814 const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 32; 833 const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 32;
834 bool too_frequent = false;
kmadhusu 2011/07/15 01:22:46 Declare this variable after the comments
Lei Zhang 2011/07/15 01:48:02 I don't think it helps with readability.
815 835
816 // Check if there is script repeatedly trying to print and ignore it if too 836 // Check if there is script repeatedly trying to print and ignore it if too
817 // frequent. The first 3 times, we use a constant wait time, but if this 837 // frequent. The first 3 times, we use a constant wait time, but if this
818 // gets excessive, we switch to exponential wait time. So for a page that 838 // gets excessive, we switch to exponential wait time. So for a page that
819 // calls print() in a loop the user will need to cancel the print dialog 839 // calls print() in a loop the user will need to cancel the print dialog
820 // after: [2, 2, 2, 4, 8, 16, 32, 32, ...] seconds. 840 // after: [2, 2, 2, 4, 8, 16, 32, 32, ...] seconds.
821 // This gives the user time to navigate from the page. 841 // This gives the user time to navigate from the page.
822 if (user_cancelled_scripted_print_count_ > 0) { 842 if (user_cancelled_scripted_print_count_ > 0) {
823 base::TimeDelta diff = base::Time::Now() - last_cancelled_script_print_; 843 base::TimeDelta diff = base::Time::Now() - last_cancelled_script_print_;
824 int min_wait_seconds = kMinSecondsToIgnoreJavascriptInitiatedPrint; 844 int min_wait_seconds = kMinSecondsToIgnoreJavascriptInitiatedPrint;
825 if (user_cancelled_scripted_print_count_ > 3) { 845 if (user_cancelled_scripted_print_count_ > 3) {
826 min_wait_seconds = std::min( 846 min_wait_seconds = std::min(
827 kMinSecondsToIgnoreJavascriptInitiatedPrint << 847 kMinSecondsToIgnoreJavascriptInitiatedPrint <<
828 (user_cancelled_scripted_print_count_ - 3), 848 (user_cancelled_scripted_print_count_ - 3),
829 kMaxSecondsToIgnoreJavascriptInitiatedPrint); 849 kMaxSecondsToIgnoreJavascriptInitiatedPrint);
830 } 850 }
831 if (diff.InSeconds() < min_wait_seconds) { 851 if (diff.InSeconds() < min_wait_seconds) {
832 WebString message(WebString::fromUTF8( 852 too_frequent = true;
833 "Ignoring too frequent calls to print()."));
834 frame->addMessageToConsole(WebConsoleMessage(
835 WebConsoleMessage::LevelWarning,
836 message));
837 return true;
838 } 853 }
839 } 854 }
840 return false; 855
856 if (!too_frequent && print_preview_context_.IsBusy())
857 too_frequent = true;
858
859 if (!too_frequent)
860 return false;
861
862 WebString message(WebString::fromUTF8(
863 "Ignoring too frequent calls to print()."));
864 frame->addMessageToConsole(WebConsoleMessage(WebConsoleMessage::LevelWarning,
865 message));
866 return true;
841 } 867 }
842 868
843 void PrintWebViewHelper::ResetScriptedPrintCount() { 869 void PrintWebViewHelper::ResetScriptedPrintCount() {
844 // Reset cancel counter on successful print. 870 // Reset cancel counter on successful print.
845 user_cancelled_scripted_print_count_ = 0; 871 user_cancelled_scripted_print_count_ = 0;
846 } 872 }
847 873
848 void PrintWebViewHelper::IncrementScriptedPrintCount() { 874 void PrintWebViewHelper::IncrementScriptedPrintCount() {
849 ++user_cancelled_scripted_print_count_; 875 ++user_cancelled_scripted_print_count_;
850 last_cancelled_script_print_ = base::Time::Now(); 876 last_cancelled_script_print_ = base::Time::Now();
851 } 877 }
852 878
853 void PrintWebViewHelper::DisplayPrintJobError() { 879 void PrintWebViewHelper::DisplayPrintJobError() {
854 WebView* web_view = print_web_view_; 880 WebView* web_view = print_web_view_;
855 if (!web_view) 881 if (!web_view)
856 web_view = render_view()->webview(); 882 web_view = render_view()->webview();
857 883
858 render_view()->runModalAlertDialog( 884 render_view()->runModalAlertDialog(
859 web_view->mainFrame(), 885 web_view->mainFrame(),
860 l10n_util::GetStringUTF16(IDS_PRINT_SPOOL_FAILED_ERROR_TEXT)); 886 l10n_util::GetStringUTF16(IDS_PRINT_SPOOL_FAILED_ERROR_TEXT));
861 } 887 }
862 888
863 void PrintWebViewHelper::RequestPrintPreview() { 889 void PrintWebViewHelper::RequestPrintPreview() {
864 old_print_pages_params_.reset(); 890 old_print_pages_params_.reset();
865 Send(new PrintHostMsg_RequestPrintPreview(routing_id())); 891 Send(new PrintHostMsg_RequestPrintPreview(routing_id()));
866 } 892 }
867 893
868 bool PrintWebViewHelper::PreviewPageRendered(int page_number) { 894 void PrintWebViewHelper::PreviewPageRendered(int page_number) {
869 bool cancel = false; 895 int cookie = print_pages_params_->params.document_cookie;
870 Send(new PrintHostMsg_DidPreviewPage(routing_id(), page_number, &cancel)); 896 Send(new PrintHostMsg_DidPreviewPage(routing_id(), page_number, cookie));
871 if (cancel)
872 notify_browser_of_print_failure_ = false;
873 return !cancel;
874 } 897 }
898
899 PrintWebViewHelper::PrintPreviewContext::PrintPreviewContext()
900 : frame_(NULL),
901 page_count_(0),
902 actual_page_count_(0),
903 current_page_(0),
904 state_(UNINITIALIZED) {
905 }
906
907 void PrintWebViewHelper::PrintPreviewContext::InitWithFrame(
908 WebKit::WebFrame* web_frame) {
909 DCHECK(web_frame);
910 if (IsInitialized())
911 return;
912 state_ = INITIALIZED;
913 frame_ = web_frame;
914 node_.reset();
915 }
916
917 void PrintWebViewHelper::PrintPreviewContext::InitWithNode(
918 const WebKit::WebNode& web_node) {
919 DCHECK(!web_node.isNull());
920 if (IsInitialized())
921 return;
922 state_ = INITIALIZED;
923 frame_ = web_node.document().frame();
924 node_.reset(new WebNode(web_node));
925 }
926
927 void PrintWebViewHelper::PrintPreviewContext::OnPrintPreview() {
928 DCHECK(IsInitialized());
929 Reset();
930 }
931
932 bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument(
933 const PrintMsg_Print_Params& printParams,
934 const std::vector<int>& pages) {
935 DCHECK(IsInitialized());
kmadhusu 2011/07/15 01:22:46 If (!IsInitialized()) return false; is better t
Lei Zhang 2011/07/15 01:48:02 The DCHECK should never fail. If it fails in a rel
936 state_ = PRINTING;
937
938 print_params_.reset(new PrintMsg_Print_Params(printParams));
939
940 metafile_.reset(new printing::PreviewMetafile);
941 if (!metafile_->Init())
942 return false;
943
944 // Need to make sure old object gets destroyed first.
945 prep_frame_view_.reset(new PrepareFrameAndViewForPrint(printParams,
946 frame(),
kmadhusu 2011/07/15 01:22:46 nit: frame() can fit in the previous line.
Lei Zhang 2011/07/15 01:48:02 Done.
947 node(),
948 frame()->view()));
949 page_count_ = prep_frame_view_->GetExpectedPageCount();
950 if (page_count_ == 0)
951 return false;
952
953 current_page_ = 0;
954 if (pages.empty()) {
kmadhusu 2011/07/15 01:22:46 How about: actual_page_count = pages.empty()? pag
Lei Zhang 2011/07/15 01:48:02 Your logic is wrong.
kmadhusu 2011/07/15 19:25:46 oops.. I meant if (actual_page_count_ == page_coun
955 actual_page_count_ = page_count_;
956 rendered_pages_ = std::vector<bool>(page_count_, false);
957 } else {
958 actual_page_count_ = pages.size();
959 rendered_pages_ = std::vector<bool>(page_count_, true);
960 for (size_t i = 0; i < pages.size(); ++i) {
kmadhusu 2011/07/15 01:22:46 "i < actual_page_count_"
Lei Zhang 2011/07/15 01:48:02 Done.
961 int page_number = pages[i];
962 if (page_number < 0 || page_number >= page_count_)
963 return false;
964 rendered_pages_[page_number] = false;
965 }
966 }
967
968 document_render_time_ = base::TimeDelta();
969 begin_time_ = base::TimeTicks::Now();
970
971 return true;
972 }
973
974 void PrintWebViewHelper::PrintPreviewContext::RenderedPreviewPage(
975 const base::TimeDelta& page_time) {
976 DCHECK_EQ(PRINTING, state_);
977 document_render_time_ += page_time;
978 UMA_HISTOGRAM_TIMES("PrintPreview.RenderPDFPageTime", page_time);
979 }
980
981 void PrintWebViewHelper::PrintPreviewContext::FinalizePreviewDocument() {
982 DCHECK_EQ(PRINTING, state_);
983 state_ = DONE;
984
985 base::TimeTicks begin_time = base::TimeTicks::Now();
986
987 prep_frame_view_->FinishPrinting();
kmadhusu 2011/07/15 01:22:46 Please retain the previous comment. http://codere
Lei Zhang 2011/07/15 01:48:02 We have the comment on Windows only, but not Linux
988 metafile_->FinishDocument();
kmadhusu 2011/07/15 01:22:46 if (!metafile->FinishDocument) NOTREACHED();
Lei Zhang 2011/07/15 01:48:02 Again, we don't have it on Mac/Linux.
kmadhusu 2011/07/15 19:25:46 At least on linux, we should have handled this cas
989
990 if (actual_page_count_ <= 0) {
991 NOTREACHED();
992 return;
993 }
994
995 UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderToPDFTime",
996 document_render_time_);
997 base::TimeDelta total_time = (base::TimeTicks::Now() - begin_time) +
998 document_render_time_;
kmadhusu 2011/07/15 01:22:46 nit: Fix indentation.
Lei Zhang 2011/07/15 01:48:02 Done.
999 UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime",
1000 total_time);
1001 UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage",
1002 total_time / actual_page_count_);
1003 }
1004
1005 void PrintWebViewHelper::PrintPreviewContext::Finished() {
1006 DCHECK_EQ(DONE, state_);
1007 Reset();
1008 }
1009
1010 void PrintWebViewHelper::PrintPreviewContext::Abort() {
1011 state_ = UNINITIALIZED;
1012 Reset();
1013 frame_ = NULL;
1014 node_.reset();
1015 }
1016
1017 void PrintWebViewHelper::PrintPreviewContext::Cancel() {
1018 DCHECK(IsInitialized());
1019 state_ = DONE;
1020 Reset();
1021 }
1022
1023 bool PrintWebViewHelper::PrintPreviewContext::GetNextPage(
1024 int* page_number) {
1025 DCHECK_EQ(PRINTING, state_);
1026 while (current_page_ < page_count_ && rendered_pages_[current_page_])
1027 ++current_page_;
1028 if (current_page_ == page_count_)
1029 return true;
1030 rendered_pages_[current_page_] = true;
1031 *page_number = current_page_++;
1032 return false;
1033 }
1034
1035 bool PrintWebViewHelper::PrintPreviewContext::IsInitialized() const {
kmadhusu 2011/07/15 01:22:46 I was expecting "return state_ == INITIALIZED;" as
Lei Zhang 2011/07/15 01:48:02 Changed to "IsReadyToRender()"
1036 return state_ != UNINITIALIZED;
1037 }
1038
1039 bool PrintWebViewHelper::PrintPreviewContext::IsBusy() const {
kmadhusu 2011/07/15 01:22:46 This function needs a better name. state PRINTIN
Lei Zhang 2011/07/15 01:48:02 I can't think of a better name. "Busy" is relative
1040 return state_ == INITIALIZED || state_ == PRINTING;
1041 }
1042
1043 bool PrintWebViewHelper::PrintPreviewContext::IsModifiable() const {
1044 if (node())
1045 return false;
1046 std::string mime(frame()->dataSource()->response().mimeType().utf8());
1047 if (mime == "application/pdf")
kmadhusu 2011/07/15 01:22:46 Instead of lines 1047-1049, use return mime != "
Lei Zhang 2011/07/15 01:48:02 Done.
1048 return false;
1049 return true;
1050 }
1051
1052 WebKit::WebFrame* PrintWebViewHelper::PrintPreviewContext::frame() const {
1053 return frame_;
1054 }
1055
1056 WebKit::WebNode* PrintWebViewHelper::PrintPreviewContext::node() const {
1057 return node_.get();
1058 }
1059
1060 int PrintWebViewHelper::PrintPreviewContext::page_count() const {
1061 return page_count_;
1062 }
1063
1064 printing::Metafile* PrintWebViewHelper::PrintPreviewContext::metafile() const {
1065 return metafile_.get();
1066 }
1067
1068 const PrintMsg_Print_Params&
1069 PrintWebViewHelper::PrintPreviewContext::print_params() const {
1070 return *print_params_;
1071 }
1072
1073 const gfx::Size&
1074 PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const {
1075 return prep_frame_view_->GetPrintCanvasSize();
1076 }
1077
1078 void PrintWebViewHelper::PrintPreviewContext::Reset() {
1079 prep_frame_view_.reset();
1080 metafile_.reset();
1081 rendered_pages_.clear();
1082 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698