Upstream version 5.34.104.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 printing {
19
20 // See definition below.
21 class JobEventDetails;
22
23 class PrintedDocument;
24 class PrintedPage;
25 class PrintedPagesSource;
26 class PrintJobWorker;
27 class PrinterQuery;
28
29 // Manages the print work for a specific document. Talks to the printer through
30 // PrintingContext through PrintJobWorker. Hides access to PrintingContext in a
31 // worker thread so the caller never blocks. PrintJob will send notifications on
32 // any state change. While printing, the PrintJobManager instance keeps a
33 // reference to the job to be sure it is kept alive. All the code in this class
34 // runs in the UI thread.
35 class PrintJob : public PrintJobWorkerOwner,
36                  public content::NotificationObserver,
37                  public base::MessageLoop::DestructionObserver {
38  public:
39   // Create a empty PrintJob. When initializing with this constructor,
40   // post-constructor initialization must be done with Initialize().
41   PrintJob();
42
43   // Grabs the ownership of the PrintJobWorker from another job, which is
44   // usually a PrinterQuery. Set the expected page count of the print job.
45   void Initialize(PrintJobWorkerOwner* job, PrintedPagesSource* source,
46                   int page_count);
47
48   // content::NotificationObserver implementation.
49   virtual void Observe(int type,
50                        const content::NotificationSource& source,
51                        const content::NotificationDetails& details) OVERRIDE;
52
53   // PrintJobWorkerOwner implementation.
54   virtual void GetSettingsDone(const PrintSettings& new_settings,
55                                PrintingContext::Result result) OVERRIDE;
56   virtual PrintJobWorker* DetachWorker(PrintJobWorkerOwner* new_owner) OVERRIDE;
57   virtual base::MessageLoop* message_loop() OVERRIDE;
58   virtual const PrintSettings& settings() const OVERRIDE;
59   virtual int cookie() const OVERRIDE;
60
61   // DestructionObserver implementation.
62   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
63
64   // Starts the actual printing. Signals the worker that it should begin to
65   // spool as soon as data is available.
66   void StartPrinting();
67
68   // Asks for the worker thread to finish its queued tasks and disconnects the
69   // delegate object. The PrintJobManager will remove its reference. This may
70   // have the side-effect of destroying the object if the caller doesn't have a
71   // handle to the object. Use PrintJob::is_stopped() to check whether the
72   // worker thread has actually stopped.
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(base::TimeDelta timeout);
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   // Called at shutdown when running a nested message loop.
113   void Quit();
114
115   void HoldUntilStopIsCalled();
116
117   content::NotificationRegistrar registrar_;
118
119   // Main message loop reference. Used to send notifications in the right
120   // thread.
121   base::MessageLoop* const ui_message_loop_;
122
123   // Source that generates the PrintedPage's (i.e. a WebContents). It will be
124   // set back to NULL if the source is deleted before this object.
125   PrintedPagesSource* source_;
126
127   // All the UI is done in a worker thread because many Win32 print functions
128   // are blocking and enters a message loop without your consent. There is one
129   // worker thread per print job.
130   scoped_ptr<PrintJobWorker> worker_;
131
132   // Cache of the print context settings for access in the UI thread.
133   PrintSettings settings_;
134
135   // The printed document.
136   scoped_refptr<PrintedDocument> document_;
137
138   // Is the worker thread printing.
139   bool is_job_pending_;
140
141   // Is Canceling? If so, try to not cause recursion if on FAILED notification,
142   // the notified calls Cancel() again.
143   bool is_canceling_;
144
145   // Used at shutdown so that we can quit a nested message loop.
146   base::WeakPtrFactory<PrintJob> quit_factory_;
147
148   DISALLOW_COPY_AND_ASSIGN(PrintJob);
149 };
150
151 // Details for a NOTIFY_PRINT_JOB_EVENT notification. The members may be NULL.
152 class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
153  public:
154   // Event type.
155   enum Type {
156     // Print... dialog box has been closed with OK button.
157     USER_INIT_DONE,
158
159     // Print... dialog box has been closed with CANCEL button.
160     USER_INIT_CANCELED,
161
162     // An automated initialization has been done, e.g. Init(false, NULL).
163     DEFAULT_INIT_DONE,
164
165     // A new document started printing.
166     NEW_DOC,
167
168     // A new page started printing.
169     NEW_PAGE,
170
171     // A page is done printing.
172     PAGE_DONE,
173
174     // A document is done printing. The worker thread is still alive. Warning:
175     // not a good moment to release the handle to PrintJob.
176     DOC_DONE,
177
178     // The worker thread is finished. A good moment to release the handle to
179     // PrintJob.
180     JOB_DONE,
181
182     // All missing pages have been requested.
183     ALL_PAGES_REQUESTED,
184
185     // An error occured. Printing is canceled.
186     FAILED,
187   };
188
189   JobEventDetails(Type type, PrintedDocument* document, PrintedPage* page);
190
191   // Getters.
192   PrintedDocument* document() const;
193   PrintedPage* page() const;
194   Type type() const {
195     return type_;
196   }
197
198  private:
199   friend class base::RefCountedThreadSafe<JobEventDetails>;
200
201   ~JobEventDetails();
202
203   scoped_refptr<PrintedDocument> document_;
204   scoped_refptr<PrintedPage> page_;
205   const Type type_;
206
207   DISALLOW_COPY_AND_ASSIGN(JobEventDetails);
208 };
209
210 }  // namespace printing
211
212 #endif  // CHROME_BROWSER_PRINTING_PRINT_JOB_H_