• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
type()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