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_worker.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/printing/print_job.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/render_view_host.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/web_contents.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/print_job_constants.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_document.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/printed_page.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "printing/printing_utils.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace printing { 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function to ensure |owner| is valid until at least |callback| returns. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass PrintingContextDelegate : public PrintingContext::Delegate { 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintingContextDelegate(int render_process_id, int render_view_id); 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual ~PrintingContextDelegate(); 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual gfx::NativeView GetParentView() OVERRIDE; 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual std::string GetAppLocale() OVERRIDE; 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int render_process_id_; 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int render_view_id_; 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPrintingContextDelegate::PrintingContextDelegate(int render_process_id, 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int render_view_id) 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : render_process_id_(render_process_id), 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_view_id_(render_view_id) { 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPrintingContextDelegate::~PrintingContextDelegate() { 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccigfx::NativeView PrintingContextDelegate::GetParentView() { 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_CURRENTLY_ON(BrowserThread::UI); 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::RenderViewHost* view = 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::RenderViewHost::FromID(render_process_id_, render_view_id_); 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!view) 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::WebContents* wc = content::WebContents::FromRenderViewHost(view); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return wc ? wc->GetNativeView() : NULL; 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string PrintingContextDelegate::GetAppLocale() { 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return g_browser_process->GetApplicationLocale(); 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NotificationCallback(PrintJobWorkerOwner* print_job, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JobEventDetails::Type detail_type, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintedDocument* document, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintedPage* page) { 79a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch JobEventDetails* details = new JobEventDetails(detail_type, document, page); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_PRINT_JOB_EVENT, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We know that is is a PrintJob object in this circumstance. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<PrintJob>(static_cast<PrintJob*>(print_job)), 84a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch content::Details<JobEventDetails>(details)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPrintJobWorker::PrintJobWorker(int render_process_id, 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int render_view_id, 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintJobWorkerOwner* owner) 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : owner_(owner), thread_("Printing_Worker"), weak_factory_(this) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The object is created in the IO thread. 9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(owner_->RunsTasksOnCurrentThread()); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci printing_context_delegate_.reset( 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new PrintingContextDelegate(render_process_id, render_view_id)); 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci printing_context_ = PrintingContext::Create(printing_context_delegate_.get()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrintJobWorker::~PrintJobWorker() { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The object is normally deleted in the UI thread, but when the user 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cancels printing or in the case of print preview, the worker is destroyed 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the I/O thread. 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(owner_->RunsTasksOnCurrentThread()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(page_number_ == PageNumber::npos()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_ = new_owner; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrintJobWorker::GetSettings( 1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool ask_user_for_settings, 1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int document_page_count, 1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool has_selection, 1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) MarginType margin_type) { 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(page_number_, PageNumber::npos()); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Recursive task processing is needed for the dialog in case it needs to be 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroyed by a task. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(thestig): This code is wrong. SetNestableTasksAllowed(true) is needed 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the thread where the PrintDlgEx is called, and definitely both calls 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should happen on the same thread. See http://crbug.com/73466 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageLoop::current()->SetNestableTasksAllowed(true); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printing_context_->set_margin_type(margin_type); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When we delegate to a destination, we don't ask the user for settings. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mad): Ask the destination for settings. 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ask_user_for_settings) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&HoldRefCallback, make_scoped_refptr(owner_), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::GetSettingsWithUI, 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::Unretained(this), 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) document_page_count, 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) has_selection))); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&HoldRefCallback, make_scoped_refptr(owner_), 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::UseDefaultSettings, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)))); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PrintJobWorker::SetSettings( 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<base::DictionaryValue> new_settings) { 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) BrowserThread::UI, 155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FROM_HERE, 156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&HoldRefCallback, 157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) make_scoped_refptr(owner_), 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::UpdatePrintSettings, 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this), 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Passed(&new_settings)))); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::UpdatePrintSettings( 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<base::DictionaryValue> new_settings) { 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_CURRENTLY_ON(BrowserThread::UI); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintingContext::Result result = 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) printing_context_->UpdatePrintSettings(*new_settings); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSettingsDone(result); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Most PrintingContext functions may start a message loop and process 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message recursively, so disable recursive task processing. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(thestig): See above comment. SetNestableTasksAllowed(false) needs to 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be called on the same thread as the previous call. See 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/73466 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageLoop::current()->SetNestableTasksAllowed(false); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can't use OnFailure() here since owner_ may not support notifications. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PrintJob will create the new PrintedDocument. 18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) owner_->PostTask(FROM_HERE, 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(&PrintJobWorkerOwner::GetSettingsDone, 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_refptr(owner_), 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) printing_context_->settings(), 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) result)); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PrintJobWorker::GetSettingsWithUI( 1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int document_page_count, 1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool has_selection) { 1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printing_context_->AskUserForSettings( 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci document_page_count, 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci has_selection, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::GetSettingsWithUIDone, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) { 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PostTask(FROM_HERE, 20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(&HoldRefCallback, 20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_refptr(owner_), 20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(&PrintJobWorker::GetSettingsDone, 20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Unretained(this), 20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) result))); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::UseDefaultSettings() { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintingContext::Result result = printing_context_->UseDefaultSettings(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSettingsDone(result); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::StartPrinting(PrintedDocument* new_document) { 21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(page_number_, PageNumber::npos()); 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(document_.get(), new_document); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(document_.get()); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!document_.get() || page_number_ != PageNumber::npos() || 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) document_.get() != new_document) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 document_name = 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) printing::SimplifyDocumentTitle(document_->name()); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (document_name.empty()) { 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) document_name = printing::SimplifyDocumentTitle( 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_DEFAULT_PRINT_DOCUMENT_TITLE)); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintingContext::Result result = 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printing_context_->NewDocument(document_name); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != PrintingContext::OK) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnFailure(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to print already cached data. It may already have been generated for 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the print preview. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnNewPage(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't touch this anymore since the instance could be destroyed. It happens 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if all the pages are printed a one sweep and the client doesn't have a 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handle to us anymore. There's a timing issue involved between the worker 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread and the UI thread. Take no chance. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) { 24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(page_number_, PageNumber::npos()); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (page_number_ != PageNumber::npos()) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document_ = new_document; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::OnNewPage() { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!document_.get()) // Spurious message. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message_loop() could return NULL when the print job is cancelled. 26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (page_number_ == PageNumber::npos()) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find first page to print. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int page_count = document_->page_count(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!page_count) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We still don't know how many pages the document contains. We can't 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // start to print the document yet since the header/footer may refer to 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the document's page count. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have enough information to initialize page_number_. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_number_.Init(document_->settings(), page_count); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(page_number_, PageNumber::npos()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Is the page available? 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<PrintedPage> page = document_->GetPage(page_number_.ToInt()); 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!page.get()) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to wait for the page to be available. 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PrintJobWorker::OnNewPage, weak_factory_.GetWeakPtr()), 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(500)); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The page is there, print it. 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SpoolPage(page.get()); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++page_number_; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (page_number_ == PageNumber::npos()) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnDocumentDone(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't touch this anymore since the instance could be destroyed. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::Cancel() { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the only function that can be called from any thread. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printing_context_->Cancel(); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cannot touch any member variable since we don't know in which thread 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // context we run. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool PrintJobWorker::IsRunning() const { 30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return thread_.IsRunning(); 30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool PrintJobWorker::PostTask(const tracked_objects::Location& from_here, 31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const base::Closure& task) { 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (task_runner_.get()) 31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return task_runner_->PostTask(from_here, task); 31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void PrintJobWorker::StopSoon() { 31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) thread_.StopSoon(); 32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void PrintJobWorker::Stop() { 32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) thread_.Stop(); 32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool PrintJobWorker::Start() { 32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool result = thread_.Start(); 32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_ = thread_.task_runner(); 32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return result; 33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::OnDocumentDone() { 33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(page_number_, PageNumber::npos()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(document_.get()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (printing_context_->DocumentDone() != PrintingContext::OK) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnFailure(); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) owner_->PostTask(FROM_HERE, 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&NotificationCallback, 34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_refptr(owner_), 34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) JobEventDetails::DOC_DONE, 34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) document_, 34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<PrintedPage>())); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Makes sure the variables are reinitialized. 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document_ = NULL; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::SpoolPage(PrintedPage* page) { 35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(page_number_, PageNumber::npos()); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Signal everyone that the page is about to be printed. 35803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) owner_->PostTask(FROM_HERE, 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&NotificationCallback, 36003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_refptr(owner_), 36103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) JobEventDetails::NEW_PAGE, 36203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) document_, 36303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_refptr(page))); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Preprocess. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (printing_context_->NewPage() != PrintingContext::OK) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnFailure(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Actual printing. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document_->RenderPrintedPage(*page, printing_context_->context()); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document_->RenderPrintedPage(*page, printing_context_.get()); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Postprocess. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (printing_context_->PageDone() != PrintingContext::OK) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnFailure(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Signal everyone that the page is printed. 38503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) owner_->PostTask(FROM_HERE, 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&NotificationCallback, 38703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_refptr(owner_), 38803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) JobEventDetails::PAGE_DONE, 38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) document_, 39003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_refptr(page))); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintJobWorker::OnFailure() { 39403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may loose our last reference by broadcasting the FAILED event. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<PrintJobWorkerOwner> handle(owner_); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) owner_->PostTask(FROM_HERE, 4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&NotificationCallback, 40103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_refptr(owner_), 40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) JobEventDetails::FAILED, 40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) document_, 40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<PrintedPage>())); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Cancel(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Makes sure the variables are reinitialized. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document_ = NULL; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_number_ = PageNumber::npos(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace printing 413