| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/printing/print_job.h" | 5 #include "chrome/browser/printing/print_job.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/threading/thread_restrictions.h" | 8 #include "base/threading/thread_restrictions.h" |
| 9 #include "base/timer.h" | 9 #include "base/timer.h" |
| 10 #include "chrome/browser/printing/print_job_worker.h" | 10 #include "chrome/browser/printing/print_job_worker.h" |
| 11 #include "chrome/common/notification_service.h" | 11 #include "chrome/common/notification_service.h" |
| 12 #include "printing/printed_document.h" | 12 #include "printing/printed_document.h" |
| 13 #include "printing/printed_page.h" | 13 #include "printing/printed_page.h" |
| 14 | 14 |
| 15 using base::TimeDelta; | 15 using base::TimeDelta; |
| 16 | 16 |
| 17 namespace printing { | 17 namespace printing { |
| 18 | 18 |
| 19 PrintJob::PrintJob() | 19 PrintJob::PrintJob() |
| 20 : ui_message_loop_(MessageLoop::current()), | 20 : ui_message_loop_(MessageLoop::current()), |
| 21 source_(NULL), | 21 source_(NULL), |
| 22 worker_(), | 22 worker_(), |
| 23 settings_(), | 23 settings_(), |
| 24 is_job_pending_(false), | 24 is_job_pending_(false), |
| 25 is_print_dialog_box_shown_(false), | |
| 26 is_canceling_(false) { | 25 is_canceling_(false) { |
| 27 DCHECK(ui_message_loop_); | 26 DCHECK(ui_message_loop_); |
| 28 // This is normally a UI message loop, but in unit tests, the message loop is | 27 // This is normally a UI message loop, but in unit tests, the message loop is |
| 29 // of the 'default' type. | 28 // of the 'default' type. |
| 30 DCHECK(ui_message_loop_->type() == MessageLoop::TYPE_UI || | 29 DCHECK(ui_message_loop_->type() == MessageLoop::TYPE_UI || |
| 31 ui_message_loop_->type() == MessageLoop::TYPE_DEFAULT); | 30 ui_message_loop_->type() == MessageLoop::TYPE_DEFAULT); |
| 32 ui_message_loop_->AddDestructionObserver(this); | 31 ui_message_loop_->AddDestructionObserver(this); |
| 33 } | 32 } |
| 34 | 33 |
| 35 PrintJob::~PrintJob() { | 34 PrintJob::~PrintJob() { |
| 36 ui_message_loop_->RemoveDestructionObserver(this); | 35 ui_message_loop_->RemoveDestructionObserver(this); |
| 37 // The job should be finished (or at least canceled) when it is destroyed. | 36 // The job should be finished (or at least canceled) when it is destroyed. |
| 38 DCHECK(!is_job_pending_); | 37 DCHECK(!is_job_pending_); |
| 39 DCHECK(!is_print_dialog_box_shown_); | |
| 40 DCHECK(!is_canceling_); | 38 DCHECK(!is_canceling_); |
| 41 if (worker_.get()) | 39 if (worker_.get()) |
| 42 DCHECK(worker_->message_loop() == NULL); | 40 DCHECK(worker_->message_loop() == NULL); |
| 43 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); | 41 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); |
| 44 } | 42 } |
| 45 | 43 |
| 46 void PrintJob::Initialize(PrintJobWorkerOwner* job, | 44 void PrintJob::Initialize(PrintJobWorkerOwner* job, |
| 47 PrintedPagesSource* source, | 45 PrintedPagesSource* source, |
| 48 int page_count) { | 46 int page_count) { |
| 49 DCHECK(!source_); | 47 DCHECK(!source_); |
| 50 DCHECK(!worker_.get()); | 48 DCHECK(!worker_.get()); |
| 51 DCHECK(!is_job_pending_); | 49 DCHECK(!is_job_pending_); |
| 52 DCHECK(!is_print_dialog_box_shown_); | |
| 53 DCHECK(!is_canceling_); | 50 DCHECK(!is_canceling_); |
| 54 DCHECK(!document_.get()); | 51 DCHECK(!document_.get()); |
| 55 source_ = source; | 52 source_ = source; |
| 56 worker_.reset(job->DetachWorker(this)); | 53 worker_.reset(job->DetachWorker(this)); |
| 57 settings_ = job->settings(); | 54 settings_ = job->settings(); |
| 58 | 55 |
| 59 PrintedDocument* new_doc = | 56 PrintedDocument* new_doc = |
| 60 new PrintedDocument(settings_, source_, job->cookie()); | 57 new PrintedDocument(settings_, source_, job->cookie()); |
| 61 new_doc->set_page_count(page_count); | 58 new_doc->set_page_count(page_count); |
| 62 UpdatePrintedDocument(new_doc); | 59 UpdatePrintedDocument(new_doc); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 } | 104 } |
| 108 | 105 |
| 109 void PrintJob::WillDestroyCurrentMessageLoop() { | 106 void PrintJob::WillDestroyCurrentMessageLoop() { |
| 110 NOTREACHED(); | 107 NOTREACHED(); |
| 111 } | 108 } |
| 112 | 109 |
| 113 void PrintJob::StartPrinting() { | 110 void PrintJob::StartPrinting() { |
| 114 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); | 111 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); |
| 115 DCHECK(worker_->message_loop()); | 112 DCHECK(worker_->message_loop()); |
| 116 DCHECK(!is_job_pending_); | 113 DCHECK(!is_job_pending_); |
| 117 DCHECK(!is_print_dialog_box_shown_); | |
| 118 if (!worker_->message_loop() || is_job_pending_) | 114 if (!worker_->message_loop() || is_job_pending_) |
| 119 return; | 115 return; |
| 120 | 116 |
| 121 // Real work is done in PrintJobWorker::StartPrinting(). | 117 // Real work is done in PrintJobWorker::StartPrinting(). |
| 122 worker_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 118 worker_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 123 worker_.get(), &PrintJobWorker::StartPrinting, document_)); | 119 worker_.get(), &PrintJobWorker::StartPrinting, document_)); |
| 124 // Set the flag right now. | 120 // Set the flag right now. |
| 125 is_job_pending_ = true; | 121 is_job_pending_ = true; |
| 126 | 122 |
| 127 // Tell everyone! | 123 // Tell everyone! |
| 128 scoped_refptr<JobEventDetails> details( | 124 scoped_refptr<JobEventDetails> details( |
| 129 new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL)); | 125 new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL)); |
| 130 NotificationService::current()->Notify( | 126 NotificationService::current()->Notify( |
| 131 NotificationType::PRINT_JOB_EVENT, | 127 NotificationType::PRINT_JOB_EVENT, |
| 132 Source<PrintJob>(this), | 128 Source<PrintJob>(this), |
| 133 Details<JobEventDetails>(details.get())); | 129 Details<JobEventDetails>(details.get())); |
| 134 } | 130 } |
| 135 | 131 |
| 136 void PrintJob::Stop() { | 132 void PrintJob::Stop() { |
| 137 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); | 133 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); |
| 138 | 134 |
| 139 // Be sure to live long enough. | 135 // Be sure to live long enough. |
| 140 scoped_refptr<PrintJob> handle(this); | 136 scoped_refptr<PrintJob> handle(this); |
| 141 | 137 |
| 142 MessageLoop* worker_loop = worker_->message_loop(); | 138 MessageLoop* worker_loop = worker_->message_loop(); |
| 143 if (worker_loop) { | 139 if (worker_loop) { |
| 144 if (is_print_dialog_box_shown_) { | |
| 145 // Make sure there is no Print... dialog box. | |
| 146 worker_loop->PostTask(FROM_HERE, NewRunnableMethod( | |
| 147 worker_.get(), &PrintJobWorker::DismissDialog)); | |
| 148 is_print_dialog_box_shown_ = false; | |
| 149 } | |
| 150 | |
| 151 ControlledWorkerShutdown(); | 140 ControlledWorkerShutdown(); |
| 152 | 141 |
| 153 is_job_pending_ = false; | 142 is_job_pending_ = false; |
| 154 registrar_.Remove(this, NotificationType::PRINT_JOB_EVENT, | 143 registrar_.Remove(this, NotificationType::PRINT_JOB_EVENT, |
| 155 Source<PrintJob>(this)); | 144 Source<PrintJob>(this)); |
| 156 } | 145 } |
| 157 // Flush the cached document. | 146 // Flush the cached document. |
| 158 UpdatePrintedDocument(NULL); | 147 UpdatePrintedDocument(NULL); |
| 159 } | 148 } |
| 160 | 149 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 void PrintJob::DisconnectSource() { | 198 void PrintJob::DisconnectSource() { |
| 210 source_ = NULL; | 199 source_ = NULL; |
| 211 if (document_.get()) | 200 if (document_.get()) |
| 212 document_->DisconnectSource(); | 201 document_->DisconnectSource(); |
| 213 } | 202 } |
| 214 | 203 |
| 215 bool PrintJob::is_job_pending() const { | 204 bool PrintJob::is_job_pending() const { |
| 216 return is_job_pending_; | 205 return is_job_pending_; |
| 217 } | 206 } |
| 218 | 207 |
| 219 bool PrintJob::is_print_dialog_box_shown() const { | |
| 220 return is_print_dialog_box_shown_; | |
| 221 } | |
| 222 | |
| 223 PrintedDocument* PrintJob::document() const { | 208 PrintedDocument* PrintJob::document() const { |
| 224 return document_.get(); | 209 return document_.get(); |
| 225 } | 210 } |
| 226 | 211 |
| 227 void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) { | 212 void PrintJob::UpdatePrintedDocument(PrintedDocument* new_document) { |
| 228 if (document_.get() == new_document) | 213 if (document_.get() == new_document) |
| 229 return; | 214 return; |
| 230 | 215 |
| 231 document_ = new_document; | 216 document_ = new_document; |
| 232 | 217 |
| 233 if (document_.get()) { | 218 if (document_.get()) { |
| 234 settings_ = document_->settings(); | 219 settings_ = document_->settings(); |
| 235 } | 220 } |
| 236 | 221 |
| 237 if (worker_.get() && worker_->message_loop()) { | 222 if (worker_.get() && worker_->message_loop()) { |
| 238 DCHECK(!is_job_pending_); | 223 DCHECK(!is_job_pending_); |
| 239 // Sync the document with the worker. | 224 // Sync the document with the worker. |
| 240 worker_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 225 worker_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 241 worker_.get(), &PrintJobWorker::OnDocumentChanged, document_)); | 226 worker_.get(), &PrintJobWorker::OnDocumentChanged, document_)); |
| 242 } | 227 } |
| 243 } | 228 } |
| 244 | 229 |
| 245 void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) { | 230 void PrintJob::OnNotifyPrintJobEvent(const JobEventDetails& event_details) { |
| 246 switch (event_details.type()) { | 231 switch (event_details.type()) { |
| 247 case JobEventDetails::FAILED: { | 232 case JobEventDetails::FAILED: { |
| 248 settings_.Clear(); | 233 settings_.Clear(); |
| 249 // Update internal state. | |
| 250 is_print_dialog_box_shown_ = false; | |
| 251 // No need to cancel since the worker already canceled itself. | 234 // No need to cancel since the worker already canceled itself. |
| 252 Stop(); | 235 Stop(); |
| 253 break; | 236 break; |
| 254 } | 237 } |
| 255 case JobEventDetails::USER_INIT_DONE: | 238 case JobEventDetails::USER_INIT_DONE: |
| 256 case JobEventDetails::DEFAULT_INIT_DONE: | 239 case JobEventDetails::DEFAULT_INIT_DONE: |
| 257 case JobEventDetails::USER_INIT_CANCELED: { | 240 case JobEventDetails::USER_INIT_CANCELED: { |
| 258 DCHECK_EQ(event_details.document(), document_.get()); | 241 DCHECK_EQ(event_details.document(), document_.get()); |
| 259 break; | 242 break; |
| 260 } | 243 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 346 |
| 364 PrintedDocument* JobEventDetails::document() const { | 347 PrintedDocument* JobEventDetails::document() const { |
| 365 return document_; | 348 return document_; |
| 366 } | 349 } |
| 367 | 350 |
| 368 PrintedPage* JobEventDetails::page() const { | 351 PrintedPage* JobEventDetails::page() const { |
| 369 return page_; | 352 return page_; |
| 370 } | 353 } |
| 371 | 354 |
| 372 } // namespace printing | 355 } // namespace printing |
| OLD | NEW |