OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/chromeos/printing/cups_print_job_manager_impl.h" | 5 #include "chrome/browser/chromeos/printing/cups_print_job_manager_impl.h" |
6 | 6 |
7 #include <cups/cups.h> | 7 #include <cups/cups.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
11 #include <utility> | 11 #include <utility> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
17 #include "base/sequenced_task_runner.h" | |
17 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
18 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
19 #include "base/threading/sequenced_task_runner_handle.h" | 20 #include "base/task_scheduler/post_task.h" |
20 #include "base/threading/sequenced_worker_pool.h" | |
21 #include "chrome/browser/chrome_notification_types.h" | 21 #include "chrome/browser/chrome_notification_types.h" |
22 #include "chrome/browser/chromeos/printing/cups_print_job.h" | 22 #include "chrome/browser/chromeos/printing/cups_print_job.h" |
23 #include "chrome/browser/chromeos/printing/printers_manager.h" | 23 #include "chrome/browser/chromeos/printing/printers_manager.h" |
24 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" | 24 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" |
25 #include "chrome/browser/printing/print_job.h" | 25 #include "chrome/browser/printing/print_job.h" |
26 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
27 #include "content/public/browser/browser_context.h" | 27 #include "content/public/browser/browser_context.h" |
28 #include "content/public/browser/browser_thread.h" | |
29 #include "content/public/browser/notification_registrar.h" | 28 #include "content/public/browser/notification_registrar.h" |
30 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
31 #include "printing/backend/cups_connection.h" | 30 #include "printing/backend/cups_connection.h" |
32 #include "printing/printed_document.h" | 31 #include "printing/printed_document.h" |
33 | 32 |
34 namespace { | 33 namespace { |
35 | 34 |
36 // The rate in milliseconds at which we will poll CUPS for print job updates. | 35 // The rate in milliseconds at which we will poll CUPS for print job updates. |
37 const int kPollRate = 1000; | 36 const int kPollRate = 1000; |
38 | 37 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
97 break; | 96 break; |
98 } | 97 } |
99 | 98 |
100 NOTREACHED(); | 99 NOTREACHED(); |
101 | 100 |
102 return State::STATE_NONE; | 101 return State::STATE_NONE; |
103 } | 102 } |
104 | 103 |
105 chromeos::QueryResult QueryCups(::printing::CupsConnection* connection, | 104 chromeos::QueryResult QueryCups(::printing::CupsConnection* connection, |
106 const std::vector<std::string>& printer_ids) { | 105 const std::vector<std::string>& printer_ids) { |
106 base::ThreadRestrictions::AssertIOAllowed(); | |
107 chromeos::QueryResult result; | 107 chromeos::QueryResult result; |
108 result.success = connection->GetJobs(printer_ids, &result.queues); | 108 result.success = connection->GetJobs(printer_ids, &result.queues); |
109 return result; | 109 return result; |
110 } | 110 } |
111 | 111 |
112 // Returns true if |printer_status|.reasons contains |reason|. | 112 // Returns true if |printer_status|.reasons contains |reason|. |
113 bool ContainsReason(const printing::PrinterStatus printer_status, | 113 bool ContainsReason(const printing::PrinterStatus printer_status, |
114 PrinterReason::Reason reason) { | 114 PrinterReason::Reason reason) { |
115 return std::find_if(printer_status.reasons.begin(), | 115 return std::find_if(printer_status.reasons.begin(), |
116 printer_status.reasons.end(), | 116 printer_status.reasons.end(), |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 | 178 |
179 QueryResult::QueryResult() = default; | 179 QueryResult::QueryResult() = default; |
180 | 180 |
181 QueryResult::QueryResult(const QueryResult& other) = default; | 181 QueryResult::QueryResult(const QueryResult& other) = default; |
182 | 182 |
183 QueryResult::~QueryResult() = default; | 183 QueryResult::~QueryResult() = default; |
184 | 184 |
185 CupsPrintJobManagerImpl::CupsPrintJobManagerImpl(Profile* profile) | 185 CupsPrintJobManagerImpl::CupsPrintJobManagerImpl(Profile* profile) |
186 : CupsPrintJobManager(profile), | 186 : CupsPrintJobManager(profile), |
187 cups_connection_(GURL(), HTTP_ENCRYPT_NEVER, false), | 187 cups_connection_(GURL(), HTTP_ENCRYPT_NEVER, false), |
188 query_runner_(base::CreateSequencedTaskRunnerWithTraits( | |
189 base::TaskTraits(base::TaskPriority::BACKGROUND, | |
190 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN))), | |
188 weak_ptr_factory_(this) { | 191 weak_ptr_factory_(this) { |
189 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, | 192 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, |
190 content::NotificationService::AllSources()); | 193 content::NotificationService::AllSources()); |
191 } | 194 } |
192 | 195 |
193 CupsPrintJobManagerImpl::~CupsPrintJobManagerImpl() {} | 196 CupsPrintJobManagerImpl::~CupsPrintJobManagerImpl() {} |
194 | 197 |
195 // Must be run from the UI thread. | 198 // Must be run from the UI thread. |
196 void CupsPrintJobManagerImpl::CancelPrintJob(CupsPrintJob* job) { | 199 void CupsPrintJobManagerImpl::CancelPrintJob(CupsPrintJob* job) { |
197 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
Carlson
2017/06/20 19:02:09
Are you removing the requirement, or just the DCHE
skau
2017/06/24 01:03:44
The requirement still exits. It's now enforced as
| |
198 | |
199 // Copy job_id and printer_id. |job| is about to be freed. | 200 // Copy job_id and printer_id. |job| is about to be freed. |
200 const int job_id = job->job_id(); | 201 const int job_id = job->job_id(); |
201 const std::string printer_id = job->printer().id(); | 202 const std::string printer_id = job->printer().id(); |
202 | 203 |
203 // Stop montioring jobs after we cancel them. The user no longer cares. | 204 // Stop montioring jobs after we cancel them. The user no longer cares. |
204 jobs_.erase(job->GetUniqueId()); | 205 jobs_.erase(job->GetUniqueId()); |
205 | 206 |
206 // Be sure to copy out all relevant fields. |job| may be destroyed after we | 207 // Be sure to copy out all relevant fields. |job| may be destroyed after we |
207 // exit this scope. | 208 // exit this scope. |
208 content::BrowserThread::GetBlockingPool()->PostTask( | 209 base::PostTaskWithTraits( |
209 FROM_HERE, | 210 FROM_HERE, base::TaskTraits(base::TaskPriority::USER_VISIBLE), |
Carlson
2017/06/20 19:02:09
I don't understand how concurrency safety works wi
gab
2017/06/20 21:04:49
Right, seems this was racy before and still is..?
skau
2017/06/24 01:03:44
I've sequenced QueryJobs and CancelPrintJobImpl by
| |
210 base::Bind(&CupsPrintJobManagerImpl::CancelJobImpl, | 211 base::Bind(&CupsPrintJobManagerImpl::CancelJobImpl, |
211 weak_ptr_factory_.GetWeakPtr(), printer_id, job_id)); | 212 weak_ptr_factory_.GetWeakPtr(), printer_id, job_id)); |
212 } | 213 } |
213 | 214 |
214 bool CupsPrintJobManagerImpl::SuspendPrintJob(CupsPrintJob* job) { | 215 bool CupsPrintJobManagerImpl::SuspendPrintJob(CupsPrintJob* job) { |
215 NOTREACHED() << "Pause printer is not implemented"; | 216 NOTREACHED() << "Pause printer is not implemented"; |
216 return false; | 217 return false; |
217 } | 218 } |
218 | 219 |
219 bool CupsPrintJobManagerImpl::ResumePrintJob(CupsPrintJob* job) { | 220 bool CupsPrintJobManagerImpl::ResumePrintJob(CupsPrintJob* job) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 } | 278 } |
278 | 279 |
279 void CupsPrintJobManagerImpl::ScheduleQuery() { | 280 void CupsPrintJobManagerImpl::ScheduleQuery() { |
280 ScheduleQuery(base::TimeDelta::FromMilliseconds(kPollRate)); | 281 ScheduleQuery(base::TimeDelta::FromMilliseconds(kPollRate)); |
281 } | 282 } |
282 | 283 |
283 void CupsPrintJobManagerImpl::ScheduleQuery(const base::TimeDelta& delay) { | 284 void CupsPrintJobManagerImpl::ScheduleQuery(const base::TimeDelta& delay) { |
284 if (!in_query_) { | 285 if (!in_query_) { |
285 in_query_ = true; | 286 in_query_ = true; |
286 | 287 |
287 base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( | 288 query_runner_->PostDelayedTask( |
288 FROM_HERE, | 289 FROM_HERE, |
289 base::Bind(&CupsPrintJobManagerImpl::PostQuery, | 290 base::Bind(&CupsPrintJobManagerImpl::PostQuery, |
290 weak_ptr_factory_.GetWeakPtr()), | 291 weak_ptr_factory_.GetWeakPtr()), |
291 delay); | 292 delay); |
292 } | 293 } |
293 } | 294 } |
294 | 295 |
295 void CupsPrintJobManagerImpl::PostQuery() { | 296 void CupsPrintJobManagerImpl::PostQuery() { |
296 // The set of active printers is expected to be small. | 297 // The set of active printers is expected to be small. |
297 std::set<std::string> printer_ids; | 298 std::set<std::string> printer_ids; |
298 for (const auto& entry : jobs_) { | 299 for (const auto& entry : jobs_) { |
299 printer_ids.insert(entry.second->printer().id()); | 300 printer_ids.insert(entry.second->printer().id()); |
300 } | 301 } |
301 std::vector<std::string> ids{printer_ids.begin(), printer_ids.end()}; | 302 std::vector<std::string> ids{printer_ids.begin(), printer_ids.end()}; |
302 | 303 |
303 content::BrowserThread::PostTaskAndReplyWithResult( | 304 query_runner_->PostTaskAndReplyWithResult( |
304 content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE, | 305 FROM_HERE, base::Bind(&QueryCups, &cups_connection_, ids), |
skau
2017/06/20 01:24:17
This was higher than necessary.
| |
305 base::Bind(&QueryCups, &cups_connection_, ids), | |
306 base::Bind(&CupsPrintJobManagerImpl::UpdateJobs, | 306 base::Bind(&CupsPrintJobManagerImpl::UpdateJobs, |
307 weak_ptr_factory_.GetWeakPtr())); | 307 weak_ptr_factory_.GetWeakPtr())); |
308 } | 308 } |
309 | 309 |
310 bool CupsPrintJobManagerImpl::UpdatePrintJob( | 310 bool CupsPrintJobManagerImpl::UpdatePrintJob( |
311 const ::printing::PrinterStatus& printer_status, | 311 const ::printing::PrinterStatus& printer_status, |
312 const ::printing::CupsJob& job, | 312 const ::printing::CupsJob& job, |
313 CupsPrintJob* print_job) { | 313 CupsPrintJob* print_job) { |
314 DCHECK_EQ(job.id, print_job->job_id()); | 314 DCHECK_EQ(job.id, print_job->job_id()); |
315 | 315 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 break; | 472 break; |
473 } | 473 } |
474 } | 474 } |
475 | 475 |
476 // static | 476 // static |
477 CupsPrintJobManager* CupsPrintJobManager::CreateInstance(Profile* profile) { | 477 CupsPrintJobManager* CupsPrintJobManager::CreateInstance(Profile* profile) { |
478 return new CupsPrintJobManagerImpl(profile); | 478 return new CupsPrintJobManagerImpl(profile); |
479 } | 479 } |
480 | 480 |
481 } // namespace chromeos | 481 } // namespace chromeos |
OLD | NEW |