Chromium Code Reviews| 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 |