| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 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_worker.h" | 5 #include "chrome/browser/printing/print_job_worker.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "chrome/browser/chrome_thread.h" | 8 #include "chrome/browser/chrome_thread.h" |
| 9 #include "chrome/browser/printing/print_job.h" | 9 #include "chrome/browser/printing/print_job.h" |
| 10 #include "chrome/common/notification_service.h" | 10 #include "chrome/common/notification_service.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 scoped_refptr<PrintJobWorkerOwner> print_job_; | 45 scoped_refptr<PrintJobWorkerOwner> print_job_; |
| 46 scoped_refptr<JobEventDetails> details_; | 46 scoped_refptr<JobEventDetails> details_; |
| 47 }; | 47 }; |
| 48 | 48 |
| 49 | 49 |
| 50 PrintJobWorker::PrintJobWorker(PrintJobWorkerOwner* owner) | 50 PrintJobWorker::PrintJobWorker(PrintJobWorkerOwner* owner) |
| 51 : Thread("Printing_Worker"), | 51 : Thread("Printing_Worker"), |
| 52 owner_(owner) { | 52 owner_(owner) { |
| 53 // The object is created in the IO thread. | 53 // The object is created in the IO thread. |
| 54 DCHECK_EQ(owner_->message_loop(), MessageLoop::current()); | 54 DCHECK_EQ(owner_->message_loop(), MessageLoop::current()); |
| 55 |
| 56 printing_context_.reset(PrintingContext::Create()); |
| 55 } | 57 } |
| 56 | 58 |
| 57 PrintJobWorker::~PrintJobWorker() { | 59 PrintJobWorker::~PrintJobWorker() { |
| 58 // The object is deleted in the UI thread. | 60 // The object is deleted in the UI thread. |
| 59 DCHECK_EQ(owner_->message_loop(), MessageLoop::current()); | 61 DCHECK_EQ(owner_->message_loop(), MessageLoop::current()); |
| 60 } | 62 } |
| 61 | 63 |
| 62 void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { | 64 void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) { |
| 63 DCHECK(page_number_ == PageNumber::npos()); | 65 DCHECK(page_number_ == PageNumber::npos()); |
| 64 owner_ = new_owner; | 66 owner_ = new_owner; |
| 65 } | 67 } |
| 66 | 68 |
| 67 void PrintJobWorker::GetSettings(bool ask_user_for_settings, | 69 void PrintJobWorker::GetSettings(bool ask_user_for_settings, |
| 68 gfx::NativeView parent_view, | 70 gfx::NativeView parent_view, |
| 69 int document_page_count, | 71 int document_page_count, |
| 70 bool has_selection, | 72 bool has_selection, |
| 71 bool use_overlays) { | 73 bool use_overlays) { |
| 72 DCHECK_EQ(message_loop(), MessageLoop::current()); | 74 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 73 DCHECK_EQ(page_number_, PageNumber::npos()); | 75 DCHECK_EQ(page_number_, PageNumber::npos()); |
| 74 | 76 |
| 75 // Recursive task processing is needed for the dialog in case it needs to be | 77 // Recursive task processing is needed for the dialog in case it needs to be |
| 76 // destroyed by a task. | 78 // destroyed by a task. |
| 77 MessageLoop::current()->SetNestableTasksAllowed(true); | 79 MessageLoop::current()->SetNestableTasksAllowed(true); |
| 78 printing_context_.SetUseOverlays(use_overlays); | 80 printing_context_->set_use_overlays(use_overlays); |
| 79 | 81 |
| 80 if (ask_user_for_settings) { | 82 if (ask_user_for_settings) { |
| 81 #if defined(OS_MACOSX) || defined(USE_X11) | 83 #if defined(OS_MACOSX) || defined(USE_X11) |
| 82 ChromeThread::PostTask( | 84 ChromeThread::PostTask( |
| 83 ChromeThread::UI, FROM_HERE, | 85 ChromeThread::UI, FROM_HERE, |
| 84 NewRunnableMethod(this, &PrintJobWorker::GetSettingsWithUI, | 86 NewRunnableMethod(this, &PrintJobWorker::GetSettingsWithUI, |
| 85 parent_view, document_page_count, | 87 parent_view, document_page_count, |
| 86 has_selection)); | 88 has_selection)); |
| 87 #else | 89 #else |
| 88 printing_context_.AskUserForSettings( | 90 printing_context_->AskUserForSettings( |
| 89 parent_view, | 91 parent_view, |
| 90 document_page_count, | 92 document_page_count, |
| 91 has_selection, | 93 has_selection, |
| 92 NewCallback(this, &PrintJobWorker::GetSettingsDone)); | 94 NewCallback(this, &PrintJobWorker::GetSettingsDone)); |
| 93 #endif // defined(OS_MACOSX) || defined(USE_X11) | 95 #endif // defined(OS_MACOSX) || defined(USE_X11) |
| 94 } else { | 96 } else { |
| 95 PrintingContext::Result result = printing_context_.UseDefaultSettings(); | 97 PrintingContext::Result result = printing_context_->UseDefaultSettings(); |
| 96 GetSettingsDone(result); | 98 GetSettingsDone(result); |
| 97 } | 99 } |
| 98 } | 100 } |
| 99 | 101 |
| 100 void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) { | 102 void PrintJobWorker::GetSettingsDone(PrintingContext::Result result) { |
| 101 // Most PrintingContext functions may start a message loop and process | 103 // Most PrintingContext functions may start a message loop and process |
| 102 // message recursively, so disable recursive task processing. | 104 // message recursively, so disable recursive task processing. |
| 103 MessageLoop::current()->SetNestableTasksAllowed(false); | 105 MessageLoop::current()->SetNestableTasksAllowed(false); |
| 104 | 106 |
| 105 // We can't use OnFailure() here since owner_ may not support notifications. | 107 // We can't use OnFailure() here since owner_ may not support notifications. |
| 106 | 108 |
| 107 // PrintJob will create the new PrintedDocument. | 109 // PrintJob will create the new PrintedDocument. |
| 108 owner_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 110 owner_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 109 owner_, | 111 owner_, |
| 110 &PrintJobWorkerOwner::GetSettingsDone, | 112 &PrintJobWorkerOwner::GetSettingsDone, |
| 111 printing_context_.settings(), | 113 printing_context_->settings(), |
| 112 result)); | 114 result)); |
| 113 } | 115 } |
| 114 | 116 |
| 115 #if defined(OS_MACOSX) || defined(USE_X11) | 117 #if defined(OS_MACOSX) || defined(USE_X11) |
| 116 void PrintJobWorker::GetSettingsWithUI(gfx::NativeView parent_view, | 118 void PrintJobWorker::GetSettingsWithUI(gfx::NativeView parent_view, |
| 117 int document_page_count, | 119 int document_page_count, |
| 118 bool has_selection) { | 120 bool has_selection) { |
| 119 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 121 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 120 | 122 |
| 121 printing_context_.AskUserForSettings( | 123 printing_context_->AskUserForSettings( |
| 122 parent_view, | 124 parent_view, |
| 123 document_page_count, | 125 document_page_count, |
| 124 has_selection, | 126 has_selection, |
| 125 NewCallback(this, &PrintJobWorker::GetSettingsWithUIDone)); | 127 NewCallback(this, &PrintJobWorker::GetSettingsWithUIDone)); |
| 126 } | 128 } |
| 127 | 129 |
| 128 void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) { | 130 void PrintJobWorker::GetSettingsWithUIDone(PrintingContext::Result result) { |
| 129 message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 131 message_loop()->PostTask(FROM_HERE, NewRunnableMethod( |
| 130 this, &PrintJobWorker::GetSettingsDone, result)); | 132 this, &PrintJobWorker::GetSettingsDone, result)); |
| 131 } | 133 } |
| 132 #endif // defined(OS_MACOSX) || defined(USE_X11) | 134 #endif // defined(OS_MACOSX) || defined(USE_X11) |
| 133 | 135 |
| 134 void PrintJobWorker::StartPrinting(PrintedDocument* new_document) { | 136 void PrintJobWorker::StartPrinting(PrintedDocument* new_document) { |
| 135 DCHECK_EQ(message_loop(), MessageLoop::current()); | 137 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 136 DCHECK_EQ(page_number_, PageNumber::npos()); | 138 DCHECK_EQ(page_number_, PageNumber::npos()); |
| 137 DCHECK_EQ(document_, new_document); | 139 DCHECK_EQ(document_, new_document); |
| 138 DCHECK(document_.get()); | 140 DCHECK(document_.get()); |
| 139 DCHECK(new_document->settings().Equals(printing_context_.settings())); | 141 DCHECK(new_document->settings().Equals(printing_context_->settings())); |
| 140 | 142 |
| 141 if (!document_.get() || page_number_ != PageNumber::npos() || | 143 if (!document_.get() || page_number_ != PageNumber::npos() || |
| 142 document_ != new_document) { | 144 document_ != new_document) { |
| 143 return; | 145 return; |
| 144 } | 146 } |
| 145 | 147 |
| 146 PrintingContext::Result result = | 148 PrintingContext::Result result = |
| 147 printing_context_.NewDocument(document_->name()); | 149 printing_context_->NewDocument(document_->name()); |
| 148 if (result != PrintingContext::OK) { | 150 if (result != PrintingContext::OK) { |
| 149 OnFailure(); | 151 OnFailure(); |
| 150 return; | 152 return; |
| 151 } | 153 } |
| 152 | 154 |
| 153 // Try to print already cached data. It may already have been generated for | 155 // Try to print already cached data. It may already have been generated for |
| 154 // the print preview. | 156 // the print preview. |
| 155 OnNewPage(); | 157 OnNewPage(); |
| 156 // Don't touch this anymore since the instance could be destroyed. It happens | 158 // Don't touch this anymore since the instance could be destroyed. It happens |
| 157 // if all the pages are printed a one sweep and the client doesn't have a | 159 // if all the pages are printed a one sweep and the client doesn't have a |
| 158 // handle to us anymore. There's a timing issue involved between the worker | 160 // handle to us anymore. There's a timing issue involved between the worker |
| 159 // thread and the UI thread. Take no chance. | 161 // thread and the UI thread. Take no chance. |
| 160 } | 162 } |
| 161 | 163 |
| 162 void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) { | 164 void PrintJobWorker::OnDocumentChanged(PrintedDocument* new_document) { |
| 163 DCHECK_EQ(message_loop(), MessageLoop::current()); | 165 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 164 DCHECK_EQ(page_number_, PageNumber::npos()); | 166 DCHECK_EQ(page_number_, PageNumber::npos()); |
| 165 DCHECK(!new_document || | 167 DCHECK(!new_document || |
| 166 new_document->settings().Equals(printing_context_.settings())); | 168 new_document->settings().Equals(printing_context_->settings())); |
| 167 | 169 |
| 168 if (page_number_ != PageNumber::npos()) | 170 if (page_number_ != PageNumber::npos()) |
| 169 return; | 171 return; |
| 170 | 172 |
| 171 document_ = new_document; | 173 document_ = new_document; |
| 172 } | 174 } |
| 173 | 175 |
| 174 void PrintJobWorker::OnNewPage() { | 176 void PrintJobWorker::OnNewPage() { |
| 175 if (!document_.get()) { | 177 if (!document_.get()) { |
| 176 // Spurious message. | 178 // Spurious message. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 if (page_number_ == PageNumber::npos()) { | 212 if (page_number_ == PageNumber::npos()) { |
| 211 OnDocumentDone(); | 213 OnDocumentDone(); |
| 212 // Don't touch this anymore since the instance could be destroyed. | 214 // Don't touch this anymore since the instance could be destroyed. |
| 213 break; | 215 break; |
| 214 } | 216 } |
| 215 } | 217 } |
| 216 } | 218 } |
| 217 | 219 |
| 218 void PrintJobWorker::Cancel() { | 220 void PrintJobWorker::Cancel() { |
| 219 // This is the only function that can be called from any thread. | 221 // This is the only function that can be called from any thread. |
| 220 printing_context_.Cancel(); | 222 printing_context_->Cancel(); |
| 221 // Cannot touch any member variable since we don't know in which thread | 223 // Cannot touch any member variable since we don't know in which thread |
| 222 // context we run. | 224 // context we run. |
| 223 } | 225 } |
| 224 | 226 |
| 225 void PrintJobWorker::DismissDialog() { | 227 void PrintJobWorker::DismissDialog() { |
| 226 printing_context_.DismissDialog(); | 228 printing_context_->DismissDialog(); |
| 227 } | 229 } |
| 228 | 230 |
| 229 void PrintJobWorker::OnDocumentDone() { | 231 void PrintJobWorker::OnDocumentDone() { |
| 230 DCHECK_EQ(message_loop(), MessageLoop::current()); | 232 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 231 DCHECK_EQ(page_number_, PageNumber::npos()); | 233 DCHECK_EQ(page_number_, PageNumber::npos()); |
| 232 DCHECK(document_.get()); | 234 DCHECK(document_.get()); |
| 233 | 235 |
| 234 if (printing_context_.DocumentDone() != PrintingContext::OK) { | 236 if (printing_context_->DocumentDone() != PrintingContext::OK) { |
| 235 OnFailure(); | 237 OnFailure(); |
| 236 return; | 238 return; |
| 237 } | 239 } |
| 238 | 240 |
| 239 // Tell everyone! | 241 // Tell everyone! |
| 240 NotificationTask* task = new NotificationTask(); | 242 NotificationTask* task = new NotificationTask(); |
| 241 task->Init(owner_, | 243 task->Init(owner_, |
| 242 JobEventDetails::DOC_DONE, | 244 JobEventDetails::DOC_DONE, |
| 243 document_.get(), | 245 document_.get(), |
| 244 NULL); | 246 NULL); |
| 245 owner_->message_loop()->PostTask(FROM_HERE, task); | 247 owner_->message_loop()->PostTask(FROM_HERE, task); |
| 246 | 248 |
| 247 // Makes sure the variables are reinitialized. | 249 // Makes sure the variables are reinitialized. |
| 248 document_ = NULL; | 250 document_ = NULL; |
| 249 } | 251 } |
| 250 | 252 |
| 251 void PrintJobWorker::SpoolPage(PrintedPage& page) { | 253 void PrintJobWorker::SpoolPage(PrintedPage& page) { |
| 252 DCHECK_EQ(message_loop(), MessageLoop::current()); | 254 DCHECK_EQ(message_loop(), MessageLoop::current()); |
| 253 DCHECK_NE(page_number_, PageNumber::npos()); | 255 DCHECK_NE(page_number_, PageNumber::npos()); |
| 254 | 256 |
| 255 // Signal everyone that the page is about to be printed. | 257 // Signal everyone that the page is about to be printed. |
| 256 NotificationTask* task = new NotificationTask(); | 258 NotificationTask* task = new NotificationTask(); |
| 257 task->Init(owner_, | 259 task->Init(owner_, |
| 258 JobEventDetails::NEW_PAGE, | 260 JobEventDetails::NEW_PAGE, |
| 259 document_.get(), | 261 document_.get(), |
| 260 &page); | 262 &page); |
| 261 owner_->message_loop()->PostTask(FROM_HERE, task); | 263 owner_->message_loop()->PostTask(FROM_HERE, task); |
| 262 | 264 |
| 263 // Preprocess. | 265 // Preprocess. |
| 264 if (printing_context_.NewPage() != PrintingContext::OK) { | 266 if (printing_context_->NewPage() != PrintingContext::OK) { |
| 265 OnFailure(); | 267 OnFailure(); |
| 266 return; | 268 return; |
| 267 } | 269 } |
| 268 | 270 |
| 269 // Actual printing. | 271 // Actual printing. |
| 270 document_->RenderPrintedPage(page, printing_context_.context()); | 272 document_->RenderPrintedPage(page, printing_context_->context()); |
| 271 | 273 |
| 272 // Postprocess. | 274 // Postprocess. |
| 273 if (printing_context_.PageDone() != PrintingContext::OK) { | 275 if (printing_context_->PageDone() != PrintingContext::OK) { |
| 274 OnFailure(); | 276 OnFailure(); |
| 275 return; | 277 return; |
| 276 } | 278 } |
| 277 | 279 |
| 278 // Signal everyone that the page is printed. | 280 // Signal everyone that the page is printed. |
| 279 task = new NotificationTask(); | 281 task = new NotificationTask(); |
| 280 task->Init(owner_, | 282 task->Init(owner_, |
| 281 JobEventDetails::PAGE_DONE, | 283 JobEventDetails::PAGE_DONE, |
| 282 document_.get(), | 284 document_.get(), |
| 283 &page); | 285 &page); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 309 printing::PrintJobWorker* obj) { | 311 printing::PrintJobWorker* obj) { |
| 310 DCHECK(!owner_.get()); | 312 DCHECK(!owner_.get()); |
| 311 owner_ = obj->owner_; | 313 owner_ = obj->owner_; |
| 312 } | 314 } |
| 313 | 315 |
| 314 void RunnableMethodTraits<printing::PrintJobWorker>::ReleaseCallee( | 316 void RunnableMethodTraits<printing::PrintJobWorker>::ReleaseCallee( |
| 315 printing::PrintJobWorker* obj) { | 317 printing::PrintJobWorker* obj) { |
| 316 DCHECK_EQ(owner_, obj->owner_); | 318 DCHECK_EQ(owner_, obj->owner_); |
| 317 owner_ = NULL; | 319 owner_ = NULL; |
| 318 } | 320 } |
| OLD | NEW |