Fix for race condition where print preview hangs when attempting to print a PDF that hasn't loaded.

If |type| in RequestPrintPreview() equals PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME and |is_loading_| is true, RequestPrintPreview() returns,
then is called again, right after |is_loading_| is set to false in DidStopLoading(). 


BUG=376969
TEST=See bug for steps to reproduce.

Additional way to reproduce:
Build blink_tests and browser_tests in out/Release. Then in src/webkit/tools/layout_tests run this command:
./run_webkit_tests.py --platform browser_test.linux source_pdf/

you can replace linux with win or mac depending on your platform.

The program will attempt to save a PDF as a PDF through print preview. It will eventually fail because Print Preview will hang due to this bug.
If you want visual confirmation that this will happen open:
src/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/browser_test_driver.py.

Then add this line of code to the function cmd_line.
cmd.append('--enable-pixel-output-in-tests')

Then run the script again. Enabling pixel output will also make it significantly more likely for the bug to occur.
Its also more likely to happen on windows for some reason.

This is how I came across the bug.

Review URL: https://codereview.chromium.org/427723004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287982 0039d316-1c4b-4281-b951-d872f2087c98
parent c627054e
......@@ -820,7 +820,8 @@ void PrintWebViewHelper::DidStartLoading() {
void PrintWebViewHelper::DidStopLoading() {
is_loading_ = false;
ShowScriptedPrintPreview();
if (!on_stop_loading_closure_.is_null())
on_stop_loading_closure_.Run();
}
// Prints |frame| which called window.print().
......@@ -1711,6 +1712,9 @@ void PrintWebViewHelper::RequestPrintPreview(PrintPreviewRequestType type) {
// Wait for DidStopLoading. Plugins may not know the correct
// |is_modifiable| value until they are fully loaded, which occurs when
// DidStopLoading() is called. Defer showing the preview until then.
on_stop_loading_closure_ =
base::Bind(&PrintWebViewHelper::ShowScriptedPrintPreview,
base::Unretained(this));
} else {
base::MessageLoop::current()->PostTask(
FROM_HERE,
......@@ -1725,6 +1729,17 @@ void PrintWebViewHelper::RequestPrintPreview(PrintPreviewRequestType type) {
return;
}
case PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME: {
// Wait for DidStopLoading. Continuing with this function while
// |is_loading_| is true will cause print preview to hang when try to
// print a PDF document.
if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) {
on_stop_loading_closure_ =
base::Bind(&PrintWebViewHelper::RequestPrintPreview,
base::Unretained(this),
type);
return;
}
break;
}
case PRINT_PREVIEW_USER_INITIATED_SELECTION: {
......@@ -1733,6 +1748,15 @@ void PrintWebViewHelper::RequestPrintPreview(PrintPreviewRequestType type) {
break;
}
case PRINT_PREVIEW_USER_INITIATED_CONTEXT_NODE: {
// Same situation as in PRINT_PREVIEW_USER_INITIATED_ENTIRE_FRAME.
if (is_loading_ && GetPlugin(print_preview_context_.source_frame())) {
on_stop_loading_closure_ =
base::Bind(&PrintWebViewHelper::RequestPrintPreview,
base::Unretained(this),
type);
return;
}
params.webnode_only = true;
break;
}
......
......@@ -7,6 +7,7 @@
#include <vector>
#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/shared_memory.h"
......@@ -461,6 +462,12 @@ class PrintWebViewHelper
bool is_loading_;
bool is_scripted_preview_delayed_;
base::WeakPtrFactory<PrintWebViewHelper> weak_ptr_factory_;
// Used to fix a race condition where the source is a PDF and print preview
// hangs because RequestPrintPreview is called before DidStopLoading() is
// called. This is a store for the RequestPrintPreview() call and its
// parameters so that it can be invoked after DidStopLoading.
base::Closure on_stop_loading_closure_;
DISALLOW_COPY_AND_ASSIGN(PrintWebViewHelper);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment