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/stl_util.h" | 17 #include "base/stl_util.h" |
| 17 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| 18 #include "base/threading/sequenced_task_runner_handle.h" | 19 #include "base/threading/sequenced_task_runner_handle.h" |
| 19 #include "base/threading/sequenced_worker_pool.h" | 20 #include "base/threading/sequenced_worker_pool.h" |
| 20 #include "chrome/browser/chrome_notification_types.h" | 21 #include "chrome/browser/chrome_notification_types.h" |
| 21 #include "chrome/browser/chromeos/printing/cups_print_job.h" | 22 #include "chrome/browser/chromeos/printing/cups_print_job.h" |
| 22 #include "chrome/browser/chromeos/printing/printers_manager.h" | 23 #include "chrome/browser/chromeos/printing/printers_manager.h" |
| 23 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" | 24 #include "chrome/browser/chromeos/printing/printers_manager_factory.h" |
| 24 #include "chrome/browser/printing/print_job.h" | 25 #include "chrome/browser/printing/print_job.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 39 const int kConnectingTimeout = 20; | 40 const int kConnectingTimeout = 20; |
| 40 | 41 |
| 41 // Threshold for giving up on communicating with CUPS. | 42 // Threshold for giving up on communicating with CUPS. |
| 42 const int kRetryMax = 6; | 43 const int kRetryMax = 6; |
| 43 | 44 |
| 44 using State = chromeos::CupsPrintJob::State; | 45 using State = chromeos::CupsPrintJob::State; |
| 45 using ErrorCode = chromeos::CupsPrintJob::ErrorCode; | 46 using ErrorCode = chromeos::CupsPrintJob::ErrorCode; |
| 46 | 47 |
| 47 using PrinterReason = printing::PrinterStatus::PrinterReason; | 48 using PrinterReason = printing::PrinterStatus::PrinterReason; |
| 48 | 49 |
| 50 // Enumeration of print job results for histograms. Do not modify! | |
| 51 enum JobResult { | |
|
Carlson
2017/05/25 16:27:17
If this is specific to histograms, can the enum na
skau
2017/05/25 18:45:40
Done.
| |
| 52 UNKNOWN = 0, // unidentified result | |
| 53 FINISHED = 1, // successful completion of job | |
| 54 TIMEOUT_CANCEL = 2, // cancelled due to timeout | |
| 55 PRINTER_CANCEL = 3, // cancelled by printer | |
| 56 LOST = 4, // final state never received | |
| 57 RESULT_MAX | |
| 58 }; | |
| 59 | |
| 60 // Returns the appropriate JobResult for a given |state|. Only FINISHED and | |
| 61 // PRINTER_CANCEL are derived from CupsPrintJob::State. | |
| 62 JobResult ResultForHistogram(State state) { | |
| 63 switch (state) { | |
| 64 case State::STATE_DOCUMENT_DONE: | |
| 65 return FINISHED; | |
| 66 case State::STATE_CANCELLED: | |
| 67 return PRINTER_CANCEL; | |
| 68 default: | |
| 69 break; | |
| 70 } | |
| 71 | |
| 72 return UNKNOWN; | |
| 73 } | |
| 74 | |
| 49 // Returns the equivalient CupsPrintJob#State from a CupsJob#JobState. | 75 // Returns the equivalient CupsPrintJob#State from a CupsJob#JobState. |
| 50 chromeos::CupsPrintJob::State ConvertState(printing::CupsJob::JobState state) { | 76 chromeos::CupsPrintJob::State ConvertState(printing::CupsJob::JobState state) { |
| 51 switch (state) { | 77 switch (state) { |
| 52 case printing::CupsJob::PENDING: | 78 case printing::CupsJob::PENDING: |
| 53 return State::STATE_WAITING; | 79 return State::STATE_WAITING; |
| 54 case printing::CupsJob::HELD: | 80 case printing::CupsJob::HELD: |
| 55 return State::STATE_SUSPENDED; | 81 return State::STATE_SUSPENDED; |
| 56 case printing::CupsJob::PROCESSING: | 82 case printing::CupsJob::PROCESSING: |
| 57 return State::STATE_STARTED; | 83 return State::STATE_STARTED; |
| 58 case printing::CupsJob::CANCELED: | 84 case printing::CupsJob::CANCELED: |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 int total_page_number) { | 242 int total_page_number) { |
| 217 auto printer = | 243 auto printer = |
| 218 PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinter( | 244 PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinter( |
| 219 printer_name); | 245 printer_name); |
| 220 if (!printer) { | 246 if (!printer) { |
| 221 LOG(WARNING) << "Printer was removed while job was in progress. It cannot " | 247 LOG(WARNING) << "Printer was removed while job was in progress. It cannot " |
| 222 "be tracked"; | 248 "be tracked"; |
| 223 return false; | 249 return false; |
| 224 } | 250 } |
| 225 | 251 |
| 252 // Records the number of jobs we're currently tracking when a new job is | |
| 253 // started. This is equivalent to print queue size in the current | |
| 254 // implementation. | |
| 255 UMA_HISTOGRAM_EXACT_LINEAR("CUPS.PrintJobsQueued", jobs_.size(), 20); | |
| 256 | |
| 226 // Create a new print job. | 257 // Create a new print job. |
| 227 auto cpj = base::MakeUnique<CupsPrintJob>(*printer, job_id, title, | 258 auto cpj = base::MakeUnique<CupsPrintJob>(*printer, job_id, title, |
| 228 total_page_number); | 259 total_page_number); |
| 229 std::string key = cpj->GetUniqueId(); | 260 std::string key = cpj->GetUniqueId(); |
| 230 jobs_[key] = std::move(cpj); | 261 jobs_[key] = std::move(cpj); |
| 231 | 262 |
| 232 CupsPrintJob* job = jobs_[key].get(); | 263 CupsPrintJob* job = jobs_[key].get(); |
| 233 NotifyJobCreated(job); | 264 NotifyJobCreated(job); |
| 234 | 265 |
| 235 // Always start jobs in the waiting state. | 266 // Always start jobs in the waiting state. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 347 | 378 |
| 348 CupsPrintJob* print_job = entry->second.get(); | 379 CupsPrintJob* print_job = entry->second.get(); |
| 349 | 380 |
| 350 if (UpdatePrintJob(queue.printer_status, job, print_job)) { | 381 if (UpdatePrintJob(queue.printer_status, job, print_job)) { |
| 351 // The state of the job changed, notify observers. | 382 // The state of the job changed, notify observers. |
| 352 NotifyJobStateUpdate(print_job); | 383 NotifyJobStateUpdate(print_job); |
| 353 } | 384 } |
| 354 | 385 |
| 355 if (print_job->expired()) { | 386 if (print_job->expired()) { |
| 356 // Job needs to be forcibly cancelled. | 387 // Job needs to be forcibly cancelled. |
| 388 UMA_HISTOGRAM_ENUMERATION("CUPS.JobResult", TIMEOUT_CANCEL, RESULT_MAX); | |
| 357 CancelPrintJob(print_job); | 389 CancelPrintJob(print_job); |
| 358 // Beware, print_job was removed from jobs_ and deleted. | 390 // Beware, print_job was removed from jobs_ and deleted. |
| 359 } else if (print_job->IsJobFinished()) { | 391 } else if (print_job->IsJobFinished()) { |
| 360 // Cleanup completed jobs. | 392 // Cleanup completed jobs. |
| 393 UMA_HISTOGRAM_ENUMERATION("CUPS.JobResult", | |
| 394 ResultForHistogram(print_job->state()), | |
| 395 RESULT_MAX); | |
| 361 jobs_.erase(entry); | 396 jobs_.erase(entry); |
| 362 } else { | 397 } else { |
| 363 active_jobs.push_back(key); | 398 active_jobs.push_back(key); |
| 364 } | 399 } |
| 365 } | 400 } |
| 366 } | 401 } |
| 367 | 402 |
| 368 // Keep polling until all jobs complete or error. | 403 // Keep polling until all jobs complete or error. |
| 369 if (!active_jobs.empty()) { | 404 if (!active_jobs.empty()) { |
| 370 // During normal operations, we poll at the default rate. | 405 // During normal operations, we poll at the default rate. |
| 371 ScheduleQuery(); | 406 ScheduleQuery(); |
| 372 } else if (!jobs_.empty()) { | 407 } else if (!jobs_.empty()) { |
| 373 // We're tracking jobs that we didn't receive an update for. Something bad | 408 // We're tracking jobs that we didn't receive an update for. Something bad |
| 374 // has happened. | 409 // has happened. |
| 375 LOG(ERROR) << "Lost track of (" << jobs_.size() << ") jobs"; | 410 LOG(ERROR) << "Lost track of (" << jobs_.size() << ") jobs"; |
| 376 PurgeJobs(); | 411 PurgeJobs(); |
| 377 } | 412 } |
| 378 } | 413 } |
| 379 | 414 |
| 380 void CupsPrintJobManagerImpl::PurgeJobs() { | 415 void CupsPrintJobManagerImpl::PurgeJobs() { |
| 381 for (const auto& entry : jobs_) { | 416 for (const auto& entry : jobs_) { |
| 382 // Declare all lost jobs errors. | 417 // Declare all lost jobs errors. |
| 418 UMA_HISTOGRAM_ENUMERATION("CUPS.JobResult", LOST, RESULT_MAX); | |
|
Alexei Svitkine (slow)
2017/05/25 15:13:56
Please make a helper function for logging this his
skau
2017/05/25 18:45:40
Done.
| |
| 383 CupsPrintJob* job = entry.second.get(); | 419 CupsPrintJob* job = entry.second.get(); |
| 384 job->set_state(CupsPrintJob::State::STATE_ERROR); | 420 job->set_state(CupsPrintJob::State::STATE_ERROR); |
| 385 NotifyJobStateUpdate(job); | 421 NotifyJobStateUpdate(job); |
| 386 } | 422 } |
| 387 | 423 |
| 388 jobs_.clear(); | 424 jobs_.clear(); |
| 389 } | 425 } |
| 390 | 426 |
| 391 void CupsPrintJobManagerImpl::CancelJobImpl(const std::string& printer_id, | 427 void CupsPrintJobManagerImpl::CancelJobImpl(const std::string& printer_id, |
| 392 const int job_id) { | 428 const int job_id) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 break; | 470 break; |
| 435 } | 471 } |
| 436 } | 472 } |
| 437 | 473 |
| 438 // static | 474 // static |
| 439 CupsPrintJobManager* CupsPrintJobManager::CreateInstance(Profile* profile) { | 475 CupsPrintJobManager* CupsPrintJobManager::CreateInstance(Profile* profile) { |
| 440 return new CupsPrintJobManagerImpl(profile); | 476 return new CupsPrintJobManagerImpl(profile); |
| 441 } | 477 } |
| 442 | 478 |
| 443 } // namespace chromeos | 479 } // namespace chromeos |
| OLD | NEW |