deepak1556 2018-04-13 14:13:52 +05:30 committed by Samuel Attard
parent 37d64e6a00
commit 39b30b76ea
13 changed files with 154 additions and 97 deletions

View file

@ -14,7 +14,6 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
@ -22,7 +21,6 @@
#include "chrome/browser/printing/print_job_worker.h"
#include "content/public/browser/notification_service.h"
#include "printing/printed_document.h"
#include "printing/printed_page.h"
#if defined(OS_WIN)
#include "chrome/browser/printing/pdf_to_emf_converter.h"
@ -129,7 +127,7 @@ void PrintJob::StartPrinting() {
// Tell everyone!
scoped_refptr<JobEventDetails> details(
new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), nullptr));
new JobEventDetails(JobEventDetails::NEW_DOC, 0, document_.get()));
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT, content::Source<PrintJob>(this),
content::Details<JobEventDetails>(details.get()));
@ -173,7 +171,7 @@ void PrintJob::Cancel() {
}
// Make sure a Cancel() is broadcast.
scoped_refptr<JobEventDetails> details(
new JobEventDetails(JobEventDetails::FAILED, nullptr, nullptr));
new JobEventDetails(JobEventDetails::FAILED, 0, nullptr));
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT, content::Source<PrintJob>(this),
content::Details<JobEventDetails>(details.get()));
@ -393,7 +391,7 @@ void PrintJob::OnDocumentDone() {
Stop();
scoped_refptr<JobEventDetails> details(
new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), nullptr));
new JobEventDetails(JobEventDetails::JOB_DONE, 0, document_.get()));
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT, content::Source<PrintJob>(this),
content::Details<JobEventDetails>(details.get()));
@ -445,10 +443,18 @@ void PrintJob::Quit() {
}
// Takes settings_ ownership and will be deleted in the receiving thread.
#if defined(OS_WIN)
JobEventDetails::JobEventDetails(Type type,
int job_id,
PrintedDocument* document,
PrintedPage* page)
: document_(document), page_(page), type_(type) {}
: document_(document), page_(page), type_(type), job_id_(job_id) {}
#endif
JobEventDetails::JobEventDetails(Type type,
int job_id,
PrintedDocument* document)
: document_(document), type_(type), job_id_(job_id) {}
JobEventDetails::~JobEventDetails() {}
@ -456,8 +462,7 @@ PrintedDocument* JobEventDetails::document() const {
return document_.get();
}
PrintedPage* JobEventDetails::page() const {
return page_.get();
}
#if defined(OS_WIN)
PrintedPage* JobEventDetails::page() const { return page_.get(); }
#endif
} // namespace printing

View file

@ -26,7 +26,9 @@ class MetafilePlayer;
class PdfToEmfConverter;
class PrintJobWorker;
class PrintedDocument;
#if defined(OS_WIN)
class PrintedPage;
#endif
class PrinterQuery;
// Manages the print work for a specific document. Talks to the printer through
@ -204,12 +206,21 @@ class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
FAILED,
};
JobEventDetails(Type type, PrintedDocument* document, PrintedPage* page);
#if defined(OS_WIN)
JobEventDetails(Type type,
int job_id,
PrintedDocument* document,
PrintedPage* page);
#endif
JobEventDetails(Type type, int job_id, PrintedDocument* document);
// Getters.
PrintedDocument* document() const;
#if defined(OS_WIN)
PrintedPage* page() const;
#endif
Type type() const { return type_; }
int job_id() const { return job_id_; }
private:
friend class base::RefCountedThreadSafe<JobEventDetails>;
@ -217,8 +228,11 @@ class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
~JobEventDetails();
scoped_refptr<PrintedDocument> document_;
#if defined(OS_WIN)
scoped_refptr<PrintedPage> page_;
#endif
const Type type_;
int job_id_;
DISALLOW_COPY_AND_ASSIGN(JobEventDetails);
};

View file

