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