Index: chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_print_to_phone_jobs_fetcher.cc |
diff --git a/chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_print_to_phone_jobs_fetcher.cc b/chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_print_to_phone_jobs_fetcher.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..85a06cb1f75630e8bc18228d9381b5cec2954812 |
--- /dev/null |
+++ b/chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_print_to_phone_jobs_fetcher.cc |
@@ -0,0 +1,217 @@ |
+// Copyright 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_print_to_phone_jobs_fetcher.h" |
+ |
+#include <vector> |
+ |
+#include "base/values.h" |
+#include "chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_receive_util.h" |
+#include "chrome/common/cloud_print/cloud_print_consts.h" |
+#include "chrome/common/cloud_print/cloud_print_helpers.h" |
+ |
+namespace chrome_to_mobile_receive { |
+ |
+ChromeToMobilePrintToPhoneJobsFetcher::ChromeToMobilePrintToPhoneJobsFetcher( |
+ const GURL& cloud_print_server_url, |
+ const std::string& printer_id, |
+ const chrome_to_mobile::CloudPrintRequest::Settings& settings, |
+ ChromeToMobilePrintToPhoneJobsFetcher::Consumer* consumer) |
+ : cloud_print_server_url_(cloud_print_server_url), |
+ printer_id_(printer_id), |
+ settings_(settings), |
+ consumer_(consumer) { |
+ DCHECK(consumer); |
+} |
+ |
+ChromeToMobilePrintToPhoneJobsFetcher:: |
+ ~ChromeToMobilePrintToPhoneJobsFetcher() { |
+ CancelAllRequests(); |
+} |
+ |
+void ChromeToMobilePrintToPhoneJobsFetcher::CancelAllRequests() { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ if (HasProcessedAllFetchInvocations()) |
+ return; |
+ |
+ for (RequestMap::const_iterator it = pending_download_requests_.begin(); |
+ it != pending_download_requests_.end(); ++it) { |
+ consumer_->OnPrintToPhoneJobDownloadComplete( |
+ it->first, false, std::string(), std::string()); |
+ delete it->second; |
+ } |
+ pending_download_requests_.clear(); |
+ |
+ for (RequestMap::const_iterator it = pending_job_update_requests_.begin(); |
+ it != pending_job_update_requests_.end(); ++it) { |
+ delete it->second; |
+ } |
+ pending_job_update_requests_.clear(); |
+ |
+ fetch_request_.reset(); |
+ |
+ consumer_->OnPrintJobsFetchComplete(this); |
+} |
+ |
+void ChromeToMobilePrintToPhoneJobsFetcher::Fetch() { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ fetch_request_.reset( |
+ chrome_to_mobile::CloudPrintRequest::CreateAndStartGetRequest( |
+ cloud_print::GetUrlForJobFetch( |
+ cloud_print_server_url_, printer_id_, std::string()), |
+ settings_, |
+ this)); |
+} |
+ |
+void ChromeToMobilePrintToPhoneJobsFetcher::OnRequestComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ has_oauth2_token_fetch_failure_ = source->HasOAuth2AccessTokenFailure(); |
+ has_cloud_print_auth_error_ = source->HasCloudPrintAuthError(); |
+ if (has_oauth2_token_fetch_failure_ || has_cloud_print_auth_error_) { |
+ CancelAllRequests(); |
+ return; |
+ } |
+ |
+ if (!HandleFetchComplete(source)) { |
+ if (!HandleDownloadComplete(source)) |
+ HandleJobUpdateComplete(source); |
+ } |
+ |
+ if (HasProcessedAllFetchInvocations()) |
+ consumer_->OnPrintJobsFetchComplete(this); |
+} |
+ |
+bool ChromeToMobilePrintToPhoneJobsFetcher::HandleFetchComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ DCHECK(CalledOnValidThread()); |
+ if (source != fetch_request_.get()) |
+ return false; |
+ |
+ scoped_ptr<chrome_to_mobile::CloudPrintRequest> to_be_release( |
+ fetch_request_.release()); |
+ |
+ bool succeeded; |
+ std::string response_data = source->GetResponseData(&succeeded); |
+ scoped_ptr<base::DictionaryValue> response_dict_to_be_release; |
+ base::DictionaryValue* response_dict = NULL; |
+ if (succeeded) { |
+ cloud_print::ParseResponseJSON(response_data, &succeeded, &response_dict); |
+ response_dict_to_be_release.reset(response_dict); |
+ } |
+ base::ListValue* job_list = NULL; |
+ if (succeeded && response_dict) |
+ succeeded = response_dict->GetList(cloud_print::kJobListValue, &job_list); |
+ |
+ if (!succeeded || !job_list) |
+ return true; |
+ |
+ for (size_t index = 0; index < job_list->GetSize(); ++index) { |
+ std::string job_id; |
+ std::string title; |
+ std::string download_url; |
+ if (!ParseQueuedPrintToPhoneJobFromFetchJobList( |
+ job_list, index, &job_id, &title, &download_url) || |
+ download_url.empty()) { |
+ continue; |
+ } |
+ // No action if this job is being downloaded or updated. |
+ if (pending_download_requests_.find(job_id) != |
+ pending_download_requests_.end() || |
+ pending_job_update_requests_.find(job_id) != |
+ pending_job_update_requests_.end()) { |
+ continue; |
+ } |
+ |
+ pending_download_requests_[job_id] = |
+ chrome_to_mobile::CloudPrintRequest::CreateAndStart( |
+ GURL(download_url), std::string("Accept: application/pdf"), |
+ net::URLFetcher::GET, std::string(), std::string(), |
+ settings_, this); |
+ consumer_->OnPrintToPhoneJobDownloadStart(job_id, title); |
+ } |
+ |
+ return true; |
+} |
+ |
+bool ChromeToMobilePrintToPhoneJobsFetcher::HandleDownloadComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ for (RequestMap::const_iterator it = pending_download_requests_.begin(); |
+ it != pending_download_requests_.end(); |
+ ++it) { |
+ if (it->second != source) |
+ continue; |
+ |
+ scoped_ptr<chrome_to_mobile::CloudPrintRequest> to_be_release(source); |
+ std::string job_id = it->first; |
+ pending_download_requests_.erase(job_id); |
+ |
+ bool success; |
+ std::string data = source->GetResponseData(&success); |
+ if (!success) { |
+ consumer_->OnPrintToPhoneJobDownloadComplete( |
+ job_id, false, std::string(), std::string()); |
+ } else { |
+ consumer_->OnPrintToPhoneJobDownloadComplete( |
+ job_id, true, source->GetResponseMimeType(), data); |
+ pending_job_update_requests_[job_id] = |
+ chrome_to_mobile::CloudPrintRequest::CreateAndStartGetRequest( |
+ cloud_print::GetUrlForJobStatusUpdate( |
+ cloud_print_server_url_, job_id, "DONE"), |
+ settings_, |
+ this); |
+ } |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
+bool ChromeToMobilePrintToPhoneJobsFetcher::HandleJobUpdateComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ for (RequestMap::const_iterator it = pending_job_update_requests_.begin(); |
+ it != pending_job_update_requests_.end(); |
+ ++it) { |
+ if (it->second != source) |
+ continue; |
+ |
+ scoped_ptr<chrome_to_mobile::CloudPrintRequest> to_be_release(source); |
+ std::string job_id = it->first; |
+ pending_job_update_requests_.erase(job_id); |
+ |
+ bool success; |
+ std::string data = source->GetResponseData(&success); |
+ if (!success) |
+ LOG(ERROR) << "Fail to update job with id " << job_id; |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+bool ChromeToMobilePrintToPhoneJobsFetcher::HasCloudPrintAuthError() const { |
+ DCHECK(CalledOnValidThread()); |
+ return has_cloud_print_auth_error_; |
+} |
+ |
+bool ChromeToMobilePrintToPhoneJobsFetcher::HasOAuth2AccessTokenFailure() |
+ const { |
+ DCHECK(CalledOnValidThread()); |
+ return has_oauth2_token_fetch_failure_; |
+} |
+ |
+bool ChromeToMobilePrintToPhoneJobsFetcher::HasProcessedAllFetchInvocations() |
+ const { |
+ return !fetch_request_.get() && |
+ pending_download_requests_.empty() && |
+ pending_job_update_requests_.empty(); |
+} |
+ |
+} // namespace chrome_to_mobile_receive |