Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2680)

Unified Diff: chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc

Issue 2691093006: Implement IPP Get-Jobs and Get-Printer-Attributes requests. (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
index d333cb94627dfad9331afc59102276e97efb1daa..16be4881082c354374dccec85f3eb31b9af16bc1 100644
--- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
+++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
@@ -33,6 +33,9 @@ namespace {
// The rate in milliseconds at which we will poll CUPS for print job updates.
const int kPollRate = 1000;
+// Threshold for giving up on communicating with CUPS.
+const int kRetryMax = 6;
+
// Returns the equivalient CupsPrintJob#State from a CupsJob#JobState.
chromeos::CupsPrintJob::State ConvertState(printing::CupsJob::JobState state) {
using cpj = chromeos::CupsPrintJob::State;
@@ -61,6 +64,13 @@ chromeos::CupsPrintJob::State ConvertState(printing::CupsJob::JobState state) {
return cpj::STATE_NONE;
}
+chromeos::QueryResult QueryCups(::printing::CupsConnection* connection,
+ const std::vector<std::string>& printer_ids) {
+ chromeos::QueryResult result;
+ result.success = connection->GetJobs(printer_ids, &(result.queues));
Lei Zhang 2017/03/07 23:31:29 nit: Do you need the extra parenthesis around resu
skau 2017/03/10 01:07:00 Done.
+ return result;
+}
+
} // namespace
namespace chromeos {
@@ -134,6 +144,7 @@ bool CupsPrintJobManagerImpl::CreatePrintJob(const std::string& printer_name,
total_page_number);
std::string key = cpj->GetUniqueId();
jobs_[key] = std::move(cpj);
+
CupsPrintJob* job = jobs_[key].get();
NotifyJobCreated(job);
@@ -153,36 +164,68 @@ void CupsPrintJobManagerImpl::ScheduleQuery() {
void CupsPrintJobManagerImpl::ScheduleQuery(const base::TimeDelta& delay) {
if (!in_query_) {
in_query_ = true;
- content::BrowserThread::PostDelayedTask(
- content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE,
- base::Bind(&CupsPrintJobManagerImpl::QueryCups,
+
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&CupsPrintJobManagerImpl::PostQuery,
weak_ptr_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kPollRate));
+ delay);
}
}
// Query CUPS asynchronously. Post results back to UI thread.
Lei Zhang 2017/03/07 23:31:29 Can you move this to the header and consolidate it
skau 2017/03/10 01:07:00 Done.
-void CupsPrintJobManagerImpl::QueryCups() {
- std::vector<::printing::CupsJob> jobs = cups_connection_.GetJobs();
+void CupsPrintJobManagerImpl::PostQuery() {
+ // The set of active printers is expected to be small.
+ std::set<std::string> printer_ids;
+ for (const auto& entry : jobs_) {
+ printer_ids.insert(entry.second->printer().id());
+ }
+ std::vector<std::string> ids{printer_ids.begin(), printer_ids.end()};
- content::BrowserThread::PostTask(
- content::BrowserThread::ID::UI, FROM_HERE,
+ content::BrowserThread::PostTaskAndReplyWithResult(
+ content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE,
+ base::Bind(&QueryCups, &cups_connection_, ids),
base::Bind(&CupsPrintJobManagerImpl::UpdateJobs,
- weak_ptr_factory_.GetWeakPtr(), jobs));
+ weak_ptr_factory_.GetWeakPtr()));
}
// Use job information to update local job states. Previously completed jobs
// could be in |jobs| but those are ignored as we will not emit updates for them
// after they are completed.
-void CupsPrintJobManagerImpl::UpdateJobs(
- const std::vector<::printing::CupsJob>& jobs) {
+void CupsPrintJobManagerImpl::UpdateJobs(const QueryResult& result) {
+ const std::vector<::printing::QueueStatus>& queues = result.queues;
+
+ // Query has completed. Allow more queries.
in_query_ = false;
+ // If the query failed, either retry or purge.
+ if (!result.success) {
+ retry_count_++;
+ LOG(WARNING) << "Failed to query CUPS for queue status. Schedule retry ("
+ << retry_count_ << ")";
+ if (retry_count_ > kRetryMax) {
+ LOG(ERROR) << "CUPS is unreachable. Giving up on all jobs.";
+ PurgeJobs();
+ } else {
+ // Schedule another query with a larger delay.
+ DCHECK_GE(1, retry_count_);
+ ScheduleQuery(
+ base::TimeDelta::FromMilliseconds(kPollRate * retry_count_));
+ }
+ return;
+ }
+
+ // A query has completed. Reset retry counter.
+ retry_count_ = 0;
+
std::vector<std::string> active_jobs;
- for (auto& job : jobs) {
- std::string key = CupsPrintJob::GetUniqueId(job.printer_id, job.id);
- const auto& entry = jobs_.find(key);
- if (entry != jobs_.end()) {
+ for (const auto& queue : queues) {
+ for (auto& job : queue.jobs) {
+ std::string key = CupsPrintJob::GetUniqueId(job.printer_id, job.id);
+ const auto& entry = jobs_.find(key);
+ if (entry == jobs_.end())
+ continue;
+
CupsPrintJob* print_job = entry->second.get();
// Update a job we're tracking.
@@ -199,18 +242,23 @@ void CupsPrintJobManagerImpl::UpdateJobs(
// Keep polling until all jobs complete or error.
if (!active_jobs.empty()) {
+ // During normal operations, we poll at the default rate.
ScheduleQuery();
} else if (!jobs_.empty()) {
// We're tracking jobs that we didn't receive an update for. Something bad
// has happened.
LOG(ERROR) << "Lost track of (" << jobs_.size() << ") jobs";
- for (const auto& entry : jobs_) {
- // Declare all lost jobs errors.
- JobStateUpdated(entry.second.get(), CupsPrintJob::State::STATE_ERROR);
- }
+ PurgeJobs();
+ }
+}
- jobs_.clear();
+void CupsPrintJobManagerImpl::PurgeJobs() {
+ for (const auto& entry : jobs_) {
+ // Declare all lost jobs errors.
+ JobStateUpdated(entry.second.get(), CupsPrintJob::State::STATE_ERROR);
}
+
+ jobs_.clear();
}
void CupsPrintJobManagerImpl::JobStateUpdated(CupsPrintJob* job,

Powered by Google App Engine
This is Rietveld 408576698