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

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: assign default values to id and state 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 468adc44817cf85085233f8c64c358a097b80695..11054845e727e176b15bb57c8a911c4fc1b6a653 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;
@@ -69,6 +72,13 @@ bool JobFinished(chromeos::CupsPrintJob::State state) {
state == CupsPrintJob::State::STATE_DOCUMENT_DONE;
}
+chromeos::QueryResult QueryCups(::printing::CupsConnection* connection,
+ const std::vector<std::string>& printer_ids) {
+ chromeos::QueryResult result;
+ result.success = connection->GetJobs(printer_ids, &(result.queues));
+ return result;
+}
+
} // namespace
namespace chromeos {
@@ -142,6 +152,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);
@@ -161,36 +172,67 @@ 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.
-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) {
+ PurgeJobs();
Carlson 2017/02/24 00:02:08 Does this deserve a "Giving up" log message?
skau 2017/02/28 00:59:58 Done.
+ } else {
+ // Schedule another query with a larger delay.
+ DCHECK_GE(1, retry_count);
+ ScheduleQuery(base::TimeDelta::FromMilliseconds(kPollRate * retry_count));
+ }
+
Carlson 2017/02/24 00:02:08 Nit: Remove blank line
skau 2017/02/28 00:59:58 Done.
+ 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.
@@ -212,13 +254,17 @@ void CupsPrintJobManagerImpl::UpdateJobs(
// 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