summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvitalybuka <vitalybuka@chromium.org>2014-09-09 18:23:36 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-10 01:28:58 +0000
commitf470ae06577e8f07c0664c1a8997b5d219401882 (patch)
treede09522e1ce2a55e3e933d84750755376a2d199c
parentdafbe9581cc48ef683931d9a79890c2b99395712 (diff)
downloadchromium_src-f470ae06577e8f07c0664c1a8997b5d219401882.zip
chromium_src-f470ae06577e8f07c0664c1a8997b5d219401882.tar.gz
chromium_src-f470ae06577e8f07c0664c1a8997b5d219401882.tar.bz2
Fixed print_web_view_helper for CEF.
Restored disabling preview. Restored printing throttling. Restoring printing without print preview removed in https://codereview.chromium.org/488853002 Restored code is not used in Chrome or Chromium browsers. BUG=374321 TBR=gene@chromium.org Review URL: https://codereview.chromium.org/550033002 Cr-Commit-Position: refs/heads/master@{#294063}
-rw-r--r--chrome/chrome_tests.gypi6
-rw-r--r--chrome/renderer/printing/print_web_view_helper.cc87
-rw-r--r--chrome/renderer/printing/print_web_view_helper.h30
-rw-r--r--chrome/renderer/printing/print_web_view_helper_browsertest.cc76
4 files changed, 188 insertions, 11 deletions
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 9aaeda7..f0b8b6a 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2080,12 +2080,16 @@
['exclude', '^browser/printing/print_preview_pdf_generated_browsertest.cc'],
['exclude', '^browser/service_process/service_process_control_browsertest.cc'],
['exclude', '^browser/ui/webui/print_preview/print_preview_ui_browsertest.cc'],
- ['exclude', '^renderer/printing/print_web_view_helper_browsertest.cc'],
['exclude', '^test/data/webui/print_preview.cc'],
['exclude', '^test/data/webui/print_preview.h'],
['exclude', '^test/data/webui/print_preview.js'],
],
}],
+ ['enable_printing==0', {
+ 'sources/': [
+ ['exclude', '^renderer/printing/print_web_view_helper_browsertest.cc'],
+ ],
+ }],
['enable_mdns==1', {
'sources' : [
'browser/ui/webui/local_discovery/local_discovery_ui_browsertest.cc',
diff --git a/chrome/renderer/printing/print_web_view_helper.cc b/chrome/renderer/printing/print_web_view_helper.cc
index 6077438..4f8be2e 100644
--- a/chrome/renderer/printing/print_web_view_helper.cc
+++ b/chrome/renderer/printing/print_web_view_helper.cc
@@ -68,6 +68,12 @@ const char kPageLoadScriptFormat[] =
const char kPageSetupScriptFormat[] = "setup(%s);";
+#if defined(ENABLE_FULL_PRINTING)
+bool g_is_preview_enabled_ = true;
+#else
+bool g_is_preview_enabled_ = false;
+#endif
+
void ExecuteScript(blink::WebFrame* frame,
const char* script_format,
const base::Value& parameters) {
@@ -791,14 +797,23 @@ PrintWebViewHelper::PrintWebViewHelper(content::RenderView* render_view)
PrintWebViewHelper::~PrintWebViewHelper() {}
+// static
+void PrintWebViewHelper::DisablePreview() {
+ g_is_preview_enabled_ = false;
+}
+
bool PrintWebViewHelper::IsScriptInitiatedPrintAllowed(
blink::WebFrame* frame, bool user_initiated) {
#if defined(OS_ANDROID)
return false;
#endif // defined(OS_ANDROID)
- if (is_scripted_printing_blocked_)
- return false;
- return true;
+ // If preview is enabled, then the print dialog is tab modal, and the user
+ // can always close the tab on a mis-behaving page (the system print dialog
+ // is app modal). If the print was initiated through user action, don't
+ // throttle. Or, if the command line flag to skip throttling has been set.
+ return !is_scripted_printing_blocked_ &&
+ (user_initiated || g_is_preview_enabled_ ||
+ scripting_throttler_.IsAllowed(frame));
}
void PrintWebViewHelper::DidStartLoading() {
@@ -827,8 +842,13 @@ void PrintWebViewHelper::PrintPage(blink::WebLocalFrame* frame,
if (!IsScriptInitiatedPrintAllowed(frame, user_initiated))
return;
- print_preview_context_.InitWithFrame(frame);
- RequestPrintPreview(PRINT_PREVIEW_SCRIPTED);
+
+ if (!g_is_preview_enabled_) {
+ Print(frame, blink::WebNode());
+ } else {
+ print_preview_context_.InitWithFrame(frame);
+ RequestPrintPreview(PRINT_PREVIEW_SCRIPTED);
+ }
}
bool PrintWebViewHelper::OnMessageReceived(const IPC::Message& message) {
@@ -1220,13 +1240,17 @@ void PrintWebViewHelper::PrintNode(const blink::WebNode& node) {
// Make a copy of the node, in case RenderView::OnContextMenuClosed resets
// its |context_menu_node_|.
- print_preview_context_.InitWithNode(node);
- RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE);
+ if (!g_is_preview_enabled_) {
+ blink::WebNode duplicate_node(node);
+ Print(duplicate_node.document().frame(), duplicate_node);
+ } else {
+ print_preview_context_.InitWithNode(node);
+ RequestPrintPreview(PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE);
+ }
print_node_in_progress_ = false;
}
-#if !defined(DISABLE_BASIC_PRINTING)
void PrintWebViewHelper::Print(blink::WebLocalFrame* frame,
const blink::WebNode& node) {
// If still not finished with earlier print request simply ignore.
@@ -1259,8 +1283,8 @@ void PrintWebViewHelper::Print(blink::WebLocalFrame* frame,
LOG(ERROR) << "RenderPagesForPrint failed";
DidFinishPrinting(FAIL_PRINT);
}
+ scripting_throttler_.Reset();
}
-#endif // !DISABLE_BASIC_PRINTING
void PrintWebViewHelper::DidFinishPrinting(PrintingResult result) {
switch (result) {
@@ -1970,4 +1994,49 @@ void PrintWebViewHelper::SetPrintPagesParams(
settings.params.document_cookie));
}
+PrintWebViewHelper::ScriptingThrottler::ScriptingThrottler() : count_(0) {
+}
+
+bool PrintWebViewHelper::ScriptingThrottler::IsAllowed(blink::WebFrame* frame) {
+ const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2;
+ const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 32;
+ bool too_frequent = false;
+
+ // Check if there is script repeatedly trying to print and ignore it if too
+ // frequent. The first 3 times, we use a constant wait time, but if this
+ // gets excessive, we switch to exponential wait time. So for a page that
+ // calls print() in a loop the user will need to cancel the print dialog
+ // after: [2, 2, 2, 4, 8, 16, 32, 32, ...] seconds.
+ // This gives the user time to navigate from the page.
+ if (count_ > 0) {
+ base::TimeDelta diff = base::Time::Now() - last_print_;
+ int min_wait_seconds = kMinSecondsToIgnoreJavascriptInitiatedPrint;
+ if (count_ > 3) {
+ min_wait_seconds =
+ std::min(kMinSecondsToIgnoreJavascriptInitiatedPrint << (count_ - 3),
+ kMaxSecondsToIgnoreJavascriptInitiatedPrint);
+ }
+ if (diff.InSeconds() < min_wait_seconds) {
+ too_frequent = true;
+ }
+ }
+
+ if (!too_frequent) {
+ ++count_;
+ last_print_ = base::Time::Now();
+ return true;
+ }
+
+ blink::WebString message(
+ blink::WebString::fromUTF8("Ignoring too frequent calls to print()."));
+ frame->addMessageToConsole(blink::WebConsoleMessage(
+ blink::WebConsoleMessage::LevelWarning, message));
+ return false;
+}
+
+void PrintWebViewHelper::ScriptingThrottler::Reset() {
+ // Reset counter on successful print.
+ count_ = 0;
+}
+
} // namespace printing
diff --git a/chrome/renderer/printing/print_web_view_helper.h b/chrome/renderer/printing/print_web_view_helper.h
index 4ce36b8..e7cd7da 100644
--- a/chrome/renderer/printing/print_web_view_helper.h
+++ b/chrome/renderer/printing/print_web_view_helper.h
@@ -69,6 +69,10 @@ class PrintWebViewHelper
explicit PrintWebViewHelper(content::RenderView* render_view);
virtual ~PrintWebViewHelper();
+ // Disable print preview and switch to system dialog printing even if full
+ // printing is build-in. This method is used by CEF.
+ static void DisablePreview();
+
bool IsPrintingEnabled();
void PrintNode(const blink::WebNode& node);
@@ -78,7 +82,11 @@ class PrintWebViewHelper
FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperPreviewTest,
BlockScriptInitiatedPrinting);
FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, OnPrintPages);
-
+ FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, OnPrintPages);
+ FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest,
+ BlockScriptInitiatedPrinting);
+ FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest,
+ BlockScriptInitiatedPrintingFromPopup);
#if defined(OS_WIN) || defined(OS_MACOSX)
FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintLayoutTest);
FRIEND_TEST_ALL_PREFIXES(PrintWebViewHelperTest, PrintWithIframe);
@@ -309,6 +317,7 @@ class PrintWebViewHelper
scoped_ptr<PrintMsg_PrintPages_Params> print_pages_params_;
bool is_print_ready_metafile_sent_;
bool ignore_css_margins_;
+
// Used for scripted initiated printing blocking.
bool is_scripted_printing_blocked_;
@@ -428,6 +437,25 @@ class PrintWebViewHelper
State state_;
};
+ class ScriptingThrottler {
+ public:
+ ScriptingThrottler();
+
+ // Returns false if script initiated printing occurs too often.
+ bool IsAllowed(blink::WebFrame* frame);
+
+ // Reset the counter for script initiated printing.
+ // Scripted printing will be allowed to continue.
+ void Reset();
+
+ private:
+ base::Time last_print_;
+ int count_ = 0;
+ DISALLOW_COPY_AND_ASSIGN(ScriptingThrottler);
+ };
+
+ ScriptingThrottler scripting_throttler_;
+
bool print_node_in_progress_;
PrintPreviewContext print_preview_context_;
bool is_loading_;
diff --git a/chrome/renderer/printing/print_web_view_helper_browsertest.cc b/chrome/renderer/printing/print_web_view_helper_browsertest.cc
index 55a8ae5..3c777bd 100644
--- a/chrome/renderer/printing/print_web_view_helper_browsertest.cc
+++ b/chrome/renderer/printing/print_web_view_helper_browsertest.cc
@@ -236,6 +236,80 @@ class PrintWebViewHelperTest : public PrintWebViewHelperTestBase {
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperTest);
};
+// This tests only for platforms without print preview.
+#if !defined(ENABLE_FULL_PRINTING)
+// Tests that the renderer blocks window.print() calls if they occur too
+// frequently.
+TEST_F(PrintWebViewHelperTest, BlockScriptInitiatedPrinting) {
+ // Pretend user will cancel printing.
+ chrome_render_thread_->set_print_dialog_user_response(false);
+ // Try to print with window.print() a few times.
+ PrintWithJavaScript();
+ PrintWithJavaScript();
+ PrintWithJavaScript();
+ VerifyPagesPrinted(false);
+
+ // Pretend user will print. (but printing is blocked.)
+ chrome_render_thread_->set_print_dialog_user_response(true);
+ PrintWithJavaScript();
+ VerifyPagesPrinted(false);
+
+ // Unblock script initiated printing and verify printing works.
+ PrintWebViewHelper::Get(view_)->scripting_throttler_.Reset();
+ chrome_render_thread_->printer()->ResetPrinter();
+ PrintWithJavaScript();
+ VerifyPageCount(1);
+ VerifyPagesPrinted(true);
+}
+
+// Tests that the renderer always allows window.print() calls if they are user
+// initiated.
+TEST_F(PrintWebViewHelperTest, AllowUserOriginatedPrinting) {
+ // Pretend user will cancel printing.
+ chrome_render_thread_->set_print_dialog_user_response(false);
+ // Try to print with window.print() a few times.
+ PrintWithJavaScript();
+ PrintWithJavaScript();
+ PrintWithJavaScript();
+ VerifyPagesPrinted(false);
+
+ // Pretend user will print. (but printing is blocked.)
+ chrome_render_thread_->set_print_dialog_user_response(true);
+ PrintWithJavaScript();
+ VerifyPagesPrinted(false);
+
+ // Try again as if user initiated, without resetting the print count.
+ chrome_render_thread_->printer()->ResetPrinter();
+ LoadHTML(kPrintOnUserAction);
+ gfx::Size new_size(200, 100);
+ Resize(new_size, gfx::Rect(), false);
+
+ gfx::Rect bounds = GetElementBounds("print");
+ EXPECT_FALSE(bounds.IsEmpty());
+ blink::WebMouseEvent mouse_event;
+ mouse_event.type = blink::WebInputEvent::MouseDown;
+ mouse_event.button = blink::WebMouseEvent::ButtonLeft;
+ mouse_event.x = bounds.CenterPoint().x();
+ mouse_event.y = bounds.CenterPoint().y();
+ mouse_event.clickCount = 1;
+ SendWebMouseEvent(mouse_event);
+ mouse_event.type = blink::WebInputEvent::MouseUp;
+ SendWebMouseEvent(mouse_event);
+ ProcessPendingMessages();
+
+ VerifyPageCount(1);
+ VerifyPagesPrinted(true);
+}
+
+// Duplicate of OnPrintPagesTest only using javascript to print.
+TEST_F(PrintWebViewHelperTest, PrintWithJavascript) {
+ PrintWithJavaScript();
+
+ VerifyPageCount(1);
+ VerifyPagesPrinted(true);
+}
+#endif // !ENABLE_FULL_PRINTING
+
#if !defined(DISABLE_BASIC_PRINTING)
// Tests that printing pages work and sending and receiving messages through
// that channel all works.
@@ -487,6 +561,7 @@ class PrintWebViewHelperPreviewTest : public PrintWebViewHelperTestBase {
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelperPreviewTest);
};
+#if defined(ENABLE_FULL_PRINTING)
TEST_F(PrintWebViewHelperPreviewTest, BlockScriptInitiatedPrinting) {
PrintWebViewHelper* print_web_view_helper = PrintWebViewHelper::Get(view_);
print_web_view_helper->SetScriptedPrintBlocked(true);
@@ -517,6 +592,7 @@ TEST_F(PrintWebViewHelperPreviewTest, PrintWithJavaScript) {
VerifyPreviewRequest(true);
}
+#endif // ENABLE_FULL_PRINTING
// Tests that print preview work and sending and receiving messages through
// that channel all works.