Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3619)

Unified Diff: chrome/browser/extensions/api/gcd_private/gcd_private_api.cc

Issue 411783002: Initial implementation of session APIs, sans WiFi component (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..0fe6ceddb7949d69c9965fe786e38f30c1e31b8c 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,13 @@
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.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"
@@ -72,8 +75,70 @@ scoped_ptr<local_discovery::GCDApiFlow> MakeGCDApiFlow(Profile* profile) {
} // namespace
+class GcdPrivateRequest : public local_discovery::PrivetV3Session::Request {
+ public:
+ GcdPrivateRequest(const std::string& api,
+ const base::DictionaryValue& input,
+ const GcdPrivateAPI::MessageResponseCallback& callback,
+ GcdPrivateSessionHolder* session_holder);
+ virtual ~GcdPrivateRequest();
+
+ // local_discovery::PrivetV3Session::Request implementation.
+ virtual std::string GetName() OVERRIDE;
+ virtual const base::DictionaryValue& GetInput() OVERRIDE;
+ virtual void OnError(
+ local_discovery::PrivetURLFetcher::ErrorType error) OVERRIDE;
+ virtual void OnParsedJson(const base::DictionaryValue& value,
+ bool has_error) OVERRIDE;
+
+ private:
+ std::string api_;
+ scoped_ptr<base::DictionaryValue> input_;
+ GcdPrivateAPI::MessageResponseCallback callback_;
+ GcdPrivateSessionHolder* session_holder_;
+};
+
+class GcdPrivateSessionHolder
+ : public local_discovery::PrivetV3Session::Delegate {
+ public:
+ typedef base::Callback<void(api::gcd_private::Status status,
+ const std::string& code,
+ api::gcd_private::ConfirmationType type)>
+ ConfirmationCodeCallback;
+
+ GcdPrivateSessionHolder(const std::string& ip_address,
+ int port,
+ net::URLRequestContextGetter* request_context);
+ virtual ~GcdPrivateSessionHolder();
+
+ void Start(const ConfirmationCodeCallback& callback);
+
+ void ConfirmCode(const GcdPrivateAPI::SessionEstablishedCallback& callback);
+
+ void SendMessage(const std::string& api,
+ const base::DictionaryValue& input,
+ GcdPrivateAPI::MessageResponseCallback callback);
+
+ void DeleteRequest(GcdPrivateRequest* request);
+
+ private:
+ // local_discovery::PrivetV3Session::Delegate implementation.
+ virtual void OnSetupConfirmationNeeded(
+ const std::string& confirmation_code) OVERRIDE;
+ virtual void OnSessionEstablished() OVERRIDE;
+ virtual void OnCannotEstablishSession() OVERRIDE;
+
+ scoped_ptr<local_discovery::PrivetHTTPClient> http_client_;
+ scoped_ptr<local_discovery::PrivetV3Session> privet_session_;
+ typedef ScopedVector<GcdPrivateRequest> RequestVector;
+ RequestVector requests_;
+
+ ConfirmationCodeCallback confirm_callback_;
+ GcdPrivateAPI::SessionEstablishedCallback session_established_callback_;
+};
+
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 +242,166 @@ 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);
+}
+
+void GcdPrivateAPI::RemoveSession(int session_id) {
+ sessions_.erase(session_id);
+}
+
// 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
asargent_no_longer_on_chrome 2014/07/25 20:50:10 FYI it looks like there are some helper methods in
Noam Samuel 2014/07/25 21:15:56 Done.
+ 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) {
+ GcdPrivateRequest* request =
+ new GcdPrivateRequest(api, input, callback, this);
+ requests_.push_back(request);
+ privet_session_->StartRequest(request);
+}
+
+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 == 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 +522,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 +560,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 +593,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() {
@@ -333,7 +631,22 @@ GcdPrivateTerminateSessionFunction::~GcdPrivateTerminateSessionFunction() {
}
bool GcdPrivateTerminateSessionFunction::RunAsync() {
- return false;
+ scoped_ptr<gcd_private::TerminateSession::Params> params =
+ gcd_private::TerminateSession::Params::Create(*args_);
+
+ if (!params)
+ return false;
+
+ GcdPrivateAPI* gcd_api =
+ BrowserContextKeyedAPIFactory<GcdPrivateAPI>::Get(GetProfile());
+
+ if (!gcd_api)
+ return false;
+
+ gcd_api->RemoveSession(params->session_id);
+
+ SendResponse(true);
+ return true;
}
GcdPrivateGetCommandDefinitionsFunction::

Powered by Google App Engine
This is Rietveld 408576698