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