Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / gcd_private / gcd_private_api.cc
blob22a79fbd18700f75e7777e53591cf8e97de92118
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/location.h"
9 #include "base/memory/linked_ptr.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "chrome/browser/local_discovery/cloud_device_list.h"
15 #include "chrome/browser/local_discovery/cloud_print_printer_list.h"
16 #include "chrome/browser/local_discovery/gcd_api_flow.h"
17 #include "chrome/browser/local_discovery/gcd_constants.h"
18 #include "chrome/browser/local_discovery/privet_device_lister_impl.h"
19 #include "chrome/browser/local_discovery/privet_http_asynchronous_factory.h"
20 #include "chrome/browser/local_discovery/privet_http_impl.h"
21 #include "chrome/browser/local_discovery/privetv3_session.h"
22 #include "chrome/browser/local_discovery/service_discovery_shared_client.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
25 #include "chrome/browser/signin/signin_manager_factory.h"
26 #include "components/signin/core/browser/profile_oauth2_token_service.h"
27 #include "components/signin/core/browser/signin_manager.h"
28 #include "components/signin/core/browser/signin_manager_base.h"
29 #include "extensions/browser/event_router.h"
30 #include "net/base/net_util.h"
32 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
33 #include "chrome/browser/local_discovery/wifi/wifi_manager.h"
34 #endif
36 namespace extensions {
38 namespace gcd_private = api::gcd_private;
40 namespace {
42 const int kNumRequestsNeeded = 2;
44 const char kIDPrefixCloudPrinter[] = "cloudprint:";
45 const char kIDPrefixGcd[] = "gcd:";
46 const char kIDPrefixMdns[] = "mdns:";
48 const char kPrivatAPISetup[] = "/privet/v3/setup/start";
49 const char kPrivetKeyWifi[] = "wifi";
50 const char kPrivetKeyPassphrase[] = "passphrase";
51 const char kPrivetKeySSID[] = "ssid";
52 const char kPrivetKeyPassphraseDotted[] = "wifi.passphrase";
54 scoped_ptr<Event> MakeDeviceStateChangedEvent(
55 const gcd_private::GCDDevice& device) {
56 scoped_ptr<base::ListValue> params =
57 gcd_private::OnDeviceStateChanged::Create(device);
58 scoped_ptr<Event> event(
59 new Event(events::GCD_PRIVATE_ON_DEVICE_STATE_CHANGED,
60 gcd_private::OnDeviceStateChanged::kEventName, params.Pass()));
61 return event.Pass();
64 scoped_ptr<Event> MakeDeviceRemovedEvent(const std::string& device) {
65 scoped_ptr<base::ListValue> params =
66 gcd_private::OnDeviceRemoved::Create(device);
67 scoped_ptr<Event> event(new Event(events::GCD_PRIVATE_ON_DEVICE_REMOVED,
68 gcd_private::OnDeviceRemoved::kEventName,
69 params.Pass()));
70 return event.Pass();
73 GcdPrivateAPI::GCDApiFlowFactoryForTests* g_gcd_api_flow_factory = NULL;
75 base::LazyInstance<BrowserContextKeyedAPIFactory<GcdPrivateAPI> > g_factory =
76 LAZY_INSTANCE_INITIALIZER;
78 scoped_ptr<local_discovery::GCDApiFlow> MakeGCDApiFlow(Profile* profile) {
79 if (g_gcd_api_flow_factory) {
80 return g_gcd_api_flow_factory->CreateGCDApiFlow();
83 ProfileOAuth2TokenService* token_service =
84 ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
85 if (!token_service)
86 return scoped_ptr<local_discovery::GCDApiFlow>();
87 SigninManagerBase* signin_manager =
88 SigninManagerFactory::GetInstance()->GetForProfile(profile);
89 if (!signin_manager)
90 return scoped_ptr<local_discovery::GCDApiFlow>();
91 return local_discovery::GCDApiFlow::Create(
92 profile->GetRequestContext(),
93 token_service,
94 signin_manager->GetAuthenticatedAccountId());
97 } // namespace
99 class GcdPrivateSessionHolder;
101 class GcdPrivateAPIImpl : public EventRouter::Observer,
102 public local_discovery::PrivetDeviceLister::Delegate {
103 public:
104 typedef base::Callback<void(bool success)> SuccessCallback;
106 typedef base::Callback<void(int session_id,
107 api::gcd_private::Status status,
108 const base::DictionaryValue& info)>
109 CreateSessionCallback;
111 typedef base::Callback<void(api::gcd_private::Status status)> SessionCallback;
113 typedef base::Callback<void(api::gcd_private::Status status,
114 const base::DictionaryValue& response)>
115 MessageResponseCallback;
117 explicit GcdPrivateAPIImpl(content::BrowserContext* context);
118 virtual ~GcdPrivateAPIImpl();
120 static GcdPrivateAPIImpl* Get(content::BrowserContext* context);
122 bool QueryForDevices();
124 void CreateSession(const std::string& service_name,
125 const CreateSessionCallback& callback);
127 void StartPairing(int session_id,
128 api::gcd_private::PairingType pairing_type,
129 const SessionCallback& callback);
131 void ConfirmCode(int session_id,
132 const std::string& code,
133 const SessionCallback& callback);
135 void SendMessage(int session_id,
136 const std::string& api,
137 const base::DictionaryValue& input,
138 const MessageResponseCallback& callback);
140 void RequestWifiPassword(const std::string& ssid,
141 const SuccessCallback& callback);
143 void RemoveSession(int session_id);
144 void RemoveSessionDelayed(int session_id);
146 scoped_ptr<base::ListValue> GetPrefetchedSSIDList();
148 private:
149 typedef std::map<std::string /* id_string */,
150 linked_ptr<api::gcd_private::GCDDevice> > GCDDeviceMap;
152 typedef std::map<std::string /* ssid */, std::string /* password */>
153 PasswordMap;
155 // EventRouter::Observer implementation.
156 void OnListenerAdded(const EventListenerInfo& details) override;
157 void OnListenerRemoved(const EventListenerInfo& details) override;
159 // local_discovery::PrivetDeviceLister implementation.
160 void DeviceChanged(
161 bool added,
162 const std::string& name,
163 const local_discovery::DeviceDescription& description) override;
164 void DeviceRemoved(const std::string& name) override;
165 void DeviceCacheFlushed() override;
167 void SendMessageInternal(int session_id,
168 const std::string& api,
169 const base::DictionaryValue& input,
170 const MessageResponseCallback& callback);
172 void OnServiceResolved(int session_id,
173 const CreateSessionCallback& callback,
174 scoped_ptr<local_discovery::PrivetHTTPClient> client);
176 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
177 void OnWifiPassword(const SuccessCallback& callback,
178 bool success,
179 const std::string& ssid,
180 const std::string& password);
181 void StartWifiIfNotStarted();
182 #endif
184 int num_device_listeners_;
185 scoped_refptr<local_discovery::ServiceDiscoverySharedClient>
186 service_discovery_client_;
187 scoped_ptr<local_discovery::PrivetDeviceLister> privet_device_lister_;
188 GCDDeviceMap known_devices_;
190 struct SessionInfo {
191 linked_ptr<local_discovery::PrivetV3Session> session;
192 linked_ptr<local_discovery::PrivetHTTPResolution> http_resolution;
195 std::map<int, SessionInfo> sessions_;
196 int last_session_id_;
198 content::BrowserContext* const browser_context_;
200 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
201 scoped_ptr<local_discovery::wifi::WifiManager> wifi_manager_;
202 #endif
203 PasswordMap wifi_passwords_;
205 base::WeakPtrFactory<GcdPrivateAPIImpl> weak_ptr_factory_{this};
207 DISALLOW_COPY_AND_ASSIGN(GcdPrivateAPIImpl);
211 GcdPrivateAPIImpl::GcdPrivateAPIImpl(content::BrowserContext* context)
212 : num_device_listeners_(0), last_session_id_(0), browser_context_(context) {
213 DCHECK(browser_context_);
214 if (EventRouter::Get(context)) {
215 EventRouter::Get(context)
216 ->RegisterObserver(this, gcd_private::OnDeviceStateChanged::kEventName);
217 EventRouter::Get(context)
218 ->RegisterObserver(this, gcd_private::OnDeviceRemoved::kEventName);
222 GcdPrivateAPIImpl::~GcdPrivateAPIImpl() {
223 if (EventRouter::Get(browser_context_)) {
224 EventRouter::Get(browser_context_)->UnregisterObserver(this);
228 void GcdPrivateAPIImpl::OnListenerAdded(const EventListenerInfo& details) {
229 if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
230 details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
231 num_device_listeners_++;
233 if (num_device_listeners_ == 1) {
234 service_discovery_client_ =
235 local_discovery::ServiceDiscoverySharedClient::GetInstance();
236 privet_device_lister_.reset(new local_discovery::PrivetDeviceListerImpl(
237 service_discovery_client_.get(), this));
238 privet_device_lister_->Start();
241 for (GCDDeviceMap::iterator i = known_devices_.begin();
242 i != known_devices_.end();
243 i++) {
244 EventRouter::Get(browser_context_)->DispatchEventToExtension(
245 details.extension_id, MakeDeviceStateChangedEvent(*i->second));
250 void GcdPrivateAPIImpl::OnListenerRemoved(const EventListenerInfo& details) {
251 if (details.event_name == gcd_private::OnDeviceStateChanged::kEventName ||
252 details.event_name == gcd_private::OnDeviceRemoved::kEventName) {
253 num_device_listeners_--;
255 if (num_device_listeners_ == 0) {
256 privet_device_lister_.reset();
257 service_discovery_client_ = NULL;
262 void GcdPrivateAPIImpl::DeviceChanged(
263 bool added,
264 const std::string& name,
265 const local_discovery::DeviceDescription& description) {
266 linked_ptr<gcd_private::GCDDevice> device(new gcd_private::GCDDevice);
267 device->setup_type = gcd_private::SETUP_TYPE_MDNS;
268 device->device_id = kIDPrefixMdns + name;
269 device->device_type = description.type;
270 device->device_name = description.name;
271 device->device_description = description.description;
272 if (!description.id.empty())
273 device->cloud_id.reset(new std::string(description.id));
275 known_devices_[device->device_id] = device;
277 EventRouter::Get(browser_context_)
278 ->BroadcastEvent(MakeDeviceStateChangedEvent(*device));
281 void GcdPrivateAPIImpl::DeviceRemoved(const std::string& name) {
282 GCDDeviceMap::iterator found = known_devices_.find(kIDPrefixMdns + name);
283 linked_ptr<gcd_private::GCDDevice> device = found->second;
284 known_devices_.erase(found);
286 EventRouter::Get(browser_context_)
287 ->BroadcastEvent(MakeDeviceRemovedEvent(device->device_id));
290 void GcdPrivateAPIImpl::DeviceCacheFlushed() {
291 for (GCDDeviceMap::iterator i = known_devices_.begin();
292 i != known_devices_.end();
293 i++) {
294 EventRouter::Get(browser_context_)
295 ->BroadcastEvent(MakeDeviceRemovedEvent(i->second->device_id));
298 known_devices_.clear();
301 // static
302 GcdPrivateAPIImpl* GcdPrivateAPIImpl::Get(content::BrowserContext* context) {
303 GcdPrivateAPI* gcd_api =
304 BrowserContextKeyedAPIFactory<GcdPrivateAPI>::Get(context);
305 return gcd_api ? gcd_api->impl_.get() : NULL;
308 bool GcdPrivateAPIImpl::QueryForDevices() {
309 if (!privet_device_lister_)
310 return false;
312 privet_device_lister_->DiscoverNewDevices(true);
314 return true;
317 void GcdPrivateAPIImpl::CreateSession(const std::string& service_name,
318 const CreateSessionCallback& callback) {
319 int session_id = last_session_id_++;
320 scoped_ptr<local_discovery::PrivetHTTPAsynchronousFactory> factory(
321 local_discovery::PrivetHTTPAsynchronousFactory::CreateInstance(
322 browser_context_->GetRequestContext()));
323 auto& session_data = sessions_[session_id];
324 session_data.http_resolution.reset(
325 factory->CreatePrivetHTTP(service_name).release());
326 session_data.http_resolution->Start(
327 base::Bind(&GcdPrivateAPIImpl::OnServiceResolved, base::Unretained(this),
328 session_id, callback));
331 void GcdPrivateAPIImpl::OnServiceResolved(
332 int session_id,
333 const CreateSessionCallback& callback,
334 scoped_ptr<local_discovery::PrivetHTTPClient> client) {
335 if (!client) {
336 return callback.Run(session_id, gcd_private::STATUS_SERVICERESOLUTIONERROR,
337 base::DictionaryValue());
339 auto& session_data = sessions_[session_id];
340 session_data.session.reset(
341 new local_discovery::PrivetV3Session(client.Pass()));
342 session_data.session->Init(base::Bind(callback, session_id));
345 void GcdPrivateAPIImpl::StartPairing(int session_id,
346 api::gcd_private::PairingType pairing_type,
347 const SessionCallback& callback) {
348 auto found = sessions_.find(session_id);
350 if (found == sessions_.end())
351 return callback.Run(gcd_private::STATUS_UNKNOWNSESSIONERROR);
353 found->second.session->StartPairing(pairing_type, callback);
356 void GcdPrivateAPIImpl::ConfirmCode(int session_id,
357 const std::string& code,
358 const SessionCallback& callback) {
359 auto found = sessions_.find(session_id);
361 if (found == sessions_.end())
362 return callback.Run(gcd_private::STATUS_UNKNOWNSESSIONERROR);
364 found->second.session->ConfirmCode(code, callback);
367 void GcdPrivateAPIImpl::SendMessage(int session_id,
368 const std::string& api,
369 const base::DictionaryValue& input,
370 const MessageResponseCallback& callback) {
371 const base::DictionaryValue* input_actual = &input;
372 scoped_ptr<base::DictionaryValue> input_cloned;
374 if (api == kPrivatAPISetup) {
375 const base::DictionaryValue* wifi = NULL;
377 if (input.GetDictionary(kPrivetKeyWifi, &wifi)) {
378 std::string ssid;
380 if (!wifi->GetString(kPrivetKeySSID, &ssid)) {
381 LOG(ERROR) << "Missing " << kPrivetKeySSID;
382 return callback.Run(gcd_private::STATUS_SETUPPARSEERROR,
383 base::DictionaryValue());
386 if (!wifi->HasKey(kPrivetKeyPassphrase)) {
387 // If the message is a setup message, has a wifi section, try sending
388 // the passphrase.
390 PasswordMap::iterator found = wifi_passwords_.find(ssid);
391 if (found == wifi_passwords_.end()) {
392 LOG(ERROR) << "Password is unknown";
393 return callback.Run(gcd_private::STATUS_WIFIPASSWORDERROR,
394 base::DictionaryValue());
397 input_cloned.reset(input.DeepCopy());
398 input_cloned->SetString(kPrivetKeyPassphraseDotted, found->second);
399 input_actual = input_cloned.get();
404 auto found = sessions_.find(session_id);
406 if (found == sessions_.end()) {
407 return callback.Run(gcd_private::STATUS_UNKNOWNSESSIONERROR,
408 base::DictionaryValue());
411 found->second.session->SendMessage(api, *input_actual, callback);
414 void GcdPrivateAPIImpl::RequestWifiPassword(const std::string& ssid,
415 const SuccessCallback& callback) {
416 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
417 StartWifiIfNotStarted();
418 wifi_manager_->RequestNetworkCredentials(
419 ssid,
420 base::Bind(&GcdPrivateAPIImpl::OnWifiPassword,
421 base::Unretained(this),
422 callback));
423 #else
424 callback.Run(false);
425 #endif
428 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
429 void GcdPrivateAPIImpl::OnWifiPassword(const SuccessCallback& callback,
430 bool success,
431 const std::string& ssid,
432 const std::string& password) {
433 if (success) {
434 wifi_passwords_[ssid] = password;
437 callback.Run(success);
440 void GcdPrivateAPIImpl::StartWifiIfNotStarted() {
441 if (!wifi_manager_) {
442 wifi_manager_ = local_discovery::wifi::WifiManager::Create();
443 wifi_manager_->Start();
447 #endif
449 void GcdPrivateAPIImpl::RemoveSession(int session_id) {
450 sessions_.erase(session_id);
453 void GcdPrivateAPIImpl::RemoveSessionDelayed(int session_id) {
454 base::ThreadTaskRunnerHandle::Get()->PostTask(
455 FROM_HERE, base::Bind(&GcdPrivateAPIImpl::RemoveSession,
456 weak_ptr_factory_.GetWeakPtr(), session_id));
459 scoped_ptr<base::ListValue> GcdPrivateAPIImpl::GetPrefetchedSSIDList() {
460 scoped_ptr<base::ListValue> retval(new base::ListValue);
462 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
463 for (PasswordMap::iterator i = wifi_passwords_.begin();
464 i != wifi_passwords_.end();
465 i++) {
466 retval->AppendString(i->first);
468 #endif
470 return retval.Pass();
475 GcdPrivateAPI::GcdPrivateAPI(content::BrowserContext* context)
476 : impl_(new GcdPrivateAPIImpl(context)) {
479 GcdPrivateAPI::~GcdPrivateAPI() {
482 // static
483 BrowserContextKeyedAPIFactory<GcdPrivateAPI>*
484 GcdPrivateAPI::GetFactoryInstance() {
485 return g_factory.Pointer();
488 // static
489 void GcdPrivateAPI::SetGCDApiFlowFactoryForTests(
490 GCDApiFlowFactoryForTests* factory) {
491 g_gcd_api_flow_factory = factory;
494 GcdPrivateGetCloudDeviceListFunction::GcdPrivateGetCloudDeviceListFunction() {
497 GcdPrivateGetCloudDeviceListFunction::~GcdPrivateGetCloudDeviceListFunction() {
500 bool GcdPrivateGetCloudDeviceListFunction::RunAsync() {
501 requests_succeeded_ = 0;
502 requests_failed_ = 0;
504 printer_list_ = MakeGCDApiFlow(GetProfile());
505 device_list_ = MakeGCDApiFlow(GetProfile());
507 if (!printer_list_ || !device_list_)
508 return false;
510 // Balanced in CheckListingDone()
511 AddRef();
513 printer_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>(
514 new local_discovery::CloudPrintPrinterList(this)));
515 device_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>(
516 new local_discovery::CloudDeviceList(this)));
518 return true;
521 void GcdPrivateGetCloudDeviceListFunction::OnDeviceListReady(
522 const DeviceList& devices) {
523 requests_succeeded_++;
525 devices_.insert(devices_.end(), devices.begin(), devices.end());
527 CheckListingDone();
530 void GcdPrivateGetCloudDeviceListFunction::OnDeviceListUnavailable() {
531 requests_failed_++;
533 CheckListingDone();
536 void GcdPrivateGetCloudDeviceListFunction::CheckListingDone() {
537 if (requests_failed_ + requests_succeeded_ != kNumRequestsNeeded)
538 return;
540 if (requests_succeeded_ == 0) {
541 SendResponse(false);
542 return;
545 std::vector<linked_ptr<gcd_private::GCDDevice> > devices;
547 for (DeviceList::iterator i = devices_.begin(); i != devices_.end(); i++) {
548 linked_ptr<gcd_private::GCDDevice> device(new gcd_private::GCDDevice);
549 device->setup_type = gcd_private::SETUP_TYPE_CLOUD;
550 if (i->type == local_discovery::kGCDTypePrinter) {
551 device->device_id = kIDPrefixCloudPrinter + i->id;
552 } else {
553 device->device_id = kIDPrefixGcd + i->id;
556 device->cloud_id.reset(new std::string(i->id));
557 device->device_type = i->type;
558 device->device_name = i->display_name;
559 device->device_description = i->description;
561 devices.push_back(device);
564 results_ = gcd_private::GetCloudDeviceList::Results::Create(devices);
566 SendResponse(true);
567 Release();
570 GcdPrivateQueryForNewLocalDevicesFunction::
571 GcdPrivateQueryForNewLocalDevicesFunction() {
574 GcdPrivateQueryForNewLocalDevicesFunction::
575 ~GcdPrivateQueryForNewLocalDevicesFunction() {
578 bool GcdPrivateQueryForNewLocalDevicesFunction::RunSync() {
579 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
581 if (!gcd_api->QueryForDevices()) {
582 error_ =
583 "You must first subscribe to onDeviceStateChanged or onDeviceRemoved "
584 "notifications";
585 return false;
588 return true;
591 GcdPrivatePrefetchWifiPasswordFunction::
592 GcdPrivatePrefetchWifiPasswordFunction() {
595 GcdPrivatePrefetchWifiPasswordFunction::
596 ~GcdPrivatePrefetchWifiPasswordFunction() {
599 bool GcdPrivatePrefetchWifiPasswordFunction::RunAsync() {
600 scoped_ptr<gcd_private::PrefetchWifiPassword::Params> params =
601 gcd_private::PrefetchWifiPassword::Params::Create(*args_);
603 if (!params)
604 return false;
606 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
608 gcd_api->RequestWifiPassword(
609 params->ssid,
610 base::Bind(&GcdPrivatePrefetchWifiPasswordFunction::OnResponse, this));
612 return true;
615 void GcdPrivatePrefetchWifiPasswordFunction::OnResponse(bool response) {
616 scoped_ptr<base::FundamentalValue> response_value(
617 new base::FundamentalValue(response));
618 SetResult(response_value.release());
619 SendResponse(true);
622 GcdPrivateGetDeviceInfoFunction::GcdPrivateGetDeviceInfoFunction() {
625 GcdPrivateGetDeviceInfoFunction::~GcdPrivateGetDeviceInfoFunction() {
628 bool GcdPrivateGetDeviceInfoFunction::RunAsync() {
629 scoped_ptr<gcd_private::CreateSession::Params> params =
630 gcd_private::CreateSession::Params::Create(*args_);
632 if (!params)
633 return false;
635 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
637 GcdPrivateAPIImpl::CreateSessionCallback callback =
638 base::Bind(&GcdPrivateGetDeviceInfoFunction::OnSessionInitialized, this);
639 gcd_api->CreateSession(params->service_name, callback);
641 return true;
644 void GcdPrivateGetDeviceInfoFunction::OnSessionInitialized(
645 int session_id,
646 api::gcd_private::Status status,
647 const base::DictionaryValue& info) {
648 gcd_private::GetDeviceInfo::Results::DeviceInfo device_info;
649 device_info.additional_properties.MergeDictionary(&info);
651 results_ = gcd_private::GetDeviceInfo::Results::Create(status, device_info);
652 SendResponse(true);
654 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
655 gcd_api->RemoveSessionDelayed(session_id);
658 GcdPrivateCreateSessionFunction::GcdPrivateCreateSessionFunction() {
661 GcdPrivateCreateSessionFunction::~GcdPrivateCreateSessionFunction() {
664 bool GcdPrivateCreateSessionFunction::RunAsync() {
665 scoped_ptr<gcd_private::CreateSession::Params> params =
666 gcd_private::CreateSession::Params::Create(*args_);
668 if (!params)
669 return false;
671 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
673 GcdPrivateAPIImpl::CreateSessionCallback callback =
674 base::Bind(&GcdPrivateCreateSessionFunction::OnSessionInitialized, this);
675 gcd_api->CreateSession(params->service_name, callback);
677 return true;
680 void GcdPrivateCreateSessionFunction::OnSessionInitialized(
681 int session_id,
682 api::gcd_private::Status status,
683 const base::DictionaryValue& info) {
684 std::vector<api::gcd_private::PairingType> pairing_types;
686 // TODO(vitalybuka): Remove this parsing and |pairing_types| from callback.
687 if (status == gcd_private::STATUS_SUCCESS) {
688 const base::ListValue* pairing = nullptr;
689 if (info.GetList("authentication.pairing", &pairing)) {
690 for (const base::Value* value : *pairing) {
691 std::string pairing_string;
692 if (value->GetAsString(&pairing_string)) {
693 api::gcd_private::PairingType pairing_type =
694 api::gcd_private::ParsePairingType(pairing_string);
695 if (pairing_type != api::gcd_private::PAIRING_TYPE_NONE)
696 pairing_types.push_back(pairing_type);
699 } else {
700 status = gcd_private::STATUS_SESSIONERROR;
704 results_ = gcd_private::CreateSession::Results::Create(session_id, status,
705 pairing_types);
706 SendResponse(true);
709 GcdPrivateStartPairingFunction::GcdPrivateStartPairingFunction() {
712 GcdPrivateStartPairingFunction::~GcdPrivateStartPairingFunction() {
715 bool GcdPrivateStartPairingFunction::RunAsync() {
716 scoped_ptr<gcd_private::StartPairing::Params> params =
717 gcd_private::StartPairing::Params::Create(*args_);
719 if (!params)
720 return false;
722 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
724 gcd_api->StartPairing(
725 params->session_id, params->pairing_type,
726 base::Bind(&GcdPrivateStartPairingFunction::OnPairingStarted, this));
728 return true;
731 void GcdPrivateStartPairingFunction::OnPairingStarted(
732 api::gcd_private::Status status) {
733 results_ = gcd_private::StartPairing::Results::Create(status);
734 SendResponse(true);
737 GcdPrivateConfirmCodeFunction::GcdPrivateConfirmCodeFunction() {
740 GcdPrivateConfirmCodeFunction::~GcdPrivateConfirmCodeFunction() {
743 bool GcdPrivateConfirmCodeFunction::RunAsync() {
744 scoped_ptr<gcd_private::ConfirmCode::Params> params =
745 gcd_private::ConfirmCode::Params::Create(*args_);
747 if (!params)
748 return false;
750 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
752 gcd_api->ConfirmCode(
753 params->session_id, params->code,
754 base::Bind(&GcdPrivateConfirmCodeFunction::OnCodeConfirmed, this));
756 return true;
759 void GcdPrivateConfirmCodeFunction::OnCodeConfirmed(
760 api::gcd_private::Status status) {
761 results_ = gcd_private::ConfirmCode::Results::Create(status);
762 SendResponse(true);
765 GcdPrivateSendMessageFunction::GcdPrivateSendMessageFunction() {
768 GcdPrivateSendMessageFunction::~GcdPrivateSendMessageFunction() {
771 bool GcdPrivateSendMessageFunction::RunAsync() {
772 scoped_ptr<gcd_private::PassMessage::Params> params =
773 gcd_private::PassMessage::Params::Create(*args_);
775 if (!params)
776 return false;
778 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
781 gcd_api->SendMessage(
782 params->session_id,
783 params->api,
784 params->input.additional_properties,
785 base::Bind(&GcdPrivateSendMessageFunction::OnMessageSentCallback, this));
787 return true;
790 void GcdPrivateSendMessageFunction::OnMessageSentCallback(
791 api::gcd_private::Status status,
792 const base::DictionaryValue& value) {
793 gcd_private::PassMessage::Results::Response response;
794 response.additional_properties.MergeDictionary(&value);
796 results_ = gcd_private::PassMessage::Results::Create(status, response);
797 SendResponse(true);
800 GcdPrivateTerminateSessionFunction::GcdPrivateTerminateSessionFunction() {
803 GcdPrivateTerminateSessionFunction::~GcdPrivateTerminateSessionFunction() {
806 bool GcdPrivateTerminateSessionFunction::RunAsync() {
807 scoped_ptr<gcd_private::TerminateSession::Params> params =
808 gcd_private::TerminateSession::Params::Create(*args_);
810 if (!params)
811 return false;
813 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
815 gcd_api->RemoveSession(params->session_id);
817 SendResponse(true);
818 return true;
821 GcdPrivateGetCommandDefinitionsFunction::
822 GcdPrivateGetCommandDefinitionsFunction() {
825 GcdPrivateGetCommandDefinitionsFunction::
826 ~GcdPrivateGetCommandDefinitionsFunction() {
829 GcdPrivateGetPrefetchedWifiNameListFunction::
830 GcdPrivateGetPrefetchedWifiNameListFunction() {
833 GcdPrivateGetPrefetchedWifiNameListFunction::
834 ~GcdPrivateGetPrefetchedWifiNameListFunction() {
837 bool GcdPrivateGetPrefetchedWifiNameListFunction::RunSync() {
838 GcdPrivateAPIImpl* gcd_api = GcdPrivateAPIImpl::Get(GetProfile());
840 scoped_ptr<base::ListValue> ssid_list = gcd_api->GetPrefetchedSSIDList();
842 SetResult(ssid_list.release());
844 return true;
847 bool GcdPrivateGetCommandDefinitionsFunction::RunAsync() {
848 return false;
851 GcdPrivateInsertCommandFunction::GcdPrivateInsertCommandFunction() {
854 GcdPrivateInsertCommandFunction::~GcdPrivateInsertCommandFunction() {
857 bool GcdPrivateInsertCommandFunction::RunAsync() {
858 return false;
861 GcdPrivateGetCommandFunction::GcdPrivateGetCommandFunction() {
864 GcdPrivateGetCommandFunction::~GcdPrivateGetCommandFunction() {
867 bool GcdPrivateGetCommandFunction::RunAsync() {
868 return false;
871 GcdPrivateCancelCommandFunction::GcdPrivateCancelCommandFunction() {
874 GcdPrivateCancelCommandFunction::~GcdPrivateCancelCommandFunction() {
877 bool GcdPrivateCancelCommandFunction::RunAsync() {
878 return false;
881 GcdPrivateGetCommandsListFunction::GcdPrivateGetCommandsListFunction() {
884 GcdPrivateGetCommandsListFunction::~GcdPrivateGetCommandsListFunction() {
887 bool GcdPrivateGetCommandsListFunction::RunAsync() {
888 return false;
891 } // namespace extensions