Home | History | Annotate | Download | only in printing
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_PRINTING_PRINT_JOB_H_
      6 #define CHROME_BROWSER_PRINTING_PRINT_JOB_H_
      7 #pragma once
      8 
      9 #include "base/basictypes.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/message_loop.h"
     12 #include "chrome/browser/printing/print_job_worker_owner.h"
     13 #include "content/common/notification_observer.h"
     14 #include "content/common/notification_registrar.h"
     15 
     16 class GURL;
     17 class Thread;
     18 
     19 namespace printing {
     20 
     21 // See definition below.
     22 class JobEventDetails;
     23 
     24 class PrintedDocument;
     25 class PrintedPage;
     26 class PrintedPagesSource;
     27 class PrintJobWorker;
     28 class PrinterQuery;
     29 
     30 // Manages the print work for a specific document. Talks to the printer through
     31 // PrintingContext though PrintJob::Worker. Hides access to PrintingContext in a
     32 // worker thread so the caller never blocks. PrintJob will send notifications on
     33 // any state change. While printing, the PrintJobManager instance keeps a
     34 // reference to the job to be sure it is kept alive. All the code in this class
     35 // runs in the UI thread.
     36 class PrintJob : public PrintJobWorkerOwner,
     37                  public NotificationObserver,
     38                  public MessageLoop::DestructionObserver {
     39  public:
     40   // Create a empty PrintJob. When initializing with this constructor,
     41   // post-constructor initialization must be done with Initialize().
     42   PrintJob();
     43 
     44   // Grabs the ownership of the PrintJobWorker from another job, which is
     45   // usually a PrinterQuery. Set the expected page count of the print job.
     46   void Initialize(PrintJobWorkerOwner* job, PrintedPagesSource* source,
     47                   int page_count);
     48 
     49   // NotificationObserver
     50   virtual void Observe(NotificationType type,
     51                        const NotificationSource& source,
     52                        const NotificationDetails& details);
     53 
     54   // PrintJobWorkerOwner
     55   virtual void GetSettingsDone(const PrintSettings& new_settings,
     56                                PrintingContext::Result result);
     57   virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner);
     58   virtual MessageLoop* message_loop();
     59   virtual const PrintSettings& settings() const;
     60   virtual int cookie() const;
     61 
     62   // DestructionObserver
     63   virtual void WillDestroyCurrentMessageLoop();
     64 
     65   // Starts the actual printing. Signals the worker that it should begin to
     66   // spool as soon as data is available.
     67   void StartPrinting();
     68 
     69   // Waits for the worker thread to finish its queued tasks and disconnects the
     70   // delegate object. The PrintJobManager will remove it reference. This may
     71   // have the side-effect of destroying the object if the caller doesn't have a
     72   // handle to the object.
     73   void Stop();
     74 
     75   // Cancels printing job and stops the worker thread. Takes effect immediately.
     76   void Cancel();
     77 
     78   // Synchronously wait for the job to finish. It is mainly useful when the
     79   // process is about to be shut down and we're waiting for the spooler to eat
     80   // our data.
     81   bool FlushJob(int timeout_ms);
     82 
     83   // Disconnects the PrintedPage source (PrintedPagesSource). It is done when
     84   // the source is being destroyed.
     85   void DisconnectSource();
     86 
     87   // Returns true if the print job is pending, i.e. between a StartPrinting()
     88   // and the end of the spooling.
     89   bool is_job_pending() const;
     90 
     91   // Access the current printed document. Warning: may be NULL.
     92   PrintedDocument* document() const;
     93 
     94  protected:
     95   virtual ~PrintJob();
     96 
     97  private:
     98   // Updates document_ to a new instance.
     99   void UpdatePrintedDocument(PrintedDocument* new_document);
    100 
    101   // Processes a NOTIFY_PRINT_JOB_EVENT notification.
    102   void OnNotifyPrintJobEvent(const JobEventDetails& event_details);
    103 
    104   // Releases the worker thread by calling Stop(), then broadcasts a JOB_DONE
    105   // notification.
    106   void OnDocumentDone();
    107 
    108   // Terminates the worker thread in a very controlled way, to work around any
    109   // eventual deadlock.
    110   void ControlledWorkerShutdown();
    111 
    112   NotificationRegistrar registrar_;
    113 
    114   // Main message loop reference. Used to send notifications in the right
    115   // thread.
    116   MessageLoop* const ui_message_loop_;
    117 
    118   // Source that generates the PrintedPage's (i.e. a TabContents). It will be
    119   // set back to NULL if the source is deleted before this object.
    120   PrintedPagesSource* source_;
    121 
    122   // All the UI is done in a worker thread because many Win32 print functions
    123   // are blocking and enters a message loop without your consent. There is one
    124   // worker thread per print job.
    125   scoped_ptr<PrintJobWorker> worker_;
    126 
    127   // Cache of the print context settings for access in the UI thread.
    128   PrintSettings settings_;
    129 
    130   // The printed document.
    131   scoped_refptr<PrintedDocument> document_;
    132 
    133   // Is the worker thread printing.
    134   bool is_job_pending_;
    135 
    136   // Is Canceling? If so, try to not cause recursion if on FAILED notification,
    137   // the notified calls Cancel() again.
    138   bool is_canceling_;
    139 
    140   DISALLOW_COPY_AND_ASSIGN(PrintJob);
    141 };
    142 
    143 // Details for a NOTIFY_PRINT_JOB_EVENT notification. The members may be NULL.
    144 class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
    145  public:
    146   // Event type.
    147   enum Type {
    148     // Print... dialog box has been closed with OK button.
    149     USER_INIT_DONE,
    150 
    151     // Print... dialog box has been closed with CANCEL button.
    152     USER_INIT_CANCELED,
    153 
    154     // An automated initialization has been done, e.g. Init(false, NULL).
    155     DEFAULT_INIT_DONE,
    156 
    157     // A new document started printing.
    158     NEW_DOC,
    159 
    160     // A new page started printing.
    161     NEW_PAGE,
    162 
    163     // A page is done printing.
    164     PAGE_DONE,
    165 
    166     // A document is done printing. The worker thread is still alive. Warning:
    167     // not a good moment to release the handle to PrintJob.
    168     DOC_DONE,
    169 
    170     // The worker thread is finished. A good moment to release the handle to
    171     // PrintJob.
    172     JOB_DONE,
    173 
    174     // All missing pages have been requested.
    175     ALL_PAGES_REQUESTED,
    176 
    177     // An error occured. Printing is canceled.
    178     FAILED,
    179   };
    180 
    181   JobEventDetails(Type type, PrintedDocument* document, PrintedPage* page);
    182 
    183   // Getters.
    184   PrintedDocument* document() const;
    185   PrintedPage* page() const;
    186   Type type() const {
    187     return type_;
    188   }
    189 
    190  private:
    191   friend class base::RefCountedThreadSafe<JobEventDetails>;
    192 
    193   ~JobEventDetails();
    194 
    195   scoped_refptr<PrintedDocument> document_;
    196   scoped_refptr<PrintedPage> page_;
    197   const Type type_;
    198 
    199   DISALLOW_COPY_AND_ASSIGN(JobEventDetails);
    200 };
    201 
    202 }  // namespace printing
    203 
    204 #endif  // CHROME_BROWSER_PRINTING_PRINT_JOB_H_
    205