- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / sockets_udp / sockets_udp_api.cc
1 // Copyright 2013 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/sockets_udp/sockets_udp_api.h"
6
7 #include "chrome/browser/extensions/api/socket/udp_socket.h"
8 #include "chrome/browser/extensions/api/sockets_udp/udp_socket_event_dispatcher.h"
9 #include "chrome/common/extensions/api/sockets/sockets_handler.h"
10 #include "content/public/common/socket_permission_request.h"
11 #include "net/base/net_errors.h"
12
13 namespace extensions {
14 namespace api {
15
16 using content::SocketPermissionRequest;
17
18 const char kSocketNotFoundError[] = "Socket not found";
19 const char kPermissionError[] = "App does not have permission";
20 const char kWildcardAddress[] = "*";
21 const int kWildcardPort = 0;
22
23 UDPSocketAsyncApiFunction::~UDPSocketAsyncApiFunction() {}
24
25 scoped_ptr<SocketResourceManagerInterface>
26     UDPSocketAsyncApiFunction::CreateSocketResourceManager() {
27   return scoped_ptr<SocketResourceManagerInterface>(
28       new SocketResourceManager<ResumableUDPSocket>()).Pass();
29 }
30
31 ResumableUDPSocket* UDPSocketAsyncApiFunction::GetUdpSocket(int socket_id) {
32   return static_cast<ResumableUDPSocket*>(GetSocket(socket_id));
33 }
34
35 UDPSocketExtensionWithDnsLookupFunction::
36     ~UDPSocketExtensionWithDnsLookupFunction() {}
37
38 scoped_ptr<SocketResourceManagerInterface>
39     UDPSocketExtensionWithDnsLookupFunction::CreateSocketResourceManager() {
40   return scoped_ptr<SocketResourceManagerInterface>(
41       new SocketResourceManager<ResumableUDPSocket>()).Pass();
42 }
43
44 ResumableUDPSocket* UDPSocketExtensionWithDnsLookupFunction::GetUdpSocket(
45     int socket_id) {
46   return static_cast<ResumableUDPSocket*>(GetSocket(socket_id));
47 }
48
49 linked_ptr<sockets_udp::SocketInfo> CreateSocketInfo(
50     int socket_id,
51     ResumableUDPSocket* socket) {
52   linked_ptr<sockets_udp::SocketInfo> socket_info(
53       new sockets_udp::SocketInfo());
54   // This represents what we know about the socket, and does not call through
55   // to the system.
56   socket_info->socket_id = socket_id;
57   if (!socket->name().empty()) {
58     socket_info->name.reset(new std::string(socket->name()));
59   }
60   socket_info->persistent = socket->persistent();
61   if (socket->buffer_size() > 0) {
62     socket_info->buffer_size.reset(new int(socket->buffer_size()));
63   }
64
65   // Grab the local address as known by the OS.
66   net::IPEndPoint localAddress;
67   if (socket->GetLocalAddress(&localAddress)) {
68     socket_info->local_address.reset(
69         new std::string(localAddress.ToStringWithoutPort()));
70     socket_info->local_port.reset(new int(localAddress.port()));
71   }
72
73   return socket_info;
74 }
75
76 void SetSocketProperties(ResumableUDPSocket* socket,
77                          sockets_udp::SocketProperties* properties) {
78   if (properties->name.get()) {
79     socket->set_name(*properties->name.get());
80   }
81   if (properties->persistent.get()) {
82     socket->set_persistent(*properties->persistent.get());
83   }
84   if (properties->buffer_size.get()) {
85     socket->set_buffer_size(*properties->buffer_size.get());
86   }
87 }
88
89 SocketsUdpCreateFunction::SocketsUdpCreateFunction() {}
90
91 SocketsUdpCreateFunction::~SocketsUdpCreateFunction() {}
92
93 bool SocketsUdpCreateFunction::Prepare() {
94   params_ = sockets_udp::Create::Params::Create(*args_);
95   EXTENSION_FUNCTION_VALIDATE(params_.get());
96   return true;
97 }
98
99 void SocketsUdpCreateFunction::Work() {
100   ResumableUDPSocket* socket = new ResumableUDPSocket(extension_->id());
101
102   sockets_udp::SocketProperties* properties = params_.get()->properties.get();
103   if (properties) {
104     SetSocketProperties(socket, properties);
105   }
106
107   sockets_udp::CreateInfo create_info;
108   create_info.socket_id = AddSocket(socket);
109   results_ = sockets_udp::Create::Results::Create(create_info);
110 }
111
112 SocketsUdpUpdateFunction::SocketsUdpUpdateFunction() {}
113
114 SocketsUdpUpdateFunction::~SocketsUdpUpdateFunction() {}
115
116 bool SocketsUdpUpdateFunction::Prepare() {
117   params_ = sockets_udp::Update::Params::Create(*args_);
118   EXTENSION_FUNCTION_VALIDATE(params_.get());
119   return true;
120 }
121
122 void SocketsUdpUpdateFunction::Work() {
123   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
124   if (!socket) {
125     error_ = kSocketNotFoundError;
126     return;
127   }
128
129   SetSocketProperties(socket, &params_.get()->properties);
130   results_ = sockets_udp::Update::Results::Create();
131 }
132
133 SocketsUdpBindFunction::SocketsUdpBindFunction()
134     : socket_event_dispatcher_(NULL) {
135 }
136
137 SocketsUdpBindFunction::~SocketsUdpBindFunction() {}
138
139 bool SocketsUdpBindFunction::Prepare() {
140   params_ = sockets_udp::Bind::Params::Create(*args_);
141   EXTENSION_FUNCTION_VALIDATE(params_.get());
142
143   socket_event_dispatcher_ = UDPSocketEventDispatcher::Get(GetProfile());
144   DCHECK(socket_event_dispatcher_) << "There is no socket event dispatcher. "
145     "If this assertion is failing during a test, then it is likely that "
146     "TestExtensionSystem is failing to provide an instance of "
147     "UDPSocketEventDispatcher.";
148   return socket_event_dispatcher_ != NULL;
149 }
150
151 void SocketsUdpBindFunction::Work() {
152   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
153   if (!socket) {
154     error_ = kSocketNotFoundError;
155     return;
156   }
157
158   content::SocketPermissionRequest param(
159       SocketPermissionRequest::UDP_BIND,
160       params_->address,
161       params_->port);
162   if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
163     error_ = kPermissionError;
164     return;
165   }
166
167   int net_result = socket->Bind(params_->address, params_->port);
168   if (net_result == net::OK) {
169     socket_event_dispatcher_->OnSocketBind(extension_->id(),
170                                            params_->socket_id);
171   }
172
173   if (net_result != net::OK)
174     error_ = net::ErrorToString(net_result);
175   results_ = sockets_udp::Bind::Results::Create(net_result);
176 }
177
178 SocketsUdpSendFunction::SocketsUdpSendFunction()
179     : io_buffer_size_(0) {}
180
181 SocketsUdpSendFunction::~SocketsUdpSendFunction() {}
182
183 bool SocketsUdpSendFunction::Prepare() {
184   params_ = sockets_udp::Send::Params::Create(*args_);
185   EXTENSION_FUNCTION_VALIDATE(params_.get());
186   io_buffer_size_ = params_->data.size();
187   io_buffer_ = new net::WrappedIOBuffer(params_->data.data());
188   return true;
189 }
190
191 void SocketsUdpSendFunction::AsyncWorkStart() {
192   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
193   if (!socket) {
194     error_ = kSocketNotFoundError;
195     AsyncWorkCompleted();
196     return;
197   }
198
199   content::SocketPermissionRequest param(
200       SocketPermissionRequest::UDP_SEND_TO,
201       params_->address,
202       params_->port);
203   if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
204     error_ = kPermissionError;
205     AsyncWorkCompleted();
206     return;
207   }
208
209   StartDnsLookup(params_->address);
210 }
211
212 void SocketsUdpSendFunction::AfterDnsLookup(int lookup_result) {
213   if (lookup_result == net::OK) {
214     StartSendTo();
215   } else {
216     SetSendResult(lookup_result, -1);
217   }
218 }
219
220 void SocketsUdpSendFunction::StartSendTo() {
221   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
222   if (!socket) {
223     error_ = kSocketNotFoundError;
224     AsyncWorkCompleted();
225     return;
226   }
227
228   socket->SendTo(io_buffer_, io_buffer_size_, resolved_address_, params_->port,
229                   base::Bind(&SocketsUdpSendFunction::OnCompleted, this));
230 }
231
232 void SocketsUdpSendFunction::OnCompleted(int net_result) {
233   if (net_result >= net::OK) {
234     SetSendResult(net::OK, net_result);
235   } else {
236     SetSendResult(net_result, -1);
237   }
238 }
239
240 void SocketsUdpSendFunction::SetSendResult(int net_result, int bytes_sent) {
241   CHECK(net_result <= net::OK) << "Network status code must be < 0";
242
243   sockets_udp::SendInfo send_info;
244   send_info.result_code = net_result;
245   if (net_result == net::OK) {
246     send_info.bytes_sent.reset(new int(bytes_sent));
247   }
248
249   if (net_result != net::OK)
250     error_ = net::ErrorToString(net_result);
251   results_ = sockets_udp::Send::Results::Create(send_info);
252   AsyncWorkCompleted();
253 }
254
255 SocketsUdpCloseFunction::SocketsUdpCloseFunction() {}
256
257 SocketsUdpCloseFunction::~SocketsUdpCloseFunction() {}
258
259 bool SocketsUdpCloseFunction::Prepare() {
260   params_ = sockets_udp::Close::Params::Create(*args_);
261   EXTENSION_FUNCTION_VALIDATE(params_.get());
262   return true;
263 }
264
265 void SocketsUdpCloseFunction::Work() {
266   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
267   if (!socket) {
268     error_ = kSocketNotFoundError;
269     return;
270   }
271
272   RemoveSocket(params_->socket_id);
273   results_ = sockets_udp::Close::Results::Create();
274 }
275
276 SocketsUdpGetInfoFunction::SocketsUdpGetInfoFunction() {}
277
278 SocketsUdpGetInfoFunction::~SocketsUdpGetInfoFunction() {}
279
280 bool SocketsUdpGetInfoFunction::Prepare() {
281   params_ = sockets_udp::GetInfo::Params::Create(*args_);
282   EXTENSION_FUNCTION_VALIDATE(params_.get());
283   return true;
284 }
285
286 void SocketsUdpGetInfoFunction::Work() {
287   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
288   if (!socket) {
289     error_ = kSocketNotFoundError;
290     return;
291   }
292
293   linked_ptr<sockets_udp::SocketInfo> socket_info =
294       CreateSocketInfo(params_->socket_id, socket);
295   results_ = sockets_udp::GetInfo::Results::Create(*socket_info);
296 }
297
298 SocketsUdpGetSocketsFunction::SocketsUdpGetSocketsFunction() {}
299
300 SocketsUdpGetSocketsFunction::~SocketsUdpGetSocketsFunction() {}
301
302 bool SocketsUdpGetSocketsFunction::Prepare() {
303   return true;
304 }
305
306 void SocketsUdpGetSocketsFunction::Work() {
307   std::vector<linked_ptr<sockets_udp::SocketInfo> > socket_infos;
308   base::hash_set<int>* resource_ids = GetSocketIds();
309   if (resource_ids != NULL) {
310     for (base::hash_set<int>::iterator it = resource_ids->begin();
311              it != resource_ids->end(); ++it) {
312       int socket_id = *it;
313       ResumableUDPSocket* socket = GetUdpSocket(socket_id);
314       if (socket) {
315         socket_infos.push_back(CreateSocketInfo(socket_id, socket));
316       }
317     }
318   }
319   results_ = sockets_udp::GetSockets::Results::Create(socket_infos);
320 }
321
322 SocketsUdpJoinGroupFunction::SocketsUdpJoinGroupFunction() {}
323
324 SocketsUdpJoinGroupFunction::~SocketsUdpJoinGroupFunction() {}
325
326 bool SocketsUdpJoinGroupFunction::Prepare() {
327   params_ = sockets_udp::JoinGroup::Params::Create(*args_);
328   EXTENSION_FUNCTION_VALIDATE(params_.get());
329   return true;
330 }
331
332 void SocketsUdpJoinGroupFunction::Work() {
333   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
334   if (!socket) {
335     error_ = kSocketNotFoundError;
336     return;
337   }
338
339   content::SocketPermissionRequest param(
340       SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
341       kWildcardAddress,
342       kWildcardPort);
343   if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
344     error_ = kPermissionError;
345     return;
346   }
347
348   int net_result = socket->JoinGroup(params_->address);
349   if (net_result != net::OK)
350     error_ = net::ErrorToString(net_result);
351   results_ = sockets_udp::JoinGroup::Results::Create(net_result);
352 }
353
354 SocketsUdpLeaveGroupFunction::SocketsUdpLeaveGroupFunction() {}
355
356 SocketsUdpLeaveGroupFunction::~SocketsUdpLeaveGroupFunction() {}
357
358 bool SocketsUdpLeaveGroupFunction::Prepare() {
359   params_ = api::sockets_udp::LeaveGroup::Params::Create(*args_);
360   EXTENSION_FUNCTION_VALIDATE(params_.get());
361   return true;
362 }
363
364 void SocketsUdpLeaveGroupFunction::Work() {
365   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
366   if (!socket) {
367     error_ = kSocketNotFoundError;
368     return;
369   }
370
371   content::SocketPermissionRequest param(
372       SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
373       kWildcardAddress,
374       kWildcardPort);
375   if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
376     error_ = kPermissionError;
377     return;
378   }
379
380   int net_result = socket->LeaveGroup(params_->address);
381   if (net_result != net::OK)
382     error_ = net::ErrorToString(net_result);
383   results_ = sockets_udp::LeaveGroup::Results::Create(net_result);
384 }
385
386 SocketsUdpSetMulticastTimeToLiveFunction::
387     SocketsUdpSetMulticastTimeToLiveFunction() {}
388
389 SocketsUdpSetMulticastTimeToLiveFunction::
390     ~SocketsUdpSetMulticastTimeToLiveFunction() {}
391
392 bool SocketsUdpSetMulticastTimeToLiveFunction::Prepare() {
393   params_ = api::sockets_udp::SetMulticastTimeToLive::Params::Create(*args_);
394   EXTENSION_FUNCTION_VALIDATE(params_.get());
395   return true;
396 }
397
398 void SocketsUdpSetMulticastTimeToLiveFunction::Work() {
399   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
400   if (!socket) {
401     error_ = kSocketNotFoundError;
402     return;
403   }
404
405   int net_result = socket->SetMulticastTimeToLive(params_->ttl);
406   if (net_result != net::OK)
407     error_ = net::ErrorToString(net_result);
408   results_ = sockets_udp::SetMulticastTimeToLive::Results::Create(net_result);
409 }
410
411 SocketsUdpSetMulticastLoopbackModeFunction::
412     SocketsUdpSetMulticastLoopbackModeFunction() {}
413
414 SocketsUdpSetMulticastLoopbackModeFunction::
415   ~SocketsUdpSetMulticastLoopbackModeFunction() {}
416
417 bool SocketsUdpSetMulticastLoopbackModeFunction::Prepare() {
418   params_ = api::sockets_udp::SetMulticastLoopbackMode::Params::Create(*args_);
419   EXTENSION_FUNCTION_VALIDATE(params_.get());
420   return true;
421 }
422
423 void SocketsUdpSetMulticastLoopbackModeFunction::Work() {
424   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
425   if (!socket) {
426     error_ = kSocketNotFoundError;
427     return;
428   }
429
430   int net_result = socket->SetMulticastLoopbackMode(params_->enabled);
431   if (net_result != net::OK)
432     error_ = net::ErrorToString(net_result);
433   results_ = sockets_udp::SetMulticastLoopbackMode::Results::Create(net_result);
434 }
435
436 SocketsUdpGetJoinedGroupsFunction::SocketsUdpGetJoinedGroupsFunction() {}
437
438 SocketsUdpGetJoinedGroupsFunction::~SocketsUdpGetJoinedGroupsFunction() {}
439
440 bool SocketsUdpGetJoinedGroupsFunction::Prepare() {
441   params_ = api::sockets_udp::GetJoinedGroups::Params::Create(*args_);
442   EXTENSION_FUNCTION_VALIDATE(params_.get());
443   return true;
444 }
445
446 void SocketsUdpGetJoinedGroupsFunction::Work() {
447   ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id);
448   if (!socket) {
449     error_ = kSocketNotFoundError;
450     return;
451   }
452
453   content::SocketPermissionRequest param(
454       SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
455       kWildcardAddress,
456       kWildcardPort);
457   if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
458     error_ = kPermissionError;
459     return;
460   }
461
462   const std::vector<std::string>& groups = socket->GetJoinedGroups();
463   results_ = sockets_udp::GetJoinedGroups::Results::Create(groups);
464 }
465
466 }  // namespace api
467 }  // namespace extensions