Home | History | Annotate | Download | only in cloud_print
      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 
     21 bool IsTerminalJobState(PrintJobStatus status) {
     22   return status == PRINT_JOB_STATUS_ERROR ||
     23          status == PRINT_JOB_STATUS_COMPLETED;
     24 }
     25 
     26 }  // namespace
     27 
     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.
     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 
     89 void JobStatusUpdater::Stop() {
     90   request_ = NULL;
     91   DCHECK(delegate_);
     92   stopped_ = true;
     93   delegate_->OnJobCompleted(this);
     94 }
     95 
     96 // CloudPrintURLFetcher::Delegate implementation.
     97 CloudPrintURLFetcher::ResponseAction JobStatusUpdater::HandleJSONData(
     98       const net::URLFetcher* source,
     99       const GURL& url,
    100       base::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 
    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 
    119 std::string JobStatusUpdater::GetAuthHeader() {
    120   return GetCloudPrintAuthHeaderFromStore();
    121 }
    122 
    123 JobStatusUpdater::~JobStatusUpdater() {}
    124 
    125 }  // namespace cloud_print
    126