Added function to get list of networks with prefetched passwords.
[chromium-blink-merge.git] / chrome / browser / extensions / api / gcd_private / gcd_private_api.cc
blobb01e6f486a860947a1ebe56c5d34dd62f8298bd6
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/gcd_private/gcd_private_api.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/linked_ptr.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/scoped_vector.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/local_discovery/cloud_device_list.h"
13 #include "chrome/browser/local_discovery/cloud_print_printer_list.h"
14 #include "chrome/browser/local_discovery/gcd_api_flow.h"
15 #include "chrome/browser/local_discovery/gcd_constants.h"
16 #include "chrome/browser/local_discovery/privet_device_lister_impl.h"
17 #include "chrome/browser/local_discovery/privet_http_impl.h"
18 #include "chrome/browser/local_discovery/privetv3_session.h"
19 #include "chrome/browser/local_discovery/service_discovery_shared_client.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
22 #include "chrome/browser/signin/signin_manager_factory.h"
23 #include "components/signin/core/browser/profile_oauth2_token_service.h"
24 #include "components/signin/core/browser/signin_manager.h"
25 #include "components/signin/core/browser/signin_manager_base.h"
26 #include "extensions/browser/event_router.h"
27 #include "net/base/net_util.h"
29 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
30 #include "chrome/browser/local_discovery/wifi/wifi_manager.h"
31 #endif
33 namespace extensions {
35 namespace gcd_private = api::gcd_private;
37 namespace {
39 const int kNumRequestsNeeded = 2;
41 const char kIDPrefixCloudPrinter[] = "cloudprint:";
42 const char kIDPrefixGcd[] = "gcd:";
43 const char kIDPrefixMdns[] = "mdns:";
45 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
46 const char kPrivatAPISetup[] = "/privet/v3/setup/start";
47 const char kPrivetKeyWifi[] = "wifi";
48 const char kPrivetKeyPassphrase[] = "passphrase";
49 const char kPrivetKeySSID[] = "ssid";
50 const char kPrivetKeyPassphraseDotted[] = "wifi.passphrase";
51 #endif // ENABLE_WIFI_BOOTSTRAPPING
53 scoped_ptr<Event> MakeDeviceStateChangedEvent(
54 const gcd_private::GCDDevice& device) {
55 scoped_ptr<base::ListValue> params =
56 gcd_private::OnDeviceStateChanged::Create(device);
57 scoped_ptr<Event> event(
58 new Event(gcd_private::OnDeviceStateChanged::kEventName, params.Pass()));
59 return event.Pass();
62 scoped_ptr<Event> MakeDeviceRemovedEvent(const std::string& device) {
63 scoped_ptr<base::ListValue> params =
64 gcd_private::OnDeviceRemoved::Create(device);
65 scoped_ptr<Event> event(
66 new Event(gcd_private::OnDeviceRemoved::kEventName, params.Pass()));
67 return event.Pass();
70 GcdPrivateAPI::GCDApiFlowFactoryForTests* g_gcd_api_flow_factory = NULL;
72 base::LazyInstance<BrowserContextKeyedAPIFactory<GcdPrivateAPI> > g_factory =
73 LAZY_INSTANCE_INITIALIZER;
75 scoped_ptr<local_discovery::GCDApiFlow> MakeGCDApiFlow(Profile* profile) {
76 if (g_gcd_api_flow_factory) {
77 return g_gcd_api_flow_factory->CreateGCDApiFlow();
80 ProfileOAuth2TokenService* token_service =
81 ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
82 if (!token_service)
83 return scoped_ptr<local_discovery::GCDApiFlow>();
84 SigninManagerBase* signin_manager =
85 SigninManagerFactory::GetInstance()->GetForProfile(profile);
86 if (!signin_manager)
87 return scoped_ptr<local_discovery::GCDApiFlow>();
88 return local_discovery::GCDApiFlow::Create(
89 profile->GetRequestContext(),
90 token_service,
91 signin_manager->GetAuthenticatedAccountId());
94 } // namespace
96 class GcdPrivateSessionHolder;
98 class GcdPrivateAPIImpl : public EventRouter::Observer,
99 public local_discovery::PrivetDeviceLister::Delegate {
100 public:
101 typedef base::Callback<void(bool success)> SuccessCallback;
103 typedef base::Callback<void(int session_id,
104 api::gcd_private::Status status,
105 const std::string& code,
106 api::gcd_private::ConfirmationType type)>
107 ConfirmationCodeCallback;
109 typedef base::Callback<void(api::gcd_private::Status status)>
110 SessionEstablishedCallback;
112 typedef base::Callback<void(api::gcd_private::Status status,
113 const base::DictionaryValue& response)>
114 MessageResponseCallback;
116 explicit GcdPrivateAPIImpl(content::BrowserContext* context);
117 virtual ~GcdPrivateAPIImpl();
119 static GcdPrivateAPIImpl* Get(content::BrowserContext* context);
121 bool QueryForDevices();
123 void EstablishSession(const std::string& ip_address,
124 int port,
125 ConfirmationCodeCallback callback);
127 void ConfirmCode(int session_id, SessionEstablishedCallback callback);
129 void SendMessage(int session_id,
130 const std::string& api,
131 const base::DictionaryValue& input,
132 MessageResponseCallback callback);
134 void RequestWifiPassword(const std::string& ssid,
135 const SuccessCallback& callback);
137 void RemoveSession(int session_id);
139 scoped_ptr<base::ListValue> GetPrefetchedSSIDList();
141 private:
142 typedef std::map<std::string /* id_string */,
143 linked_ptr<api::gcd_private::GCDDevice> > GCDDeviceMap;
145 typedef std::map<int /* session id*/, linked_ptr<GcdPrivateSessionHolder> >
146 GCDSessionMap;
148 typedef std::map<std::string /* ssid */, std::string /* password */>
149 PasswordMap;
151 // EventRouter::Observer implementation.
152 virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
153 virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
155 // local_discovery::PrivetDeviceLister implementation.
156 virtual void DeviceChanged(
157 bool added,
158 const std::string& name,
159 const local_discovery::DeviceDescription& description) OVERRIDE;
160 virtual void DeviceRemoved(const std::string& name) OVERRIDE;
161 virtual void DeviceCacheFlushed() OVERRIDE;
163 void SendMessageInternal(int session_id,
164 const std::string& api,
165 const base::DictionaryValue& input,
166 const MessageResponseCallback& callback);
168 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
169 void OnWifiPassword(const SuccessCallback& callback,
170 bool success,
171 const std::string& ssid,
172 const std::string& password);
173 void StartWifiIfNotStarted();
174 #endif
176 int num_device_listeners_;
177 scoped_refptr<local_discovery::ServiceDiscoverySharedClient>
178 service_discovery_client_;
179 scoped_ptr<local_discovery::PrivetDeviceLister> privet_device_lister_;
180 GCDDeviceMap known_devices_;
182 GCDSessionMap sessions_;
183 int last_session_id_;
185 content::BrowserContext* const browser_context_;
187 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
188 scoped_ptr<local_discovery::wifi::WifiManager> wifi_manager_;
189 PasswordMap wifi_passwords_;
190 #endif
193 class GcdPrivateRequest : public local_discovery::PrivetV3Session::Request {
194 public:
195 GcdPrivateRequest(const std::string& api,
196 const base::DictionaryValue& input,
197 const GcdPrivateAPIImpl::MessageResponseCallback& callback,
198 GcdPrivateSessionHolder* session_holder);
199 virtual ~GcdPrivateRequest();
201 // local_discovery::PrivetV3Session::Request implementation.
202 virtual std::string GetName() OVERRIDE;
203 virtual const base::DictionaryValue& GetInput() OVERRIDE;
204 virtual void OnError(
205 local_discovery::PrivetURLFetcher::ErrorType error) OVERRIDE;
206 virtual void OnParsedJson(const base::DictionaryValue& value,
207 bool has_error) OVERRIDE;
209 private:
210 std::string api_;
211 scoped_ptr<base::DictionaryValue> input_;
212 GcdPrivateAPIImpl::MessageResponseCallback callback_;
213 GcdPrivateSessionHolder* session_holder_;
216 class GcdPrivateSessionHolder
217 : public local_discovery::PrivetV3Session::Delegate {
218 public:
219 typedef base::Callback<void(api::gcd_private::Status status,
220 const std::string& code,
221 api::gcd_private::ConfirmationType type)>
222 ConfirmationCodeCallback;
224 GcdPrivateSessionHolder(const std::string& ip_address,
225 int port,
226 net::URLRequestContextGetter* request_context);
227 virtual ~GcdPrivateSessionHolder();
229 void Start(const ConfirmationCodeCallback& callback);
231 void ConfirmCode(
232 const GcdPrivateAPIImpl::SessionEstablishedCallback& callback);
234 void SendMessage(const std::string& api,
235 const base::DictionaryValue& input,
236 GcdPrivateAPIImpl::MessageResponseCallback callback);
238 void DeleteRequest(GcdPrivateRequest* request);
240 private:
241 // local_discovery::PrivetV3Session::Delegate implementation.
242 virtual void OnSetupConfirmationNeeded(
243 const std::string& confirmation_code) OVERRIDE;
244 virtual void OnSessionEstablished() OVERRIDE;
245 virtual void OnCannotEstablishSession() OVERRIDE;
247 scoped_ptr<local_discovery::PrivetHTTPClient> http_client_;
248 scoped_ptr<local_discovery::PrivetV3Session> privet_session_;
249 typedef ScopedVector<GcdPrivateRequest> RequestVector;
250 RequestVector requests_;
252 ConfirmationCodeCallback confirm_callback_;
253 GcdPrivateAPIImpl::SessionEstablishedCallback session_established_callback_;
256 GcdPrivateAPIImpl::GcdPrivateAPIImpl(content::BrowserContext* context)
257 : num_device_listeners_(0), last_session_id_(0), browser_context_(context) {
258 DCHECK(browser_context_);
259 if (EventRouter::Get(context)) {
260 EventRouter::Get(context)
261 ->RegisterObserver(this, gcd_private::OnDeviceStateChanged::kEventName);
262 EventRouter::Get(context)
263 ->RegisterObserver(this, gcd_private::OnDeviceRemoved::kEventName);
267 GcdPrivateAPIImpl::~GcdPrivateAPIImpl() {
268 if (EventRouter::Get(browser_context_)) {
269 EventRouter::Get(browser_context_)->UnregisterObserver(this);
273 void GcdPrivateAPIImpl::OnListenerAdded(const EventListenerInfo& details) {
274 if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
275 details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
276 num_device_listeners_++;
278 if (num_device_listeners_ == 1) {
279 service_discovery_client_ =
280 local_discovery::ServiceDiscoverySharedClient::GetInstance();
281 privet_device_lister_.reset(new local_discovery::PrivetDeviceListerImpl(
282 service_discovery_client_.get(), this));
283 privet_device_lister_->Start();
286 for (GCDDeviceMap::iterator i = known_devices_.begin();
287 i != known_devices_.end();
288 i++) {
289 EventRouter::Get(browser_context_)->DispatchEventToExtension(
290 details.extension_id, MakeDeviceStateChangedEvent(*i->second));
295 void GcdPrivateAPIImpl::OnListenerRemoved(const EventListenerInfo& details) {
296 if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
297 details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
298 num_device_listeners_--;
300 if (num_device_listeners_ == 0) {
301 privet_device_lister_.reset();
302 service_discovery_client_ = NULL;
307 void GcdPrivateAPIImpl::DeviceChanged(
308 bool added,
309 const std::string& name,
310 const local_discovery::DeviceDescription& description) {
311 linked_ptr<gcd_private::GCDDevice> device(new gcd_private::GCDDevice);
312 device->setup_type = gcd_private::SETUP_TYPE_MDNS;
313 device->device_id = kIDPrefixMdns + name;
314 device->device_type = description.type;
315 device->device_name = description.name;
316 device->device_description = description.description;
317 if (!description.id.empty())
318 device->cloud_id.reset(new std::string(description.id));
320 known_devices_[device->device_id] = device;
322 EventRouter::Get(browser_context_)
323 ->BroadcastEvent(MakeDeviceStateChangedEvent(*device));
326 void GcdPrivateAPIImpl::DeviceRemoved(const std::string& name) {
327 GCDDeviceMap::iterator found = known_devices_.find(kIDPrefixMdns + name);
328 linked_ptr<gcd_private::GCDDevice> device = found->second;
329 known_devices_.erase(found);
331 EventRouter::Get(browser_context_)
332 ->BroadcastEvent(MakeDeviceRemovedEvent(device->device_id));
335 void GcdPrivateAPIImpl::DeviceCacheFlushed() {
336 for (GCDDeviceMap::iterator i = known_devices_.begin();
337 i != known_devices_.end();
338 i++) {
339 EventRouter::Get(browser_context_)
340 ->BroadcastEvent(MakeDeviceRemovedEvent(i->second->device_id));
343 known_devices_.clear();
346 // static
347 GcdPrivateAPIImpl* GcdPrivateAPIImpl::Get(content::BrowserContext* context) {
348 GcdPrivateAPI* gcd_api =
349 BrowserContextKeyedAPIFactory<GcdPrivateAPI>::Get(context);
350 return gcd_api ? gcd_api->impl_.get() : NULL;
353 bool GcdPrivateAPIImpl::QueryForDevices() {
354 if (!privet_device_lister_)
355 return false;
357 privet_device_lister_->DiscoverNewDevices(true);
359 return true;
362 void GcdPrivateAPIImpl::EstablishSession(const std::string& ip_address,
363 int port,
364 ConfirmationCodeCallback callback) {
365 int session_id = last_session_id_++;
366 linked_ptr<GcdPrivateSessionHolder> session_handler(
367 new GcdPrivateSessionHolder(
368 ip_address, port, browser_context_->GetRequestContext()));
369 sessions_[session_id] = session_handler;
370 session_handler->Start(base::Bind(callback, session_id));
373 void GcdPrivateAPIImpl::ConfirmCode(int session_id,
374 SessionEstablishedCallback callback) {
375 GCDSessionMap::iterator found = sessions_.find(session_id);
377 if (found == sessions_.end()) {
378 callback.Run(gcd_private::STATUS_UNKNOWNSESSIONERROR);
379 return;
382 found->second->ConfirmCode(callback);
385 void GcdPrivateAPIImpl::SendMessage(int session_id,
386 const std::string& api,
387 const base::DictionaryValue& input,
388 MessageResponseCallback callback) {
389 const base::DictionaryValue* input_actual = &input;
390 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
391 scoped_ptr<base::DictionaryValue> input_cloned;
393 if (api == kPrivatAPISetup) {
394 const base::DictionaryValue* wifi = NULL;
396 if (input.GetDictionary(kPrivetKeyWifi, &wifi)) {
397 std::string ssid;
399 if (!wifi->GetString(kPrivetKeySSID, &ssid)) {
400 callback.Run(gcd_private::STATUS_SETUPPARSEERROR,
401 base::DictionaryValue());
402 return;
405 if (!wifi->HasKey(kPrivetKeyPassphrase)) {
406 // If the message is a setup message, has a wifi section, try sending
407 // the passphrase.
409 PasswordMap::iterator found = wifi_passwords_.find(ssid);
410 if (found == wifi_passwords_.end()) {
411 callback.Run(gcd_private::STATUS_WIFIPASSWORDERROR,
412 base::DictionaryValue());
413 return;
416 input_cloned.reset(input.DeepCopy());
417 input_cloned->SetString(kPrivetKeyPassphraseDotted, found->second);
418 input_actual = input_cloned.get();
422 #endif
424 GCDSessionMap::iterator found = sessions_.find(session_id);
426 if (found == sessions_.end()) {
427 callback.Run(gcd_private::STATUS_UNKNOWNSESSIONERROR,
428 base::DictionaryValue());
429 return;
432 found->second->SendMessage(api, *input_actual, callback);
435 void GcdPrivateAPIImpl::RequestWifiPassword(const std::string& ssid,
436 const SuccessCallback& callback) {
437 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
438 StartWifiIfNotStarted();
439 wifi_manager_->RequestNetworkCredentials(
440 ssid,
441 base::Bind(&GcdPrivateAPIImpl::OnWifiPassword,
442 base::Unretained(this),
443 callback));
444 #else
445 callback.Run(false);
446 #endif
449 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
450 void GcdPrivateAPIImpl::OnWifiPassword(const SuccessCallback& callback,
451 bool success,
452 const std::string& ssid,
453 const std::string& password) {
454 if (success) {
455 wifi_passwords_[ssid] = password;
458 callback.Run(success);
461 void GcdPrivateAPIImpl::StartWifiIfNotStarted() {
462 if (!wifi_manager_) {
463 wifi_manager_ = local_discovery::wifi::WifiManager::Create();
464 wifi_manager_->Start();
468 #endif
470 void GcdPrivateAPIImpl::RemoveSession(int session_id) {
471 sessions_.erase(session_id);
474 scoped_ptr<base::ListValue> GcdPrivateAPIImpl::GetPrefetchedSSIDList() {
475 scoped_ptr<base::ListValue> retval(new base::ListValue);
477 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
478 for (PasswordMap::iterator i = wifi_passwords_.begin();
479 i != wifi_passwords_.end();
480 i++) {
481 retval->AppendString(i->first);
483 #endif
485 return retval.Pass();
488 GcdPrivateRequest::GcdPrivateRequest(
489 const std::string& api,
490 const base::DictionaryValue& input,
491 const GcdPrivateAPIImpl::MessageResponseCallback& callback,
492 GcdPrivateSessionHolder* session_holder)
493 : api_(api),
494 input_(input.DeepCopy()),
495 callback_(callback),
496 session_holder_(session_holder) {
499 GcdPrivateRequest::~GcdPrivateRequest() {
502 std::string GcdPrivateRequest::GetName() {
503 return api_;
506 const base::DictionaryValue& GcdPrivateRequest::GetInput() {
507 return *input_;
510 void GcdPrivateRequest::OnError(
511 local_discovery::PrivetURLFetcher::ErrorType error) {
512 callback_.Run(gcd_private::STATUS_CONNECTIONERROR, base::DictionaryValue());
514 session_holder_->DeleteRequest(this);
517 void GcdPrivateRequest::OnParsedJson(const base::DictionaryValue& value,
518 bool has_error) {
519 callback_.Run(gcd_private::STATUS_SUCCESS, value);
521 session_holder_->DeleteRequest(this);
524 GcdPrivateSessionHolder::GcdPrivateSessionHolder(
525 const std::string& ip_address,
526 int port,
527 net::URLRequestContextGetter* request_context) {
528 std::string host_string;
529 net::IPAddressNumber address_number;
531 if (net::ParseIPLiteralToNumber(ip_address, &address_number) &&
532 address_number.size() == net::kIPv6AddressSize) {
533 host_string = base::StringPrintf("[%s]", ip_address.c_str());
534 } else {
535 host_string = ip_address;
538 http_client_.reset(new local_discovery::PrivetHTTPClientImpl(
539 "", net::HostPortPair(host_string, port), request_context));
542 GcdPrivateSessionHolder::~GcdPrivateSessionHolder() {
545 void GcdPrivateSessionHolder::Start(const ConfirmationCodeCallback& callback) {
546 confirm_callback_ = callback;
548 privet_session_.reset(
549 new local_discovery::PrivetV3Session(http_client_.Pass(), this));
550 privet_session_->Start();
553 void GcdPrivateSessionHolder::ConfirmCode(
554 const GcdPrivateAPIImpl::SessionEstablishedCallback& callback) {
555 session_established_callback_ = callback;
556 privet_session_->ConfirmCode();
559 void GcdPrivateSessionHolder::SendMessage(
560 const std::string& api,
561 const base::DictionaryValue& input,
562 GcdPrivateAPIImpl::MessageResponseCallback callback) {
563 GcdPrivateRequest* request =
564 new GcdPrivateRequest(api, input, callback, this);
565 requests_.push_back(request);
566 privet_session_->StartRequest(request);
569 void GcdPrivateSessionHolder::DeleteRequest(GcdPrivateRequest* request) {
570 // TODO(noamsml): Does this need to be optimized?
571 for (RequestVector::iterator i = requests_.begin(); i != requests_.end();
572 i++) {
573 if (*i == request) {
574 requests_.erase(i);
575 break;
580 void GcdPrivateSessionHolder::OnSetupConfirmationNeeded(
581 const std::string& confirmation_code) {
582 confirm_callback_.Run(gcd_private::STATUS_SUCCESS,
583 confirmation_code,
584 gcd_private::CONFIRMATION_TYPE_DISPLAYCODE);
586 confirm_callback_.Reset();
589 void GcdPrivateSessionHolder::OnSessionEstablished() {
590 session_established_callback_.Run(gcd_private::STATUS_SUCCESS);
592 session_established_callback_.Reset();
595 void GcdPrivateSessionHolder::OnCannotEstablishSession() {
596 session_established_callback_.Run(gcd_private::STATUS_SESSIONERROR);
598 session_established_callback_.Reset();
601 GcdPrivateAPI::GcdPrivateAPI(content::BrowserContext* context)
602 : impl_(new GcdPrivateAPIImpl(context)) {
605 GcdPrivateAPI::~GcdPrivateAPI() {
608 // static
609 BrowserContextKeyedAPIFactory<GcdPrivateAPI>*
610 GcdPrivateAPI::GetFactoryInstance() {
611 return g_factory.Pointer();
614 // static
615 void GcdPrivateAPI::SetGCDApiFlowFactoryForTests(
616 GCDApiFlowFactoryForTests* factory) {
617 g_gcd_api_flow_factory = factory;
620 GcdPrivateGetCloudDeviceListFunction::GcdPrivateGetCloudDeviceListFunction() {
623 GcdPrivateGetCloudDeviceListFunction::~GcdPrivateGetCloudDeviceListFunction() {
626 bool GcdPrivateGetCloudDeviceListFunction::RunAsync() {
627 requests_succeeded_ = 0;
628 requests_failed_ = 0;
630 printer_list_ = MakeGCDApiFlow(GetProfile());
631 device_list_ = MakeGCDApiFlow(GetProfile());
633 if (!printer_list_ || !device_list_)
634 return false;
636 // Balanced in CheckListingDone()
637 AddRef();
639 printer_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>(
640 new local_discovery::CloudPrintPrinterList(this)));
641 device_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>(
642 new local_discovery::CloudDeviceList(this)));
644 return true;
647 void GcdPrivateGetCloudDeviceListFunction::OnDeviceListReady(
648 const DeviceList& devices) {
649 requests_succeeded_++;
651 devices_.insert(devices_.end(), devices.begin(), devices.end());
653 CheckListingDone();
656 void GcdPrivateGetCloudDeviceListFunction::OnDeviceListUnavailable() {
657 requests_failed_++;
659 CheckListingDone();
662 void GcdPrivateGetCloudDeviceListFunction::CheckListingDone() {
663 if (requests_failed_ + requests_succeeded_ != kNumRequestsNeeded)
664 return;
666 if (requests_succeeded_ == 0) {
667 SendResponse(false);
668 return;
671 std::vector<linked_ptr<gcd_private::GCDDevice> > devices;
673 for (DeviceList::iterator i = devices_.begin(); i != devices_.end(); i++) {
674 linked_ptr<gcd_private::GCDDevice> device(new gcd_private::GCDDevice);
675 device->setup_type = gcd_private::SETUP_TYPE_CLOUD;
676 if (i->type == local_discovery::kGCDTypePrinter) {
677 device->device_id = kIDPrefixCloudPrinter + i->id;
678 } else {
679 device->device_id = kIDPrefixGcd + i->id;
682 device->cloud_id.reset(new std::string(i->id));
683 device->device_type = i->type;
684 device->device_name = i->display_name;
685 device->device_description = i->description;
687 devices.push_back(device);
690 results_ = gcd_private::GetCloudDeviceList::Results::Create(devices);
692 SendResponse(true);
693 Release();
696 GcdPrivateQueryForNewLocalDevicesFunction::
697 GcdPrivateQueryForNewLocalDevicesFunction() {
700 GcdPrivateQueryForNewLocalDevicesFunction::
701 ~GcdPrivateQueryForNewLocalDevicesFunction() {
704 bool GcdPrivateQueryForNewLocalDevicesFunction::RunSync() {
705 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
707 if (!gcd_api->QueryForDevices()) {
708 error_ =
709 "You must first subscribe to onDeviceStateChanged or onDeviceRemoved "
710 "notifications";
711 return false;
714 return true;
717 GcdPrivatePrefetchWifiPasswordFunction::
718 GcdPrivatePrefetchWifiPasswordFunction() {
721 GcdPrivatePrefetchWifiPasswordFunction::
722 ~GcdPrivatePrefetchWifiPasswordFunction() {
725 bool GcdPrivatePrefetchWifiPasswordFunction::RunAsync() {
726 scoped_ptr<gcd_private::PrefetchWifiPassword::Params> params =
727 gcd_private::PrefetchWifiPassword::Params::Create(*args_);
729 if (!params)
730 return false;
732 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
734 gcd_api->RequestWifiPassword(
735 params->ssid,
736 base::Bind(&GcdPrivatePrefetchWifiPasswordFunction::OnResponse, this));
738 return true;
741 void GcdPrivatePrefetchWifiPasswordFunction::OnResponse(bool response) {
742 scoped_ptr<base::FundamentalValue> response_value(
743 new base::FundamentalValue(response));
744 SetResult(response_value.release());
745 SendResponse(true);
748 GcdPrivateEstablishSessionFunction::GcdPrivateEstablishSessionFunction() {
751 GcdPrivateEstablishSessionFunction::~GcdPrivateEstablishSessionFunction() {
754 bool GcdPrivateEstablishSessionFunction::RunAsync() {
755 scoped_ptr<gcd_private::EstablishSession::Params> params =
756 gcd_private::EstablishSession::Params::Create(*args_);
758 if (!params)
759 return false;
761 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
763 gcd_api->EstablishSession(
764 params->ip_address,
765 params->port,
766 base::Bind(&GcdPrivateEstablishSessionFunction::OnConfirmCodeCallback,
767 this));
769 return true;
772 void GcdPrivateEstablishSessionFunction::OnConfirmCodeCallback(
773 int session_id,
774 gcd_private::Status status,
775 const std::string& confirm_code,
776 gcd_private::ConfirmationType confirmation_type) {
777 results_ = gcd_private::EstablishSession::Results::Create(
778 session_id, status, confirm_code, confirmation_type);
779 SendResponse(true);
782 GcdPrivateConfirmCodeFunction::GcdPrivateConfirmCodeFunction() {
785 GcdPrivateConfirmCodeFunction::~GcdPrivateConfirmCodeFunction() {
788 bool GcdPrivateConfirmCodeFunction::RunAsync() {
789 scoped_ptr<gcd_private::ConfirmCode::Params> params =
790 gcd_private::ConfirmCode::Params::Create(*args_);
792 if (!params)
793 return false;
795 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
797 gcd_api->ConfirmCode(
798 params->session_id,
799 base::Bind(&GcdPrivateConfirmCodeFunction::OnSessionEstablishedCallback,
800 this));
802 return true;
805 void GcdPrivateConfirmCodeFunction::OnSessionEstablishedCallback(
806 api::gcd_private::Status status) {
807 results_ = gcd_private::ConfirmCode::Results::Create(status);
808 SendResponse(true);
811 GcdPrivateSendMessageFunction::GcdPrivateSendMessageFunction() {
814 GcdPrivateSendMessageFunction::~GcdPrivateSendMessageFunction() {
817 bool GcdPrivateSendMessageFunction::RunAsync() {
818 scoped_ptr<gcd_private::PassMessage::Params> params =
819 gcd_private::PassMessage::Params::Create(*args_);
821 if (!params)
822 return false;
824 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
827 gcd_api->SendMessage(
828 params->session_id,
829 params->api,
830 params->input.additional_properties,
831 base::Bind(&GcdPrivateSendMessageFunction::OnMessageSentCallback, this));
833 return true;
836 void GcdPrivateSendMessageFunction::OnMessageSentCallback(
837 api::gcd_private::Status status,
838 const base::DictionaryValue& value) {
839 gcd_private::PassMessage::Results::Response response;
840 response.additional_properties.MergeDictionary(&value);
842 results_ = gcd_private::PassMessage::Results::Create(status, response);
843 SendResponse(true);
846 GcdPrivateTerminateSessionFunction::GcdPrivateTerminateSessionFunction() {
849 GcdPrivateTerminateSessionFunction::~GcdPrivateTerminateSessionFunction() {
852 bool GcdPrivateTerminateSessionFunction::RunAsync() {
853 scoped_ptr<gcd_private::TerminateSession::Params> params =
854 gcd_private::TerminateSession::Params::Create(*args_);
856 if (!params)
857 return false;
859 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
861 gcd_api->RemoveSession(params->session_id);
863 SendResponse(true);
864 return true;
867 GcdPrivateGetCommandDefinitionsFunction::
868 GcdPrivateGetCommandDefinitionsFunction() {
871 GcdPrivateGetCommandDefinitionsFunction::
872 ~GcdPrivateGetCommandDefinitionsFunction() {
875 GcdPrivateGetPrefetchedWifiNameListFunction::
876 GcdPrivateGetPrefetchedWifiNameListFunction() {
879 GcdPrivateGetPrefetchedWifiNameListFunction::
880 ~GcdPrivateGetPrefetchedWifiNameListFunction() {
883 bool GcdPrivateGetPrefetchedWifiNameListFunction::RunSync() {
884 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
886 scoped_ptr<base::ListValue> ssid_list = gcd_api->GetPrefetchedSSIDList();
888 SetResult(ssid_list.release());
890 return true;
893 bool GcdPrivateGetCommandDefinitionsFunction::RunAsync() {
894 return false;
897 GcdPrivateInsertCommandFunction::GcdPrivateInsertCommandFunction() {
900 GcdPrivateInsertCommandFunction::~GcdPrivateInsertCommandFunction() {
903 bool GcdPrivateInsertCommandFunction::RunAsync() {
904 return false;
907 GcdPrivateGetCommandFunction::GcdPrivateGetCommandFunction() {
910 GcdPrivateGetCommandFunction::~GcdPrivateGetCommandFunction() {
913 bool GcdPrivateGetCommandFunction::RunAsync() {
914 return false;
917 GcdPrivateCancelCommandFunction::GcdPrivateCancelCommandFunction() {
920 GcdPrivateCancelCommandFunction::~GcdPrivateCancelCommandFunction() {
923 bool GcdPrivateCancelCommandFunction::RunAsync() {
924 return false;
927 GcdPrivateGetCommandsListFunction::GcdPrivateGetCommandsListFunction() {
930 GcdPrivateGetCommandsListFunction::~GcdPrivateGetCommandsListFunction() {
933 bool GcdPrivateGetCommandsListFunction::RunAsync() {
934 return false;
937 } // namespace extensions