• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/service/cloud_print/job_status_updater.h"
6 
7 #include "base/bind.h"
8 #include "base/json/json_reader.h"
9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/common/cloud_print/cloud_print_constants.h"
14 #include "chrome/service/cloud_print/cloud_print_service_helpers.h"
15 #include "url/gurl.h"
16 
17 namespace cloud_print {
18 
19 namespace {
20 
IsTerminalJobState(PrintJobStatus status)21 bool IsTerminalJobState(PrintJobStatus status) {
22   return status == PRINT_JOB_STATUS_ERROR ||
23          status == PRINT_JOB_STATUS_COMPLETED;
24 }
25 
26 }  // namespace
27 
JobStatusUpdater(const std::string & printer_name,const std::string & job_id,PlatformJobId & local_job_id,const GURL & cloud_print_server_url,PrintSystem * print_system,Delegate * delegate)28 JobStatusUpdater::JobStatusUpdater(const std::string& printer_name,
29                                    const std::string& job_id,
30                                    PlatformJobId& local_job_id,
31                                    const GURL& cloud_print_server_url,
32                                    PrintSystem* print_system,
33                                    Delegate* delegate)
34     : start_time_(base::Time::Now()),
35       printer_name_(printer_name),
36       job_id_(job_id),
37       local_job_id_(local_job_id),
38       cloud_print_server_url_(cloud_print_server_url),
39       print_system_(print_system),
40       delegate_(delegate),
41       stopped_(false) {
42   DCHECK(delegate_);
43 }
44 
45 // Start checking the status of the local print job.
UpdateStatus()46 void JobStatusUpdater::UpdateStatus() {
47   // It does not matter if we had already sent out an update and are waiting for
48   // a response. This is a new update and we will simply cancel the old request
49   // and send a new one.
50   if (!stopped_) {
51     bool need_update = false;
52     // If the job has already been completed, we just need to update the server
53     // with that status. The *only* reason we would come back here in that case
54     // is if our last server update attempt failed.
55     if (IsTerminalJobState(last_job_details_.status)) {
56       need_update = true;
57     } else {
58       PrintJobDetails details;
59       if (print_system_->GetJobDetails(printer_name_, local_job_id_,
60                                        &details)) {
61         if (details != last_job_details_) {
62           last_job_details_ = details;
63           need_update = true;
64         }
65       } else {
66         // If GetJobDetails failed, the most likely case is that the job no
67         // longer exists in the OS queue. We are going to assume it is done in
68         // this case.
69         last_job_details_.Clear();
70         last_job_details_.status = PRINT_JOB_STATUS_COMPLETED;
71         need_update = true;
72       }
73       UMA_HISTOGRAM_ENUMERATION("CloudPrint.NativeJobStatus",
74                                 last_job_details_.status, PRINT_JOB_STATUS_MAX);
75     }
76     if (need_update) {
77       request_ = CloudPrintURLFetcher::Create();
78       request_->StartGetRequest(
79           CloudPrintURLFetcher::REQUEST_UPDATE_JOB,
80           GetUrlForJobStatusUpdate(
81               cloud_print_server_url_, job_id_, last_job_details_),
82           this,
83           kCloudPrintAPIMaxRetryCount,
84           std::string());
85     }
86   }
87 }
88 
Stop()89 void JobStatusUpdater::Stop() {
90   request_ = NULL;
91   DCHECK(delegate_);
92   stopped_ = true;
93   delegate_->OnJobCompleted(this);
94 }
95 
96 // CloudPrintURLFetcher::Delegate implementation.
HandleJSONData(const net::URLFetcher * source,const GURL & url,DictionaryValue * json_data,bool succeeded)97 CloudPrintURLFetcher::ResponseAction JobStatusUpdater::HandleJSONData(
98       const net::URLFetcher* source,
99       const GURL& url,
100       DictionaryValue* json_data,
101       bool succeeded) {
102   if (IsTerminalJobState(last_job_details_.status)) {
103     base::MessageLoop::current()->PostTask(
104         FROM_HERE, base::Bind(&JobStatusUpdater::Stop, this));
105   }
106   return CloudPrintURLFetcher::STOP_PROCESSING;
107 }
108 
OnRequestAuthError()109 CloudPrintURLFetcher::ResponseAction JobStatusUpdater::OnRequestAuthError() {
110   // We got an Auth error and have no idea how long it will take to refresh
111   // auth information (may take forever). We'll drop current request and
112   // propagate this error to the upper level. After auth issues will be
113   // resolved, GCP connector will restart.
114   if (delegate_)
115     delegate_->OnAuthError();
116   return CloudPrintURLFetcher::STOP_PROCESSING;
117 }
118 
GetAuthHeader()119 std::string JobStatusUpdater::GetAuthHeader() {
120   return GetCloudPrintAuthHeaderFromStore();
121 }
122 
~JobStatusUpdater()123 JobStatusUpdater::~JobStatusUpdater() {}
124 
125 }  // namespace cloud_print
126