Commit d20e4ef3 authored by rbpotter's avatar rbpotter Committed by Commit Bot

Fix print job early termination during PDF conversion

Many webpages use window.print() immediately followed by window.close()
in JS. This means that the renderer and web contents are torn down
while the PDF is still being converted for the printer on Windows.
However, the web contents are not needed if the full PDF document has
already been rendered, so the PrintViewManager should just release the
query and allow conversion and spooling to complete instead of
cancelling the job.

The CL to send the Print Preview PDF directly to the PrintViewManager
broke this for users that use Print Preview because we no longer store an
extra copy of the web contents in the BackgroundPrintingManager. This has
been broken if using the system dialog since M64 or earlier.

Bug: 820105
Change-Id: I308adba43b3604509275f6c0f2946545b94dd1d5
Reviewed-on: https://chromium-review.googlesource.com/956257
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: default avatarWei Li <weili@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542203}
parent e11d27a9
...@@ -191,6 +191,11 @@ void PrintViewManagerBase::PrintDocument( ...@@ -191,6 +191,11 @@ void PrintViewManagerBase::PrintDocument(
print_job_->StartPdfToEmfConversion(print_data, page_size, content_area, print_job_->StartPdfToEmfConversion(print_data, page_size, content_area,
print_text_with_gdi); print_text_with_gdi);
} }
// Indicate that the PDF is fully rendered and we no longer need the renderer
// and web contents, so the print job does not need to be cancelled if they
// die. This is needed on Windows because the PrintedDocument will not be
// considered complete until PDF conversion finishes.
document->SetConvertingPdf();
#else #else
std::unique_ptr<PdfMetafileSkia> metafile = std::unique_ptr<PdfMetafileSkia> metafile =
std::make_unique<PdfMetafileSkia>(); std::make_unique<PdfMetafileSkia>();
...@@ -518,6 +523,12 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() { ...@@ -518,6 +523,12 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
if (!print_job_.get() || !print_job_->is_job_pending()) if (!print_job_.get() || !print_job_->is_job_pending())
return false; return false;
// Is the document already complete?
if (print_job_->document() && print_job_->document()->IsComplete()) {
printing_succeeded_ = true;
return true;
}
// We can't print if there is no renderer. // We can't print if there is no renderer.
if (!web_contents() || if (!web_contents() ||
!web_contents()->GetRenderViewHost() || !web_contents()->GetRenderViewHost() ||
...@@ -525,12 +536,6 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() { ...@@ -525,12 +536,6 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() {
return false; return false;
} }
// Is the document already complete?
if (print_job_->document() && print_job_->document()->IsComplete()) {
printing_succeeded_ = true;
return true;
}
// WebContents is either dying or a second consecutive request to print // WebContents is either dying or a second consecutive request to print
// happened before the first had time to finish. We need to render all the // happened before the first had time to finish. We need to render all the
// pages in an hurry if a print_job_ is still pending. No need to wait for it // pages in an hurry if a print_job_ is still pending. No need to wait for it
......
...@@ -131,6 +131,11 @@ PrintedDocument::PrintedDocument(const PrintSettings& settings, ...@@ -131,6 +131,11 @@ PrintedDocument::PrintedDocument(const PrintSettings& settings,
PrintedDocument::~PrintedDocument() = default; PrintedDocument::~PrintedDocument() = default;
#if defined(OS_WIN) #if defined(OS_WIN)
void PrintedDocument::SetConvertingPdf() {
base::AutoLock lock(lock_);
mutable_.converting_pdf_ = true;
}
void PrintedDocument::SetPage(int page_number, void PrintedDocument::SetPage(int page_number,
std::unique_ptr<MetafilePlayer> metafile, std::unique_ptr<MetafilePlayer> metafile,
float shrink, float shrink,
...@@ -195,6 +200,9 @@ bool PrintedDocument::IsComplete() const { ...@@ -195,6 +200,9 @@ bool PrintedDocument::IsComplete() const {
if (!mutable_.page_count_) if (!mutable_.page_count_)
return false; return false;
#if defined(OS_WIN) #if defined(OS_WIN)
if (mutable_.converting_pdf_)
return true;
PageNumber page(immutable_.settings_, mutable_.page_count_); PageNumber page(immutable_.settings_, mutable_.page_count_);
if (page == PageNumber::npos()) if (page == PageNumber::npos())
return false; return false;
......
...@@ -43,6 +43,11 @@ class PRINTING_EXPORT PrintedDocument ...@@ -43,6 +43,11 @@ class PRINTING_EXPORT PrintedDocument
int cookie); int cookie);
#if defined(OS_WIN) #if defined(OS_WIN)
// Indicates that the PDF has been generated and the document is waiting for
// conversion for printing. This is needed on Windows so that the print job
// is not cancelled if the web contents dies before PDF conversion finishes.
void SetConvertingPdf();
// Sets a page's data. 0-based. Note: locks for a short amount of time. // Sets a page's data. 0-based. Note: locks for a short amount of time.
void SetPage(int page_number, void SetPage(int page_number,
std::unique_ptr<MetafilePlayer> metafile, std::unique_ptr<MetafilePlayer> metafile,
...@@ -78,7 +83,7 @@ class PRINTING_EXPORT PrintedDocument ...@@ -78,7 +83,7 @@ class PRINTING_EXPORT PrintedDocument
// Returns true if all the necessary pages for the settings are already // Returns true if all the necessary pages for the settings are already
// rendered. // rendered.
// Note: locks while parsing the whole tree. // Note: This function always locks and may parse the whole tree.
bool IsComplete() const; bool IsComplete() const;
// Sets the number of pages in the document to be rendered. Can only be set // Sets the number of pages in the document to be rendered. Can only be set
...@@ -153,6 +158,9 @@ class PRINTING_EXPORT PrintedDocument ...@@ -153,6 +158,9 @@ class PRINTING_EXPORT PrintedDocument
// Contains the pages' representation. This is a collection of PrintedPage. // Contains the pages' representation. This is a collection of PrintedPage.
// Warning: Lock must be held when accessing this member. // Warning: Lock must be held when accessing this member.
PrintedPages pages_; PrintedPages pages_;
// Whether the PDF is being converted for printing.
bool converting_pdf_ = false;
#else #else
std::unique_ptr<MetafilePlayer> metafile_; std::unique_ptr<MetafilePlayer> metafile_;
#endif #endif
......
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