123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef CHROME_BROWSER_PRINTING_PRINT_JOB_H_
- #define CHROME_BROWSER_PRINTING_PRINT_JOB_H_
- #include <memory>
- #include <vector>
- #include "base/macros.h"
- #include "base/memory/weak_ptr.h"
- #include "build/build_config.h"
- #include "chrome/browser/printing/print_job_worker_owner.h"
- #include "content/public/browser/notification_observer.h"
- #include "content/public/browser/notification_registrar.h"
- namespace base {
- class RefCountedMemory;
- }
- namespace printing {
- class JobEventDetails;
- class MetafilePlayer;
- class PdfToEmfConverter;
- class PrintJobWorker;
- class PrintedDocument;
- class PrintedPage;
- class PrinterQuery;
- // Manages the print work for a specific document. Talks to the printer through
- // PrintingContext through PrintJobWorker. Hides access to PrintingContext in a
- // worker thread so the caller never blocks. PrintJob will send notifications on
- // any state change. While printing, the PrintJobManager instance keeps a
- // reference to the job to be sure it is kept alive. All the code in this class
- // runs in the UI thread.
- class PrintJob : public PrintJobWorkerOwner,
- public content::NotificationObserver {
- public:
- // Create a empty PrintJob. When initializing with this constructor,
- // post-constructor initialization must be done with Initialize().
- PrintJob();
- // Grabs the ownership of the PrintJobWorker from another job, which is
- // usually a PrinterQuery. Set the expected page count of the print job.
- void Initialize(PrintJobWorkerOwner* job,
- const base::string16& name,
- int page_count);
- // content::NotificationObserver implementation.
- void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) override;
- // PrintJobWorkerOwner implementation.
- void GetSettingsDone(const PrintSettings& new_settings,
- PrintingContext::Result result) override;
- std::unique_ptr<PrintJobWorker> DetachWorker(
- PrintJobWorkerOwner* new_owner) override;
- const PrintSettings& settings() const override;
- int cookie() const override;
- // Starts the actual printing. Signals the worker that it should begin to
- // spool as soon as data is available.
- void StartPrinting();
- // Asks for the worker thread to finish its queued tasks and disconnects the
- // delegate object. The PrintJobManager will remove its reference. This may
- // have the side-effect of destroying the object if the caller doesn't have a
- // handle to the object. Use PrintJob::is_stopped() to check whether the
- // worker thread has actually stopped.
- void Stop();
- // Cancels printing job and stops the worker thread. Takes effect immediately.
- void Cancel();
- // Synchronously wait for the job to finish. It is mainly useful when the
- // process is about to be shut down and we're waiting for the spooler to eat
- // our data.
- bool FlushJob(base::TimeDelta timeout);
- // Returns true if the print job is pending, i.e. between a StartPrinting()
- // and the end of the spooling.
- bool is_job_pending() const;
- // Access the current printed document. Warning: may be NULL.
- PrintedDocument* document() const;
- #if defined(OS_WIN)
- // Let the PrintJob know the 0-based |page_number| of a given printed page.
- void AppendPrintedPage(int page_number);
- void StartPdfToEmfConversion(
- const scoped_refptr<base::RefCountedMemory>& bytes,
- const gfx::Size& page_size,
- const gfx::Rect& content_area,
- bool print_text_with_gdi);
- void StartPdfToPostScriptConversion(
- const scoped_refptr<base::RefCountedMemory>& bytes,
- const gfx::Rect& content_area,
- const gfx::Point& physical_offset,
- bool ps_level2);
- #endif // defined(OS_WIN)
- protected:
- ~PrintJob() override;
- private:
- // Updates |document_| to a new instance.
- void UpdatePrintedDocument(PrintedDocument* new_document);
- // Processes a NOTIFY_PRINT_JOB_EVENT notification.
- void OnNotifyPrintJobEvent(const JobEventDetails& event_details);
- // Releases the worker thread by calling Stop(), then broadcasts a JOB_DONE
- // notification.
- void OnDocumentDone();
- // Terminates the worker thread in a very controlled way, to work around any
- // eventual deadlock.
- void ControlledWorkerShutdown();
- // Called at shutdown when running a nested message loop.
- void Quit();
- void HoldUntilStopIsCalled();
- #if defined(OS_WIN)
- void OnPdfConversionStarted(int page_count);
- void OnPdfPageConverted(int page_number,
- float scale_factor,
- std::unique_ptr<MetafilePlayer> emf);
- #endif // defined(OS_WIN)
- content::NotificationRegistrar registrar_;
- // All the UI is done in a worker thread because many Win32 print functions
- // are blocking and enters a message loop without your consent. There is one
- // worker thread per print job.
- std::unique_ptr<PrintJobWorker> worker_;
- // Cache of the print context settings for access in the UI thread.
- PrintSettings settings_;
- // The printed document.
- scoped_refptr<PrintedDocument> document_;
- // Is the worker thread printing.
- bool is_job_pending_;
- // Is Canceling? If so, try to not cause recursion if on FAILED notification,
- // the notified calls Cancel() again.
- bool is_canceling_;
- #if defined(OS_WIN)
- class PdfConversionState;
- std::unique_ptr<PdfConversionState> pdf_conversion_state_;
- std::vector<int> pdf_page_mapping_;
- #endif // defined(OS_WIN)
- // Used at shutdown so that we can quit a nested message loop.
- base::WeakPtrFactory<PrintJob> quit_factory_;
- DISALLOW_COPY_AND_ASSIGN(PrintJob);
- };
- // Details for a NOTIFY_PRINT_JOB_EVENT notification. The members may be NULL.
- class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
- public:
- // Event type.
- enum Type {
- // Print... dialog box has been closed with OK button.
- USER_INIT_DONE,
- // Print... dialog box has been closed with CANCEL button.
- USER_INIT_CANCELED,
- // An automated initialization has been done, e.g. Init(false, NULL).
- DEFAULT_INIT_DONE,
- // A new document started printing.
- NEW_DOC,
- // A new page started printing.
- NEW_PAGE,
- // A page is done printing.
- PAGE_DONE,
- // A document is done printing. The worker thread is still alive. Warning:
- // not a good moment to release the handle to PrintJob.
- DOC_DONE,
- // The worker thread is finished. A good moment to release the handle to
- // PrintJob.
- JOB_DONE,
- // All missing pages have been requested.
- ALL_PAGES_REQUESTED,
- // An error occured. Printing is canceled.
- FAILED,
- };
- JobEventDetails(Type type, PrintedDocument* document, PrintedPage* page);
- // Getters.
- PrintedDocument* document() const;
- PrintedPage* page() const;
- Type type() const { return type_; }
- private:
- friend class base::RefCountedThreadSafe<JobEventDetails>;
- ~JobEventDetails();
- scoped_refptr<PrintedDocument> document_;
- scoped_refptr<PrintedPage> page_;
- const Type type_;
- DISALLOW_COPY_AND_ASSIGN(JobEventDetails);
- };
- } // namespace printing
- #endif // CHROME_BROWSER_PRINTING_PRINT_JOB_H_
|