| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/service/cloud_print/print_system.h" | 5 #include "chrome/service/cloud_print/print_system.h" |
| 6 | 6 |
| 7 #include <objidl.h> | 7 #include <objidl.h> |
| 8 #include <winspool.h> | 8 #include <winspool.h> |
| 9 #include <xpsprint.h> | 9 #include <xpsprint.h> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "base/win/object_watcher.h" | 16 #include "base/win/object_watcher.h" |
| 17 #include "base/win/scoped_bstr.h" | 17 #include "base/win/scoped_bstr.h" |
| 18 #include "base/win/scoped_com_initializer.h" |
| 18 #include "base/win/scoped_comptr.h" | 19 #include "base/win/scoped_comptr.h" |
| 19 #include "base/win/scoped_hdc.h" | 20 #include "base/win/scoped_hdc.h" |
| 20 #include "chrome/common/child_process_logging.h" | 21 #include "chrome/common/child_process_logging.h" |
| 21 #include "chrome/service/service_process.h" | 22 #include "chrome/service/service_process.h" |
| 22 #include "chrome/service/service_utility_process_host.h" | 23 #include "chrome/service/service_utility_process_host.h" |
| 23 #include "grit/generated_resources.h" | 24 #include "grit/generated_resources.h" |
| 24 #include "printing/backend/print_backend.h" | 25 #include "printing/backend/print_backend.h" |
| 25 #include "printing/backend/print_backend_consts.h" | 26 #include "printing/backend/print_backend_consts.h" |
| 26 #include "printing/backend/win_helper.h" | 27 #include "printing/backend/win_helper.h" |
| 27 #include "printing/emf_win.h" | 28 #include "printing/emf_win.h" |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 private: | 383 private: |
| 383 // We use a Core class because we want a separate RefCountedThreadSafe | 384 // We use a Core class because we want a separate RefCountedThreadSafe |
| 384 // implementation for ServiceUtilityProcessHost::Client. | 385 // implementation for ServiceUtilityProcessHost::Client. |
| 385 class Core : public ServiceUtilityProcessHost::Client, | 386 class Core : public ServiceUtilityProcessHost::Client, |
| 386 public base::win::ObjectWatcher::Delegate { | 387 public base::win::ObjectWatcher::Delegate { |
| 387 public: | 388 public: |
| 388 Core() | 389 Core() |
| 389 : last_page_printed_(-1), | 390 : last_page_printed_(-1), |
| 390 job_id_(-1), | 391 job_id_(-1), |
| 391 delegate_(NULL), | 392 delegate_(NULL), |
| 392 saved_dc_(0), | 393 saved_dc_(0) { |
| 393 should_couninit_(false) { | |
| 394 } | 394 } |
| 395 | 395 |
| 396 ~Core() {} | 396 ~Core() {} |
| 397 | 397 |
| 398 bool Spool(const std::string& print_ticket, | 398 bool Spool(const std::string& print_ticket, |
| 399 const FilePath& print_data_file_path, | 399 const FilePath& print_data_file_path, |
| 400 const std::string& print_data_mime_type, | 400 const std::string& print_data_mime_type, |
| 401 const std::string& printer_name, | 401 const std::string& printer_name, |
| 402 const std::string& job_title, | 402 const std::string& job_title, |
| 403 JobSpooler::Delegate* delegate) { | 403 JobSpooler::Delegate* delegate) { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 (job_status.completion == XPS_JOB_COMPLETED)) { | 507 (job_status.completion == XPS_JOB_COMPLETED)) { |
| 508 // Note: In the case of the XPS document being printed to the | 508 // Note: In the case of the XPS document being printed to the |
| 509 // Microsoft XPS Document Writer, it seems to skip spooling the job | 509 // Microsoft XPS Document Writer, it seems to skip spooling the job |
| 510 // and goes to the completed state without ever assigning a job id. | 510 // and goes to the completed state without ever assigning a job id. |
| 511 delegate_->OnJobSpoolSucceeded(job_status.jobId); | 511 delegate_->OnJobSpoolSucceeded(job_status.jobId); |
| 512 done = true; | 512 done = true; |
| 513 } else { | 513 } else { |
| 514 job_progress_watcher_.StopWatching(); | 514 job_progress_watcher_.StopWatching(); |
| 515 job_progress_watcher_.StartWatching(job_progress_event_.Get(), this); | 515 job_progress_watcher_.StartWatching(job_progress_event_.Get(), this); |
| 516 } | 516 } |
| 517 if (done && should_couninit_) { | 517 if (done) |
| 518 CoUninitialize(); | 518 com_initializer_.reset(); |
| 519 should_couninit_ = false; | |
| 520 } | |
| 521 } | 519 } |
| 522 | 520 |
| 523 virtual void OnRenderPDFPagesToMetafileFailed() OVERRIDE { | 521 virtual void OnRenderPDFPagesToMetafileFailed() OVERRIDE { |
| 524 PrintJobDone(); | 522 PrintJobDone(); |
| 525 } | 523 } |
| 526 | 524 |
| 527 virtual void OnChildDied() OVERRIDE { | 525 virtual void OnChildDied() OVERRIDE { |
| 528 PrintJobDone(); | 526 PrintJobDone(); |
| 529 } | 527 } |
| 530 | 528 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 | 586 |
| 589 bool PrintXPSDocument(const std::string& printer_name, | 587 bool PrintXPSDocument(const std::string& printer_name, |
| 590 const std::string& job_title, | 588 const std::string& job_title, |
| 591 const FilePath& print_data_file_path, | 589 const FilePath& print_data_file_path, |
| 592 const std::string& print_ticket) { | 590 const std::string& print_ticket) { |
| 593 if (!printing::XPSPrintModule::Init()) | 591 if (!printing::XPSPrintModule::Init()) |
| 594 return false; | 592 return false; |
| 595 job_progress_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); | 593 job_progress_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); |
| 596 if (!job_progress_event_.Get()) | 594 if (!job_progress_event_.Get()) |
| 597 return false; | 595 return false; |
| 598 should_couninit_ = SUCCEEDED(CoInitializeEx(NULL, | 596 scoped_ptr<base::win::ScopedCOMInitializer> com_initializer( |
| 599 COINIT_MULTITHREADED)); | 597 new base::win::ScopedCOMInitializer( |
| 598 base::win::ScopedCOMInitializer::kMTA)); |
| 600 base::win::ScopedComPtr<IXpsPrintJobStream> doc_stream; | 599 base::win::ScopedComPtr<IXpsPrintJobStream> doc_stream; |
| 601 base::win::ScopedComPtr<IXpsPrintJobStream> print_ticket_stream; | 600 base::win::ScopedComPtr<IXpsPrintJobStream> print_ticket_stream; |
| 602 bool ret = false; | 601 bool ret = false; |
| 603 // Use nested SUCCEEDED checks because we want a common return point. | 602 // Use nested SUCCEEDED checks because we want a common return point. |
| 604 if (SUCCEEDED(printing::XPSPrintModule::StartXpsPrintJob( | 603 if (SUCCEEDED(printing::XPSPrintModule::StartXpsPrintJob( |
| 605 UTF8ToWide(printer_name).c_str(), | 604 UTF8ToWide(printer_name).c_str(), |
| 606 UTF8ToWide(job_title).c_str(), | 605 UTF8ToWide(job_title).c_str(), |
| 607 NULL, | 606 NULL, |
| 608 job_progress_event_.Get(), | 607 job_progress_event_.Get(), |
| 609 NULL, | 608 NULL, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 621 std::string document_data; | 620 std::string document_data; |
| 622 file_util::ReadFileToString(print_data_file_path, &document_data); | 621 file_util::ReadFileToString(print_data_file_path, &document_data); |
| 623 bytes_written = 0; | 622 bytes_written = 0; |
| 624 if (SUCCEEDED(doc_stream->Write(document_data.c_str(), | 623 if (SUCCEEDED(doc_stream->Write(document_data.c_str(), |
| 625 document_data.length(), | 624 document_data.length(), |
| 626 &bytes_written))) { | 625 &bytes_written))) { |
| 627 DCHECK(bytes_written == document_data.length()); | 626 DCHECK(bytes_written == document_data.length()); |
| 628 if (SUCCEEDED(doc_stream->Close())) { | 627 if (SUCCEEDED(doc_stream->Close())) { |
| 629 job_progress_watcher_.StartWatching(job_progress_event_.Get(), | 628 job_progress_watcher_.StartWatching(job_progress_event_.Get(), |
| 630 this); | 629 this); |
| 630 com_initializer_.swap(com_initializer); |
| 631 ret = true; | 631 ret = true; |
| 632 } | 632 } |
| 633 } | 633 } |
| 634 } | 634 } |
| 635 } | 635 } |
| 636 } | 636 } |
| 637 if (!ret) { | 637 if (!ret) { |
| 638 if (xps_print_job_) { | 638 if (xps_print_job_) { |
| 639 xps_print_job_->Cancel(); | 639 xps_print_job_->Cancel(); |
| 640 xps_print_job_.Release(); | 640 xps_print_job_.Release(); |
| 641 } | 641 } |
| 642 if (should_couninit_) { | |
| 643 CoUninitialize(); | |
| 644 should_couninit_ = false; | |
| 645 } | |
| 646 } | 642 } |
| 647 return ret; | 643 return ret; |
| 648 } | 644 } |
| 649 | 645 |
| 650 // Some Cairo-generated PDFs from Chrome OS result in huge metafiles. | 646 // Some Cairo-generated PDFs from Chrome OS result in huge metafiles. |
| 651 // So the PageCountPerBatch is set to 1 for now. | 647 // So the PageCountPerBatch is set to 1 for now. |
| 652 // TODO(sanjeevr): Figure out a smarter way to determine the pages per | 648 // TODO(sanjeevr): Figure out a smarter way to determine the pages per |
| 653 // batch. Filed a bug to track this at | 649 // batch. Filed a bug to track this at |
| 654 // http://code.google.com/p/chromium/issues/detail?id=57350. | 650 // http://code.google.com/p/chromium/issues/detail?id=57350. |
| 655 static const int kPageCountPerBatch = 1; | 651 static const int kPageCountPerBatch = 1; |
| 656 int last_page_printed_; | 652 int last_page_printed_; |
| 657 PlatformJobId job_id_; | 653 PlatformJobId job_id_; |
| 658 PrintSystem::JobSpooler::Delegate* delegate_; | 654 PrintSystem::JobSpooler::Delegate* delegate_; |
| 659 int saved_dc_; | 655 int saved_dc_; |
| 660 base::win::ScopedCreateDC printer_dc_; | 656 base::win::ScopedCreateDC printer_dc_; |
| 661 FilePath print_data_file_path_; | 657 FilePath print_data_file_path_; |
| 662 base::win::ScopedHandle job_progress_event_; | 658 base::win::ScopedHandle job_progress_event_; |
| 663 base::win::ObjectWatcher job_progress_watcher_; | 659 base::win::ObjectWatcher job_progress_watcher_; |
| 664 base::win::ScopedComPtr<IXpsPrintJob> xps_print_job_; | 660 base::win::ScopedComPtr<IXpsPrintJob> xps_print_job_; |
| 665 bool should_couninit_; | 661 scoped_ptr<base::win::ScopedCOMInitializer> com_initializer_; |
| 666 | 662 |
| 667 DISALLOW_COPY_AND_ASSIGN(Core); | 663 DISALLOW_COPY_AND_ASSIGN(Core); |
| 668 }; | 664 }; |
| 669 scoped_refptr<Core> core_; | 665 scoped_refptr<Core> core_; |
| 670 | 666 |
| 671 DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin); | 667 DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin); |
| 672 }; | 668 }; |
| 673 | 669 |
| 674 // A helper class to handle the response from the utility process to the | 670 // A helper class to handle the response from the utility process to the |
| 675 // request to fetch printer capabilities and defaults. | 671 // request to fetch printer capabilities and defaults. |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 return "application/pdf"; | 885 return "application/pdf"; |
| 890 } | 886 } |
| 891 | 887 |
| 892 | 888 |
| 893 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( | 889 scoped_refptr<PrintSystem> PrintSystem::CreateInstance( |
| 894 const base::DictionaryValue* print_system_settings) { | 890 const base::DictionaryValue* print_system_settings) { |
| 895 return new PrintSystemWin; | 891 return new PrintSystemWin; |
| 896 } | 892 } |
| 897 | 893 |
| 898 } // namespace cloud_print | 894 } // namespace cloud_print |
| OLD | NEW |