OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 DCHECK(base::MessageLoopForUI::IsCurrent() || | 55 DCHECK(base::MessageLoopForUI::IsCurrent() || |
56 base::MessageLoop::current()->type() == | 56 base::MessageLoop::current()->type() == |
57 base::MessageLoop::TYPE_DEFAULT); | 57 base::MessageLoop::TYPE_DEFAULT); |
58 } | 58 } |
59 | 59 |
60 PrintJob::~PrintJob() { | 60 PrintJob::~PrintJob() { |
61 // The job should be finished (or at least canceled) when it is destroyed. | 61 // The job should be finished (or at least canceled) when it is destroyed. |
62 DCHECK(!is_job_pending_); | 62 DCHECK(!is_job_pending_); |
63 DCHECK(!is_canceling_); | 63 DCHECK(!is_canceling_); |
64 DCHECK(!worker_ || !worker_->IsRunning()); | 64 DCHECK(!worker_ || !worker_->IsRunning()); |
65 DCHECK(RunsTasksOnCurrentThread()); | 65 DCHECK(RunsTasksInCurrentSequence()); |
66 } | 66 } |
67 | 67 |
68 void PrintJob::Initialize(PrintJobWorkerOwner* job, | 68 void PrintJob::Initialize(PrintJobWorkerOwner* job, |
69 PrintedPagesSource* source, | 69 PrintedPagesSource* source, |
70 int page_count) { | 70 int page_count) { |
71 DCHECK(!source_); | 71 DCHECK(!source_); |
72 DCHECK(!worker_); | 72 DCHECK(!worker_); |
73 DCHECK(!is_job_pending_); | 73 DCHECK(!is_job_pending_); |
74 DCHECK(!is_canceling_); | 74 DCHECK(!is_canceling_); |
75 DCHECK(!document_.get()); | 75 DCHECK(!document_.get()); |
(...skipping 10 matching lines...) Expand all Loading... |
86 UpdatePrintedDocument(new_doc); | 86 UpdatePrintedDocument(new_doc); |
87 | 87 |
88 // Don't forget to register to our own messages. | 88 // Don't forget to register to our own messages. |
89 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, | 89 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, |
90 content::Source<PrintJob>(this)); | 90 content::Source<PrintJob>(this)); |
91 } | 91 } |
92 | 92 |
93 void PrintJob::Observe(int type, | 93 void PrintJob::Observe(int type, |
94 const content::NotificationSource& source, | 94 const content::NotificationSource& source, |
95 const content::NotificationDetails& details) { | 95 const content::NotificationDetails& details) { |
96 DCHECK(RunsTasksOnCurrentThread()); | 96 DCHECK(RunsTasksInCurrentSequence()); |
97 DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type); | 97 DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type); |
98 | 98 |
99 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr()); | 99 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr()); |
100 } | 100 } |
101 | 101 |
102 void PrintJob::GetSettingsDone(const PrintSettings& new_settings, | 102 void PrintJob::GetSettingsDone(const PrintSettings& new_settings, |
103 PrintingContext::Result result) { | 103 PrintingContext::Result result) { |
104 NOTREACHED(); | 104 NOTREACHED(); |
105 } | 105 } |
106 | 106 |
107 std::unique_ptr<PrintJobWorker> PrintJob::DetachWorker( | 107 std::unique_ptr<PrintJobWorker> PrintJob::DetachWorker( |
108 PrintJobWorkerOwner* new_owner) { | 108 PrintJobWorkerOwner* new_owner) { |
109 NOTREACHED(); | 109 NOTREACHED(); |
110 return nullptr; | 110 return nullptr; |
111 } | 111 } |
112 | 112 |
113 const PrintSettings& PrintJob::settings() const { | 113 const PrintSettings& PrintJob::settings() const { |
114 return settings_; | 114 return settings_; |
115 } | 115 } |
116 | 116 |
117 int PrintJob::cookie() const { | 117 int PrintJob::cookie() const { |
118 // Always use an invalid cookie in this case. | 118 // Always use an invalid cookie in this case. |
119 if (!document_.get()) | 119 if (!document_.get()) |
120 return 0; | 120 return 0; |
121 return document_->cookie(); | 121 return document_->cookie(); |
122 } | 122 } |
123 | 123 |
124 void PrintJob::StartPrinting() { | 124 void PrintJob::StartPrinting() { |
125 DCHECK(RunsTasksOnCurrentThread()); | 125 DCHECK(RunsTasksInCurrentSequence()); |
126 if (!worker_->IsRunning() || is_job_pending_) { | 126 if (!worker_->IsRunning() || is_job_pending_) { |
127 NOTREACHED(); | 127 NOTREACHED(); |
128 return; | 128 return; |
129 } | 129 } |
130 | 130 |
131 // Real work is done in PrintJobWorker::StartPrinting(). | 131 // Real work is done in PrintJobWorker::StartPrinting(). |
132 worker_->PostTask(FROM_HERE, | 132 worker_->PostTask(FROM_HERE, |
133 base::Bind(&HoldRefCallback, make_scoped_refptr(this), | 133 base::Bind(&HoldRefCallback, make_scoped_refptr(this), |
134 base::Bind(&PrintJobWorker::StartPrinting, | 134 base::Bind(&PrintJobWorker::StartPrinting, |
135 base::Unretained(worker_.get()), | 135 base::Unretained(worker_.get()), |
136 base::RetainedRef(document_)))); | 136 base::RetainedRef(document_)))); |
137 // Set the flag right now. | 137 // Set the flag right now. |
138 is_job_pending_ = true; | 138 is_job_pending_ = true; |
139 | 139 |
140 // Tell everyone! | 140 // Tell everyone! |
141 scoped_refptr<JobEventDetails> details(new JobEventDetails( | 141 scoped_refptr<JobEventDetails> details(new JobEventDetails( |
142 JobEventDetails::NEW_DOC, 0, document_.get(), nullptr)); | 142 JobEventDetails::NEW_DOC, 0, document_.get(), nullptr)); |
143 content::NotificationService::current()->Notify( | 143 content::NotificationService::current()->Notify( |
144 chrome::NOTIFICATION_PRINT_JOB_EVENT, | 144 chrome::NOTIFICATION_PRINT_JOB_EVENT, |
145 content::Source<PrintJob>(this), | 145 content::Source<PrintJob>(this), |
146 content::Details<JobEventDetails>(details.get())); | 146 content::Details<JobEventDetails>(details.get())); |
147 } | 147 } |
148 | 148 |
149 void PrintJob::Stop() { | 149 void PrintJob::Stop() { |
150 DCHECK(RunsTasksOnCurrentThread()); | 150 DCHECK(RunsTasksInCurrentSequence()); |
151 | 151 |
152 if (quit_factory_.HasWeakPtrs()) { | 152 if (quit_factory_.HasWeakPtrs()) { |
153 // In case we're running a nested run loop to wait for a job to finish, | 153 // In case we're running a nested run loop to wait for a job to finish, |
154 // and we finished before the timeout, quit the nested loop right away. | 154 // and we finished before the timeout, quit the nested loop right away. |
155 Quit(); | 155 Quit(); |
156 quit_factory_.InvalidateWeakPtrs(); | 156 quit_factory_.InvalidateWeakPtrs(); |
157 } | 157 } |
158 | 158 |
159 // Be sure to live long enough. | 159 // Be sure to live long enough. |
160 scoped_refptr<PrintJob> handle(this); | 160 scoped_refptr<PrintJob> handle(this); |
161 | 161 |
162 if (worker_->IsRunning()) { | 162 if (worker_->IsRunning()) { |
163 ControlledWorkerShutdown(); | 163 ControlledWorkerShutdown(); |
164 } else { | 164 } else { |
165 // Flush the cached document. | 165 // Flush the cached document. |
166 is_job_pending_ = false; | 166 is_job_pending_ = false; |
167 UpdatePrintedDocument(nullptr); | 167 UpdatePrintedDocument(nullptr); |
168 } | 168 } |
169 } | 169 } |
170 | 170 |
171 void PrintJob::Cancel() { | 171 void PrintJob::Cancel() { |
172 if (is_canceling_) | 172 if (is_canceling_) |
173 return; | 173 return; |
174 is_canceling_ = true; | 174 is_canceling_ = true; |
175 | 175 |
176 // Be sure to live long enough. | 176 // Be sure to live long enough. |
177 scoped_refptr<PrintJob> handle(this); | 177 scoped_refptr<PrintJob> handle(this); |
178 | 178 |
179 DCHECK(RunsTasksOnCurrentThread()); | 179 DCHECK(RunsTasksInCurrentSequence()); |
180 if (worker_ && worker_->IsRunning()) { | 180 if (worker_ && worker_->IsRunning()) { |
181 // Call this right now so it renders the context invalid. Do not use | 181 // Call this right now so it renders the context invalid. Do not use |
182 // InvokeLater since it would take too much time. | 182 // InvokeLater since it would take too much time. |
183 worker_->Cancel(); | 183 worker_->Cancel(); |
184 } | 184 } |
185 // Make sure a Cancel() is broadcast. | 185 // Make sure a Cancel() is broadcast. |
186 scoped_refptr<JobEventDetails> details( | 186 scoped_refptr<JobEventDetails> details( |
187 new JobEventDetails(JobEventDetails::FAILED, 0, nullptr, nullptr)); | 187 new JobEventDetails(JobEventDetails::FAILED, 0, nullptr, nullptr)); |
188 content::NotificationService::current()->Notify( | 188 content::NotificationService::current()->Notify( |
189 chrome::NOTIFICATION_PRINT_JOB_EVENT, | 189 chrome::NOTIFICATION_PRINT_JOB_EVENT, |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 | 411 |
412 scoped_refptr<JobEventDetails> details(new JobEventDetails( | 412 scoped_refptr<JobEventDetails> details(new JobEventDetails( |
413 JobEventDetails::JOB_DONE, 0, document_.get(), nullptr)); | 413 JobEventDetails::JOB_DONE, 0, document_.get(), nullptr)); |
414 content::NotificationService::current()->Notify( | 414 content::NotificationService::current()->Notify( |
415 chrome::NOTIFICATION_PRINT_JOB_EVENT, | 415 chrome::NOTIFICATION_PRINT_JOB_EVENT, |
416 content::Source<PrintJob>(this), | 416 content::Source<PrintJob>(this), |
417 content::Details<JobEventDetails>(details.get())); | 417 content::Details<JobEventDetails>(details.get())); |
418 } | 418 } |
419 | 419 |
420 void PrintJob::ControlledWorkerShutdown() { | 420 void PrintJob::ControlledWorkerShutdown() { |
421 DCHECK(RunsTasksOnCurrentThread()); | 421 DCHECK(RunsTasksInCurrentSequence()); |
422 | 422 |
423 // The deadlock this code works around is specific to window messaging on | 423 // The deadlock this code works around is specific to window messaging on |
424 // Windows, so we aren't likely to need it on any other platforms. | 424 // Windows, so we aren't likely to need it on any other platforms. |
425 #if defined(OS_WIN) | 425 #if defined(OS_WIN) |
426 // We could easily get into a deadlock case if worker_->Stop() is used; the | 426 // We could easily get into a deadlock case if worker_->Stop() is used; the |
427 // printer driver created a window as a child of the browser window. By | 427 // printer driver created a window as a child of the browser window. By |
428 // canceling the job, the printer driver initiated dialog box is destroyed, | 428 // canceling the job, the printer driver initiated dialog box is destroyed, |
429 // which sends a blocking message to its parent window. If the browser window | 429 // which sends a blocking message to its parent window. If the browser window |
430 // thread is not processing messages, a deadlock occurs. | 430 // thread is not processing messages, a deadlock occurs. |
431 // | 431 // |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 : document_(document), page_(page), type_(type), job_id_(job_id) {} | 476 : document_(document), page_(page), type_(type), job_id_(job_id) {} |
477 | 477 |
478 JobEventDetails::~JobEventDetails() { | 478 JobEventDetails::~JobEventDetails() { |
479 } | 479 } |
480 | 480 |
481 PrintedDocument* JobEventDetails::document() const { return document_.get(); } | 481 PrintedDocument* JobEventDetails::document() const { return document_.get(); } |
482 | 482 |
483 PrintedPage* JobEventDetails::page() const { return page_.get(); } | 483 PrintedPage* JobEventDetails::page() const { return page_.get(); } |
484 | 484 |
485 } // namespace printing | 485 } // namespace printing |
OLD | NEW |