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