diff options
23 files changed, 564 insertions, 321 deletions
diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.cc b/content/browser/renderer_host/pepper/pepper_message_filter.cc index 8db9bc4..573ff03 100644 --- a/content/browser/renderer_host/pepper/pepper_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_message_filter.cc @@ -37,6 +37,7 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/api_id.h" #include "ppapi/shared_impl/private/net_address_private_impl.h" +#include "ppapi/shared_impl/socket_option_data.h" using ppapi::NetAddressPrivateImpl; @@ -96,11 +97,8 @@ PepperMessageFilter::PepperMessageFilter( void PepperMessageFilter::OverrideThreadForMessage( const IPC::Message& message, BrowserThread::ID* thread) { - if (message.type() == PpapiHostMsg_PPBTCPServerSocket_Listen::ID || - message.type() == PpapiHostMsg_PPBTCPSocket_Connect::ID || - message.type() == PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress::ID) { + if (message.type() == PpapiHostMsg_PPBTCPServerSocket_Listen::ID) *thread = BrowserThread::UI; - } } bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg, @@ -109,6 +107,8 @@ bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg, IPC_BEGIN_MESSAGE_MAP_EX(PepperMessageFilter, msg, *message_was_ok) // TCP messages. IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Create, OnTCPCreate) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_CreatePrivate, + OnTCPCreatePrivate) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Connect, OnTCPConnect) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress, OnTCPConnectWithNetAddress) @@ -117,8 +117,7 @@ bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg, IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Read, OnTCPRead) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Write, OnTCPWrite) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Disconnect, OnTCPDisconnect) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_SetBoolOption, - OnTCPSetBoolOption) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_SetOption, OnTCPSetOption) // TCP Server messages. IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPServerSocket_Listen, @@ -170,16 +169,19 @@ uint32 PepperMessageFilter::AddAcceptedTCPSocket( int32 routing_id, uint32 plugin_dispatcher_id, net::StreamSocket* socket) { - scoped_ptr<net::StreamSocket> s(socket); + scoped_ptr<net::StreamSocket> s(socket); uint32 tcp_socket_id = GenerateSocketID(); if (tcp_socket_id != kInvalidSocketID) { + // Currently all TCP sockets created this way correspond to + // PPB_TCPSocket_Private. tcp_sockets_[tcp_socket_id] = linked_ptr<PepperTCPSocket>( new PepperTCPSocket(this, routing_id, plugin_dispatcher_id, tcp_socket_id, - s.release())); + s.release(), + true /* private_api */)); } return tcp_socket_id; } @@ -205,80 +207,103 @@ PepperMessageFilter::~PepperMessageFilter() { void PepperMessageFilter::OnTCPCreate(int32 routing_id, uint32 plugin_dispatcher_id, uint32* socket_id) { - *socket_id = GenerateSocketID(); - if (*socket_id == kInvalidSocketID) - return; + CreateTCPSocket(routing_id, plugin_dispatcher_id, false, socket_id); +} - tcp_sockets_[*socket_id] = linked_ptr<PepperTCPSocket>( - new PepperTCPSocket(this, routing_id, plugin_dispatcher_id, *socket_id)); +void PepperMessageFilter::OnTCPCreatePrivate(int32 routing_id, + uint32 plugin_dispatcher_id, + uint32* socket_id) { + CreateTCPSocket(routing_id, plugin_dispatcher_id, true, socket_id); } void PepperMessageFilter::OnTCPConnect(int32 routing_id, uint32 socket_id, const std::string& host, uint16_t port) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); + if (iter == tcp_sockets_.end()) { + NOTREACHED(); + return; + } + + // This is only supported by PPB_TCPSocket_Private. + if (!iter->second->private_api()) { + NOTREACHED(); + return; + } + content::SocketPermissionRequest params( content::SocketPermissionRequest::TCP_CONNECT, host, port); - bool allowed = CanUseSocketAPIs(routing_id, params); - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::UI, FROM_HERE, + base::Bind(&PepperMessageFilter::CanUseSocketAPIs, this, + routing_id, params, true /* private_api */), base::Bind(&PepperMessageFilter::DoTCPConnect, this, - allowed, routing_id, socket_id, host, port)); + routing_id, socket_id, host, port)); } -void PepperMessageFilter::DoTCPConnect(bool allowed, - int32 routing_id, +void PepperMessageFilter::DoTCPConnect(int32 routing_id, uint32 socket_id, const std::string& host, - uint16_t port) { + uint16_t port, + bool allowed) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); if (iter == tcp_sockets_.end()) { // Due to current permission check process (IO -> UI -> IO) some - // calls to TCPSocketPrivate interface can be intermixed (like - // Connect and Close). So, NOTREACHED() is not needed there. + // calls to the TCP socket interface can be intermixed (like + // Connect and Close). So, NOTREACHED() is not appropriate here. return; } if (routing_id == iter->second->routing_id() && allowed) iter->second->Connect(host, port); else - iter->second->SendConnectACKError(); + iter->second->SendConnectACKError(PP_ERROR_NOACCESS); } void PepperMessageFilter::OnTCPConnectWithNetAddress( int32 routing_id, uint32 socket_id, const PP_NetAddress_Private& net_addr) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - bool allowed = CanUseSocketAPIs( - routing_id, + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); + if (iter == tcp_sockets_.end()) { + NOTREACHED(); + return; + } + + content::SocketPermissionRequest params = pepper_socket_utils::CreateSocketPermissionRequest( - content::SocketPermissionRequest::TCP_CONNECT, net_addr)); - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + content::SocketPermissionRequest::TCP_CONNECT, net_addr); + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::UI, FROM_HERE, + base::Bind(&PepperMessageFilter::CanUseSocketAPIs, this, + routing_id, params, iter->second->private_api()), base::Bind(&PepperMessageFilter::DoTCPConnectWithNetAddress, this, - allowed, routing_id, socket_id, net_addr)); + routing_id, socket_id, net_addr)); } void PepperMessageFilter::DoTCPConnectWithNetAddress( - bool allowed, int32 routing_id, uint32 socket_id, - const PP_NetAddress_Private& net_addr) { + const PP_NetAddress_Private& net_addr, + bool allowed) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); if (iter == tcp_sockets_.end()) { // Due to current permission check process (IO -> UI -> IO) some - // calls to TCPSocketPrivate interface can be intermixed (like + // calls to the TCP socket interface can be intermixed (like // ConnectWithNetAddress and Close). So, NOTREACHED() is not - // needed there. + // appropriate here. return; } if (routing_id == iter->second->routing_id() && allowed) iter->second->ConnectWithNetAddress(net_addr); else - iter->second->SendConnectACKError(); + iter->second->SendConnectACKError(PP_ERROR_NOACCESS); } void PepperMessageFilter::OnTCPSSLHandshake( @@ -293,6 +318,12 @@ void PepperMessageFilter::OnTCPSSLHandshake( return; } + // This is only supported by PPB_TCPSocket_Private. + if (!iter->second->private_api()) { + NOTREACHED(); + return; + } + iter->second->SSLHandshake(server_name, server_port, trusted_certs, untrusted_certs); } @@ -331,16 +362,16 @@ void PepperMessageFilter::OnTCPDisconnect(uint32 socket_id) { tcp_sockets_.erase(iter); } -void PepperMessageFilter::OnTCPSetBoolOption(uint32 socket_id, - uint32_t name, - bool value) { +void PepperMessageFilter::OnTCPSetOption(uint32 socket_id, + PP_TCPSocket_Option_Dev name, + const ppapi::SocketOptionData& value) { TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); if (iter == tcp_sockets_.end()) { NOTREACHED(); return; } - iter->second->SetBoolOption(name, value); + iter->second->SetOption(name, value); } void PepperMessageFilter::OnTCPServerListen(int32 routing_id, @@ -352,7 +383,8 @@ void PepperMessageFilter::OnTCPServerListen(int32 routing_id, bool allowed = CanUseSocketAPIs( routing_id, pepper_socket_utils::CreateSocketPermissionRequest( - content::SocketPermissionRequest::TCP_LISTEN, addr)); + content::SocketPermissionRequest::TCP_LISTEN, addr), + true /* private_api */); BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&PepperMessageFilter::DoTCPServerListen, this, @@ -470,8 +502,10 @@ uint32 PepperMessageFilter::GenerateSocketID() { return socket_id; } -bool PepperMessageFilter::CanUseSocketAPIs(int32 render_id, - const content::SocketPermissionRequest& params) { +bool PepperMessageFilter::CanUseSocketAPIs( + int32 render_id, + const content::SocketPermissionRequest& params, + bool private_api) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // External plugins always get their own PepperMessageFilter, initialized with @@ -487,7 +521,7 @@ bool PepperMessageFilter::CanUseSocketAPIs(int32 render_id, RenderViewHostImpl::FromID(process_id_, render_id); return pepper_socket_utils::CanUseSocketAPIs(external_plugin, - true, + private_api, params, render_view_host); } @@ -539,4 +573,17 @@ void PepperMessageFilter::SendNetworkList( } } +void PepperMessageFilter::CreateTCPSocket(int32 routing_id, + uint32 plugin_dispatcher_id, + bool private_api, + uint32* socket_id) { + *socket_id = GenerateSocketID(); + if (*socket_id == kInvalidSocketID) + return; + + tcp_sockets_[*socket_id] = linked_ptr<PepperTCPSocket>( + new PepperTCPSocket(this, routing_id, plugin_dispatcher_id, *socket_id, + private_api)); +} + } // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.h b/content/browser/renderer_host/pepper/pepper_message_filter.h index a745768..02c7abb 100644 --- a/content/browser/renderer_host/pepper/pepper_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_message_filter.h @@ -23,6 +23,7 @@ #include "net/http/transport_security_state.h" #include "net/socket/stream_socket.h" #include "net/ssl/ssl_config_service.h" +#include "ppapi/c/dev/ppb_tcp_socket_dev.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_stdint.h" #include "ppapi/c/private/ppb_flash.h" @@ -42,6 +43,7 @@ class HostResolver; namespace ppapi { class PPB_X509Certificate_Fields; +class SocketOptionData; } namespace content { @@ -125,6 +127,9 @@ class PepperMessageFilter void OnTCPCreate(int32 routing_id, uint32 plugin_dispatcher_id, uint32* socket_id); + void OnTCPCreatePrivate(int32 routing_id, + uint32 plugin_dispatcher_id, + uint32* socket_id); void OnTCPConnect(int32 routing_id, uint32 socket_id, const std::string& host, @@ -141,7 +146,9 @@ class PepperMessageFilter void OnTCPRead(uint32 socket_id, int32_t bytes_to_read); void OnTCPWrite(uint32 socket_id, const std::string& data); void OnTCPDisconnect(uint32 socket_id); - void OnTCPSetBoolOption(uint32 socket_id, uint32_t name, bool value); + void OnTCPSetOption(uint32 socket_id, + PP_TCPSocket_Option_Dev name, + const ppapi::SocketOptionData& value); void OnTCPServerListen(int32 routing_id, uint32 plugin_dispatcher_id, PP_Resource socket_resource, @@ -153,15 +160,15 @@ class PepperMessageFilter void OnNetworkMonitorStart(uint32 plugin_dispatcher_id); void OnNetworkMonitorStop(uint32 plugin_dispatcher_id); - void DoTCPConnect(bool allowed, - int32 routing_id, + void DoTCPConnect(int32 routing_id, uint32 socket_id, const std::string& host, - uint16_t port); - void DoTCPConnectWithNetAddress(bool allowed, - int32 routing_id, + uint16_t port, + bool allowed); + void DoTCPConnectWithNetAddress(int32 routing_id, uint32 socket_id, - const PP_NetAddress_Private& net_addr); + const PP_NetAddress_Private& net_addr, + bool allowed); void DoTCPServerListen(bool allowed, int32 routing_id, uint32 plugin_dispatcher_id, @@ -177,12 +184,16 @@ class PepperMessageFilter // Return true if render with given ID can use socket APIs. bool CanUseSocketAPIs(int32 render_id, - const content::SocketPermissionRequest& params); + const content::SocketPermissionRequest& params, + bool private_api); void GetAndSendNetworkList(); void DoGetNetworkList(); void SendNetworkList(scoped_ptr<net::NetworkInterfaceList> list); - + void CreateTCPSocket(int32 routing_id, + uint32 plugin_dispatcher_id, + bool private_api, + uint32* socket_id); enum PluginType { PLUGIN_TYPE_IN_PROCESS, PLUGIN_TYPE_OUT_OF_PROCESS, diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket.cc b/content/browser/renderer_host/pepper/pepper_tcp_socket.cc index 1f58e08..2dfb41b 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_socket.cc +++ b/content/browser/renderer_host/pepper/pepper_tcp_socket.cc @@ -25,11 +25,14 @@ #include "net/socket/client_socket_handle.h" #include "net/socket/ssl_client_socket.h" #include "net/socket/tcp_client_socket.h" +#include "ppapi/host/error_conversion.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/private/net_address_private_impl.h" #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" -#include "ppapi/shared_impl/private/tcp_socket_private_impl.h" +#include "ppapi/shared_impl/socket_option_data.h" +#include "ppapi/shared_impl/tcp_socket_shared.h" +using ppapi::host::NetErrorToPepperError; using ppapi::NetAddressPrivateImpl; namespace content { @@ -38,11 +41,13 @@ PepperTCPSocket::PepperTCPSocket( PepperMessageFilter* manager, int32 routing_id, uint32 plugin_dispatcher_id, - uint32 socket_id) + uint32 socket_id, + bool private_api) : manager_(manager), routing_id_(routing_id), plugin_dispatcher_id_(plugin_dispatcher_id), socket_id_(socket_id), + private_api_(private_api), connection_state_(BEFORE_CONNECT), end_of_file_reached_(false) { DCHECK(manager); @@ -53,11 +58,13 @@ PepperTCPSocket::PepperTCPSocket( int32 routing_id, uint32 plugin_dispatcher_id, uint32 socket_id, - net::StreamSocket* socket) + net::StreamSocket* socket, + bool private_api) : manager_(manager), routing_id_(routing_id), plugin_dispatcher_id_(plugin_dispatcher_id), socket_id_(socket_id), + private_api_(private_api), connection_state_(CONNECTED), end_of_file_reached_(false), socket_(socket) { @@ -74,7 +81,7 @@ void PepperTCPSocket::Connect(const std::string& host, uint16_t port) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (connection_state_ != BEFORE_CONNECT) { - SendConnectACKError(); + SendConnectACKError(PP_ERROR_FAILED); return; } @@ -82,25 +89,28 @@ void PepperTCPSocket::Connect(const std::string& host, uint16_t port) { net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port)); resolver_.reset(new net::SingleRequestHostResolver( manager_->GetHostResolver())); - int result = resolver_->Resolve( + int net_result = resolver_->Resolve( request_info, &address_list_, base::Bind(&PepperTCPSocket::OnResolveCompleted, base::Unretained(this)), net::BoundNetLog()); - if (result != net::ERR_IO_PENDING) - OnResolveCompleted(result); + if (net_result != net::ERR_IO_PENDING) + OnResolveCompleted(net_result); } void PepperTCPSocket::ConnectWithNetAddress( const PP_NetAddress_Private& net_addr) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (connection_state_ != BEFORE_CONNECT) { + SendConnectACKError(PP_ERROR_FAILED); + return; + } + net::IPAddressNumber address; int port; - if (connection_state_ != BEFORE_CONNECT || - !NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr, - &address, + if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr, &address, &port)) { - SendConnectACKError(); + SendConnectACKError(PP_ERROR_ADDRESS_INVALID); return; } @@ -147,49 +157,59 @@ void PepperTCPSocket::SSLHandshake( return; } - int result = socket_->Connect( + int net_result = socket_->Connect( base::Bind(&PepperTCPSocket::OnSSLHandshakeCompleted, base::Unretained(this))); - if (result != net::ERR_IO_PENDING) - OnSSLHandshakeCompleted(result); + if (net_result != net::ERR_IO_PENDING) + OnSSLHandshakeCompleted(net_result); } void PepperTCPSocket::Read(int32 bytes_to_read) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (!IsConnected() || end_of_file_reached_ || read_buffer_.get() || - bytes_to_read <= 0) { - SendReadACKError(); + if (!IsConnected() || end_of_file_reached_) { + SendReadACKError(PP_ERROR_FAILED); return; } - if (bytes_to_read > ppapi::TCPSocketPrivateImpl::kMaxReadSize) { - NOTREACHED(); - bytes_to_read = ppapi::TCPSocketPrivateImpl::kMaxReadSize; + if (read_buffer_.get()) { + SendReadACKError(PP_ERROR_INPROGRESS); + return; + } + + if (bytes_to_read <= 0 || + bytes_to_read > ppapi::TCPSocketShared::kMaxReadSize) { + SendReadACKError(PP_ERROR_BADARGUMENT); + return; } read_buffer_ = new net::IOBuffer(bytes_to_read); - int result = socket_->Read( + int net_result = socket_->Read( read_buffer_.get(), bytes_to_read, base::Bind(&PepperTCPSocket::OnReadCompleted, base::Unretained(this))); - if (result != net::ERR_IO_PENDING) - OnReadCompleted(result); + if (net_result != net::ERR_IO_PENDING) + OnReadCompleted(net_result); } void PepperTCPSocket::Write(const std::string& data) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (!IsConnected() || write_buffer_base_.get() || write_buffer_.get() || - data.empty()) { - SendWriteACKError(); + if (!IsConnected()) { + SendWriteACKError(PP_ERROR_FAILED); return; } - int data_size = data.size(); - if (data_size > ppapi::TCPSocketPrivateImpl::kMaxWriteSize) { - NOTREACHED(); - data_size = ppapi::TCPSocketPrivateImpl::kMaxWriteSize; + if (write_buffer_base_.get() || write_buffer_.get()) { + SendWriteACKError(PP_ERROR_INPROGRESS); + return; + } + + size_t data_size = data.size(); + if (data_size == 0 || + data_size > static_cast<size_t>(ppapi::TCPSocketShared::kMaxWriteSize)) { + SendWriteACKError(PP_ERROR_BADARGUMENT); + return; } write_buffer_base_ = new net::IOBuffer(data_size); @@ -199,26 +219,62 @@ void PepperTCPSocket::Write(const std::string& data) { DoWrite(); } -void PepperTCPSocket::SetBoolOption(uint32_t name, bool value) { +void PepperTCPSocket::SetOption(PP_TCPSocket_Option_Dev name, + const ppapi::SocketOptionData& value) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(socket_.get()); + + if (!IsConnected() || IsSsl()) { + SendSetOptionACK(PP_ERROR_FAILED); + return; + } + + net::TCPClientSocket* tcp_socket = + static_cast<net::TCPClientSocket*>(socket_.get()); + DCHECK(tcp_socket); switch (name) { - case PP_TCPSOCKETOPTION_NO_DELAY: - if (!IsSsl()) { - net::TCPClientSocket* tcp_socket = - static_cast<net::TCPClientSocket*>(socket_.get()); - SendSetBoolOptionACK(tcp_socket->SetNoDelay(value)); + case PP_TCPSOCKET_OPTION_NO_DELAY: { + bool boolean_value = false; + if (!value.GetBool(&boolean_value)) { + SendSetOptionACK(PP_ERROR_BADARGUMENT); + return; + } + + SendSetOptionACK( + tcp_socket->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED); + return; + } + case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: + case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { + int32_t integer_value = 0; + if (!value.GetInt32(&integer_value) || integer_value <= 0) { + SendSetOptionACK(PP_ERROR_BADARGUMENT); + return; + } + + bool result = false; + if (name == PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE) { + if (integer_value > ppapi::TCPSocketShared::kMaxSendBufferSize) { + SendSetOptionACK(PP_ERROR_BADARGUMENT); + return; + } + result = tcp_socket->SetSendBufferSize(integer_value); } else { - SendSetBoolOptionACK(false); + if (integer_value > ppapi::TCPSocketShared::kMaxReceiveBufferSize) { + SendSetOptionACK(PP_ERROR_BADARGUMENT); + return; + } + result = tcp_socket->SetReceiveBufferSize(integer_value); } + SendSetOptionACK(result ? PP_OK : PP_ERROR_FAILED); return; - default: - break; + } + default: { + NOTREACHED(); + SendSetOptionACK(PP_ERROR_BADARGUMENT); + return; + } } - - NOTREACHED(); - SendSetBoolOptionACK(false); } void PepperTCPSocket::StartConnect(const net::AddressList& addresses) { @@ -226,16 +282,16 @@ void PepperTCPSocket::StartConnect(const net::AddressList& addresses) { socket_.reset(new net::TCPClientSocket(addresses, NULL, net::NetLog::Source())); - int result = socket_->Connect( + int net_result = socket_->Connect( base::Bind(&PepperTCPSocket::OnConnectCompleted, base::Unretained(this))); - if (result != net::ERR_IO_PENDING) - OnConnectCompleted(result); + if (net_result != net::ERR_IO_PENDING) + OnConnectCompleted(net_result); } -void PepperTCPSocket::SendConnectACKError() { +void PepperTCPSocket::SendConnectACKError(int32_t error) { manager_->Send(new PpapiMsg_PPBTCPSocket_ConnectACK( - routing_id_, plugin_dispatcher_id_, socket_id_, false, + routing_id_, plugin_dispatcher_id_, socket_id_, error, NetAddressPrivateImpl::kInvalidNetAddress, NetAddressPrivateImpl::kInvalidNetAddress)); } @@ -299,14 +355,15 @@ bool PepperTCPSocket::GetCertificateFields( return GetCertificateFields(*cert.get(), fields); } -void PepperTCPSocket::SendReadACKError() { +void PepperTCPSocket::SendReadACKError(int32_t error) { manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK( - routing_id_, plugin_dispatcher_id_, socket_id_, false, std::string())); + routing_id_, plugin_dispatcher_id_, socket_id_, error, std::string())); } -void PepperTCPSocket::SendWriteACKError() { +void PepperTCPSocket::SendWriteACKError(int32_t error) { + DCHECK_GT(0, error); manager_->Send(new PpapiMsg_PPBTCPSocket_WriteACK( - routing_id_, plugin_dispatcher_id_, socket_id_, false, 0)); + routing_id_, plugin_dispatcher_id_, socket_id_, error)); } void PepperTCPSocket::SendSSLHandshakeACK(bool succeeded) { @@ -328,16 +385,16 @@ void PepperTCPSocket::SendSSLHandshakeACK(bool succeeded) { certificate_fields)); } -void PepperTCPSocket::SendSetBoolOptionACK(bool succeeded) { - manager_->Send(new PpapiMsg_PPBTCPSocket_SetBoolOptionACK( - routing_id_, plugin_dispatcher_id_, socket_id_, succeeded)); +void PepperTCPSocket::SendSetOptionACK(int32_t result) { + manager_->Send(new PpapiMsg_PPBTCPSocket_SetOptionACK( + routing_id_, plugin_dispatcher_id_, socket_id_, result)); } -void PepperTCPSocket::OnResolveCompleted(int result) { +void PepperTCPSocket::OnResolveCompleted(int net_result) { DCHECK(connection_state_ == CONNECT_IN_PROGRESS); - if (result != net::OK) { - SendConnectACKError(); + if (net_result != net::OK) { + SendConnectACKError(NetErrorToPepperError(net_result)); connection_state_ = BEFORE_CONNECT; return; } @@ -345,86 +402,97 @@ void PepperTCPSocket::OnResolveCompleted(int result) { StartConnect(address_list_); } -void PepperTCPSocket::OnConnectCompleted(int result) { +void PepperTCPSocket::OnConnectCompleted(int net_result) { DCHECK(connection_state_ == CONNECT_IN_PROGRESS && socket_.get()); - if (result != net::OK) { - SendConnectACKError(); - connection_state_ = BEFORE_CONNECT; - } else { + int32_t pp_result = NetErrorToPepperError(net_result); + do { + if (pp_result != PP_OK) + break; + net::IPEndPoint ip_end_point_local; net::IPEndPoint ip_end_point_remote; + pp_result = NetErrorToPepperError( + socket_->GetLocalAddress(&ip_end_point_local)); + if (pp_result != PP_OK) + break; + pp_result = NetErrorToPepperError( + socket_->GetPeerAddress(&ip_end_point_remote)); + if (pp_result != PP_OK) + break; + PP_NetAddress_Private local_addr = NetAddressPrivateImpl::kInvalidNetAddress; PP_NetAddress_Private remote_addr = NetAddressPrivateImpl::kInvalidNetAddress; - - if (socket_->GetLocalAddress(&ip_end_point_local) != net::OK || - !NetAddressPrivateImpl::IPEndPointToNetAddress( + if (!NetAddressPrivateImpl::IPEndPointToNetAddress( ip_end_point_local.address(), ip_end_point_local.port(), &local_addr) || - socket_->GetPeerAddress(&ip_end_point_remote) != net::OK || !NetAddressPrivateImpl::IPEndPointToNetAddress( ip_end_point_remote.address(), ip_end_point_remote.port(), &remote_addr)) { - SendConnectACKError(); - connection_state_ = BEFORE_CONNECT; - } else { - manager_->Send(new PpapiMsg_PPBTCPSocket_ConnectACK( - routing_id_, plugin_dispatcher_id_, socket_id_, true, - local_addr, remote_addr)); - connection_state_ = CONNECTED; + pp_result = PP_ERROR_ADDRESS_INVALID; + break; } - } + + manager_->Send(new PpapiMsg_PPBTCPSocket_ConnectACK( + routing_id_, plugin_dispatcher_id_, socket_id_, PP_OK, + local_addr, remote_addr)); + connection_state_ = CONNECTED; + return; + } while (false); + + SendConnectACKError(pp_result); + connection_state_ = BEFORE_CONNECT; } -void PepperTCPSocket::OnSSLHandshakeCompleted(int result) { +void PepperTCPSocket::OnSSLHandshakeCompleted(int net_result) { DCHECK(connection_state_ == SSL_HANDSHAKE_IN_PROGRESS); - bool succeeded = result == net::OK; + bool succeeded = net_result == net::OK; SendSSLHandshakeACK(succeeded); connection_state_ = succeeded ? SSL_CONNECTED : SSL_HANDSHAKE_FAILED; } -void PepperTCPSocket::OnReadCompleted(int result) { +void PepperTCPSocket::OnReadCompleted(int net_result) { DCHECK(read_buffer_.get()); - if (result > 0) { + if (net_result > 0) { manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK( - routing_id_, plugin_dispatcher_id_, socket_id_, true, - std::string(read_buffer_->data(), result))); - } else if (result == 0) { + routing_id_, plugin_dispatcher_id_, socket_id_, PP_OK, + std::string(read_buffer_->data(), net_result))); + } else if (net_result == 0) { end_of_file_reached_ = true; manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK( - routing_id_, plugin_dispatcher_id_, socket_id_, true, std::string())); + routing_id_, plugin_dispatcher_id_, socket_id_, PP_OK, std::string())); } else { - SendReadACKError(); + SendReadACKError(NetErrorToPepperError(net_result)); } read_buffer_ = NULL; } -void PepperTCPSocket::OnWriteCompleted(int result) { +void PepperTCPSocket::OnWriteCompleted(int net_result) { DCHECK(write_buffer_base_.get()); DCHECK(write_buffer_.get()); // Note: For partial writes of 0 bytes, don't continue writing to avoid a // likely infinite loop. - if (result > 0) { - write_buffer_->DidConsume(result); + if (net_result > 0) { + write_buffer_->DidConsume(net_result); if (write_buffer_->BytesRemaining() > 0) { DoWrite(); return; } } - if (result >= 0) { + if (net_result >= 0) { manager_->Send(new PpapiMsg_PPBTCPSocket_WriteACK( - routing_id_, plugin_dispatcher_id_, socket_id_, true, + routing_id_, plugin_dispatcher_id_, socket_id_, write_buffer_->BytesConsumed())); } else { - SendWriteACKError(); + SendWriteACKError(NetErrorToPepperError(net_result)); } write_buffer_ = NULL; @@ -446,12 +514,12 @@ void PepperTCPSocket::DoWrite() { DCHECK(write_buffer_.get()); DCHECK_GT(write_buffer_->BytesRemaining(), 0); - int result = socket_->Write( + int net_result = socket_->Write( write_buffer_.get(), write_buffer_->BytesRemaining(), base::Bind(&PepperTCPSocket::OnWriteCompleted, base::Unretained(this))); - if (result != net::ERR_IO_PENDING) - OnWriteCompleted(result); + if (net_result != net::ERR_IO_PENDING) + OnWriteCompleted(net_result); } } // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket.h b/content/browser/renderer_host/pepper/pepper_tcp_socket.h index bfc8693..5292d6a 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_socket.h +++ b/content/browser/renderer_host/pepper/pepper_tcp_socket.h @@ -12,12 +12,14 @@ #include "base/memory/scoped_ptr.h" #include "net/base/address_list.h" #include "net/base/completion_callback.h" +#include "ppapi/c/dev/ppb_tcp_socket_dev.h" #include "ppapi/c/pp_stdint.h" struct PP_NetAddress_Private; namespace ppapi { class PPB_X509Certificate_Fields; +class SocketOptionData; } namespace net { @@ -32,13 +34,14 @@ namespace content { class PepperMessageFilter; // PepperTCPSocket is used by PepperMessageFilter to handle requests from -// the Pepper TCP socket API (PPB_TCPSocket_Private). +// the Pepper TCP socket API (PPB_TCPSocket and PPB_TCPSocket_Private). class PepperTCPSocket { public: PepperTCPSocket(PepperMessageFilter* manager, int32 routing_id, uint32 plugin_dispatcher_id, - uint32 socket_id); + uint32 socket_id, + bool private_api); // Used for creation already connected sockets. Takes ownership of // |socket|. @@ -46,10 +49,12 @@ class PepperTCPSocket { int32 routing_id, uint32 plugin_dispatcher_id, uint32 socket_id, - net::StreamSocket* socket); + net::StreamSocket* socket, + bool private_api); ~PepperTCPSocket(); int routing_id() { return routing_id_; } + bool private_api() const { return private_api_; } void Connect(const std::string& host, uint16_t port); void ConnectWithNetAddress(const PP_NetAddress_Private& net_addr); @@ -60,9 +65,10 @@ class PepperTCPSocket { const std::vector<std::vector<char> >& untrusted_certs); void Read(int32 bytes_to_read); void Write(const std::string& data); - void SetBoolOption(uint32_t name, bool value); + void SetOption(PP_TCPSocket_Option_Dev name, + const ppapi::SocketOptionData& value); - void SendConnectACKError(); + void SendConnectACKError(int32_t error); // Extracts the certificate field data from a |net::X509Certificate| into // |PPB_X509Certificate_Fields|. @@ -93,16 +99,16 @@ class PepperTCPSocket { void StartConnect(const net::AddressList& addresses); - void SendReadACKError(); - void SendWriteACKError(); + void SendReadACKError(int32_t error); + void SendWriteACKError(int32_t error); void SendSSLHandshakeACK(bool succeeded); - void SendSetBoolOptionACK(bool succeeded); + void SendSetOptionACK(int32_t result); - void OnResolveCompleted(int result); - void OnConnectCompleted(int result); - void OnSSLHandshakeCompleted(int result); - void OnReadCompleted(int result); - void OnWriteCompleted(int result); + void OnResolveCompleted(int net_result); + void OnConnectCompleted(int net_result); + void OnSSLHandshakeCompleted(int net_result); + void OnReadCompleted(int net_result); + void OnWriteCompleted(int net_result); bool IsConnected() const; bool IsSsl() const; @@ -115,6 +121,7 @@ class PepperTCPSocket { int32 routing_id_; uint32 plugin_dispatcher_id_; uint32 socket_id_; + bool private_api_; ConnectionState connection_state_; bool end_of_file_reached_; diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc index a22d624..0793387 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc @@ -81,6 +81,7 @@ #include "ppapi/shared_impl/ppb_device_ref_shared.h" #include "ppapi/shared_impl/ppp_instance_combined.h" #include "ppapi/shared_impl/resource_tracker.h" +#include "ppapi/shared_impl/socket_option_data.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_tcp_server_socket_private_api.h" #include "third_party/WebKit/public/web/WebCursorInfo.h" @@ -1148,8 +1149,11 @@ PepperPluginDelegateImpl::GetFileThreadMessageLoopProxy() { } uint32 PepperPluginDelegateImpl::TCPSocketCreate() { + // This was used for PPB_TCPSocket_Private creation. And it shouldn't be + // needed anymore. + // TODO(yzshen): Remove TCP socket-related contents from the plugin delegate. uint32 socket_id = 0; - render_view_->Send(new PpapiHostMsg_PPBTCPSocket_Create( + render_view_->Send(new PpapiHostMsg_PPBTCPSocket_CreatePrivate( render_view_->routing_id(), 0, &socket_id)); return socket_id; } @@ -1207,13 +1211,13 @@ void PepperPluginDelegateImpl::TCPSocketDisconnect(uint32 socket_id) { tcp_sockets_.Remove(socket_id); } -void PepperPluginDelegateImpl::TCPSocketSetBoolOption( +void PepperPluginDelegateImpl::TCPSocketSetOption( uint32 socket_id, - PP_TCPSocketOption_Private name, - bool value) { + PP_TCPSocket_Option_Dev name, + const ppapi::SocketOptionData& value) { DCHECK(tcp_sockets_.Lookup(socket_id)); render_view_->Send( - new PpapiHostMsg_PPBTCPSocket_SetBoolOption(socket_id, name, value)); + new PpapiHostMsg_PPBTCPSocket_SetOption(socket_id, name, value)); } void PepperPluginDelegateImpl::RegisterTCPSocket( @@ -1491,8 +1495,8 @@ bool PepperPluginDelegateImpl::OnMessageReceived(const IPC::Message& message) { OnTCPSocketSSLHandshakeACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnTCPSocketReadACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnTCPSocketWriteACK) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetBoolOptionACK, - OnTCPSocketSetBoolOptionACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK, + OnTCPSocketSetOptionACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_ListenACK, OnTCPServerSocketListenACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_AcceptACK, @@ -1511,14 +1515,14 @@ void PepperPluginDelegateImpl::OnDestruct() { void PepperPluginDelegateImpl::OnTCPSocketConnectACK( uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, + int32_t result, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr) { webkit::ppapi::PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id); if (socket) - socket->OnConnectCompleted(succeeded, local_addr, remote_addr); - if (!succeeded) + socket->OnConnectCompleted(result, local_addr, remote_addr); + if (result != PP_OK) tcp_sockets_.Remove(socket_id); } @@ -1535,32 +1539,31 @@ void PepperPluginDelegateImpl::OnTCPSocketSSLHandshakeACK( void PepperPluginDelegateImpl::OnTCPSocketReadACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, + int32_t result, const std::string& data) { webkit::ppapi::PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id); if (socket) - socket->OnReadCompleted(succeeded, data); + socket->OnReadCompleted(result, data); } void PepperPluginDelegateImpl::OnTCPSocketWriteACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, - int32_t bytes_written) { + int32_t result) { webkit::ppapi::PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id); if (socket) - socket->OnWriteCompleted(succeeded, bytes_written); + socket->OnWriteCompleted(result); } -void PepperPluginDelegateImpl::OnTCPSocketSetBoolOptionACK( +void PepperPluginDelegateImpl::OnTCPSocketSetOptionACK( uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded) { + int32_t result) { webkit::ppapi::PPB_TCPSocket_Private_Impl* socket = tcp_sockets_.Lookup(socket_id); if (socket) - socket->OnSetOptionCompleted(succeeded); + socket->OnSetOptionCompleted(result); } void PepperPluginDelegateImpl::OnTCPServerSocketListenACK( diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h index 1c0089a..83f9f82 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.h +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h @@ -282,9 +282,10 @@ class PepperPluginDelegateImpl virtual void TCPSocketWrite(uint32 socket_id, const std::string& buffer) OVERRIDE; virtual void TCPSocketDisconnect(uint32 socket_id) OVERRIDE; - virtual void TCPSocketSetBoolOption(uint32 socket_id, - PP_TCPSocketOption_Private name, - bool value) OVERRIDE; + virtual void TCPSocketSetOption( + uint32 socket_id, + PP_TCPSocket_Option_Dev name, + const ppapi::SocketOptionData& value) OVERRIDE; virtual void RegisterTCPSocket( webkit::ppapi::PPB_TCPSocket_Private_Impl* socket, uint32 socket_id) OVERRIDE; @@ -341,7 +342,7 @@ class PepperPluginDelegateImpl void OnTCPSocketConnectACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, + int32_t result, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr); void OnTCPSocketSSLHandshakeACK( @@ -351,15 +352,14 @@ class PepperPluginDelegateImpl const ppapi::PPB_X509Certificate_Fields& certificate_fields); void OnTCPSocketReadACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, + int32_t result, const std::string& data); void OnTCPSocketWriteACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, - int32_t bytes_written); - void OnTCPSocketSetBoolOptionACK(uint32 plugin_dispatcher_id, - uint32 socket_id, - bool succeeded); + int32_t result); + void OnTCPSocketSetOptionACK(uint32 plugin_dispatcher_id, + uint32 socket_id, + int32_t result); void OnTCPServerSocketListenACK(uint32 plugin_dispatcher_id, PP_Resource socket_resource, uint32 socket_id, diff --git a/ppapi/api/dev/ppb_tcp_socket_dev.idl b/ppapi/api/dev/ppb_tcp_socket_dev.idl index dfc038a..920a9e9 100644 --- a/ppapi/api/dev/ppb_tcp_socket_dev.idl +++ b/ppapi/api/dev/ppb_tcp_socket_dev.idl @@ -17,10 +17,12 @@ label Chrome { enum PP_TCPSocket_Option_Dev { // Disables coalescing of small writes to make TCP segments, and instead // deliver data immediately. Value type is PP_VARTYPE_BOOL. + // This option can only be set after a successful Connect() call. PP_TCPSOCKET_OPTION_NO_DELAY = 0, // Specifies the socket send buffer in bytes. Value's type should be // PP_VARTYPE_INT32. + // This option can only be set after a successful Connect() call. // Note: This is only treated as a hint for the browser to set the buffer // size. Even if SetOption() reports that this option has been successfully // set, the browser doesn't guarantee to conform to it. @@ -28,6 +30,7 @@ enum PP_TCPSocket_Option_Dev { // Specifies the socket receive buffer in bytes. Value's type should be // PP_VARTYPE_INT32. + // This option can only be set after a successful Connect() call. // Note: This is only treated as a hint for the browser to set the buffer // size. Even if SetOption() reports that this option has been successfully // set, the browser doesn't guarantee to conform to it. @@ -106,7 +109,7 @@ interface PPB_TCPSocket_Dev { * Sets an option on |tcp_socket|. Supported |name| and |value| parameters * are as described for PP_TCPSocketOption_Dev. |callback| will be * invoked with PP_OK if setting the option succeeds, or an error code - * otherwise. The socket must be connected before SetOption is called. + * otherwise. */ int32_t SetOption([in] PP_Resource tcp_socket, [in] PP_TCPSocket_Option_Dev name, diff --git a/ppapi/c/dev/ppb_tcp_socket_dev.h b/ppapi/c/dev/ppb_tcp_socket_dev.h index d59bc31..044a03e 100644 --- a/ppapi/c/dev/ppb_tcp_socket_dev.h +++ b/ppapi/c/dev/ppb_tcp_socket_dev.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From dev/ppb_tcp_socket_dev.idl modified Wed Jun 12 11:16:37 2013. */ +/* From dev/ppb_tcp_socket_dev.idl modified Tue Jun 18 15:48:42 2013. */ #ifndef PPAPI_C_DEV_PPB_TCP_SOCKET_DEV_H_ #define PPAPI_C_DEV_PPB_TCP_SOCKET_DEV_H_ @@ -31,16 +31,19 @@ */ typedef enum { /* Disables coalescing of small writes to make TCP segments, and instead - * deliver data immediately. Value type is PP_VARTYPE_BOOL. */ + * deliver data immediately. Value type is PP_VARTYPE_BOOL. + * This option can only be set after a successful Connect() call. */ PP_TCPSOCKET_OPTION_NO_DELAY = 0, /* Specifies the socket send buffer in bytes. Value's type should be * PP_VARTYPE_INT32. + * This option can only be set after a successful Connect() call. * Note: This is only treated as a hint for the browser to set the buffer * size. Even if SetOption() reports that this option has been successfully * set, the browser doesn't guarantee to conform to it. */ PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE = 1, /* Specifies the socket receive buffer in bytes. Value's type should be * PP_VARTYPE_INT32. + * This option can only be set after a successful Connect() call. * Note: This is only treated as a hint for the browser to set the buffer * size. Even if SetOption() reports that this option has been successfully * set, the browser doesn't guarantee to conform to it. */ @@ -119,7 +122,7 @@ struct PPB_TCPSocket_Dev_0_1 { * Sets an option on |tcp_socket|. Supported |name| and |value| parameters * are as described for PP_TCPSocketOption_Dev. |callback| will be * invoked with PP_OK if setting the option succeeds, or an error code - * otherwise. The socket must be connected before SetOption is called. + * otherwise. */ int32_t (*SetOption)(PP_Resource tcp_socket, PP_TCPSocket_Option_Dev name, diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index ddc2581..a977dca 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -21,6 +21,7 @@ #include "ipc/ipc_platform_file.h" #include "ppapi/c/dev/pp_video_capture_dev.h" #include "ppapi/c/dev/pp_video_dev.h" +#include "ppapi/c/dev/ppb_tcp_socket_dev.h" #include "ppapi/c/dev/ppb_text_input_dev.h" #include "ppapi/c/dev/ppb_truetype_font_dev.h" #include "ppapi/c/dev/ppb_udp_socket_dev.h" @@ -43,7 +44,6 @@ #include "ppapi/c/private/ppb_host_resolver_private.h" #include "ppapi/c/private/ppb_net_address_private.h" #include "ppapi/c/private/ppb_pdf.h" -#include "ppapi/c/private/ppb_tcp_socket_private.h" #include "ppapi/c/private/ppp_flash_browser_operations.h" #include "ppapi/c/private/ppb_talk_private.h" #include "ppapi/proxy/host_resolver_private_resource.h" @@ -96,6 +96,8 @@ IPC_ENUM_TRAITS(PP_ResourceString) IPC_ENUM_TRAITS_MAX_VALUE(PP_TalkEvent, PP_TALKEVENT_NUM_EVENTS - 1) IPC_ENUM_TRAITS_MAX_VALUE(PP_TalkPermission, PP_TALKPERMISSION_NUM_PERMISSIONS - 1) +IPC_ENUM_TRAITS_MAX_VALUE(PP_TCPSocket_Option_Dev, + PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE) IPC_ENUM_TRAITS(PP_TextInput_Type) IPC_ENUM_TRAITS(PP_TrueTypeFontFamily_Dev) IPC_ENUM_TRAITS(PP_TrueTypeFontStyle_Dev) @@ -700,11 +702,11 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPPContentDecryptor_DecryptAndDecode, std::string /* serialized_block_info */) #endif // !defined(OS_NACL) && !defined(NACL_WIN64) -// PPB_TCPSocket_Private. +// PPB_TCPSocket and PPB_TCPSocket_Private. IPC_MESSAGE_ROUTED5(PpapiMsg_PPBTCPSocket_ConnectACK, uint32 /* plugin_dispatcher_id */, uint32 /* socket_id */, - bool /* succeeded */, + int32_t /* result */, PP_NetAddress_Private /* local_addr */, PP_NetAddress_Private /* remote_addr */) IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_SSLHandshakeACK, @@ -715,17 +717,16 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_SSLHandshakeACK, IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_ReadACK, uint32 /* plugin_dispatcher_id */, uint32 /* socket_id */, - bool /* succeeded */, + int32_t /* result */, std::string /* data */) -IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_WriteACK, +IPC_MESSAGE_ROUTED3(PpapiMsg_PPBTCPSocket_WriteACK, uint32 /* plugin_dispatcher_id */, uint32 /* socket_id */, - bool /* succeeded */, - int32_t /* bytes_written */) -IPC_MESSAGE_ROUTED3(PpapiMsg_PPBTCPSocket_SetBoolOptionACK, + int32_t /* result */) +IPC_MESSAGE_ROUTED3(PpapiMsg_PPBTCPSocket_SetOptionACK, uint32 /* plugin_dispatcher_id */, uint32 /* socket_id */, - bool /* succeeded */) + int32_t /* result */) // PPB_TCPServerSocket_Private. @@ -1185,11 +1186,17 @@ IPC_SYNC_MESSAGE_ROUTED1_0(PpapiHostMsg_PPBFlashMessageLoop_Quit, ppapi::HostResource /* flash_message_loop */) #endif // !defined(OS_NACL) && !defined(NACL_WIN64) -// PPB_TCPSocket_Private. +// PPB_TCPSocket and PPB_TCPSocket_Private. +// Creates a PPB_TCPSocket resource. IPC_SYNC_MESSAGE_CONTROL2_1(PpapiHostMsg_PPBTCPSocket_Create, int32 /* routing_id */, uint32 /* plugin_dispatcher_id */, uint32 /* socket_id */) +// Creates a PPB_TCPSocket_Private resource. +IPC_SYNC_MESSAGE_CONTROL2_1(PpapiHostMsg_PPBTCPSocket_CreatePrivate, + int32 /* routing_id */, + uint32 /* plugin_dispatcher_id */, + uint32 /* socket_id */) IPC_MESSAGE_CONTROL4(PpapiHostMsg_PPBTCPSocket_Connect, int32 /* routing_id */, uint32 /* socket_id */, @@ -1213,10 +1220,10 @@ IPC_MESSAGE_CONTROL2(PpapiHostMsg_PPBTCPSocket_Write, std::string /* data */) IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBTCPSocket_Disconnect, uint32 /* socket_id */) -IPC_MESSAGE_CONTROL3(PpapiHostMsg_PPBTCPSocket_SetBoolOption, +IPC_MESSAGE_CONTROL3(PpapiHostMsg_PPBTCPSocket_SetOption, uint32 /* socket_id */, - uint32 /* name */, - bool /* value */) + PP_TCPSocket_Option_Dev /* name */, + ppapi::SocketOptionData /* value */) // PPB_TCPServerSocket_Private. IPC_MESSAGE_CONTROL5(PpapiHostMsg_PPBTCPServerSocket_Listen, diff --git a/ppapi/proxy/ppb_tcp_socket_private_proxy.cc b/ppapi/proxy/ppb_tcp_socket_private_proxy.cc index 7f7fb78..7075657 100644 --- a/ppapi/proxy/ppb_tcp_socket_private_proxy.cc +++ b/ppapi/proxy/ppb_tcp_socket_private_proxy.cc @@ -14,6 +14,7 @@ #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" #include "ppapi/shared_impl/private/tcp_socket_private_impl.h" #include "ppapi/shared_impl/resource.h" +#include "ppapi/shared_impl/socket_option_data.h" #include "ppapi/thunk/thunk.h" namespace ppapi { @@ -46,8 +47,8 @@ class TCPSocket : public TCPSocketPrivateImpl { virtual void SendRead(int32_t bytes_to_read) OVERRIDE; virtual void SendWrite(const std::string& buffer) OVERRIDE; virtual void SendDisconnect() OVERRIDE; - virtual void SendSetBoolOption(PP_TCPSocketOption_Private name, - bool value) OVERRIDE; + virtual void SendSetOption(PP_TCPSocket_Option_Dev name, + const SocketOptionData& value) OVERRIDE; private: void SendToBrowser(IPC::Message* msg); @@ -118,9 +119,10 @@ void TCPSocket::SendDisconnect() { SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_)); } -void TCPSocket::SendSetBoolOption(PP_TCPSocketOption_Private name, bool value) { +void TCPSocket::SendSetOption(PP_TCPSocket_Option_Dev name, + const SocketOptionData& value) { SendToBrowser( - new PpapiHostMsg_PPBTCPSocket_SetBoolOption(socket_id_, name, value)); + new PpapiHostMsg_PPBTCPSocket_SetOption(socket_id_, name, value)); } void TCPSocket::SendToBrowser(IPC::Message* msg) { @@ -147,7 +149,7 @@ PP_Resource PPB_TCPSocket_Private_Proxy::CreateProxyResource( uint32 socket_id = 0; PluginGlobals::Get()->GetBrowserSender()->Send( - new PpapiHostMsg_PPBTCPSocket_Create( + new PpapiHostMsg_PPBTCPSocket_CreatePrivate( API_ID_PPB_TCPSOCKET_PRIVATE, dispatcher->plugin_dispatcher_id(), &socket_id)); if (socket_id == 0) @@ -177,8 +179,7 @@ bool PPB_TCPSocket_Private_Proxy::OnMessageReceived(const IPC::Message& msg) { OnMsgSSLHandshakeACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnMsgReadACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnMsgWriteACK) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetBoolOptionACK, - OnMsgSetBoolOptionACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK, OnMsgSetOptionACK) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -187,7 +188,7 @@ bool PPB_TCPSocket_Private_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPB_TCPSocket_Private_Proxy::OnMsgConnectACK( uint32 /* plugin_dispatcher_id */, uint32 socket_id, - bool succeeded, + int32_t result, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr) { if (!g_id_to_socket) { @@ -197,7 +198,7 @@ void PPB_TCPSocket_Private_Proxy::OnMsgConnectACK( IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); if (iter == g_id_to_socket->end()) return; - iter->second->OnConnectCompleted(succeeded, local_addr, remote_addr); + iter->second->OnConnectCompleted(result, local_addr, remote_addr); } void PPB_TCPSocket_Private_Proxy::OnMsgSSLHandshakeACK( @@ -218,7 +219,7 @@ void PPB_TCPSocket_Private_Proxy::OnMsgSSLHandshakeACK( void PPB_TCPSocket_Private_Proxy::OnMsgReadACK( uint32 /* plugin_dispatcher_id */, uint32 socket_id, - bool succeeded, + int32_t result, const std::string& data) { if (!g_id_to_socket) { NOTREACHED(); @@ -227,14 +228,13 @@ void PPB_TCPSocket_Private_Proxy::OnMsgReadACK( IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); if (iter == g_id_to_socket->end()) return; - iter->second->OnReadCompleted(succeeded, data); + iter->second->OnReadCompleted(result, data); } void PPB_TCPSocket_Private_Proxy::OnMsgWriteACK( uint32 /* plugin_dispatcher_id */, uint32 socket_id, - bool succeeded, - int32_t bytes_written) { + int32_t result) { if (!g_id_to_socket) { NOTREACHED(); return; @@ -242,13 +242,13 @@ void PPB_TCPSocket_Private_Proxy::OnMsgWriteACK( IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); if (iter == g_id_to_socket->end()) return; - iter->second->OnWriteCompleted(succeeded, bytes_written); + iter->second->OnWriteCompleted(result); } -void PPB_TCPSocket_Private_Proxy::OnMsgSetBoolOptionACK( +void PPB_TCPSocket_Private_Proxy::OnMsgSetOptionACK( uint32 /* plugin_dispatcher_id */, uint32 socket_id, - bool succeeded) { + int32_t result) { if (!g_id_to_socket) { NOTREACHED(); return; @@ -256,7 +256,7 @@ void PPB_TCPSocket_Private_Proxy::OnMsgSetBoolOptionACK( IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); if (iter == g_id_to_socket->end()) return; - iter->second->OnSetOptionCompleted(succeeded); + iter->second->OnSetOptionCompleted(result); } } // namespace proxy diff --git a/ppapi/proxy/ppb_tcp_socket_private_proxy.h b/ppapi/proxy/ppb_tcp_socket_private_proxy.h index 6f0f0f4..0813531 100644 --- a/ppapi/proxy/ppb_tcp_socket_private_proxy.h +++ b/ppapi/proxy/ppb_tcp_socket_private_proxy.h @@ -41,7 +41,7 @@ class PPB_TCPSocket_Private_Proxy : public InterfaceProxy { // Browser->plugin message handlers. void OnMsgConnectACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, + int32_t result, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr); void OnMsgSSLHandshakeACK( @@ -51,15 +51,14 @@ class PPB_TCPSocket_Private_Proxy : public InterfaceProxy { const PPB_X509Certificate_Fields& certificate_fields); void OnMsgReadACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, + int32_t result, const std::string& data); void OnMsgWriteACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, - int32_t bytes_written); - void OnMsgSetBoolOptionACK(uint32 plugin_dispatcher_id, - uint32 socket_id, - bool succeeded); + int32_t result); + void OnMsgSetOptionACK(uint32 plugin_dispatcher_id, + uint32 socket_id, + int32_t result); DISALLOW_COPY_AND_ASSIGN(PPB_TCPSocket_Private_Proxy); }; diff --git a/ppapi/proxy/ppb_tcp_socket_proxy.cc b/ppapi/proxy/ppb_tcp_socket_proxy.cc index 1b6bd8a..6e41c91 100644 --- a/ppapi/proxy/ppb_tcp_socket_proxy.cc +++ b/ppapi/proxy/ppb_tcp_socket_proxy.cc @@ -11,6 +11,7 @@ #include "ppapi/proxy/plugin_globals.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/resource.h" +#include "ppapi/shared_impl/socket_option_data.h" #include "ppapi/shared_impl/tcp_socket_shared.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_net_address_api.h" @@ -66,8 +67,8 @@ class TCPSocket : public thunk::PPB_TCPSocket_API, virtual void SendRead(int32_t bytes_to_read) OVERRIDE; virtual void SendWrite(const std::string& buffer) OVERRIDE; virtual void SendDisconnect() OVERRIDE; - virtual void SendSetBoolOption(PP_TCPSocketOption_Private name, - bool value) OVERRIDE; + virtual void SendSetOption(PP_TCPSocket_Option_Dev name, + const SocketOptionData& value) OVERRIDE; virtual Resource* GetOwnerResource() OVERRIDE; private: @@ -146,11 +147,7 @@ void TCPSocket::Close() { int32_t TCPSocket::SetOption(PP_TCPSocket_Option_Dev name, const PP_Var& value, scoped_refptr<TrackedCallback> callback) { - // TODO(yzshen): Add support for other options. - if (name == PP_TCPSOCKET_OPTION_NO_DELAY) - return SetOptionImpl(PP_TCPSOCKETOPTION_NO_DELAY, value, callback); - - return PP_ERROR_NOTSUPPORTED; + return SetOptionImpl(name, value, callback); } void TCPSocket::SendConnect(const std::string& host, uint16_t port) { @@ -186,9 +183,10 @@ void TCPSocket::SendDisconnect() { SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_)); } -void TCPSocket::SendSetBoolOption(PP_TCPSocketOption_Private name, bool value) { +void TCPSocket::SendSetOption(PP_TCPSocket_Option_Dev name, + const SocketOptionData& value) { SendToBrowser( - new PpapiHostMsg_PPBTCPSocket_SetBoolOption(socket_id_, name, value)); + new PpapiHostMsg_PPBTCPSocket_SetOption(socket_id_, name, value)); } Resource* TCPSocket::GetOwnerResource() { @@ -234,8 +232,8 @@ bool PPB_TCPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) { OnMsgConnectACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnMsgReadACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnMsgWriteACK) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetBoolOptionACK, - OnMsgSetBoolOptionACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK, + OnMsgSetOptionACK) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -244,7 +242,7 @@ bool PPB_TCPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPB_TCPSocket_Proxy::OnMsgConnectACK( uint32 /* plugin_dispatcher_id */, uint32 socket_id, - bool succeeded, + int32_t result, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr) { if (!g_id_to_socket) { @@ -254,12 +252,12 @@ void PPB_TCPSocket_Proxy::OnMsgConnectACK( IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); if (iter == g_id_to_socket->end()) return; - iter->second->OnConnectCompleted(succeeded, local_addr, remote_addr); + iter->second->OnConnectCompleted(result, local_addr, remote_addr); } void PPB_TCPSocket_Proxy::OnMsgReadACK(uint32 /* plugin_dispatcher_id */, uint32 socket_id, - bool succeeded, + int32_t result, const std::string& data) { if (!g_id_to_socket) { NOTREACHED(); @@ -268,13 +266,12 @@ void PPB_TCPSocket_Proxy::OnMsgReadACK(uint32 /* plugin_dispatcher_id */, IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); if (iter == g_id_to_socket->end()) return; - iter->second->OnReadCompleted(succeeded, data); + iter->second->OnReadCompleted(result, data); } void PPB_TCPSocket_Proxy::OnMsgWriteACK(uint32 /* plugin_dispatcher_id */, uint32 socket_id, - bool succeeded, - int32_t bytes_written) { + int32_t result) { if (!g_id_to_socket) { NOTREACHED(); return; @@ -282,13 +279,12 @@ void PPB_TCPSocket_Proxy::OnMsgWriteACK(uint32 /* plugin_dispatcher_id */, IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); if (iter == g_id_to_socket->end()) return; - iter->second->OnWriteCompleted(succeeded, bytes_written); + iter->second->OnWriteCompleted(result); } -void PPB_TCPSocket_Proxy::OnMsgSetBoolOptionACK( - uint32 /* plugin_dispatcher_id */, - uint32 socket_id, - bool succeeded) { +void PPB_TCPSocket_Proxy::OnMsgSetOptionACK(uint32 /* plugin_dispatcher_id */, + uint32 socket_id, + int32_t result) { if (!g_id_to_socket) { NOTREACHED(); return; @@ -296,7 +292,7 @@ void PPB_TCPSocket_Proxy::OnMsgSetBoolOptionACK( IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); if (iter == g_id_to_socket->end()) return; - iter->second->OnSetOptionCompleted(succeeded); + iter->second->OnSetOptionCompleted(result); } } // namespace proxy diff --git a/ppapi/proxy/ppb_tcp_socket_proxy.h b/ppapi/proxy/ppb_tcp_socket_proxy.h index 35314a3..c5a3de8 100644 --- a/ppapi/proxy/ppb_tcp_socket_proxy.h +++ b/ppapi/proxy/ppb_tcp_socket_proxy.h @@ -34,20 +34,19 @@ class PPB_TCPSocket_Proxy : public InterfaceProxy { // Browser->plugin message handlers. void OnMsgConnectACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, + int32_t result, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr); void OnMsgReadACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, + int32_t result, const std::string& data); void OnMsgWriteACK(uint32 plugin_dispatcher_id, uint32 socket_id, - bool succeeded, - int32_t bytes_written); - void OnMsgSetBoolOptionACK(uint32 plugin_dispatcher_id, - uint32 socket_id, - bool succeeded); + int32_t result); + void OnMsgSetOptionACK(uint32 plugin_dispatcher_id, + uint32 socket_id, + int32_t result); DISALLOW_COPY_AND_ASSIGN(PPB_TCPSocket_Proxy); }; diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.cc b/ppapi/shared_impl/private/tcp_socket_private_impl.cc index 832603c..ce8f03a 100644 --- a/ppapi/shared_impl/private/tcp_socket_private_impl.cc +++ b/ppapi/shared_impl/private/tcp_socket_private_impl.cc @@ -4,6 +4,9 @@ #include "ppapi/shared_impl/private/tcp_socket_private_impl.h" +#include "base/logging.h" +#include "ppapi/c/pp_errors.h" + namespace ppapi { TCPSocketPrivateImpl::TCPSocketPrivateImpl(PP_Instance instance, @@ -85,11 +88,28 @@ int32_t TCPSocketPrivateImpl::SetOption( PP_TCPSocketOption_Private name, const PP_Var& value, scoped_refptr<TrackedCallback> callback) { - return SetOptionImpl(name, value, callback); + switch (name) { + case PP_TCPSOCKETOPTION_INVALID: + return PP_ERROR_BADARGUMENT; + case PP_TCPSOCKETOPTION_NO_DELAY: + return SetOptionImpl(PP_TCPSOCKET_OPTION_NO_DELAY, value, callback); + default: + NOTREACHED(); + return PP_ERROR_BADARGUMENT; + } } Resource* TCPSocketPrivateImpl::GetOwnerResource() { return this; } +int32_t TCPSocketPrivateImpl::OverridePPError(int32_t pp_error) { + // PPB_TCPSocket_Private treats all errors from the browser process as + // PP_ERROR_FAILED. + if (pp_error < 0) + return PP_ERROR_FAILED; + + return pp_error; +} + } // namespace ppapi diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.h b/ppapi/shared_impl/private/tcp_socket_private_impl.h index 62fba8e..36303fa 100644 --- a/ppapi/shared_impl/private/tcp_socket_private_impl.h +++ b/ppapi/shared_impl/private/tcp_socket_private_impl.h @@ -62,6 +62,9 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl // TCPSocketShared implementation. virtual Resource* GetOwnerResource() OVERRIDE; + // TCPSocketShared overrides. + virtual int32_t OverridePPError(int32_t pp_error) OVERRIDE; + private: DISALLOW_COPY_AND_ASSIGN(TCPSocketPrivateImpl); }; diff --git a/ppapi/shared_impl/tcp_socket_shared.cc b/ppapi/shared_impl/tcp_socket_shared.cc index 8799c49..9656637 100644 --- a/ppapi/shared_impl/tcp_socket_shared.cc +++ b/ppapi/shared_impl/tcp_socket_shared.cc @@ -11,10 +11,12 @@ #include "base/basictypes.h" #include "base/bind.h" #include "base/logging.h" +#include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" +#include "ppapi/shared_impl/socket_option_data.h" #include "ppapi/shared_impl/var_tracker.h" #include "ppapi/shared_impl/var.h" #include "ppapi/thunk/enter.h" @@ -24,6 +26,10 @@ namespace ppapi { const int32_t TCPSocketShared::kMaxReadSize = 1024 * 1024; const int32_t TCPSocketShared::kMaxWriteSize = 1024 * 1024; +const int32_t TCPSocketShared::kMaxSendBufferSize = + 1024 * TCPSocketShared::kMaxWriteSize; +const int32_t TCPSocketShared::kMaxReceiveBufferSize = + 1024 * TCPSocketShared::kMaxReadSize; TCPSocketShared::TCPSocketShared(ResourceObjectType resource_type, uint32 socket_id) @@ -35,7 +41,7 @@ TCPSocketShared::~TCPSocketShared() { } void TCPSocketShared::OnConnectCompleted( - bool succeeded, + int32_t result, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr) { if (connection_state_ != BEFORE_CONNECT || @@ -44,12 +50,13 @@ void TCPSocketShared::OnConnectCompleted( return; } - if (succeeded) { + result = OverridePPError(result); + if (result == PP_OK) { local_addr_ = local_addr; remote_addr_ = remote_addr; connection_state_ = CONNECTED; } - connect_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED); + connect_callback_->Run(result); } void TCPSocketShared::OnSSLHandshakeCompleted( @@ -78,13 +85,15 @@ void TCPSocketShared::OnSSLHandshakeCompleted( } } -void TCPSocketShared::OnReadCompleted(bool succeeded, +void TCPSocketShared::OnReadCompleted(int32_t result, const std::string& data) { if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_) { NOTREACHED(); return; } + result = OverridePPError(result); + bool succeeded = result == PP_OK; if (succeeded) { CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_); if (!data.empty()) @@ -94,29 +103,35 @@ void TCPSocketShared::OnReadCompleted(bool succeeded, bytes_to_read_ = -1; read_callback_->Run( - succeeded ? static_cast<int32_t>(data.size()) : - static_cast<int32_t>(PP_ERROR_FAILED)); + succeeded ? static_cast<int32_t>(data.size()) : result); } -void TCPSocketShared::OnWriteCompleted(bool succeeded, - int32_t bytes_written) { - if (!TrackedCallback::IsPending(write_callback_) || - (succeeded && bytes_written < 0)) { +void TCPSocketShared::OnWriteCompleted(int32_t result) { + if (!TrackedCallback::IsPending(write_callback_)) { NOTREACHED(); return; } - write_callback_->Run( - succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED)); + result = OverridePPError(result); + write_callback_->Run(result); } -void TCPSocketShared::OnSetOptionCompleted(bool succeeded) { - if (!TrackedCallback::IsPending(set_option_callback_)) { +void TCPSocketShared::OnSetOptionCompleted(int32_t result) { + if (set_option_callbacks_.empty()) { NOTREACHED(); return; } - set_option_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED); + result = OverridePPError(result); + scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front(); + set_option_callbacks_.pop(); + + if (TrackedCallback::IsPending(callback)) + callback->Run(result); +} + +int32_t TCPSocketShared::OverridePPError(int32_t pp_error) { + return pp_error; } int32_t TCPSocketShared::ConnectImpl(const char* host, @@ -283,32 +298,42 @@ void TCPSocketShared::DisconnectImpl() { PostAbortIfNecessary(&ssl_handshake_callback_); PostAbortIfNecessary(&read_callback_); PostAbortIfNecessary(&write_callback_); - PostAbortIfNecessary(&set_option_callback_); read_buffer_ = NULL; bytes_to_read_ = -1; server_certificate_ = NULL; } int32_t TCPSocketShared::SetOptionImpl( - PP_TCPSocketOption_Private name, + PP_TCPSocket_Option_Dev name, const PP_Var& value, scoped_refptr<TrackedCallback> callback) { if (!IsConnected()) return PP_ERROR_FAILED; - if (TrackedCallback::IsPending(set_option_callback_)) - return PP_ERROR_INPROGRESS; - - set_option_callback_ = callback; + SocketOptionData option_data; switch (name) { - case PP_TCPSOCKETOPTION_NO_DELAY: + case PP_TCPSOCKET_OPTION_NO_DELAY: { if (value.type != PP_VARTYPE_BOOL) return PP_ERROR_BADARGUMENT; - SendSetBoolOption(name, PP_ToBool(value.value.as_bool)); - return PP_OK_COMPLETIONPENDING; - default: + option_data.SetBool(PP_ToBool(value.value.as_bool)); + break; + } + case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: + case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { + if (value.type != PP_VARTYPE_INT32) + return PP_ERROR_BADARGUMENT; + option_data.SetInt32(value.value.as_int); + break; + } + default: { + NOTREACHED(); return PP_ERROR_BADARGUMENT; + } } + + set_option_callbacks_.push(callback); + SendSetOption(name, option_data); + return PP_OK_COMPLETIONPENDING; } void TCPSocketShared::Init(uint32 socket_id) { diff --git a/ppapi/shared_impl/tcp_socket_shared.h b/ppapi/shared_impl/tcp_socket_shared.h index bd5e56b..46b29dc 100644 --- a/ppapi/shared_impl/tcp_socket_shared.h +++ b/ppapi/shared_impl/tcp_socket_shared.h @@ -5,11 +5,13 @@ #ifndef PPAPI_SHARED_IMPL_TCP_SOCKET_SHARED_H_ #define PPAPI_SHARED_IMPL_TCP_SOCKET_SHARED_H_ +#include <queue> #include <string> #include <vector> #include "base/compiler_specific.h" -#include "ppapi/c/private/ppb_tcp_socket_private.h" +#include "ppapi/c/dev/ppb_tcp_socket_dev.h" +#include "ppapi/c/private/ppb_net_address_private.h" #include "ppapi/shared_impl/resource.h" #include "ppapi/shared_impl/tracked_callback.h" @@ -17,6 +19,7 @@ namespace ppapi { class PPB_X509Certificate_Fields; class PPB_X509Certificate_Private_Shared; +class SocketOptionData; // This class provides the shared implementation for both PPB_TCPSocket and // PPB_TCPSocket_Private. @@ -29,16 +32,27 @@ class PPAPI_SHARED_EXPORT TCPSocketShared { // message is allowed to carry. static const int32_t kMaxWriteSize; + // The maximum number that we allow for setting + // PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE. This number is only for input + // argument sanity check, it doesn't mean the browser guarantees to support + // such a buffer size. + static const int32_t kMaxSendBufferSize; + // The maximum number that we allow for setting + // PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE. This number is only for input + // argument sanity check, it doesn't mean the browser guarantees to support + // such a buffer size. + static const int32_t kMaxReceiveBufferSize; + // Notifications on operations completion. - void OnConnectCompleted(bool succeeded, + void OnConnectCompleted(int32_t result, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr); void OnSSLHandshakeCompleted( bool succeeded, const PPB_X509Certificate_Fields& certificate_fields); - void OnReadCompleted(bool succeeded, const std::string& data); - void OnWriteCompleted(bool succeeded, int32_t bytes_written); - void OnSetOptionCompleted(bool succeeded); + void OnReadCompleted(int32_t result, const std::string& data); + void OnWriteCompleted(int32_t result); + void OnSetOptionCompleted(int32_t result); // Send functions that need to be implemented differently for the // proxied and non-proxied derived classes. @@ -52,11 +66,14 @@ class PPAPI_SHARED_EXPORT TCPSocketShared { virtual void SendRead(int32_t bytes_to_read) = 0; virtual void SendWrite(const std::string& buffer) = 0; virtual void SendDisconnect() = 0; - virtual void SendSetBoolOption(PP_TCPSocketOption_Private name, - bool value) = 0; + virtual void SendSetOption(PP_TCPSocket_Option_Dev name, + const SocketOptionData& value) = 0; virtual Resource* GetOwnerResource() = 0; + // Used to override PP_Error codes received from the browser side. + virtual int32_t OverridePPError(int32_t pp_error); + protected: enum ConnectionState { // Before a connection is successfully established (including a connect @@ -94,7 +111,7 @@ class PPAPI_SHARED_EXPORT TCPSocketShared { int32_t bytes_to_write, scoped_refptr<TrackedCallback> callback); void DisconnectImpl(); - int32_t SetOptionImpl(PP_TCPSocketOption_Private name, + int32_t SetOptionImpl(PP_TCPSocket_Option_Dev name, const PP_Var& value, scoped_refptr<TrackedCallback> callback); @@ -111,7 +128,7 @@ class PPAPI_SHARED_EXPORT TCPSocketShared { scoped_refptr<TrackedCallback> ssl_handshake_callback_; scoped_refptr<TrackedCallback> read_callback_; scoped_refptr<TrackedCallback> write_callback_; - scoped_refptr<TrackedCallback> set_option_callback_; + std::queue<scoped_refptr<TrackedCallback> > set_option_callbacks_; char* read_buffer_; int32_t bytes_to_read_; diff --git a/ppapi/tests/test_tcp_socket.cc b/ppapi/tests/test_tcp_socket.cc index 7a14fe7..d177a31 100644 --- a/ppapi/tests/test_tcp_socket.cc +++ b/ppapi/tests/test_tcp_socket.cc @@ -92,21 +92,52 @@ std::string TestTCPSocket::TestReadWrite() { std::string TestTCPSocket::TestSetOption() { pp::TCPSocket_Dev socket(instance_); - TestCompletionCallback cb(instance_->pp_instance(), callback_type()); - - cb.WaitForResult( - socket.SetOption(PP_TCPSOCKET_OPTION_NO_DELAY, true, cb.GetCallback())); - CHECK_CALLBACK_BEHAVIOR(cb); - ASSERT_EQ(PP_ERROR_FAILED, cb.result()); - - cb.WaitForResult(socket.Connect(addr_, cb.GetCallback())); - CHECK_CALLBACK_BEHAVIOR(cb); - ASSERT_EQ(PP_OK, cb.result()); - - cb.WaitForResult( - socket.SetOption(PP_TCPSOCKET_OPTION_NO_DELAY, true, cb.GetCallback())); - CHECK_CALLBACK_BEHAVIOR(cb); - ASSERT_EQ(PP_OK, cb.result()); + TestCompletionCallback cb_1(instance_->pp_instance(), callback_type()); + TestCompletionCallback cb_2(instance_->pp_instance(), callback_type()); + TestCompletionCallback cb_3(instance_->pp_instance(), callback_type()); + + // These options cannot be set before the socket is connected. + int32_t result_1 = socket.SetOption(PP_TCPSOCKET_OPTION_NO_DELAY, + true, cb_1.GetCallback()); + int32_t result_2 = socket.SetOption(PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE, + 256, cb_2.GetCallback()); + int32_t result_3 = socket.SetOption(PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE, + 512, cb_3.GetCallback()); + + cb_1.WaitForResult(result_1); + CHECK_CALLBACK_BEHAVIOR(cb_1); + ASSERT_EQ(PP_ERROR_FAILED, cb_1.result()); + + cb_2.WaitForResult(result_2); + CHECK_CALLBACK_BEHAVIOR(cb_2); + ASSERT_EQ(PP_ERROR_FAILED, cb_2.result()); + + cb_3.WaitForResult(result_3); + CHECK_CALLBACK_BEHAVIOR(cb_3); + ASSERT_EQ(PP_ERROR_FAILED, cb_3.result()); + + cb_1.WaitForResult(socket.Connect(addr_, cb_1.GetCallback())); + CHECK_CALLBACK_BEHAVIOR(cb_1); + ASSERT_EQ(PP_OK, cb_1.result()); + + result_1 = socket.SetOption(PP_TCPSOCKET_OPTION_NO_DELAY, + false, cb_1.GetCallback()); + result_2 = socket.SetOption(PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE, + 512, cb_2.GetCallback()); + result_3 = socket.SetOption(PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE, + 1024, cb_3.GetCallback()); + + cb_1.WaitForResult(result_1); + CHECK_CALLBACK_BEHAVIOR(cb_1); + ASSERT_EQ(PP_OK, cb_1.result()); + + cb_2.WaitForResult(result_2); + CHECK_CALLBACK_BEHAVIOR(cb_2); + ASSERT_EQ(PP_OK, cb_2.result()); + + cb_3.WaitForResult(result_3); + CHECK_CALLBACK_BEHAVIOR(cb_3); + ASSERT_EQ(PP_OK, cb_3.result()); PASS(); } diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc index 5f27a2e..10c0253d 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.cc +++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc @@ -283,9 +283,10 @@ void MockPluginDelegate::TCPSocketWrite(uint32 socket_id, const std::string& buffer) { } -void MockPluginDelegate::TCPSocketSetBoolOption(uint32 socket_id, - PP_TCPSocketOption_Private name, - bool value) { +void MockPluginDelegate::TCPSocketSetOption( + uint32 socket_id, + PP_TCPSocket_Option_Dev name, + const ::ppapi::SocketOptionData& value) { } void MockPluginDelegate::TCPSocketDisconnect(uint32 socket_id) { diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.h b/webkit/plugins/ppapi/mock_plugin_delegate.h index c1d74f0..7d1abb3 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.h +++ b/webkit/plugins/ppapi/mock_plugin_delegate.h @@ -132,9 +132,9 @@ 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 TCPSocketSetBoolOption(uint32 socket_id, - PP_TCPSocketOption_Private name, - bool value); + virtual void TCPSocketSetOption(uint32 socket_id, + PP_TCPSocket_Option_Dev name, + const ::ppapi::SocketOptionData& value); virtual void RegisterTCPSocket(PPB_TCPSocket_Private_Impl* socket, uint32 socket_id); virtual void TCPServerSocketListen(PP_Resource socket_resource, diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h index 962c78b..1e1dfb5 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -22,6 +22,7 @@ #include "media/video/video_decode_accelerator.h" #include "ppapi/c/dev/pp_video_dev.h" #include "ppapi/c/dev/ppb_device_ref_dev.h" +#include "ppapi/c/dev/ppb_tcp_socket_dev.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_file_info.h" @@ -69,6 +70,7 @@ struct Mailbox; namespace ppapi { class PepperFilePath; class PPB_X509Certificate_Fields; +class SocketOptionData; struct DeviceRefData; struct HostPortPair; struct Preferences; @@ -571,9 +573,9 @@ 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 TCPSocketSetBoolOption(uint32 socket_id, - PP_TCPSocketOption_Private name, - bool value) = 0; + virtual void TCPSocketSetOption(uint32 socket_id, + PP_TCPSocket_Option_Dev name, + const ::ppapi::SocketOptionData& value) = 0; virtual void RegisterTCPSocket(PPB_TCPSocket_Private_Impl* socket, uint32 socket_id) = 0; diff --git a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc index b2c80d1..318a206 100644 --- a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc +++ b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc @@ -4,6 +4,7 @@ #include "webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h" +#include "ppapi/shared_impl/socket_option_data.h" #include "webkit/plugins/ppapi/host_globals.h" #include "webkit/plugins/ppapi/plugin_delegate.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" @@ -110,14 +111,14 @@ void PPB_TCPSocket_Private_Impl::SendDisconnect() { plugin_delegate->TCPSocketDisconnect(socket_id_); } -void PPB_TCPSocket_Private_Impl::SendSetBoolOption( - PP_TCPSocketOption_Private name, - bool value) { +void PPB_TCPSocket_Private_Impl::SendSetOption( + PP_TCPSocket_Option_Dev name, + const ::ppapi::SocketOptionData& value) { PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this); if (!plugin_delegate) return; - plugin_delegate->TCPSocketSetBoolOption(socket_id_, name, value); + plugin_delegate->TCPSocketSetOption(socket_id_, name, value); } PluginDelegate* PPB_TCPSocket_Private_Impl::GetPluginDelegate( diff --git a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h index 80d077a..9d7545e 100644 --- a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h +++ b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h @@ -35,8 +35,8 @@ class PPB_TCPSocket_Private_Impl : public ::ppapi::TCPSocketPrivateImpl { virtual void SendRead(int32_t bytes_to_read) OVERRIDE; virtual void SendWrite(const std::string& buffer) OVERRIDE; virtual void SendDisconnect() OVERRIDE; - virtual void SendSetBoolOption(PP_TCPSocketOption_Private name, - bool value) OVERRIDE; + virtual void SendSetOption(PP_TCPSocket_Option_Dev name, + const ::ppapi::SocketOptionData& value) OVERRIDE; private: PPB_TCPSocket_Private_Impl(PP_Instance instance, uint32 socket_id); |