1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h"
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/common/socket_permission_request.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/socket/tcp_socket.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h"
104ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#include "extensions/common/api/sockets/sockets_manifest_data.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/permissions/socket_permission.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/base/net_errors.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using content::SocketPermissionRequest;
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using extensions::ResumableTCPServerSocket;
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using extensions::core_api::sockets_tcp_server::SocketInfo;
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using extensions::core_api::sockets_tcp_server::SocketProperties;
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace {
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kSocketNotFoundError[] = "Socket not found";
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kPermissionError[] = "Does not have permission";
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const int kDefaultListenBacklog = SOMAXCONN;
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)linked_ptr<SocketInfo> CreateSocketInfo(int socket_id,
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                        ResumableTCPServerSocket* socket) {
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  linked_ptr<SocketInfo> socket_info(new SocketInfo());
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // This represents what we know about the socket, and does not call through
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // to the system.
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  socket_info->socket_id = socket_id;
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!socket->name().empty()) {
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    socket_info->name.reset(new std::string(socket->name()));
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  socket_info->persistent = socket->persistent();
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  socket_info->paused = socket->paused();
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Grab the local address as known by the OS.
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  net::IPEndPoint localAddress;
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (socket->GetLocalAddress(&localAddress)) {
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    socket_info->local_address.reset(
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new std::string(localAddress.ToStringWithoutPort()));
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    socket_info->local_port.reset(new int(localAddress.port()));
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return socket_info;
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SetSocketProperties(ResumableTCPServerSocket* socket,
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                         SocketProperties* properties) {
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (properties->name.get()) {
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    socket->set_name(*properties->name.get());
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (properties->persistent.get()) {
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    socket->set_persistent(*properties->persistent.get());
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace extensions {
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace core_api {
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TCPServerSocketAsyncApiFunction::~TCPServerSocketAsyncApiFunction() {}
658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)scoped_ptr<SocketResourceManagerInterface>
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TCPServerSocketAsyncApiFunction::CreateSocketResourceManager() {
688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return scoped_ptr<SocketResourceManagerInterface>(
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             new SocketResourceManager<ResumableTCPServerSocket>()).Pass();
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ResumableTCPServerSocket* TCPServerSocketAsyncApiFunction::GetTcpSocket(
738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int socket_id) {
748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return static_cast<ResumableTCPServerSocket*>(GetSocket(socket_id));
758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerCreateFunction::SocketsTcpServerCreateFunction() {}
788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerCreateFunction::~SocketsTcpServerCreateFunction() {}
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SocketsTcpServerCreateFunction::Prepare() {
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  params_ = sockets_tcp_server::Create::Params::Create(*args_);
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params_.get());
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SocketsTcpServerCreateFunction::Work() {
888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ResumableTCPServerSocket* socket =
898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new ResumableTCPServerSocket(extension_->id());
908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  sockets_tcp_server::SocketProperties* properties =
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      params_.get()->properties.get();
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (properties) {
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    SetSocketProperties(socket, properties);
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  sockets_tcp_server::CreateInfo create_info;
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  create_info.socket_id = AddSocket(socket);
998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_ = sockets_tcp_server::Create::Results::Create(create_info);
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerUpdateFunction::SocketsTcpServerUpdateFunction() {}
1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerUpdateFunction::~SocketsTcpServerUpdateFunction() {}
1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SocketsTcpServerUpdateFunction::Prepare() {
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  params_ = sockets_tcp_server::Update::Params::Create(*args_);
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params_.get());
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SocketsTcpServerUpdateFunction::Work() {
1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!socket) {
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    error_ = kSocketNotFoundError;
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SetSocketProperties(socket, &params_.get()->properties);
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_ = sockets_tcp_server::Update::Results::Create();
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerSetPausedFunction::SocketsTcpServerSetPausedFunction()
1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : socket_event_dispatcher_(NULL) {}
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerSetPausedFunction::~SocketsTcpServerSetPausedFunction() {}
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SocketsTcpServerSetPausedFunction::Prepare() {
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  params_ = core_api::sockets_tcp_server::SetPaused::Params::Create(*args_);
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params_.get());
1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_event_dispatcher_ =
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      TCPServerSocketEventDispatcher::Get(browser_context());
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(socket_event_dispatcher_)
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "There is no socket event dispatcher. "
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         "If this assertion is failing during a test, then it is likely that "
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         "TestExtensionSystem is failing to provide an instance of "
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         "TCPServerSocketEventDispatcher.";
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return socket_event_dispatcher_ != NULL;
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SocketsTcpServerSetPausedFunction::Work() {
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!socket) {
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    error_ = kSocketNotFoundError;
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (socket->paused() != params_->paused) {
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    socket->set_paused(params_->paused);
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (socket->IsConnected() && !params_->paused) {
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      socket_event_dispatcher_->OnServerSocketResume(extension_->id(),
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                     params_->socket_id);
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_ = sockets_tcp_server::SetPaused::Results::Create();
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerListenFunction::SocketsTcpServerListenFunction()
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : socket_event_dispatcher_(NULL) {}
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerListenFunction::~SocketsTcpServerListenFunction() {}
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SocketsTcpServerListenFunction::Prepare() {
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  params_ = core_api::sockets_tcp_server::Listen::Params::Create(*args_);
1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params_.get());
1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  socket_event_dispatcher_ =
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      TCPServerSocketEventDispatcher::Get(browser_context());
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(socket_event_dispatcher_)
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      << "There is no socket event dispatcher. "
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         "If this assertion is failing during a test, then it is likely that "
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         "TestExtensionSystem is failing to provide an instance of "
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         "TCPServerSocketEventDispatcher.";
1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return socket_event_dispatcher_ != NULL;
1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SocketsTcpServerListenFunction::Work() {
1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!socket) {
1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    error_ = kSocketNotFoundError;
1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  SocketPermissionRequest param(
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      SocketPermissionRequest::TCP_LISTEN, params_->address, params_->port);
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!SocketsManifestData::CheckRequest(extension(), param)) {
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    error_ = kPermissionError;
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int net_result = socket->Listen(
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      params_->address,
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      params_->port,
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      params_->backlog.get() ? *params_->backlog.get() : kDefaultListenBacklog,
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      &error_);
1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (net_result != net::OK)
2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    error_ = net::ErrorToString(net_result);
2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (net_result == net::OK) {
2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    socket_event_dispatcher_->OnServerSocketListen(extension_->id(),
2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                   params_->socket_id);
2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_ = sockets_tcp_server::Listen::Results::Create(net_result);
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerDisconnectFunction::SocketsTcpServerDisconnectFunction() {}
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerDisconnectFunction::~SocketsTcpServerDisconnectFunction() {}
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SocketsTcpServerDisconnectFunction::Prepare() {
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  params_ = sockets_tcp_server::Disconnect::Params::Create(*args_);
2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params_.get());
2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SocketsTcpServerDisconnectFunction::Work() {
2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!socket) {
2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    error_ = kSocketNotFoundError;
2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  socket->Disconnect();
2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_ = sockets_tcp_server::Disconnect::Results::Create();
2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {}
2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerCloseFunction::~SocketsTcpServerCloseFunction() {}
2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SocketsTcpServerCloseFunction::Prepare() {
2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  params_ = sockets_tcp_server::Close::Params::Create(*args_);
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params_.get());
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SocketsTcpServerCloseFunction::Work() {
2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!socket) {
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    error_ = kSocketNotFoundError;
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  RemoveSocket(params_->socket_id);
2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_ = sockets_tcp_server::Close::Results::Create();
2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {}
2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerGetInfoFunction::~SocketsTcpServerGetInfoFunction() {}
2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SocketsTcpServerGetInfoFunction::Prepare() {
2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  params_ = sockets_tcp_server::GetInfo::Params::Create(*args_);
2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params_.get());
2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SocketsTcpServerGetInfoFunction::Work() {
2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!socket) {
2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    error_ = kSocketNotFoundError;
2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  linked_ptr<sockets_tcp_server::SocketInfo> socket_info =
2708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      CreateSocketInfo(params_->socket_id, socket);
2718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_ = sockets_tcp_server::GetInfo::Results::Create(*socket_info);
2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {}
2758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SocketsTcpServerGetSocketsFunction::~SocketsTcpServerGetSocketsFunction() {}
2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool SocketsTcpServerGetSocketsFunction::Prepare() { return true; }
2798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SocketsTcpServerGetSocketsFunction::Work() {
2818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<linked_ptr<sockets_tcp_server::SocketInfo> > socket_infos;
2828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::hash_set<int>* resource_ids = GetSocketIds();
2838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (resource_ids != NULL) {
2848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    for (base::hash_set<int>::iterator it = resource_ids->begin();
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         it != resource_ids->end();
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         ++it) {
2878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      int socket_id = *it;
2888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ResumableTCPServerSocket* socket = GetTcpSocket(socket_id);
2898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      if (socket) {
2908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        socket_infos.push_back(CreateSocketInfo(socket_id, socket));
2918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      }
2928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
2938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  results_ = sockets_tcp_server::GetSockets::Results::Create(socket_infos);
2958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace core_api
2988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace extensions
299