15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/printing/print_job.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/worker_pool.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/printing/print_job_worker.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_document.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_page.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_WIN)
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/printing/pdf_to_emf_converter.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "printing/pdf_render_settings.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function to ensure |owner| is valid until at least |callback| returns.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const base::Closure& callback) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.Run();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace printing {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintJob::PrintJob()
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : source_(NULL),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      worker_(),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings_(),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_job_pending_(false),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_canceling_(false),
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      quit_factory_(this) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is normally a UI message loop, but in unit tests, the message loop is
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the 'default' type.
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(base::MessageLoopForUI::IsCurrent() ||
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         base::MessageLoop::current()->type() ==
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)             base::MessageLoop::TYPE_DEFAULT);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintJob::~PrintJob() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The job should be finished (or at least canceled) when it is destroyed.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_job_pending_);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_canceling_);
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(!worker_ || !worker_->IsRunning());
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(RunsTasksOnCurrentThread());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::Initialize(PrintJobWorkerOwner* job,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          PrintedPagesSource* source,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          int page_count) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!source_);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!worker_.get());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_job_pending_);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_canceling_);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!document_.get());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source_ = source;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  worker_.reset(job->DetachWorker(this));
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings_ = job->settings();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrintedDocument* new_doc =
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new PrintedDocument(settings_,
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                          source_,
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                          job->cookie(),
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                          content::BrowserThread::GetBlockingPool());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new_doc->set_page_count(page_count);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdatePrintedDocument(new_doc);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't forget to register to our own messages.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<PrintJob>(this));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::Observe(int type,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) {
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(RunsTasksOnCurrentThread());
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default: {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::GetSettingsDone(const PrintSettings& new_settings,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               PrintingContext::Result result) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintJobWorker* PrintJob::DetachWorker(PrintJobWorkerOwner* new_owner) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PrintSettings& PrintJob::settings() const {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return settings_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PrintJob::cookie() const {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!document_.get())
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Always use an invalid cookie in this case.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return document_->cookie();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::StartPrinting() {
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(RunsTasksOnCurrentThread());
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(worker_->IsRunning());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_job_pending_);
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!worker_->IsRunning() || is_job_pending_)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Real work is done in PrintJobWorker::StartPrinting().
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  worker_->PostTask(FROM_HERE,
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                    base::Bind(&HoldRefCallback,
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               make_scoped_refptr(this),
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                               base::Bind(&PrintJobWorker::StartPrinting,
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                          base::Unretained(worker_.get()),
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                          document_)));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the flag right now.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_job_pending_ = true;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tell everyone!
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<JobEventDetails> details(
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PRINT_JOB_EVENT,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<PrintJob>(this),
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<JobEventDetails>(details.get()));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::Stop() {
14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(RunsTasksOnCurrentThread());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (quit_factory_.HasWeakPtrs()) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // In case we're running a nested message loop to wait for a job to finish,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and we finished before the timeout, quit the nested loop right away.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Quit();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    quit_factory_.InvalidateWeakPtrs();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Be sure to live long enough.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PrintJob> handle(this);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (worker_->IsRunning()) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ControlledWorkerShutdown();
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Flush the cached document.
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UpdatePrintedDocument(NULL);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::Cancel() {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_canceling_)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_canceling_ = true;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Be sure to live long enough.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PrintJob> handle(this);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(RunsTasksOnCurrentThread());
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (worker_ && worker_->IsRunning()) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Call this right now so it renders the context invalid. Do not use
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // InvokeLater since it would take too much time.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker_->Cancel();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure a Cancel() is broadcast.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<JobEventDetails> details(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new JobEventDetails(JobEventDetails::FAILED, NULL, NULL));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PRINT_JOB_EVENT,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<PrintJob>(this),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<JobEventDetails>(details.get()));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stop();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_canceling_ = false;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrintJob::FlushJob(base::TimeDelta timeout) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the object outlive this message loop.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PrintJob> handle(this);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&PrintJob::Quit, quit_factory_.GetWeakPtr()), timeout);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::ScopedNestableTaskAllower allow(
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current());
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::DisconnectSource() {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  source_ = NULL;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document_.get())
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    document_->DisconnectSource();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrintJob::is_job_pending() const {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_job_pending_;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintedDocument* PrintJob::document() const {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return document_.get();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_WIN)
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass PrintJob::PdfToEmfState {
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PdfToEmfState(const gfx::Size& page_size, const gfx::Rect& content_area)
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : page_count_(0),
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        current_page_(0),
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        pages_in_progress_(0),
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        page_size_(page_size),
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        content_area_(content_area),
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        converter_(PdfToEmfConverter::CreateDefault()) {}
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void Start(const scoped_refptr<base::RefCountedMemory>& data,
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             const PdfRenderSettings& conversion_settings,
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             const PdfToEmfConverter::StartCallback& start_callback) {
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    converter_->Start(data, conversion_settings, start_callback);
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void GetMorePages(
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const PdfToEmfConverter::GetPageCallback& get_page_callback) {
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const int kMaxNumberOfTempFilesPerDocument = 3;
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    while (pages_in_progress_ < kMaxNumberOfTempFilesPerDocument &&
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           current_page_ < page_count_) {
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ++pages_in_progress_;
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      converter_->GetPage(current_page_++, get_page_callback);
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnPageProcessed(
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const PdfToEmfConverter::GetPageCallback& get_page_callback) {
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    --pages_in_progress_;
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GetMorePages(get_page_callback);
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Release converter if we don't need this any more.
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!pages_in_progress_ && current_page_ >= page_count_)
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      converter_.reset();
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void set_page_count(int page_count) { page_count_ = page_count; }
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Size page_size() const { return page_size_; }
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect content_area() const { return content_area_; }
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int page_count_;
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int current_page_;
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int pages_in_progress_;
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Size page_size_;
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect content_area_;
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<PdfToEmfConverter> converter_;
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PrintJob::StartPdfToEmfConversion(
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<base::RefCountedMemory>& bytes,
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const gfx::Size& page_size,
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const gfx::Rect& content_area) {
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!ptd_to_emf_state_.get());
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ptd_to_emf_state_.reset(new PdfToEmfState(page_size, content_area));
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const int kPrinterDpi = settings().dpi();
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ptd_to_emf_state_->Start(
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bytes,
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      printing::PdfRenderSettings(content_area, kPrinterDpi, true),
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&PrintJob::OnPdfToEmfStarted, this));
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PrintJob::OnPdfToEmfStarted(int page_count) {
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (page_count <= 0) {
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ptd_to_emf_state_.reset();
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Cancel();
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ptd_to_emf_state_->set_page_count(page_count);
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ptd_to_emf_state_->GetMorePages(
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PrintJob::OnPdfToEmfPageConverted(int page_number,
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       double scale_factor,
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       scoped_ptr<MetafilePlayer> emf) {
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(ptd_to_emf_state_);
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!document_.get() || !emf) {
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ptd_to_emf_state_.reset();
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Cancel();
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Update the rendered document. It will send notifications to the listener.
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  document_->SetPage(page_number,
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     emf.Pass(),
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     scale_factor,
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     ptd_to_emf_state_->page_size(),
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     ptd_to_emf_state_->content_area());
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ptd_to_emf_state_->GetMorePages(
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // OS_WIN
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document_.get() == new_document)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document_ = new_document;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (document_.get()) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    settings_ = document_->settings();
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (worker_) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!is_job_pending_);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sync the document with the worker.
33203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    worker_->PostTask(FROM_HERE,
33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                      base::Bind(&HoldRefCallback,
33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 make_scoped_refptr(this),
33503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 base::Bind(&PrintJobWorker::OnDocumentChanged,
33603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                            base::Unretained(worker_.get()),
33703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                            document_)));
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (event_details.type()) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::FAILED: {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings_.Clear();
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // No need to cancel since the worker already canceled itself.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Stop();
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::USER_INIT_DONE:
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::DEFAULT_INIT_DONE:
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::USER_INIT_CANCELED: {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_EQ(event_details.document(), document_.get());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::NEW_DOC:
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::NEW_PAGE:
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::JOB_DONE:
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::ALL_PAGES_REQUESTED: {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't care.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JobEventDetails::DOC_DONE: {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This will call Stop() and broadcast a JOB_DONE message.
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current()->PostTask(
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this));
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case JobEventDetails::PAGE_DONE:
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_WIN)
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ptd_to_emf_state_->OnPageProcessed(
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::Bind(&PrintJob::OnPdfToEmfPageConverted, this));
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // OS_WIN
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      break;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default: {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::OnDocumentDone() {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Be sure to live long enough. The instance could be destroyed by the
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JOB_DONE broadcast.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<PrintJob> handle(this);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop the worker thread.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stop();
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<JobEventDetails> details(
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), NULL));
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationService::current()->Notify(
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_PRINT_JOB_EVENT,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<PrintJob>(this),
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<JobEventDetails>(details.get()));
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::ControlledWorkerShutdown() {
39803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(RunsTasksOnCurrentThread());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The deadlock this code works around is specific to window messaging on
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Windows, so we aren't likely to need it on any other platforms.
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We could easily get into a deadlock case if worker_->Stop() is used; the
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // printer driver created a window as a child of the browser window. By
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // canceling the job, the printer driver initiated dialog box is destroyed,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which sends a blocking message to its parent window. If the browser window
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread is not processing messages, a deadlock occurs.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function ensures that the dialog box will be destroyed in a timely
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // manner by the mere fact that the thread will terminate. So the potential
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deadlock is eliminated.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  worker_->StopSoon();
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Delay shutdown until the worker terminates.  We want this code path
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to wait on the thread to quit before continuing.
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (worker_->IsRunning()) {
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&PrintJob::ControlledWorkerShutdown, this),
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(100));
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now make sure the thread object is cleaned up. Do this on a worker
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // thread because it may block.
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::WorkerPool::PostTaskAndReply(
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&PrintJobWorker::Stop, base::Unretained(worker_.get())),
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&PrintJob::HoldUntilStopIsCalled, this),
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      false);
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  is_job_pending_ = false;
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registrar_.RemoveAll();
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdatePrintedDocument(NULL);
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PrintJob::HoldUntilStopIsCalled() {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJob::Quit() {
44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Quit();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes settings_ ownership and will be deleted in the receiving thread.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JobEventDetails::JobEventDetails(Type type,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 PrintedDocument* document,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 PrintedPage* page)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : document_(document),
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      page_(page),
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type_(type) {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JobEventDetails::~JobEventDetails() {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PrintedDocument* JobEventDetails::document() const { return document_.get(); }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PrintedPage* JobEventDetails::page() const { return page_.get(); }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace printing
463