Index: chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_receive_device_manager.cc |
diff --git a/chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_receive_device_manager.cc b/chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_receive_device_manager.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e9dbb359c6ec4796ab3cd272dfc422e5f0eaab86 |
--- /dev/null |
+++ b/chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_receive_device_manager.cc |
@@ -0,0 +1,285 @@ |
+// 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_receive_device_manager.h" |
+ |
+#include "base/logging.h" |
+#include "chrome/browser/chrome_to_mobile/receive/chrome_to_mobile_receive_util.h" |
+#include "chrome/common/cloud_print/cloud_print_helpers.h" |
+#include "net/url_request/url_request_context_getter.h" |
+ |
+namespace chrome_to_mobile_receive { |
+ |
+ChromeToMobileReceiveDeviceManager::Delegate::Delegate() { |
+} |
+ |
+ChromeToMobileReceiveDeviceManager::Delegate::~Delegate() { |
+} |
+ |
+// static. |
+ChromeToMobileReceiveDeviceManager* |
+ ChromeToMobileReceiveDeviceManager::CreateAndStart( |
+ const GURL& cloud_printer_server_url, |
+ const std::string& existing_printer_id, |
+ const std::map<std::string, std::string>& printer_tags, |
+ const chrome_to_mobile::CloudPrintRequest::Settings& settings, |
+ Delegate* delegate) { |
+ ChromeToMobileReceiveDeviceManager* device_manager = |
+ new ChromeToMobileReceiveDeviceManager( |
+ cloud_printer_server_url, |
+ existing_printer_id, |
+ printer_tags, |
+ settings, |
+ delegate); |
+ device_manager->StartDevice(); |
+ return device_manager; |
+} |
+ |
+ChromeToMobileReceiveDeviceManager::ChromeToMobileReceiveDeviceManager( |
+ const GURL& cloud_print_server_url, |
+ const std::string& existing_printer_id, |
+ const std::map<std::string, std::string>& printer_tags, |
+ const chrome_to_mobile::CloudPrintRequest::Settings& settings, |
+ Delegate* delegate) |
+ : cloud_print_server_url_(cloud_print_server_url), |
+ existing_printer_id_(existing_printer_id), |
+ printer_tags_(printer_tags), |
+ settings_(settings), |
+ delegate_(delegate), |
+ start_status_(kStarting), |
+ has_oauth2_token_fetch_failure_(false), |
+ has_cloud_print_auth_error_(false) { |
+ DCHECK(delegate_); |
+} |
+ |
+ChromeToMobileReceiveDeviceManager::~ChromeToMobileReceiveDeviceManager() { |
+ CancelAllRequests(); |
+} |
+ |
+void ChromeToMobileReceiveDeviceManager::CancelAllRequests() { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ list_request_.reset(); |
+ update_request_.reset(); |
+ register_request_.reset(); |
+ for (std::set<chrome_to_mobile::CloudPrintRequest*>::iterator it = |
+ delete_requests_.begin(); it != delete_requests_.end(); ++it) { |
+ delete *it; |
+ } |
+ |
+ if (start_status_ == kStarting) { |
+ start_status_ = kFail; |
+ delegate_->OnStartDeviceComplete(this); |
+ } |
+} |
+ |
+void ChromeToMobileReceiveDeviceManager::StartDevice() { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ list_request_.reset( |
+ chrome_to_mobile::CloudPrintRequest::CreateAndStartGetRequest( |
+ cloud_print::GetUrlForPrinterList( |
+ cloud_print_server_url_, |
+ chrome_to_mobile_receive::GenerateProxyIdValue()), |
+ settings_, |
+ this)); |
+} |
+ |
+void ChromeToMobileReceiveDeviceManager::OnRequestComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ has_oauth2_token_fetch_failure_ = source->HasOAuth2AccessTokenFailure(); |
+ has_cloud_print_auth_error_ = source->HasCloudPrintAuthError(); |
+ // Stops if there is an authentication issue. |
+ if (has_cloud_print_auth_error_ || has_oauth2_token_fetch_failure_) { |
+ CancelAllRequests(); |
+ return; |
+ } |
+ |
+ if (!HandleRegisterComplete(source)) { |
+ if (!HandleUpdateComplete(source)) { |
+ if (!HandleListComplete(source)) { |
+ if (!HandleDeleteComplete(source)) |
+ NOTREACHED(); |
+ } |
+ } |
+ } |
+ |
+ if (HasCompleted()) |
+ delegate_->OnStartDeviceComplete(this); |
+} |
+ |
+bool ChromeToMobileReceiveDeviceManager::HandleListComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ if (source != list_request_.get()) |
+ return false; |
+ |
+ scoped_ptr<chrome_to_mobile::CloudPrintRequest> to_be_released( |
+ list_request_.release()); |
+ |
+ std::set<std::string> printer_ids; |
+ bool success; |
+ std::string response_data = source->GetResponseData(&success); |
+ if (success) { |
+ cloud_print::ParsePrinterIdsFromListResponse( |
+ response_data, &success, &printer_ids); |
+ } |
+ // Deletes unexpected printers in this proxy. |
+ for (std::set<std::string>::iterator it = printer_ids.begin(); |
+ it != printer_ids.end(); ++it) { |
+ // Not to delete the one that was used by this device. |
+ if (existing_printer_id_.compare(*it) == 0) |
+ continue; |
+ DeletePrinter(*it); |
+ } |
+ |
+ bool is_existing_printer_properly_registered = |
+ !existing_printer_id_.empty() && |
+ printer_ids.find(existing_printer_id_) != printer_ids.end(); |
+ |
+ if (is_existing_printer_properly_registered) { |
+ // Updates the printer identified by |existing_printer_id_|. |
+ std::string post_mime_type; |
+ std::string post_data = |
+ chrome_to_mobile_receive::GeneratePrinterUpdatePostData( |
+ printer_tags_, &post_mime_type); |
+ update_request_.reset( |
+ chrome_to_mobile::CloudPrintRequest::CreateAndStartPostRequest( |
+ cloud_print::GetUrlForPrinterUpdate( |
+ cloud_print_server_url_, existing_printer_id_), |
+ post_mime_type, |
+ post_data, |
+ settings_, |
+ this)); |
+ return true; |
+ } |
+ |
+ // Otherwise, deletes the existing printer and register a new one. |
+ if (!existing_printer_id_.empty()) |
+ DeletePrinter(existing_printer_id_); |
+ RegisterPrinter(); |
+ return true; |
+} |
+ |
+bool ChromeToMobileReceiveDeviceManager::HandleDeleteComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ DCHECK(CalledOnValidThread()); |
+ if (delete_requests_.find(source) == delete_requests_.end()) |
+ return false; |
+ |
+ delete_requests_.erase(source); |
+ scoped_ptr<chrome_to_mobile::CloudPrintRequest> to_be_released(source); |
+ return true; |
+} |
+ |
+bool ChromeToMobileReceiveDeviceManager::HandleUpdateComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ if (source != update_request_.get()) |
+ return false; |
+ |
+ scoped_ptr<chrome_to_mobile::CloudPrintRequest> to_be_released( |
+ update_request_.release()); |
+ |
+ bool success; |
+ source->GetResponseData(&success); |
+ if (success) { |
+ start_status_ = kSuccess; |
+ started_printer_id_ = existing_printer_id_; |
+ return true; |
+ } |
+ |
+ // Registers the device as a printer if update fails, with the same set of |
+ // printer tags used in the update request. |
+ DeletePrinter(existing_printer_id_); |
+ RegisterPrinter(); |
+ return true; |
+} |
+ |
+bool ChromeToMobileReceiveDeviceManager::HandleRegisterComplete( |
+ chrome_to_mobile::CloudPrintRequest* source) { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ if (source != register_request_.get()) |
+ return false; |
+ scoped_ptr<chrome_to_mobile::CloudPrintRequest> to_be_released( |
+ register_request_.release()); |
+ |
+ std::string printer_id; |
+ bool success; |
+ std::string response_data = source->GetResponseData(&success); |
+ if (success) { |
+ cloud_print::ParsePrinterIdFromRegisterResponse( |
+ response_data, &success, &printer_id); |
+ } |
+ if (printer_id.empty()) |
+ success = false; |
+ |
+ start_status_ = success ? kSuccess : kFail; |
+ started_printer_id_ = printer_id; |
+ return true; |
+} |
+ |
+void ChromeToMobileReceiveDeviceManager::DeletePrinter( |
+ const std::string& printer_id) { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ chrome_to_mobile::CloudPrintRequest* delete_request = |
+ chrome_to_mobile::CloudPrintRequest::CreateAndStartGetRequest( |
+ cloud_print::GetUrlForPrinterDelete( |
+ cloud_print_server_url_, printer_id, "unexpected printer"), |
+ settings_, |
+ this); |
+ delete_requests_.insert(delete_request); |
+} |
+ |
+void ChromeToMobileReceiveDeviceManager::RegisterPrinter() { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ std::string post_mime_type; |
+ std::string post_data = |
+ chrome_to_mobile_receive::GeneratePrinterRegistrationPostData( |
+ printer_tags_, &post_mime_type); |
+ |
+ register_request_.reset( |
+ chrome_to_mobile::CloudPrintRequest::CreateAndStartPostRequest( |
+ cloud_print::GetUrlForPrinterRegistration( |
+ cloud_print_server_url_), |
+ post_mime_type, |
+ post_data, |
+ settings_, |
+ this)); |
+} |
+ |
+bool ChromeToMobileReceiveDeviceManager::HasCompleted() const { |
+ DCHECK(CalledOnValidThread()); |
+ return delete_requests_.empty() && |
+ !list_request_.get() && |
+ !update_request_.get() && |
+ !register_request_.get(); |
+} |
+ |
+bool ChromeToMobileReceiveDeviceManager::HasCloudPrintAuthError() const { |
+ DCHECK(CalledOnValidThread()); |
+ return has_cloud_print_auth_error_; |
+} |
+ |
+bool ChromeToMobileReceiveDeviceManager::HasOAuth2AccessTokenFailure() const { |
+ DCHECK(CalledOnValidThread()); |
+ return has_oauth2_token_fetch_failure_; |
+} |
+ |
+std::string ChromeToMobileReceiveDeviceManager::GetStartedPrinterId() const { |
+ DCHECK(CalledOnValidThread()); |
+ return started_printer_id_; |
+} |
+ |
+bool ChromeToMobileReceiveDeviceManager::IsSuccess() const { |
+ DCHECK(CalledOnValidThread()); |
+ return start_status_ == kSuccess; |
+} |
+ |
+} // namespace chrome_to_mobile_receive |