summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/printing/print_preview_message_handler.cc38
-rw-r--r--chrome/browser/printing/print_preview_message_handler.h2
-rw-r--r--chrome/browser/printing/printing_message_filter.cc15
-rw-r--r--chrome/browser/printing/printing_message_filter.h6
-rw-r--r--chrome/browser/ui/webui/print_preview_handler.cc19
-rw-r--r--chrome/browser/ui/webui/print_preview_ui.cc110
-rw-r--r--chrome/browser/ui/webui/print_preview_ui.h31
-rw-r--r--chrome/browser/ui/webui/print_preview_ui_unittest.cc62
-rw-r--r--chrome/common/print_messages.cc29
-rw-r--r--chrome/common/print_messages.h31
-rw-r--r--chrome/renderer/mock_render_thread.cc17
-rw-r--r--chrome/renderer/mock_render_thread.h11
-rw-r--r--chrome/renderer/print_web_view_helper.cc176
-rw-r--r--chrome/renderer/print_web_view_helper.h43
-rw-r--r--chrome/renderer/print_web_view_helper_browsertest.cc40
-rw-r--r--chrome/renderer/print_web_view_helper_linux.cc5
-rw-r--r--chrome/renderer/print_web_view_helper_mac.mm7
-rw-r--r--chrome/renderer/print_web_view_helper_win.cc4
-rw-r--r--printing/print_job_constants.cc7
-rw-r--r--printing/print_job_constants.h2
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, &current_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 {