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