diff options
-rw-r--r-- | chrome/browser/printing/print_preview_message_handler.cc | 50 | ||||
-rw-r--r-- | chrome/browser/printing/print_preview_message_handler.h | 5 | ||||
-rw-r--r-- | chrome/browser/ui/webui/print_preview_handler.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/webui/print_preview_ui.cc | 12 | ||||
-rw-r--r-- | chrome/browser/ui/webui/print_preview_ui.h | 7 | ||||
-rw-r--r-- | chrome/common/print_messages.h | 23 | ||||
-rw-r--r-- | chrome/renderer/mock_render_thread.cc | 30 | ||||
-rw-r--r-- | chrome/renderer/mock_render_thread.h | 11 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.cc | 475 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper.h | 152 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_browsertest.cc | 36 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_linux.cc | 75 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_mac.mm | 80 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_win.cc | 98 |
14 files changed, 567 insertions, 492 deletions
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc index db57d77..99be3f5 100644 --- a/chrome/browser/printing/print_preview_message_handler.cc +++ b/chrome/browser/printing/print_preview_message_handler.cc @@ -63,7 +63,8 @@ void PrintPreviewMessageHandler::OnRequestPrintPreview() { PrintPreviewTabController::PrintPreview(tab_contents()); } -void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(int page_count) { +void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(int document_cookie, + int page_count) { if (page_count <= 0) return; TabContents* print_preview_tab = GetPrintPreviewTab(); @@ -72,34 +73,39 @@ void PrintPreviewMessageHandler::OnDidGetPreviewPageCount(int page_count) { PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(print_preview_tab->web_ui()); - print_preview_ui->OnDidGetPreviewPageCount(page_count); + print_preview_ui->OnDidGetPreviewPageCount(document_cookie, page_count); } -void PrintPreviewMessageHandler::OnDidPreviewPage(int page_number, - bool* cancel) { +void PrintPreviewMessageHandler::OnDidPreviewPage(int page_number) { + RenderViewHost* rvh = tab_contents()->render_view_host(); TabContents* print_preview_tab = GetPrintPreviewTab(); - if (!print_preview_tab) { - // Can't find print preview tab means we should cancel. - *cancel = true; + if (!(print_preview_tab && print_preview_tab->web_ui())) { + // Can't find print preview tab means we should abort. + rvh->Send(new PrintMsg_AbortPreview(rvh->routing_id())); return; } PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(print_preview_tab->web_ui()); bool has_pending = print_preview_ui->HasPendingRequests(); - if (!has_pending && page_number >= 0) + if (has_pending) { + // Cancel. Next print preview request will cancel the current one. + // Just do the required maintainance work here. + StopWorker(print_preview_ui->document_cookie()); + print_preview_ui->OnPrintPreviewCancelled(); + return; + } + + // Continue + if (page_number >= 0) print_preview_ui->OnDidPreviewPage(page_number); - *cancel = has_pending; + rvh->Send(new PrintMsg_ContinuePreview(rvh->routing_id())); } void PrintPreviewMessageHandler::OnPagesReadyForPreview( const PrintHostMsg_DidPreviewDocument_Params& params) { - // Always need to stop the worker and send PrintMsg_PrintingDone. StopWorker(params.document_cookie); - RenderViewHost* rvh = tab_contents()->render_view_host(); - rvh->Send(new PrintMsg_PrintingDone(rvh->routing_id(), true)); - // Get the print preview tab. TabContents* print_preview_tab = GetPrintPreviewTab(); // User might have closed it already. @@ -114,7 +120,8 @@ void PrintPreviewMessageHandler::OnPagesReadyForPreview( if (params.reuse_existing_data) { // Need to match normal rendering where we are expected to send this. - print_preview_ui->OnDidGetPreviewPageCount(params.expected_pages_count); + print_preview_ui->OnDidGetPreviewPageCount(params.document_cookie, + params.expected_pages_count); print_preview_ui->OnPreviewDataIsAvailable( params.expected_pages_count, @@ -175,19 +182,6 @@ void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) { } } -void PrintPreviewMessageHandler::OnPrintPreviewCancelled(int document_cookie) { - // Always need to stop the worker. - StopWorker(document_cookie); - - TabContents* print_preview_tab = GetPrintPreviewTab(); - if (!print_preview_tab) - return; - - PrintPreviewUI* print_preview_ui = - static_cast<PrintPreviewUI*>(print_preview_tab->web_ui()); - print_preview_ui->OnPrintPreviewCancelled(); -} - bool PrintPreviewMessageHandler::OnMessageReceived( const IPC::Message& message) { bool handled = true; @@ -202,8 +196,6 @@ bool PrintPreviewMessageHandler::OnMessageReceived( OnPagesReadyForPreview) IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewFailed, OnPrintPreviewFailed) - IPC_MESSAGE_HANDLER(PrintHostMsg_PrintPreviewCancelled, - OnPrintPreviewCancelled) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h index 1421de9..9d049d0 100644 --- a/chrome/browser/printing/print_preview_message_handler.h +++ b/chrome/browser/printing/print_preview_message_handler.h @@ -30,13 +30,12 @@ class PrintPreviewMessageHandler : public TabContentsObserver { // Message handlers. void OnRequestPrintPreview(); - void OnDidGetPreviewPageCount(int page_count); + void OnDidGetPreviewPageCount(int document_cookie, int page_count); // |page_number| is 0-based. - void OnDidPreviewPage(int page_number, bool* cancel); + void OnDidPreviewPage(int page_number); void OnPagesReadyForPreview( const PrintHostMsg_DidPreviewDocument_Params& params); void OnPrintPreviewFailed(int document_cookie); - void OnPrintPreviewCancelled(int document_cookie); DISALLOW_COPY_AND_ASSIGN(PrintPreviewMessageHandler); }; diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc index 4206b4b..e1455bd 100644 --- a/chrome/browser/ui/webui/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview_handler.cc @@ -827,6 +827,11 @@ void PrintPreviewHandler::OnNavigation() { TabContentsWrapper* wrapper = TabContentsWrapper::GetCurrentWrapperForContents(initiator_tab); wrapper->print_view_manager()->set_observer(NULL); + + // Tell the initiator tab to stop rendering the print preview, if any, + // since the preview tab is gone. + RenderViewHost* rvh = initiator_tab->render_view_host(); + rvh->Send(new PrintMsg_AbortPreview(rvh->routing_id())); } void PrintPreviewHandler::FileSelected(const FilePath& path, diff --git a/chrome/browser/ui/webui/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview_ui.cc index f6de73c..6fe75d5 100644 --- a/chrome/browser/ui/webui/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview_ui.cc @@ -16,7 +16,8 @@ PrintPreviewUI::PrintPreviewUI(TabContents* contents) : ChromeWebUI(contents), initial_preview_start_time_(base::TimeTicks::Now()), - request_count_(0U) { + request_count_(0U), + document_cookie_(0) { // WebUI owns |handler_|. handler_ = new PrintPreviewHandler(); AddMessageHandler(handler_->Attach(this)); @@ -54,8 +55,10 @@ void PrintPreviewUI::OnPrintPreviewRequest() { request_count_++; } -void PrintPreviewUI::OnDidGetPreviewPageCount(int page_count) { +void PrintPreviewUI::OnDidGetPreviewPageCount(int document_cookie, + int page_count) { DCHECK_GT(page_count, 0); + document_cookie_ = document_cookie; FundamentalValue count(page_count); CallJavascriptFunction("onDidGetPreviewPageCount", count); } @@ -116,7 +119,10 @@ PrintPreviewDataService* PrintPreviewUI::print_preview_data_service() { } void PrintPreviewUI::DecrementRequestCount() { - DCHECK_GT(request_count_, 0U); if (request_count_ > 0) request_count_--; } + +int PrintPreviewUI::document_cookie() { + return document_cookie_; +} diff --git a/chrome/browser/ui/webui/print_preview_ui.h b/chrome/browser/ui/webui/print_preview_ui.h index 28a91ad..13b4aff 100644 --- a/chrome/browser/ui/webui/print_preview_ui.h +++ b/chrome/browser/ui/webui/print_preview_ui.h @@ -36,7 +36,7 @@ class PrintPreviewUI : public ChromeWebUI { void OnPrintPreviewRequest(); // Notify the Web UI that the print preview will have |page_count| pages. - void OnDidGetPreviewPageCount(int page_count); + void OnDidGetPreviewPageCount(int document_cookie_, int page_count); // Notify the Web UI that the 0-based page |page_number| has been rendered. void OnDidPreviewPage(int page_number); @@ -75,6 +75,8 @@ class PrintPreviewUI : public ChromeWebUI { // Return true if there are pending requests. bool HasPendingRequests(); + int document_cookie(); + private: // Helper function PrintPreviewDataService* print_preview_data_service(); @@ -92,6 +94,9 @@ class PrintPreviewUI : public ChromeWebUI { // The number of print preview requests in flight. uint32 request_count_; + // Document cookie from the initiator renderer. + int document_cookie_; + DISALLOW_COPY_AND_ASSIGN(PrintPreviewUI); }; diff --git a/chrome/common/print_messages.h b/chrome/common/print_messages.h index 11547bc..139b99b4 100644 --- a/chrome/common/print_messages.h +++ b/chrome/common/print_messages.h @@ -170,6 +170,11 @@ IPC_MESSAGE_ROUTED1(PrintMsg_PrintPreview, // Tells a renderer to stop blocking script initiated printing. IPC_MESSAGE_ROUTED0(PrintMsg_ResetScriptedPrintCount) +// Tells a renderer to continue generating the print preview. +IPC_MESSAGE_ROUTED0(PrintMsg_ContinuePreview) + +// Tells a renderer to abort the print preview and reset all state. +IPC_MESSAGE_ROUTED0(PrintMsg_AbortPreview) // Messages sent from the renderer to the browser. @@ -234,19 +239,19 @@ IPC_MESSAGE_CONTROL1(PrintHostMsg_TempFileForPrintingWritten, IPC_MESSAGE_ROUTED0(PrintHostMsg_RequestPrintPreview) // Notify the browser the number of pages in the print preview document. -IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetPreviewPageCount, +IPC_MESSAGE_ROUTED2(PrintHostMsg_DidGetPreviewPageCount, + int /* document cookie */, int /* page count */) // Notify the browser a print preview page has been rendered. Give the browser // a chance to cancel the print preview as needed. Page number is zero-based, // and can be -1 if it is just a check. -IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_DidPreviewPage, - int /* page number */, - bool /* print preview cancelled */) +IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPreviewPage, + int /* page number */) -// Sends back to the browser the rendered "printed document" for preview that -// was requested by a PrintMsg_PrintPreview message. The memory handle in this -// message is already valid in the browser process. +// Sends back to the browser the complete rendered document for print preview +// that was requested by a PrintMsg_PrintPreview message. The memory handle in +// this message is already valid in the browser process. IPC_MESSAGE_ROUTED1(PrintHostMsg_PagesReadyForPreview, PrintHostMsg_DidPreviewDocument_Params /* params */) @@ -257,7 +262,3 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintingFailed, // Tell the browser print preview failed. IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewFailed, int /* document cookie */) - -// Tell the browser print preview was cancelled. -IPC_MESSAGE_ROUTED1(PrintHostMsg_PrintPreviewCancelled, - int /* document cookie */) diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc index 2535ff3..ab0654d 100644 --- a/chrome/renderer/mock_render_thread.cc +++ b/chrome/renderer/mock_render_thread.cc @@ -25,7 +25,7 @@ MockRenderThread::MockRenderThread() reply_deserializer_(NULL), printer_(new MockPrinter), print_dialog_user_response_(true), - cancel_print_preview_(false) { + print_preview_pages_remaining_(0) { } MockRenderThread::~MockRenderThread() { @@ -61,7 +61,7 @@ bool MockRenderThread::IsIncognitoProcess() const { } // Called by the Widget. Used to send messages to the browser. -// We short-circuit the mechanim and handle the messages right here on this +// We short-circuit the mechanism and handle the messages right here on this // class. bool MockRenderThread::Send(IPC::Message* msg) { // We need to simulate a synchronous channel, thus we are going to receive @@ -103,15 +103,14 @@ bool MockRenderThread::OnMessageReceived(const IPC::Message& msg) { OnMsgOpenChannelToExtension) IPC_MESSAGE_HANDLER(PrintHostMsg_GetDefaultPrintSettings, OnGetDefaultPrintSettings) - IPC_MESSAGE_HANDLER(PrintHostMsg_ScriptedPrint, - OnScriptedPrint) - IPC_MESSAGE_HANDLER(PrintHostMsg_UpdatePrintSettings, - OnUpdatePrintSettings) + IPC_MESSAGE_HANDLER(PrintHostMsg_ScriptedPrint, OnScriptedPrint) + IPC_MESSAGE_HANDLER(PrintHostMsg_UpdatePrintSettings, OnUpdatePrintSettings) IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount, OnDidGetPrintedPagesCount) IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, - OnDidPreviewPage) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount, + OnDidGetPreviewPageCount) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage) #if defined(OS_WIN) IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection) #endif @@ -212,8 +211,15 @@ void MockRenderThread::OnDidPrintPage( printer_->PrintPage(params); } -void MockRenderThread::OnDidPreviewPage(int page_number, bool* cancel) { - *cancel = cancel_print_preview_; +void MockRenderThread::OnDidGetPreviewPageCount(int document_cookie, + int number_pages) { + print_preview_pages_remaining_ = number_pages; +} + +void MockRenderThread::OnDidPreviewPage(int page_number) { + if (page_number < 0) + return; + print_preview_pages_remaining_--; } void MockRenderThread::OnUpdatePrintSettings( @@ -242,6 +248,6 @@ void MockRenderThread::set_print_dialog_user_response(bool response) { print_dialog_user_response_ = response; } -void MockRenderThread::set_cancel_print_preview(bool cancel) { - cancel_print_preview_ = cancel; +int MockRenderThread::print_preview_pages_remaining() { + return print_preview_pages_remaining_; } diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h index 3b359cf..1d2036b 100644 --- a/chrome/renderer/mock_render_thread.h +++ b/chrome/renderer/mock_render_thread.h @@ -83,8 +83,8 @@ class MockRenderThread : public RenderThreadBase { // False if the user decides to cancel. void set_print_dialog_user_response(bool response); - // Set to true to simulate canceling of a print preview. - void set_cancel_print_preview(bool cancel); + // Get the number of pages to generate for print preview. + int print_preview_pages_remaining(); private: // This function operates as a regular IPC listener. @@ -124,7 +124,8 @@ class MockRenderThread : public RenderThreadBase { void OnDidGetPrintedPagesCount(int cookie, int number_pages); void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params); - void OnDidPreviewPage(int page_number, bool* cancel); + void OnDidGetPreviewPageCount(int document_cookie, int number_pages); + void OnDidPreviewPage(int page_number); // For print preview, PrintWebViewHelper will update settings. void OnUpdatePrintSettings(int document_cookie, @@ -152,8 +153,8 @@ class MockRenderThread : public RenderThreadBase { // True to simulate user clicking print. False to cancel. bool print_dialog_user_response_; - // True to simulate cancelling a print preview. - bool cancel_print_preview_; + // Number of pages to generate for print preview. + int print_preview_pages_remaining_; }; #endif // CHROME_RENDERER_MOCK_RENDER_THREAD_H_ diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index 9f870be..f55fc3b 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -18,7 +18,7 @@ #include "chrome/renderer/prerender/prerender_helper.h" #include "content/renderer/render_view.h" #include "grit/generated_resources.h" -#include "printing/metafile.h" +#include "printing/metafile_impl.h" #include "printing/print_job_constants.h" #include "printing/units.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h" @@ -97,10 +97,9 @@ bool PrintMsg_Print_Params_IsEqual( PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( const PrintMsg_Print_Params& print_params, WebFrame* frame, - WebNode* node, - WebView* web_view) + WebNode* node) : frame_(frame), - web_view_(web_view), + web_view_(frame->view()), expected_pages_count_(0), use_browser_overlays_(true), finished_(false) { @@ -124,9 +123,9 @@ PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint( if (WebFrame* web_frame = web_view_->mainFrame()) prev_scroll_offset_ = web_frame->scrollOffset(); - prev_view_size_ = web_view->size(); + prev_view_size_ = web_view_->size(); - web_view->resize(print_layout_size); + web_view_->resize(print_layout_size); WebNode node_to_print; if (node) @@ -154,11 +153,8 @@ PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view) : RenderViewObserver(render_view), RenderViewObserverTracker<PrintWebViewHelper>(render_view), print_web_view_(NULL), - script_initiated_preview_frame_(NULL), - context_menu_preview_node_(NULL), user_cancelled_scripted_print_count_(0), - notify_browser_of_print_failure_(true), - preview_page_count_(0) { + notify_browser_of_print_failure_(true) { is_preview_ = switches::IsPrintPreviewEnabled(); } @@ -179,8 +175,7 @@ void PrintWebViewHelper::PrintPage(WebKit::WebFrame* frame) { IncrementScriptedPrintCount(); if (is_preview_) { - script_initiated_preview_frame_ = frame; - context_menu_preview_node_.reset(); + print_preview_context_.InitWithFrame(frame); RequestPrintPreview(); } else { Print(frame, NULL); @@ -191,16 +186,16 @@ bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PrintWebViewHelper, message) IPC_MESSAGE_HANDLER(PrintMsg_PrintPages, OnPrintPages) - IPC_MESSAGE_HANDLER(PrintMsg_InitiatePrintPreview, - OnInitiatePrintPreview) + IPC_MESSAGE_HANDLER(PrintMsg_InitiatePrintPreview, OnInitiatePrintPreview) IPC_MESSAGE_HANDLER(PrintMsg_PrintNodeUnderContextMenu, OnPrintNodeUnderContextMenu) IPC_MESSAGE_HANDLER(PrintMsg_PrintPreview, OnPrintPreview) - IPC_MESSAGE_HANDLER(PrintMsg_PrintForPrintPreview, - OnPrintForPrintPreview) + IPC_MESSAGE_HANDLER(PrintMsg_PrintForPrintPreview, OnPrintForPrintPreview) IPC_MESSAGE_HANDLER(PrintMsg_PrintingDone, OnPrintingDone) IPC_MESSAGE_HANDLER(PrintMsg_ResetScriptedPrintCount, ResetScriptedPrintCount) + IPC_MESSAGE_HANDLER(PrintMsg_ContinuePreview, OnContinuePreview) + IPC_MESSAGE_HANDLER(PrintMsg_AbortPreview, OnAbortPreview) IPC_MESSAGE_HANDLER(PrintMsg_PreviewPrintingRequestCancelled, DisplayPrintJobError) IPC_MESSAGE_UNHANDLED(handled = false) @@ -268,21 +263,115 @@ void PrintWebViewHelper::OnPrintPages() { void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) { DCHECK(is_preview_); - DCHECK(!context_menu_preview_node_.get() || !script_initiated_preview_frame_); - - if (script_initiated_preview_frame_) { - // Script initiated print preview. - PrintPreview(script_initiated_preview_frame_, NULL, settings); - } else if (context_menu_preview_node_.get()) { - // User initiated - print node under context menu. - PrintPreview(context_menu_preview_node_->document().frame(), - context_menu_preview_node_.get(), settings); - } else { - // User initiated - normal print preview. - WebFrame* frame; - if (GetPrintFrame(&frame)) - PrintPreview(frame, NULL, settings); + print_preview_context_.OnPrintPreview(); + + if (!InitPrintSettings(print_preview_context_.frame(), + print_preview_context_.node())) { + NOTREACHED(); + return; + } + + if (!UpdatePrintSettings(settings)) { + DidFinishPrinting(FAIL_PREVIEW); + return; + } + + if (print_pages_params_->params.preview_request_id != 0 && + old_print_pages_params_.get() && + PrintMsg_Print_Params_IsEqual(*old_print_pages_params_, + *print_pages_params_)) { + PrintHostMsg_DidPreviewDocument_Params preview_params; + preview_params.reuse_existing_data = true; + preview_params.data_size = 0; + preview_params.document_cookie = + print_pages_params_->params.document_cookie; + preview_params.expected_pages_count = + print_preview_context_.total_page_count(); + preview_params.modifiable = print_preview_context_.IsModifiable(); + preview_params.preview_request_id = + print_pages_params_->params.preview_request_id; + + Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params)); + return; + } + + // PDF printer device supports alpha blending. + print_pages_params_->params.supports_alpha_blend = true; + if (!CreatePreviewDocument()) + DidFinishPrinting(FAIL_PREVIEW); +} + +bool PrintWebViewHelper::CreatePreviewDocument() { + PrintMsg_Print_Params printParams = print_pages_params_->params; + UpdatePrintableSizeInPrintParameters(print_preview_context_.frame(), + print_preview_context_.node(), + &printParams); + + const std::vector<int>& pages = print_pages_params_->pages; + if (!print_preview_context_.CreatePreviewDocument(printParams, pages)) + return false; + int page_count = print_preview_context_.total_page_count(); + int document_cookie = print_pages_params_->params.document_cookie; + Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), document_cookie, + page_count)); + PreviewPageRendered(-1); + return true; +} + +void PrintWebViewHelper::OnContinuePreview() { + // Spurious message. We already finished/cancelled/aborted the print preview. + if (!print_preview_context_.IsBusy()) + return; + + int page_number = print_preview_context_.GetNextPageNumber(); + if (page_number >= 0) { + // Continue generating the print preview. + RenderPreviewPage(page_number); + return; + } + + // Finished generating preview. Finalize the document. + if (FinalizePreviewDocument()) + DidFinishPrinting(OK); + else + DidFinishPrinting(FAIL_PREVIEW); +} + +void PrintWebViewHelper::OnAbortPreview() { + DidFinishPrinting(ABORT_PREVIEW); + return; +} + +bool PrintWebViewHelper::FinalizePreviewDocument() { + print_preview_context_.FinalizePreviewDocument(); + + // Get the size of the resulting metafile. + printing::Metafile* metafile = print_preview_context_.metafile(); + uint32 buf_size = metafile->GetDataSize(); + DCHECK_GT(buf_size, 0u); + + PrintHostMsg_DidPreviewDocument_Params preview_params; + preview_params.reuse_existing_data = false; + preview_params.data_size = buf_size; + preview_params.document_cookie = print_pages_params_->params.document_cookie; + preview_params.expected_pages_count = + print_preview_context_.total_page_count(); + preview_params.modifiable = print_preview_context_.IsModifiable(); + preview_params.preview_request_id = + print_pages_params_->params.preview_request_id; + + // Ask the browser to create the shared memory for us. + if (!CopyMetafileDataToSharedMem(metafile, + &(preview_params.metafile_data_handle))) { + return false; } +#if defined(OS_WIN) + Send(new PrintHostMsg_DuplicateSection(routing_id(), + preview_params.metafile_data_handle, + &preview_params.metafile_data_handle)); +#endif + Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params)); + return true; } void PrintWebViewHelper::OnPrintingDone(bool success) { @@ -300,8 +389,7 @@ void PrintWebViewHelper::OnPrintNodeUnderContextMenu() { // Make a copy of the node, in case RenderView::OnContextMenuClosed resets // its |context_menu_node_|. if (is_preview_) { - context_menu_preview_node_.reset(new WebNode(context_menu_node)); - script_initiated_preview_frame_ = NULL; + print_preview_context_.InitWithNode(context_menu_node); RequestPrintPreview(); } else { WebNode duplicate_node(context_menu_node); @@ -311,9 +399,11 @@ void PrintWebViewHelper::OnPrintNodeUnderContextMenu() { void PrintWebViewHelper::OnInitiatePrintPreview() { DCHECK(is_preview_); - script_initiated_preview_frame_ = NULL; - context_menu_preview_node_.reset(); - RequestPrintPreview(); + WebFrame* frame; + if (GetPrintFrame(&frame)) { + print_preview_context_.InitWithFrame(frame); + RequestPrintPreview(); + } } void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) { @@ -332,7 +422,7 @@ void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) { // a scope for itself (see comments on PrepareFrameAndViewForPrint). { PrepareFrameAndViewForPrint prep_frame_view( - print_pages_params_->params, frame, node, frame->view()); + print_pages_params_->params, frame, node); expected_pages_count = prep_frame_view.GetExpectedPageCount(); if (expected_pages_count) use_browser_overlays = prep_frame_view.ShouldUseBrowserOverlays(); @@ -357,44 +447,6 @@ void PrintWebViewHelper::Print(WebKit::WebFrame* frame, WebKit::WebNode* node) { ResetScriptedPrintCount(); } -void PrintWebViewHelper::PrintPreview(WebKit::WebFrame* frame, - WebKit::WebNode* node, - const DictionaryValue& settings) { - DCHECK(is_preview_); - - if (!InitPrintSettings(frame, node)) { - NOTREACHED() << "Failed to initialize print page settings"; - return; - } - - if (!UpdatePrintSettings(settings)) { - DidFinishPrinting(FAIL_PREVIEW); - return; - } - - if (print_pages_params_->params.preview_request_id != 0 && - old_print_pages_params_.get() && - PrintMsg_Print_Params_IsEqual(*old_print_pages_params_, - *print_pages_params_)) { - PrintHostMsg_DidPreviewDocument_Params preview_params; - preview_params.reuse_existing_data = true; - preview_params.data_size = 0; - preview_params.document_cookie = - print_pages_params_->params.document_cookie; - preview_params.expected_pages_count = preview_page_count_; - preview_params.modifiable = IsModifiable(frame, node); - preview_params.preview_request_id = - print_pages_params_->params.preview_request_id; - - Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params)); - return; - } - - // Render Pages for preview. - if (!RenderPagesForPreview(frame, node)) - DidFinishPrinting(FAIL_PREVIEW); -} - void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) { bool store_print_pages_params = true; if (result == FAIL_PRINT) { @@ -405,13 +457,17 @@ void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) { Send(new PrintHostMsg_PrintingFailed(routing_id(), cookie)); } } else if (result == FAIL_PREVIEW) { + DCHECK(is_preview_); + store_print_pages_params = false; int cookie = print_pages_params_->params.document_cookie; + Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie)); + print_preview_context_.Abort(); + } else if (result == ABORT_PREVIEW) { + DCHECK(is_preview_); store_print_pages_params = false; - if (notify_browser_of_print_failure_) { - Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie)); - } else { - Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie)); - } + print_preview_context_.Abort(); + } else if (result == OK && is_preview_) { + print_preview_context_.Finished(); } if (print_web_view_) { @@ -462,10 +518,7 @@ bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params, PrintMsg_Print_Params printParams = params.params; UpdatePrintableSizeInPrintParameters(frame, node, &printParams); - PrepareFrameAndViewForPrint prep_frame_view(printParams, - frame, - node, - frame->view()); + PrepareFrameAndViewForPrint prep_frame_view(printParams, frame, node); int page_count = prep_frame_view.GetExpectedPageCount(); if (!page_count) return false; @@ -575,16 +628,6 @@ void PrintWebViewHelper::GetPageSizeAndMarginsInPoints( ConvertPixelsToPointDouble(margin_left_in_pixels); } -bool PrintWebViewHelper::IsModifiable(WebKit::WebFrame* frame, - WebKit::WebNode* node) { - if (node) - return false; - std::string mime(frame->dataSource()->response().mimeType().utf8()); - if (mime == "application/pdf") - return false; - return true; -} - void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters( WebFrame* frame, WebNode* node, @@ -595,7 +638,7 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters( double margin_right_in_points; double margin_bottom_in_points; double margin_left_in_points; - PrepareFrameAndViewForPrint prepare(*params, frame, node, frame->view()); + PrepareFrameAndViewForPrint prepare(*params, frame, node); PrintWebViewHelper::GetPageSizeAndMarginsInPoints(frame, 0, *params, &content_width_in_points, &content_height_in_points, &margin_top_in_points, &margin_right_in_points, @@ -626,6 +669,7 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters( bool PrintWebViewHelper::InitPrintSettings(WebKit::WebFrame* frame, WebKit::WebNode* node) { + DCHECK(frame); PrintMsg_PrintPages_Params settings; // TODO(abodenha@chromium.org) It doesn't make sense to do this if our @@ -751,42 +795,6 @@ bool PrintWebViewHelper::RenderPagesForPrint(WebKit::WebFrame* frame, } } -bool PrintWebViewHelper::RenderPagesForPreview(WebKit::WebFrame* frame, - WebKit::WebNode* node) { - PrintMsg_PrintPages_Params print_settings = *print_pages_params_; - // PDF printer device supports alpha blending. - print_settings.params.supports_alpha_blend = true; - // TODO(kmadhusu): Handle print selection. - return CreatePreviewDocument(print_settings, frame, node); -} - -base::TimeTicks PrintWebViewHelper::ReportPreviewPageRenderTime( - base::TimeTicks start_time) { - base::TimeTicks now = base::TimeTicks::Now(); - UMA_HISTOGRAM_TIMES("PrintPreview.RenderPDFPageTime", now - start_time); - return now; -} - -void PrintWebViewHelper::ReportTotalPreviewGenerationTime( - int selected_pages_length, int total_pages, - base::TimeDelta render_time, base::TimeDelta total_time) { - if (selected_pages_length == 0) - selected_pages_length = total_pages; - - if (selected_pages_length <= 0) { - // This shouldn't happen, but this makes sure it doesn't affect the - // statistics if it does. - return; - } - - UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderToPDFTime", - render_time); - UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime", - total_time); - UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage", - total_time / selected_pages_length); -} - #if defined(OS_POSIX) bool PrintWebViewHelper::CopyMetafileDataToSharedMem( printing::Metafile* metafile, @@ -812,6 +820,7 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent( WebKit::WebFrame* frame) { const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2; const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 32; + bool too_frequent = false; // Check if there is script repeatedly trying to print and ignore it if too // frequent. The first 3 times, we use a constant wait time, but if this @@ -829,15 +838,21 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent( kMaxSecondsToIgnoreJavascriptInitiatedPrint); } if (diff.InSeconds() < min_wait_seconds) { - WebString message(WebString::fromUTF8( - "Ignoring too frequent calls to print().")); - frame->addMessageToConsole(WebConsoleMessage( - WebConsoleMessage::LevelWarning, - message)); - return true; + too_frequent = true; } } - return false; + + if (!too_frequent && print_preview_context_.IsBusy()) + too_frequent = true; + + if (!too_frequent) + return false; + + WebString message(WebString::fromUTF8( + "Ignoring too frequent calls to print().")); + frame->addMessageToConsole(WebConsoleMessage(WebConsoleMessage::LevelWarning, + message)); + return true; } void PrintWebViewHelper::ResetScriptedPrintCount() { @@ -865,10 +880,184 @@ void PrintWebViewHelper::RequestPrintPreview() { Send(new PrintHostMsg_RequestPrintPreview(routing_id())); } -bool PrintWebViewHelper::PreviewPageRendered(int page_number) { - bool cancel = false; - Send(new PrintHostMsg_DidPreviewPage(routing_id(), page_number, &cancel)); - if (cancel) - notify_browser_of_print_failure_ = false; - return !cancel; +void PrintWebViewHelper::PreviewPageRendered(int page_number) { + Send(new PrintHostMsg_DidPreviewPage(routing_id(), page_number)); +} + +PrintWebViewHelper::PrintPreviewContext::PrintPreviewContext() + : frame_(NULL), + total_page_count_(0), + actual_page_count_(0), + current_page_number_(0), + state_(UNINITIALIZED) { +} + +PrintWebViewHelper::PrintPreviewContext::~PrintPreviewContext() { +} + +void PrintWebViewHelper::PrintPreviewContext::InitWithFrame( + WebKit::WebFrame* web_frame) { + DCHECK(web_frame); + if (IsReadyToRender()) + return; + state_ = INITIALIZED; + frame_ = web_frame; + node_.reset(); +} + +void PrintWebViewHelper::PrintPreviewContext::InitWithNode( + const WebKit::WebNode& web_node) { + DCHECK(!web_node.isNull()); + if (IsReadyToRender()) + return; + state_ = INITIALIZED; + frame_ = web_node.document().frame(); + node_.reset(new WebNode(web_node)); +} + +void PrintWebViewHelper::PrintPreviewContext::OnPrintPreview() { + DCHECK(IsReadyToRender()); + ClearContext(); +} + +bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument( + const PrintMsg_Print_Params& printParams, + const std::vector<int>& pages) { + DCHECK(IsReadyToRender()); + state_ = RENDERING; + + print_params_.reset(new PrintMsg_Print_Params(printParams)); + + metafile_.reset(new printing::PreviewMetafile); + if (!metafile_->Init()) + return false; + + // Need to make sure old object gets destroyed first. + prep_frame_view_.reset(new PrepareFrameAndViewForPrint(printParams, frame(), + node())); + total_page_count_ = prep_frame_view_->GetExpectedPageCount(); + if (total_page_count_ == 0) + return false; + + current_page_number_ = 0; + if (pages.empty()) { + actual_page_count_ = total_page_count_; + rendered_pages_ = std::vector<bool>(total_page_count_, false); + } else { + actual_page_count_ = pages.size(); + rendered_pages_ = std::vector<bool>(total_page_count_, true); + for (int i = 0; i < actual_page_count_; ++i) { + int page_number = pages[i]; + if (page_number < 0 || page_number >= total_page_count_) + return false; + rendered_pages_[page_number] = false; + } + } + + document_render_time_ = base::TimeDelta(); + begin_time_ = base::TimeTicks::Now(); + + return true; +} + +void PrintWebViewHelper::PrintPreviewContext::RenderedPreviewPage( + const base::TimeDelta& page_time) { + DCHECK_EQ(RENDERING, state_); + document_render_time_ += page_time; + UMA_HISTOGRAM_TIMES("PrintPreview.RenderPDFPageTime", page_time); +} + +void PrintWebViewHelper::PrintPreviewContext::FinalizePreviewDocument() { + DCHECK_EQ(RENDERING, state_); + state_ = DONE; + + base::TimeTicks begin_time = base::TimeTicks::Now(); + + prep_frame_view_->FinishPrinting(); + metafile_->FinishDocument(); + + if (actual_page_count_ <= 0) { + NOTREACHED(); + return; + } + + UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderToPDFTime", + document_render_time_); + base::TimeDelta total_time = (base::TimeTicks::Now() - begin_time) + + document_render_time_; + UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTime", + total_time); + UMA_HISTOGRAM_MEDIUM_TIMES("PrintPreview.RenderAndGeneratePDFTimeAvgPerPage", + total_time / actual_page_count_); +} + +void PrintWebViewHelper::PrintPreviewContext::Finished() { + DCHECK_EQ(DONE, state_); + ClearContext(); +} + +void PrintWebViewHelper::PrintPreviewContext::Abort() { + state_ = UNINITIALIZED; + ClearContext(); + frame_ = NULL; + node_.reset(); +} + +int PrintWebViewHelper::PrintPreviewContext::GetNextPageNumber() { + DCHECK_EQ(RENDERING, state_); + while (current_page_number_ < total_page_count_ && + rendered_pages_[current_page_number_]) { + ++current_page_number_; + } + if (current_page_number_ == total_page_count_) + return -1; + rendered_pages_[current_page_number_] = true; + return current_page_number_++; +} + +bool PrintWebViewHelper::PrintPreviewContext::IsReadyToRender() const { + return state_ != UNINITIALIZED; +} + +bool PrintWebViewHelper::PrintPreviewContext::IsBusy() const { + return state_ == INITIALIZED || state_ == RENDERING; +} + +bool PrintWebViewHelper::PrintPreviewContext::IsModifiable() const { + if (node()) + return false; + std::string mime(frame()->dataSource()->response().mimeType().utf8()); + return mime != "application/pdf"; +} + +WebKit::WebFrame* PrintWebViewHelper::PrintPreviewContext::frame() const { + return frame_; +} + +WebKit::WebNode* PrintWebViewHelper::PrintPreviewContext::node() const { + return node_.get(); +} + +int PrintWebViewHelper::PrintPreviewContext::total_page_count() const { + return total_page_count_; +} + +printing::Metafile* PrintWebViewHelper::PrintPreviewContext::metafile() const { + return metafile_.get(); +} + +const PrintMsg_Print_Params& +PrintWebViewHelper::PrintPreviewContext::print_params() const { + return *print_params_; +} + +const gfx::Size& +PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const { + return prep_frame_view_->GetPrintCanvasSize(); +} + +void PrintWebViewHelper::PrintPreviewContext::ClearContext() { + prep_frame_view_.reset(); + metafile_.reset(); + rendered_pages_.clear(); } diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h index 48b7037..81d40e3 100644 --- a/chrome/renderer/print_web_view_helper.h +++ b/chrome/renderer/print_web_view_helper.h @@ -6,6 +6,8 @@ #define CHROME_RENDERER_PRINT_WEB_VIEW_HELPER_H_ #pragma once +#include <vector> + #include "base/memory/scoped_ptr.h" #include "base/shared_memory.h" #include "base/time.h" @@ -34,8 +36,7 @@ class PrepareFrameAndViewForPrint { // printed. PrepareFrameAndViewForPrint(const PrintMsg_Print_Params& print_params, WebKit::WebFrame* frame, - WebKit::WebNode* node, - WebKit::WebView* web_view); + WebKit::WebNode* node); ~PrepareFrameAndViewForPrint(); int GetExpectedPageCount() const { @@ -108,8 +109,21 @@ class PrintWebViewHelper : public RenderViewObserver, // Initiate print preview. void OnInitiatePrintPreview(); - // Generate a print preview using |settings|. + // Start the process of generating a print preview using |settings|. void OnPrintPreview(const base::DictionaryValue& settings); + // Initialize the print preview document. + bool CreatePreviewDocument(); + + // Continue generating the print preview. + void OnContinuePreview(); + // Renders a print preview page. |page_number| is 0-based. + void RenderPreviewPage(int page_number); + // Finalize the print preview document. + bool FinalizePreviewDocument(); + + // Abort the preview to put |print_preview_context_| into the 'UNINITIALIZED' + // state. + void OnAbortPreview(); // Print / preview the node under the context menu. void OnPrintNodeUnderContextMenu(); @@ -124,14 +138,11 @@ class PrintWebViewHelper : public RenderViewObserver, void Print(WebKit::WebFrame* frame, WebKit::WebNode* node); - void PrintPreview(WebKit::WebFrame* frame, - WebKit::WebNode* node, - const base::DictionaryValue& settings); - enum PrintingResult { OK, FAIL_PRINT, FAIL_PREVIEW, + ABORT_PREVIEW, }; // Notification when printing is done - signal tear-down/free resources. @@ -187,16 +198,6 @@ class PrintWebViewHelper : public RenderViewObserver, // Render the frame for printing. bool RenderPagesForPrint(WebKit::WebFrame* frame, WebKit::WebNode* node); - // Render the frame for preview. - bool RenderPagesForPreview(WebKit::WebFrame* frame, WebKit::WebNode* node); - - // Renders all the pages listed in |params| for preview. - // On success, Send PrintHostMsg_PagesReadyForPreview message with a - // valid metafile data handle. - bool CreatePreviewDocument(const PrintMsg_PrintPages_Params& params, - WebKit::WebFrame* frame, - WebKit::WebNode* node); - // Platform specific helper function for rendering page(s) to |metafile|. #if defined(OS_WIN) void RenderPage(const PrintMsg_Print_Params& params, float* scale_factor, @@ -208,11 +209,8 @@ class PrintWebViewHelper : public RenderViewObserver, WebKit::WebFrame* frame, printing::Metafile* metafile); #elif defined(OS_POSIX) bool RenderPages(const PrintMsg_PrintPages_Params& params, - WebKit::WebFrame* frame, - WebKit::WebNode* node, - int* page_count, - printing::Metafile* metafile, - bool is_preview); + WebKit::WebFrame* frame, WebKit::WebNode* node, + int* page_count, printing::Metafile* metafile); #endif // defined(OS_WIN) // Helper methods ----------------------------------------------------------- @@ -233,21 +231,14 @@ class PrintWebViewHelper : public RenderViewObserver, double* margin_bottom_in_points, double* margin_left_in_points); - bool IsModifiable(WebKit::WebFrame* frame, WebKit::WebNode* node); - void UpdatePrintableSizeInPrintParameters(WebKit::WebFrame* frame, WebKit::WebNode* node, PrintMsg_Print_Params* params); bool GetPrintFrame(WebKit::WebFrame** frame); - // This reports the current time - |start_time| as the time to render - // a page and returns the current time. - base::TimeTicks ReportPreviewPageRenderTime(base::TimeTicks start_time); - void ReportTotalPreviewGenerationTime(int selected_pages_length, - int total_pages, - base::TimeDelta render_time, - base::TimeDelta total_time); + // This reports the current time - |start_time| as the time to render a page. + void ReportPreviewPageRenderTime(base::TimeTicks start_time); // Script Initiated Printing ------------------------------------------------ @@ -267,20 +258,12 @@ class PrintWebViewHelper : public RenderViewObserver, void RequestPrintPreview(); - // Called every time print preview renders a page. Notify the browser of the - // event and check if print preview should be cancelled. Returns false if - // print preview has been cancelled. |page_number| is 0-based, or negative to - // indicate its a cancel check only. - bool PreviewPageRendered(int page_number); + // Notify the browser a print preview page has been rendered. + // |page_number| is 0-based. + void PreviewPageRendered(int page_number); WebKit::WebView* print_web_view_; - // The frame to print for script initiated print preview. - WebKit::WebFrame* script_initiated_preview_frame_; - - // The node under the context menu to print preview. - scoped_ptr<WebKit::WebNode> context_menu_preview_node_; - scoped_ptr<PrintMsg_PrintPages_Params> print_pages_params_; bool is_preview_; @@ -292,9 +275,92 @@ class PrintWebViewHelper : public RenderViewObserver, // the failure came from the browser in the first place. bool notify_browser_of_print_failure_; - int preview_page_count_; scoped_ptr<PrintMsg_PrintPages_Params> old_print_pages_params_; + // Keeps track of the state of print preview between messages. + class PrintPreviewContext { + public: + PrintPreviewContext(); + ~PrintPreviewContext(); + + // Initializes the print preview context. Need to be called to set + // the |web_frame| / |web_node| to generate the print preview for. + void InitWithFrame(WebKit::WebFrame* web_frame); + void InitWithNode(const WebKit::WebNode& web_node); + + // Does bookkeeping at the beginning of print preview. + void OnPrintPreview(); + + // Create the print preview document. |pages| is empty to print all pages. + bool CreatePreviewDocument(const PrintMsg_Print_Params& params, + const std::vector<int>& pages); + + // Called after a page gets rendered. |page_time| is how long the + // rendering took. + void RenderedPreviewPage(const base::TimeDelta& page_time); + + // Finalizes the print preview document. + void FinalizePreviewDocument(); + + // Cleanup after print preview finishes. + void Finished(); + + // Abort the print preview. + void Abort(); + + // Helper functions + int GetNextPageNumber(); + bool IsReadyToRender() const; + bool IsBusy() const; + bool IsModifiable() const; + + // Getters + WebKit::WebFrame* frame() const; + WebKit::WebNode* node() const; + int total_page_count() const; + printing::Metafile* metafile() const; + const PrintMsg_Print_Params& print_params() const; + const gfx::Size& GetPrintCanvasSize() const; + + private: + enum State { + UNINITIALIZED, // Not ready to render. + INITIALIZED, // Ready to render. + RENDERING, // Rendering. + DONE // Finished rendering. + }; + + // Reset some of the internal rendering context. + void ClearContext(); + + // Specifies what to render for print preview. + WebKit::WebFrame* frame_; + scoped_ptr<WebKit::WebNode> node_; + + scoped_ptr<PrepareFrameAndViewForPrint> prep_frame_view_; + scoped_ptr<printing::Metafile> metafile_; + scoped_ptr<PrintMsg_Print_Params> print_params_; + + // Total page count in the renderer. + int total_page_count_; + + // Number of pages to render. + int actual_page_count_; + + // The current page to render. + int current_page_number_; + + // Array to keep track of which pages have been printed. + std::vector<bool> rendered_pages_; + + base::TimeDelta document_render_time_; + base::TimeTicks begin_time_; + + State state_; + }; + + PrintPreviewContext print_preview_context_; + DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper); }; diff --git a/chrome/renderer/print_web_view_helper_browsertest.cc b/chrome/renderer/print_web_view_helper_browsertest.cc index 97873d6..2bfa797 100644 --- a/chrome/renderer/print_web_view_helper_browsertest.cc +++ b/chrome/renderer/print_web_view_helper_browsertest.cc @@ -311,13 +311,6 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase { } protected: - void VerifyPrintPreviewCancelled(bool did_cancel) { - bool print_preview_cancelled = - (render_thread_.sink().GetUniqueMessageMatching( - PrintHostMsg_PrintPreviewCancelled::ID) != NULL); - EXPECT_EQ(did_cancel, print_preview_cancelled); - } - void VerifyPrintPreviewFailed(bool did_fail) { bool print_preview_failed = (render_thread_.sink().GetUniqueMessageMatching( PrintHostMsg_PrintPreviewFailed::ID) != NULL); @@ -353,32 +346,20 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase { TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreview) { LoadHTML(kHelloWorldHTML); + PrintWebViewHelper::Get(view_)->OnInitiatePrintPreview(); // Fill in some dummy values. DictionaryValue dict; CreatePrintSettingsDictionary(&dict); PrintWebViewHelper::Get(view_)->OnPrintPreview(dict); - VerifyPrintPreviewCancelled(false); - VerifyPrintPreviewFailed(false); - VerifyPrintPreviewGenerated(true); - VerifyPagesPrinted(false); -} - -// Tests that cancelling a print preview works correctly. -TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewCancel) { - LoadHTML(kPrintPreviewHTML); - - // Cancel the print preview. - render_thread_.set_cancel_print_preview(true); - - // Fill in some dummy values. - DictionaryValue dict; - CreatePrintSettingsDictionary(&dict); - PrintWebViewHelper::Get(view_)->OnPrintPreview(dict); + // Need to finish simulating print preview. + // Generate the page and finalize it. + PrintWebViewHelper::Get(view_)->OnContinuePreview(); + PrintWebViewHelper::Get(view_)->OnContinuePreview(); - VerifyPrintPreviewCancelled(true); + EXPECT_EQ(0, render_thread_.print_preview_pages_remaining()); VerifyPrintPreviewFailed(false); - VerifyPrintPreviewGenerated(false); + VerifyPrintPreviewGenerated(true); VerifyPagesPrinted(false); } @@ -387,11 +368,12 @@ TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewCancel) { TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewFail) { LoadHTML(kHelloWorldHTML); + PrintWebViewHelper::Get(view_)->OnInitiatePrintPreview(); // An empty dictionary should fail. DictionaryValue empty_dict; PrintWebViewHelper::Get(view_)->OnPrintPreview(empty_dict); - VerifyPrintPreviewCancelled(false); + EXPECT_EQ(0, render_thread_.print_preview_pages_remaining()); VerifyPrintPreviewFailed(true); VerifyPrintPreviewGenerated(false); VerifyPagesPrinted(false); diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc index 4947f14..8c6dad9 100644 --- a/chrome/renderer/print_web_view_helper_linux.cc +++ b/chrome/renderer/print_web_view_helper_linux.cc @@ -25,38 +25,19 @@ using WebKit::WebFrame; using WebKit::WebNode; -bool PrintWebViewHelper::CreatePreviewDocument( - const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, - WebKit::WebNode* node) { - if (!PreviewPageRendered(-1)) - return false; - - printing::PreviewMetafile metafile; - if (!metafile.Init()) - return false; - - preview_page_count_ = 0; - if (!RenderPages(params, frame, node, &preview_page_count_, &metafile, true)) - return false; - - // Get the size of the resulting metafile. - uint32 buf_size = metafile.GetDataSize(); - DCHECK_GT(buf_size, 0u); - - PrintHostMsg_DidPreviewDocument_Params preview_params; - preview_params.reuse_existing_data = false; - preview_params.data_size = buf_size; - preview_params.document_cookie = params.params.document_cookie; - preview_params.expected_pages_count = preview_page_count_; - preview_params.modifiable = IsModifiable(frame, node); - preview_params.preview_request_id = params.params.preview_request_id; +void PrintWebViewHelper::RenderPreviewPage(int page_number) { + PrintMsg_PrintPage_Params page_params; + page_params.params = print_preview_context_.print_params(); + page_params.page_number = page_number; - if (!CopyMetafileDataToSharedMem(&metafile, - &(preview_params.metafile_data_handle))) { - return false; - } - Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params)); - return true; + base::TimeTicks begin_time = base::TimeTicks::Now(); + PrintPageInternal(page_params, + print_preview_context_.GetPrintCanvasSize(), + print_preview_context_.frame(), + print_preview_context_.metafile()); + print_preview_context_.RenderedPreviewPage( + base::TimeTicks::Now() - begin_time); + PreviewPageRendered(page_number); } bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params, @@ -67,7 +48,7 @@ bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params, return false; int page_count = 0; - if (!RenderPages(params, frame, node, &page_count, &metafile, false)) + if (!RenderPages(params, frame, node, &page_count, &metafile)) return false; // Get the size of the resulting metafile. @@ -142,29 +123,21 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, WebKit::WebNode* node, int* page_count, - printing::Metafile* metafile, - bool is_preview) { + printing::Metafile* metafile) { PrintMsg_Print_Params printParams = params.params; UpdatePrintableSizeInPrintParameters(frame, node, &printParams); - PrepareFrameAndViewForPrint prep_frame_view(printParams, frame, node, - frame->view()); - if (is_preview && !PreviewPageRendered(-1)) - return false; - + PrepareFrameAndViewForPrint prep_frame_view(printParams, frame, node); *page_count = prep_frame_view.GetExpectedPageCount(); if (!*page_count) return false; - if (is_preview) { - Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), *page_count)); - } else { + #if !defined(OS_CHROMEOS) Send(new PrintHostMsg_DidGetPrintedPagesCount(routing_id(), printParams.document_cookie, *page_count)); #endif - } base::TimeTicks begin_time = base::TimeTicks::Now(); base::TimeTicks page_begin_time = begin_time; @@ -176,21 +149,11 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params, for (int i = 0; i < *page_count; ++i) { page_params.page_number = i; PrintPageInternal(page_params, canvas_size, frame, metafile); - if (is_preview) { - page_begin_time = ReportPreviewPageRenderTime(page_begin_time); - if (!PreviewPageRendered(i)) - return false; - } } } else { for (size_t i = 0; i < params.pages.size(); ++i) { page_params.page_number = params.pages[i]; PrintPageInternal(page_params, canvas_size, frame, metafile); - if (is_preview) { - page_begin_time = ReportPreviewPageRenderTime(page_begin_time); - if (!PreviewPageRendered(params.pages[i])) - return false; - } } } @@ -198,12 +161,6 @@ bool PrintWebViewHelper::RenderPages(const PrintMsg_PrintPages_Params& params, prep_frame_view.FinishPrinting(); metafile->FinishDocument(); - - if (is_preview) { - ReportTotalPreviewGenerationTime(params.pages.size(), *page_count, - render_time, - base::TimeTicks::Now() - begin_time); - } return true; } diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm index 5878c20..3836161f 100644 --- a/chrome/renderer/print_web_view_helper_mac.mm +++ b/chrome/renderer/print_web_view_helper_mac.mm @@ -59,83 +59,19 @@ void PrintWebViewHelper::PrintPageInternal( Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params)); } -bool PrintWebViewHelper::CreatePreviewDocument( - const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, - WebKit::WebNode* node) { - if (!PreviewPageRendered(-1)) - return false; - - PrintMsg_Print_Params printParams = params.params; - UpdatePrintableSizeInPrintParameters(frame, node, &printParams); - - PrepareFrameAndViewForPrint prep_frame_view(printParams, - frame, node, frame->view()); - if (!PreviewPageRendered(-1)) - return false; - - preview_page_count_ = prep_frame_view.GetExpectedPageCount(); - if (!preview_page_count_) - return false; - Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), - preview_page_count_)); - - printing::PreviewMetafile metafile; - if (!metafile.Init()) - return false; - - float scale_factor = frame->getPrintPageShrink(0); +void PrintWebViewHelper::RenderPreviewPage(int page_number) { + float scale_factor = print_preview_context_.frame()->getPrintPageShrink(0); + PrintMsg_Print_Params printParams = print_preview_context_.print_params(); gfx::Rect content_area(printParams.margin_left, printParams.margin_top, printParams.printable_size.width(), printParams.printable_size.height()); base::TimeTicks begin_time = base::TimeTicks::Now(); - base::TimeTicks page_begin_time = begin_time; - - if (params.pages.empty()) { - for (int i = 0; i < preview_page_count_; ++i) { - RenderPage(printParams.page_size, content_area, scale_factor, i, frame, - &metafile); - page_begin_time = ReportPreviewPageRenderTime(page_begin_time); - if (!PreviewPageRendered(i)) - return false; - } - } else { - for (size_t i = 0; i < params.pages.size(); ++i) { - if (params.pages[i] >= preview_page_count_) - break; - RenderPage(printParams.page_size, content_area, scale_factor, - params.pages[i], frame, &metafile); - page_begin_time = ReportPreviewPageRenderTime(page_begin_time); - if (!PreviewPageRendered(params.pages[i])) - return false; - } - } - - base::TimeDelta render_time = base::TimeTicks::Now() - begin_time; - - prep_frame_view.FinishPrinting(); - metafile.FinishDocument(); - - ReportTotalPreviewGenerationTime(params.pages.size(), - preview_page_count_, - render_time, - base::TimeTicks::Now() - begin_time); - - PrintHostMsg_DidPreviewDocument_Params preview_params; - preview_params.reuse_existing_data = false; - preview_params.data_size = metafile.GetDataSize(); - preview_params.document_cookie = params.params.document_cookie; - preview_params.expected_pages_count = preview_page_count_; - preview_params.modifiable = IsModifiable(frame, node); - preview_params.preview_request_id = params.params.preview_request_id; - - // Ask the browser to create the shared memory for us. - if (!CopyMetafileDataToSharedMem(&metafile, - &(preview_params.metafile_data_handle))) { - return false; - } - Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params)); - return true; + RenderPage(printParams.page_size, content_area, scale_factor, page_number, + print_preview_context_.frame(), print_preview_context_.metafile()); + print_preview_context_.RenderedPreviewPage( + base::TimeTicks::Now() - begin_time); + PreviewPageRendered(page_number); } void PrintWebViewHelper::RenderPage( diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc index 36139be..4627e0d 100644 --- a/chrome/renderer/print_web_view_helper_win.cc +++ b/chrome/renderer/print_web_view_helper_win.cc @@ -123,93 +123,23 @@ void PrintWebViewHelper::PrintPageInternal( Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params)); } -bool PrintWebViewHelper::CreatePreviewDocument( - const PrintMsg_PrintPages_Params& params, WebKit::WebFrame* frame, - WebKit::WebNode* node) { - if (!PreviewPageRendered(-1)) - return false; - - PrintMsg_Print_Params print_params = params.params; - UpdatePrintableSizeInPrintParameters(frame, node, &print_params); - PrepareFrameAndViewForPrint prep_frame_view(print_params, frame, node, - frame->view()); - if (!PreviewPageRendered(-1)) - return false; - - preview_page_count_ = prep_frame_view.GetExpectedPageCount(); - if (!preview_page_count_) - return false; - Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), - preview_page_count_)); - - scoped_ptr<Metafile> metafile(new printing::PreviewMetafile); - metafile->Init(); - +void PrintWebViewHelper::RenderPreviewPage(int page_number) { + PrintMsg_Print_Params print_params = print_preview_context_.print_params(); // Calculate the dpi adjustment. - float shrink = static_cast<float>(print_params.desired_dpi / - print_params.dpi); + float scale_factor = static_cast<float>(print_params.desired_dpi / + print_params.dpi); + // Needed for RenderPage() below. + // Not taking ownership with intent to reset(). + scoped_ptr<Metafile> metafile(print_preview_context_.metafile()); base::TimeTicks begin_time = base::TimeTicks::Now(); - base::TimeTicks page_begin_time = begin_time; - - if (params.pages.empty()) { - for (int i = 0; i < preview_page_count_; ++i) { - float scale_factor = shrink; - RenderPage(print_params, &scale_factor, i, true, frame, &metafile); - page_begin_time = ReportPreviewPageRenderTime(page_begin_time); - if (!PreviewPageRendered(i)) - return false; - } - } else { - for (size_t i = 0; i < params.pages.size(); ++i) { - if (params.pages[i] >= preview_page_count_) - break; - float scale_factor = shrink; - RenderPage(print_params, &scale_factor, params.pages[i], true, frame, - &metafile); - page_begin_time = ReportPreviewPageRenderTime(page_begin_time); - if (!PreviewPageRendered(params.pages[i])) - return false; - } - } - - base::TimeDelta render_time = base::TimeTicks::Now() - begin_time; - - // Ensure that printing has finished before we start cleaning up and - // allocating buffers; this causes prep_frame_view to flush anything pending - // into the metafile. Then we can get the final size and copy it into a - // shared segment. - prep_frame_view.FinishPrinting(); - - if (!metafile->FinishDocument()) - NOTREACHED(); - - ReportTotalPreviewGenerationTime(params.pages.size(), - preview_page_count_, - render_time, - base::TimeTicks::Now() - begin_time); - - // Get the size of the compiled metafile. - uint32 buf_size = metafile->GetDataSize(); - DCHECK_GT(buf_size, 128u); - - PrintHostMsg_DidPreviewDocument_Params preview_params; - preview_params.reuse_existing_data = false; - preview_params.data_size = buf_size; - preview_params.document_cookie = params.params.document_cookie; - preview_params.expected_pages_count = preview_page_count_; - preview_params.modifiable = IsModifiable(frame, node); - preview_params.preview_request_id = params.params.preview_request_id; - - if (!CopyMetafileDataToSharedMem(metafile.get(), - &(preview_params.metafile_data_handle))) { - return false; - } - Send(new PrintHostMsg_DuplicateSection(routing_id(), - preview_params.metafile_data_handle, - &preview_params.metafile_data_handle)); - Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params)); - return true; + RenderPage(print_params, &scale_factor, page_number, true, + print_preview_context_.frame(), &metafile); + // Release since |print_preview_context_| is the real owner. + metafile.release(); + print_preview_context_.RenderedPreviewPage( + base::TimeTicks::Now() - begin_time); + PreviewPageRendered(page_number); } void PrintWebViewHelper::RenderPage( |