Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / gcd_private / gcd_private_api.cc
index b17b984..7f97009 100644 (file)
@@ -5,20 +5,34 @@
 #include "chrome/browser/extensions/api/gcd_private/gcd_private_api.h"
 
 #include "base/lazy_instance.h"
+#include "base/memory/linked_ptr.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_api_flow.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/local_discovery/privetv3_session.h"
+#include "chrome/browser/local_discovery/service_discovery_shared_client.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"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_manager.h"
 #include "components/signin/core/browser/signin_manager_base.h"
+#include "extensions/browser/event_router.h"
+#include "net/base/net_util.h"
+
+#if defined(ENABLE_WIFI_BOOTSTRAPPING)
+#include "chrome/browser/local_discovery/wifi/wifi_manager.h"
+#endif
 
 namespace extensions {
 
-using extensions::api::gcd_private::GCDDevice;
+namespace gcd_private = api::gcd_private;
 
 namespace {
 
@@ -26,6 +40,30 @@ const int kNumRequestsNeeded = 2;
 
 const char kIDPrefixCloudPrinter[] = "cloudprint:";
 const char kIDPrefixGcd[] = "gcd:";
+const char kIDPrefixMdns[] = "mdns:";
+
+const char kPrivatAPISetup[] = "/privet/v3/setup/start";
+const char kPrivetKeyWifi[] = "wifi";
+const char kPrivetKeyPassphrase[] = "passphrase";
+const char kPrivetKeySSID[] = "ssid";
+const char kPrivetKeyPassphraseDotted[] = "wifi.passphrase";
+
+scoped_ptr<Event> MakeDeviceStateChangedEvent(
+    const gcd_private::GCDDevice& device) {
+  scoped_ptr<base::ListValue> params =
+      gcd_private::OnDeviceStateChanged::Create(device);
+  scoped_ptr<Event> event(
+      new Event(gcd_private::OnDeviceStateChanged::kEventName, params.Pass()));
+  return event.Pass();
+}
+
+scoped_ptr<Event> MakeDeviceRemovedEvent(const std::string& device) {
+  scoped_ptr<base::ListValue> params =
+      gcd_private::OnDeviceRemoved::Create(device);
+  scoped_ptr<Event> event(
+      new Event(gcd_private::OnDeviceRemoved::kEventName, params.Pass()));
+  return event.Pass();
+}
 
 GcdPrivateAPI::GCDApiFlowFactoryForTests* g_gcd_api_flow_factory = NULL;
 
@@ -53,8 +91,510 @@ scoped_ptr<local_discovery::GCDApiFlow> MakeGCDApiFlow(Profile* profile) {
 
 }  // namespace
 
+class GcdPrivateSessionHolder;
+
+class GcdPrivateAPIImpl : public EventRouter::Observer,
+                          public local_discovery::PrivetDeviceLister::Delegate {
+ public:
+  typedef base::Callback<void(bool success)> SuccessCallback;
+
+  typedef base::Callback<void(int session_id,
+                              api::gcd_private::Status status,
+                              const std::string& code,
+                              api::gcd_private::ConfirmationType type)>
+      ConfirmationCodeCallback;
+
+  typedef base::Callback<void(api::gcd_private::Status status)>
+      SessionEstablishedCallback;
+
+  typedef base::Callback<void(api::gcd_private::Status status,
+                              const base::DictionaryValue& response)>
+      MessageResponseCallback;
+
+  explicit GcdPrivateAPIImpl(content::BrowserContext* context);
+  virtual ~GcdPrivateAPIImpl();
+
+  static GcdPrivateAPIImpl* Get(content::BrowserContext* context);
+
+  bool QueryForDevices();
+
+  void EstablishSession(const std::string& ip_address,
+                        int port,
+                        ConfirmationCodeCallback callback);
+
+  void ConfirmCode(int session_id,
+                   const std::string& code,
+                   SessionEstablishedCallback callback);
+
+  void SendMessage(int session_id,
+                   const std::string& api,
+                   const base::DictionaryValue& input,
+                   MessageResponseCallback callback);
+
+  void RequestWifiPassword(const std::string& ssid,
+                           const SuccessCallback& callback);
+
+  void RemoveSession(int session_id);
+
+  scoped_ptr<base::ListValue> GetPrefetchedSSIDList();
+
+ private:
+  typedef std::map<std::string /* id_string */,
+                   linked_ptr<api::gcd_private::GCDDevice> > GCDDeviceMap;
+
+  typedef std::map<int /* session id*/, linked_ptr<GcdPrivateSessionHolder> >
+      GCDSessionMap;
+
+  typedef std::map<std::string /* ssid */, std::string /* password */>
+      PasswordMap;
+
+  // EventRouter::Observer implementation.
+  virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
+  virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
+
+  // local_discovery::PrivetDeviceLister implementation.
+  virtual void DeviceChanged(
+      bool added,
+      const std::string& name,
+      const local_discovery::DeviceDescription& description) OVERRIDE;
+  virtual void DeviceRemoved(const std::string& name) OVERRIDE;
+  virtual void DeviceCacheFlushed() OVERRIDE;
+
+  void SendMessageInternal(int session_id,
+                           const std::string& api,
+                           const base::DictionaryValue& input,
+                           const MessageResponseCallback& callback);
+
+#if defined(ENABLE_WIFI_BOOTSTRAPPING)
+  void OnWifiPassword(const SuccessCallback& callback,
+                      bool success,
+                      const std::string& ssid,
+                      const std::string& password);
+  void StartWifiIfNotStarted();
+#endif
+
+  int num_device_listeners_;
+  scoped_refptr<local_discovery::ServiceDiscoverySharedClient>
+      service_discovery_client_;
+  scoped_ptr<local_discovery::PrivetDeviceLister> privet_device_lister_;
+  GCDDeviceMap known_devices_;
+
+  GCDSessionMap sessions_;
+  int last_session_id_;
+
+  content::BrowserContext* const browser_context_;
+
+#if defined(ENABLE_WIFI_BOOTSTRAPPING)
+  scoped_ptr<local_discovery::wifi::WifiManager> wifi_manager_;
+#endif
+  PasswordMap wifi_passwords_;
+};
+
+class GcdPrivateRequest : public local_discovery::PrivetV3Session::Request {
+ public:
+  GcdPrivateRequest(const std::string& api,
+                    const base::DictionaryValue& input,
+                    const GcdPrivateAPIImpl::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_;
+  GcdPrivateAPIImpl::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 std::string& code,
+      const GcdPrivateAPIImpl::SessionEstablishedCallback& callback);
+
+  void SendMessage(const std::string& api,
+                   const base::DictionaryValue& input,
+                   GcdPrivateAPIImpl::MessageResponseCallback callback);
+
+  void DeleteRequest(GcdPrivateRequest* request);
+
+ private:
+  // local_discovery::PrivetV3Session::Delegate implementation.
+  virtual void OnSetupConfirmationNeeded(
+      const std::string& confirmation_code,
+      api::gcd_private::ConfirmationType confirmation_type) OVERRIDE;
+  virtual void OnSessionStatus(api::gcd_private::Status status) OVERRIDE;
+
+  scoped_ptr<local_discovery::PrivetHTTPClient> http_client_;
+  scoped_ptr<local_discovery::PrivetV3Session> privet_session_;
+  typedef ScopedVector<GcdPrivateRequest> RequestVector;
+  RequestVector requests_;
+
+  ConfirmationCodeCallback confirm_callback_;
+  GcdPrivateAPIImpl::SessionEstablishedCallback session_established_callback_;
+};
+
+GcdPrivateAPIImpl::GcdPrivateAPIImpl(content::BrowserContext* context)
+    : num_device_listeners_(0), last_session_id_(0), browser_context_(context) {
+  DCHECK(browser_context_);
+  if (EventRouter::Get(context)) {
+    EventRouter::Get(context)
+        ->RegisterObserver(this, gcd_private::OnDeviceStateChanged::kEventName);
+    EventRouter::Get(context)
+        ->RegisterObserver(this, gcd_private::OnDeviceRemoved::kEventName);
+  }
+}
+
+GcdPrivateAPIImpl::~GcdPrivateAPIImpl() {
+  if (EventRouter::Get(browser_context_)) {
+    EventRouter::Get(browser_context_)->UnregisterObserver(this);
+  }
+}
+
+void GcdPrivateAPIImpl::OnListenerAdded(const EventListenerInfo& details) {
+  if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
+      details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
+    num_device_listeners_++;
+
+    if (num_device_listeners_ == 1) {
+      service_discovery_client_ =
+          local_discovery::ServiceDiscoverySharedClient::GetInstance();
+      privet_device_lister_.reset(new local_discovery::PrivetDeviceListerImpl(
+          service_discovery_client_.get(), this));
+      privet_device_lister_->Start();
+    }
+
+    for (GCDDeviceMap::iterator i = known_devices_.begin();
+         i != known_devices_.end();
+         i++) {
+      EventRouter::Get(browser_context_)->DispatchEventToExtension(
+          details.extension_id, MakeDeviceStateChangedEvent(*i->second));
+    }
+  }
+}
+
+void GcdPrivateAPIImpl::OnListenerRemoved(const EventListenerInfo& details) {
+  if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
+      details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
+    num_device_listeners_--;
+
+    if (num_device_listeners_ == 0) {
+      privet_device_lister_.reset();
+      service_discovery_client_ = NULL;
+    }
+  }
+}
+
+void GcdPrivateAPIImpl::DeviceChanged(
+    bool added,
+    const std::string& name,
+    const local_discovery::DeviceDescription& description) {
+  linked_ptr<gcd_private::GCDDevice> device(new gcd_private::GCDDevice);
+  device->setup_type = gcd_private::SETUP_TYPE_MDNS;
+  device->device_id = kIDPrefixMdns + name;
+  device->device_type = description.type;
+  device->device_name = description.name;
+  device->device_description = description.description;
+  if (!description.id.empty())
+    device->cloud_id.reset(new std::string(description.id));
+
+  known_devices_[device->device_id] = device;
+
+  EventRouter::Get(browser_context_)
+      ->BroadcastEvent(MakeDeviceStateChangedEvent(*device));
+}
+
+void GcdPrivateAPIImpl::DeviceRemoved(const std::string& name) {
+  GCDDeviceMap::iterator found = known_devices_.find(kIDPrefixMdns + name);
+  linked_ptr<gcd_private::GCDDevice> device = found->second;
+  known_devices_.erase(found);
+
+  EventRouter::Get(browser_context_)
+      ->BroadcastEvent(MakeDeviceRemovedEvent(device->device_id));
+}
+
+void GcdPrivateAPIImpl::DeviceCacheFlushed() {
+  for (GCDDeviceMap::iterator i = known_devices_.begin();
+       i != known_devices_.end();
+       i++) {
+    EventRouter::Get(browser_context_)
+        ->BroadcastEvent(MakeDeviceRemovedEvent(i->second->device_id));
+  }
+
+  known_devices_.clear();
+}
+
+// static
+GcdPrivateAPIImpl* GcdPrivateAPIImpl::Get(content::BrowserContext* context) {
+  GcdPrivateAPI* gcd_api =
+      BrowserContextKeyedAPIFactory<GcdPrivateAPI>::Get(context);
+  return gcd_api ? gcd_api->impl_.get() : NULL;
+}
+
+bool GcdPrivateAPIImpl::QueryForDevices() {
+  if (!privet_device_lister_)
+    return false;
+
+  privet_device_lister_->DiscoverNewDevices(true);
+
+  return true;
+}
+
+void GcdPrivateAPIImpl::EstablishSession(const 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 GcdPrivateAPIImpl::ConfirmCode(int session_id,
+                                    const std::string& code,
+                                    SessionEstablishedCallback callback) {
+  GCDSessionMap::iterator found = sessions_.find(session_id);
+
+  if (found == sessions_.end()) {
+    callback.Run(gcd_private::STATUS_UNKNOWNSESSIONERROR);
+    return;
+  }
+
+  found->second->ConfirmCode(code, callback);
+}
+
+void GcdPrivateAPIImpl::SendMessage(int session_id,
+                                    const std::string& api,
+                                    const base::DictionaryValue& input,
+                                    MessageResponseCallback callback) {
+  const base::DictionaryValue* input_actual = &input;
+  scoped_ptr<base::DictionaryValue> input_cloned;
+
+  if (api == kPrivatAPISetup) {
+    const base::DictionaryValue* wifi = NULL;
+
+    if (input.GetDictionary(kPrivetKeyWifi, &wifi)) {
+      std::string ssid;
+
+      if (!wifi->GetString(kPrivetKeySSID, &ssid)) {
+        callback.Run(gcd_private::STATUS_SETUPPARSEERROR,
+                     base::DictionaryValue());
+        return;
+      }
+
+      if (!wifi->HasKey(kPrivetKeyPassphrase)) {
+        // If the message is a setup message, has a wifi section, try sending
+        // the passphrase.
+
+        PasswordMap::iterator found = wifi_passwords_.find(ssid);
+        if (found == wifi_passwords_.end()) {
+          callback.Run(gcd_private::STATUS_WIFIPASSWORDERROR,
+                       base::DictionaryValue());
+          return;
+        }
+
+        input_cloned.reset(input.DeepCopy());
+        input_cloned->SetString(kPrivetKeyPassphraseDotted, found->second);
+        input_actual = input_cloned.get();
+      }
+    }
+  }
+
+  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_actual, callback);
+}
+
+void GcdPrivateAPIImpl::RequestWifiPassword(const std::string& ssid,
+                                            const SuccessCallback& callback) {
+#if defined(ENABLE_WIFI_BOOTSTRAPPING)
+  StartWifiIfNotStarted();
+  wifi_manager_->RequestNetworkCredentials(
+      ssid,
+      base::Bind(&GcdPrivateAPIImpl::OnWifiPassword,
+                 base::Unretained(this),
+                 callback));
+#else
+  callback.Run(false);
+#endif
+}
+
+#if defined(ENABLE_WIFI_BOOTSTRAPPING)
+void GcdPrivateAPIImpl::OnWifiPassword(const SuccessCallback& callback,
+                                       bool success,
+                                       const std::string& ssid,
+                                       const std::string& password) {
+  if (success) {
+    wifi_passwords_[ssid] = password;
+  }
+
+  callback.Run(success);
+}
+
+void GcdPrivateAPIImpl::StartWifiIfNotStarted() {
+  if (!wifi_manager_) {
+    wifi_manager_ = local_discovery::wifi::WifiManager::Create();
+    wifi_manager_->Start();
+  }
+}
+
+#endif
+
+void GcdPrivateAPIImpl::RemoveSession(int session_id) {
+  sessions_.erase(session_id);
+}
+
+scoped_ptr<base::ListValue> GcdPrivateAPIImpl::GetPrefetchedSSIDList() {
+  scoped_ptr<base::ListValue> retval(new base::ListValue);
+
+#if defined(ENABLE_WIFI_BOOTSTRAPPING)
+  for (PasswordMap::iterator i = wifi_passwords_.begin();
+       i != wifi_passwords_.end();
+       i++) {
+    retval->AppendString(i->first);
+  }
+#endif
+
+  return retval.Pass();
+}
+
+GcdPrivateRequest::GcdPrivateRequest(
+    const std::string& api,
+    const base::DictionaryValue& input,
+    const GcdPrivateAPIImpl::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;
+  net::IPAddressNumber address_number;
+
+  if (net::ParseIPLiteralToNumber(ip_address, &address_number) &&
+      address_number.size() == net::kIPv6AddressSize) {
+    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 std::string& code,
+    const GcdPrivateAPIImpl::SessionEstablishedCallback& callback) {
+  session_established_callback_ = callback;
+  privet_session_->ConfirmCode(code);
+}
+
+void GcdPrivateSessionHolder::SendMessage(
+    const std::string& api,
+    const base::DictionaryValue& input,
+    GcdPrivateAPIImpl::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,
+    gcd_private::ConfirmationType confirmation_type) {
+  confirm_callback_.Run(
+      gcd_private::STATUS_SUCCESS, confirmation_code, confirmation_type);
+
+  confirm_callback_.Reset();
+}
+
+void GcdPrivateSessionHolder::OnSessionStatus(gcd_private::Status status) {
+  session_established_callback_.Run(status);
+
+  session_established_callback_.Reset();
+}
+
 GcdPrivateAPI::GcdPrivateAPI(content::BrowserContext* context)
-    : browser_context_(context) {
+    : impl_(new GcdPrivateAPIImpl(context)) {
 }
 
 GcdPrivateAPI::~GcdPrivateAPI() {
@@ -74,6 +614,7 @@ void GcdPrivateAPI::SetGCDApiFlowFactoryForTests(
 
 GcdPrivateGetCloudDeviceListFunction::GcdPrivateGetCloudDeviceListFunction() {
 }
+
 GcdPrivateGetCloudDeviceListFunction::~GcdPrivateGetCloudDeviceListFunction() {
 }
 
@@ -122,15 +663,15 @@ void GcdPrivateGetCloudDeviceListFunction::CheckListingDone() {
     return;
   }
 
-  std::vector<linked_ptr<GCDDevice> > devices;
+  std::vector<linked_ptr<gcd_private::GCDDevice> > devices;
 
   for (DeviceList::iterator i = devices_.begin(); i != devices_.end(); i++) {
-    linked_ptr<GCDDevice> device(new GCDDevice);
-    device->setup_type = extensions::api::gcd_private::SETUP_TYPE_CLOUD;
+    linked_ptr<gcd_private::GCDDevice> device(new gcd_private::GCDDevice);
+    device->setup_type = gcd_private::SETUP_TYPE_CLOUD;
     if (i->type == local_discovery::kGCDTypePrinter) {
-      device->id_string = kIDPrefixCloudPrinter + i->id;
+      device->device_id = kIDPrefixCloudPrinter + i->id;
     } else {
-      device->id_string = kIDPrefixGcd + i->id;
+      device->device_id = kIDPrefixGcd + i->id;
     }
 
     device->cloud_id.reset(new std::string(i->id));
@@ -141,11 +682,259 @@ void GcdPrivateGetCloudDeviceListFunction::CheckListingDone() {
     devices.push_back(device);
   }
 
-  results_ = extensions::api::gcd_private::GetCloudDeviceList::Results::Create(
-      devices);
+  results_ = gcd_private::GetCloudDeviceList::Results::Create(devices);
 
   SendResponse(true);
   Release();
 }
 
+GcdPrivateQueryForNewLocalDevicesFunction::
+    GcdPrivateQueryForNewLocalDevicesFunction() {
+}
+
+GcdPrivateQueryForNewLocalDevicesFunction::
+    ~GcdPrivateQueryForNewLocalDevicesFunction() {
+}
+
+bool GcdPrivateQueryForNewLocalDevicesFunction::RunSync() {
+  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
+
+  if (!gcd_api->QueryForDevices()) {
+    error_ =
+        "You must first subscribe to onDeviceStateChanged or onDeviceRemoved "
+        "notifications";
+    return false;
+  }
+
+  return true;
+}
+
+GcdPrivatePrefetchWifiPasswordFunction::
+    GcdPrivatePrefetchWifiPasswordFunction() {
+}
+
+GcdPrivatePrefetchWifiPasswordFunction::
+    ~GcdPrivatePrefetchWifiPasswordFunction() {
+}
+
+bool GcdPrivatePrefetchWifiPasswordFunction::RunAsync() {
+  scoped_ptr<gcd_private::PrefetchWifiPassword::Params> params =
+      gcd_private::PrefetchWifiPassword::Params::Create(*args_);
+
+  if (!params)
+    return false;
+
+  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
+
+  gcd_api->RequestWifiPassword(
+      params->ssid,
+      base::Bind(&GcdPrivatePrefetchWifiPasswordFunction::OnResponse, this));
+
+  return true;
+}
+
+void GcdPrivatePrefetchWifiPasswordFunction::OnResponse(bool response) {
+  scoped_ptr<base::FundamentalValue> response_value(
+      new base::FundamentalValue(response));
+  SetResult(response_value.release());
+  SendResponse(true);
+}
+
+GcdPrivateEstablishSessionFunction::GcdPrivateEstablishSessionFunction() {
+}
+
+GcdPrivateEstablishSessionFunction::~GcdPrivateEstablishSessionFunction() {
+}
+
+bool GcdPrivateEstablishSessionFunction::RunAsync() {
+  scoped_ptr<gcd_private::EstablishSession::Params> params =
+      gcd_private::EstablishSession::Params::Create(*args_);
+
+  if (!params)
+    return false;
+
+  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
+
+  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) {
+  gcd_private::ConfirmationInfo info;
+
+  info.type = confirmation_type;
+  if (!confirm_code.empty()) {
+    info.code.reset(new std::string(confirm_code));
+  }
+
+  results_ =
+      gcd_private::EstablishSession::Results::Create(session_id, status, info);
+  SendResponse(true);
+}
+
+GcdPrivateConfirmCodeFunction::GcdPrivateConfirmCodeFunction() {
+}
+
+GcdPrivateConfirmCodeFunction::~GcdPrivateConfirmCodeFunction() {
+}
+
+bool GcdPrivateConfirmCodeFunction::RunAsync() {
+  scoped_ptr<gcd_private::ConfirmCode::Params> params =
+      gcd_private::ConfirmCode::Params::Create(*args_);
+
+  if (!params)
+    return false;
+
+  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
+
+  gcd_api->ConfirmCode(
+      params->session_id,
+      params->code,
+      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() {
+}
+
+GcdPrivateSendMessageFunction::~GcdPrivateSendMessageFunction() {
+}
+
+bool GcdPrivateSendMessageFunction::RunAsync() {
+  scoped_ptr<gcd_private::PassMessage::Params> params =
+      gcd_private::PassMessage::Params::Create(*args_);
+
+  if (!params)
+    return false;
+
+  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
+
+
+  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() {
+}
+
+GcdPrivateTerminateSessionFunction::~GcdPrivateTerminateSessionFunction() {
+}
+
+bool GcdPrivateTerminateSessionFunction::RunAsync() {
+  scoped_ptr<gcd_private::TerminateSession::Params> params =
+      gcd_private::TerminateSession::Params::Create(*args_);
+
+  if (!params)
+    return false;
+
+  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
+
+  gcd_api->RemoveSession(params->session_id);
+
+  SendResponse(true);
+  return true;
+}
+
+GcdPrivateGetCommandDefinitionsFunction::
+    GcdPrivateGetCommandDefinitionsFunction() {
+}
+
+GcdPrivateGetCommandDefinitionsFunction::
+    ~GcdPrivateGetCommandDefinitionsFunction() {
+}
+
+GcdPrivateGetPrefetchedWifiNameListFunction::
+    GcdPrivateGetPrefetchedWifiNameListFunction() {
+}
+
+GcdPrivateGetPrefetchedWifiNameListFunction::
+    ~GcdPrivateGetPrefetchedWifiNameListFunction() {
+}
+
+bool GcdPrivateGetPrefetchedWifiNameListFunction::RunSync() {
+  GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
+
+  scoped_ptr<base::ListValue> ssid_list = gcd_api->GetPrefetchedSSIDList();
+
+  SetResult(ssid_list.release());
+
+  return true;
+}
+
+bool GcdPrivateGetCommandDefinitionsFunction::RunAsync() {
+  return false;
+}
+
+GcdPrivateInsertCommandFunction::GcdPrivateInsertCommandFunction() {
+}
+
+GcdPrivateInsertCommandFunction::~GcdPrivateInsertCommandFunction() {
+}
+
+bool GcdPrivateInsertCommandFunction::RunAsync() {
+  return false;
+}
+
+GcdPrivateGetCommandFunction::GcdPrivateGetCommandFunction() {
+}
+
+GcdPrivateGetCommandFunction::~GcdPrivateGetCommandFunction() {
+}
+
+bool GcdPrivateGetCommandFunction::RunAsync() {
+  return false;
+}
+
+GcdPrivateCancelCommandFunction::GcdPrivateCancelCommandFunction() {
+}
+
+GcdPrivateCancelCommandFunction::~GcdPrivateCancelCommandFunction() {
+}
+
+bool GcdPrivateCancelCommandFunction::RunAsync() {
+  return false;
+}
+
+GcdPrivateGetCommandsListFunction::GcdPrivateGetCommandsListFunction() {
+}
+
+GcdPrivateGetCommandsListFunction::~GcdPrivateGetCommandsListFunction() {
+}
+
+bool GcdPrivateGetCommandsListFunction::RunAsync() {
+  return false;
+}
+
 }  // namespace extensions