@ -10,7 +10,6 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "printing/printed_document.h"
#include "printing/printed_page.h"
namespace printing {

View file

@ -25,7 +25,6 @@
#include "content/public/browser/web_contents.h"
#include "printing/print_job_constants.h"
#include "printing/printed_document.h"
#include "printing/printed_page.h"
#include "printing/printing_utils.h"
#include "ui/base/l10n/l10n_util.h"
@ -43,6 +42,10 @@
#include "printing/print_settings.h"
#include "printing/units.h"
#if defined(OS_WIN)
#include "printing/printed_page_win.h"
#endif
using content::BrowserThread;
namespace printing {
@ -51,8 +54,8 @@ namespace {
// Helper function to ensure |owner| is valid until at least |callback| returns.
void HoldRefCallback(const scoped_refptr<PrintJobWorkerOwner>& owner,
const base::Closure& callback) {
callback.Run();
base::OnceClosure callback) {
std::move(callback).Run();
}
void SetCustomMarginsToJobSettings(const PageSizeMargins& page_size_margins,
@ -175,9 +178,9 @@ std::string PrintingContextDelegate::GetAppLocale() {
void NotificationCallback(PrintJobWorkerOwner* print_job,
JobEventDetails::Type detail_type,
PrintedDocument* document,
PrintedPage* page) {
JobEventDetails* details = new JobEventDetails(detail_type, document, page);
int job_id,
PrintedDocument* document) {
JobEventDetails* details = new JobEventDetails(detail_type, job_id, document);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT,
// We know that is is a PrintJob object in this circumstance.
@ -186,12 +189,29 @@ void NotificationCallback(PrintJobWorkerOwner* print_job,
}
void PostOnOwnerThread(const scoped_refptr<PrintJobWorkerOwner>& owner,
const PrintingContext::PrintSettingsCallback& callback,
PrintingContext::PrintSettingsCallback callback,
PrintingContext::Result result) {
owner->PostTask(FROM_HERE, base::Bind(&HoldRefCallback, owner,
base::Bind(callback, result)));
owner->PostTask(FROM_HERE,
base::BindOnce(&HoldRefCallback, owner,
base::BindOnce(std::move(callback), result)));
}
#if defined(OS_WIN)
void PageNotificationCallback(PrintJobWorkerOwner* print_job,
JobEventDetails::Type detail_type,
int job_id,
PrintedDocument* document,
PrintedPage* page) {
JobEventDetails* details =
new JobEventDetails(detail_type, job_id, document, page);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT,
// We know that is is a PrintJob object in this circumstance.
content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
content::Details<JobEventDetails>(details));
}
#endif
} // namespace
PrintJobWorker::PrintJobWorker(int render_process_id,
@ -243,22 +263,23 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
if (ask_user_for_settings) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&HoldRefCallback, WrapRefCounted(owner_),
base::Bind(&PrintJobWorker::GetSettingsWithUI,
base::Unretained(this), document_page_count,
has_selection, is_scripted)));
base::BindOnce(
&HoldRefCallback, WrapRefCounted(owner_),
base::BindOnce(&PrintJobWorker::GetSettingsWithUI,
base::Unretained(this), document_page_count,
has_selection, is_scripted)));
} else if (!device_name.empty()) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&HoldRefCallback, WrapRefCounted(owner_),
base::Bind(&PrintJobWorker::InitWithDeviceName,
base::Unretained(this), device_name)));
base::BindOnce(&HoldRefCallback, WrapRefCounted(owner_),
base::BindOnce(&PrintJobWorker::InitWithDeviceName,
base::Unretained(this), device_name)));
} else {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&HoldRefCallback, WrapRefCounted(owner_),
base::Bind(&PrintJobWorker::UseDefaultSettings,
base::Unretained(this))));
base::BindOnce(&HoldRefCallback, WrapRefCounted(owner_),
base::BindOnce(&PrintJobWorker::UseDefaultSettings,
base::Unretained(this))));
}
}
@ -268,10 +289,10 @@ void PrintJobWorker::SetSettings(
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(
base::BindOnce(
&HoldRefCallback, WrapRefCounted(owner_),
base::Bind(&PrintJobWorker::UpdatePrintSettings,
base::Unretained(this), base::Passed(&new_settings))));
base::BindOnce(&PrintJobWorker::UpdatePrintSettings,
base::Unretained(this), base::Passed(&new_settings))));
}
void PrintJobWorker::UpdatePrintSettings(
@ -307,9 +328,9 @@ void PrintJobWorker::GetSettingsWithUI(int document_page_count,
// weak_factory_ creates pointers valid only on owner_ thread.
printing_context_->AskUserForSettings(
document_page_count, has_selection, is_scripted,
base::Bind(&PostOnOwnerThread, WrapRefCounted(owner_),
base::Bind(&PrintJobWorker::GetSettingsDone,
weak_factory_.GetWeakPtr())));
base::BindOnce(&PostOnOwnerThread, WrapRefCounted(owner_),
base::BindOnce(&PrintJobWorker::GetSettingsDone,
weak_factory_.GetWeakPtr())));
}
void PrintJobWorker::UseDefaultSettings() {
@ -364,6 +385,15 @@ void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) {
document_ = new_document;
}
void PrintJobWorker::PostWaitForPage() {
// We need to wait for the page to be available.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&PrintJobWorker::OnNewPage, weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(500));
}
#if defined(OS_WIN)
void PrintJobWorker::OnNewPage() {
if (!document_.get()) // Spurious message.
return;
@ -383,17 +413,13 @@ void PrintJobWorker::OnNewPage() {
// We have enough information to initialize page_number_.
page_number_.Init(document_->settings(), page_count);
}
DCHECK_NE(page_number_, PageNumber::npos());
DCHECK_NE(page_number_, PageNumber::npos());
while (true) {
// Is the page available?
scoped_refptr<PrintedPage> page = document_->GetPage(page_number_.ToInt());
if (!page.get()) {
// We need to wait for the page to be available.
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&PrintJobWorker::OnNewPage, weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(500));
PostWaitForPage();
break;
}
// The page is there, print it.
@ -406,6 +432,24 @@ void PrintJobWorker::OnNewPage() {
}
}
}
#else
void PrintJobWorker::OnNewPage() {
if (!document_.get()) // Spurious message.
return;
// message_loop() could return NULL when the print job is cancelled.
DCHECK(task_runner_->RunsTasksInCurrentSequence());
const MetafilePlayer* metafile = document_->GetMetafile();
if (!metafile) {
PostWaitForPage();
return;
}
SpoolJob();
// Don't touch this anymore since the instance could be destroyed.
OnDocumentDone();
}
#endif // defined(OS_WIN)
void PrintJobWorker::Cancel() {
// This is the only function that can be called from any thread.
@ -444,6 +488,7 @@ void PrintJobWorker::OnDocumentDone() {
DCHECK_EQ(page_number_, PageNumber::npos());
DCHECK(document_.get());
int job_id = printing_context_->job_id();
if (printing_context_->DocumentDone() != PrintingContext::OK) {
OnFailure();
return;
@ -451,24 +496,18 @@ void PrintJobWorker::OnDocumentDone() {
owner_->PostTask(FROM_HERE,
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::DOC_DONE,
base::RetainedRef(document_), nullptr));
JobEventDetails::DOC_DONE, job_id,
base::RetainedRef(document_)));
// Makes sure the variables are reinitialized.
document_ = NULL;
}
#if defined(OS_WIN)
void PrintJobWorker::SpoolPage(PrintedPage* page) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK_NE(page_number_, PageNumber::npos());
// Signal everyone that the page is about to be printed.
owner_->PostTask(
FROM_HERE,
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::NEW_PAGE, base::RetainedRef(document_),
base::RetainedRef(page)));
// Preprocess.
if (printing_context_->NewPage() != PrintingContext::OK) {
OnFailure();
@ -476,11 +515,7 @@ void PrintJobWorker::SpoolPage(PrintedPage* page) {
}
// Actual printing.
#if defined(OS_WIN) || defined(OS_MACOSX)
document_->RenderPrintedPage(*page, printing_context_->context());
#elif defined(OS_POSIX)
document_->RenderPrintedPage(*page, printing_context_.get());
#endif
// Postprocess.
if (printing_context_->PageDone() != PrintingContext::OK) {
@ -489,12 +524,19 @@ void PrintJobWorker::SpoolPage(PrintedPage* page) {
}
// Signal everyone that the page is printed.
owner_->PostTask(
FROM_HERE,
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::PAGE_DONE, base::RetainedRef(document_),
base::RetainedRef(page)));
owner_->PostTask(FROM_HERE,
base::BindRepeating(
&PageNotificationCallback, base::RetainedRef(owner_),
JobEventDetails::PAGE_DONE, printing_context_->job_id(),
base::RetainedRef(document_), base::RetainedRef(page)));
}
#else
void PrintJobWorker::SpoolJob() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (!document_->RenderPrintedDocument(printing_context_.get()))
OnFailure();
}
#endif
void PrintJobWorker::OnFailure() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
@ -502,10 +544,10 @@ void PrintJobWorker::OnFailure() {
// We may loose our last reference by broadcasting the FAILED event.
scoped_refptr<PrintJobWorkerOwner> handle(owner_);
owner_->PostTask(FROM_HERE,
base::Bind(&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::FAILED,
base::RetainedRef(document_), nullptr));
owner_->PostTask(
FROM_HERE, base::BindRepeating(
&NotificationCallback, base::RetainedRef(owner_),
JobEventDetails::FAILED, 0, base::RetainedRef(document_)));
Cancel();
// Makes sure the variables are reinitialized.

View file

@ -12,6 +12,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "chrome/browser/printing/printer_query.h"
#include "content/public/browser/browser_thread.h"
#include "printing/page_number.h"
@ -100,8 +101,17 @@ class PrintJobWorker {
// and DEFAULT_INIT_DONE. These three are sent through PrintJob::InitDone().
class NotificationTask;
// Posts a task to call OnNewPage(). Used to wait for pages/document to be
// available.
void PostWaitForPage();
#if defined(OS_WIN)
// Renders a page in the printer.
void SpoolPage(PrintedPage* page);
#else
// Renders the document to the printer.
void SpoolJob();
#endif
// Closes the job since spooling is done.
void OnDocumentDone();

View file

@ -20,8 +20,8 @@ bool PrintJobWorkerOwner::RunsTasksInCurrentSequence() const {
}
bool PrintJobWorkerOwner::PostTask(const base::Location& from_here,
const base::Closure& task) {
return task_runner_->PostTask(from_here, task);
base::OnceClosure task) {
return task_runner_->PostTask(from_here, std::move(task));
}
} // namespace printing

View file

@ -48,7 +48,7 @@ class PrintJobWorkerOwner
bool RunsTasksInCurrentSequence() const;
// Posts the given task to be run.
bool PostTask(const base::Location& from_here, const base::Closure& task);
bool PostTask(const base::Location& from_here, base::OnceClosure task);
protected:
friend class base::RefCountedThreadSafe<PrintJobWorkerOwner>;

View file

@ -52,9 +52,7 @@ PrintViewManagerBase::PrintViewManagerBase(content::WebContents* web_contents)
cookie_(0),
queue_(g_browser_process->print_job_manager()->queue()) {
DCHECK(queue_.get());
#if !defined(OS_MACOSX)
expecting_first_page_ = true;
#endif // OS_MACOSX
printing_enabled_ = true;
}
@ -113,6 +111,13 @@ void PrintViewManagerBase::OnDidGetDocumentCookie(int cookie) {
void PrintViewManagerBase::OnDidPrintPage(
const PrintHostMsg_DidPrintPage_Params& params) {
// TODO(rbpotter): Remove this check once there are no more spurious
// DidPrintPage messages.
#if !defined(OS_WIN)
if (!expecting_first_page_)
return;
#endif
if (!OpportunisticallyCreatePrintJob(params.document_cookie))
return;
@ -123,12 +128,8 @@ void PrintViewManagerBase::OnDidPrintPage(
return;
}
#if defined(OS_MACOSX)
const bool metafile_must_be_valid = true;
#else
const bool metafile_must_be_valid = expecting_first_page_;
expecting_first_page_ = false;
#endif // OS_MACOSX
base::SharedMemory shared_buf(params.metafile_data_handle, true);
if (metafile_must_be_valid) {
@ -150,8 +151,8 @@ void PrintViewManagerBase::OnDidPrintPage(
#if !defined(OS_WIN)
// Update the rendered document. It will send notifications to the listener.
document->SetPage(params.page_number, std::move(metafile), params.page_size,
params.content_area);
document->SetDocument(std::move(metafile), params.page_size,
params.content_area);
ShouldQuitFromInnerMessageLoop();
#else
@ -361,9 +362,7 @@ void PrintViewManagerBase::DisconnectFromCurrentPrintJob() {
// DO NOT wait for the job to finish.
ReleasePrintJob();
}
#if !defined(OS_MACOSX)
expecting_first_page_ = true;
#endif // OS_MACOSX
}
void PrintViewManagerBase::PrintingDone(bool success) {

View file

@ -150,10 +150,8 @@ class PrintViewManagerBase : public content::NotificationObserver,
// print settings are being loaded.
bool inside_inner_message_loop_;
#if !defined(OS_MACOSX)
// Set to true when OnDidPrintPage() should be expecting the first page.
bool expecting_first_page_;
#endif // OS_MACOSX
// The document cookie of the current PrinterQuery.
int cookie_;

View file

@ -289,16 +289,8 @@ void PrintingMessageFilter::OnUpdatePrintSettings(
scoped_refptr<PrinterQuery> printer_query;
printer_query = queue_->PopPrinterQuery(document_cookie);
if (!printer_query.get()) {
int host_id = render_process_id_;
int routing_id = reply_msg->routing_id();
if (!new_settings->GetInteger(printing::kPreviewInitiatorHostId,
&host_id) ||
!new_settings->GetInteger(printing::kPreviewInitiatorRoutingId,
&routing_id)) {
host_id = content::ChildProcessHost::kInvalidUniqueID;
routing_id = content::ChildProcessHost::kInvalidUniqueID;
}
printer_query = queue_->CreatePrinterQuery(host_id, routing_id);
printer_query = queue_->CreatePrinterQuery(
content::ChildProcessHost::kInvalidUniqueID, MSG_ROUTING_NONE);
}
printer_query->SetSettings(
std::move(new_settings),

View file

@ -25,6 +25,7 @@
#include "net/base/escape.h"
#include "printing/pdf_metafile_skia.h"
#include "printing/units.h"
#include "third_party/WebKit/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/WebKit/public/platform/WebDoubleSize.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
@ -510,8 +511,8 @@ void PrepareFrameAndViewForPrint::CopySelection(
WebPreferences prefs = preferences;
prefs.javascript_enabled = false;
blink::WebView* web_view =
blink::WebView::Create(this, blink::kWebPageVisibilityStateVisible);
blink::WebView* web_view = blink::WebView::Create(
this, blink::mojom::PageVisibilityState::kVisible, nullptr);
owns_web_view_ = true;
content::RenderView::ApplyWebPreferences(prefs, web_view);
blink::WebLocalFrame* main_frame =

View file

@ -203,7 +203,6 @@ class PrintWebViewHelper
void RenderPage(const PrintMsg_Print_Params& params,
int page_number,
blink::WebLocalFrame* frame,
bool is_preview,
PdfMetafileSkia* metafile,
gfx::Size* page_size,
gfx::Rect* content_rect);

View file

@ -28,7 +28,7 @@ void PrintWebViewHelper::PrintPageInternal(
int page_number = params.page_number;
gfx::Size page_size_in_dpi;
gfx::Rect content_area_in_dpi;
RenderPage(print_pages_params_->params, page_number, frame, false, &metafile,
RenderPage(print_pages_params_->params, page_number, frame, &metafile,
&page_size_in_dpi, &content_area_in_dpi);
metafile.FinishDocument();
@ -68,7 +68,7 @@ bool PrintWebViewHelper::RenderPreviewPage(
base::TimeTicks begin_time = base::TimeTicks::Now();
gfx::Size page_size;
RenderPage(printParams, page_number, print_preview_context_.prepared_frame(),
true, initial_render_metafile, &page_size, NULL);
initial_render_metafile, &page_size, nullptr);
print_preview_context_.RenderedPreviewPage(base::TimeTicks::Now() -
begin_time);
@ -89,7 +89,6 @@ bool PrintWebViewHelper::RenderPreviewPage(
void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params,
int page_number,
WebLocalFrame* frame,
bool is_preview,
PdfMetafileSkia* metafile,
gfx::Size* page_size,
gfx::Rect* content_rect) {
@ -117,7 +116,6 @@ void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params,
return;
MetafileSkiaWrapper::SetMetafileOnCanvas(canvas, metafile);
cc::SetIsPreviewMetafile(canvas, is_preview);
RenderPageContent(frame, page_number, canvas_area, content_area,
scale_factor, static_cast<blink::WebCanvas*>(canvas));
}