diff options
20 files changed, 389 insertions, 266 deletions
diff --git a/chrome/browser/printing/print_preview_message_handler.cc b/chrome/browser/printing/print_preview_message_handler.cc index acaecba..810f0ab 100644 --- a/chrome/browser/printing/print_preview_message_handler.cc +++ b/chrome/browser/printing/print_preview_message_handler.cc @@ -84,8 +84,10 @@ void PrintPreviewMessageHandler::OnRequestPrintPreview() { void PrintPreviewMessageHandler::OnDidGetPreviewPageCount( const PrintHostMsg_DidGetPreviewPageCount_Params& params) { - if (params.page_count <= 0) + if (params.page_count <= 0) { + NOTREACHED(); return; + } TabContents* print_preview_tab = GetPrintPreviewTab(); if (!print_preview_tab || !print_preview_tab->web_ui()) @@ -98,26 +100,12 @@ void PrintPreviewMessageHandler::OnDidGetPreviewPageCount( void PrintPreviewMessageHandler::OnDidPreviewPage( const PrintHostMsg_DidPreviewPage_Params& params) { - RenderViewHost* rvh = tab_contents()->render_view_host(); TabContents* print_preview_tab = GetPrintPreviewTab(); - 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())); + if (!print_preview_tab || !print_preview_tab->web_ui()) return; - } PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(print_preview_tab->web_ui()); - bool has_pending = print_preview_ui->HasPendingRequests(); - if (has_pending) { - // Cancel. Next print preview request will cancel the current one. Just do - // the required maintenance work here. - StopWorker(print_preview_ui->document_cookie()); - print_preview_ui->OnPrintPreviewCancelled(); - return; - } - - int requested_preview_page_index = INVALID_PAGE_INDEX; int page_number = params.page_number; if (page_number == FIRST_PAGE_INDEX) @@ -130,18 +118,19 @@ void PrintPreviewMessageHandler::OnDidPreviewPage( print_preview_ui->SetPrintPreviewDataForIndex(page_number, data_bytes); print_preview_ui->OnDidPreviewPage(page_number, params.preview_request_id); - // TODO(kmadhusu): Query |PrintPreviewUI| and update - // |requested_preview_page_index| accordingly. } - - rvh->Send(new PrintMsg_ContinuePreview(rvh->routing_id(), - requested_preview_page_index)); } void PrintPreviewMessageHandler::OnPagesReadyForPreview( const PrintHostMsg_DidPreviewDocument_Params& params) { + // Always try to stop the worker. StopWorker(params.document_cookie); + if (params.expected_pages_count <= 0) { + NOTREACHED(); + return; + } + // Get the print preview tab. TabContents* print_preview_tab = GetPrintPreviewTab(); // User might have closed it already. @@ -206,6 +195,11 @@ void PrintPreviewMessageHandler::OnPrintPreviewFailed(int document_cookie) { } } +void PrintPreviewMessageHandler::OnPrintPreviewCancelled(int document_cookie) { + // Always need to stop the worker. + StopWorker(document_cookie); +} + bool PrintPreviewMessageHandler::OnMessageReceived( const IPC::Message& message) { bool handled = true; @@ -220,6 +214,8 @@ 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 11bc8a0..647e5b5 100644 --- a/chrome/browser/printing/print_preview_message_handler.h +++ b/chrome/browser/printing/print_preview_message_handler.h @@ -34,11 +34,11 @@ class PrintPreviewMessageHandler : public TabContentsObserver { void OnRequestPrintPreview(); void OnDidGetPreviewPageCount( const PrintHostMsg_DidGetPreviewPageCount_Params& params); - // |page_number| is 0-based. void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params); 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/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc index c9593d1..1f9ad53 100644 --- a/chrome/browser/printing/printing_message_filter.cc +++ b/chrome/browser/printing/printing_message_filter.cc @@ -4,16 +4,20 @@ #include "chrome/browser/printing/printing_message_filter.h" +#include <string> + #include "base/process_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/printing/printer_query.h" #include "chrome/browser/printing/print_job_manager.h" +#include "chrome/browser/ui/webui/print_preview_ui.h" #include "chrome/common/print_messages.h" -#include "content/common/view_messages.h" #if defined(OS_CHROMEOS) #include <fcntl.h> +#include <map> + #include "base/file_util.h" #include "base/lazy_instance.h" #include "chrome/browser/printing/print_dialog_cloud.h" @@ -108,6 +112,7 @@ bool PrintingMessageFilter::OnMessageReceived(const IPC::Message& message, IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_ScriptedPrint, OnScriptedPrint) IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_UpdatePrintSettings, OnUpdatePrintSettings) + IPC_MESSAGE_HANDLER(PrintHostMsg_CheckForCancel, OnCheckForCancel) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -313,3 +318,11 @@ void PrintingMessageFilter::OnUpdatePrintSettingsReply( else printer_query->StopWorker(); } + +void PrintingMessageFilter::OnCheckForCancel(const std::string& preview_ui_addr, + int preview_request_id, + bool* cancel) { + PrintPreviewUI::GetCurrentPrintPreviewStatus(preview_ui_addr, + preview_request_id, + cancel); +} diff --git a/chrome/browser/printing/printing_message_filter.h b/chrome/browser/printing/printing_message_filter.h index a611394..2918ac1 100644 --- a/chrome/browser/printing/printing_message_filter.h +++ b/chrome/browser/printing/printing_message_filter.h @@ -6,6 +6,8 @@ #define CHROME_BROWSER_PRINTING_PRINTING_MESSAGE_FILTER_H_ #pragma once +#include <string> + #include "content/browser/browser_message_filter.h" #if defined(OS_WIN) @@ -77,6 +79,10 @@ class PrintingMessageFilter : public BrowserMessageFilter { scoped_refptr<printing::PrinterQuery> printer_query, IPC::Message* reply_msg); + void OnCheckForCancel(const std::string& preview_ui_addr, + int preview_request_id, + bool* cancel); + printing::PrintJobManager* print_job_manager_; bool cloud_print_enabled_; diff --git a/chrome/browser/ui/webui/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview_handler.cc index d904c18..aa0007f 100644 --- a/chrome/browser/ui/webui/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview_handler.cc @@ -477,13 +477,21 @@ void PrintPreviewHandler::HandleGetPreview(const ListValue* args) { scoped_ptr<DictionaryValue> settings(GetSettingsDictionary(args)); if (!settings.get()) return; + int request_id = -1; + if (!settings->GetInteger(printing::kPreviewRequestID, &request_id)) + return; + + PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(web_ui_); + print_preview_ui->OnPrintPreviewRequest(request_id); + // Add an additional key in order to identify |print_preview_ui| later on + // when calling PrintPreviewUI::GetCurrentPrintPreviewStatus() on the IO + // thread. + settings->SetString(printing::kPreviewUIAddr, + print_preview_ui->GetPrintPreviewUIAddress()); // Increment request count. ++regenerate_preview_request_count_; - PrintPreviewUI* print_preview_ui = static_cast<PrintPreviewUI*>(web_ui_); - print_preview_ui->OnPrintPreviewRequest(); - TabContents* initiator_tab = GetInitiatorTab(); if (!initiator_tab) { if (!reported_failed_preview_) { @@ -874,11 +882,6 @@ void PrintPreviewHandler::OnTabDestroyed() { 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 d8b4785..64a7d58 100644 --- a/chrome/browser/ui/webui/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview_ui.cc @@ -4,8 +4,12 @@ #include "chrome/browser/ui/webui/print_preview_ui.h" +#include <map> + +#include "base/lazy_instance.h" #include "base/metrics/histogram.h" #include "base/string_util.h" +#include "base/synchronization/lock.h" #include "base/values.h" #include "chrome/browser/printing/print_preview_data_service.h" #include "chrome/browser/profiles/profile.h" @@ -13,12 +17,55 @@ #include "chrome/browser/ui/webui/print_preview_handler.h" #include "chrome/common/print_messages.h" #include "content/browser/tab_contents/tab_contents.h" +#include "printing/print_job_constants.h" + +namespace { + +// Thread-safe wrapper around a std::map to keep track of mappings from +// PrintPreviewUI addresses to most recent print preview request ids. +class PrintPreviewRequestIdMapWithLock { + public: + PrintPreviewRequestIdMapWithLock() {} + ~PrintPreviewRequestIdMapWithLock() {} + + // Get the value for |addr|. Returns true and sets |out_value| on success. + bool Get(const std::string& addr, int* out_value) { + base::AutoLock lock(lock_); + PrintPreviewRequestIdMap::const_iterator it = map_.find(addr); + if (it == map_.end()) + return false; + *out_value = it->second; + return true; + } + + // Sets the |value| for |addr|. + void Set(const std::string& addr, int value) { + base::AutoLock lock(lock_); + map_[addr] = value; + } + + // Erase the entry for |addr|. + void Erase(const std::string& addr) { + base::AutoLock lock(lock_); + map_.erase(addr); + } + + private: + typedef std::map<std::string, int> PrintPreviewRequestIdMap; + + PrintPreviewRequestIdMap map_; + base::Lock lock_; +}; + +// Written to on the UI thread, read from any thread. +base::LazyInstance<PrintPreviewRequestIdMapWithLock> + g_print_preview_request_id_map(base::LINKER_INITIALIZED); + +} // namespace PrintPreviewUI::PrintPreviewUI(TabContents* contents) : ChromeWebUI(contents), - initial_preview_start_time_(base::TimeTicks::Now()), - request_count_(0U), - document_cookie_(0) { + initial_preview_start_time_(base::TimeTicks::Now()) { // WebUI owns |handler_|. handler_ = new PrintPreviewHandler(); AddMessageHandler(handler_->Attach(this)); @@ -28,15 +75,15 @@ PrintPreviewUI::PrintPreviewUI(TabContents* contents) profile->GetChromeURLDataManager()->AddDataSource( new PrintPreviewDataSource()); - // Store the PrintPreviewUIAddress as a string. - // "0x" + deadc0de + '\0' = 2 + 2 * sizeof(this) + 1; - char preview_ui_addr[2 + (2 * sizeof(this)) + 1]; - base::snprintf(preview_ui_addr, sizeof(preview_ui_addr), "%p", this); - preview_ui_addr_str_ = preview_ui_addr; + preview_ui_addr_str_ = GetPrintPreviewUIAddress(); + + g_print_preview_request_id_map.Get().Set(preview_ui_addr_str_, -1); } PrintPreviewUI::~PrintPreviewUI() { print_preview_data_service()->RemoveEntry(preview_ui_addr_str_); + + g_print_preview_request_id_map.Get().Erase(preview_ui_addr_str_); } void PrintPreviewUI::GetPrintPreviewDataForIndex( @@ -61,6 +108,27 @@ void PrintPreviewUI::SetInitiatorTabURLAndTitle( initiator_tab_title_ = job_title; } +// static +void PrintPreviewUI::GetCurrentPrintPreviewStatus( + const std::string& preview_ui_addr, + int request_id, + bool* cancel) { + int current_id = -1; + if (!g_print_preview_request_id_map.Get().Get(preview_ui_addr, ¤t_id)) { + *cancel = true; + return; + } + *cancel = (request_id != current_id); +} + +std::string PrintPreviewUI::GetPrintPreviewUIAddress() const { + // Store the PrintPreviewUIAddress as a string. + // "0x" + deadc0de + '\0' = 2 + 2 * sizeof(this) + 1; + char preview_ui_addr[2 + (2 * sizeof(this)) + 1]; + base::snprintf(preview_ui_addr, sizeof(preview_ui_addr), "%p", this); + return preview_ui_addr; +} + void PrintPreviewUI::OnInitiatorTabCrashed() { StringValue initiator_tab_url(initiator_url_); CallJavascriptFunction("onInitiatorTabCrashed", initiator_tab_url); @@ -71,14 +139,13 @@ void PrintPreviewUI::OnInitiatorTabClosed() { CallJavascriptFunction("onInitiatorTabClosed", initiator_tab_url); } -void PrintPreviewUI::OnPrintPreviewRequest() { - request_count_++; +void PrintPreviewUI::OnPrintPreviewRequest(int request_id) { + g_print_preview_request_id_map.Get().Set(preview_ui_addr_str_, request_id); } void PrintPreviewUI::OnDidGetPreviewPageCount( const PrintHostMsg_DidGetPreviewPageCount_Params& params) { DCHECK_GT(params.page_count, 0); - document_cookie_ = params.document_cookie; base::FundamentalValue count(params.page_count); base::FundamentalValue modifiable(params.is_modifiable); base::FundamentalValue request_id(params.preview_request_id); @@ -97,8 +164,6 @@ void PrintPreviewUI::OnDidPreviewPage(int page_number, } void PrintPreviewUI::OnReusePreviewData(int preview_request_id) { - DecrementRequestCount(); - base::StringValue ui_identifier(preview_ui_addr_str_); base::FundamentalValue ui_preview_request_id(preview_request_id); CallJavascriptFunction("reloadPreviewPages", ui_identifier, @@ -109,7 +174,6 @@ void PrintPreviewUI::OnPreviewDataIsAvailable(int expected_pages_count, int preview_request_id) { VLOG(1) << "Print preview request finished with " << expected_pages_count << " pages"; - DecrementRequestCount(); if (!initial_preview_start_time_.is_null()) { UMA_HISTOGRAM_TIMES("PrintPreview.InitalDisplayTime", @@ -133,27 +197,9 @@ void PrintPreviewUI::OnFileSelectionCancelled() { } void PrintPreviewUI::OnPrintPreviewFailed() { - DecrementRequestCount(); CallJavascriptFunction("printPreviewFailed"); } -void PrintPreviewUI::OnPrintPreviewCancelled() { - DecrementRequestCount(); -} - -bool PrintPreviewUI::HasPendingRequests() { - return request_count_ > 1; -} - PrintPreviewDataService* PrintPreviewUI::print_preview_data_service() { return PrintPreviewDataService::GetInstance(); } - -void PrintPreviewUI::DecrementRequestCount() { - 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 3530bf2..d90eddd 100644 --- a/chrome/browser/ui/webui/print_preview_ui.h +++ b/chrome/browser/ui/webui/print_preview_ui.h @@ -41,9 +41,18 @@ class PrintPreviewUI : public ChromeWebUI { void SetInitiatorTabURLAndTitle(const std::string& initiator_url, const string16& initiator_tab_title); - // Notifies the Web UI that there is a print preview request. There should be - // a matching call to OnPreviewDataIsAvailable() or OnPrintPreviewFailed(). - void OnPrintPreviewRequest(); + // Determines whether to cancel a print preview request based on + // |preview_ui_addr| and |request_id|. + // Can be called from any thread. + static void GetCurrentPrintPreviewStatus(const std::string& preview_ui_addr, + int request_id, + bool* cancel); + + // Returns a string to uniquely identify this PrintPreviewUI. + std::string GetPrintPreviewUIAddress() const; + + // Notifies the Web UI of a print preview request with |request_id|. + void OnPrintPreviewRequest(int request_id); // Notifies the Web UI about the page count of the request preview. void OnDidGetPreviewPageCount( @@ -68,9 +77,6 @@ class PrintPreviewUI : public ChromeWebUI { // Notifies the Web UI that the print preview failed to render. void OnPrintPreviewFailed(); - // Notifies the Web UI that the print preview request has been cancelled. - void OnPrintPreviewCancelled(); - // Notifies the Web UI that initiator tab is closed, so we can disable all the // controls that need the initiator tab for generating the preview data. void OnInitiatorTabClosed(); @@ -81,17 +87,10 @@ class PrintPreviewUI : public ChromeWebUI { // Notifies the Web UI renderer that file selection has been cancelled. void OnFileSelectionCancelled(); - // Returns true if there are pending requests. - bool HasPendingRequests(); - - int document_cookie(); - private: // Returns the Singleton instance of the PrintPreviewDataService. PrintPreviewDataService* print_preview_data_service(); - void DecrementRequestCount(); - base::TimeTicks initial_preview_start_time_; // Store the PrintPreviewUI address string. @@ -100,12 +99,6 @@ class PrintPreviewUI : public ChromeWebUI { // Weak pointer to the WebUI handler. PrintPreviewHandler* handler_; - // The number of print preview requests in flight. - uint32 request_count_; - - // Document cookie from the initiator renderer. - int document_cookie_; - // Store the |initiator_url| in order to display an accurate error message // when the initiator tab is closed/crashed. std::string initiator_url_; diff --git a/chrome/browser/ui/webui/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview_ui_unittest.cc index 43b51a9..7ef5fee 100644 --- a/chrome/browser/ui/webui/print_preview_ui_unittest.cc +++ b/chrome/browser/ui/webui/print_preview_ui_unittest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <vector> + #include "base/command_line.h" #include "base/memory/ref_counted_memory.h" #include "chrome/browser/printing/print_preview_tab_controller.h" @@ -142,3 +144,63 @@ TEST_F(PrintPreviewUITest, PrintPreviewDraftPages) { preview_ui->GetPrintPreviewDataForIndex(printing::FIRST_PAGE_INDEX, &data); EXPECT_EQ(NULL, data.get()); } + +// Test the browser-side print preview cancellation functionality. +TEST_F(PrintPreviewUITest, GetCurrentPrintPreviewStatus) { +#if !defined(GOOGLE_CHROME_BUILD) || defined(OS_CHROMEOS) + CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnablePrintPreview); +#endif + ASSERT_TRUE(browser()); + BrowserList::SetLastActive(browser()); + ASSERT_TRUE(BrowserList::GetLastActive()); + + browser()->NewTab(); + TabContents* initiator_tab = browser()->GetSelectedTabContents(); + ASSERT_TRUE(initiator_tab); + + scoped_refptr<printing::PrintPreviewTabController> + controller(new printing::PrintPreviewTabController()); + ASSERT_TRUE(controller); + + TabContents* preview_tab = controller->GetOrCreatePreviewTab(initiator_tab); + + EXPECT_NE(initiator_tab, preview_tab); + EXPECT_EQ(2, browser()->tab_count()); + + PrintPreviewUI* preview_ui = + reinterpret_cast<PrintPreviewUI*>(preview_tab->web_ui()); + ASSERT_TRUE(preview_ui != NULL); + + // Test with invalid |preview_ui_addr|. + bool cancel = false; + preview_ui->GetCurrentPrintPreviewStatus("invalid", 0, &cancel); + EXPECT_TRUE(cancel); + + const int kFirstRequestId = 1000; + const int kSecondRequestId = 1001; + const std::string preview_ui_addr = preview_ui->GetPrintPreviewUIAddress(); + + // Test with kFirstRequestId. + preview_ui->OnPrintPreviewRequest(kFirstRequestId); + cancel = true; + preview_ui->GetCurrentPrintPreviewStatus(preview_ui_addr, kFirstRequestId, + &cancel); + EXPECT_FALSE(cancel); + + cancel = false; + preview_ui->GetCurrentPrintPreviewStatus(preview_ui_addr, kSecondRequestId, + &cancel); + EXPECT_TRUE(cancel); + + // Test with kSecondRequestId. + preview_ui->OnPrintPreviewRequest(kSecondRequestId); + cancel = false; + preview_ui->GetCurrentPrintPreviewStatus(preview_ui_addr, kFirstRequestId, + &cancel); + EXPECT_TRUE(cancel); + + cancel = true; + preview_ui->GetCurrentPrintPreviewStatus(preview_ui_addr, kSecondRequestId, + &cancel); + EXPECT_FALSE(cancel); +} diff --git a/chrome/common/print_messages.cc b/chrome/common/print_messages.cc index 4ddd381..4464f13 100644 --- a/chrome/common/print_messages.cc +++ b/chrome/common/print_messages.cc @@ -18,11 +18,12 @@ PrintMsg_Print_Params::PrintMsg_Print_Params() max_shrink(0), desired_dpi(0), document_cookie(0), - selection_only(0), - supports_alpha_blend(0), + selection_only(false), + supports_alpha_blend(false), + preview_ui_addr(), preview_request_id(0), - is_first_request(0), - display_header_footer(0), + is_first_request(false), + display_header_footer(false), date(), title(), url() { @@ -31,20 +32,21 @@ PrintMsg_Print_Params::PrintMsg_Print_Params() PrintMsg_Print_Params::~PrintMsg_Print_Params() {} void PrintMsg_Print_Params::Reset() { + page_size = gfx::Size(); + printable_size = gfx::Size(); + margin_top = 0; + margin_left = 0; dpi = 0; - max_shrink = 0; min_shrink = 0; + max_shrink = 0; desired_dpi = 0; - selection_only = 0; document_cookie = 0; - page_size = gfx::Size(); - page_size = gfx::Size(); - printable_size = gfx::Size(); - margin_left = 0; - margin_top = 0; - is_first_request = 0; + selection_only = false; + supports_alpha_blend = false; + preview_ui_addr = std::string(); preview_request_id = 0; - display_header_footer = 0; + is_first_request = false; + display_header_footer = false; date = string16(); title = string16(); url = string16(); @@ -60,4 +62,3 @@ void PrintMsg_PrintPages_Params::Reset() { params.Reset(); pages = std::vector<int>(); } - diff --git a/chrome/common/print_messages.h b/chrome/common/print_messages.h index beb6665..a3714ea 100644 --- a/chrome/common/print_messages.h +++ b/chrome/common/print_messages.h @@ -5,6 +5,7 @@ // IPC messages for printing. // Multiply-included message file, hence no include guard. +#include <string> #include <vector> #include "base/values.h" @@ -34,6 +35,7 @@ struct PrintMsg_Print_Params { int document_cookie; bool selection_only; bool supports_alpha_blend; + std::string preview_ui_addr; int preview_request_id; bool is_first_request; bool display_header_footer; @@ -93,10 +95,15 @@ IPC_STRUCT_TRAITS_BEGIN(PrintMsg_Print_Params) // Does the printer support alpha blending? IPC_STRUCT_TRAITS_MEMBER(supports_alpha_blend) - // The id of the preview request, used only for print preview. + // *** Parameters below are used only for print preview. *** + + // The print preview ui associated with this request. + IPC_STRUCT_TRAITS_MEMBER(preview_ui_addr) + + // The id of the preview request. IPC_STRUCT_TRAITS_MEMBER(preview_request_id) - // True if this is the first preview request, used only for print preview. + // True if this is the first preview request. IPC_STRUCT_TRAITS_MEMBER(is_first_request) // Specifies if the header and footer should be rendered. @@ -264,16 +271,6 @@ IPC_MESSAGE_ROUTED0(PrintMsg_PrintForSystemDialog) // Tells a renderer to stop blocking script initiated printing. IPC_MESSAGE_ROUTED0(PrintMsg_ResetScriptedPrintCount) -// Tells a renderer to continue generating the print preview. -// Use |requested_preview_page_index| to request a specific preview page data. -// |requested_preview_page_index| is 1-based or |printing::INVALID_PAGE_INDEX| -// to render the next page. -IPC_MESSAGE_ROUTED1(PrintMsg_ContinuePreview, - int /* requested_preview_page_index */) - -// 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. #if defined(OS_WIN) @@ -344,6 +341,12 @@ IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetPreviewPageCount, IPC_MESSAGE_ROUTED1(PrintHostMsg_DidPreviewPage, PrintHostMsg_DidPreviewPage_Params /* params */) +// Asks the browser whether the print preview has been cancelled. +IPC_SYNC_MESSAGE_ROUTED2_1(PrintHostMsg_CheckForCancel, + std::string /* print preview ui address */, + int /* request id */, + bool /* print preview cancelled */) + // 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. @@ -357,3 +360,7 @@ 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 b443559..6844c44 100644 --- a/chrome/renderer/mock_render_thread.cc +++ b/chrome/renderer/mock_render_thread.cc @@ -25,6 +25,7 @@ MockRenderThread::MockRenderThread() reply_deserializer_(NULL), printer_(new MockPrinter), print_dialog_user_response_(true), + print_preview_cancel_page_number_(-1), print_preview_pages_remaining_(0) { } @@ -111,6 +112,7 @@ bool MockRenderThread::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPreviewPageCount, OnDidGetPreviewPageCount) IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage) + IPC_MESSAGE_HANDLER(PrintHostMsg_CheckForCancel, OnCheckForCancel) #if defined(OS_WIN) IPC_MESSAGE_HANDLER(PrintHostMsg_DuplicateSection, OnDuplicateSection) #endif @@ -218,11 +220,17 @@ void MockRenderThread::OnDidGetPreviewPageCount( void MockRenderThread::OnDidPreviewPage( const PrintHostMsg_DidPreviewPage_Params& params) { - if (params.page_number < printing::FIRST_PAGE_INDEX) - return; + DCHECK(params.page_number >= printing::FIRST_PAGE_INDEX); print_preview_pages_remaining_--; } +void MockRenderThread::OnCheckForCancel(const std::string& preview_ui_addr, + int preview_request_id, + bool* cancel) { + *cancel = + (print_preview_pages_remaining_ == print_preview_cancel_page_number_); +} + void MockRenderThread::OnUpdatePrintSettings( int document_cookie, const DictionaryValue& job_settings, @@ -238,6 +246,7 @@ void MockRenderThread::OnUpdatePrintSettings( !job_settings.GetString(printing::kSettingDeviceName, &dummy_string) || !job_settings.GetInteger(printing::kSettingDuplexMode, NULL) || !job_settings.GetInteger(printing::kSettingCopies, NULL) || + !job_settings.GetString(printing::kPreviewUIAddr, &dummy_string) || !job_settings.GetInteger(printing::kPreviewRequestID, NULL)) { return; } @@ -251,6 +260,10 @@ void MockRenderThread::set_print_dialog_user_response(bool response) { print_dialog_user_response_ = response; } +void MockRenderThread::set_print_preview_cancel_page_number(int page) { + print_preview_cancel_page_number_ = page; +} + 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 c510d91..d0344b8 100644 --- a/chrome/renderer/mock_render_thread.h +++ b/chrome/renderer/mock_render_thread.h @@ -85,6 +85,9 @@ class MockRenderThread : public RenderThreadBase { // False if the user decides to cancel. void set_print_dialog_user_response(bool response); + // Cancel print preview when print preview has |page| remaining pages. + void set_print_preview_cancel_page_number(int page); + // Get the number of pages to generate for print preview. int print_preview_pages_remaining(); @@ -129,6 +132,10 @@ class MockRenderThread : public RenderThreadBase { void OnDidGetPreviewPageCount( const PrintHostMsg_DidGetPreviewPageCount_Params& params); void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params); + void OnCheckForCancel(const std::string& preview_ui_addr, + int preview_request_id, + bool* cancel); + // For print preview, PrintWebViewHelper will update settings. void OnUpdatePrintSettings(int document_cookie, @@ -156,6 +163,10 @@ class MockRenderThread : public RenderThreadBase { // True to simulate user clicking print. False to cancel. bool print_dialog_user_response_; + // Simulates cancelling print preview if |print_preview_pages_remaining_| + // equals this. + int print_preview_cancel_page_number_; + // Number of pages to generate for print preview. int print_preview_pages_remaining_; }; diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index 485667f9..67250e9 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -13,7 +13,6 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/metrics/histogram.h" -#include "base/process_util.h" #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/common/chrome_switches.h" @@ -40,6 +39,7 @@ #include "ui/base/l10n/l10n_util.h" #if defined(OS_POSIX) +#include "base/process_util.h" #include "content/common/view_messages.h" #endif @@ -461,8 +461,6 @@ bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) { 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) @@ -585,7 +583,9 @@ void PrintWebViewHelper::OnPrintPreview(const DictionaryValue& settings) { // PDF printer device supports alpha blending. print_pages_params_->params.supports_alpha_blend = true; - if (!CreatePreviewDocument()) + if (CreatePreviewDocument()) + DidFinishPrinting(OK); + else DidFinishPrinting(FAIL_PREVIEW); } @@ -600,42 +600,22 @@ bool PrintWebViewHelper::CreatePreviewDocument() { params.document_cookie = print_pages_params_->params.document_cookie; params.preview_request_id = print_pages_params_->params.preview_request_id; Send(new PrintHostMsg_DidGetPreviewPageCount(routing_id(), params)); - PreviewPageRendered(printing::INVALID_PAGE_INDEX, NULL); - return true; -} + if (CheckForCancel()) + return false; -void PrintWebViewHelper::OnContinuePreview(int requested_preview_page_index) { - // Spurious message. We already finished/cancelled/aborted the print preview. - if (!print_preview_context_.IsBusy()) - return; int page_number; -#if defined(USE_SKIA) - if (requested_preview_page_index >= printing::FIRST_PAGE_INDEX) { - page_number = requested_preview_page_index; - } else -#endif - { - page_number = print_preview_context_.GetNextPageNumber(); - } - - if (page_number >= printing::FIRST_PAGE_INDEX) { - // Continue generating the print preview. - RenderPreviewPage(page_number); - return; - } + while ((page_number = print_preview_context_.GetNextPageNumber()) >= 0) { + if (!RenderPreviewPage(page_number)) + return false; + if (CheckForCancel()) + return false; + }; // Finished generating preview. Finalize the document. - if (FinalizePreviewDocument()) { - print_preview_context_.Finished(); - DidFinishPrinting(OK); - } else { - DidFinishPrinting(FAIL_PREVIEW); - } -} - -void PrintWebViewHelper::OnAbortPreview() { - DidFinishPrinting(ABORT_PREVIEW); - return; + if (!FinalizePreviewDocument()) + return false; + print_preview_context_.Finished(); + return true; } bool PrintWebViewHelper::FinalizePreviewDocument() { @@ -750,12 +730,11 @@ void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) { DCHECK(is_preview_); store_print_pages_params = false; int cookie = print_pages_params_->params.document_cookie; - Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie)); + if (notify_browser_of_print_failure_) + Send(new PrintHostMsg_PrintPreviewFailed(routing_id(), cookie)); + else + Send(new PrintHostMsg_PrintPreviewCancelled(routing_id(), cookie)); print_preview_context_.Failed(); - } else if (result == ABORT_PREVIEW) { - DCHECK(is_preview_); - store_print_pages_params = false; - print_preview_context_.Abort(); } if (print_web_view_) { @@ -993,17 +972,6 @@ bool PrintWebViewHelper::InitPrintSettingsAndPrepareFrame( return true; } -bool PrintWebViewHelper::UpdatePrintSettingsRequestId( - const DictionaryValue& job_settings, - PrintMsg_Print_Params* params) { - if (!job_settings.GetInteger(printing::kPreviewRequestID, - &(params->preview_request_id))) { - NOTREACHED(); - return false; - } - return true; -} - bool PrintWebViewHelper::UpdatePrintSettings( const DictionaryValue& job_settings) { PrintMsg_PrintPages_Params settings; @@ -1014,12 +982,14 @@ bool PrintWebViewHelper::UpdatePrintSettings( if (settings.params.dpi < kMinDpi || !settings.params.document_cookie) return false; - if (!UpdatePrintSettingsRequestId(job_settings, &(settings.params))) - return false; - - if (!job_settings.GetBoolean(printing::kIsFirstRequest, + if (!job_settings.GetString(printing::kPreviewUIAddr, + &(settings.params.preview_ui_addr)) || + !job_settings.GetInteger(printing::kPreviewRequestID, + &(settings.params.preview_request_id)) || + !job_settings.GetBoolean(printing::kIsFirstRequest, &(settings.params.is_first_request))) { NOTREACHED(); + return false; } print_pages_params_.reset(new PrintMsg_PrintPages_Params(settings)); @@ -1129,9 +1099,6 @@ bool PrintWebViewHelper::IsScriptInitiatedPrintTooFrequent( } } - if (!too_frequent && print_preview_context_.IsBusy()) - too_frequent = true; - if (!too_frequent) return false; @@ -1167,40 +1134,56 @@ void PrintWebViewHelper::RequestPrintPreview() { Send(new PrintHostMsg_RequestPrintPreview(routing_id())); } -void PrintWebViewHelper::PreviewPageRendered(int page_number, +bool PrintWebViewHelper::CheckForCancel() { + bool cancel = false; + Send(new PrintHostMsg_CheckForCancel( + routing_id(), + print_pages_params_->params.preview_ui_addr, + print_pages_params_->params.preview_request_id, + &cancel)); + if (cancel) + notify_browser_of_print_failure_ = false; + return cancel; +} + +bool PrintWebViewHelper::PreviewPageRendered(int page_number, printing::Metafile* metafile) { - if ((page_number == printing::INVALID_PAGE_INDEX && metafile) || - (page_number >= printing::FIRST_PAGE_INDEX && !metafile && - print_preview_context_.IsModifiable())) { + DCHECK_GE(page_number, printing::FIRST_PAGE_INDEX); + + // For non-modifiable files, |metafile| should be NULL, so do not bother + // sending a message. + if (!print_preview_context_.IsModifiable()) { + DCHECK(!metafile); + return true; + } + + if (!metafile) { NOTREACHED(); - DidFinishPrinting(FAIL_PREVIEW); - return; + return false; } - uint32 buf_size = 0; PrintHostMsg_DidPreviewPage_Params preview_page_params; // Get the size of the resulting metafile. - if (metafile) { - buf_size = metafile->GetDataSize(); - DCHECK_GT(buf_size, 0u); - if (!CopyMetafileDataToSharedMem( - metafile, &(preview_page_params.metafile_data_handle))) { - DidFinishPrinting(FAIL_PREVIEW); - return; - } + uint32 buf_size = metafile->GetDataSize(); + DCHECK_GT(buf_size, 0u); + if (!CopyMetafileDataToSharedMem( + metafile, &(preview_page_params.metafile_data_handle))) { + return false; } preview_page_params.data_size = buf_size; preview_page_params.page_number = page_number; preview_page_params.preview_request_id = print_pages_params_->params.preview_request_id; + Send(new PrintHostMsg_DidPreviewPage(routing_id(), preview_page_params)); + return true; } PrintWebViewHelper::PrintPreviewContext::PrintPreviewContext() : frame_(NULL), total_page_count_(0), actual_page_count_(0), - current_page_number_(0), + current_page_index_(0), state_(UNINITIALIZED) { } @@ -1210,8 +1193,6 @@ PrintWebViewHelper::PrintPreviewContext::~PrintPreviewContext() { void PrintWebViewHelper::PrintPreviewContext::InitWithFrame( WebKit::WebFrame* web_frame) { DCHECK(web_frame); - if (IsReadyToRender()) - return; state_ = INITIALIZED; frame_ = web_frame; node_.reset(); @@ -1220,8 +1201,6 @@ void PrintWebViewHelper::PrintPreviewContext::InitWithFrame( 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)); @@ -1254,23 +1233,20 @@ bool PrintWebViewHelper::PrintPreviewContext::CreatePreviewDocument( if (total_page_count_ == 0) return false; - current_page_number_ = 0; + current_page_index_ = 0; if (pages.empty()) { actual_page_count_ = total_page_count_; - rendered_pages_ = std::vector<PreviewPageInfo>(total_page_count_, - std::make_pair(false, -1)); + for (int i = 0; i < actual_page_count_; ++i) + pages_to_render_.push_back(i); } else { actual_page_count_ = pages.size(); - rendered_pages_ = std::vector<PreviewPageInfo>(total_page_count_, - std::make_pair(true, -1)); for (int i = 0; i < actual_page_count_; ++i) { int page_number = pages[i]; if (page_number < printing::FIRST_PAGE_INDEX || page_number >= total_page_count_) { return false; } - rendered_pages_[page_number].first = false; - rendered_pages_[page_number].second = i; + pages_to_render_.push_back(page_number); } } @@ -1317,39 +1293,22 @@ void PrintWebViewHelper::PrintPreviewContext::Finished() { } void PrintWebViewHelper::PrintPreviewContext::Failed() { - DCHECK(IsBusy()); + DCHECK(state_ == INITIALIZED || state_ == RENDERING); state_ = INITIALIZED; ClearContext(); } -void PrintWebViewHelper::PrintPreviewContext::Abort() { - state_ = UNINITIALIZED; - ClearContext(); - frame_ = NULL; - node_.reset(); -} - int PrintWebViewHelper::PrintPreviewContext::GetNextPageNumber() { DCHECK_EQ(RENDERING, state_); - for (int i = 0; i < total_page_count_; i++) { - if (!rendered_pages_[current_page_number_].first) - break; - current_page_number_ = (current_page_number_ + 1) % total_page_count_; - } - if (rendered_pages_[current_page_number_].first) - return printing::INVALID_PAGE_INDEX; - rendered_pages_[current_page_number_].first = true; - return current_page_number_; + if (current_page_index_ >= actual_page_count_) + return -1; + return pages_to_render_[current_page_index_++]; } bool PrintWebViewHelper::PrintPreviewContext::IsReadyToRender() const { return state_ != UNINITIALIZED; } -bool PrintWebViewHelper::PrintPreviewContext::IsBusy() const { - return state_ == INITIALIZED || state_ == RENDERING; -} - bool PrintWebViewHelper::PrintPreviewContext::IsModifiable() const { // TODO(vandebo) I think this should only return false if the content is a // PDF, just because we are printing a particular node does not mean it's @@ -1369,6 +1328,7 @@ WebKit::WebNode* PrintWebViewHelper::PrintPreviewContext::node() const { } int PrintWebViewHelper::PrintPreviewContext::total_page_count() const { + DCHECK(IsReadyToRender()); return total_page_count_; } @@ -1390,5 +1350,5 @@ PrintWebViewHelper::PrintPreviewContext::GetPrintCanvasSize() const { void PrintWebViewHelper::PrintPreviewContext::ClearContext() { prep_frame_view_.reset(); metafile_.reset(); - rendered_pages_.clear(); + pages_to_render_.clear(); } diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h index c4aea91..2dc20fb 100644 --- a/chrome/renderer/print_web_view_helper.h +++ b/chrome/renderer/print_web_view_helper.h @@ -142,19 +142,13 @@ class PrintWebViewHelper : public RenderViewObserver, // Initialize the print preview document. bool CreatePreviewDocument(); - // Continue generating the print preview. |requested_preview_page_index| - // specifies the browser requested preview page index. It is 1-based or - // |printing::INVALID_PAGE_INDEX| to continue with next page. - void OnContinuePreview(int requested_preview_page_index); // Renders a print preview page. |page_number| is 0-based. - void RenderPreviewPage(int page_number); + // Returns true if print preview should continue, false on failure. + bool 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(); @@ -172,7 +166,6 @@ class PrintWebViewHelper : public RenderViewObserver, OK, FAIL_PRINT, FAIL_PREVIEW, - ABORT_PREVIEW, }; // Notification when printing is done - signal tear-down/free resources. @@ -191,11 +184,6 @@ class PrintWebViewHelper : public RenderViewObserver, WebKit::WebNode* node, scoped_ptr<PrepareFrameAndViewForPrint>* prepare); - // Parse the request id out of |job_settings| and store it in |params|. - // Returns false on failure. - bool UpdatePrintSettingsRequestId(const base::DictionaryValue& job_settings, - PrintMsg_Print_Params* params); - // Update the current print settings with new |job_settings|. |job_settings| // dictionary contains print job details such as printer name, number of // copies, page range, etc. @@ -305,10 +293,16 @@ class PrintWebViewHelper : public RenderViewObserver, void RequestPrintPreview(); - // Notify the browser a print preview page has been rendered. - // |page_number| is 0-based or |printing::INVALID_PAGE_INDEX| to check - // for pending preview requests. - void PreviewPageRendered(int page_number, printing::Metafile* metafile); + // Checks whether print preview should continue or not. + // Returns true if cancelling, false if continuing. + bool CheckForCancel(); + + // Notifies the browser a print preview page has been rendered. + // |page_number| is 0-based. + // For a valid |page_number| with modifiable content, + // |metafile| is the rendered page. Otherwise |metafile| is NULL. + // Returns true if print preview should continue, false on failure. + bool PreviewPageRendered(int page_number, printing::Metafile* metafile); WebKit::WebView* print_web_view_; @@ -360,13 +354,9 @@ class PrintWebViewHelper : public RenderViewObserver, // Cleanup after print preview fails. void Failed(); - // Abort the print preview. - void Abort(); - // Helper functions int GetNextPageNumber(); bool IsReadyToRender() const; - bool IsBusy() const; bool IsModifiable() const; // Getters @@ -403,12 +393,9 @@ class PrintWebViewHelper : public RenderViewObserver, int actual_page_count_; // The current page to render. - int current_page_number_; + int current_page_index_; - // |rendered_pages_| tracks which pages need to be printed as well as - // the page slot it should be printed in. See GetPageSlotForPage. - typedef std::pair<bool, int> PreviewPageInfo; - std::vector<PreviewPageInfo> rendered_pages_; + std::vector<int> pages_to_render_; base::TimeDelta document_render_time_; base::TimeTicks begin_time_; diff --git a/chrome/renderer/print_web_view_helper_browsertest.cc b/chrome/renderer/print_web_view_helper_browsertest.cc index 57f9170..6df060c 100644 --- a/chrome/renderer/print_web_view_helper_browsertest.cc +++ b/chrome/renderer/print_web_view_helper_browsertest.cc @@ -29,6 +29,10 @@ const char kHelloWorldHTML[] = "<body><p>Hello World!</p></body>"; const char kPrintWithJSHTML[] = "<body>Hello<script>window.print()</script>World</body>"; +// A longer web page. +const char kLongPageHTML[] = + "<body><img src=\"\" width=10 height=10000 /></body>"; + // A web page to simulate the print preview page. const char kPrintPreviewHTML[] = "<body><p id=\"pdf-viewer\">Hello World!</p></body>"; @@ -41,6 +45,7 @@ void CreatePrintSettingsDictionary(DictionaryValue* dict) { dict->SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX); dict->SetInteger(printing::kSettingCopies, 1); dict->SetString(printing::kSettingDeviceName, "dummy"); + dict->SetString(printing::kPreviewUIAddr, "0xb33fbeef"); dict->SetInteger(printing::kPreviewRequestID, 12345); dict->SetBoolean(printing::kIsFirstRequest, true); dict->SetBoolean(printing::kSettingHeaderFooterEnabled, false); @@ -305,6 +310,13 @@ 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); @@ -346,14 +358,8 @@ TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreview) { CreatePrintSettingsDictionary(&dict); PrintWebViewHelper::Get(view_)->OnPrintPreview(dict); - // Need to finish simulating print preview. - // Generate the page and finalize it. - PrintWebViewHelper::Get(view_)->OnContinuePreview( - printing::INVALID_PAGE_INDEX); - PrintWebViewHelper::Get(view_)->OnContinuePreview( - printing::INVALID_PAGE_INDEX); - EXPECT_EQ(0, render_thread_.print_preview_pages_remaining()); + VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(false); VerifyPrintPreviewGenerated(true); VerifyPagesPrinted(false); @@ -370,11 +376,31 @@ TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewFail) { PrintWebViewHelper::Get(view_)->OnPrintPreview(empty_dict); EXPECT_EQ(0, render_thread_.print_preview_pages_remaining()); + VerifyPrintPreviewCancelled(false); VerifyPrintPreviewFailed(true); VerifyPrintPreviewGenerated(false); VerifyPagesPrinted(false); } +// Tests that cancelling print preview works. +TEST_F(PrintWebViewHelperPreviewTest, OnPrintPreviewCancel) { + LoadHTML(kLongPageHTML); + + const int kCancelPage = 3; + render_thread_.set_print_preview_cancel_page_number(kCancelPage); + PrintWebViewHelper::Get(view_)->OnInitiatePrintPreview(); + // Fill in some dummy values. + DictionaryValue dict; + CreatePrintSettingsDictionary(&dict); + PrintWebViewHelper::Get(view_)->OnPrintPreview(dict); + + EXPECT_EQ(kCancelPage, render_thread_.print_preview_pages_remaining()); + VerifyPrintPreviewCancelled(true); + VerifyPrintPreviewFailed(false); + VerifyPrintPreviewGenerated(false); + VerifyPagesPrinted(false); +} + // Tests that printing from print preview works and sending and receiving // messages through that channel all works. TEST_F(PrintWebViewHelperPreviewTest, OnPrintForPrintPreview) { diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc index d457aecb..3a72edd 100644 --- a/chrome/renderer/print_web_view_helper_linux.cc +++ b/chrome/renderer/print_web_view_helper_linux.cc @@ -16,7 +16,6 @@ #include "skia/ext/vector_canvas.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" -#include "ui/gfx/point.h" #if !defined(OS_CHROMEOS) #include "base/process_util.h" @@ -25,7 +24,7 @@ using WebKit::WebFrame; using WebKit::WebNode; -void PrintWebViewHelper::RenderPreviewPage(int page_number) { +bool PrintWebViewHelper::RenderPreviewPage(int page_number) { PrintMsg_PrintPage_Params page_params; page_params.params = print_preview_context_.print_params(); page_params.page_number = page_number; @@ -43,7 +42,7 @@ void PrintWebViewHelper::RenderPreviewPage(int page_number) { page_metafile.reset( print_preview_context_.metafile()->GetMetafileForCurrentPage()); } - PreviewPageRendered(page_number, page_metafile.get()); + return PreviewPageRendered(page_number, page_metafile.get()); } bool PrintWebViewHelper::PrintPages(const PrintMsg_PrintPages_Params& params, diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm index 3e5051f..73c7bbf 100644 --- a/chrome/renderer/print_web_view_helper_mac.mm +++ b/chrome/renderer/print_web_view_helper_mac.mm @@ -59,7 +59,7 @@ void PrintWebViewHelper::PrintPageInternal( Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params)); } -void PrintWebViewHelper::RenderPreviewPage(int page_number) { +bool 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, @@ -73,8 +73,7 @@ void PrintWebViewHelper::RenderPreviewPage(int page_number) { if (print_preview_context_.IsModifiable()) { draft_metafile.reset(new printing::PreviewMetafile); if (!draft_metafile->Init()) { - DidFinishPrinting(FAIL_PREVIEW); - return; + return false; } initial_render_metafile = draft_metafile.get(); } @@ -118,7 +117,7 @@ void PrintWebViewHelper::RenderPreviewPage(int page_number) { #endif } - PreviewPageRendered(page_number, draft_metafile.get()); + return PreviewPageRendered(page_number, draft_metafile.get()); } void PrintWebViewHelper::RenderPage( diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc index 2c3180a..dec1ddd 100644 --- a/chrome/renderer/print_web_view_helper_win.cc +++ b/chrome/renderer/print_web_view_helper_win.cc @@ -121,7 +121,7 @@ void PrintWebViewHelper::PrintPageInternal( Send(new PrintHostMsg_DidPrintPage(routing_id(), page_params)); } -void PrintWebViewHelper::RenderPreviewPage(int page_number) { +bool PrintWebViewHelper::RenderPreviewPage(int page_number) { PrintMsg_Print_Params print_params = print_preview_context_.print_params(); // Calculate the dpi adjustment. float scale_factor = static_cast<float>(print_params.desired_dpi / @@ -143,7 +143,7 @@ void PrintWebViewHelper::RenderPreviewPage(int page_number) { page_metafile.reset( print_preview_context_.metafile()->GetMetafileForCurrentPage()); } - PreviewPageRendered(page_number, page_metafile.get()); + return PreviewPageRendered(page_number, page_metafile.get()); } Metafile* PrintWebViewHelper::RenderPage( diff --git a/printing/print_job_constants.cc b/printing/print_job_constants.cc index abaf167..b1928e5 100644 --- a/printing/print_job_constants.cc +++ b/printing/print_job_constants.cc @@ -12,6 +12,9 @@ const char kIsFirstRequest[] = "isFirstRequest"; // Unique ID sent along every preview request. const char kPreviewRequestID[] = "requestID"; +// Unique ID to identify a print preview UI. +const char kPreviewUIAddr[] = "previewUIAddr"; + // Print using cloud print: true if selected, false if not. const char kSettingCloudPrintId[] = "cloudPrintID"; @@ -83,10 +86,8 @@ const char kSettingPrinterName[] = "printerName"; // Print to PDF option: true if selected, false if not. const char kSettingPrintToPDF[] = "printToPDF"; -// Indices used to represent first page, invalid page and complete -// preview document. +// Indices used to represent first preview page and complete preview document. const int FIRST_PAGE_INDEX = 0; const int COMPLETE_PREVIEW_DOCUMENT_INDEX = -1; -const int INVALID_PAGE_INDEX = -2; } // namespace printing diff --git a/printing/print_job_constants.h b/printing/print_job_constants.h index f9188be..e451189 100644 --- a/printing/print_job_constants.h +++ b/printing/print_job_constants.h @@ -9,6 +9,7 @@ namespace printing { extern const char kIsFirstRequest[]; extern const char kPreviewRequestID[]; +extern const char kPreviewUIAddr[]; extern const char kSettingCloudPrintId[]; extern const char kSettingCollate[]; extern const char kSettingColor[]; @@ -34,7 +35,6 @@ extern const char kSettingPrintToPDF[]; extern const int FIRST_PAGE_INDEX; extern const int COMPLETE_PREVIEW_DOCUMENT_INDEX; -extern const int INVALID_PAGE_INDEX; // Print job duplex mode values. enum DuplexMode { |