summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/ui/ppapi_uitest.cc2
-rw-r--r--content/browser/renderer_host/pepper_message_filter.cc109
-rw-r--r--content/browser/renderer_host/pepper_message_filter.h28
-rw-r--r--content/browser/renderer_host/pepper_tcp_server_socket.cc160
-rw-r--r--content/browser/renderer_host/pepper_tcp_server_socket.h63
-rw-r--r--content/browser/renderer_host/pepper_tcp_socket.cc18
-rw-r--r--content/browser/renderer_host/pepper_tcp_socket.h8
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.cc98
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.h25
-rw-r--r--ppapi/api/private/ppb_tcp_server_socket_private.idl61
-rw-r--r--ppapi/c/private/ppb_tcp_server_socket_private.h87
-rw-r--r--ppapi/ppapi_shared.gypi5
-rw-r--r--ppapi/ppapi_sources.gypi2
-rw-r--r--ppapi/proxy/ppapi_messages.h36
-rw-r--r--ppapi/proxy/resource_creation_proxy.cc6
-rw-r--r--ppapi/proxy/resource_creation_proxy.h2
-rw-r--r--ppapi/shared_impl/private/ppb_tcp_server_socket_shared.cc113
-rw-r--r--ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h84
-rw-r--r--ppapi/shared_impl/resource.h1
-rw-r--r--ppapi/tests/test_tcp_server_socket_private.cc399
-rw-r--r--ppapi/tests/test_tcp_server_socket_private.h56
-rw-r--r--ppapi/thunk/ppb_tcp_server_socket_private_api.h29
-rw-r--r--ppapi/thunk/ppb_tcp_server_socket_private_thunk.cc71
-rw-r--r--ppapi/thunk/resource_creation_api.h1
-rw-r--r--ppapi/thunk/thunk.h3
-rw-r--r--webkit/glue/webkit_glue.gypi2
-rw-r--r--webkit/plugins/ppapi/mock_plugin_delegate.cc18
-rw-r--r--webkit/plugins/ppapi/mock_plugin_delegate.h9
-rw-r--r--webkit/plugins/ppapi/plugin_delegate.h12
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc3
-rw-r--r--webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.cc86
-rw-r--r--webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.h41
-rw-r--r--webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc36
-rw-r--r--webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h11
-rw-r--r--webkit/plugins/ppapi/resource_creation_impl.cc6
-rw-r--r--webkit/plugins/ppapi/resource_creation_impl.h3
37 files changed, 1680 insertions, 16 deletions
diff --git a/chrome/test/ui/ppapi_uitest.cc b/chrome/test/ui/ppapi_uitest.cc
index 5e17212..6fb6dbd 100644
--- a/chrome/test/ui/ppapi_uitest.cc
+++ b/chrome/test/ui/ppapi_uitest.cc
@@ -401,6 +401,8 @@ TEST_PPAPI_NACL_VIA_HTTP(UDPSocketPrivateShared)
TEST_PPAPI_NACL_VIA_HTTP_DISALLOWED_SOCKETS(TCPSocketPrivateDisallowed)
TEST_PPAPI_NACL_VIA_HTTP_DISALLOWED_SOCKETS(UDPSocketPrivateDisallowed)
+TEST_PPAPI_IN_PROCESS_VIA_HTTP(TCPServerSocketPrivate)
+
// URLLoader tests.
TEST_PPAPI_IN_PROCESS_VIA_HTTP(URLLoader_BasicGET)
TEST_PPAPI_IN_PROCESS_VIA_HTTP(URLLoader_BasicPOST)
diff --git a/content/browser/renderer_host/pepper_message_filter.cc b/content/browser/renderer_host/pepper_message_filter.cc
index b1a04c6..21327c6 100644
--- a/content/browser/renderer_host/pepper_message_filter.cc
+++ b/content/browser/renderer_host/pepper_message_filter.cc
@@ -9,10 +9,12 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/process_util.h"
#include "base/threading/worker_pool.h"
#include "base/values.h"
#include "content/browser/font_list_async.h"
+#include "content/browser/renderer_host/pepper_tcp_server_socket.h"
#include "content/browser/renderer_host/pepper_tcp_socket.h"
#include "content/browser/renderer_host/pepper_udp_socket.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
@@ -29,6 +31,7 @@
#include "net/base/host_resolver.h"
#include "net/base/net_errors.h"
#include "net/base/single_request_host_resolver.h"
+#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_flash_net_connector.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/private/net_address_private_impl.h"
@@ -83,7 +86,8 @@ void PepperMessageFilter::OverrideThreadForMessage(
BrowserThread::ID* thread) {
if (message.type() == PpapiHostMsg_PPBTCPSocket_Connect::ID ||
message.type() == PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress::ID ||
- message.type() == PpapiHostMsg_PPBUDPSocket_Bind::ID) {
+ message.type() == PpapiHostMsg_PPBUDPSocket_Bind::ID ||
+ message.type() == PpapiHostMsg_PPBTCPServerSocket_Listen::ID) {
*thread = BrowserThread::UI;
}
}
@@ -118,6 +122,14 @@ bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg,
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBUDPSocket_SendTo, OnUDPSendTo)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBUDPSocket_Close, OnUDPClose)
+ // TCP Server messages.
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPServerSocket_Listen,
+ OnTCPServerListen)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPServerSocket_Accept,
+ OnTCPServerAccept)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPServerSocket_Destroy,
+ RemoveTCPServerSocket)
+
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
return handled;
@@ -135,6 +147,37 @@ net::CertVerifier* PepperMessageFilter::GetCertVerifier() {
return cert_verifier_.get();
}
+uint32 PepperMessageFilter::AddAcceptedTCPSocket(
+ int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ net::StreamSocket* socket) {
+ scoped_ptr<net::StreamSocket> s(socket);
+
+ uint32 tcp_socket_id = GenerateSocketID();
+ if (tcp_socket_id != kInvalidSocketID) {
+ tcp_sockets_[tcp_socket_id] = linked_ptr<PepperTCPSocket>(
+ new PepperTCPSocket(this,
+ routing_id,
+ plugin_dispatcher_id,
+ tcp_socket_id,
+ s.release()));
+ }
+ return tcp_socket_id;
+}
+
+void PepperMessageFilter::RemoveTCPServerSocket(uint32 real_socket_id) {
+ TCPServerSocketMap::iterator iter = tcp_server_sockets_.find(real_socket_id);
+ if (iter == tcp_server_sockets_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ // Destroy the TCPServerSocket instance will cancel any pending completion
+ // callback. From this point on, there won't be any messages associated with
+ // this socket sent to the plugin side.
+ tcp_server_sockets_.erase(iter);
+}
+
#if defined(ENABLE_FLAPPER_HACKS)
namespace {
@@ -546,6 +589,63 @@ void PepperMessageFilter::OnUDPClose(uint32 socket_id) {
udp_sockets_.erase(iter);
}
+void PepperMessageFilter::OnTCPServerListen(int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&PepperMessageFilter::DoTCPServerListen,
+ this,
+ CanUseSocketAPIs(routing_id),
+ routing_id,
+ plugin_dispatcher_id,
+ temp_socket_id,
+ addr,
+ backlog));
+}
+
+void PepperMessageFilter::DoTCPServerListen(bool allowed,
+ int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (!allowed) {
+ Send(new PpapiMsg_PPBTCPServerSocket_ListenACK(routing_id,
+ plugin_dispatcher_id,
+ 0,
+ temp_socket_id,
+ PP_ERROR_FAILED));
+ return;
+ }
+ uint32 real_socket_id = GenerateSocketID();
+ if (real_socket_id == kInvalidSocketID) {
+ Send(new PpapiMsg_PPBTCPServerSocket_ListenACK(routing_id,
+ plugin_dispatcher_id,
+ real_socket_id,
+ temp_socket_id,
+ PP_ERROR_NOSPACE));
+ return;
+ }
+ PepperTCPServerSocket* socket = new PepperTCPServerSocket(
+ this, routing_id, plugin_dispatcher_id, real_socket_id, temp_socket_id);
+ tcp_server_sockets_[real_socket_id] =
+ linked_ptr<PepperTCPServerSocket>(socket);
+ socket->Listen(addr, backlog);
+}
+
+void PepperMessageFilter::OnTCPServerAccept(uint32 real_socket_id) {
+ TCPServerSocketMap::iterator iter = tcp_server_sockets_.find(real_socket_id);
+ if (iter == tcp_server_sockets_.end()) {
+ NOTREACHED();
+ return;
+ }
+ iter->second->Accept();
+}
+
void PepperMessageFilter::GetFontFamiliesComplete(
IPC::Message* reply_msg,
scoped_refptr<content::FontListResult> result) {
@@ -584,8 +684,10 @@ uint32 PepperMessageFilter::GenerateSocketID() {
// PepperSocketMessageHandler object, because for each plugin or renderer
// process, there is at most one PepperMessageFilter (in other words, at most
// one PepperSocketMessageHandler) talking to it.
- if (tcp_sockets_.size() + udp_sockets_.size() >= kMaxSocketsAllowed)
+ if (tcp_sockets_.size() + udp_sockets_.size() + tcp_server_sockets_.size() >=
+ kMaxSocketsAllowed) {
return kInvalidSocketID;
+ }
uint32 socket_id = kInvalidSocketID;
do {
@@ -594,7 +696,8 @@ uint32 PepperMessageFilter::GenerateSocketID() {
socket_id = next_socket_id_++;
} while (socket_id == kInvalidSocketID ||
tcp_sockets_.find(socket_id) != tcp_sockets_.end() ||
- udp_sockets_.find(socket_id) != udp_sockets_.end());
+ udp_sockets_.find(socket_id) != udp_sockets_.end() ||
+ tcp_server_sockets_.find(socket_id) != tcp_server_sockets_.end());
return socket_id;
}
diff --git a/content/browser/renderer_host/pepper_message_filter.h b/content/browser/renderer_host/pepper_message_filter.h
index 203491d..a5f5dec 100644
--- a/content/browser/renderer_host/pepper_message_filter.h
+++ b/content/browser/renderer_host/pepper_message_filter.h
@@ -17,8 +17,10 @@
#include "content/browser/font_list_async.h"
#include "content/public/browser/browser_message_filter.h"
#include "net/base/ssl_config_service.h"
+#include "net/socket/stream_socket.h"
#include "ppapi/c/pp_stdint.h"
+class PepperTCPServerSocket;
class PepperTCPSocket;
class PepperUDPSocket;
struct PP_NetAddress_Private;
@@ -68,6 +70,15 @@ class PepperMessageFilter : public content::BrowserMessageFilter {
net::CertVerifier* GetCertVerifier();
+ // Adds already accepted socket to the internal TCP sockets table. Takes
+ // ownership over |socket|. In the case of failure (full socket table)
+ // returns 0 and deletes |socket|. Otherwise, returns generated ID for
+ // |socket|.
+ uint32 AddAcceptedTCPSocket(int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ net::StreamSocket* socket);
+ void RemoveTCPServerSocket(uint32 real_socket_id);
+
const net::SSLConfig& ssl_config() { return ssl_config_; }
private:
@@ -135,6 +146,13 @@ class PepperMessageFilter : public content::BrowserMessageFilter {
const PP_NetAddress_Private& addr);
void OnUDPClose(uint32 socket_id);
+ void OnTCPServerListen(int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog);
+ void OnTCPServerAccept(uint32 real_socket_id);
+
void DoTCPConnect(bool allowed,
int32 routing_id,
uint32 socket_id,
@@ -148,6 +166,12 @@ class PepperMessageFilter : public content::BrowserMessageFilter {
int32 routing_id,
uint32 socket_id,
const PP_NetAddress_Private& addr);
+ void DoTCPServerListen(bool allowed,
+ int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog);
// Callback when the font list has been retrieved on a background thread.
void GetFontFamiliesComplete(IPC::Message* reply_msg,
@@ -184,6 +208,10 @@ class PepperMessageFilter : public content::BrowserMessageFilter {
typedef std::map<uint32, linked_ptr<PepperUDPSocket> > UDPSocketMap;
UDPSocketMap udp_sockets_;
+ typedef std::map<uint32,
+ linked_ptr<PepperTCPServerSocket> > TCPServerSocketMap;
+ TCPServerSocketMap tcp_server_sockets_;
+
DISALLOW_COPY_AND_ASSIGN(PepperMessageFilter);
};
diff --git a/content/browser/renderer_host/pepper_tcp_server_socket.cc b/content/browser/renderer_host/pepper_tcp_server_socket.cc
new file mode 100644
index 0000000..b108d0f
--- /dev/null
+++ b/content/browser/renderer_host/pepper_tcp_server_socket.cc
@@ -0,0 +1,160 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/pepper_tcp_server_socket.h"
+
+#include <cstddef>
+
+#include "base/logging.h"
+#include "content/browser/renderer_host/pepper_message_filter.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/socket/tcp_client_socket.h"
+#include "net/socket/tcp_server_socket.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/private/net_address_private_impl.h"
+
+using content::BrowserThread;
+using ppapi::NetAddressPrivateImpl;
+
+PepperTCPServerSocket::PepperTCPServerSocket(
+ PepperMessageFilter* manager,
+ int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32 real_socket_id,
+ uint32 temp_socket_id)
+ : manager_(manager),
+ routing_id_(routing_id),
+ plugin_dispatcher_id_(plugin_dispatcher_id),
+ real_socket_id_(real_socket_id),
+ temp_socket_id_(temp_socket_id),
+ state_(BEFORE_LISTENING) {
+ DCHECK(manager);
+}
+
+PepperTCPServerSocket::~PepperTCPServerSocket() {
+}
+
+void PepperTCPServerSocket::Listen(const PP_NetAddress_Private& addr,
+ int32 backlog) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ net::IPEndPoint ip_end_point;
+ if (state_ != BEFORE_LISTENING ||
+ !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &ip_end_point)) {
+ CancelListenRequest();
+ return;
+ }
+
+ state_ = LISTEN_IN_PROGRESS;
+
+ socket_.reset(new net::TCPServerSocket(NULL, net::NetLog::Source()));
+ int result = socket_->Listen(ip_end_point, backlog);
+ if (result != net::ERR_IO_PENDING)
+ OnListenCompleted(result);
+}
+
+void PepperTCPServerSocket::Accept() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ if (state_ != LISTENING) {
+ SendAcceptACKError();
+ return;
+ }
+
+ state_ = ACCEPT_IN_PROGRESS;
+
+ int result = socket_->Accept(
+ &socket_buffer_,
+ base::Bind(&PepperTCPServerSocket::OnAcceptCompleted,
+ base::Unretained(this)));
+ if (result != net::ERR_IO_PENDING)
+ OnAcceptCompleted(result);
+}
+
+void PepperTCPServerSocket::CancelListenRequest() {
+ manager_->Send(new PpapiMsg_PPBTCPServerSocket_ListenACK(
+ routing_id_,
+ plugin_dispatcher_id_,
+ 0,
+ temp_socket_id_,
+ PP_ERROR_FAILED));
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&PepperMessageFilter::RemoveTCPServerSocket, manager_,
+ real_socket_id_));
+}
+
+void PepperTCPServerSocket::SendAcceptACKError() {
+ manager_->Send(new PpapiMsg_PPBTCPServerSocket_AcceptACK(
+ routing_id_,
+ plugin_dispatcher_id_,
+ real_socket_id_,
+ 0,
+ NetAddressPrivateImpl::kInvalidNetAddress,
+ NetAddressPrivateImpl::kInvalidNetAddress));
+}
+
+void PepperTCPServerSocket::OnListenCompleted(int result) {
+ DCHECK(state_ == LISTEN_IN_PROGRESS && socket_.get());
+
+ if (result != net::OK) {
+ CancelListenRequest();
+ } else {
+ manager_->Send(new PpapiMsg_PPBTCPServerSocket_ListenACK(
+ routing_id_,
+ plugin_dispatcher_id_,
+ real_socket_id_,
+ temp_socket_id_,
+ PP_OK));
+ state_ = LISTENING;
+ }
+}
+
+void PepperTCPServerSocket::OnAcceptCompleted(int result) {
+ DCHECK(state_ == ACCEPT_IN_PROGRESS && socket_buffer_.get());
+
+ if (result != net::OK) {
+ SendAcceptACKError();
+ } else {
+ scoped_ptr<net::StreamSocket> socket(socket_buffer_.release());
+
+ net::IPEndPoint ip_end_point;
+ net::AddressList address_list;
+ PP_NetAddress_Private local_addr =
+ NetAddressPrivateImpl::kInvalidNetAddress;
+ PP_NetAddress_Private remote_addr =
+ NetAddressPrivateImpl::kInvalidNetAddress;
+
+ if (socket->GetLocalAddress(&ip_end_point) != net::OK ||
+ !NetAddressPrivateImpl::IPEndPointToNetAddress(ip_end_point,
+ &local_addr) ||
+ socket->GetPeerAddress(&address_list) != net::OK ||
+ !NetAddressPrivateImpl::AddressListToNetAddress(address_list,
+ &remote_addr)) {
+ SendAcceptACKError();
+ } else {
+ uint32 accepted_socket_id =
+ manager_->AddAcceptedTCPSocket(routing_id_,
+ plugin_dispatcher_id_,
+ socket.release());
+ if (accepted_socket_id != 0) {
+ manager_->Send(new PpapiMsg_PPBTCPServerSocket_AcceptACK(
+ routing_id_,
+ plugin_dispatcher_id_,
+ real_socket_id_,
+ accepted_socket_id,
+ local_addr,
+ remote_addr));
+ } else {
+ SendAcceptACKError();
+ }
+ }
+ }
+
+ state_ = LISTENING;
+}
diff --git a/content/browser/renderer_host/pepper_tcp_server_socket.h b/content/browser/renderer_host/pepper_tcp_server_socket.h
new file mode 100644
index 0000000..77b5f43
--- /dev/null
+++ b/content/browser/renderer_host/pepper_tcp_server_socket.h
@@ -0,0 +1,63 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_TCP_SERVER_SOCKET_H_
+#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_TCP_SERVER_SOCKET_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+
+class PepperMessageFilter;
+struct PP_NetAddress_Private;
+
+namespace net {
+class ServerSocket;
+class StreamSocket;
+}
+
+// PepperTCPSocket is used by PepperMessageFilter to handle requests
+// from the Pepper TCP server socket API
+// (PPB_TCPServerSocket_Private).
+class PepperTCPServerSocket {
+ public:
+ PepperTCPServerSocket(PepperMessageFilter* manager,
+ int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32 real_socket_id,
+ uint32 temp_socket_id);
+ ~PepperTCPServerSocket();
+
+ void Listen(const PP_NetAddress_Private& addr, int32 backlog);
+ void Accept();
+
+ private:
+ enum State {
+ BEFORE_LISTENING,
+ LISTEN_IN_PROGRESS,
+ LISTENING,
+ ACCEPT_IN_PROGRESS,
+ };
+
+ void CancelListenRequest();
+ void SendAcceptACKError();
+
+ void OnListenCompleted(int result);
+ void OnAcceptCompleted(int result);
+
+ PepperMessageFilter* manager_;
+ int32 routing_id_;
+ uint32 plugin_dispatcher_id_;
+ uint32 real_socket_id_;
+ uint32 temp_socket_id_;
+
+ State state_;
+
+ scoped_ptr<net::ServerSocket> socket_;
+ scoped_ptr<net::StreamSocket> socket_buffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperTCPServerSocket);
+};
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_TCP_SERVER_SOCKET_H_
diff --git a/content/browser/renderer_host/pepper_tcp_socket.cc b/content/browser/renderer_host/pepper_tcp_socket.cc
index 05a84cf..21b1cef 100644
--- a/content/browser/renderer_host/pepper_tcp_socket.cc
+++ b/content/browser/renderer_host/pepper_tcp_socket.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -44,6 +44,22 @@ PepperTCPSocket::PepperTCPSocket(
DCHECK(manager);
}
+PepperTCPSocket::PepperTCPSocket(
+ PepperMessageFilter* manager,
+ int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32 socket_id,
+ net::StreamSocket* socket)
+ : manager_(manager),
+ routing_id_(routing_id),
+ plugin_dispatcher_id_(plugin_dispatcher_id),
+ socket_id_(socket_id),
+ connection_state_(CONNECTED),
+ end_of_file_reached_(false),
+ socket_(socket) {
+ DCHECK(manager);
+}
+
PepperTCPSocket::~PepperTCPSocket() {
// Make sure no further callbacks from socket_.
if (socket_.get())
diff --git a/content/browser/renderer_host/pepper_tcp_socket.h b/content/browser/renderer_host/pepper_tcp_socket.h
index 77378d4..af1b6ed 100644
--- a/content/browser/renderer_host/pepper_tcp_socket.h
+++ b/content/browser/renderer_host/pepper_tcp_socket.h
@@ -32,6 +32,14 @@ class PepperTCPSocket {
int32 routing_id,
uint32 plugin_dispatcher_id,
uint32 socket_id);
+
+ // Used for creation already connected sockets. Takes ownership of
+ // |socket|.
+ PepperTCPSocket(PepperMessageFilter* manager,
+ int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32 socket_id,
+ net::StreamSocket* socket);
~PepperTCPSocket();
int routing_id() { return routing_id_; }
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 79727e9..ff70b51 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -512,6 +512,8 @@
'browser/renderer_host/pepper_file_message_filter.h',
'browser/renderer_host/pepper_message_filter.cc',
'browser/renderer_host/pepper_message_filter.h',
+ 'browser/renderer_host/pepper_tcp_server_socket.cc',
+ 'browser/renderer_host/pepper_tcp_server_socket.h',
'browser/renderer_host/pepper_tcp_socket.cc',
'browser/renderer_host/pepper_tcp_socket.h',
'browser/renderer_host/pepper_udp_socket.cc',
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
index c18475e..337b920 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
@@ -79,6 +79,7 @@
#include "webkit/plugins/ppapi/ppb_broker_impl.h"
#include "webkit/plugins/ppapi/ppb_flash_impl.h"
#include "webkit/plugins/ppapi/ppb_flash_net_connector_impl.h"
+#include "webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.h"
#include "webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h"
#include "webkit/plugins/ppapi/ppb_udp_socket_private_impl.h"
#include "webkit/plugins/ppapi/resource_helper.h"
@@ -1774,18 +1775,20 @@ void PepperPluginDelegateImpl::TCPSocketConnect(
uint32 socket_id,
const std::string& host,
uint16_t port) {
- tcp_sockets_.AddWithID(socket, socket_id);
- render_view_->Send(new PpapiHostMsg_PPBTCPSocket_Connect(
- render_view_->routing_id(), socket_id, host, port));
+ RegisterTCPSocket(socket, socket_id);
+ render_view_->Send(
+ new PpapiHostMsg_PPBTCPSocket_Connect(
+ render_view_->routing_id(), socket_id, host, port));
}
void PepperPluginDelegateImpl::TCPSocketConnectWithNetAddress(
webkit::ppapi::PPB_TCPSocket_Private_Impl* socket,
uint32 socket_id,
const PP_NetAddress_Private& addr) {
- tcp_sockets_.AddWithID(socket, socket_id);
- render_view_->Send(new PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress(
- render_view_->routing_id(), socket_id, addr));
+ RegisterTCPSocket(socket, socket_id);
+ render_view_->Send(
+ new PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress(
+ render_view_->routing_id(), socket_id, addr));
}
void PepperPluginDelegateImpl::TCPSocketSSLHandshake(
@@ -1819,6 +1822,12 @@ void PepperPluginDelegateImpl::TCPSocketDisconnect(uint32 socket_id) {
tcp_sockets_.Remove(socket_id);
}
+void PepperPluginDelegateImpl::RegisterTCPSocket(
+ webkit::ppapi::PPB_TCPSocket_Private_Impl* socket,
+ uint32 socket_id) {
+ tcp_sockets_.AddWithID(socket, socket_id);
+}
+
uint32 PepperPluginDelegateImpl::UDPSocketCreate() {
uint32 socket_id = 0;
render_view_->Send(new PpapiHostMsg_PPBUDPSocket_Create(
@@ -1859,6 +1868,38 @@ void PepperPluginDelegateImpl::UDPSocketClose(uint32 socket_id) {
udp_sockets_.Remove(socket_id);
}
+void PepperPluginDelegateImpl::TCPServerSocketListen(
+ webkit::ppapi::PPB_TCPServerSocket_Private_Impl* socket,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) {
+ uninitialized_tcp_server_sockets_.AddWithID(socket, temp_socket_id);
+ render_view_->Send(
+ new PpapiHostMsg_PPBTCPServerSocket_Listen(
+ render_view_->routing_id(), 0, temp_socket_id, addr, backlog));
+}
+
+void PepperPluginDelegateImpl::TCPServerSocketAccept(uint32 real_socket_id) {
+ DCHECK(tcp_server_sockets_.Lookup(real_socket_id));
+ render_view_->Send(new PpapiHostMsg_PPBTCPServerSocket_Accept(
+ real_socket_id));
+}
+
+void PepperPluginDelegateImpl::TCPServerSocketStopListening(
+ uint32 real_socket_id,
+ uint32 temp_socket_id) {
+ if (real_socket_id == 0) {
+ if (uninitialized_tcp_server_sockets_.Lookup(temp_socket_id)) {
+ // Pending Listen request.
+ uninitialized_tcp_server_sockets_.Remove(temp_socket_id);
+ }
+ } else {
+ render_view_->Send(
+ new PpapiHostMsg_PPBTCPServerSocket_Destroy(real_socket_id));
+ tcp_server_sockets_.Remove(real_socket_id);
+ }
+}
+
int32_t PepperPluginDelegateImpl::ShowContextMenu(
webkit::ppapi::PluginInstance* instance,
webkit::ppapi::PPB_Flash_Menu_Impl* menu,
@@ -2110,6 +2151,10 @@ bool PepperPluginDelegateImpl::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(PpapiMsg_PPBUDPSocket_RecvFromACK,
OnUDPSocketRecvFromACK)
IPC_MESSAGE_HANDLER(PpapiMsg_PPBUDPSocket_SendToACK, OnUDPSocketSendToACK)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_ListenACK,
+ OnTCPServerSocketListenACK)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_AcceptACK,
+ OnTCPServerSocketAcceptACK)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -2131,6 +2176,8 @@ void PepperPluginDelegateImpl::OnTCPSocketConnectACK(
tcp_sockets_.Lookup(socket_id);
if (socket)
socket->OnConnectCompleted(succeeded, local_addr, remote_addr);
+ if (!succeeded)
+ tcp_sockets_.Remove(socket_id);
}
void PepperPluginDelegateImpl::OnTCPSocketSSLHandshakeACK(
@@ -2172,6 +2219,8 @@ void PepperPluginDelegateImpl::OnUDPSocketBindACK(
udp_sockets_.Lookup(socket_id);
if (socket)
socket->OnBindCompleted(succeeded, addr);
+ if (!succeeded)
+ udp_sockets_.Remove(socket_id);
}
void PepperPluginDelegateImpl::OnUDPSocketRecvFromACK(
@@ -2196,6 +2245,43 @@ void PepperPluginDelegateImpl::OnUDPSocketSendToACK(uint32 plugin_dispatcher_id,
socket->OnSendToCompleted(succeeded, bytes_written);
}
+void PepperPluginDelegateImpl::OnTCPServerSocketListenACK(
+ uint32 plugin_dispatcher_id,
+ uint32 real_socket_id,
+ uint32 temp_socket_id,
+ int32_t status) {
+ webkit::ppapi::PPB_TCPServerSocket_Private_Impl* socket =
+ uninitialized_tcp_server_sockets_.Lookup(temp_socket_id);
+ if (socket == NULL) {
+ // StopListening was called before completion of Listen.
+ render_view_->Send(
+ new PpapiHostMsg_PPBTCPServerSocket_Destroy(real_socket_id));
+ } else {
+ uninitialized_tcp_server_sockets_.Remove(temp_socket_id);
+
+ if (status == PP_OK)
+ tcp_server_sockets_.AddWithID(socket, real_socket_id);
+ socket->OnListenCompleted(real_socket_id, status);
+ }
+}
+
+void PepperPluginDelegateImpl::OnTCPServerSocketAcceptACK(
+ uint32 plugin_dispatcher_id,
+ uint32 real_server_socket_id,
+ uint32 accepted_socket_id,
+ const PP_NetAddress_Private& local_addr,
+ const PP_NetAddress_Private& remote_addr) {
+ webkit::ppapi::PPB_TCPServerSocket_Private_Impl* socket =
+ tcp_server_sockets_.Lookup(real_server_socket_id);
+ if (socket) {
+ bool succeeded = accepted_socket_id != 0;
+ socket->OnAcceptCompleted(succeeded,
+ accepted_socket_id,
+ local_addr,
+ remote_addr);
+ }
+}
+
int PepperPluginDelegateImpl::GetRoutingId() const {
return render_view_->routing_id();
}
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h
index 0679f38..92222b1 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.h
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h
@@ -337,6 +337,9 @@ class PepperPluginDelegateImpl
virtual void TCPSocketWrite(uint32 socket_id,
const std::string& buffer) OVERRIDE;
virtual void TCPSocketDisconnect(uint32 socket_id) OVERRIDE;
+ virtual void RegisterTCPSocket(
+ webkit::ppapi::PPB_TCPSocket_Private_Impl* socket,
+ uint32 socket_id) OVERRIDE;
virtual uint32 UDPSocketCreate() OVERRIDE;
virtual void UDPSocketBind(
@@ -349,6 +352,14 @@ class PepperPluginDelegateImpl
const std::string& buffer,
const PP_NetAddress_Private& addr) OVERRIDE;
virtual void UDPSocketClose(uint32 socket_id) OVERRIDE;
+ virtual void TCPServerSocketListen(
+ webkit::ppapi::PPB_TCPServerSocket_Private_Impl* socket,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) OVERRIDE;
+ virtual void TCPServerSocketAccept(uint32 real_socket_id) OVERRIDE;
+ virtual void TCPServerSocketStopListening(uint32 real_socket_id,
+ uint32 temp_socket_id) OVERRIDE;
virtual int32_t ShowContextMenu(
webkit::ppapi::PluginInstance* instance,
@@ -427,6 +438,15 @@ class PepperPluginDelegateImpl
bool succeeded,
const std::string& data,
const PP_NetAddress_Private& addr);
+ void OnTCPServerSocketListenACK(uint32 plugin_dispatcher_id,
+ uint32 real_socket_id,
+ uint32 temp_socket_id,
+ int32_t status);
+ void OnTCPServerSocketAcceptACK(uint32 plugin_dispatcher_id,
+ uint32 real_server_socket_id,
+ uint32 accepted_socket_id,
+ const PP_NetAddress_Private& local_addr,
+ const PP_NetAddress_Private& remote_addr);
CONTENT_EXPORT int GetRoutingId() const;
@@ -481,6 +501,11 @@ class PepperPluginDelegateImpl
IDMap<webkit::ppapi::PPB_UDPSocket_Private_Impl> udp_sockets_;
+ IDMap<webkit::ppapi::PPB_TCPServerSocket_Private_Impl> tcp_server_sockets_;
+
+ IDMap<webkit::ppapi::PPB_TCPServerSocket_Private_Impl>
+ uninitialized_tcp_server_sockets_;
+
IDMap<scoped_refptr<webkit::ppapi::PPB_Flash_Menu_Impl>,
IDMapOwnPointer> pending_context_menus_;
diff --git a/ppapi/api/private/ppb_tcp_server_socket_private.idl b/ppapi/api/private/ppb_tcp_server_socket_private.idl
new file mode 100644
index 0000000..a1224e1
--- /dev/null
+++ b/ppapi/api/private/ppb_tcp_server_socket_private.idl
@@ -0,0 +1,61 @@
+/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * This file defines the <code>PPB_TCPServerSocket_Private</code> interface.
+ */
+
+label Chrome {
+ M18 = 0.1
+};
+
+/**
+ * The <code>PPB_TCPServerSocket_Private</code> interface provides TCP
+ * server socket operations.
+ */
+interface PPB_TCPServerSocket_Private {
+ /**
+ * Allocates a TCP server socket resource.
+ */
+ PP_Resource Create([in] PP_Instance instance);
+
+ /**
+ * Determines if a given resource is TCP server socket.
+ */
+ PP_Bool IsTCPServerSocket([in] PP_Resource resource);
+
+ /**
+ * Binds |tcp_server_socket| to the address given by |addr| and
+ * starts listening. The |backlog| argument defines the maximum
+ * length to which the queue of pending connections may
+ * grow. |callback| is invoked when |tcp_server_socket| is ready to
+ * accept incoming connections or in the case of failure. Returns
+ * PP_ERROR_NOSPACE if socket can't be initialized, or
+ * PP_ERROR_FAILED in the case of Listen failure. Otherwise, returns
+ * PP_OK.
+ */
+ int32_t Listen([in] PP_Resource tcp_server_socket,
+ [in] PP_NetAddress_Private addr,
+ [in] int32_t backlog,
+ [in] PP_CompletionCallback callback);
+
+ /**
+ * Accepts single connection, creates instance of
+ * PPB_TCPSocket_Private and stores reference to it in
+ * |tcp_socket|. |callback| is invoked when connection is accepted
+ * or in the case of failure. This method can be called only after
+ * succesfull Listen call on |tcp_server_socket|.
+ */
+ int32_t Accept([in] PP_Resource tcp_server_socket,
+ [out] PP_Resource tcp_socket,
+ [in] PP_CompletionCallback callback);
+
+ /**
+ * Cancels all pending callbacks reporting PP_ERROR_ABORTED and
+ * closes the socket. Note: this method is implicitly called when
+ * server socket is destroyed.
+ */
+ void StopListening([in] PP_Resource tcp_server_socket);
+};
diff --git a/ppapi/c/private/ppb_tcp_server_socket_private.h b/ppapi/c/private/ppb_tcp_server_socket_private.h
new file mode 100644
index 0000000..8355b15
--- /dev/null
+++ b/ppapi/c/private/ppb_tcp_server_socket_private.h
@@ -0,0 +1,87 @@
+/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* From private/ppb_tcp_server_socket_private.idl,
+ * modified Tue Feb 14 12:24:48 2012.
+ */
+
+#ifndef PPAPI_C_PRIVATE_PPB_TCP_SERVER_SOCKET_PRIVATE_H_
+#define PPAPI_C_PRIVATE_PPB_TCP_SERVER_SOCKET_PRIVATE_H_
+
+#include "ppapi/c/pp_bool.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_macros.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/private/ppb_net_address_private.h"
+
+#define PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE_0_1 \
+ "PPB_TCPServerSocket_Private;0.1"
+#define PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE \
+ PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE_0_1
+
+/**
+ * @file
+ * This file defines the <code>PPB_TCPServerSocket_Private</code> interface.
+ */
+
+
+/**
+ * @addtogroup Interfaces
+ * @{
+ */
+/**
+ * The <code>PPB_TCPServerSocket_Private</code> interface provides TCP
+ * server socket operations.
+ */
+struct PPB_TCPServerSocket_Private_0_1 {
+ /**
+ * Allocates a TCP server socket resource.
+ */
+ PP_Resource (*Create)(PP_Instance instance);
+ /**
+ * Determines if a given resource is TCP server socket.
+ */
+ PP_Bool (*IsTCPServerSocket)(PP_Resource resource);
+ /**
+ * Binds |tcp_server_socket| to the address given by |addr| and
+ * starts listening. The |backlog| argument defines the maximum
+ * length to which the queue of pending connections may
+ * grow. |callback| is invoked when |tcp_server_socket| is ready to
+ * accept incoming connections or in the case of failure. Returns
+ * PP_ERROR_NOSPACE if socket can't be initialized, or
+ * PP_ERROR_FAILED in the case of Listen failure. Otherwise, returns
+ * PP_OK.
+ */
+ int32_t (*Listen)(PP_Resource tcp_server_socket,
+ const struct PP_NetAddress_Private* addr,
+ int32_t backlog,
+ struct PP_CompletionCallback callback);
+ /**
+ * Accepts single connection, creates instance of
+ * PPB_TCPSocket_Private and stores reference to it in
+ * |tcp_socket|. |callback| is invoked when connection is accepted
+ * or in the case of failure. This method can be called only after
+ * succesfull Listen call on |tcp_server_socket|.
+ */
+ int32_t (*Accept)(PP_Resource tcp_server_socket,
+ PP_Resource* tcp_socket,
+ struct PP_CompletionCallback callback);
+ /**
+ * Cancels all pending callbacks reporting PP_ERROR_ABORTED and
+ * closes the socket. Note: this method is implicitly called when
+ * server socket is destroyed.
+ */
+ void (*StopListening)(PP_Resource tcp_server_socket);
+};
+
+typedef struct PPB_TCPServerSocket_Private_0_1 PPB_TCPServerSocket_Private;
+/**
+ * @}
+ */
+
+#endif /* PPAPI_C_PRIVATE_PPB_TCP_SERVER_SOCKET_PRIVATE_H_ */
+
diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi
index b6c3b62..56df78c1 100644
--- a/ppapi/ppapi_shared.gypi
+++ b/ppapi/ppapi_shared.gypi
@@ -130,7 +130,8 @@
'shared_impl/private/ppb_browser_font_trusted_shared.h',
'shared_impl/private/ppb_char_set_shared.cc',
'shared_impl/private/ppb_char_set_shared.h',
-
+ 'shared_impl/private/ppb_tcp_server_socket_shared.cc',
+ 'shared_impl/private/ppb_tcp_server_socket_shared.h',
'shared_impl/private/tcp_socket_private_impl.cc',
'shared_impl/private/tcp_socket_private_impl.h',
'shared_impl/private/udp_socket_private_impl.cc',
@@ -206,6 +207,8 @@
'thunk/ppb_resource_array_thunk.cc',
'thunk/ppb_scrollbar_api.h',
'thunk/ppb_scrollbar_thunk.cc',
+ 'thunk/ppb_tcp_server_socket_private_api.h',
+ 'thunk/ppb_tcp_server_socket_private_thunk.cc',
'thunk/ppb_tcp_socket_private_api.h',
'thunk/ppb_tcp_socket_private_thunk.cc',
'thunk/ppb_text_input_api.h',
diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi
index d0bee15..e212681 100644
--- a/ppapi/ppapi_sources.gypi
+++ b/ppapi/ppapi_sources.gypi
@@ -290,6 +290,8 @@
'tests/test_case.h',
'tests/test_net_address_private_untrusted.cc',
'tests/test_net_address_private_untrusted.h',
+ 'tests/test_tcp_server_socket_private.cc',
+ 'tests/test_tcp_server_socket_private.h',
'tests/test_tcp_socket_private_shared.cc',
'tests/test_tcp_socket_private_shared.h',
'tests/test_udp_socket_private_shared.cc',
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index dceb91d..ff19419 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -332,6 +332,26 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBUDPSocket_SendToACK,
bool /* succeeded */,
int32_t /* bytes_written */)
+// PPB_TCPServerSocket_Private.
+
+// |status| == PP_ERROR_NOSPACE means that the socket table is full
+// and new socket can't be initialized.
+// |status| == PP_ERROR_FAILED means that socket is correctly
+// initialized (if needed) but Listen call is failed.
+// |status| == PP_OK means that socket is correctly initialized (if
+// needed) and Listen call succeeds.
+IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPServerSocket_ListenACK,
+ uint32 /* plugin_dispatcher_id */,
+ uint32 /* real_socket_id */,
+ uint32 /* temp_socket_id */,
+ int32_t /* status */)
+IPC_MESSAGE_ROUTED5(PpapiMsg_PPBTCPServerSocket_AcceptACK,
+ uint32 /* plugin_dispatcher_id */,
+ uint32 /* real_server_socket_id */,
+ uint32 /* accepted_socket_id */,
+ PP_NetAddress_Private /* local_addr */,
+ PP_NetAddress_Private /* remote_addr */)
+
// PPB_Graphics2D.
IPC_MESSAGE_ROUTED2(PpapiMsg_PPBGraphics2D_FlushACK,
ppapi::HostResource /* graphics_2d */,
@@ -849,6 +869,22 @@ IPC_MESSAGE_CONTROL3(PpapiHostMsg_PPBUDPSocket_SendTo,
IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBUDPSocket_Close,
uint32 /* socket_id */)
+// PPB_TCPServerSocket_Private.
+IPC_MESSAGE_CONTROL5(PpapiHostMsg_PPBTCPServerSocket_Listen,
+ int32 /* routing_id */,
+ uint32 /* plugin_dispatcher_id */,
+ uint32 /* temp_socket_id */,
+ PP_NetAddress_Private /* addr */,
+ int32_t /* backlog */)
+IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBTCPServerSocket_Accept,
+ uint32 /* real_socket_id */)
+IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBTCPServerSocket_Destroy,
+ uint32 /* real_socket_id */)
+
+// PPB_Font.
+IPC_SYNC_MESSAGE_CONTROL0_1(PpapiHostMsg_PPBFont_GetFontFamilies,
+ std::string /* result */)
+
// PPB_Graphics2D.
IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBGraphics2D_Create,
PP_Instance /* instance */,
diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc
index 731dd60..45dd02e 100644
--- a/ppapi/proxy/resource_creation_proxy.cc
+++ b/ppapi/proxy/resource_creation_proxy.cc
@@ -268,6 +268,12 @@ PP_Resource ResourceCreationProxy::CreateScrollbar(PP_Instance instance,
return 0;
}
+PP_Resource ResourceCreationProxy::CreateTCPServerSocketPrivate(
+ PP_Instance instance) {
+ // TODO (ygorshenin): implement this
+ return 0;
+}
+
PP_Resource ResourceCreationProxy::CreateTCPSocketPrivate(
PP_Instance instance) {
return PPB_TCPSocket_Private_Proxy::CreateProxyResource(instance);
diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h
index f508e42..c7f84ab 100644
--- a/ppapi/proxy/resource_creation_proxy.h
+++ b/ppapi/proxy/resource_creation_proxy.h
@@ -106,6 +106,8 @@ class ResourceCreationProxy : public InterfaceProxy,
uint32_t size) OVERRIDE;
virtual PP_Resource CreateScrollbar(PP_Instance instance,
PP_Bool vertical) OVERRIDE;
+ virtual PP_Resource CreateTCPServerSocketPrivate(
+ PP_Instance instance) OVERRIDE;
virtual PP_Resource CreateTCPSocketPrivate(PP_Instance instance) OVERRIDE;
virtual PP_Resource CreateTransport(PP_Instance instance,
const char* name,
diff --git a/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.cc b/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.cc
new file mode 100644
index 0000000..284db1e
--- /dev/null
+++ b/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.cc
@@ -0,0 +1,113 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h"
+
+#include <cstddef>
+
+#include "base/logging.h"
+#include "ppapi/c/pp_errors.h"
+
+namespace ppapi {
+
+PPB_TCPServerSocket_Shared::PPB_TCPServerSocket_Shared(PP_Instance instance)
+ : Resource(OBJECT_IS_IMPL, instance),
+ real_socket_id_(0),
+ temp_socket_id_(GenerateTempSocketID()),
+ state_(BEFORE_LISTENING),
+ tcp_socket_buffer_(NULL) {
+}
+
+PPB_TCPServerSocket_Shared::PPB_TCPServerSocket_Shared(
+ const HostResource& resource)
+ : Resource(OBJECT_IS_PROXY, resource),
+ real_socket_id_(0),
+ temp_socket_id_(GenerateTempSocketID()),
+ state_(BEFORE_LISTENING),
+ tcp_socket_buffer_(NULL) {
+}
+
+PPB_TCPServerSocket_Shared::~PPB_TCPServerSocket_Shared() {
+}
+
+thunk::PPB_TCPServerSocket_Private_API*
+PPB_TCPServerSocket_Shared::AsPPB_TCPServerSocket_Private_API() {
+ return this;
+}
+
+int32_t PPB_TCPServerSocket_Shared::Listen(const PP_NetAddress_Private* addr,
+ int32_t backlog,
+ PP_CompletionCallback callback) {
+ if (!addr)
+ return PP_ERROR_BADARGUMENT;
+ if (!callback.func)
+ return PP_ERROR_BLOCKS_MAIN_THREAD;
+ if (state_ != BEFORE_LISTENING)
+ return PP_ERROR_FAILED;
+ if (TrackedCallback::IsPending(listen_callback_))
+ return PP_ERROR_INPROGRESS; // Can only have one pending request.
+
+ listen_callback_ = new TrackedCallback(this, callback);
+ // Send the request, the browser will call us back via ListenACK
+ SendListen(temp_socket_id_, *addr, backlog);
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PPB_TCPServerSocket_Shared::Accept(PP_Resource* tcp_socket,
+ PP_CompletionCallback callback) {
+ if (!tcp_socket)
+ return PP_ERROR_BADARGUMENT;
+ if (!callback.func)
+ return PP_ERROR_BLOCKS_MAIN_THREAD;
+
+ if (state_ != LISTENING)
+ return PP_ERROR_FAILED;
+ if (TrackedCallback::IsPending(accept_callback_))
+ return PP_ERROR_INPROGRESS;
+
+ tcp_socket_buffer_ = tcp_socket;
+ accept_callback_ = new TrackedCallback(this, callback);
+
+ SendAccept();
+ return PP_OK_COMPLETIONPENDING;
+}
+
+void PPB_TCPServerSocket_Shared::StopListening() {
+ if (state_ == CLOSED)
+ return;
+
+ state_ = CLOSED;
+
+ SendStopListening();
+ real_socket_id_ = 0;
+
+ if (listen_callback_.get())
+ listen_callback_->PostAbort();
+ if (accept_callback_.get())
+ accept_callback_->PostAbort();
+ tcp_socket_buffer_ = NULL;
+}
+
+void PPB_TCPServerSocket_Shared::OnListenCompleted(uint32 real_socket_id,
+ int32_t status) {
+ if (state_ != BEFORE_LISTENING ||
+ !TrackedCallback::IsPending(listen_callback_)) {
+ NOTREACHED();
+ return;
+ }
+
+ if (status == PP_OK) {
+ real_socket_id_ = real_socket_id;
+ state_ = LISTENING;
+ }
+
+ TrackedCallback::ClearAndRun(&listen_callback_, status);
+}
+
+uint32 PPB_TCPServerSocket_Shared::GenerateTempSocketID() {
+ static uint32 socket_id = 0;
+ return socket_id++;
+}
+
+} // namespace ppapi
diff --git a/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h b/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h
new file mode 100644
index 0000000..15cbc03
--- /dev/null
+++ b/ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_SHARED_IMPL_PRIVATE_PPB_TCP_SERVER_SOCKET_SHARED_H_
+#define PPAPI_SHARED_IMPL_PRIVATE_PPB_TCP_SERVER_SOCKET_SHARED_H_
+
+#include "base/compiler_specific.h"
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/shared_impl/resource.h"
+#include "ppapi/shared_impl/tracked_callback.h"
+#include "ppapi/thunk/ppb_tcp_server_socket_private_api.h"
+
+namespace ppapi {
+
+// This class provides the shared implementation of a
+// PPB_TCPServerSocket_Private. The functions that actually send
+// messages to browser are implemented differently for the proxied and
+// non-proxied derived classes.
+class PPAPI_SHARED_EXPORT PPB_TCPServerSocket_Shared
+ : public thunk::PPB_TCPServerSocket_Private_API,
+ public Resource {
+ public:
+ // C-tor used in Impl case.
+ PPB_TCPServerSocket_Shared(PP_Instance instance);
+ // C-tor used in Proxy case.
+ PPB_TCPServerSocket_Shared(const HostResource& resource);
+
+ virtual ~PPB_TCPServerSocket_Shared();
+
+ // Resource overrides.
+ virtual PPB_TCPServerSocket_Private_API*
+ AsPPB_TCPServerSocket_Private_API() OVERRIDE;
+
+ // PPB_TCPServerSocket_Private_API implementation.
+ virtual int32_t Listen(const PP_NetAddress_Private* addr,
+ int32_t backlog,
+ PP_CompletionCallback callback) OVERRIDE;
+ virtual int32_t Accept(PP_Resource* tcp_socket,
+ PP_CompletionCallback callback) OVERRIDE;
+ virtual void StopListening() OVERRIDE;
+
+ void OnListenCompleted(uint32 real_socket_id, int32_t status);
+ virtual void OnAcceptCompleted(bool succeeded,
+ uint32 tcp_socket_id,
+ const PP_NetAddress_Private& local_addr,
+ const PP_NetAddress_Private& remote_addr) = 0;
+
+ // Send functions that need to be implemented differently for the
+ // proxied and non-proxied derived classes.
+ virtual void SendListen(uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) = 0;
+ virtual void SendAccept() = 0;
+ virtual void SendStopListening() = 0;
+
+ protected:
+ enum State {
+ // Before listening (including a listen request is pending or a
+ // previous listen request failed).
+ BEFORE_LISTENING,
+ // Socket is successfully bound and in listening mode.
+ LISTENING,
+ // The socket is closed.
+ CLOSED
+ };
+
+ static uint32 GenerateTempSocketID();
+
+ uint32 real_socket_id_;
+ uint32 temp_socket_id_;
+ State state_;
+
+ scoped_refptr<TrackedCallback> listen_callback_;
+ scoped_refptr<TrackedCallback> accept_callback_;
+
+ PP_Resource* tcp_socket_buffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PPB_TCPServerSocket_Shared);
+};
+
+} // namespace ppapi
+
+#endif // PPAPI_SHARED_IMPL_PRIVATE_PPB_TCP_SERVER_SOCKET_SHARED_H_
diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h
index 8f4dc25..34df0ea 100644
--- a/ppapi/shared_impl/resource.h
+++ b/ppapi/shared_impl/resource.h
@@ -47,6 +47,7 @@
F(PPB_PDFFont_API) \
F(PPB_ResourceArray_API) \
F(PPB_Scrollbar_API) \
+ F(PPB_TCPServerSocket_Private_API) \
F(PPB_TCPSocket_Private_API) \
F(PPB_Transport_API) \
F(PPB_UDPSocket_Private_API) \
diff --git a/ppapi/tests/test_tcp_server_socket_private.cc b/ppapi/tests/test_tcp_server_socket_private.cc
new file mode 100644
index 0000000..47edda9
--- /dev/null
+++ b/ppapi/tests/test_tcp_server_socket_private.cc
@@ -0,0 +1,399 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/tests/test_tcp_server_socket_private.h"
+
+#include <cstddef>
+#include <cstring>
+#include <vector>
+
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/private/net_address_private.h"
+#include "ppapi/cpp/private/tcp_socket_private.h"
+#include "ppapi/tests/test_utils.h"
+#include "ppapi/tests/testing_instance.h"
+
+#define ASSERT_SUCCESS(error_message) \
+ if (!(error_message).empty()) \
+ return (error_message);
+
+using pp::NetAddressPrivate;
+using pp::TCPSocketPrivate;
+
+namespace {
+
+const uint16_t kPortScanFrom = 1024;
+const uint16_t kPortScanTo = 4096;
+
+} // namespace
+
+REGISTER_TEST_CASE(TCPServerSocketPrivate);
+
+TestTCPServerSocketPrivate::TestTCPServerSocketPrivate(
+ TestingInstance* instance)
+ : TestCase(instance),
+ core_interface_(NULL),
+ tcp_server_socket_private_interface_(NULL),
+ tcp_socket_private_interface_(NULL),
+ port_(0) {
+}
+
+bool TestTCPServerSocketPrivate::Init() {
+ core_interface_ = static_cast<const PPB_Core*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
+ if (!core_interface_)
+ instance_->AppendError("PPB_Core interface not available");
+ tcp_server_socket_private_interface_ =
+ static_cast<const PPB_TCPServerSocket_Private*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE));
+ if (!tcp_server_socket_private_interface_) {
+ instance_->AppendError(
+ "PPB_TCPServerSocket_Private interface not available");
+ }
+
+ tcp_socket_private_interface_ =
+ static_cast<const PPB_TCPSocket_Private*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_TCPSOCKET_PRIVATE_INTERFACE));
+ if (!tcp_socket_private_interface_)
+ instance_->AppendError("PPB_TCPSocket_Private interface not available");
+
+ bool tcp_socket_private_is_available = TCPSocketPrivate::IsAvailable();
+ if (!tcp_socket_private_is_available)
+ instance_->AppendError("PPB_TCPSocket_Private interface not available");
+
+ bool net_address_private_is_available = NetAddressPrivate::IsAvailable();
+ if (!net_address_private_is_available)
+ instance_->AppendError("PPB_NetAddress_Private interface not available");
+
+ bool init_host_port = GetLocalHostPort(
+ instance_->pp_instance(), &host_, &port_);
+ if (!init_host_port)
+ instance_->AppendError("Can't init host and port");
+
+ return core_interface_ &&
+ tcp_server_socket_private_interface_ &&
+ tcp_socket_private_is_available &&
+ net_address_private_is_available &&
+ init_host_port &&
+ CheckTestingInterface();
+}
+
+void TestTCPServerSocketPrivate::RunTests(const std::string& filter) {
+ RUN_TEST_FORCEASYNC_AND_NOT(Create, filter);
+ RUN_TEST_FORCEASYNC_AND_NOT(Listen, filter);
+ RUN_TEST_FORCEASYNC_AND_NOT(Backlog, filter);
+}
+
+std::string TestTCPServerSocketPrivate::GetLocalAddress(
+ PP_NetAddress_Private* address) {
+ TCPSocketPrivate socket(instance_);
+
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+ int32_t rv = socket.Connect(host_.c_str(), port_, callback);
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_TCPSocket_Private::Connect force_async", rv);
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("PPB_TCPSocket_Private::Connect", rv);
+
+ if (!socket.GetLocalAddress(address))
+ return ReportError("PPB_TCPSocket_Private::GetLocalAddress", 0);
+ socket.Disconnect();
+ PASS();
+}
+
+std::string TestTCPServerSocketPrivate::SyncRead(PP_Resource socket,
+ char* buffer,
+ int32_t num_bytes) {
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+
+ int32_t rv = tcp_socket_private_interface_->Read(
+ socket, buffer, num_bytes,
+ static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
+
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_TCPSocket_Private::Read force_async", rv);
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+
+ if (num_bytes != rv)
+ return ReportError("PPB_TCPSocket_Private::Read", rv);
+
+ PASS();
+}
+
+std::string TestTCPServerSocketPrivate::SyncWrite(PP_Resource socket,
+ const char* buffer,
+ int32_t num_bytes) {
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+ int32_t rv = tcp_socket_private_interface_->Write(
+ socket, buffer, num_bytes,
+ static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
+
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_TCPSocket_Private::Write force_async", rv);
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+ if (num_bytes != rv)
+ return ReportError("PPB_TCPSocket_Private::Write", rv);
+
+ PASS();
+}
+
+std::string TestTCPServerSocketPrivate::SyncConnect(PP_Resource socket,
+ const char* host,
+ uint16_t port) {
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+ int32_t rv = tcp_socket_private_interface_->Connect(
+ socket,
+ host_.c_str(),
+ port,
+ static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_TCPSocket_Private::Connect force_async", rv);
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("PPB_TCPSocket_Private::Connect", rv);
+
+ PASS();
+}
+
+void TestTCPServerSocketPrivate::ForceConnect(PP_Resource socket,
+ const char* host,
+ uint16_t port) {
+ std::string error_message;
+ do {
+ error_message = SyncConnect(socket, host, port);
+ } while (!error_message.empty());
+}
+
+std::string TestTCPServerSocketPrivate::SyncListen(PP_Resource socket,
+ uint16_t* port,
+ int32_t backlog) {
+ PP_NetAddress_Private base_address, local_address;
+ std::string error_message = GetLocalAddress(&base_address);
+ ASSERT_SUCCESS(error_message);
+
+ // TODO (ygorshenin): find more efficient way to select available
+ // ports.
+ bool is_free_port_found = false;
+ for (uint16_t p = kPortScanFrom; p < kPortScanTo; ++p) {
+ if (!NetAddressPrivate::ReplacePort(base_address, p, &local_address))
+ return ReportError("PPB_NetAddress_Private::ReplacePort", 0);
+
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+ int32_t rv = tcp_server_socket_private_interface_->Listen(
+ socket,
+ &local_address,
+ backlog,
+ static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_TCPServerSocket_Private::Listen force_async", rv);
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+ if (rv == PP_OK) {
+ *port = p;
+ is_free_port_found = true;
+ break;
+ }
+ }
+
+ if (!is_free_port_found)
+ return "Can't find available port";
+ PASS();
+}
+
+bool TestTCPServerSocketPrivate::IsSocketsConnected(
+ PP_Resource lhs,
+ PP_Resource rhs) {
+ PP_NetAddress_Private lhs_local_addr, lhs_remote_addr;
+
+ if (!tcp_socket_private_interface_->GetLocalAddress(lhs, &lhs_local_addr))
+ return false;
+ if (!tcp_socket_private_interface_->GetRemoteAddress(lhs, &lhs_remote_addr))
+ return false;
+
+ PP_NetAddress_Private rhs_local_addr, rhs_remote_addr;
+ if (!tcp_socket_private_interface_->GetLocalAddress(rhs, &rhs_local_addr))
+ return false;
+ if (!tcp_socket_private_interface_->GetRemoteAddress(rhs, &rhs_remote_addr))
+ return false;
+
+ return NetAddressPrivate::AreEqual(lhs_local_addr, rhs_remote_addr) &&
+ NetAddressPrivate::AreEqual(lhs_remote_addr, rhs_local_addr);
+}
+
+std::string TestTCPServerSocketPrivate::SendMessage(PP_Resource dst,
+ PP_Resource src,
+ const char* message) {
+ const size_t message_size = strlen(message);
+
+ std::string error_message = SyncWrite(src, message, message_size);
+ ASSERT_SUCCESS(error_message);
+
+ std::vector<char> message_buffer(message_size);
+ error_message = SyncRead(dst, &message_buffer[0], message_size);
+ ASSERT_SUCCESS(error_message);
+ ASSERT_EQ(0, strncmp(message, &message_buffer[0], message_size));
+ PASS();
+}
+
+std::string TestTCPServerSocketPrivate::TestConnectedSockets(PP_Resource lhs,
+ PP_Resource rhs) {
+ static const char* const kMessage = "simple message";
+ std::string error_message = SendMessage(lhs, rhs, kMessage);
+ ASSERT_SUCCESS(error_message);
+ error_message = SendMessage(rhs, lhs, kMessage);
+ ASSERT_SUCCESS(error_message);
+ PASS();
+}
+
+std::string TestTCPServerSocketPrivate::TestCreate() {
+ PP_Resource server_socket;
+
+ server_socket = tcp_server_socket_private_interface_->Create(0);
+ ASSERT_EQ(0, server_socket);
+ core_interface_->ReleaseResource(server_socket);
+
+ server_socket =
+ tcp_server_socket_private_interface_->Create(instance_->pp_instance());
+ ASSERT_TRUE(server_socket != 0);
+ ASSERT_TRUE(tcp_server_socket_private_interface_->IsTCPServerSocket(
+ server_socket));
+ core_interface_->ReleaseResource(server_socket);
+ PASS();
+}
+
+std::string TestTCPServerSocketPrivate::TestListen() {
+ static const int kBacklog = 2;
+
+ PP_Resource server_socket =
+ tcp_server_socket_private_interface_->Create(instance_->pp_instance());
+ ASSERT_TRUE(server_socket != 0);
+
+ uint16_t port;
+ std::string error_message = SyncListen(server_socket, &port, kBacklog);
+ ASSERT_SUCCESS(error_message);
+
+ TestCompletionCallback accept_callback(instance_->pp_instance(),
+ force_async_);
+ PP_Resource accepted_socket;
+ int32_t accept_rv = tcp_server_socket_private_interface_->Accept(
+ server_socket,
+ &accepted_socket,
+ static_cast<pp::CompletionCallback>(
+ accept_callback).pp_completion_callback());
+
+ TCPSocketPrivate client_socket(instance_);
+
+ ForceConnect(client_socket.pp_resource(), host_.c_str(), port);
+
+ if (force_async_ && accept_rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_TCPServerSocket_Private::Accept force_async",
+ accept_rv);
+ if (accept_rv == PP_OK_COMPLETIONPENDING)
+ accept_rv = accept_callback.WaitForResult();
+ if (accept_rv != PP_OK)
+ return ReportError("PPB_TCPServerSocket_Private::Accept", accept_rv);
+
+ ASSERT_TRUE(accepted_socket != 0);
+ ASSERT_TRUE(tcp_socket_private_interface_->IsTCPSocket(accepted_socket));
+
+ ASSERT_TRUE(IsSocketsConnected(client_socket.pp_resource(), accepted_socket));
+ error_message = TestConnectedSockets(client_socket.pp_resource(),
+ accepted_socket);
+ ASSERT_SUCCESS(error_message);
+
+ tcp_socket_private_interface_->Disconnect(accepted_socket);
+ client_socket.Disconnect();
+ tcp_server_socket_private_interface_->StopListening(server_socket);
+
+ core_interface_->ReleaseResource(accepted_socket);
+ core_interface_->ReleaseResource(server_socket);
+ PASS();
+}
+
+std::string TestTCPServerSocketPrivate::TestBacklog() {
+ static const size_t kBacklog = 5;
+
+ PP_Resource server_socket =
+ tcp_server_socket_private_interface_->Create(instance_->pp_instance());
+ ASSERT_TRUE(server_socket != 0);
+
+ uint16_t port;
+ std::string error_message = SyncListen(server_socket, &port, 2 * kBacklog);
+ ASSERT_SUCCESS(error_message);
+
+ std::vector<TCPSocketPrivate*> client_sockets(kBacklog);
+ std::vector<TestCompletionCallback*> connect_callbacks(kBacklog);
+ std::vector<int32_t> connect_rv(kBacklog);
+ for (size_t i = 0; i < kBacklog; ++i) {
+ client_sockets[i] = new TCPSocketPrivate(instance_);
+ connect_callbacks[i] = new TestCompletionCallback(instance_->pp_instance(),
+ force_async_);
+ connect_rv[i] = client_sockets[i]->Connect(host_.c_str(),
+ port,
+ *connect_callbacks[i]);
+ if (force_async_ && connect_rv[i] != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_TCPSocket_Private::Connect force_async",
+ connect_rv[i]);
+ }
+
+ std::vector<PP_Resource> accepted_sockets(kBacklog);
+ for (size_t i = 0; i < kBacklog; ++i) {
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+ int32_t rv = tcp_server_socket_private_interface_->Accept(
+ server_socket,
+ &accepted_sockets[i],
+ static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_TCPServerSocket_Private::Accept force_async", rv);
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("PPB_TCPServerSocket_Private::Accept", rv);
+
+ ASSERT_TRUE(accepted_sockets[i] != 0);
+ ASSERT_TRUE(tcp_socket_private_interface_->IsTCPSocket(
+ accepted_sockets[i]));
+ }
+
+ for (size_t i = 0; i < kBacklog; ++i) {
+ if (connect_rv[i] == PP_OK_COMPLETIONPENDING)
+ connect_rv[i] = connect_callbacks[i]->WaitForResult();
+ if (connect_rv[i] != PP_OK)
+ return ReportError("PPB_TCPSocket_Private::Connect", connect_rv[i]);
+ }
+
+ for (size_t i = 0; i < kBacklog; ++i) {
+ bool found = false;
+ for (size_t j = 0; j < kBacklog && !found; ++j)
+ if (IsSocketsConnected(client_sockets[i]->pp_resource(),
+ accepted_sockets[j])) {
+ TestConnectedSockets(client_sockets[i]->pp_resource(),
+ accepted_sockets[j]);
+ found = true;
+ }
+ ASSERT_TRUE(found);
+ }
+
+ for (size_t i = 0; i < kBacklog; ++i) {
+ tcp_socket_private_interface_->Disconnect(accepted_sockets[i]);
+ core_interface_->ReleaseResource(accepted_sockets[i]);
+ }
+
+ for (size_t i = 0; i < kBacklog; ++i) {
+ client_sockets[i]->Disconnect();
+ delete client_sockets[i];
+ delete connect_callbacks[i];
+ }
+
+ tcp_server_socket_private_interface_->StopListening(server_socket);
+ core_interface_->ReleaseResource(server_socket);
+ PASS();
+}
diff --git a/ppapi/tests/test_tcp_server_socket_private.h b/ppapi/tests/test_tcp_server_socket_private.h
new file mode 100644
index 0000000..5ada1c1
--- /dev/null
+++ b/ppapi/tests/test_tcp_server_socket_private.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_TESTS_TEST_TCP_SERVER_SOCKET_PRIVATE_H_
+#define PPAPI_TESTS_TEST_TCP_SERVER_SOCKET_PRIVATE_H_
+
+#include <string>
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/c/private/ppb_net_address_private.h"
+#include "ppapi/c/private/ppb_tcp_server_socket_private.h"
+#include "ppapi/c/private/ppb_tcp_socket_private.h"
+#include "ppapi/tests/test_case.h"
+
+class TestTCPServerSocketPrivate : public TestCase {
+ public:
+ explicit TestTCPServerSocketPrivate(TestingInstance* instance);
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTests(const std::string& filter);
+
+ private:
+ std::string GetLocalAddress(PP_NetAddress_Private* address);
+ std::string SyncRead(PP_Resource socket, char* buffer, int32_t num_bytes);
+ std::string SyncWrite(PP_Resource socket,
+ const char* buffer,
+ int32_t num_bytes);
+ std::string SyncConnect(PP_Resource socket, const char* host, uint16_t port);
+ void ForceConnect(PP_Resource socket, const char* host, uint16_t port);
+ std::string SyncListen(PP_Resource socket, uint16_t* port, int32_t backlog);
+
+ bool IsSocketsConnected(PP_Resource lhs, PP_Resource rhs);
+ std::string SendMessage(PP_Resource dst,
+ PP_Resource src,
+ const char* message);
+ std::string TestConnectedSockets(PP_Resource lhs, PP_Resource rhs);
+
+ std::string CheckIOOfConnectedSockets(PP_Resource src, PP_Resource dst);
+ std::string CheckAddressesOfConnectedSockets(PP_Resource lhs,
+ PP_Resource rhs);
+
+ std::string TestCreate();
+ std::string TestListen();
+ std::string TestBacklog();
+
+ const PPB_Core* core_interface_;
+ const PPB_TCPServerSocket_Private* tcp_server_socket_private_interface_;
+ const PPB_TCPSocket_Private* tcp_socket_private_interface_;
+ std::string host_;
+ uint16_t port_;
+};
+
+#endif // PPAPI_TESTS_TEST_TCP_SERVER_SOCKET_PRIVATE_H_
diff --git a/ppapi/thunk/ppb_tcp_server_socket_private_api.h b/ppapi/thunk/ppb_tcp_server_socket_private_api.h
new file mode 100644
index 0000000..b88dfc8
--- /dev/null
+++ b/ppapi/thunk/ppb_tcp_server_socket_private_api.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_THUNK_PPB_TCP_SERVER_SOCKET_PRIVATE_API_H_
+#define PPAPI_THUNK_PPB_TCP_SERVER_SOCKET_PRIVATE_API_H_
+
+#include "ppapi/c/private/ppb_tcp_server_socket_private.h"
+#include "ppapi/thunk/ppapi_thunk_export.h"
+
+namespace ppapi {
+namespace thunk {
+
+class PPAPI_THUNK_EXPORT PPB_TCPServerSocket_Private_API {
+public:
+ virtual ~PPB_TCPServerSocket_Private_API() {}
+
+ virtual int32_t Listen(const PP_NetAddress_Private* addr,
+ int32_t backlog,
+ PP_CompletionCallback callback) = 0;
+ virtual int32_t Accept(PP_Resource* tcp_socket,
+ PP_CompletionCallback callback) = 0;
+ virtual void StopListening() = 0;
+};
+
+} // namespace thunk
+} // namespace ppapi
+
+#endif // PPAPI_THUNK_PPB_TCP_SERVER_SOCKET_PRIVATE_API_H_
diff --git a/ppapi/thunk/ppb_tcp_server_socket_private_thunk.cc b/ppapi/thunk/ppb_tcp_server_socket_private_thunk.cc
new file mode 100644
index 0000000..c4b6bd8
--- /dev/null
+++ b/ppapi/thunk/ppb_tcp_server_socket_private_thunk.cc
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/private/ppb_tcp_server_socket_private.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_tcp_server_socket_private_api.h"
+#include "ppapi/thunk/resource_creation_api.h"
+#include "ppapi/thunk/thunk.h"
+
+namespace ppapi {
+namespace thunk {
+
+namespace {
+
+typedef EnterResource<PPB_TCPServerSocket_Private_API> EnterTCPServer;
+
+PP_Resource Create(PP_Instance instance) {
+ EnterFunction<ResourceCreationAPI> enter(instance, true);
+ if (enter.failed())
+ return 0;
+ return enter.functions()->CreateTCPServerSocketPrivate(instance);
+}
+
+PP_Bool IsTCPServerSocket(PP_Resource resource) {
+ EnterTCPServer enter(resource, false);
+ return PP_FromBool(enter.succeeded());
+}
+
+int32_t Listen(PP_Resource tcp_server_socket,
+ const PP_NetAddress_Private* addr,
+ int32_t backlog,
+ PP_CompletionCallback callback) {
+ EnterTCPServer enter(tcp_server_socket, callback, true);
+ if (enter.failed())
+ return enter.retval();
+ return enter.SetResult(enter.object()->Listen(addr, backlog, callback));
+}
+
+int32_t Accept(PP_Resource tcp_server_socket,
+ PP_Resource* tcp_socket,
+ PP_CompletionCallback callback) {
+ EnterTCPServer enter(tcp_server_socket, callback, true);
+ if (enter.failed())
+ return enter.retval();
+ return enter.SetResult(enter.object()->Accept(tcp_socket, callback));
+}
+
+void StopListening(PP_Resource tcp_server_socket) {
+ EnterTCPServer enter(tcp_server_socket, true);
+ if (enter.succeeded())
+ enter.object()->StopListening();
+}
+
+const PPB_TCPServerSocket_Private g_ppb_tcp_server_socket_thunk = {
+ Create,
+ IsTCPServerSocket,
+ Listen,
+ Accept,
+ StopListening
+};
+
+} // namespace
+
+const PPB_TCPServerSocket_Private* GetPPB_TCPServerSocket_Private_0_1_Thunk() {
+ return &g_ppb_tcp_server_socket_thunk;
+}
+
+} // namespace thunk
+} // namespace ppapi
diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h
index 05c90c2..d567a18 100644
--- a/ppapi/thunk/resource_creation_api.h
+++ b/ppapi/thunk/resource_creation_api.h
@@ -108,6 +108,7 @@ class ResourceCreationAPI {
uint32_t size) = 0;
virtual PP_Resource CreateScrollbar(PP_Instance instance,
PP_Bool vertical) = 0;
+ virtual PP_Resource CreateTCPServerSocketPrivate(PP_Instance instance) = 0;
virtual PP_Resource CreateTCPSocketPrivate(PP_Instance instace) = 0;
virtual PP_Resource CreateTransport(PP_Instance instance,
const char* name,
diff --git a/ppapi/thunk/thunk.h b/ppapi/thunk/thunk.h
index 703ab02..f7ac751 100644
--- a/ppapi/thunk/thunk.h
+++ b/ppapi/thunk/thunk.h
@@ -12,6 +12,7 @@
#include "ppapi/c/private/ppb_flash_net_connector.h"
#include "ppapi/c/private/ppb_flash_fullscreen.h"
#include "ppapi/c/private/ppb_instance_private.h"
+#include "ppapi/c/private/ppb_tcp_server_socket_private.h"
#include "ppapi/c/private/ppb_tcp_socket_private.h"
#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/trusted/ppb_audio_input_trusted_dev.h"
@@ -71,6 +72,8 @@ PPAPI_THUNK_EXPORT const PPB_ImageDataTrusted_0_4*
GetPPB_ImageDataTrusted_0_4_Thunk();
PPAPI_THUNK_EXPORT const PPB_Instance_Private_0_1*
GetPPB_Instance_Private_0_1_Thunk();
+PPAPI_THUNK_EXPORT const PPB_TCPServerSocket_Private_0_1*
+ GetPPB_TCPServerSocket_Private_0_1_Thunk();
PPAPI_THUNK_EXPORT const PPB_TCPSocket_Private_0_3*
GetPPB_TCPSocket_Private_0_3_Thunk();
PPAPI_THUNK_EXPORT const PPB_UDPSocket_Private_0_2*
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index 36cbcde..d294167 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -299,6 +299,8 @@
'../plugins/ppapi/ppb_proxy_impl.h',
'../plugins/ppapi/ppb_scrollbar_impl.cc',
'../plugins/ppapi/ppb_scrollbar_impl.h',
+ '../plugins/ppapi/ppb_tcp_server_socket_private_impl.cc',
+ '../plugins/ppapi/ppb_tcp_server_socket_private_impl.h',
'../plugins/ppapi/ppb_tcp_socket_private_impl.cc',
'../plugins/ppapi/ppb_tcp_socket_private_impl.h',
'../plugins/ppapi/ppb_text_input_impl.cc',
diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc
index ea6a9f2..c62f39e 100644
--- a/webkit/plugins/ppapi/mock_plugin_delegate.cc
+++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc
@@ -275,6 +275,10 @@ void MockPluginDelegate::TCPSocketWrite(uint32 socket_id,
void MockPluginDelegate::TCPSocketDisconnect(uint32 socket_id) {
}
+void MockPluginDelegate::RegisterTCPSocket(PPB_TCPSocket_Private_Impl* socket,
+ uint32 socket_id) {
+}
+
uint32 MockPluginDelegate::UDPSocketCreate() {
return 0;
}
@@ -296,6 +300,20 @@ void MockPluginDelegate::UDPSocketSendTo(uint32 socket_id,
void MockPluginDelegate::UDPSocketClose(uint32 socket_id) {
}
+void MockPluginDelegate::TCPServerSocketListen(
+ PPB_TCPServerSocket_Private_Impl* socket,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) {
+}
+
+void MockPluginDelegate::TCPServerSocketAccept(uint32 real_socket_id) {
+}
+
+void MockPluginDelegate::TCPServerSocketStopListening(uint32 real_socket_id,
+ uint32 temp_socket_id) {
+}
+
int32_t MockPluginDelegate::ShowContextMenu(
PluginInstance* instance,
webkit::ppapi::PPB_Flash_Menu_Impl* menu,
diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.h b/webkit/plugins/ppapi/mock_plugin_delegate.h
index cb40de7..8b35aff 100644
--- a/webkit/plugins/ppapi/mock_plugin_delegate.h
+++ b/webkit/plugins/ppapi/mock_plugin_delegate.h
@@ -122,6 +122,8 @@ class MockPluginDelegate : public PluginDelegate {
virtual void TCPSocketRead(uint32 socket_id, int32_t bytes_to_read);
virtual void TCPSocketWrite(uint32 socket_id, const std::string& buffer);
virtual void TCPSocketDisconnect(uint32 socket_id);
+ virtual void RegisterTCPSocket(PPB_TCPSocket_Private_Impl* socket,
+ uint32 socket_id);
virtual uint32 UDPSocketCreate();
virtual void UDPSocketBind(PPB_UDPSocket_Private_Impl* socket,
uint32 socket_id,
@@ -131,6 +133,13 @@ class MockPluginDelegate : public PluginDelegate {
const std::string& buffer,
const PP_NetAddress_Private& addr);
virtual void UDPSocketClose(uint32 socket_id);
+ virtual void TCPServerSocketListen(PPB_TCPServerSocket_Private_Impl* socket,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog);
+ virtual void TCPServerSocketAccept(uint32 real_socket_id);
+ virtual void TCPServerSocketStopListening(uint32 real_socket_id,
+ uint32 temp_socket_id);
virtual int32_t ShowContextMenu(
PluginInstance* instance,
webkit::ppapi::PPB_Flash_Menu_Impl* menu,
diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h
index fe7d45d..973c6e4 100644
--- a/webkit/plugins/ppapi/plugin_delegate.h
+++ b/webkit/plugins/ppapi/plugin_delegate.h
@@ -82,6 +82,7 @@ class PluginModule;
class PPB_Broker_Impl;
class PPB_Flash_Menu_Impl;
class PPB_Flash_NetConnector_Impl;
+class PPB_TCPServerSocket_Private_Impl;
class PPB_TCPSocket_Private_Impl;
class PPB_UDPSocket_Private_Impl;
@@ -452,6 +453,8 @@ class PluginDelegate {
virtual void TCPSocketRead(uint32 socket_id, int32_t bytes_to_read) = 0;
virtual void TCPSocketWrite(uint32 socket_id, const std::string& buffer) = 0;
virtual void TCPSocketDisconnect(uint32 socket_id) = 0;
+ virtual void RegisterTCPSocket(PPB_TCPSocket_Private_Impl* socket,
+ uint32 socket_id) = 0;
// For PPB_UDPSocket_Private.
virtual uint32 UDPSocketCreate() = 0;
@@ -464,6 +467,15 @@ class PluginDelegate {
const PP_NetAddress_Private& addr) = 0;
virtual void UDPSocketClose(uint32 socket_id) = 0;
+ // For PPB_TCPServerSocket_Private.
+ virtual void TCPServerSocketListen(PPB_TCPServerSocket_Private_Impl* socket,
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) = 0;
+ virtual void TCPServerSocketAccept(uint32 real_socket_id) = 0;
+ virtual void TCPServerSocketStopListening(uint32 real_socket_id,
+ uint32 temp_socket_id) = 0;
+
// Show the given context menu at the given position (in the plugin's
// coordinates).
virtual int32_t ShowContextMenu(
diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc
index 195046a..0a5d457 100644
--- a/webkit/plugins/ppapi/plugin_module.cc
+++ b/webkit/plugins/ppapi/plugin_module.cc
@@ -76,6 +76,7 @@
#include "ppapi/c/private/ppb_instance_private.h"
#include "ppapi/c/private/ppb_pdf.h"
#include "ppapi/c/private/ppb_proxy_private.h"
+#include "ppapi/c/private/ppb_tcp_server_socket_private.h"
#include "ppapi/c/private/ppb_tcp_socket_private.h"
#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/private/ppb_uma_private.h"
@@ -343,6 +344,8 @@ const void* GetInterface(const char* name) {
return ::ppapi::PPB_OpenGLES2_Shared::GetInterface();
if (strcmp(name, PPB_PROXY_PRIVATE_INTERFACE) == 0)
return PPB_Proxy_Impl::GetInterface();
+ if (strcmp(name, PPB_TCPSERVERSOCKET_PRIVATE_INTERFACE) == 0)
+ return ::ppapi::thunk::GetPPB_TCPServerSocket_Private_0_1_Thunk();
if (strcmp(name, PPB_UMA_PRIVATE_INTERFACE) == 0)
return PPB_UMA_Private_Impl::GetInterface();
if (strcmp(name, PPB_URLLOADERTRUSTED_INTERFACE_0_3) == 0)
diff --git a/webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.cc b/webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.cc
new file mode 100644
index 0000000..213b4bf
--- /dev/null
+++ b/webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.cc
@@ -0,0 +1,86 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.h"
+
+#include "base/logging.h"
+#include "webkit/plugins/ppapi/host_globals.h"
+#include "webkit/plugins/ppapi/plugin_delegate.h"
+#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+#include "webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h"
+#include "webkit/plugins/ppapi/resource_helper.h"
+
+namespace webkit {
+namespace ppapi {
+
+PPB_TCPServerSocket_Private_Impl::PPB_TCPServerSocket_Private_Impl(
+ PP_Instance instance)
+ : ::ppapi::PPB_TCPServerSocket_Shared(instance) {
+}
+
+PPB_TCPServerSocket_Private_Impl::~PPB_TCPServerSocket_Private_Impl() {
+ StopListening();
+}
+
+PP_Resource PPB_TCPServerSocket_Private_Impl::CreateResource(
+ PP_Instance instance) {
+ PPB_TCPServerSocket_Private_Impl* socket =
+ new PPB_TCPServerSocket_Private_Impl(instance);
+ return socket->GetReference();
+}
+
+void PPB_TCPServerSocket_Private_Impl::OnAcceptCompleted(
+ bool succeeded,
+ uint32 tcp_socket_id,
+ const PP_NetAddress_Private& local_addr,
+ const PP_NetAddress_Private& remote_addr) {
+ if (!::ppapi::TrackedCallback::IsPending(accept_callback_) ||
+ !tcp_socket_buffer_) {
+ NOTREACHED();
+ return;
+ }
+
+ if (succeeded) {
+ *tcp_socket_buffer_ =
+ PPB_TCPSocket_Private_Impl::CreateConnectedSocket(pp_instance(),
+ tcp_socket_id,
+ local_addr,
+ remote_addr);
+ }
+ tcp_socket_buffer_ = NULL;
+
+ ::ppapi::TrackedCallback::ClearAndRun(&accept_callback_,
+ succeeded ? PP_OK : PP_ERROR_FAILED);
+}
+
+void PPB_TCPServerSocket_Private_Impl::SendListen(
+ uint32 temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) {
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
+ if (!plugin_delegate)
+ return;
+
+ plugin_delegate->TCPServerSocketListen(this, temp_socket_id, addr, backlog);
+}
+
+void PPB_TCPServerSocket_Private_Impl::SendAccept() {
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
+ if (!plugin_delegate)
+ return;
+
+ plugin_delegate->TCPServerSocketAccept(real_socket_id_);
+}
+
+void PPB_TCPServerSocket_Private_Impl::SendStopListening() {
+ PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
+ if (!plugin_delegate)
+ return;
+
+ plugin_delegate->TCPServerSocketStopListening(real_socket_id_,
+ temp_socket_id_);
+}
+
+} // namespace ppapi
+} // namespace webkit
diff --git a/webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.h b/webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.h
new file mode 100644
index 0000000..6533e61
--- /dev/null
+++ b/webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_PLUGINS_PPAPI_PPB_TCP_SERVER_SOCKET_PRIVATE_IMPL_H_
+#define WEBKIT_PLUGINS_PPAPI_PPB_TCP_SERVER_SOCKET_PRIVATE_IMPL_H_
+
+#include "base/compiler_specific.h"
+#include "ppapi/shared_impl/private/ppb_tcp_server_socket_shared.h"
+
+namespace webkit {
+namespace ppapi {
+
+class PPB_TCPServerSocket_Private_Impl
+ : public ::ppapi::PPB_TCPServerSocket_Shared {
+ public:
+ static PP_Resource CreateResource(PP_Instance instance);
+
+ virtual void OnAcceptCompleted(
+ bool succeeded,
+ uint32 tcp_socket_id,
+ const PP_NetAddress_Private& local_addr,
+ const PP_NetAddress_Private& remote_addr) OVERRIDE;
+
+ virtual void SendListen(uint32_t temp_socket_id,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) OVERRIDE;
+ virtual void SendAccept() OVERRIDE;
+ virtual void SendStopListening() OVERRIDE;
+
+ private:
+ PPB_TCPServerSocket_Private_Impl(PP_Instance instance);
+ virtual ~PPB_TCPServerSocket_Private_Impl();
+
+ DISALLOW_COPY_AND_ASSIGN(PPB_TCPServerSocket_Private_Impl);
+};
+
+} // namespace ppapi
+} // namespace webkit
+
+#endif // WEBKIT_PLUGINS_PPAPI_PPB_TCP_SERVER_SOCKET_PRIVATE_IMPL_H_
diff --git a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc
index 61fc83c..06489aa 100644
--- a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc
+++ b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -22,11 +22,10 @@ PPB_TCPSocket_Private_Impl::~PPB_TCPSocket_Private_Impl() {
}
PP_Resource PPB_TCPSocket_Private_Impl::CreateResource(PP_Instance instance) {
- PluginInstance* plugin_instance = HostGlobals::Get()->GetInstance(instance);
- if (!plugin_instance)
+ PluginDelegate* plugin_delegate = GetPluginDelegate(instance);
+ if (!plugin_delegate)
return 0;
- PluginDelegate* plugin_delegate = plugin_instance->delegate();
uint32 socket_id = plugin_delegate->TCPSocketCreate();
if (!socket_id)
return 0;
@@ -34,6 +33,27 @@ PP_Resource PPB_TCPSocket_Private_Impl::CreateResource(PP_Instance instance) {
return (new PPB_TCPSocket_Private_Impl(instance, socket_id))->GetReference();
}
+PP_Resource PPB_TCPSocket_Private_Impl::CreateConnectedSocket(
+ PP_Instance instance,
+ uint32 socket_id,
+ const PP_NetAddress_Private& local_addr,
+ const PP_NetAddress_Private& remote_addr) {
+ PluginDelegate* plugin_delegate = GetPluginDelegate(instance);
+ if (!plugin_delegate)
+ return 0;
+
+ PPB_TCPSocket_Private_Impl* socket =
+ new PPB_TCPSocket_Private_Impl(instance, socket_id);
+
+ socket->connection_state_ = PPB_TCPSocket_Private_Impl::CONNECTED;
+ socket->local_addr_ = local_addr;
+ socket->remote_addr_ = remote_addr;
+
+ plugin_delegate->RegisterTCPSocket(socket, socket_id);
+
+ return socket->GetReference();
+}
+
void PPB_TCPSocket_Private_Impl::SendConnect(const std::string& host,
uint16_t port) {
PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
@@ -87,5 +107,13 @@ void PPB_TCPSocket_Private_Impl::SendDisconnect() {
plugin_delegate->TCPSocketDisconnect(socket_id_);
}
+PluginDelegate* PPB_TCPSocket_Private_Impl::GetPluginDelegate(
+ PP_Instance instance) {
+ PluginInstance* plugin_instance = HostGlobals::Get()->GetInstance(instance);
+ if (!plugin_instance)
+ return NULL;
+ return plugin_instance->delegate();
+}
+
} // namespace ppapi
} // namespace webkit
diff --git a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h
index ba86518..fdc298c 100644
--- a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h
+++ b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,9 +11,16 @@
namespace webkit {
namespace ppapi {
+class PluginDelegate;
+
class PPB_TCPSocket_Private_Impl : public ::ppapi::TCPSocketPrivateImpl {
public:
static PP_Resource CreateResource(PP_Instance instance);
+ static PP_Resource CreateConnectedSocket(
+ PP_Instance instance,
+ uint32 socket_id,
+ const PP_NetAddress_Private& local_addr,
+ const PP_NetAddress_Private& remote_addr);
virtual void SendConnect(const std::string& host, uint16_t port) OVERRIDE;
virtual void SendConnectWithNetAddress(
@@ -28,6 +35,8 @@ class PPB_TCPSocket_Private_Impl : public ::ppapi::TCPSocketPrivateImpl {
PPB_TCPSocket_Private_Impl(PP_Instance instance, uint32 socket_id);
virtual ~PPB_TCPSocket_Private_Impl();
+ static PluginDelegate* GetPluginDelegate(PP_Instance instance);
+
DISALLOW_COPY_AND_ASSIGN(PPB_TCPSocket_Private_Impl);
};
diff --git a/webkit/plugins/ppapi/resource_creation_impl.cc b/webkit/plugins/ppapi/resource_creation_impl.cc
index 120c587..4ef430e 100644
--- a/webkit/plugins/ppapi/resource_creation_impl.cc
+++ b/webkit/plugins/ppapi/resource_creation_impl.cc
@@ -27,6 +27,7 @@
#include "webkit/plugins/ppapi/ppb_graphics_3d_impl.h"
#include "webkit/plugins/ppapi/ppb_image_data_impl.h"
#include "webkit/plugins/ppapi/ppb_scrollbar_impl.h"
+#include "webkit/plugins/ppapi/ppb_tcp_server_socket_private_impl.h"
#include "webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h"
#include "webkit/plugins/ppapi/ppb_transport_impl.h"
#include "webkit/plugins/ppapi/ppb_udp_socket_private_impl.h"
@@ -257,6 +258,11 @@ PP_Resource ResourceCreationImpl::CreateResourceArray(
return object->GetReference();
}
+PP_Resource ResourceCreationImpl::CreateTCPServerSocketPrivate(
+ PP_Instance instance) {
+ return PPB_TCPServerSocket_Private_Impl::CreateResource(instance);
+}
+
PP_Resource ResourceCreationImpl::CreateTCPSocketPrivate(PP_Instance instance) {
return PPB_TCPSocket_Private_Impl::CreateResource(instance);
}
diff --git a/webkit/plugins/ppapi/resource_creation_impl.h b/webkit/plugins/ppapi/resource_creation_impl.h
index d4595ae..f7c2a70 100644
--- a/webkit/plugins/ppapi/resource_creation_impl.h
+++ b/webkit/plugins/ppapi/resource_creation_impl.h
@@ -93,7 +93,10 @@ class ResourceCreationImpl : public ::ppapi::FunctionGroupBase,
uint32_t size) OVERRIDE;
virtual PP_Resource CreateScrollbar(PP_Instance instance,
PP_Bool vertical) OVERRIDE;
+ virtual PP_Resource CreateTCPServerSocketPrivate(
+ PP_Instance instance) OVERRIDE;
virtual PP_Resource CreateTCPSocketPrivate(PP_Instance instance) OVERRIDE;
+
virtual PP_Resource CreateTransport(PP_Instance instance,
const char* name,
PP_TransportType type) OVERRIDE;