print_job.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2006-2008 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/message_loop.h"
11#include "base/scoped_ptr.h"
12#include "chrome/browser/printing/print_job_worker_owner.h"
13#include "chrome/common/notification_observer.h"
14#include "chrome/common/notification_registrar.h"
15#include "gfx/native_widget_types.h"
16
17class GURL;
18class Thread;
19
20namespace printing {
21
22// See definition below.
23class JobEventDetails;
24
25class PrintedDocument;
26class PrintedPage;
27class PrintedPagesSource;
28class PrintJobWorker;
29class PrinterQuery;
30
31// Manages the print work for a specific document. Talks to the printer through
32// PrintingContext though PrintJob::Worker. Hides access to PrintingContext in a
33// worker thread so the caller never blocks. PrintJob will send notifications on
34// any state change. While printing, the PrintJobManager instance keeps a
35// reference to the job to be sure it is kept alive. All the code in this class
36// runs in the UI thread.
37class PrintJob : public PrintJobWorkerOwner,
38                 public NotificationObserver,
39                 public MessageLoop::DestructionObserver {
40 public:
41  // Create a empty PrintJob. When initializing with this constructor,
42  // post-constructor initialization must be done with Initialize().
43  PrintJob();
44
45  // Grabs the ownership of the PrintJobWorker from another job, which is
46  // usually a PrinterQuery.
47  void Initialize(PrintJobWorkerOwner* job, PrintedPagesSource* source);
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() { return ui_message_loop_; }
59  virtual const PrintSettings& settings() const { return settings_; }
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  // Returns true if the Print... dialog box is currently displayed.
92  bool is_print_dialog_box_shown() const;
93
94  // Access the current printed document. Warning: may be NULL.
95  PrintedDocument* document() const;
96
97 protected:
98  virtual ~PrintJob();
99
100 private:
101  // Updates document_ to a new instance.
102  void UpdatePrintedDocument(PrintedDocument* new_document);
103
104  // Processes a NOTIFY_PRINT_JOB_EVENT notification.
105  void OnNotifyPrintJobEvent(const JobEventDetails& event_details);
106
107  // Releases the worker thread by calling Stop(), then broadcasts a JOB_DONE
108  // notification.
109  void OnDocumentDone();
110
111  // Terminates the worker thread in a very controlled way, to work around any
112  // eventual deadlock.
113  void ControlledWorkerShutdown();
114
115  NotificationRegistrar registrar_;
116
117  // Main message loop reference. Used to send notifications in the right
118  // thread.
119  MessageLoop* const ui_message_loop_;
120
121  // Source that generates the PrintedPage's (i.e. a TabContents). It will be
122  // set back to NULL if the source is deleted before this object.
123  PrintedPagesSource* source_;
124
125  // All the UI is done in a worker thread because many Win32 print functions
126  // are blocking and enters a message loop without your consent. There is one
127  // worker thread per print job.
128  scoped_ptr<PrintJobWorker> worker_;
129
130  // Cache of the print context settings for access in the UI thread.
131  PrintSettings settings_;
132
133  // The printed document.
134  scoped_refptr<PrintedDocument> document_;
135
136  // Is the worker thread printing.
137  bool is_job_pending_;
138
139  // Is the Print... dialog box currently shown.
140  bool is_print_dialog_box_shown_;
141
142  // Is Canceling? If so, try to not cause recursion if on FAILED notification,
143  // the notified calls Cancel() again.
144  bool is_canceling_;
145
146  DISALLOW_COPY_AND_ASSIGN(PrintJob);
147};
148
149// Details for a NOTIFY_PRINT_JOB_EVENT notification. The members may be NULL.
150class JobEventDetails : public base::RefCountedThreadSafe<JobEventDetails> {
151 public:
152  // Event type.
153  enum Type {
154    // Print... dialog box has been closed with OK button.
155    USER_INIT_DONE,
156
157    // Print... dialog box has been closed with CANCEL button.
158    USER_INIT_CANCELED,
159
160    // An automated initialization has been done, e.g. Init(false, NULL).
161    DEFAULT_INIT_DONE,
162
163    // A new document started printing.
164    NEW_DOC,
165
166    // A new page started printing.
167    NEW_PAGE,
168
169    // A page is done printing.
170    PAGE_DONE,
171
172    // A document is done printing. The worker thread is still alive. Warning:
173    // not a good moment to release the handle to PrintJob.
174    DOC_DONE,
175
176    // The worker thread is finished. A good moment to release the handle to
177    // PrintJob.
178    JOB_DONE,
179
180    // All missing pages have been requested.
181    ALL_PAGES_REQUESTED,
182
183    // An error occured. Printing is canceled.
184    FAILED,
185  };
186
187  JobEventDetails(Type type, PrintedDocument* document, PrintedPage* page);
188
189  // Getters.
190  PrintedDocument* document() const;
191  PrintedPage* page() const;
192  Type type() const {
193    return type_;
194  }
195
196 private:
197  friend class base::RefCountedThreadSafe<JobEventDetails>;
198
199  ~JobEventDetails();
200
201  scoped_refptr<PrintedDocument> document_;
202  scoped_refptr<PrintedPage> page_;
203  const Type type_;
204
205  DISALLOW_COPY_AND_ASSIGN(JobEventDetails);
206};
207
208}  // namespace printing
209
210#endif  // CHROME_BROWSER_PRINTING_PRINT_JOB_H_
211