Commit 5423e5e6 authored by rbpotter's avatar rbpotter Committed by Commit Bot

Remove PrintJobWorkerOwner

PrintJobWorkerOwner has very little implementation that is actually
shared between PrintJob and PrinterQuery (task_runner_). Moreover,
in all cases where PrintJobWorker refers to its owner, only one of the
two subclasses is actually acceptable. Make this more clear by removing
this class.

Bug: None
Change-Id: Icaf5ff15ee5856dcade54fc4b64bb92539dc7a6f
Reviewed-on: https://chromium-review.googlesource.com/1013118Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551345}
parent afccef39
...@@ -3298,8 +3298,6 @@ jumbo_split_static_library("browser") { ...@@ -3298,8 +3298,6 @@ jumbo_split_static_library("browser") {
"printing/print_job_manager.h", "printing/print_job_manager.h",
"printing/print_job_worker.cc", "printing/print_job_worker.cc",
"printing/print_job_worker.h", "printing/print_job_worker.h",
"printing/print_job_worker_owner.cc",
"printing/print_job_worker_owner.h",
"printing/print_view_manager_base.cc", "printing/print_view_manager_base.cc",
"printing/print_view_manager_base.h", "printing/print_view_manager_base.h",
"printing/print_view_manager_common.cc", "printing/print_view_manager_common.cc",
......
...@@ -34,14 +34,16 @@ using base::TimeDelta; ...@@ -34,14 +34,16 @@ using base::TimeDelta;
namespace printing { namespace printing {
// Helper function to ensure |owner| is valid until at least |callback| returns. // Helper function to ensure |job| is valid until at least |callback| returns.
void HoldRefCallback(scoped_refptr<PrintJobWorkerOwner> owner, void HoldRefCallback(scoped_refptr<PrintJob> job, base::OnceClosure callback) {
base::OnceClosure callback) {
std::move(callback).Run(); std::move(callback).Run();
} }
PrintJob::PrintJob() PrintJob::PrintJob()
: is_job_pending_(false), is_canceling_(false), quit_factory_(this) { : is_job_pending_(false),
is_canceling_(false),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
quit_factory_(this) {
DCHECK(base::MessageLoopForUI::IsCurrent()); DCHECK(base::MessageLoopForUI::IsCurrent());
} }
...@@ -60,7 +62,8 @@ void PrintJob::Initialize(PrinterQuery* query, ...@@ -60,7 +62,8 @@ void PrintJob::Initialize(PrinterQuery* query,
DCHECK(!is_job_pending_); DCHECK(!is_job_pending_);
DCHECK(!is_canceling_); DCHECK(!is_canceling_);
DCHECK(!document_); DCHECK(!document_);
worker_ = query->DetachWorker(this); worker_ = query->DetachWorker();
worker_->SetPrintJob(this);
settings_ = query->settings(); settings_ = query->settings();
auto new_doc = auto new_doc =
...@@ -135,21 +138,6 @@ void PrintJob::Observe(int type, ...@@ -135,21 +138,6 @@ void PrintJob::Observe(int type,
OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr()); OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
} }
void PrintJob::GetSettingsDone(const PrintSettings& new_settings,
PrintingContext::Result result) {
NOTREACHED();
}
std::unique_ptr<PrintJobWorker> PrintJob::DetachWorker(
PrintJobWorkerOwner* new_owner) {
NOTREACHED();
return nullptr;
}
const PrintSettings& PrintJob::settings() const {
return settings_;
}
void PrintJob::StartPrinting() { void PrintJob::StartPrinting() {
DCHECK(RunsTasksInCurrentSequence()); DCHECK(RunsTasksInCurrentSequence());
if (!worker_->IsRunning() || is_job_pending_) { if (!worker_->IsRunning() || is_job_pending_) {
...@@ -305,7 +293,7 @@ void PrintJob::StartPdfToEmfConversion( ...@@ -305,7 +293,7 @@ void PrintJob::StartPdfToEmfConversion(
settings_.print_text_with_gdi() && !settings_.printer_is_xps() && settings_.print_text_with_gdi() && !settings_.printer_is_xps() &&
base::FeatureList::IsEnabled(features::kGdiTextPrinting); base::FeatureList::IsEnabled(features::kGdiTextPrinting);
PdfRenderSettings render_settings( PdfRenderSettings render_settings(
content_area, gfx::Point(0, 0), settings().dpi_size(), content_area, gfx::Point(0, 0), settings_.dpi_size(),
/*autorotate=*/true, settings_.color() == COLOR, /*autorotate=*/true, settings_.color() == COLOR,
print_text_with_gdi ? PdfRenderSettings::Mode::GDI_TEXT print_text_with_gdi ? PdfRenderSettings::Mode::GDI_TEXT
: PdfRenderSettings::Mode::NORMAL); : PdfRenderSettings::Mode::NORMAL);
...@@ -361,7 +349,7 @@ void PrintJob::StartPdfToTextConversion( ...@@ -361,7 +349,7 @@ void PrintJob::StartPdfToTextConversion(
std::make_unique<PdfConversionState>(gfx::Size(), gfx::Rect()); std::make_unique<PdfConversionState>(gfx::Size(), gfx::Rect());
gfx::Rect page_area = gfx::Rect(0, 0, page_size.width(), page_size.height()); gfx::Rect page_area = gfx::Rect(0, 0, page_size.width(), page_size.height());
PdfRenderSettings render_settings( PdfRenderSettings render_settings(
page_area, gfx::Point(0, 0), settings().dpi_size(), page_area, gfx::Point(0, 0), settings_.dpi_size(),
/*autorotate=*/true, /*autorotate=*/true,
/*use_color=*/true, PdfRenderSettings::Mode::TEXTONLY); /*use_color=*/true, PdfRenderSettings::Mode::TEXTONLY);
pdf_conversion_state_->Start( pdf_conversion_state_->Start(
...@@ -378,7 +366,7 @@ void PrintJob::StartPdfToPostScriptConversion( ...@@ -378,7 +366,7 @@ void PrintJob::StartPdfToPostScriptConversion(
pdf_conversion_state_ = std::make_unique<PdfConversionState>( pdf_conversion_state_ = std::make_unique<PdfConversionState>(
gfx::Size(), gfx::Rect()); gfx::Size(), gfx::Rect());
PdfRenderSettings render_settings( PdfRenderSettings render_settings(
content_area, physical_offsets, settings().dpi_size(), content_area, physical_offsets, settings_.dpi_size(),
/*autorotate=*/true, settings_.color() == COLOR, /*autorotate=*/true, settings_.color() == COLOR,
ps_level2 ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2 ps_level2 ? PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2
: PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3); : PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3);
...@@ -516,6 +504,15 @@ void PrintJob::ControlledWorkerShutdown() { ...@@ -516,6 +504,15 @@ void PrintJob::ControlledWorkerShutdown() {
ClearPrintedDocument(); ClearPrintedDocument();
} }
bool PrintJob::RunsTasksInCurrentSequence() const {
return task_runner_->RunsTasksInCurrentSequence();
}
bool PrintJob::PostTask(const base::Location& from_here,
base::OnceClosure task) {
return task_runner_->PostTask(from_here, std::move(task));
}
void PrintJob::HoldUntilStopIsCalled() { void PrintJob::HoldUntilStopIsCalled() {
} }
......
...@@ -10,14 +10,17 @@ ...@@ -10,14 +10,17 @@
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/printing/print_job_worker_owner.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "printing/print_settings.h"
namespace base { namespace base {
class Location;
class RefCountedMemory; class RefCountedMemory;
class SequencedTaskRunner;
} }
namespace printing { namespace printing {
...@@ -25,15 +28,12 @@ namespace printing { ...@@ -25,15 +28,12 @@ namespace printing {
class JobEventDetails; class JobEventDetails;
class MetafilePlayer; class MetafilePlayer;
class PrintJobWorker; class PrintJobWorker;
class PrintJobWorkerOwner;
class PrintedDocument; class PrintedDocument;
#if defined(OS_WIN) #if defined(OS_WIN)
class PrintedPage; class PrintedPage;
#endif #endif
class PrinterQuery; class PrinterQuery;
class PrintSettings;
void HoldRefCallback(scoped_refptr<PrintJobWorkerOwner> owner,
base::OnceClosure callback);
// Manages the print work for a specific document. Talks to the printer through // Manages the print work for a specific document. Talks to the printer through
// PrintingContext through PrintJobWorker. Hides access to PrintingContext in a // PrintingContext through PrintJobWorker. Hides access to PrintingContext in a
...@@ -42,7 +42,7 @@ void HoldRefCallback(scoped_refptr<PrintJobWorkerOwner> owner, ...@@ -42,7 +42,7 @@ void HoldRefCallback(scoped_refptr<PrintJobWorkerOwner> owner,
// reference to the job to be sure it is kept alive. All the code in this class // reference to the job to be sure it is kept alive. All the code in this class
// runs in the UI thread. All virtual functions are virtual only so that // runs in the UI thread. All virtual functions are virtual only so that
// TestPrintJob can override them in tests. // TestPrintJob can override them in tests.
class PrintJob : public PrintJobWorkerOwner, class PrintJob : public base::RefCountedThreadSafe<PrintJob>,
public content::NotificationObserver { public content::NotificationObserver {
public: public:
// Create a empty PrintJob. When initializing with this constructor, // Create a empty PrintJob. When initializing with this constructor,
...@@ -76,13 +76,6 @@ class PrintJob : public PrintJobWorkerOwner, ...@@ -76,13 +76,6 @@ class PrintJob : public PrintJobWorkerOwner,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) override; const content::NotificationDetails& details) override;
// PrintJobWorkerOwner implementation.
void GetSettingsDone(const PrintSettings& new_settings,
PrintingContext::Result result) override;
std::unique_ptr<PrintJobWorker> DetachWorker(
PrintJobWorkerOwner* new_owner) override;
const PrintSettings& settings() const override;
// Starts the actual printing. Signals the worker that it should begin to // Starts the actual printing. Signals the worker that it should begin to
// spool as soon as data is available. // spool as soon as data is available.
virtual void StartPrinting(); virtual void StartPrinting();
...@@ -111,7 +104,17 @@ class PrintJob : public PrintJobWorkerOwner, ...@@ -111,7 +104,17 @@ class PrintJob : public PrintJobWorkerOwner,
// Access the current printed document. Warning: may be NULL. // Access the current printed document. Warning: may be NULL.
PrintedDocument* document() const; PrintedDocument* document() const;
// Returns true if tasks posted to this TaskRunner are sequenced
// with this call.
bool RunsTasksInCurrentSequence() const;
// Posts the given task to be run.
bool PostTask(const base::Location& from_here, base::OnceClosure task);
protected: protected:
// Refcounted class.
friend class base::RefCountedThreadSafe<PrintJob>;
~PrintJob() override; ~PrintJob() override;
// The functions below are used for tests only. // The functions below are used for tests only.
...@@ -202,6 +205,10 @@ class PrintJob : public PrintJobWorkerOwner, ...@@ -202,6 +205,10 @@ class PrintJob : public PrintJobWorkerOwner,
std::vector<int> pdf_page_mapping_; std::vector<int> pdf_page_mapping_;
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
// Task runner reference. Used to send notifications in the right
// thread.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// Used at shutdown so that we can quit a nested run loop. // Used at shutdown so that we can quit a nested run loop.
base::WeakPtrFactory<PrintJob> quit_factory_; base::WeakPtrFactory<PrintJob> quit_factory_;
......
...@@ -31,8 +31,8 @@ class PrintQueriesQueue : public base::RefCountedThreadSafe<PrintQueriesQueue> { ...@@ -31,8 +31,8 @@ class PrintQueriesQueue : public base::RefCountedThreadSafe<PrintQueriesQueue> {
// TODO(maruel): Have them vanish after a timeout (~5 minutes?) // TODO(maruel): Have them vanish after a timeout (~5 minutes?)
void QueuePrinterQuery(PrinterQuery* query); void QueuePrinterQuery(PrinterQuery* query);
// Pops a queued PrintJobWorkerOwner object that was previously queued or // Pops a queued PrinterQuery object that was previously queued or creates
// create new one. Can be called from any thread. // a new one. Can be called from any thread.
scoped_refptr<PrinterQuery> PopPrinterQuery(int document_cookie); scoped_refptr<PrinterQuery> PopPrinterQuery(int document_cookie);
// Creates new query. Virtual so that tests can override it. // Creates new query. Virtual so that tests can override it.
......
...@@ -26,16 +26,16 @@ namespace { ...@@ -26,16 +26,16 @@ namespace {
class TestPrintJobWorker : public PrintJobWorker { class TestPrintJobWorker : public PrintJobWorker {
public: public:
explicit TestPrintJobWorker(PrintJobWorkerOwner* owner) explicit TestPrintJobWorker(PrinterQuery* query)
: PrintJobWorker(content::ChildProcessHost::kInvalidUniqueID, : PrintJobWorker(content::ChildProcessHost::kInvalidUniqueID,
content::ChildProcessHost::kInvalidUniqueID, content::ChildProcessHost::kInvalidUniqueID,
owner) {} query) {}
friend class TestOwner; friend class TestQuery;
}; };
class TestOwner : public PrinterQuery { class TestQuery : public PrinterQuery {
public: public:
TestOwner() TestQuery()
: PrinterQuery(content::ChildProcessHost::kInvalidUniqueID, : PrinterQuery(content::ChildProcessHost::kInvalidUniqueID,
content::ChildProcessHost::kInvalidUniqueID) {} content::ChildProcessHost::kInvalidUniqueID) {}
...@@ -44,30 +44,30 @@ class TestOwner : public PrinterQuery { ...@@ -44,30 +44,30 @@ class TestOwner : public PrinterQuery {
FAIL(); FAIL();
} }
std::unique_ptr<PrintJobWorker> DetachWorker( std::unique_ptr<PrintJobWorker> DetachWorker() override {
PrintJobWorkerOwner* new_owner) override {
{ {
// Do an actual detach to keep the parent class happy. // Do an actual detach to keep the parent class happy.
auto real_worker = PrinterQuery::DetachWorker(new_owner); auto real_worker = PrinterQuery::DetachWorker();
} }
// We're screwing up here since we're calling worker from the main thread. // We're screwing up here since we're calling worker from the main thread.
// That's fine for testing. It is actually simulating PrinterQuery behavior. // That's fine for testing. It is actually simulating PrinterQuery behavior.
auto worker = std::make_unique<TestPrintJobWorker>(new_owner); auto worker = std::make_unique<TestPrintJobWorker>(this);
EXPECT_TRUE(worker->Start()); EXPECT_TRUE(worker->Start());
worker->printing_context()->UseDefaultSettings(); worker->printing_context()->UseDefaultSettings();
settings_ = worker->printing_context()->settings(); settings_ = worker->printing_context()->settings();
return std::move(worker); return std::move(worker);
} }
const PrintSettings& settings() const override { return settings_; } const PrintSettings& settings() const override { return settings_; }
private: private:
~TestOwner() override {} ~TestQuery() override {}
PrintSettings settings_; PrintSettings settings_;
DISALLOW_COPY_AND_ASSIGN(TestOwner); DISALLOW_COPY_AND_ASSIGN(TestQuery);
}; };
class TestPrintJob : public PrintJob { class TestPrintJob : public PrintJob {
...@@ -103,8 +103,8 @@ TEST(PrintJobTest, SimplePrint) { ...@@ -103,8 +103,8 @@ TEST(PrintJobTest, SimplePrint) {
volatile bool check = false; volatile bool check = false;
scoped_refptr<PrintJob> job(new TestPrintJob(&check)); scoped_refptr<PrintJob> job(new TestPrintJob(&check));
EXPECT_TRUE(job->RunsTasksInCurrentSequence()); EXPECT_TRUE(job->RunsTasksInCurrentSequence());
scoped_refptr<TestOwner> owner(new TestOwner); scoped_refptr<TestQuery> query = base::MakeRefCounted<TestQuery>();
job->Initialize(owner.get(), base::string16(), 1); job->Initialize(query.get(), base::string16(), 1);
job->Stop(); job->Stop();
while (job->document()) { while (job->document()) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
......
...@@ -90,7 +90,7 @@ std::string PrintingContextDelegate::GetAppLocale() { ...@@ -90,7 +90,7 @@ std::string PrintingContextDelegate::GetAppLocale() {
return g_browser_process->GetApplicationLocale(); return g_browser_process->GetApplicationLocale();
} }
void NotificationCallback(PrintJobWorkerOwner* print_job, void NotificationCallback(PrintJob* print_job,
JobEventDetails::Type detail_type, JobEventDetails::Type detail_type,
int job_id, int job_id,
PrintedDocument* document) { PrintedDocument* document) {
...@@ -98,21 +98,26 @@ void NotificationCallback(PrintJobWorkerOwner* print_job, ...@@ -98,21 +98,26 @@ void NotificationCallback(PrintJobWorkerOwner* print_job,
base::MakeRefCounted<JobEventDetails>(detail_type, job_id, document); base::MakeRefCounted<JobEventDetails>(detail_type, job_id, document);
content::NotificationService::current()->Notify( content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT, chrome::NOTIFICATION_PRINT_JOB_EVENT,
// We know that is is a PrintJob object in this circumstance. content::Source<PrintJob>(print_job),
content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
content::Details<JobEventDetails>(details.get())); content::Details<JobEventDetails>(details.get()));
} }
void PostOnOwnerThread(scoped_refptr<PrintJobWorkerOwner> owner, // Helper function to ensure |query| is valid until at least |callback| returns.
void HoldRefCallback(scoped_refptr<PrinterQuery> query,
base::OnceClosure callback) {
std::move(callback).Run();
}
void PostOnQueryThread(scoped_refptr<PrinterQuery> query,
PrintingContext::PrintSettingsCallback callback, PrintingContext::PrintSettingsCallback callback,
PrintingContext::Result result) { PrintingContext::Result result) {
owner->PostTask(FROM_HERE, query->PostTask(FROM_HERE,
base::BindOnce(&HoldRefCallback, owner, base::BindOnce(&HoldRefCallback, query,
base::BindOnce(std::move(callback), result))); base::BindOnce(std::move(callback), result)));
} }
#if defined(OS_WIN) #if defined(OS_WIN)
void PageNotificationCallback(PrintJobWorkerOwner* print_job, void PageNotificationCallback(PrintJob* print_job,
JobEventDetails::Type detail_type, JobEventDetails::Type detail_type,
int job_id, int job_id,
PrintedDocument* document, PrintedDocument* document,
...@@ -121,8 +126,7 @@ void PageNotificationCallback(PrintJobWorkerOwner* print_job, ...@@ -121,8 +126,7 @@ void PageNotificationCallback(PrintJobWorkerOwner* print_job,
document, page); document, page);
content::NotificationService::current()->Notify( content::NotificationService::current()->Notify(
chrome::NOTIFICATION_PRINT_JOB_EVENT, chrome::NOTIFICATION_PRINT_JOB_EVENT,
// We know that is is a PrintJob object in this circumstance. content::Source<PrintJob>(print_job),
content::Source<PrintJob>(static_cast<PrintJob*>(print_job)),
content::Details<JobEventDetails>(details.get())); content::Details<JobEventDetails>(details.get()));
} }
#endif #endif
...@@ -131,30 +135,39 @@ void PageNotificationCallback(PrintJobWorkerOwner* print_job, ...@@ -131,30 +135,39 @@ void PageNotificationCallback(PrintJobWorkerOwner* print_job,
PrintJobWorker::PrintJobWorker(int render_process_id, PrintJobWorker::PrintJobWorker(int render_process_id,
int render_frame_id, int render_frame_id,
PrintJobWorkerOwner* owner) PrinterQuery* query)
: printing_context_delegate_( : printing_context_delegate_(
std::make_unique<PrintingContextDelegate>(render_process_id, std::make_unique<PrintingContextDelegate>(render_process_id,
render_frame_id)), render_frame_id)),
printing_context_( printing_context_(
PrintingContext::Create(printing_context_delegate_.get())), PrintingContext::Create(printing_context_delegate_.get())),
owner_(owner), query_(query),
thread_("Printing_Worker"), thread_("Printing_Worker"),
weak_factory_(this) { weak_factory_(this) {
// The object is created in the IO thread. // The object is created in the IO thread.
DCHECK(owner_->RunsTasksInCurrentSequence()); DCHECK(query_->RunsTasksInCurrentSequence());
} }
PrintJobWorker::~PrintJobWorker() { PrintJobWorker::~PrintJobWorker() {
// The object is normally deleted in the UI thread, but when the user // The object is normally deleted by PrintJob in the UI thread, but when the
// cancels printing or in the case of print preview, the worker is destroyed // user cancels printing or in the case of print preview, the worker is
// on the I/O thread. // destroyed with the PrinterQuery, which is on the I/O thread.
DCHECK(owner_->RunsTasksInCurrentSequence()); if (query_) {
DCHECK(!print_job_);
DCHECK(query_->RunsTasksInCurrentSequence());
} else {
DCHECK(print_job_);
DCHECK(print_job_->RunsTasksInCurrentSequence());
}
Stop(); Stop();
} }
void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { void PrintJobWorker::SetPrintJob(PrintJob* print_job) {
DCHECK(page_number_ == PageNumber::npos()); DCHECK(page_number_ == PageNumber::npos());
owner_ = new_owner; print_job_ = print_job;
// Release the Printer Query reference. It is no longer needed.
query_ = nullptr;
} }
void PrintJobWorker::GetSettings(bool ask_user_for_settings, void PrintJobWorker::GetSettings(bool ask_user_for_settings,
...@@ -166,6 +179,9 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings, ...@@ -166,6 +179,9 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK_EQ(page_number_, PageNumber::npos()); DCHECK_EQ(page_number_, PageNumber::npos());
// This function is only called by the PrinterQuery.
DCHECK(query_);
// Recursive task processing is needed for the dialog in case it needs to be // Recursive task processing is needed for the dialog in case it needs to be
// destroyed by a task. // destroyed by a task.
// TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed // TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed
...@@ -181,14 +197,14 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings, ...@@ -181,14 +197,14 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, BrowserThread::UI, FROM_HERE,
base::BindOnce( base::BindOnce(
&HoldRefCallback, base::WrapRefCounted(owner_), &HoldRefCallback, base::WrapRefCounted(query_),
base::BindOnce(&PrintJobWorker::GetSettingsWithUI, base::BindOnce(&PrintJobWorker::GetSettingsWithUI,
base::Unretained(this), document_page_count, base::Unretained(this), document_page_count,
has_selection, is_scripted))); has_selection, is_scripted)));
} else { } else {
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, BrowserThread::UI, FROM_HERE,
base::BindOnce(&HoldRefCallback, base::WrapRefCounted(owner_), base::BindOnce(&HoldRefCallback, base::WrapRefCounted(query_),
base::BindOnce(&PrintJobWorker::UseDefaultSettings, base::BindOnce(&PrintJobWorker::UseDefaultSettings,
base::Unretained(this)))); base::Unretained(this))));
} }
...@@ -197,11 +213,12 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings, ...@@ -197,11 +213,12 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
void PrintJobWorker::SetSettings( void PrintJobWorker::SetSettings(
std::unique_ptr<base::DictionaryValue> new_settings) { std::unique_ptr<base::DictionaryValue> new_settings) {
DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(query_);
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, BrowserThread::UI, FROM_HERE,
base::BindOnce( base::BindOnce(
&HoldRefCallback, base::WrapRefCounted(owner_), &HoldRefCallback, base::WrapRefCounted(query_),
base::BindOnce(&PrintJobWorker::UpdatePrintSettings, base::BindOnce(&PrintJobWorker::UpdatePrintSettings,
base::Unretained(this), std::move(new_settings)))); base::Unretained(this), std::move(new_settings))));
} }
...@@ -210,11 +227,12 @@ void PrintJobWorker::SetSettings( ...@@ -210,11 +227,12 @@ void PrintJobWorker::SetSettings(
void PrintJobWorker::SetSettingsFromPOD( void PrintJobWorker::SetSettingsFromPOD(
std::unique_ptr<printing::PrintSettings> new_settings) { std::unique_ptr<printing::PrintSettings> new_settings) {
DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(query_);
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, BrowserThread::UI, FROM_HERE,
base::BindOnce( base::BindOnce(
&HoldRefCallback, base::WrapRefCounted(owner_), &HoldRefCallback, base::WrapRefCounted(query_),
base::BindOnce(&PrintJobWorker::UpdatePrintSettingsFromPOD, base::BindOnce(&PrintJobWorker::UpdatePrintSettingsFromPOD,
base::Unretained(this), std::move(new_settings)))); base::Unretained(this), std::move(new_settings))));
} }
...@@ -246,12 +264,12 @@ void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) { ...@@ -246,12 +264,12 @@ void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) {
// http://crbug.com/73466 // http://crbug.com/73466
// MessageLoop::current()->SetNestableTasksAllowed(false); // MessageLoop::current()->SetNestableTasksAllowed(false);
// We can't use OnFailure() here since owner_ may not support notifications. // We can't use OnFailure() here since query_ does not support notifications.
// PrintJob will create the new PrintedDocument. DCHECK(query_);
owner_->PostTask(FROM_HERE, query_->PostTask(FROM_HERE,
base::BindOnce(&PrintJobWorkerOwner::GetSettingsDone, base::BindOnce(&PrinterQuery::GetSettingsDone,
base::WrapRefCounted(owner_), base::WrapRefCounted(query_),
printing_context_->settings(), result)); printing_context_->settings(), result));
} }
...@@ -286,10 +304,10 @@ void PrintJobWorker::GetSettingsWithUI( ...@@ -286,10 +304,10 @@ void PrintJobWorker::GetSettingsWithUI(
if (web_contents && web_contents->IsFullscreenForCurrentTab()) if (web_contents && web_contents->IsFullscreenForCurrentTab())
web_contents->ExitFullscreen(true); web_contents->ExitFullscreen(true);
// weak_factory_ creates pointers valid only on owner_ thread. // weak_factory_ creates pointers valid only on query_ thread.
printing_context_->AskUserForSettings( printing_context_->AskUserForSettings(
document_page_count, has_selection, is_scripted, document_page_count, has_selection, is_scripted,
base::BindOnce(&PostOnOwnerThread, base::WrapRefCounted(owner_), base::BindOnce(&PostOnQueryThread, base::WrapRefCounted(query_),
base::BindOnce(&PrintJobWorker::GetSettingsDone, base::BindOnce(&PrintJobWorker::GetSettingsDone,
weak_factory_.GetWeakPtr()))); weak_factory_.GetWeakPtr())));
} }
...@@ -441,6 +459,8 @@ void PrintJobWorker::OnDocumentDone() { ...@@ -441,6 +459,8 @@ void PrintJobWorker::OnDocumentDone() {
DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK_EQ(page_number_, PageNumber::npos()); DCHECK_EQ(page_number_, PageNumber::npos());
DCHECK(document_.get()); DCHECK(document_.get());
// PrintJob must own this, because only PrintJob can send notifications.
DCHECK(print_job_);
int job_id = printing_context_->job_id(); int job_id = printing_context_->job_id();
if (printing_context_->DocumentDone() != PrintingContext::OK) { if (printing_context_->DocumentDone() != PrintingContext::OK) {
...@@ -448,10 +468,11 @@ void PrintJobWorker::OnDocumentDone() { ...@@ -448,10 +468,11 @@ void PrintJobWorker::OnDocumentDone() {
return; return;
} }
owner_->PostTask(FROM_HERE, base::BindOnce(&NotificationCallback, print_job_->PostTask(
base::RetainedRef(owner_), FROM_HERE,
JobEventDetails::DOC_DONE, job_id, base::BindOnce(&NotificationCallback, base::RetainedRef(print_job_),
base::RetainedRef(document_))); JobEventDetails::DOC_DONE, job_id,
base::RetainedRef(document_)));
// Makes sure the variables are reinitialized. // Makes sure the variables are reinitialized.
document_ = NULL; document_ = NULL;
...@@ -478,11 +499,12 @@ void PrintJobWorker::SpoolPage(PrintedPage* page) { ...@@ -478,11 +499,12 @@ void PrintJobWorker::SpoolPage(PrintedPage* page) {
} }
// Signal everyone that the page is printed. // Signal everyone that the page is printed.
owner_->PostTask(FROM_HERE, DCHECK(print_job_);
base::BindRepeating( print_job_->PostTask(
&PageNotificationCallback, base::RetainedRef(owner_), FROM_HERE, base::BindRepeating(
JobEventDetails::PAGE_DONE, printing_context_->job_id(), &PageNotificationCallback, base::RetainedRef(print_job_),
base::RetainedRef(document_), base::RetainedRef(page))); JobEventDetails::PAGE_DONE, printing_context_->job_id(),
base::RetainedRef(document_), base::RetainedRef(page)));
} }
#else #else
void PrintJobWorker::SpoolJob() { void PrintJobWorker::SpoolJob() {
...@@ -494,13 +516,14 @@ void PrintJobWorker::SpoolJob() { ...@@ -494,13 +516,14 @@ void PrintJobWorker::SpoolJob() {
void PrintJobWorker::OnFailure() { void PrintJobWorker::OnFailure() {
DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(print_job_);
// We may loose our last reference by broadcasting the FAILED event. // We may loose our last reference by broadcasting the FAILED event.
scoped_refptr<PrintJobWorkerOwner> handle(owner_); scoped_refptr<PrintJob> handle(print_job_);
owner_->PostTask( print_job_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&NotificationCallback, base::RetainedRef(owner_), base::BindOnce(&NotificationCallback, base::RetainedRef(print_job_),
JobEventDetails::FAILED, 0, base::RetainedRef(document_))); JobEventDetails::FAILED, 0, base::RetainedRef(document_)));
Cancel(); Cancel();
......
...@@ -25,9 +25,9 @@ class DictionaryValue; ...@@ -25,9 +25,9 @@ class DictionaryValue;
namespace printing { namespace printing {
class PrintJob; class PrintJob;
class PrintJobWorkerOwner;
class PrintedDocument; class PrintedDocument;
class PrintedPage; class PrintedPage;
class PrinterQuery;
// Worker thread code. It manages the PrintingContext, which can be blocking // Worker thread code. It manages the PrintingContext, which can be blocking
// and/or run a message loop. This is the object that generates most // and/or run a message loop. This is the object that generates most
...@@ -38,10 +38,12 @@ class PrintJobWorker { ...@@ -38,10 +38,12 @@ class PrintJobWorker {
public: public:
PrintJobWorker(int render_process_id, PrintJobWorker(int render_process_id,
int render_frame_id, int render_frame_id,
PrintJobWorkerOwner* owner); PrinterQuery* query);
virtual ~PrintJobWorker(); virtual ~PrintJobWorker();
void SetNewOwner(PrintJobWorkerOwner* new_owner); void SetPrintJob(PrintJob* print_job);
/* The following functions may only be called before calling SetPrintJob(). */
// Initializes the print settings. If |ask_user_for_settings| is true, a // Initializes the print settings. If |ask_user_for_settings| is true, a
// Print... dialog box will be shown to ask the user their preference. // Print... dialog box will be shown to ask the user their preference.
...@@ -63,6 +65,8 @@ class PrintJobWorker { ...@@ -63,6 +65,8 @@ class PrintJobWorker {
std::unique_ptr<printing::PrintSettings> new_settings); std::unique_ptr<printing::PrintSettings> new_settings);
#endif #endif
/* The following functions may only be called after calling SetPrintJob(). */
// Starts the printing loop. Every pages are printed as soon as the data is // Starts the printing loop. Every pages are printed as soon as the data is
// available. Makes sure the new_document is the right one. // available. Makes sure the new_document is the right one.
void StartPrinting(PrintedDocument* new_document); void StartPrinting(PrintedDocument* new_document);
...@@ -75,7 +79,9 @@ class PrintJobWorker { ...@@ -75,7 +79,9 @@ class PrintJobWorker {
// the next page can be printed. // the next page can be printed.
void OnNewPage(); void OnNewPage();
// This is the only function that can be called in a thread. /* The following functions may be called before or after SetPrintJob(). */
// Cancels the job.
void Cancel(); void Cancel();
// Returns true if the thread has been started, and not yet stopped. // Returns true if the thread has been started, and not yet stopped.
...@@ -141,7 +147,7 @@ class PrintJobWorker { ...@@ -141,7 +147,7 @@ class PrintJobWorker {
std::unique_ptr<printing::PrintSettings> new_settings); std::unique_ptr<printing::PrintSettings> new_settings);
#endif #endif
// Reports settings back to owner_. // Reports settings back to |query_|.
void GetSettingsDone(PrintingContext::Result result); void GetSettingsDone(PrintingContext::Result result);
// Use the default settings. When using GTK+ or Mac, this can still end up // Use the default settings. When using GTK+ or Mac, this can still end up
...@@ -158,9 +164,13 @@ class PrintJobWorker { ...@@ -158,9 +164,13 @@ class PrintJobWorker {
// The printed document. Only has read-only access. // The printed document. Only has read-only access.
scoped_refptr<PrintedDocument> document_; scoped_refptr<PrintedDocument> document_;
// The printer query that owns this worker thread at creation. It will own
// the object until DetachWorker() is called.
PrinterQuery* query_ = nullptr;
// The print job owning this worker thread. It is guaranteed to outlive this // The print job owning this worker thread. It is guaranteed to outlive this
// object. // object and should be set with SetPrintJob().
PrintJobWorkerOwner* owner_; PrintJob* print_job_ = nullptr;
// Current page number to print. // Current page number to print.
PageNumber page_number_; PageNumber page_number_;
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/printing/print_job_worker_owner.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
namespace printing {
PrintJobWorkerOwner::PrintJobWorkerOwner()
: task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
PrintJobWorkerOwner::~PrintJobWorkerOwner() {
}
bool PrintJobWorkerOwner::RunsTasksInCurrentSequence() const {
return task_runner_->RunsTasksInCurrentSequence();
}
bool PrintJobWorkerOwner::PostTask(const base::Location& from_here,
base::OnceClosure task) {
return task_runner_->PostTask(from_here, std::move(task));
}
} // namespace printing
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
#define CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
#include <memory>
#include "base/memory/ref_counted.h"
#include "printing/printing_context.h"
namespace base {
class Location;
class SequencedTaskRunner;
}
namespace printing {
class PrintJobWorker;
class PrintSettings;
class PrintJobWorkerOwner
: public base::RefCountedThreadSafe<PrintJobWorkerOwner> {
public:
// Can only be called in single-threaded context.
PrintJobWorkerOwner();
// Finishes the initialization began by PrintJobWorker::GetSettings().
// Creates a new PrintedDocument if necessary. Solely meant to be called by
// PrintJobWorker.
virtual void GetSettingsDone(const PrintSettings& new_settings,
PrintingContext::Result result) = 0;
// Detach the PrintJobWorker associated to this object.
virtual std::unique_ptr<PrintJobWorker> DetachWorker(
PrintJobWorkerOwner* new_owner) = 0;
// Access the current settings.
virtual const PrintSettings& settings() const = 0;
// Returns true if tasks posted to this TaskRunner are sequenced
// with this call.
bool RunsTasksInCurrentSequence() const;
// Posts the given task to be run.
bool PostTask(const base::Location& from_here, base::OnceClosure task);
protected:
friend class base::RefCountedThreadSafe<PrintJobWorkerOwner>;
virtual ~PrintJobWorkerOwner();
// Task runner reference. Used to send notifications in the right
// thread.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
};
} // namespace printing
#endif // CHROME_BROWSER_PRINTING_PRINT_JOB_WORKER_OWNER_H__
...@@ -9,18 +9,24 @@ ...@@ -9,18 +9,24 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/printing/print_job_worker.h" #include "chrome/browser/printing/print_job_worker.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "printing/print_job_constants.h"
#include "printing/print_settings.h"
namespace printing { namespace printing {
PrinterQuery::PrinterQuery(int render_process_id, int render_frame_id) PrinterQuery::PrinterQuery(int render_process_id, int render_frame_id)
: worker_(std::make_unique<PrintJobWorker>(render_process_id, : cookie_(PrintSettings::NewCookie()),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
worker_(std::make_unique<PrintJobWorker>(render_process_id,
render_frame_id, render_frame_id,
this)), this)) {
cookie_(PrintSettings::NewCookie()) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
} }
...@@ -49,12 +55,10 @@ void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings, ...@@ -49,12 +55,10 @@ void PrinterQuery::GetSettingsDone(const PrintSettings& new_settings,
} }
} }
std::unique_ptr<PrintJobWorker> PrinterQuery::DetachWorker( std::unique_ptr<PrintJobWorker> PrinterQuery::DetachWorker() {
PrintJobWorkerOwner* new_owner) {
DCHECK(!callback_); DCHECK(!callback_);
DCHECK(worker_); DCHECK(worker_);
worker_->SetNewOwner(new_owner);
return std::move(worker_); return std::move(worker_);
} }
...@@ -138,6 +142,15 @@ void PrinterQuery::StopWorker() { ...@@ -138,6 +142,15 @@ void PrinterQuery::StopWorker() {
} }
} }
bool PrinterQuery::RunsTasksInCurrentSequence() const {
return task_runner_->RunsTasksInCurrentSequence();
}
bool PrinterQuery::PostTask(const base::Location& from_here,
base::OnceClosure task) {
return task_runner_->PostTask(from_here, std::move(task));
}
bool PrinterQuery::is_callback_pending() const { bool PrinterQuery::is_callback_pending() const {
return !callback_.is_null(); return !callback_.is_null();
} }
......
...@@ -9,10 +9,15 @@ ...@@ -9,10 +9,15 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/printing/print_job_worker_owner.h" #include "base/memory/ref_counted.h"
#include "printing/print_job_constants.h"
#include "printing/print_settings.h"
#include "printing/printing_context.h"
namespace base { namespace base {
class DictionaryValue; class DictionaryValue;
class Location;
class SequencedTaskRunner;
} }
namespace printing { namespace printing {
...@@ -20,7 +25,7 @@ namespace printing { ...@@ -20,7 +25,7 @@ namespace printing {
class PrintJobWorker; class PrintJobWorker;
// Query the printer for settings. // Query the printer for settings.
class PrinterQuery : public PrintJobWorkerOwner { class PrinterQuery : public base::RefCountedThreadSafe<PrinterQuery> {
public: public:
// GetSettings() UI parameter. // GetSettings() UI parameter.
enum class GetSettingsAskParam { enum class GetSettingsAskParam {
...@@ -31,12 +36,16 @@ class PrinterQuery : public PrintJobWorkerOwner { ...@@ -31,12 +36,16 @@ class PrinterQuery : public PrintJobWorkerOwner {
// Can only be called on the IO thread. // Can only be called on the IO thread.
PrinterQuery(int render_process_id, int render_frame_id); PrinterQuery(int render_process_id, int render_frame_id);
// PrintJobWorkerOwner implementation. // Virtual so that tests can override.
void GetSettingsDone(const PrintSettings& new_settings, virtual void GetSettingsDone(const PrintSettings& new_settings,
PrintingContext::Result result) override; PrintingContext::Result result);
std::unique_ptr<PrintJobWorker> DetachWorker(
PrintJobWorkerOwner* new_owner) override; // Detach the PrintJobWorker associated to this object. Virtual so that tests
const PrintSettings& settings() const override; // can override.
virtual std::unique_ptr<PrintJobWorker> DetachWorker();
// Virtual so that tests can override.
virtual const PrintSettings& settings() const;
// Initializes the printing context. It is fine to call this function multiple // Initializes the printing context. It is fine to call this function multiple
// times to reinitialize the settings. |web_contents_observer| can be queried // times to reinitialize the settings. |web_contents_observer| can be queried
...@@ -72,18 +81,22 @@ class PrinterQuery : public PrintJobWorkerOwner { ...@@ -72,18 +81,22 @@ class PrinterQuery : public PrintJobWorkerOwner {
// Returns if a worker thread is still associated to this instance. // Returns if a worker thread is still associated to this instance.
bool is_valid() const; bool is_valid() const;
// Returns true if tasks posted to this TaskRunner are sequenced
// with this call.
bool RunsTasksInCurrentSequence() const;
// Posts the given task to be run.
bool PostTask(const base::Location& from_here, base::OnceClosure task);
protected: protected:
// Refcounted class. // Refcounted class.
~PrinterQuery() override; friend class base::RefCountedThreadSafe<PrinterQuery>;
virtual ~PrinterQuery();
// For unit tests to manually set the print callback. // For unit tests to manually set the print callback.
void set_callback(base::OnceClosure callback); void set_callback(base::OnceClosure callback);
// All the UI is done in a worker thread because many Win32 print functions
// are blocking and enters a message loop without your consent. There is one
// worker thread per print job.
std::unique_ptr<PrintJobWorker> worker_;
private: private:
// Lazy create the worker thread. There is one worker thread per print job. // Lazy create the worker thread. There is one worker thread per print job.
void StartWorker(base::OnceClosure callback); void StartWorker(base::OnceClosure callback);
...@@ -103,6 +116,15 @@ class PrinterQuery : public PrintJobWorkerOwner { ...@@ -103,6 +116,15 @@ class PrinterQuery : public PrintJobWorkerOwner {
// Callback waiting to be run. // Callback waiting to be run.
base::OnceClosure callback_; base::OnceClosure callback_;
// Task runner reference. Used to send notifications in the right
// thread.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// All the UI is done in a worker thread because many Win32 print functions
// are blocking and enters a message loop without your consent. There is one
// worker thread per print job.
std::unique_ptr<PrintJobWorker> worker_;
DISALLOW_COPY_AND_ASSIGN(PrinterQuery); DISALLOW_COPY_AND_ASSIGN(PrinterQuery);
}; };
......
...@@ -21,11 +21,13 @@ void TestPrintJob::Initialize(PrinterQuery* query, ...@@ -21,11 +21,13 @@ void TestPrintJob::Initialize(PrinterQuery* query,
int page_count) { int page_count) {
// Since we do not actually print in these tests, just let this get destroyed // Since we do not actually print in these tests, just let this get destroyed
// when this function exits. // when this function exits.
std::unique_ptr<PrintJobWorker> worker = query->DetachWorker(this); std::unique_ptr<PrintJobWorker> worker = query->DetachWorker();
set_settings(query->settings()); set_settings(query->settings());
scoped_refptr<PrintedDocument> new_doc = scoped_refptr<PrintedDocument> new_doc =
base::MakeRefCounted<PrintedDocument>(settings(), name, query->cookie()); base::MakeRefCounted<PrintedDocument>(query->settings(), name,
query->cookie());
new_doc->set_page_count(page_count); new_doc->set_page_count(page_count);
UpdatePrintedDocument(new_doc.get()); UpdatePrintedDocument(new_doc.get());
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "base/macros.h" #include "base/macros.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_job_worker_owner.h"
#include "chrome/browser/printing/printer_query.h" #include "chrome/browser/printing/printer_query.h"
namespace base { namespace base {
......
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