- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / sockets_tcp_server / sockets_tcp_server_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_tcp_server/sockets_tcp_server_api.h"
6
7 #include "chrome/browser/extensions/api/socket/tcp_socket.h"
8 #include "chrome/browser/extensions/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h"
9 #include "chrome/common/extensions/api/sockets/sockets_handler.h"
10 #include "chrome/common/extensions/permissions/permissions_data.h"
11 #include "chrome/common/extensions/permissions/socket_permission.h"
12 #include "content/public/common/socket_permission_request.h"
13 #include "net/base/net_errors.h"
14
15 using content::SocketPermissionRequest;
16 using extensions::ResumableTCPServerSocket;
17 using extensions::api::sockets_tcp_server::SocketInfo;
18 using extensions::api::sockets_tcp_server::SocketProperties;
19
20 namespace {
21
22 const char kSocketNotFoundError[] = "Socket not found";
23 const char kPermissionError[] = "Does not have permission";
24 const int kDefaultListenBacklog = SOMAXCONN;
25
26 linked_ptr<SocketInfo> CreateSocketInfo(int socket_id,
27                                         ResumableTCPServerSocket* socket) {
28   linked_ptr<SocketInfo> socket_info(new SocketInfo());
29   // This represents what we know about the socket, and does not call through
30   // to the system.
31   socket_info->socket_id = socket_id;
32   if (!socket->name().empty()) {
33     socket_info->name.reset(new std::string(socket->name()));
34   }
35   socket_info->persistent = socket->persistent();
36   socket_info->paused = socket->paused();
37
38   // Grab the local address as known by the OS.
39   net::IPEndPoint localAddress;
40   if (socket->GetLocalAddress(&localAddress)) {
41     socket_info->local_address.reset(
42         new std::string(localAddress.ToStringWithoutPort()));
43     socket_info->local_port.reset(new int(localAddress.port()));
44   }
45
46   return socket_info;
47 }
48
49 void SetSocketProperties(ResumableTCPServerSocket* socket,
50                          SocketProperties* properties) {
51   if (properties->name.get()) {
52     socket->set_name(*properties->name.get());
53   }
54   if (properties->persistent.get()) {
55     socket->set_persistent(*properties->persistent.get());
56   }
57 }
58
59 }  // namespace
60
61 namespace extensions {
62 namespace api {
63
64 TCPServerSocketAsyncApiFunction::~TCPServerSocketAsyncApiFunction() {}
65
66 scoped_ptr<SocketResourceManagerInterface>
67     TCPServerSocketAsyncApiFunction::CreateSocketResourceManager() {
68   return scoped_ptr<SocketResourceManagerInterface>(
69       new SocketResourceManager<ResumableTCPServerSocket>()).Pass();
70 }
71
72 ResumableTCPServerSocket* TCPServerSocketAsyncApiFunction::GetTcpSocket(
73     int socket_id) {
74   return static_cast<ResumableTCPServerSocket*>(GetSocket(socket_id));
75 }
76
77 SocketsTcpServerCreateFunction::SocketsTcpServerCreateFunction() {}
78
79 SocketsTcpServerCreateFunction::~SocketsTcpServerCreateFunction() {}
80
81 bool SocketsTcpServerCreateFunction::Prepare() {
82   params_ = sockets_tcp_server::Create::Params::Create(*args_);
83   EXTENSION_FUNCTION_VALIDATE(params_.get());
84   return true;
85 }
86
87 void SocketsTcpServerCreateFunction::Work() {
88   ResumableTCPServerSocket* socket =
89       new ResumableTCPServerSocket(extension_->id());
90
91   sockets_tcp_server::SocketProperties* properties =
92       params_.get()->properties.get();
93   if (properties) {
94     SetSocketProperties(socket, properties);
95   }
96
97   sockets_tcp_server::CreateInfo create_info;
98   create_info.socket_id = AddSocket(socket);
99   results_ = sockets_tcp_server::Create::Results::Create(create_info);
100 }
101
102 SocketsTcpServerUpdateFunction::SocketsTcpServerUpdateFunction() {}
103
104 SocketsTcpServerUpdateFunction::~SocketsTcpServerUpdateFunction() {}
105
106 bool SocketsTcpServerUpdateFunction::Prepare() {
107   params_ = sockets_tcp_server::Update::Params::Create(*args_);
108   EXTENSION_FUNCTION_VALIDATE(params_.get());
109   return true;
110 }
111
112 void SocketsTcpServerUpdateFunction::Work() {
113   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
114   if (!socket) {
115     error_ = kSocketNotFoundError;
116     return;
117   }
118
119   SetSocketProperties(socket, &params_.get()->properties);
120   results_ = sockets_tcp_server::Update::Results::Create();
121 }
122
123 SocketsTcpServerSetPausedFunction::SocketsTcpServerSetPausedFunction()
124     : socket_event_dispatcher_(NULL) {}
125
126 SocketsTcpServerSetPausedFunction::~SocketsTcpServerSetPausedFunction() {}
127
128 bool SocketsTcpServerSetPausedFunction::Prepare() {
129   params_ = api::sockets_tcp_server::SetPaused::Params::Create(*args_);
130   EXTENSION_FUNCTION_VALIDATE(params_.get());
131
132   socket_event_dispatcher_ = TCPServerSocketEventDispatcher::Get(GetProfile());
133   DCHECK(socket_event_dispatcher_) << "There is no socket event dispatcher. "
134     "If this assertion is failing during a test, then it is likely that "
135     "TestExtensionSystem is failing to provide an instance of "
136     "TCPServerSocketEventDispatcher.";
137   return socket_event_dispatcher_ != NULL;
138 }
139
140 void SocketsTcpServerSetPausedFunction::Work() {
141   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
142   if (!socket) {
143     error_ = kSocketNotFoundError;
144     return;
145   }
146
147   if (socket->paused() != params_->paused) {
148     socket->set_paused(params_->paused);
149     if (socket->IsConnected() && !params_->paused) {
150       socket_event_dispatcher_->OnServerSocketResume(extension_->id(),
151                                                      params_->socket_id);
152     }
153   }
154
155   results_ = sockets_tcp_server::SetPaused::Results::Create();
156 }
157
158 SocketsTcpServerListenFunction::SocketsTcpServerListenFunction()
159   : socket_event_dispatcher_(NULL) {}
160
161 SocketsTcpServerListenFunction::~SocketsTcpServerListenFunction() {}
162
163 bool SocketsTcpServerListenFunction::Prepare() {
164   params_ = api::sockets_tcp_server::Listen::Params::Create(*args_);
165   EXTENSION_FUNCTION_VALIDATE(params_.get());
166
167   socket_event_dispatcher_ = TCPServerSocketEventDispatcher::Get(GetProfile());
168   DCHECK(socket_event_dispatcher_) << "There is no socket event dispatcher. "
169     "If this assertion is failing during a test, then it is likely that "
170     "TestExtensionSystem is failing to provide an instance of "
171     "TCPServerSocketEventDispatcher.";
172   return socket_event_dispatcher_ != NULL;
173 }
174
175 void SocketsTcpServerListenFunction::Work() {
176   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
177   if (!socket) {
178     error_ = kSocketNotFoundError;
179     return;
180   }
181
182   SocketPermissionRequest param(
183       SocketPermissionRequest::TCP_LISTEN,
184       params_->address,
185       params_->port);
186   if (!SocketsManifestData::CheckRequest(GetExtension(), param)) {
187     error_ = kPermissionError;
188     return;
189   }
190
191   int net_result = socket->Listen(
192       params_->address,
193       params_->port,
194       params_->backlog.get() ? *params_->backlog.get() : kDefaultListenBacklog,
195       &error_);
196
197   if (net_result != net::OK)
198     error_ = net::ErrorToString(net_result);
199
200
201   if (net_result == net::OK) {
202     socket_event_dispatcher_->OnServerSocketListen(extension_->id(),
203                                                    params_->socket_id);
204   }
205
206   results_ = sockets_tcp_server::Listen::Results::Create(net_result);
207 }
208
209 SocketsTcpServerDisconnectFunction::SocketsTcpServerDisconnectFunction() {}
210
211 SocketsTcpServerDisconnectFunction::~SocketsTcpServerDisconnectFunction() {}
212
213 bool SocketsTcpServerDisconnectFunction::Prepare() {
214   params_ = sockets_tcp_server::Disconnect::Params::Create(*args_);
215   EXTENSION_FUNCTION_VALIDATE(params_.get());
216   return true;
217 }
218
219 void SocketsTcpServerDisconnectFunction::Work() {
220   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
221   if (!socket) {
222     error_ = kSocketNotFoundError;
223     return;
224   }
225
226   socket->Disconnect();
227   results_ = sockets_tcp_server::Disconnect::Results::Create();
228 }
229
230 SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {}
231
232 SocketsTcpServerCloseFunction::~SocketsTcpServerCloseFunction() {}
233
234 bool SocketsTcpServerCloseFunction::Prepare() {
235   params_ = sockets_tcp_server::Close::Params::Create(*args_);
236   EXTENSION_FUNCTION_VALIDATE(params_.get());
237   return true;
238 }
239
240 void SocketsTcpServerCloseFunction::Work() {
241   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
242   if (!socket) {
243     error_ = kSocketNotFoundError;
244     return;
245   }
246
247   RemoveSocket(params_->socket_id);
248   results_ = sockets_tcp_server::Close::Results::Create();
249 }
250
251 SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {}
252
253 SocketsTcpServerGetInfoFunction::~SocketsTcpServerGetInfoFunction() {}
254
255 bool SocketsTcpServerGetInfoFunction::Prepare() {
256   params_ = sockets_tcp_server::GetInfo::Params::Create(*args_);
257   EXTENSION_FUNCTION_VALIDATE(params_.get());
258   return true;
259 }
260
261 void SocketsTcpServerGetInfoFunction::Work() {
262   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
263   if (!socket) {
264     error_ = kSocketNotFoundError;
265     return;
266   }
267
268   linked_ptr<sockets_tcp_server::SocketInfo> socket_info =
269       CreateSocketInfo(params_->socket_id, socket);
270   results_ = sockets_tcp_server::GetInfo::Results::Create(*socket_info);
271 }
272
273 SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {}
274
275 SocketsTcpServerGetSocketsFunction::~SocketsTcpServerGetSocketsFunction() {}
276
277 bool SocketsTcpServerGetSocketsFunction::Prepare() {
278   return true;
279 }
280
281 void SocketsTcpServerGetSocketsFunction::Work() {
282   std::vector<linked_ptr<sockets_tcp_server::SocketInfo> > socket_infos;
283   base::hash_set<int>* resource_ids = GetSocketIds();
284   if (resource_ids != NULL) {
285     for (base::hash_set<int>::iterator it = resource_ids->begin();
286              it != resource_ids->end(); ++it) {
287       int socket_id = *it;
288       ResumableTCPServerSocket* socket = GetTcpSocket(socket_id);
289       if (socket) {
290         socket_infos.push_back(CreateSocketInfo(socket_id, socket));
291       }
292     }
293   }
294   results_ = sockets_tcp_server::GetSockets::Results::Create(socket_infos);
295 }
296
297 }  // namespace api
298 }  // namespace extensions