summaryrefslogtreecommitdiffstats
path: root/chrome/service
diff options
context:
space:
mode:
authorvitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-10 06:05:10 +0000
committervitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-10 06:05:10 +0000
commit6ed843366f5ee413ca48f1ad245ab0000981b8f6 (patch)
tree65fdf8e17fd1497bac0ae399641984d69b1ec376 /chrome/service
parent3b260c1bc932cadfbd3b0d1aea26132488f9a842 (diff)
downloadchromium_src-6ed843366f5ee413ca48f1ad245ab0000981b8f6.zip
chromium_src-6ed843366f5ee413ca48f1ad245ab0000981b8f6.tar.gz
chromium_src-6ed843366f5ee413ca48f1ad245ab0000981b8f6.tar.bz2
Move some nested classes out of PrintSystemWin
BUG=317027 Review URL: https://codereview.chromium.org/67753002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234165 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/service')
-rw-r--r--chrome/service/cloud_print/print_system_win.cc861
1 files changed, 428 insertions, 433 deletions
diff --git a/chrome/service/cloud_print/print_system_win.cc b/chrome/service/cloud_print/print_system_win.cc
index 408d6a9..778e97e 100644
--- a/chrome/service/cloud_print/print_system_win.cc
+++ b/chrome/service/cloud_print/print_system_win.cc
@@ -32,7 +32,7 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/rect.h"
-#pragma comment(lib, "rpcrt4.lib") // for UuidToString & Co.
+namespace cloud_print {
namespace {
@@ -144,10 +144,6 @@ HRESULT PrintTicketToDevMode(const std::string& printer_name,
return hr;
}
-} // namespace
-
-namespace cloud_print {
-
class PrintSystemWatcherWin : public base::win::ObjectWatcher::Delegate {
public:
PrintSystemWatcherWin()
@@ -248,501 +244,499 @@ class PrintSystemWatcherWin : public base::win::ObjectWatcher::Delegate {
// PrintSystemWin watchers from wrong Delegate, giving C2664 and C2259 errors.
typedef PrintSystemWatcherWin::Delegate PrintSystemWatcherWinDelegate;
-class PrintSystemWin : public PrintSystem {
+class PrintServerWatcherWin
+ : public PrintSystem::PrintServerWatcher,
+ public PrintSystemWatcherWinDelegate {
public:
- PrintSystemWin();
+ PrintServerWatcherWin() : delegate_(NULL) {}
- // PrintSystem implementation.
- virtual PrintSystemResult Init() OVERRIDE;
- virtual PrintSystem::PrintSystemResult EnumeratePrinters(
- printing::PrinterList* printer_list) OVERRIDE;
- virtual void GetPrinterCapsAndDefaults(
- const std::string& printer_name,
- const PrinterCapsAndDefaultsCallback& callback) OVERRIDE;
- virtual bool IsValidPrinter(const std::string& printer_name) OVERRIDE;
- virtual bool ValidatePrintTicket(
- const std::string& printer_name,
- const std::string& print_ticket_data) OVERRIDE;
- virtual bool GetJobDetails(const std::string& printer_name,
- PlatformJobId job_id,
- PrintJobDetails *job_details) OVERRIDE;
+ // PrintSystem::PrintServerWatcher implementation.
+ virtual bool StartWatching(
+ PrintSystem::PrintServerWatcher::Delegate* delegate) OVERRIDE{
+ delegate_ = delegate;
+ return watcher_.Start(std::string(), this);
+ }
- class PrintServerWatcherWin
- : public PrintSystem::PrintServerWatcher,
- public PrintSystemWatcherWinDelegate {
- public:
- PrintServerWatcherWin() : delegate_(NULL) {}
+ virtual bool StopWatching() OVERRIDE{
+ bool ret = watcher_.Stop();
+ delegate_ = NULL;
+ return ret;
+ }
- // PrintSystem::PrintServerWatcher implementation.
- virtual bool StartWatching(
- PrintSystem::PrintServerWatcher::Delegate* delegate) OVERRIDE{
- delegate_ = delegate;
- return watcher_.Start(std::string(), this);
- }
+ // PrintSystemWatcherWin::Delegate implementation.
+ virtual void OnPrinterAdded() OVERRIDE {
+ delegate_->OnPrinterAdded();
+ }
+ virtual void OnPrinterDeleted() OVERRIDE {}
+ virtual void OnPrinterChanged() OVERRIDE {}
+ virtual void OnJobChanged() OVERRIDE {}
- virtual bool StopWatching() OVERRIDE{
- bool ret = watcher_.Stop();
- delegate_ = NULL;
- return ret;
- }
+ protected:
+ virtual ~PrintServerWatcherWin() {}
- // PrintSystemWatcherWin::Delegate implementation.
- virtual void OnPrinterAdded() OVERRIDE {
- delegate_->OnPrinterAdded();
- }
- virtual void OnPrinterDeleted() OVERRIDE {}
- virtual void OnPrinterChanged() OVERRIDE {}
- virtual void OnJobChanged() OVERRIDE {}
+ private:
+ PrintSystem::PrintServerWatcher::Delegate* delegate_;
+ PrintSystemWatcherWin watcher_;
- protected:
- virtual ~PrintServerWatcherWin() {}
+ DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherWin);
+};
- private:
- PrintSystem::PrintServerWatcher::Delegate* delegate_;
- PrintSystemWatcherWin watcher_;
+class PrinterWatcherWin
+ : public PrintSystem::PrinterWatcher,
+ public PrintSystemWatcherWinDelegate {
+ public:
+ explicit PrinterWatcherWin(const std::string& printer_name)
+ : printer_name_(printer_name),
+ delegate_(NULL) {
+ }
- DISALLOW_COPY_AND_ASSIGN(PrintServerWatcherWin);
- };
+ // PrintSystem::PrinterWatcher implementation.
+ virtual bool StartWatching(
+ PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE {
+ delegate_ = delegate;
+ return watcher_.Start(printer_name_, this);
+ }
- class PrinterWatcherWin
- : public PrintSystem::PrinterWatcher,
- public PrintSystemWatcherWinDelegate {
- public:
- explicit PrinterWatcherWin(const std::string& printer_name)
- : printer_name_(printer_name),
- delegate_(NULL) {
- }
-
- // PrintSystem::PrinterWatcher implementation.
- virtual bool StartWatching(
- PrintSystem::PrinterWatcher::Delegate* delegate) OVERRIDE {
- delegate_ = delegate;
- return watcher_.Start(printer_name_, this);
- }
+ virtual bool StopWatching() OVERRIDE {
+ bool ret = watcher_.Stop();
+ delegate_ = NULL;
+ return ret;
+ }
- virtual bool StopWatching() OVERRIDE {
- bool ret = watcher_.Stop();
- delegate_ = NULL;
- return ret;
- }
+ virtual bool GetCurrentPrinterInfo(
+ printing::PrinterBasicInfo* printer_info) OVERRIDE {
+ return watcher_.GetCurrentPrinterInfo(printer_info);
+ }
- virtual bool GetCurrentPrinterInfo(
- printing::PrinterBasicInfo* printer_info) OVERRIDE {
- return watcher_.GetCurrentPrinterInfo(printer_info);
- }
+ // PrintSystemWatcherWin::Delegate implementation.
+ virtual void OnPrinterAdded() OVERRIDE {
+ NOTREACHED();
+ }
+ virtual void OnPrinterDeleted() OVERRIDE {
+ delegate_->OnPrinterDeleted();
+ }
+ virtual void OnPrinterChanged() OVERRIDE {
+ delegate_->OnPrinterChanged();
+ }
+ virtual void OnJobChanged() OVERRIDE {
+ delegate_->OnJobChanged();
+ }
- // PrintSystemWatcherWin::Delegate implementation.
- virtual void OnPrinterAdded() OVERRIDE {
- NOTREACHED();
- }
- virtual void OnPrinterDeleted() OVERRIDE {
- delegate_->OnPrinterDeleted();
- }
- virtual void OnPrinterChanged() OVERRIDE {
- delegate_->OnPrinterChanged();
- }
- virtual void OnJobChanged() OVERRIDE {
- delegate_->OnJobChanged();
- }
+ protected:
+ virtual ~PrinterWatcherWin() {}
- protected:
- virtual ~PrinterWatcherWin() {}
+ private:
+ std::string printer_name_;
+ PrintSystem::PrinterWatcher::Delegate* delegate_;
+ PrintSystemWatcherWin watcher_;
- private:
- std::string printer_name_;
- PrintSystem::PrinterWatcher::Delegate* delegate_;
- PrintSystemWatcherWin watcher_;
+ DISALLOW_COPY_AND_ASSIGN(PrinterWatcherWin);
+};
- DISALLOW_COPY_AND_ASSIGN(PrinterWatcherWin);
- };
+class JobSpoolerWin : public PrintSystem::JobSpooler {
+ public:
+ JobSpoolerWin() : core_(new Core) {}
+
+ // PrintSystem::JobSpooler implementation.
+ virtual bool Spool(const std::string& print_ticket,
+ const base::FilePath& print_data_file_path,
+ const std::string& print_data_mime_type,
+ const std::string& printer_name,
+ const std::string& job_title,
+ const std::vector<std::string>& tags,
+ JobSpooler::Delegate* delegate) OVERRIDE {
+ // TODO(gene): add tags handling.
+ scoped_refptr<printing::PrintBackend> print_backend(
+ printing::PrintBackend::CreateInstance(NULL));
+ crash_keys::ScopedPrinterInfo crash_key(
+ print_backend->GetPrinterDriverInfo(printer_name));
+ return core_->Spool(print_ticket, print_data_file_path,
+ print_data_mime_type, printer_name, job_title,
+ delegate);
+ }
+
+ protected:
+ virtual ~JobSpoolerWin() {}
- class JobSpoolerWin : public PrintSystem::JobSpooler {
+ private:
+ // We use a Core class because we want a separate RefCountedThreadSafe
+ // implementation for ServiceUtilityProcessHost::Client.
+ class Core : public ServiceUtilityProcessHost::Client,
+ public base::win::ObjectWatcher::Delegate {
public:
- JobSpoolerWin() : core_(new Core) {}
-
- // PrintSystem::JobSpooler implementation.
- virtual bool Spool(const std::string& print_ticket,
- const base::FilePath& print_data_file_path,
- const std::string& print_data_mime_type,
- const std::string& printer_name,
- const std::string& job_title,
- const std::vector<std::string>& tags,
- JobSpooler::Delegate* delegate) OVERRIDE {
- // TODO(gene): add tags handling.
+ Core()
+ : last_page_printed_(-1),
+ job_id_(-1),
+ delegate_(NULL),
+ saved_dc_(0) {
+ }
+
+ ~Core() {}
+
+ bool Spool(const std::string& print_ticket,
+ const base::FilePath& print_data_file_path,
+ const std::string& print_data_mime_type,
+ const std::string& printer_name,
+ const std::string& job_title,
+ JobSpooler::Delegate* delegate) {
scoped_refptr<printing::PrintBackend> print_backend(
printing::PrintBackend::CreateInstance(NULL));
crash_keys::ScopedPrinterInfo crash_key(
print_backend->GetPrinterDriverInfo(printer_name));
- return core_->Spool(print_ticket, print_data_file_path,
- print_data_mime_type, printer_name, job_title,
- delegate);
- }
-
- protected:
- virtual ~JobSpoolerWin() {}
-
- private:
- // We use a Core class because we want a separate RefCountedThreadSafe
- // implementation for ServiceUtilityProcessHost::Client.
- class Core : public ServiceUtilityProcessHost::Client,
- public base::win::ObjectWatcher::Delegate {
- public:
- Core()
- : last_page_printed_(-1),
- job_id_(-1),
- delegate_(NULL),
- saved_dc_(0) {
+ if (delegate_) {
+ // We are already in the process of printing.
+ NOTREACHED();
+ return false;
}
-
- ~Core() {}
-
- bool Spool(const std::string& print_ticket,
- const base::FilePath& print_data_file_path,
- const std::string& print_data_mime_type,
- const std::string& printer_name,
- const std::string& job_title,
- JobSpooler::Delegate* delegate) {
- scoped_refptr<printing::PrintBackend> print_backend(
- printing::PrintBackend::CreateInstance(NULL));
- crash_keys::ScopedPrinterInfo crash_key(
- print_backend->GetPrinterDriverInfo(printer_name));
- if (delegate_) {
- // We are already in the process of printing.
+ last_page_printed_ = -1;
+ // We only support PDF and XPS documents for now.
+ if (print_data_mime_type == "application/pdf") {
+ DevMode pt_dev_mode;
+ HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket,
+ &pt_dev_mode);
+ if (FAILED(hr)) {
NOTREACHED();
return false;
}
- last_page_printed_ = -1;
- // We only support PDF and XPS documents for now.
- if (print_data_mime_type == "application/pdf") {
- DevMode pt_dev_mode;
- HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket,
- &pt_dev_mode);
- if (FAILED(hr)) {
- NOTREACHED();
- return false;
- }
-
- HDC dc = CreateDC(L"WINSPOOL", UTF8ToWide(printer_name).c_str(),
- NULL, pt_dev_mode.dm_);
- if (!dc) {
- NOTREACHED();
- return false;
- }
- hr = E_FAIL;
- DOCINFO di = {0};
- di.cbSize = sizeof(DOCINFO);
- string16 doc_name = UTF8ToUTF16(job_title);
- DCHECK(printing::SimplifyDocumentTitle(doc_name) == doc_name);
- di.lpszDocName = doc_name.c_str();
- job_id_ = StartDoc(dc, &di);
- if (job_id_ <= 0)
- return false;
-
- printer_dc_.Set(dc);
- saved_dc_ = SaveDC(printer_dc_.Get());
- print_data_file_path_ = print_data_file_path;
- delegate_ = delegate;
- RenderNextPDFPages();
- } else if (print_data_mime_type == "application/vnd.ms-xpsdocument") {
- bool ret = PrintXPSDocument(printer_name,
- job_title,
- print_data_file_path,
- print_ticket);
- if (ret)
- delegate_ = delegate;
- return ret;
- } else {
+
+ HDC dc = CreateDC(L"WINSPOOL", UTF8ToWide(printer_name).c_str(),
+ NULL, pt_dev_mode.dm_);
+ if (!dc) {
NOTREACHED();
return false;
}
- return true;
- }
-
- void PreparePageDCForPrinting(HDC, double scale_factor) {
- SetGraphicsMode(printer_dc_.Get(), GM_ADVANCED);
- // Setup the matrix to translate and scale to the right place. Take in
- // account the scale factor.
- // Note that the printing output is relative to printable area of
- // the page. That is 0,0 is offset by PHYSICALOFFSETX/Y from the page.
- int offset_x = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETX);
- int offset_y = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETY);
- XFORM xform = {0};
- xform.eDx = static_cast<float>(-offset_x);
- xform.eDy = static_cast<float>(-offset_y);
- xform.eM11 = xform.eM22 = 1.0 / scale_factor;
- SetWorldTransform(printer_dc_.Get(), &xform);
- }
+ hr = E_FAIL;
+ DOCINFO di = {0};
+ di.cbSize = sizeof(DOCINFO);
+ string16 doc_name = UTF8ToUTF16(job_title);
+ DCHECK(printing::SimplifyDocumentTitle(doc_name) == doc_name);
+ di.lpszDocName = doc_name.c_str();
+ job_id_ = StartDoc(dc, &di);
+ if (job_id_ <= 0)
+ return false;
- // ServiceUtilityProcessHost::Client implementation.
- virtual void OnRenderPDFPagesToMetafileSucceeded(
- const printing::Emf& metafile,
- int highest_rendered_page_number,
- double scale_factor) OVERRIDE {
- PreparePageDCForPrinting(printer_dc_.Get(), scale_factor);
- metafile.SafePlayback(printer_dc_.Get());
- bool done_printing = (highest_rendered_page_number !=
- last_page_printed_ + kPageCountPerBatch);
- last_page_printed_ = highest_rendered_page_number;
- if (done_printing)
- PrintJobDone();
- else
- RenderNextPDFPages();
+ printer_dc_.Set(dc);
+ saved_dc_ = SaveDC(printer_dc_.Get());
+ print_data_file_path_ = print_data_file_path;
+ delegate_ = delegate;
+ RenderNextPDFPages();
+ } else if (print_data_mime_type == "application/vnd.ms-xpsdocument") {
+ bool ret = PrintXPSDocument(printer_name,
+ job_title,
+ print_data_file_path,
+ print_ticket);
+ if (ret)
+ delegate_ = delegate;
+ return ret;
+ } else {
+ NOTREACHED();
+ return false;
}
+ return true;
+ }
- // base::win::ObjectWatcher::Delegate implementation.
- virtual void OnObjectSignaled(HANDLE object) OVERRIDE {
- DCHECK(xps_print_job_);
- DCHECK(object == job_progress_event_.Get());
- ResetEvent(job_progress_event_.Get());
- if (!delegate_)
- return;
- XPS_JOB_STATUS job_status = {0};
- xps_print_job_->GetJobStatus(&job_status);
- bool done = false;
- if ((job_status.completion == XPS_JOB_CANCELLED) ||
- (job_status.completion == XPS_JOB_FAILED)) {
- delegate_->OnJobSpoolFailed();
- done = true;
- } else if (job_status.jobId ||
- (job_status.completion == XPS_JOB_COMPLETED)) {
- // Note: In the case of the XPS document being printed to the
- // Microsoft XPS Document Writer, it seems to skip spooling the job
- // and goes to the completed state without ever assigning a job id.
- delegate_->OnJobSpoolSucceeded(job_status.jobId);
- done = true;
- } else {
- job_progress_watcher_.StopWatching();
- job_progress_watcher_.StartWatching(job_progress_event_.Get(), this);
- }
- if (done)
- com_initializer_.reset();
- }
+ void PreparePageDCForPrinting(HDC, double scale_factor) {
+ SetGraphicsMode(printer_dc_.Get(), GM_ADVANCED);
+ // Setup the matrix to translate and scale to the right place. Take in
+ // account the scale factor.
+ // Note that the printing output is relative to printable area of
+ // the page. That is 0,0 is offset by PHYSICALOFFSETX/Y from the page.
+ int offset_x = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETX);
+ int offset_y = ::GetDeviceCaps(printer_dc_.Get(), PHYSICALOFFSETY);
+ XFORM xform = {0};
+ xform.eDx = static_cast<float>(-offset_x);
+ xform.eDy = static_cast<float>(-offset_y);
+ xform.eM11 = xform.eM22 = 1.0 / scale_factor;
+ SetWorldTransform(printer_dc_.Get(), &xform);
+ }
- virtual void OnRenderPDFPagesToMetafileFailed() OVERRIDE {
+ // ServiceUtilityProcessHost::Client implementation.
+ virtual void OnRenderPDFPagesToMetafileSucceeded(
+ const printing::Emf& metafile,
+ int highest_rendered_page_number,
+ double scale_factor) OVERRIDE {
+ PreparePageDCForPrinting(printer_dc_.Get(), scale_factor);
+ metafile.SafePlayback(printer_dc_.Get());
+ bool done_printing = (highest_rendered_page_number !=
+ last_page_printed_ + kPageCountPerBatch);
+ last_page_printed_ = highest_rendered_page_number;
+ if (done_printing)
PrintJobDone();
- }
+ else
+ RenderNextPDFPages();
+ }
- virtual void OnChildDied() OVERRIDE {
- PrintJobDone();
+ // base::win::ObjectWatcher::Delegate implementation.
+ virtual void OnObjectSignaled(HANDLE object) OVERRIDE {
+ DCHECK(xps_print_job_);
+ DCHECK(object == job_progress_event_.Get());
+ ResetEvent(job_progress_event_.Get());
+ if (!delegate_)
+ return;
+ XPS_JOB_STATUS job_status = {0};
+ xps_print_job_->GetJobStatus(&job_status);
+ bool done = false;
+ if ((job_status.completion == XPS_JOB_CANCELLED) ||
+ (job_status.completion == XPS_JOB_FAILED)) {
+ delegate_->OnJobSpoolFailed();
+ done = true;
+ } else if (job_status.jobId ||
+ (job_status.completion == XPS_JOB_COMPLETED)) {
+ // Note: In the case of the XPS document being printed to the
+ // Microsoft XPS Document Writer, it seems to skip spooling the job
+ // and goes to the completed state without ever assigning a job id.
+ delegate_->OnJobSpoolSucceeded(job_status.jobId);
+ done = true;
+ } else {
+ job_progress_watcher_.StopWatching();
+ job_progress_watcher_.StartWatching(job_progress_event_.Get(), this);
}
+ if (done)
+ com_initializer_.reset();
+ }
- private:
- // Helper class to allow PrintXPSDocument() to have multiple exits.
- class PrintJobCanceler {
- public:
- explicit PrintJobCanceler(
- base::win::ScopedComPtr<IXpsPrintJob>* job_ptr)
- : job_ptr_(job_ptr) {
- }
- ~PrintJobCanceler() {
- if (job_ptr_ && *job_ptr_) {
- (*job_ptr_)->Cancel();
- job_ptr_->Release();
- }
- }
-
- void reset() { job_ptr_ = NULL; }
-
- private:
- base::win::ScopedComPtr<IXpsPrintJob>* job_ptr_;
-
- DISALLOW_COPY_AND_ASSIGN(PrintJobCanceler);
- };
+ virtual void OnRenderPDFPagesToMetafileFailed() OVERRIDE {
+ PrintJobDone();
+ }
- void PrintJobDone() {
- // If there is no delegate, then there is nothing pending to process.
- if (!delegate_)
- return;
- RestoreDC(printer_dc_.Get(), saved_dc_);
- EndDoc(printer_dc_.Get());
- if (-1 == last_page_printed_) {
- delegate_->OnJobSpoolFailed();
- } else {
- delegate_->OnJobSpoolSucceeded(job_id_);
- }
- delegate_ = NULL;
- }
+ virtual void OnChildDied() OVERRIDE {
+ PrintJobDone();
+ }
- void RenderNextPDFPages() {
- printing::PageRange range;
- // Render 10 pages at a time.
- range.from = last_page_printed_ + 1;
- range.to = last_page_printed_ + kPageCountPerBatch;
- std::vector<printing::PageRange> page_ranges;
- page_ranges.push_back(range);
-
- int printer_dpi = ::GetDeviceCaps(printer_dc_.Get(), LOGPIXELSX);
- int dc_width = GetDeviceCaps(printer_dc_.Get(), PHYSICALWIDTH);
- int dc_height = GetDeviceCaps(printer_dc_.Get(), PHYSICALHEIGHT);
- gfx::Rect render_area(0, 0, dc_width, dc_height);
- g_service_process->io_thread()->message_loop_proxy()->PostTask(
- FROM_HERE,
- base::Bind(&JobSpoolerWin::Core::RenderPDFPagesInSandbox, this,
- print_data_file_path_, render_area, printer_dpi,
- page_ranges, base::MessageLoopProxy::current()));
+ private:
+ // Helper class to allow PrintXPSDocument() to have multiple exits.
+ class PrintJobCanceler {
+ public:
+ explicit PrintJobCanceler(
+ base::win::ScopedComPtr<IXpsPrintJob>* job_ptr)
+ : job_ptr_(job_ptr) {
}
-
- // Called on the service process IO thread.
- void RenderPDFPagesInSandbox(
- const base::FilePath& pdf_path, const gfx::Rect& render_area,
- int render_dpi, const std::vector<printing::PageRange>& page_ranges,
- const scoped_refptr<base::MessageLoopProxy>&
- client_message_loop_proxy) {
- DCHECK(g_service_process->io_thread()->message_loop_proxy()->
- BelongsToCurrentThread());
- scoped_ptr<ServiceUtilityProcessHost> utility_host(
- new ServiceUtilityProcessHost(this, client_message_loop_proxy));
- // TODO(gene): For now we disabling autorotation for CloudPrinting.
- // Landscape/Portrait setting is passed in the print ticket and
- // server is generating portrait PDF always.
- // We should enable autorotation once server will be able to generate
- // PDF that matches paper size and orientation.
- if (utility_host->StartRenderPDFPagesToMetafile(
- pdf_path,
- printing::PdfRenderSettings(render_area, render_dpi, false),
- page_ranges)) {
- // The object will self-destruct when the child process dies.
- utility_host.release();
+ ~PrintJobCanceler() {
+ if (job_ptr_ && *job_ptr_) {
+ (*job_ptr_)->Cancel();
+ job_ptr_->Release();
}
}
- bool PrintXPSDocument(const std::string& printer_name,
- const std::string& job_title,
- const base::FilePath& print_data_file_path,
- const std::string& print_ticket) {
- if (!printing::XPSPrintModule::Init())
- return false;
-
- job_progress_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL));
- if (!job_progress_event_.Get())
- return false;
-
- scoped_ptr<base::win::ScopedCOMInitializer> com_initializer(
- new base::win::ScopedCOMInitializer(
- base::win::ScopedCOMInitializer::kMTA));
- PrintJobCanceler job_canceler(&xps_print_job_);
- base::win::ScopedComPtr<IXpsPrintJobStream> doc_stream;
- base::win::ScopedComPtr<IXpsPrintJobStream> print_ticket_stream;
- if (FAILED(printing::XPSPrintModule::StartXpsPrintJob(
- UTF8ToWide(printer_name).c_str(), UTF8ToWide(job_title).c_str(),
- NULL, job_progress_event_.Get(), NULL, NULL, NULL,
- xps_print_job_.Receive(), doc_stream.Receive(),
- print_ticket_stream.Receive())))
- return false;
-
- ULONG print_bytes_written = 0;
- if (FAILED(print_ticket_stream->Write(print_ticket.c_str(),
- print_ticket.length(),
- &print_bytes_written)))
- return false;
- DCHECK_EQ(print_ticket.length(), print_bytes_written);
- if (FAILED(print_ticket_stream->Close()))
- return false;
-
- std::string document_data;
- base::ReadFileToString(print_data_file_path, &document_data);
- ULONG doc_bytes_written = 0;
- if (FAILED(doc_stream->Write(document_data.c_str(),
- document_data.length(),
- &doc_bytes_written)))
- return false;
- DCHECK_EQ(document_data.length(), doc_bytes_written);
- if (FAILED(doc_stream->Close()))
- return false;
+ void reset() { job_ptr_ = NULL; }
- job_progress_watcher_.StartWatching(job_progress_event_.Get(), this);
- com_initializer_.swap(com_initializer);
- job_canceler.reset();
- return true;
- }
+ private:
+ base::win::ScopedComPtr<IXpsPrintJob>* job_ptr_;
- // Some Cairo-generated PDFs from Chrome OS result in huge metafiles.
- // So the PageCountPerBatch is set to 1 for now.
- // TODO(sanjeevr): Figure out a smarter way to determine the pages per
- // batch. Filed a bug to track this at
- // http://code.google.com/p/chromium/issues/detail?id=57350.
- static const int kPageCountPerBatch = 1;
- int last_page_printed_;
- PlatformJobId job_id_;
- PrintSystem::JobSpooler::Delegate* delegate_;
- int saved_dc_;
- base::win::ScopedCreateDC printer_dc_;
- base::FilePath print_data_file_path_;
- base::win::ScopedHandle job_progress_event_;
- base::win::ObjectWatcher job_progress_watcher_;
- base::win::ScopedComPtr<IXpsPrintJob> xps_print_job_;
- scoped_ptr<base::win::ScopedCOMInitializer> com_initializer_;
-
- DISALLOW_COPY_AND_ASSIGN(Core);
+ DISALLOW_COPY_AND_ASSIGN(PrintJobCanceler);
};
- scoped_refptr<Core> core_;
- DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin);
- };
-
- // A helper class to handle the response from the utility process to the
- // request to fetch printer capabilities and defaults.
- class PrinterCapsHandler : public ServiceUtilityProcessHost::Client {
- public:
- PrinterCapsHandler(
- const std::string& printer_name,
- const PrinterCapsAndDefaultsCallback& callback)
- : printer_name_(printer_name), callback_(callback) {
- }
-
- // ServiceUtilityProcessHost::Client implementation.
- virtual void OnChildDied() OVERRIDE {
- OnGetPrinterCapsAndDefaultsFailed(printer_name_);
- }
-
- virtual void OnGetPrinterCapsAndDefaultsSucceeded(
- const std::string& printer_name,
- const printing::PrinterCapsAndDefaults& caps_and_defaults) OVERRIDE {
- callback_.Run(true, printer_name, caps_and_defaults);
- callback_.Reset();
- Release();
- }
-
- virtual void OnGetPrinterCapsAndDefaultsFailed(
- const std::string& printer_name) OVERRIDE {
- printing::PrinterCapsAndDefaults caps_and_defaults;
- callback_.Run(false, printer_name, caps_and_defaults);
- callback_.Reset();
- Release();
+ void PrintJobDone() {
+ // If there is no delegate, then there is nothing pending to process.
+ if (!delegate_)
+ return;
+ RestoreDC(printer_dc_.Get(), saved_dc_);
+ EndDoc(printer_dc_.Get());
+ if (-1 == last_page_printed_) {
+ delegate_->OnJobSpoolFailed();
+ } else {
+ delegate_->OnJobSpoolSucceeded(job_id_);
+ }
+ delegate_ = NULL;
}
- void Start() {
+ void RenderNextPDFPages() {
+ printing::PageRange range;
+ // Render 10 pages at a time.
+ range.from = last_page_printed_ + 1;
+ range.to = last_page_printed_ + kPageCountPerBatch;
+ std::vector<printing::PageRange> page_ranges;
+ page_ranges.push_back(range);
+
+ int printer_dpi = ::GetDeviceCaps(printer_dc_.Get(), LOGPIXELSX);
+ int dc_width = GetDeviceCaps(printer_dc_.Get(), PHYSICALWIDTH);
+ int dc_height = GetDeviceCaps(printer_dc_.Get(), PHYSICALHEIGHT);
+ gfx::Rect render_area(0, 0, dc_width, dc_height);
g_service_process->io_thread()->message_loop_proxy()->PostTask(
FROM_HERE,
- base::Bind(&PrinterCapsHandler::GetPrinterCapsAndDefaultsImpl, this,
- base::MessageLoopProxy::current()));
+ base::Bind(&JobSpoolerWin::Core::RenderPDFPagesInSandbox, this,
+ print_data_file_path_, render_area, printer_dpi,
+ page_ranges, base::MessageLoopProxy::current()));
}
- private:
- // Called on the service process IO thread.
- void GetPrinterCapsAndDefaultsImpl(
+ // Called on the service process IO thread.
+ void RenderPDFPagesInSandbox(
+ const base::FilePath& pdf_path, const gfx::Rect& render_area,
+ int render_dpi, const std::vector<printing::PageRange>& page_ranges,
const scoped_refptr<base::MessageLoopProxy>&
client_message_loop_proxy) {
DCHECK(g_service_process->io_thread()->message_loop_proxy()->
BelongsToCurrentThread());
scoped_ptr<ServiceUtilityProcessHost> utility_host(
new ServiceUtilityProcessHost(this, client_message_loop_proxy));
- if (utility_host->StartGetPrinterCapsAndDefaults(printer_name_)) {
+ // TODO(gene): For now we disabling autorotation for CloudPrinting.
+ // Landscape/Portrait setting is passed in the print ticket and
+ // server is generating portrait PDF always.
+ // We should enable autorotation once server will be able to generate
+ // PDF that matches paper size and orientation.
+ if (utility_host->StartRenderPDFPagesToMetafile(
+ pdf_path,
+ printing::PdfRenderSettings(render_area, render_dpi, false),
+ page_ranges)) {
// The object will self-destruct when the child process dies.
utility_host.release();
- } else {
- client_message_loop_proxy->PostTask(
- FROM_HERE,
- base::Bind(&PrinterCapsHandler::OnGetPrinterCapsAndDefaultsFailed,
- this, printer_name_));
}
}
- std::string printer_name_;
- PrinterCapsAndDefaultsCallback callback_;
+ bool PrintXPSDocument(const std::string& printer_name,
+ const std::string& job_title,
+ const base::FilePath& print_data_file_path,
+ const std::string& print_ticket) {
+ if (!printing::XPSPrintModule::Init())
+ return false;
+
+ job_progress_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL));
+ if (!job_progress_event_.Get())
+ return false;
+
+ scoped_ptr<base::win::ScopedCOMInitializer> com_initializer(
+ new base::win::ScopedCOMInitializer(
+ base::win::ScopedCOMInitializer::kMTA));
+ PrintJobCanceler job_canceler(&xps_print_job_);
+ base::win::ScopedComPtr<IXpsPrintJobStream> doc_stream;
+ base::win::ScopedComPtr<IXpsPrintJobStream> print_ticket_stream;
+ if (FAILED(printing::XPSPrintModule::StartXpsPrintJob(
+ UTF8ToWide(printer_name).c_str(), UTF8ToWide(job_title).c_str(),
+ NULL, job_progress_event_.Get(), NULL, NULL, NULL,
+ xps_print_job_.Receive(), doc_stream.Receive(),
+ print_ticket_stream.Receive())))
+ return false;
+
+ ULONG print_bytes_written = 0;
+ if (FAILED(print_ticket_stream->Write(print_ticket.c_str(),
+ print_ticket.length(),
+ &print_bytes_written)))
+ return false;
+ DCHECK_EQ(print_ticket.length(), print_bytes_written);
+ if (FAILED(print_ticket_stream->Close()))
+ return false;
+
+ std::string document_data;
+ base::ReadFileToString(print_data_file_path, &document_data);
+ ULONG doc_bytes_written = 0;
+ if (FAILED(doc_stream->Write(document_data.c_str(),
+ document_data.length(),
+ &doc_bytes_written)))
+ return false;
+ DCHECK_EQ(document_data.length(), doc_bytes_written);
+ if (FAILED(doc_stream->Close()))
+ return false;
+
+ job_progress_watcher_.StartWatching(job_progress_event_.Get(), this);
+ com_initializer_.swap(com_initializer);
+ job_canceler.reset();
+ return true;
+ }
+
+ // Some Cairo-generated PDFs from Chrome OS result in huge metafiles.
+ // So the PageCountPerBatch is set to 1 for now.
+ // TODO(sanjeevr): Figure out a smarter way to determine the pages per
+ // batch. Filed a bug to track this at
+ // http://code.google.com/p/chromium/issues/detail?id=57350.
+ static const int kPageCountPerBatch = 1;
+ int last_page_printed_;
+ PlatformJobId job_id_;
+ PrintSystem::JobSpooler::Delegate* delegate_;
+ int saved_dc_;
+ base::win::ScopedCreateDC printer_dc_;
+ base::FilePath print_data_file_path_;
+ base::win::ScopedHandle job_progress_event_;
+ base::win::ObjectWatcher job_progress_watcher_;
+ base::win::ScopedComPtr<IXpsPrintJob> xps_print_job_;
+ scoped_ptr<base::win::ScopedCOMInitializer> com_initializer_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
};
+ scoped_refptr<Core> core_;
+
+ DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin);
+};
+
+// A helper class to handle the response from the utility process to the
+// request to fetch printer capabilities and defaults.
+class PrinterCapsHandler : public ServiceUtilityProcessHost::Client {
+ public:
+ PrinterCapsHandler(
+ const std::string& printer_name,
+ const PrintSystem::PrinterCapsAndDefaultsCallback& callback)
+ : printer_name_(printer_name), callback_(callback) {
+ }
+
+ // ServiceUtilityProcessHost::Client implementation.
+ virtual void OnChildDied() OVERRIDE {
+ OnGetPrinterCapsAndDefaultsFailed(printer_name_);
+ }
+
+ virtual void OnGetPrinterCapsAndDefaultsSucceeded(
+ const std::string& printer_name,
+ const printing::PrinterCapsAndDefaults& caps_and_defaults) OVERRIDE {
+ callback_.Run(true, printer_name, caps_and_defaults);
+ callback_.Reset();
+ Release();
+ }
+
+ virtual void OnGetPrinterCapsAndDefaultsFailed(
+ const std::string& printer_name) OVERRIDE {
+ printing::PrinterCapsAndDefaults caps_and_defaults;
+ callback_.Run(false, printer_name, caps_and_defaults);
+ callback_.Reset();
+ Release();
+ }
+
+ void Start() {
+ g_service_process->io_thread()->message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&PrinterCapsHandler::GetPrinterCapsAndDefaultsImpl, this,
+ base::MessageLoopProxy::current()));
+ }
+
+ private:
+ // Called on the service process IO thread.
+ void GetPrinterCapsAndDefaultsImpl(
+ const scoped_refptr<base::MessageLoopProxy>&
+ client_message_loop_proxy) {
+ DCHECK(g_service_process->io_thread()->message_loop_proxy()->
+ BelongsToCurrentThread());
+ scoped_ptr<ServiceUtilityProcessHost> utility_host(
+ new ServiceUtilityProcessHost(this, client_message_loop_proxy));
+ if (utility_host->StartGetPrinterCapsAndDefaults(printer_name_)) {
+ // The object will self-destruct when the child process dies.
+ utility_host.release();
+ } else {
+ client_message_loop_proxy->PostTask(
+ FROM_HERE,
+ base::Bind(&PrinterCapsHandler::OnGetPrinterCapsAndDefaultsFailed,
+ this, printer_name_));
+ }
+ }
+ std::string printer_name_;
+ PrintSystem::PrinterCapsAndDefaultsCallback callback_;
+};
+
+class PrintSystemWin : public PrintSystem {
+ public:
+ PrintSystemWin();
+ // PrintSystem implementation.
+ virtual PrintSystemResult Init() OVERRIDE;
+ virtual PrintSystem::PrintSystemResult EnumeratePrinters(
+ printing::PrinterList* printer_list) OVERRIDE;
+ virtual void GetPrinterCapsAndDefaults(
+ const std::string& printer_name,
+ const PrinterCapsAndDefaultsCallback& callback) OVERRIDE;
+ virtual bool IsValidPrinter(const std::string& printer_name) OVERRIDE;
+ virtual bool ValidatePrintTicket(
+ const std::string& printer_name,
+ const std::string& print_ticket_data) OVERRIDE;
+ virtual bool GetJobDetails(const std::string& printer_name,
+ PlatformJobId job_id,
+ PrintJobDetails *job_details) OVERRIDE;
virtual PrintSystem::PrintServerWatcher* CreatePrintServerWatcher() OVERRIDE;
virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher(
const std::string& printer_name) OVERRIDE;
@@ -897,6 +891,7 @@ std::string PrintSystemWin::GetSupportedMimeTypes() {
return "application/pdf";
}
+} // namespace
scoped_refptr<PrintSystem> PrintSystem::CreateInstance(
const base::DictionaryValue* print_system_settings) {