Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chrome/browser/extensions/api/socket/socket_api.cc

Issue 183893041: Move sockets APIs out of src/chrome (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rename api targets Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/socket/socket_api.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/containers/hash_tables.h"
11 #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h"
12 #include "chrome/browser/extensions/api/socket/socket.h"
13 #include "chrome/browser/extensions/api/socket/tcp_socket.h"
14 #include "chrome/browser/extensions/api/socket/udp_socket.h"
15 #include "chrome/common/extensions/permissions/socket_permission.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/resource_context.h"
18 #include "extensions/browser/extension_system.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/permissions/permissions_data.h"
21 #include "net/base/host_port_pair.h"
22 #include "net/base/io_buffer.h"
23 #include "net/base/ip_endpoint.h"
24 #include "net/base/net_errors.h"
25 #include "net/base/net_log.h"
26 #include "net/base/net_util.h"
27
28 namespace extensions {
29
30 using content::SocketPermissionRequest;
31
32 const char kAddressKey[] = "address";
33 const char kPortKey[] = "port";
34 const char kBytesWrittenKey[] = "bytesWritten";
35 const char kDataKey[] = "data";
36 const char kResultCodeKey[] = "resultCode";
37 const char kSocketIdKey[] = "socketId";
38
39 const char kSocketNotFoundError[] = "Socket not found";
40 const char kDnsLookupFailedError[] = "DNS resolution failed";
41 const char kPermissionError[] = "App does not have permission";
42 const char kNetworkListError[] = "Network lookup failed or unsupported";
43 const char kTCPSocketBindError[] =
44 "TCP socket does not support bind. For TCP server please use listen.";
45 const char kMulticastSocketTypeError[] =
46 "Only UDP socket supports multicast.";
47 const char kWildcardAddress[] = "*";
48 const int kWildcardPort = 0;
49
50 SocketAsyncApiFunction::SocketAsyncApiFunction() {
51 }
52
53 SocketAsyncApiFunction::~SocketAsyncApiFunction() {
54 }
55
56 bool SocketAsyncApiFunction::PrePrepare() {
57 manager_ = CreateSocketResourceManager();
58 return manager_->SetBrowserContext(browser_context());
59 }
60
61 bool SocketAsyncApiFunction::Respond() {
62 return error_.empty();
63 }
64
65 scoped_ptr<SocketResourceManagerInterface>
66 SocketAsyncApiFunction::CreateSocketResourceManager() {
67 return scoped_ptr<SocketResourceManagerInterface>(
68 new SocketResourceManager<Socket>()).Pass();
69 }
70
71 int SocketAsyncApiFunction::AddSocket(Socket* socket) {
72 return manager_->Add(socket);
73 }
74
75 Socket* SocketAsyncApiFunction::GetSocket(int api_resource_id) {
76 return manager_->Get(extension_->id(), api_resource_id);
77 }
78
79 base::hash_set<int>* SocketAsyncApiFunction::GetSocketIds() {
80 return manager_->GetResourceIds(extension_->id());
81 }
82
83 void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) {
84 manager_->Remove(extension_->id(), api_resource_id);
85 }
86
87 SocketExtensionWithDnsLookupFunction::SocketExtensionWithDnsLookupFunction()
88 : resource_context_(NULL),
89 request_handle_(new net::HostResolver::RequestHandle),
90 addresses_(new net::AddressList) {}
91
92 SocketExtensionWithDnsLookupFunction::~SocketExtensionWithDnsLookupFunction() {
93 }
94
95 bool SocketExtensionWithDnsLookupFunction::PrePrepare() {
96 if (!SocketAsyncApiFunction::PrePrepare())
97 return false;
98 resource_context_ = browser_context()->GetResourceContext();
99 return resource_context_ != NULL;
100 }
101
102 void SocketExtensionWithDnsLookupFunction::StartDnsLookup(
103 const std::string& hostname) {
104 net::HostResolver* host_resolver =
105 extensions::HostResolverWrapper::GetInstance()->GetHostResolver(
106 resource_context_->GetHostResolver());
107 DCHECK(host_resolver);
108
109 // Yes, we are passing zero as the port. There are some interesting but not
110 // presently relevant reasons why HostResolver asks for the port of the
111 // hostname you'd like to resolve, even though it doesn't use that value in
112 // determining its answer.
113 net::HostPortPair host_port_pair(hostname, 0);
114
115 net::HostResolver::RequestInfo request_info(host_port_pair);
116 int resolve_result = host_resolver->Resolve(
117 request_info,
118 net::DEFAULT_PRIORITY,
119 addresses_.get(),
120 base::Bind(&SocketExtensionWithDnsLookupFunction::OnDnsLookup, this),
121 request_handle_.get(),
122 net::BoundNetLog());
123
124 if (resolve_result != net::ERR_IO_PENDING)
125 OnDnsLookup(resolve_result);
126 }
127
128 void SocketExtensionWithDnsLookupFunction::OnDnsLookup(int resolve_result) {
129 if (resolve_result == net::OK) {
130 DCHECK(!addresses_->empty());
131 resolved_address_ = addresses_->front().ToStringWithoutPort();
132 } else {
133 error_ = kDnsLookupFailedError;
134 }
135 AfterDnsLookup(resolve_result);
136 }
137
138 SocketCreateFunction::SocketCreateFunction()
139 : socket_type_(kSocketTypeInvalid) {
140 }
141
142 SocketCreateFunction::~SocketCreateFunction() {}
143
144 bool SocketCreateFunction::Prepare() {
145 params_ = api::socket::Create::Params::Create(*args_);
146 EXTENSION_FUNCTION_VALIDATE(params_.get());
147
148 switch (params_->type) {
149 case extensions::api::socket::SOCKET_TYPE_TCP:
150 socket_type_ = kSocketTypeTCP;
151 break;
152 case extensions::api::socket::SOCKET_TYPE_UDP:
153 socket_type_ = kSocketTypeUDP;
154 break;
155 case extensions::api::socket::SOCKET_TYPE_NONE:
156 NOTREACHED();
157 break;
158 }
159
160 return true;
161 }
162
163 void SocketCreateFunction::Work() {
164 Socket* socket = NULL;
165 if (socket_type_ == kSocketTypeTCP) {
166 socket = new TCPSocket(extension_->id());
167 } else if (socket_type_== kSocketTypeUDP) {
168 socket = new UDPSocket(extension_->id());
169 }
170 DCHECK(socket);
171
172 base::DictionaryValue* result = new base::DictionaryValue();
173 result->SetInteger(kSocketIdKey, AddSocket(socket));
174 SetResult(result);
175 }
176
177 bool SocketDestroyFunction::Prepare() {
178 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
179 return true;
180 }
181
182 void SocketDestroyFunction::Work() {
183 RemoveSocket(socket_id_);
184 }
185
186 SocketConnectFunction::SocketConnectFunction()
187 : socket_id_(0),
188 hostname_(),
189 port_(0),
190 socket_(NULL) {
191 }
192
193 SocketConnectFunction::~SocketConnectFunction() {
194 }
195
196 bool SocketConnectFunction::Prepare() {
197 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
198 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &hostname_));
199 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
200 return true;
201 }
202
203 void SocketConnectFunction::AsyncWorkStart() {
204 socket_ = GetSocket(socket_id_);
205 if (!socket_) {
206 error_ = kSocketNotFoundError;
207 SetResult(new base::FundamentalValue(-1));
208 AsyncWorkCompleted();
209 return;
210 }
211
212 SocketPermissionRequest::OperationType operation_type;
213 switch (socket_->GetSocketType()) {
214 case Socket::TYPE_TCP:
215 operation_type = SocketPermissionRequest::TCP_CONNECT;
216 break;
217 case Socket::TYPE_UDP:
218 operation_type = SocketPermissionRequest::UDP_SEND_TO;
219 break;
220 default:
221 NOTREACHED() << "Unknown socket type.";
222 operation_type = SocketPermissionRequest::NONE;
223 break;
224 }
225
226 SocketPermission::CheckParam param(operation_type, hostname_, port_);
227 if (!PermissionsData::CheckAPIPermissionWithParam(
228 GetExtension(), APIPermission::kSocket, &param)) {
229 error_ = kPermissionError;
230 SetResult(new base::FundamentalValue(-1));
231 AsyncWorkCompleted();
232 return;
233 }
234
235 StartDnsLookup(hostname_);
236 }
237
238 void SocketConnectFunction::AfterDnsLookup(int lookup_result) {
239 if (lookup_result == net::OK) {
240 StartConnect();
241 } else {
242 SetResult(new base::FundamentalValue(lookup_result));
243 AsyncWorkCompleted();
244 }
245 }
246
247 void SocketConnectFunction::StartConnect() {
248 socket_->Connect(resolved_address_, port_,
249 base::Bind(&SocketConnectFunction::OnConnect, this));
250 }
251
252 void SocketConnectFunction::OnConnect(int result) {
253 SetResult(new base::FundamentalValue(result));
254 AsyncWorkCompleted();
255 }
256
257 bool SocketDisconnectFunction::Prepare() {
258 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
259 return true;
260 }
261
262 void SocketDisconnectFunction::Work() {
263 Socket* socket = GetSocket(socket_id_);
264 if (socket)
265 socket->Disconnect();
266 else
267 error_ = kSocketNotFoundError;
268 SetResult(base::Value::CreateNullValue());
269 }
270
271 bool SocketBindFunction::Prepare() {
272 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
273 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &address_));
274 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(2, &port_));
275 return true;
276 }
277
278 void SocketBindFunction::Work() {
279 int result = -1;
280 Socket* socket = GetSocket(socket_id_);
281
282 if (!socket) {
283 error_ = kSocketNotFoundError;
284 SetResult(new base::FundamentalValue(result));
285 return;
286 }
287
288 if (socket->GetSocketType() == Socket::TYPE_UDP) {
289 SocketPermission::CheckParam param(
290 SocketPermissionRequest::UDP_BIND, address_, port_);
291 if (!PermissionsData::CheckAPIPermissionWithParam(
292 GetExtension(),
293 APIPermission::kSocket,
294 &param)) {
295 error_ = kPermissionError;
296 SetResult(new base::FundamentalValue(result));
297 return;
298 }
299 } else if (socket->GetSocketType() == Socket::TYPE_TCP) {
300 error_ = kTCPSocketBindError;
301 SetResult(new base::FundamentalValue(result));
302 return;
303 }
304
305 result = socket->Bind(address_, port_);
306 SetResult(new base::FundamentalValue(result));
307 }
308
309 SocketListenFunction::SocketListenFunction() {}
310
311 SocketListenFunction::~SocketListenFunction() {}
312
313 bool SocketListenFunction::Prepare() {
314 params_ = api::socket::Listen::Params::Create(*args_);
315 EXTENSION_FUNCTION_VALIDATE(params_.get());
316 return true;
317 }
318
319 void SocketListenFunction::Work() {
320 int result = -1;
321
322 Socket* socket = GetSocket(params_->socket_id);
323 if (socket) {
324 SocketPermission::CheckParam param(
325 SocketPermissionRequest::TCP_LISTEN, params_->address, params_->port);
326 if (!PermissionsData::CheckAPIPermissionWithParam(
327 GetExtension(),
328 APIPermission::kSocket,
329 &param)) {
330 error_ = kPermissionError;
331 SetResult(new base::FundamentalValue(result));
332 return;
333 }
334
335 result = socket->Listen(
336 params_->address,
337 params_->port,
338 params_->backlog.get() ? *params_->backlog.get() : 5,
339 &error_);
340 } else {
341 error_ = kSocketNotFoundError;
342 }
343
344 SetResult(new base::FundamentalValue(result));
345 }
346
347 SocketAcceptFunction::SocketAcceptFunction() {}
348
349 SocketAcceptFunction::~SocketAcceptFunction() {}
350
351 bool SocketAcceptFunction::Prepare() {
352 params_ = api::socket::Accept::Params::Create(*args_);
353 EXTENSION_FUNCTION_VALIDATE(params_.get());
354 return true;
355 }
356
357 void SocketAcceptFunction::AsyncWorkStart() {
358 Socket* socket = GetSocket(params_->socket_id);
359 if (socket) {
360 socket->Accept(base::Bind(&SocketAcceptFunction::OnAccept, this));
361 } else {
362 error_ = kSocketNotFoundError;
363 OnAccept(-1, NULL);
364 }
365 }
366
367 void SocketAcceptFunction::OnAccept(int result_code,
368 net::TCPClientSocket *socket) {
369 base::DictionaryValue* result = new base::DictionaryValue();
370 result->SetInteger(kResultCodeKey, result_code);
371 if (socket) {
372 Socket *client_socket = new TCPSocket(socket, extension_id(), true);
373 result->SetInteger(kSocketIdKey, AddSocket(client_socket));
374 }
375 SetResult(result);
376
377 AsyncWorkCompleted();
378 }
379
380 SocketReadFunction::SocketReadFunction() {}
381
382 SocketReadFunction::~SocketReadFunction() {}
383
384 bool SocketReadFunction::Prepare() {
385 params_ = api::socket::Read::Params::Create(*args_);
386 EXTENSION_FUNCTION_VALIDATE(params_.get());
387 return true;
388 }
389
390 void SocketReadFunction::AsyncWorkStart() {
391 Socket* socket = GetSocket(params_->socket_id);
392 if (!socket) {
393 error_ = kSocketNotFoundError;
394 OnCompleted(-1, NULL);
395 return;
396 }
397
398 socket->Read(params_->buffer_size.get() ? *params_->buffer_size.get() : 4096,
399 base::Bind(&SocketReadFunction::OnCompleted, this));
400 }
401
402 void SocketReadFunction::OnCompleted(int bytes_read,
403 scoped_refptr<net::IOBuffer> io_buffer) {
404 base::DictionaryValue* result = new base::DictionaryValue();
405 result->SetInteger(kResultCodeKey, bytes_read);
406 if (bytes_read > 0) {
407 result->Set(kDataKey,
408 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(),
409 bytes_read));
410 } else {
411 result->Set(kDataKey, new base::BinaryValue());
412 }
413 SetResult(result);
414
415 AsyncWorkCompleted();
416 }
417
418 SocketWriteFunction::SocketWriteFunction()
419 : socket_id_(0),
420 io_buffer_(NULL),
421 io_buffer_size_(0) {
422 }
423
424 SocketWriteFunction::~SocketWriteFunction() {}
425
426 bool SocketWriteFunction::Prepare() {
427 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
428 base::BinaryValue *data = NULL;
429 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data));
430
431 io_buffer_size_ = data->GetSize();
432 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer());
433 return true;
434 }
435
436 void SocketWriteFunction::AsyncWorkStart() {
437 Socket* socket = GetSocket(socket_id_);
438
439 if (!socket) {
440 error_ = kSocketNotFoundError;
441 OnCompleted(-1);
442 return;
443 }
444
445 socket->Write(io_buffer_, io_buffer_size_,
446 base::Bind(&SocketWriteFunction::OnCompleted, this));
447 }
448
449 void SocketWriteFunction::OnCompleted(int bytes_written) {
450 base::DictionaryValue* result = new base::DictionaryValue();
451 result->SetInteger(kBytesWrittenKey, bytes_written);
452 SetResult(result);
453
454 AsyncWorkCompleted();
455 }
456
457 SocketRecvFromFunction::SocketRecvFromFunction() {}
458
459 SocketRecvFromFunction::~SocketRecvFromFunction() {}
460
461 bool SocketRecvFromFunction::Prepare() {
462 params_ = api::socket::RecvFrom::Params::Create(*args_);
463 EXTENSION_FUNCTION_VALIDATE(params_.get());
464 return true;
465 }
466
467 void SocketRecvFromFunction::AsyncWorkStart() {
468 Socket* socket = GetSocket(params_->socket_id);
469 if (!socket) {
470 error_ = kSocketNotFoundError;
471 OnCompleted(-1, NULL, std::string(), 0);
472 return;
473 }
474
475 socket->RecvFrom(params_->buffer_size.get() ? *params_->buffer_size : 4096,
476 base::Bind(&SocketRecvFromFunction::OnCompleted, this));
477 }
478
479 void SocketRecvFromFunction::OnCompleted(int bytes_read,
480 scoped_refptr<net::IOBuffer> io_buffer,
481 const std::string& address,
482 int port) {
483 base::DictionaryValue* result = new base::DictionaryValue();
484 result->SetInteger(kResultCodeKey, bytes_read);
485 if (bytes_read > 0) {
486 result->Set(kDataKey,
487 base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(),
488 bytes_read));
489 } else {
490 result->Set(kDataKey, new base::BinaryValue());
491 }
492 result->SetString(kAddressKey, address);
493 result->SetInteger(kPortKey, port);
494 SetResult(result);
495
496 AsyncWorkCompleted();
497 }
498
499 SocketSendToFunction::SocketSendToFunction()
500 : socket_id_(0),
501 io_buffer_(NULL),
502 io_buffer_size_(0),
503 port_(0),
504 socket_(NULL) {
505 }
506
507 SocketSendToFunction::~SocketSendToFunction() {}
508
509 bool SocketSendToFunction::Prepare() {
510 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &socket_id_));
511 base::BinaryValue *data = NULL;
512 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data));
513 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &hostname_));
514 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(3, &port_));
515
516 io_buffer_size_ = data->GetSize();
517 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer());
518 return true;
519 }
520
521 void SocketSendToFunction::AsyncWorkStart() {
522 socket_ = GetSocket(socket_id_);
523 if (!socket_) {
524 error_ = kSocketNotFoundError;
525 SetResult(new base::FundamentalValue(-1));
526 AsyncWorkCompleted();
527 return;
528 }
529
530 if (socket_->GetSocketType() == Socket::TYPE_UDP) {
531 SocketPermission::CheckParam param(SocketPermissionRequest::UDP_SEND_TO,
532 hostname_, port_);
533 if (!PermissionsData::CheckAPIPermissionWithParam(
534 GetExtension(),
535 APIPermission::kSocket,
536 &param)) {
537 error_ = kPermissionError;
538 SetResult(new base::FundamentalValue(-1));
539 AsyncWorkCompleted();
540 return;
541 }
542 }
543
544 StartDnsLookup(hostname_);
545 }
546
547 void SocketSendToFunction::AfterDnsLookup(int lookup_result) {
548 if (lookup_result == net::OK) {
549 StartSendTo();
550 } else {
551 SetResult(new base::FundamentalValue(lookup_result));
552 AsyncWorkCompleted();
553 }
554 }
555
556 void SocketSendToFunction::StartSendTo() {
557 socket_->SendTo(io_buffer_, io_buffer_size_, resolved_address_, port_,
558 base::Bind(&SocketSendToFunction::OnCompleted, this));
559 }
560
561 void SocketSendToFunction::OnCompleted(int bytes_written) {
562 base::DictionaryValue* result = new base::DictionaryValue();
563 result->SetInteger(kBytesWrittenKey, bytes_written);
564 SetResult(result);
565
566 AsyncWorkCompleted();
567 }
568
569 SocketSetKeepAliveFunction::SocketSetKeepAliveFunction() {}
570
571 SocketSetKeepAliveFunction::~SocketSetKeepAliveFunction() {}
572
573 bool SocketSetKeepAliveFunction::Prepare() {
574 params_ = api::socket::SetKeepAlive::Params::Create(*args_);
575 EXTENSION_FUNCTION_VALIDATE(params_.get());
576 return true;
577 }
578
579 void SocketSetKeepAliveFunction::Work() {
580 bool result = false;
581 Socket* socket = GetSocket(params_->socket_id);
582 if (socket) {
583 int delay = 0;
584 if (params_->delay.get())
585 delay = *params_->delay;
586 result = socket->SetKeepAlive(params_->enable, delay);
587 } else {
588 error_ = kSocketNotFoundError;
589 }
590 SetResult(new base::FundamentalValue(result));
591 }
592
593 SocketSetNoDelayFunction::SocketSetNoDelayFunction() {}
594
595 SocketSetNoDelayFunction::~SocketSetNoDelayFunction() {}
596
597 bool SocketSetNoDelayFunction::Prepare() {
598 params_ = api::socket::SetNoDelay::Params::Create(*args_);
599 EXTENSION_FUNCTION_VALIDATE(params_.get());
600 return true;
601 }
602
603 void SocketSetNoDelayFunction::Work() {
604 bool result = false;
605 Socket* socket = GetSocket(params_->socket_id);
606 if (socket)
607 result = socket->SetNoDelay(params_->no_delay);
608 else
609 error_ = kSocketNotFoundError;
610 SetResult(new base::FundamentalValue(result));
611 }
612
613 SocketGetInfoFunction::SocketGetInfoFunction() {}
614
615 SocketGetInfoFunction::~SocketGetInfoFunction() {}
616
617 bool SocketGetInfoFunction::Prepare() {
618 params_ = api::socket::GetInfo::Params::Create(*args_);
619 EXTENSION_FUNCTION_VALIDATE(params_.get());
620 return true;
621 }
622
623 void SocketGetInfoFunction::Work() {
624 Socket* socket = GetSocket(params_->socket_id);
625 if (!socket) {
626 error_ = kSocketNotFoundError;
627 return;
628 }
629
630 api::socket::SocketInfo info;
631 // This represents what we know about the socket, and does not call through
632 // to the system.
633 if (socket->GetSocketType() == Socket::TYPE_TCP)
634 info.socket_type = extensions::api::socket::SOCKET_TYPE_TCP;
635 else
636 info.socket_type = extensions::api::socket::SOCKET_TYPE_UDP;
637 info.connected = socket->IsConnected();
638
639 // Grab the peer address as known by the OS. This and the call below will
640 // always succeed while the socket is connected, even if the socket has
641 // been remotely closed by the peer; only reading the socket will reveal
642 // that it should be closed locally.
643 net::IPEndPoint peerAddress;
644 if (socket->GetPeerAddress(&peerAddress)) {
645 info.peer_address.reset(
646 new std::string(peerAddress.ToStringWithoutPort()));
647 info.peer_port.reset(new int(peerAddress.port()));
648 }
649
650 // Grab the local address as known by the OS.
651 net::IPEndPoint localAddress;
652 if (socket->GetLocalAddress(&localAddress)) {
653 info.local_address.reset(
654 new std::string(localAddress.ToStringWithoutPort()));
655 info.local_port.reset(new int(localAddress.port()));
656 }
657
658 SetResult(info.ToValue().release());
659 }
660
661 bool SocketGetNetworkListFunction::RunImpl() {
662 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
663 base::Bind(&SocketGetNetworkListFunction::GetNetworkListOnFileThread,
664 this));
665 return true;
666 }
667
668 void SocketGetNetworkListFunction::GetNetworkListOnFileThread() {
669 net::NetworkInterfaceList interface_list;
670 if (GetNetworkList(&interface_list,
671 net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)) {
672 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
673 base::Bind(&SocketGetNetworkListFunction::SendResponseOnUIThread,
674 this, interface_list));
675 return;
676 }
677
678 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
679 base::Bind(&SocketGetNetworkListFunction::HandleGetNetworkListError,
680 this));
681 }
682
683 void SocketGetNetworkListFunction::HandleGetNetworkListError() {
684 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
685 error_ = kNetworkListError;
686 SendResponse(false);
687 }
688
689 void SocketGetNetworkListFunction::SendResponseOnUIThread(
690 const net::NetworkInterfaceList& interface_list) {
691 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
692
693 std::vector<linked_ptr<api::socket::NetworkInterface> > create_arg;
694 create_arg.reserve(interface_list.size());
695 for (net::NetworkInterfaceList::const_iterator i = interface_list.begin();
696 i != interface_list.end(); ++i) {
697 linked_ptr<api::socket::NetworkInterface> info =
698 make_linked_ptr(new api::socket::NetworkInterface);
699 info->name = i->name;
700 info->address = net::IPAddressToString(i->address);
701 info->prefix_length = i->network_prefix;
702 create_arg.push_back(info);
703 }
704
705 results_ = api::socket::GetNetworkList::Results::Create(create_arg);
706 SendResponse(true);
707 }
708
709 SocketJoinGroupFunction::SocketJoinGroupFunction() {}
710
711 SocketJoinGroupFunction::~SocketJoinGroupFunction() {}
712
713 bool SocketJoinGroupFunction::Prepare() {
714 params_ = api::socket::JoinGroup::Params::Create(*args_);
715 EXTENSION_FUNCTION_VALIDATE(params_.get());
716 return true;
717 }
718
719 void SocketJoinGroupFunction::Work() {
720 int result = -1;
721 Socket* socket = GetSocket(params_->socket_id);
722 if (!socket) {
723 error_ = kSocketNotFoundError;
724 SetResult(new base::FundamentalValue(result));
725 return;
726 }
727
728 if (socket->GetSocketType() != Socket::TYPE_UDP) {
729 error_ = kMulticastSocketTypeError;
730 SetResult(new base::FundamentalValue(result));
731 return;
732 }
733
734 SocketPermission::CheckParam param(
735 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
736 kWildcardAddress,
737 kWildcardPort);
738
739 if (!PermissionsData::CheckAPIPermissionWithParam(
740 GetExtension(), APIPermission::kSocket, &param)) {
741 error_ = kPermissionError;
742 SetResult(new base::FundamentalValue(result));
743 return;
744 }
745
746 result = static_cast<UDPSocket*>(socket)->JoinGroup(params_->address);
747 if (result != 0) {
748 error_ = net::ErrorToString(result);
749 }
750 SetResult(new base::FundamentalValue(result));
751 }
752
753 SocketLeaveGroupFunction::SocketLeaveGroupFunction() {}
754
755 SocketLeaveGroupFunction::~SocketLeaveGroupFunction() {}
756
757 bool SocketLeaveGroupFunction::Prepare() {
758 params_ = api::socket::LeaveGroup::Params::Create(*args_);
759 EXTENSION_FUNCTION_VALIDATE(params_.get());
760 return true;
761 }
762
763 void SocketLeaveGroupFunction::Work() {
764 int result = -1;
765 Socket* socket = GetSocket(params_->socket_id);
766
767 if (!socket) {
768 error_ = kSocketNotFoundError;
769 SetResult(new base::FundamentalValue(result));
770 return;
771 }
772
773 if (socket->GetSocketType() != Socket::TYPE_UDP) {
774 error_ = kMulticastSocketTypeError;
775 SetResult(new base::FundamentalValue(result));
776 return;
777 }
778
779 SocketPermission::CheckParam param(
780 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
781 kWildcardAddress,
782 kWildcardPort);
783 if (!PermissionsData::CheckAPIPermissionWithParam(GetExtension(),
784 APIPermission::kSocket,
785 &param)) {
786 error_ = kPermissionError;
787 SetResult(new base::FundamentalValue(result));
788 return;
789 }
790
791 result = static_cast<UDPSocket*>(socket)->LeaveGroup(params_->address);
792 if (result != 0)
793 error_ = net::ErrorToString(result);
794 SetResult(new base::FundamentalValue(result));
795 }
796
797 SocketSetMulticastTimeToLiveFunction::SocketSetMulticastTimeToLiveFunction() {}
798
799 SocketSetMulticastTimeToLiveFunction::~SocketSetMulticastTimeToLiveFunction() {}
800
801 bool SocketSetMulticastTimeToLiveFunction::Prepare() {
802 params_ = api::socket::SetMulticastTimeToLive::Params::Create(*args_);
803 EXTENSION_FUNCTION_VALIDATE(params_.get());
804 return true;
805 }
806 void SocketSetMulticastTimeToLiveFunction::Work() {
807 int result = -1;
808 Socket* socket = GetSocket(params_->socket_id);
809 if (!socket) {
810 error_ = kSocketNotFoundError;
811 SetResult(new base::FundamentalValue(result));
812 return;
813 }
814
815 if (socket->GetSocketType() != Socket::TYPE_UDP) {
816 error_ = kMulticastSocketTypeError;
817 SetResult(new base::FundamentalValue(result));
818 return;
819 }
820
821 result = static_cast<UDPSocket*>(socket)->SetMulticastTimeToLive(
822 params_->ttl);
823 if (result != 0)
824 error_ = net::ErrorToString(result);
825 SetResult(new base::FundamentalValue(result));
826 }
827
828 SocketSetMulticastLoopbackModeFunction::
829 SocketSetMulticastLoopbackModeFunction() {}
830
831 SocketSetMulticastLoopbackModeFunction::
832 ~SocketSetMulticastLoopbackModeFunction() {}
833
834 bool SocketSetMulticastLoopbackModeFunction::Prepare() {
835 params_ = api::socket::SetMulticastLoopbackMode::Params::Create(*args_);
836 EXTENSION_FUNCTION_VALIDATE(params_.get());
837 return true;
838 }
839
840 void SocketSetMulticastLoopbackModeFunction::Work() {
841 int result = -1;
842 Socket* socket = GetSocket(params_->socket_id);
843 if (!socket) {
844 error_ = kSocketNotFoundError;
845 SetResult(new base::FundamentalValue(result));
846 return;
847 }
848
849 if (socket->GetSocketType() != Socket::TYPE_UDP) {
850 error_ = kMulticastSocketTypeError;
851 SetResult(new base::FundamentalValue(result));
852 return;
853 }
854
855 result = static_cast<UDPSocket*>(socket)->
856 SetMulticastLoopbackMode(params_->enabled);
857 if (result != 0)
858 error_ = net::ErrorToString(result);
859 SetResult(new base::FundamentalValue(result));
860 }
861
862 SocketGetJoinedGroupsFunction::SocketGetJoinedGroupsFunction() {}
863
864 SocketGetJoinedGroupsFunction::~SocketGetJoinedGroupsFunction() {}
865
866 bool SocketGetJoinedGroupsFunction::Prepare() {
867 params_ = api::socket::GetJoinedGroups::Params::Create(*args_);
868 EXTENSION_FUNCTION_VALIDATE(params_.get());
869 return true;
870 }
871
872 void SocketGetJoinedGroupsFunction::Work() {
873 int result = -1;
874 Socket* socket = GetSocket(params_->socket_id);
875 if (!socket) {
876 error_ = kSocketNotFoundError;
877 SetResult(new base::FundamentalValue(result));
878 return;
879 }
880
881 if (socket->GetSocketType() != Socket::TYPE_UDP) {
882 error_ = kMulticastSocketTypeError;
883 SetResult(new base::FundamentalValue(result));
884 return;
885 }
886
887 SocketPermission::CheckParam param(
888 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP,
889 kWildcardAddress,
890 kWildcardPort);
891 if (!PermissionsData::CheckAPIPermissionWithParam(
892 GetExtension(),
893 APIPermission::kSocket,
894 &param)) {
895 error_ = kPermissionError;
896 SetResult(new base::FundamentalValue(result));
897 return;
898 }
899
900 base::ListValue* values = new base::ListValue();
901 values->AppendStrings((std::vector<std::string>&)
902 static_cast<UDPSocket*>(socket)->GetJoinedGroups());
903 SetResult(values);
904 }
905
906 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/socket/socket_api.h ('k') | chrome/browser/extensions/api/socket/socket_api_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698