Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / dial / dial_api.cc
1 // Copyright (c) 2012 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.
4
5 #include "chrome/browser/extensions/api/dial/dial_api.h"
6
7 #include <vector>
8
9 #include "base/time/time.h"
10 #include "chrome/browser/extensions/api/dial/dial_api_factory.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/common/extensions/api/dial.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "extensions/browser/event_router.h"
15 #include "extensions/browser/extension_system.h"
16
17 using base::TimeDelta;
18 using content::BrowserThread;
19
20 namespace {
21
22 const char kDialServiceError[] = "Dial service error.";
23
24 // How often to poll for devices.
25 const int kDialRefreshIntervalSecs = 120;
26
27 // We prune a device if it does not respond after this time.
28 const int kDialExpirationSecs = 240;
29
30 // The maximum number of devices retained at once in the registry.
31 const size_t kDialMaxDevices = 256;
32
33 }  // namespace
34
35 namespace extensions {
36
37 namespace dial = api::dial;
38
39 DialAPI::DialAPI(Profile* profile)
40     : RefcountedBrowserContextKeyedService(BrowserThread::IO),
41       profile_(profile) {
42   EventRouter::Get(profile)
43       ->RegisterObserver(this, dial::OnDeviceList::kEventName);
44 }
45
46 DialAPI::~DialAPI() {}
47
48 DialRegistry* DialAPI::dial_registry() {
49   DCHECK_CURRENTLY_ON(BrowserThread::IO);
50   if (!dial_registry_.get()) {
51     dial_registry_.reset(new DialRegistry(this,
52         TimeDelta::FromSeconds(kDialRefreshIntervalSecs),
53         TimeDelta::FromSeconds(kDialExpirationSecs),
54         kDialMaxDevices));
55   }
56   return dial_registry_.get();
57 }
58
59 void DialAPI::OnListenerAdded(const EventListenerInfo& details) {
60   DCHECK_CURRENTLY_ON(BrowserThread::UI);
61   BrowserThread::PostTask(
62       BrowserThread::IO, FROM_HERE,
63       base::Bind(&DialAPI::NotifyListenerAddedOnIOThread, this));
64 }
65
66 void DialAPI::OnListenerRemoved(const EventListenerInfo& details) {
67   DCHECK_CURRENTLY_ON(BrowserThread::UI);
68   BrowserThread::PostTask(
69       BrowserThread::IO, FROM_HERE,
70       base::Bind(&DialAPI::NotifyListenerRemovedOnIOThread, this));
71 }
72
73 void DialAPI::NotifyListenerAddedOnIOThread() {
74   DCHECK_CURRENTLY_ON(BrowserThread::IO);
75   VLOG(1) << "DIAL device event listener added.";
76   dial_registry()->OnListenerAdded();
77 }
78
79 void DialAPI::NotifyListenerRemovedOnIOThread() {
80   DCHECK_CURRENTLY_ON(BrowserThread::IO);
81   VLOG(1) << "DIAL device event listener removed";
82   dial_registry()->OnListenerRemoved();
83 }
84
85 void DialAPI::OnDialDeviceEvent(const DialRegistry::DeviceList& devices) {
86   DCHECK_CURRENTLY_ON(BrowserThread::IO);
87   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
88       base::Bind(&DialAPI::SendEventOnUIThread, this, devices));
89 }
90
91 void DialAPI::OnDialError(const DialRegistry::DialErrorCode code) {
92   DCHECK_CURRENTLY_ON(BrowserThread::IO);
93   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
94       base::Bind(&DialAPI::SendErrorOnUIThread, this, code));
95 }
96
97 void DialAPI::SendEventOnUIThread(const DialRegistry::DeviceList& devices) {
98   DCHECK_CURRENTLY_ON(BrowserThread::UI);
99
100   std::vector<linked_ptr<api::dial::DialDevice> > args;
101   for (DialRegistry::DeviceList::const_iterator it = devices.begin();
102        it != devices.end(); ++it) {
103     linked_ptr<api::dial::DialDevice> api_device =
104         make_linked_ptr(new api::dial::DialDevice);
105     it->FillDialDevice(api_device.get());
106     args.push_back(api_device);
107   }
108   scoped_ptr<base::ListValue> results = api::dial::OnDeviceList::Create(args);
109   scoped_ptr<Event> event(
110       new Event(dial::OnDeviceList::kEventName, results.Pass()));
111   EventRouter::Get(profile_)->BroadcastEvent(event.Pass());
112 }
113
114 void DialAPI::SendErrorOnUIThread(const DialRegistry::DialErrorCode code) {
115   DCHECK_CURRENTLY_ON(BrowserThread::UI);
116
117   api::dial::DialError dial_error;
118   switch (code) {
119     case DialRegistry::DIAL_NO_LISTENERS:
120       dial_error.code = api::dial::DIAL_ERROR_CODE_NO_LISTENERS;
121       break;
122     case DialRegistry::DIAL_NO_INTERFACES:
123       dial_error.code = api::dial::DIAL_ERROR_CODE_NO_VALID_NETWORK_INTERFACES;
124       break;
125     case DialRegistry::DIAL_CELLULAR_NETWORK:
126       dial_error.code = api::dial::DIAL_ERROR_CODE_CELLULAR_NETWORK;
127       break;
128     case DialRegistry::DIAL_NETWORK_DISCONNECTED:
129       dial_error.code = api::dial::DIAL_ERROR_CODE_NETWORK_DISCONNECTED;
130       break;
131     case DialRegistry::DIAL_SOCKET_ERROR:
132       dial_error.code = api::dial::DIAL_ERROR_CODE_SOCKET_ERROR;
133       break;
134     default:
135       dial_error.code = api::dial::DIAL_ERROR_CODE_UNKNOWN;
136       break;
137   }
138
139   scoped_ptr<base::ListValue> results = api::dial::OnError::Create(dial_error);
140   scoped_ptr<Event> event(new Event(dial::OnError::kEventName, results.Pass()));
141   EventRouter::Get(profile_)->BroadcastEvent(event.Pass());
142 }
143
144 void DialAPI::ShutdownOnUIThread() {}
145
146 namespace api {
147
148 DialDiscoverNowFunction::DialDiscoverNowFunction()
149     : dial_(NULL), result_(false) {
150 }
151
152 bool DialDiscoverNowFunction::Prepare() {
153   DCHECK_CURRENTLY_ON(BrowserThread::UI);
154   DCHECK(browser_context());
155   dial_ = DialAPIFactory::GetForBrowserContext(browser_context()).get();
156   return true;
157 }
158
159 void DialDiscoverNowFunction::Work() {
160   DCHECK_CURRENTLY_ON(BrowserThread::IO);
161   result_ = dial_->dial_registry()->DiscoverNow();
162 }
163
164 bool DialDiscoverNowFunction::Respond() {
165   DCHECK_CURRENTLY_ON(BrowserThread::UI);
166   if (!result_)
167     error_ = kDialServiceError;
168
169   SetResult(new base::FundamentalValue(result_));
170   return true;
171 }
172
173 }  // namespace api
174
175 }  // namespace extensions