Index: chrome/browser/extensions/api/gcd_private/gcd_private_api.cc |
diff --git a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc |
index 9596157d4fc36ad1d443e3820b6efbac48803e6b..52518bbaec8e5abd6d25d9776ad934d6b393be81 100644 |
--- a/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc |
+++ b/chrome/browser/extensions/api/gcd_private/gcd_private_api.cc |
@@ -6,10 +6,12 @@ |
#include "base/lazy_instance.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/strings/stringprintf.h" |
#include "chrome/browser/local_discovery/cloud_device_list.h" |
#include "chrome/browser/local_discovery/cloud_print_printer_list.h" |
#include "chrome/browser/local_discovery/gcd_constants.h" |
#include "chrome/browser/local_discovery/privet_device_lister_impl.h" |
+#include "chrome/browser/local_discovery/privet_http_impl.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
#include "chrome/browser/signin/signin_manager_factory.h" |
@@ -73,7 +75,7 @@ scoped_ptr<local_discovery::GCDApiFlow> MakeGCDApiFlow(Profile* profile) { |
} // namespace |
GcdPrivateAPI::GcdPrivateAPI(content::BrowserContext* context) |
- : num_device_listeners_(0), browser_context_(context) { |
+ : num_device_listeners_(0), last_session_id_(0), browser_context_(context) { |
DCHECK(browser_context_); |
if (EventRouter::Get(context)) { |
EventRouter::Get(context) |
@@ -177,12 +179,162 @@ bool GcdPrivateAPI::QueryForDevices() { |
return true; |
} |
+void GcdPrivateAPI::EstablishSession(std::string ip_address, |
+ int port, |
+ ConfirmationCodeCallback callback) { |
+ int session_id = last_session_id_++; |
+ linked_ptr<GcdPrivateSessionHolder> session_handler( |
+ new GcdPrivateSessionHolder( |
+ ip_address, port, browser_context_->GetRequestContext())); |
+ sessions_[session_id] = session_handler; |
+ session_handler->Start(base::Bind(callback, session_id)); |
+} |
+ |
+void GcdPrivateAPI::ConfirmCode(int session_id, |
+ SessionEstablishedCallback callback) { |
+ GCDSessionMap::iterator found = sessions_.find(session_id); |
+ |
+ if (found == sessions_.end()) { |
+ callback.Run(gcd_private::STATUS_UNKNOWNSESSIONERROR); |
+ return; |
+ } |
+ |
+ found->second->ConfirmCode(callback); |
+} |
+ |
+void GcdPrivateAPI::SendMessage(int session_id, |
+ const std::string& api, |
+ const base::DictionaryValue& input, |
+ MessageResponseCallback callback) { |
+ GCDSessionMap::iterator found = sessions_.find(session_id); |
+ |
+ if (found == sessions_.end()) { |
+ callback.Run(gcd_private::STATUS_UNKNOWNSESSIONERROR, |
+ base::DictionaryValue()); |
+ return; |
+ } |
+ |
+ found->second->SendMessage(api, input, callback); |
+} |
+ |
// static |
void GcdPrivateAPI::SetGCDApiFlowFactoryForTests( |
GCDApiFlowFactoryForTests* factory) { |
g_gcd_api_flow_factory = factory; |
} |
+GcdPrivateRequest::GcdPrivateRequest( |
+ const std::string& api, |
+ const base::DictionaryValue& input, |
+ const GcdPrivateAPI::MessageResponseCallback& callback, |
+ GcdPrivateSessionHolder* session_holder) |
+ : api_(api), |
+ input_(input.DeepCopy()), |
+ callback_(callback), |
+ session_holder_(session_holder) { |
+} |
+ |
+GcdPrivateRequest::~GcdPrivateRequest() { |
+} |
+ |
+std::string GcdPrivateRequest::GetName() { |
+ return api_; |
+} |
+ |
+const base::DictionaryValue& GcdPrivateRequest::GetInput() { |
+ return *input_; |
+} |
+ |
+void GcdPrivateRequest::OnError( |
+ local_discovery::PrivetURLFetcher::ErrorType error) { |
+ callback_.Run(gcd_private::STATUS_CONNECTIONERROR, base::DictionaryValue()); |
+ |
+ session_holder_->DeleteRequest(this); |
+} |
+ |
+void GcdPrivateRequest::OnParsedJson(const base::DictionaryValue& value, |
+ bool has_error) { |
+ callback_.Run(gcd_private::STATUS_SUCCESS, value); |
+ |
+ session_holder_->DeleteRequest(this); |
+} |
+ |
+GcdPrivateSessionHolder::GcdPrivateSessionHolder( |
+ const std::string& ip_address, |
+ int port, |
+ net::URLRequestContextGetter* request_context) { |
+ std::string host_string; |
+ |
+ // HACK: Check if the IP address is an IPv6 address |
+ if (ip_address.find(':') != std::string::npos) { |
+ host_string = base::StringPrintf("[%s]", ip_address.c_str()); |
+ } else { |
+ host_string = ip_address; |
+ } |
+ |
+ http_client_.reset(new local_discovery::PrivetHTTPClientImpl( |
+ "", net::HostPortPair(host_string, port), request_context)); |
+} |
+ |
+GcdPrivateSessionHolder::~GcdPrivateSessionHolder() { |
+} |
+ |
+void GcdPrivateSessionHolder::Start(const ConfirmationCodeCallback& callback) { |
+ confirm_callback_ = callback; |
+ |
+ privet_session_.reset( |
+ new local_discovery::PrivetV3Session(http_client_.Pass(), this)); |
+ privet_session_->Start(); |
+} |
+ |
+void GcdPrivateSessionHolder::ConfirmCode( |
+ const GcdPrivateAPI::SessionEstablishedCallback& callback) { |
+ session_established_callback_ = callback; |
+ privet_session_->ConfirmCode(); |
+} |
+ |
+void GcdPrivateSessionHolder::SendMessage( |
+ const std::string& api, |
+ const base::DictionaryValue& input, |
+ GcdPrivateAPI::MessageResponseCallback callback) { |
+ linked_ptr<GcdPrivateRequest> request( |
+ new GcdPrivateRequest(api, input, callback, this)); |
+ requests_.push_back(request); |
+ privet_session_->StartRequest(request.get()); |
+} |
+ |
+void GcdPrivateSessionHolder::DeleteRequest(GcdPrivateRequest* request) { |
+ // TODO(noamsml): Does this need to be optimized? |
+ for (RequestVector::iterator i = requests_.begin(); i != requests_.end(); |
+ i++) { |
+ if (i->get() == request) { |
+ requests_.erase(i); |
+ break; |
+ } |
+ } |
+} |
+ |
+void GcdPrivateSessionHolder::OnSetupConfirmationNeeded( |
+ const std::string& confirmation_code) { |
+ confirm_callback_.Run(gcd_private::STATUS_SUCCESS, |
+ confirmation_code, |
+ gcd_private::CONFIRMATION_TYPE_DISPLAYCODE); |
+ |
+ confirm_callback_.Reset(); |
+} |
+ |
+void GcdPrivateSessionHolder::OnSessionEstablished() { |
+ session_established_callback_.Run(gcd_private::STATUS_SUCCESS); |
+ |
+ session_established_callback_.Reset(); |
+} |
+ |
+void GcdPrivateSessionHolder::OnCannotEstablishSession() { |
+ session_established_callback_.Run(gcd_private::STATUS_SESSIONERROR); |
+ |
+ session_established_callback_.Reset(); |
+} |
+ |
GcdPrivateGetCloudDeviceListFunction::GcdPrivateGetCloudDeviceListFunction() { |
} |
@@ -303,7 +455,35 @@ GcdPrivateEstablishSessionFunction::~GcdPrivateEstablishSessionFunction() { |
} |
bool GcdPrivateEstablishSessionFunction::RunAsync() { |
- return false; |
+ scoped_ptr<gcd_private::EstablishSession::Params> params = |
+ gcd_private::EstablishSession::Params::Create(*args_); |
+ |
+ if (!params) |
+ return false; |
+ |
+ GcdPrivateAPI* gcd_api = |
+ BrowserContextKeyedAPIFactory<GcdPrivateAPI>::Get(GetProfile()); |
+ |
+ if (!gcd_api) |
+ return false; |
+ |
+ gcd_api->EstablishSession( |
+ params->ip_address, |
+ params->port, |
+ base::Bind(&GcdPrivateEstablishSessionFunction::OnConfirmCodeCallback, |
+ this)); |
+ |
+ return true; |
+} |
+ |
+void GcdPrivateEstablishSessionFunction::OnConfirmCodeCallback( |
+ int session_id, |
+ gcd_private::Status status, |
+ const std::string& confirm_code, |
+ gcd_private::ConfirmationType confirmation_type) { |
+ results_ = gcd_private::EstablishSession::Results::Create( |
+ session_id, status, confirm_code, confirmation_type); |
+ SendResponse(true); |
} |
GcdPrivateConfirmCodeFunction::GcdPrivateConfirmCodeFunction() { |
@@ -313,7 +493,30 @@ GcdPrivateConfirmCodeFunction::~GcdPrivateConfirmCodeFunction() { |
} |
bool GcdPrivateConfirmCodeFunction::RunAsync() { |
- return false; |
+ scoped_ptr<gcd_private::ConfirmCode::Params> params = |
+ gcd_private::ConfirmCode::Params::Create(*args_); |
+ |
+ if (!params) |
+ return false; |
+ |
+ GcdPrivateAPI* gcd_api = |
+ BrowserContextKeyedAPIFactory<GcdPrivateAPI>::Get(GetProfile()); |
+ |
+ if (!gcd_api) |
+ return false; |
+ |
+ gcd_api->ConfirmCode( |
+ params->session_id, |
+ base::Bind(&GcdPrivateConfirmCodeFunction::OnSessionEstablishedCallback, |
+ this)); |
+ |
+ return true; |
+} |
+ |
+void GcdPrivateConfirmCodeFunction::OnSessionEstablishedCallback( |
+ api::gcd_private::Status status) { |
+ results_ = gcd_private::ConfirmCode::Results::Create(status); |
+ SendResponse(true); |
} |
GcdPrivateSendMessageFunction::GcdPrivateSendMessageFunction() { |
@@ -323,7 +526,35 @@ GcdPrivateSendMessageFunction::~GcdPrivateSendMessageFunction() { |
} |
bool GcdPrivateSendMessageFunction::RunAsync() { |
- return false; |
+ scoped_ptr<gcd_private::PassMessage::Params> params = |
+ gcd_private::PassMessage::Params::Create(*args_); |
+ |
+ if (!params) |
+ return false; |
+ |
+ GcdPrivateAPI* gcd_api = |
+ BrowserContextKeyedAPIFactory<GcdPrivateAPI>::Get(GetProfile()); |
+ |
+ if (!gcd_api) |
+ return false; |
+ |
+ gcd_api->SendMessage( |
+ params->session_id, |
+ params->api, |
+ params->input.additional_properties, |
+ base::Bind(&GcdPrivateSendMessageFunction::OnMessageSentCallback, this)); |
+ |
+ return true; |
+} |
+ |
+void GcdPrivateSendMessageFunction::OnMessageSentCallback( |
+ api::gcd_private::Status status, |
+ const base::DictionaryValue& value) { |
+ gcd_private::PassMessage::Results::Response response; |
+ response.additional_properties.MergeDictionary(&value); |
+ |
+ results_ = gcd_private::PassMessage::Results::Create(status, response); |
+ SendResponse(true); |
} |
GcdPrivateTerminateSessionFunction::GcdPrivateTerminateSessionFunction() { |