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"
36 namespace extensions
{
38 namespace gcd_private
= api::gcd_private
;
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()));
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
,
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
);
86 return scoped_ptr
<local_discovery::GCDApiFlow
>();
87 SigninManagerBase
* signin_manager
=
88 SigninManagerFactory::GetInstance()->GetForProfile(profile
);
90 return scoped_ptr
<local_discovery::GCDApiFlow
>();
91 return local_discovery::GCDApiFlow::Create(
92 profile
->GetRequestContext(),
94 signin_manager
->GetAuthenticatedAccountId());
99 class GcdPrivateSessionHolder
;
101 class GcdPrivateAPIImpl
: public EventRouter::Observer
,
102 public local_discovery::PrivetDeviceLister::Delegate
{
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();
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 */>
155 // EventRouter::Observer implementation.
156 void OnListenerAdded(const EventListenerInfo
& details
) override
;
157 void OnListenerRemoved(const EventListenerInfo
& details
) override
;
159 // local_discovery::PrivetDeviceLister implementation.
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
,
179 const std::string
& ssid
,
180 const std::string
& password
);
181 void StartWifiIfNotStarted();
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_
;
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_
;
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();
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(
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();
294 EventRouter::Get(browser_context_
)
295 ->BroadcastEvent(MakeDeviceRemovedEvent(i
->second
->device_id
));
298 known_devices_
.clear();
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_
)
312 privet_device_lister_
->DiscoverNewDevices(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(
333 const CreateSessionCallback
& callback
,
334 scoped_ptr
<local_discovery::PrivetHTTPClient
> 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
)) {
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
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(
420 base::Bind(&GcdPrivateAPIImpl::OnWifiPassword
,
421 base::Unretained(this),
428 #if defined(ENABLE_WIFI_BOOTSTRAPPING)
429 void GcdPrivateAPIImpl::OnWifiPassword(const SuccessCallback
& callback
,
431 const std::string
& ssid
,
432 const std::string
& password
) {
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();
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();
466 retval
->AppendString(i
->first
);
470 return retval
.Pass();
475 GcdPrivateAPI::GcdPrivateAPI(content::BrowserContext
* context
)
476 : impl_(new GcdPrivateAPIImpl(context
)) {
479 GcdPrivateAPI::~GcdPrivateAPI() {
483 BrowserContextKeyedAPIFactory
<GcdPrivateAPI
>*
484 GcdPrivateAPI::GetFactoryInstance() {
485 return g_factory
.Pointer();
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_
)
510 // Balanced in CheckListingDone()
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)));
521 void GcdPrivateGetCloudDeviceListFunction::OnDeviceListReady(
522 const DeviceList
& devices
) {
523 requests_succeeded_
++;
525 devices_
.insert(devices_
.end(), devices
.begin(), devices
.end());
530 void GcdPrivateGetCloudDeviceListFunction::OnDeviceListUnavailable() {
536 void GcdPrivateGetCloudDeviceListFunction::CheckListingDone() {
537 if (requests_failed_
+ requests_succeeded_
!= kNumRequestsNeeded
)
540 if (requests_succeeded_
== 0) {
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
;
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
);
570 GcdPrivateQueryForNewLocalDevicesFunction::
571 GcdPrivateQueryForNewLocalDevicesFunction() {
574 GcdPrivateQueryForNewLocalDevicesFunction::
575 ~GcdPrivateQueryForNewLocalDevicesFunction() {
578 bool GcdPrivateQueryForNewLocalDevicesFunction::RunSync() {
579 GcdPrivateAPIImpl
* gcd_api
= GcdPrivateAPIImpl::Get(GetProfile());
581 if (!gcd_api
->QueryForDevices()) {
583 "You must first subscribe to onDeviceStateChanged or onDeviceRemoved "
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_
);
606 GcdPrivateAPIImpl
* gcd_api
= GcdPrivateAPIImpl::Get(GetProfile());
608 gcd_api
->RequestWifiPassword(
610 base::Bind(&GcdPrivatePrefetchWifiPasswordFunction::OnResponse
, this));
615 void GcdPrivatePrefetchWifiPasswordFunction::OnResponse(bool response
) {
616 scoped_ptr
<base::FundamentalValue
> response_value(
617 new base::FundamentalValue(response
));
618 SetResult(response_value
.release());
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_
);
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
);
644 void GcdPrivateGetDeviceInfoFunction::OnSessionInitialized(
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
);
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_
);
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
);
680 void GcdPrivateCreateSessionFunction::OnSessionInitialized(
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
);
700 status
= gcd_private::STATUS_SESSIONERROR
;
704 results_
= gcd_private::CreateSession::Results::Create(session_id
, status
,
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_
);
722 GcdPrivateAPIImpl
* gcd_api
= GcdPrivateAPIImpl::Get(GetProfile());
724 gcd_api
->StartPairing(
725 params
->session_id
, params
->pairing_type
,
726 base::Bind(&GcdPrivateStartPairingFunction::OnPairingStarted
, this));
731 void GcdPrivateStartPairingFunction::OnPairingStarted(
732 api::gcd_private::Status status
) {
733 results_
= gcd_private::StartPairing::Results::Create(status
);
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_
);
750 GcdPrivateAPIImpl
* gcd_api
= GcdPrivateAPIImpl::Get(GetProfile());
752 gcd_api
->ConfirmCode(
753 params
->session_id
, params
->code
,
754 base::Bind(&GcdPrivateConfirmCodeFunction::OnCodeConfirmed
, this));
759 void GcdPrivateConfirmCodeFunction::OnCodeConfirmed(
760 api::gcd_private::Status status
) {
761 results_
= gcd_private::ConfirmCode::Results::Create(status
);
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_
);
778 GcdPrivateAPIImpl
* gcd_api
= GcdPrivateAPIImpl::Get(GetProfile());
781 gcd_api
->SendMessage(
784 params
->input
.additional_properties
,
785 base::Bind(&GcdPrivateSendMessageFunction::OnMessageSentCallback
, this));
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
);
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_
);
813 GcdPrivateAPIImpl
* gcd_api
= GcdPrivateAPIImpl::Get(GetProfile());
815 gcd_api
->RemoveSession(params
->session_id
);
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());
847 bool GcdPrivateGetCommandDefinitionsFunction::RunAsync() {
851 GcdPrivateInsertCommandFunction::GcdPrivateInsertCommandFunction() {
854 GcdPrivateInsertCommandFunction::~GcdPrivateInsertCommandFunction() {
857 bool GcdPrivateInsertCommandFunction::RunAsync() {
861 GcdPrivateGetCommandFunction::GcdPrivateGetCommandFunction() {
864 GcdPrivateGetCommandFunction::~GcdPrivateGetCommandFunction() {
867 bool GcdPrivateGetCommandFunction::RunAsync() {
871 GcdPrivateCancelCommandFunction::GcdPrivateCancelCommandFunction() {
874 GcdPrivateCancelCommandFunction::~GcdPrivateCancelCommandFunction() {
877 bool GcdPrivateCancelCommandFunction::RunAsync() {
881 GcdPrivateGetCommandsListFunction::GcdPrivateGetCommandsListFunction() {
884 GcdPrivateGetCommandsListFunction::~GcdPrivateGetCommandsListFunction() {
887 bool GcdPrivateGetCommandsListFunction::RunAsync() {
891 } // namespace extensions