diff options
author | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-06 20:33:04 +0000 |
---|---|---|
committer | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-06 20:33:04 +0000 |
commit | fd4845aca2d351acd3453b9679ab8671b3293515 (patch) | |
tree | 2f39f3107a0cf136cfad3e8c0ddfb4b4e48ab254 /content | |
parent | f075c0b5545ad496e51adbc126986668d5a25f0b (diff) | |
download | chromium_src-fd4845aca2d351acd3453b9679ab8671b3293515.zip chromium_src-fd4845aca2d351acd3453b9679ab8671b3293515.tar.gz chromium_src-fd4845aca2d351acd3453b9679ab8671b3293515.tar.bz2 |
PepperUDPSocketPrivateHost is switched to PepperUDPSocketPrivateMessageFilter. Also, deleted obsolete methods from pepper socket utils.
BUG=164370, 179385
TEST=browser_tests:*UDPSocketPrivate*
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=184399
Review URL: https://chromiumcodereview.appspot.com/12263038
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@186493 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc | 8 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/pepper_socket_utils.h | 63 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/pepper_udp_socket_private_host.cc | 354 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc | 393 | ||||
-rw-r--r-- | content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h (renamed from content/browser/renderer_host/pepper/pepper_udp_socket_private_host.h) | 83 | ||||
-rw-r--r-- | content/content_browser.gypi | 4 |
6 files changed, 443 insertions, 462 deletions
diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc index 2089b1c..99e40a1 100644 --- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc +++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc @@ -11,7 +11,7 @@ #include "content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.h" #include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h" #include "content/browser/renderer_host/pepper/pepper_printing_host.h" -#include "content/browser/renderer_host/pepper/pepper_udp_socket_private_host.h" +#include "content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h" #include "ppapi/host/message_filter_host.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/host/resource_host.h" @@ -85,8 +85,10 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost( host_->GetPpapiHost(), instance, params.pp_resource(), host_resolver)); } if (message.type() == PpapiHostMsg_UDPSocketPrivate_Create::ID) { - return scoped_ptr<ResourceHost>(new PepperUDPSocketPrivateHost( - host_, instance, params.pp_resource())); + scoped_refptr<ResourceMessageFilter> udp_socket( + new PepperUDPSocketPrivateMessageFilter(host_, instance)); + return scoped_ptr<ResourceHost>(new MessageFilterHost( + host_->GetPpapiHost(), instance, params.pp_resource(), udp_socket)); } // Flash interfaces. diff --git a/content/browser/renderer_host/pepper/pepper_socket_utils.h b/content/browser/renderer_host/pepper/pepper_socket_utils.h index 4bfbb18..4e1b0fc 100644 --- a/content/browser/renderer_host/pepper/pepper_socket_utils.h +++ b/content/browser/renderer_host/pepper/pepper_socket_utils.h @@ -5,14 +5,8 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SOCKET_UTILS_H_ #define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SOCKET_UTILS_H_ -#include "base/callback.h" -#include "base/logging.h" -#include "base/tracked_objects.h" -#include "content/public/browser/browser_ppapi_host.h" -#include "content/public/browser/browser_thread.h" #include "content/public/common/process_type.h" #include "content/public/common/socket_permission_request.h" -#include "ppapi/c/pp_instance.h" struct PP_NetAddress_Private; @@ -30,63 +24,6 @@ bool CanUseSocketAPIs(ProcessType plugin_process_type, const SocketPermissionRequest& params, RenderViewHost* render_view_host); -// Backend for PostOnUIThreadWithRenderViewHostAndReply. This converts the IDs -// to a RenderViewHost and calls the function, or returns a -// default-constructed return value on error. -template<typename ReturnType> -ReturnType CallWithRenderViewHost( - int render_process_id, - int render_view_id, - const base::Callback<ReturnType(RenderViewHost*)>& task) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - RenderViewHost* render_view_host = RenderViewHost::FromID(render_process_id, - render_view_id); - if (render_view_host) - return task.Run(render_view_host); - return ReturnType(); -} - -// Schedules the given callback to execute on the UI thread of the browser, -// passing the RenderViewHost associated with the given instance as a -// parameter. -// -// Normally this would be called from a ResourceHost with the reply using -// a weak pointer to itself. -// -// Importantly, the task will not be run if the RenderView is destroyed by -// the time we get to the UI thread, or if the PP_Instance is invalid, but -// the reply will still be run. The return type in this case will be a -// default-constructed |ReturnType|. -// -// So you may want to make sure you don't do silly things in the reply -// handler if the task on the UI thread is never run and you get a -// default-constructed result. -template<typename ReturnType> -bool PostOnUIThreadWithRenderViewHostAndReply( - const BrowserPpapiHost* browser_ppapi_host, - const tracked_objects::Location& from_here, - PP_Instance instance, - const base::Callback<ReturnType(RenderViewHost*)>& task, - const base::Callback<void(ReturnType)>& reply) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - int render_process_id, render_view_id; - bool success = browser_ppapi_host->GetRenderViewIDsForInstance( - instance, - &render_process_id, - &render_view_id); - if (!success) - return false; - BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::UI, - from_here, - base::Bind(&CallWithRenderViewHost<ReturnType>, - render_process_id, render_view_id, task), - reply); - return true; -} - } // namespace pepper_socket_utils } // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_private_host.cc b/content/browser/renderer_host/pepper/pepper_udp_socket_private_host.cc deleted file mode 100644 index a875997..0000000 --- a/content/browser/renderer_host/pepper/pepper_udp_socket_private_host.cc +++ /dev/null @@ -1,354 +0,0 @@ -// 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/pepper_udp_socket_private_host.h" - -#include <cstring> -#include <limits> - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" -#include "content/browser/renderer_host/pepper/pepper_socket_utils.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/common/process_type.h" -#include "content/public/common/socket_permission_request.h" -#include "ipc/ipc_message_macros.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/udp/udp_server_socket.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/c/private/ppb_net_address_private.h" -#include "ppapi/c/private/ppb_udp_socket_private.h" -#include "ppapi/host/dispatch_host_message.h" -#include "ppapi/host/host_message_context.h" -#include "ppapi/host/ppapi_host.h" -#include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/proxy/udp_socket_private_resource.h" -#include "ppapi/shared_impl/private/net_address_private_impl.h" - -using ppapi::NetAddressPrivateImpl; - -namespace content { - -PepperUDPSocketPrivateHost::PepperUDPSocketPrivateHost( - BrowserPpapiHostImpl* host, - PP_Instance instance, - PP_Resource resource) - : ResourceHost(host->GetPpapiHost(), instance, resource), - allow_address_reuse_(false), - allow_broadcast_(false), - closed_(false), - host_(host), - weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { - DCHECK(host_); -} - -PepperUDPSocketPrivateHost::~PepperUDPSocketPrivateHost() { - Close(); -} - -int32_t PepperUDPSocketPrivateHost::OnResourceMessageReceived( - const IPC::Message& msg, - ppapi::host::HostMessageContext* context) { - IPC_BEGIN_MESSAGE_MAP(PepperUDPSocketPrivateHost, msg) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_UDPSocketPrivate_SetBoolSocketFeature, - OnMsgSetBoolSocketFeature) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_UDPSocketPrivate_Bind, - OnMsgBind) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_UDPSocketPrivate_RecvFrom, - OnMsgRecvFrom) - PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocketPrivate_SendTo, - OnMsgSendTo) - PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( - PpapiHostMsg_UDPSocketPrivate_Close, - OnMsgClose) - IPC_END_MESSAGE_MAP() - return PP_ERROR_FAILED; -} - -int32_t PepperUDPSocketPrivateHost::OnMsgSetBoolSocketFeature( - const ppapi::host::HostMessageContext* context, - int32_t name, - bool value) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(!socket_.get()); - DCHECK(!closed()); - - switch(static_cast<PP_UDPSocketFeature_Private>(name)) { - case PP_UDPSOCKETFEATURE_ADDRESS_REUSE: - allow_address_reuse_ = value; - break; - case PP_UDPSOCKETFEATURE_BROADCAST: - allow_broadcast_ = value; - break; - default: - NOTREACHED(); - break; - } - return PP_OK; -} - -int32_t PepperUDPSocketPrivateHost::OnMsgBind( - const ppapi::host::HostMessageContext* context, - const PP_NetAddress_Private& addr) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(context); - - if (bind_context_.get()) - return PP_ERROR_INPROGRESS; - bind_context_.reset( - new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext())); - - SocketPermissionRequest params = - pepper_socket_utils::CreateSocketPermissionRequest( - SocketPermissionRequest::UDP_BIND, addr); - CheckSocketPermissionsAndReply(params, - base::Bind(&PepperUDPSocketPrivateHost::DoBind, - weak_factory_.GetWeakPtr(), - addr)); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PepperUDPSocketPrivateHost::OnMsgRecvFrom( - const ppapi::host::HostMessageContext* context, - int32_t num_bytes) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(context); - DCHECK(socket_.get()); - DCHECK(!closed()); - - if (recv_from_context_.get() || recvfrom_buffer_.get()) - return PP_ERROR_INPROGRESS; - recv_from_context_.reset( - new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext())); - if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize) { - // |num_bytes| value is checked on the plugin side. - NOTREACHED(); - num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize; - } - recvfrom_buffer_ = new net::IOBuffer(num_bytes); - int result = socket_->RecvFrom( - recvfrom_buffer_, num_bytes, &recvfrom_address_, - base::Bind(&PepperUDPSocketPrivateHost::OnRecvFromCompleted, - weak_factory_.GetWeakPtr())); - if (result != net::ERR_IO_PENDING) - OnRecvFromCompleted(result); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PepperUDPSocketPrivateHost::OnMsgSendTo( - const ppapi::host::HostMessageContext* context, - const std::string& data, - const PP_NetAddress_Private& addr) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(context); - - if (data.empty() || - data.size() > static_cast<size_t>(std::numeric_limits<int>::max())) { - return PP_ERROR_BADARGUMENT; - } - if (send_to_context_.get() || sendto_buffer_.get()) - return PP_ERROR_INPROGRESS; - send_to_context_.reset( - new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext())); - int num_bytes = data.size(); - if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize) { - // Size of |data| is checked on the plugin side. - NOTREACHED(); - num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize; - } - sendto_buffer_ = new net::IOBufferWithSize(num_bytes); - memcpy(sendto_buffer_->data(), data.data(), num_bytes); - SocketPermissionRequest params = - pepper_socket_utils::CreateSocketPermissionRequest( - SocketPermissionRequest::UDP_SEND_TO, addr); - CheckSocketPermissionsAndReply(params, - base::Bind( - &PepperUDPSocketPrivateHost::DoSendTo, - weak_factory_.GetWeakPtr(), - addr)); - return PP_OK_COMPLETIONPENDING; -} - -int32_t PepperUDPSocketPrivateHost::OnMsgClose( - const ppapi::host::HostMessageContext* context) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - Close(); - return PP_OK; -} - -void PepperUDPSocketPrivateHost::DoBind(const PP_NetAddress_Private& addr, - bool allowed) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(!closed()); - - if (!allowed) { - SendBindError(); - return; - } - - socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source())); - - net::IPAddressNumber address; - int port; - if (!socket_.get() || - !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { - SendBindError(); - return; - } - - if (allow_address_reuse_) - socket_->AllowAddressReuse(); - if (allow_broadcast_) - socket_->AllowBroadcast(); - - int result = socket_->Listen(net::IPEndPoint(address, port)); - - if (result == net::OK && - socket_->GetLocalAddress(&bound_address_) != net::OK) { - SendBindError(); - return; - } - - OnBindCompleted(result); -} - -void PepperUDPSocketPrivateHost::DoSendTo(const PP_NetAddress_Private& addr, - bool allowed) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK(socket_.get()); - DCHECK(sendto_buffer_.get()); - DCHECK(!closed()); - - if (!allowed) { - SendSendToError(); - return; - } - - net::IPAddressNumber address; - int port; - if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { - SendSendToError(); - return; - } - - int result = socket_->SendTo( - sendto_buffer_, sendto_buffer_->size(), net::IPEndPoint(address, port), - base::Bind(&PepperUDPSocketPrivateHost::OnSendToCompleted, - weak_factory_.GetWeakPtr())); - - if (result != net::ERR_IO_PENDING) - OnSendToCompleted(result); -} - -void PepperUDPSocketPrivateHost::Close() { - if (socket_.get() && !closed_) - socket_->Close(); - closed_ = true; -} - -void PepperUDPSocketPrivateHost::OnBindCompleted(int result) { - PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress; - if (result < 0 || - !NetAddressPrivateImpl::IPEndPointToNetAddress(bound_address_.address(), - bound_address_.port(), - &addr)) { - SendBindError(); - } else { - SendBindReply(true, addr); - } -} - -void PepperUDPSocketPrivateHost::OnRecvFromCompleted(int result) { - DCHECK(recvfrom_buffer_.get()); - - // Convert IPEndPoint we get back from RecvFrom to a PP_NetAddress_Private, - // to send back. - PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress; - if (result < 0 || - !NetAddressPrivateImpl::IPEndPointToNetAddress( - recvfrom_address_.address(), - recvfrom_address_.port(), - &addr)) { - SendRecvFromError(); - } else { - SendRecvFromReply(true, - std::string(recvfrom_buffer_->data(), result), - addr); - } - - recvfrom_buffer_ = NULL; -} - -void PepperUDPSocketPrivateHost::OnSendToCompleted(int result) { - DCHECK(sendto_buffer_.get()); - if (result < 0) - SendSendToError(); - else - SendSendToReply(true, result); - sendto_buffer_ = NULL; -} - -void PepperUDPSocketPrivateHost::SendBindReply( - bool succeeded, - const PP_NetAddress_Private& addr) { - DCHECK(bind_context_.get()); - - scoped_ptr<ppapi::host::ReplyMessageContext> context(bind_context_.release()); - host()->SendReply(*context, - PpapiPluginMsg_UDPSocketPrivate_BindReply(succeeded, addr)); -} - -void PepperUDPSocketPrivateHost::SendRecvFromReply( - bool succeeded, - const std::string& data, - const PP_NetAddress_Private& addr) { - DCHECK(recv_from_context_.get()); - - scoped_ptr<ppapi::host::ReplyMessageContext> context( - recv_from_context_.release()); - host()->SendReply(*context, - PpapiPluginMsg_UDPSocketPrivate_RecvFromReply(succeeded, - data, - addr)); -} - -void PepperUDPSocketPrivateHost::SendSendToReply(bool succeeded, - int32_t bytes_written) { - DCHECK(send_to_context_.get()); - - scoped_ptr<ppapi::host::ReplyMessageContext> context( - send_to_context_.release()); - host()->SendReply(*context, - PpapiPluginMsg_UDPSocketPrivate_SendToReply(succeeded, - bytes_written)); -} - -void PepperUDPSocketPrivateHost::CheckSocketPermissionsAndReply( - const SocketPermissionRequest& params, - const RequestCallback& callback) { - pepper_socket_utils::PostOnUIThreadWithRenderViewHostAndReply( - host_, FROM_HERE, pp_instance(), - base::Bind(&pepper_socket_utils::CanUseSocketAPIs, - host_->plugin_process_type(), params), - callback); -} - -void PepperUDPSocketPrivateHost::SendBindError() { - SendBindReply(false, NetAddressPrivateImpl::kInvalidNetAddress); -} - -void PepperUDPSocketPrivateHost::SendRecvFromError() { - SendRecvFromReply(false, "", NetAddressPrivateImpl::kInvalidNetAddress); -} - -void PepperUDPSocketPrivateHost::SendSendToError() { - SendSendToReply(false, 0); -} - -} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc new file mode 100644 index 0000000..3a5f8f5 --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc @@ -0,0 +1,393 @@ +// 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/pepper_udp_socket_private_message_filter.h" + +#include <cstring> +#include <limits> + +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" +#include "content/browser/renderer_host/pepper/pepper_socket_utils.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/process_type.h" +#include "content/public/common/socket_permission_request.h" +#include "ipc/ipc_message_macros.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/udp/udp_server_socket.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_net_address_private.h" +#include "ppapi/c/private/ppb_udp_socket_private.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/udp_socket_private_resource.h" +#include "ppapi/shared_impl/private/net_address_private_impl.h" + +using ppapi::NetAddressPrivateImpl; + +namespace content { + +namespace { + +bool CanUseSocketAPIs(const SocketPermissionRequest& request, + ProcessType plugin_process_type, + int render_process_id, + int render_view_id) { + RenderViewHost* render_view_host = RenderViewHost::FromID(render_process_id, + render_view_id); + return render_view_host && + pepper_socket_utils::CanUseSocketAPIs(plugin_process_type, + request, + render_view_host); +} + +} // namespace + +PepperUDPSocketPrivateMessageFilter::PepperUDPSocketPrivateMessageFilter( + BrowserPpapiHostImpl* host, + PP_Instance instance) + : allow_address_reuse_(false), + allow_broadcast_(false), + closed_(false), + plugin_process_type_(host->plugin_process_type()), + render_process_id_(0), + render_view_id_(0) { + DCHECK(host); + + if (!host->GetRenderViewIDsForInstance( + instance, + &render_process_id_, + &render_view_id_)) { + NOTREACHED(); + } +} + +PepperUDPSocketPrivateMessageFilter::~PepperUDPSocketPrivateMessageFilter() { + Close(); +} + +scoped_refptr<base::TaskRunner> +PepperUDPSocketPrivateMessageFilter::OverrideTaskRunnerForMessage( + const IPC::Message& message) { + switch (message.type()) { + case PpapiHostMsg_UDPSocketPrivate_SetBoolSocketFeature::ID: + case PpapiHostMsg_UDPSocketPrivate_RecvFrom::ID: + case PpapiHostMsg_UDPSocketPrivate_Close::ID: + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); + case PpapiHostMsg_UDPSocketPrivate_Bind::ID: + case PpapiHostMsg_UDPSocketPrivate_SendTo::ID: + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); + } + return NULL; +} + +int32_t PepperUDPSocketPrivateMessageFilter::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + IPC_BEGIN_MESSAGE_MAP(PepperUDPSocketPrivateMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_UDPSocketPrivate_SetBoolSocketFeature, + OnMsgSetBoolSocketFeature) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_UDPSocketPrivate_Bind, + OnMsgBind) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_UDPSocketPrivate_RecvFrom, + OnMsgRecvFrom) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_UDPSocketPrivate_SendTo, + OnMsgSendTo) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( + PpapiHostMsg_UDPSocketPrivate_Close, + OnMsgClose) + IPC_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperUDPSocketPrivateMessageFilter::OnMsgSetBoolSocketFeature( + const ppapi::host::HostMessageContext* context, + int32_t name, + bool value) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(!socket_.get()); + + if (closed_) + return PP_ERROR_FAILED; + + switch(static_cast<PP_UDPSocketFeature_Private>(name)) { + case PP_UDPSOCKETFEATURE_ADDRESS_REUSE: + allow_address_reuse_ = value; + break; + case PP_UDPSOCKETFEATURE_BROADCAST: + allow_broadcast_ = value; + break; + default: + NOTREACHED(); + break; + } + return PP_OK; +} + +int32_t PepperUDPSocketPrivateMessageFilter::OnMsgBind( + const ppapi::host::HostMessageContext* context, + const PP_NetAddress_Private& addr) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(context); + + SocketPermissionRequest request = + pepper_socket_utils::CreateSocketPermissionRequest( + SocketPermissionRequest::UDP_BIND, addr); + if (!CanUseSocketAPIs(request, plugin_process_type_, + render_process_id_, render_view_id_)) { + return PP_ERROR_FAILED; + } + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&PepperUDPSocketPrivateMessageFilter::DoBind, this, + context->MakeReplyMessageContext(), + addr)); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperUDPSocketPrivateMessageFilter::OnMsgRecvFrom( + const ppapi::host::HostMessageContext* context, + int32_t num_bytes) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(context); + DCHECK(socket_.get()); + + if (closed_) + return PP_ERROR_FAILED; + + if (recvfrom_buffer_.get()) + return PP_ERROR_INPROGRESS; + if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize) { + // |num_bytes| value is checked on the plugin side. + NOTREACHED(); + num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize; + } + recvfrom_buffer_ = new net::IOBuffer(num_bytes); + int result = socket_->RecvFrom( + recvfrom_buffer_, num_bytes, &recvfrom_address_, + base::Bind(&PepperUDPSocketPrivateMessageFilter::OnRecvFromCompleted, + this, context->MakeReplyMessageContext())); + if (result != net::ERR_IO_PENDING) + OnRecvFromCompleted(context->MakeReplyMessageContext(), result); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperUDPSocketPrivateMessageFilter::OnMsgSendTo( + const ppapi::host::HostMessageContext* context, + const std::string& data, + const PP_NetAddress_Private& addr) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(context); + + SocketPermissionRequest request = + pepper_socket_utils::CreateSocketPermissionRequest( + SocketPermissionRequest::UDP_SEND_TO, addr); + if (!CanUseSocketAPIs(request, plugin_process_type_, + render_process_id_, render_view_id_)) { + return PP_ERROR_FAILED; + } + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&PepperUDPSocketPrivateMessageFilter::DoSendTo, this, + context->MakeReplyMessageContext(), data, addr)); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperUDPSocketPrivateMessageFilter::OnMsgClose( + const ppapi::host::HostMessageContext* context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + Close(); + return PP_OK; +} + +void PepperUDPSocketPrivateMessageFilter::DoBind( + const ppapi::host::ReplyMessageContext& context, + const PP_NetAddress_Private& addr) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (closed_) { + SendBindError(context, PP_ERROR_FAILED); + return; + } + + socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source())); + + net::IPAddressNumber address; + int port; + if (!socket_.get() || + !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { + SendBindError(context, PP_ERROR_FAILED); + return; + } + + if (allow_address_reuse_) + socket_->AllowAddressReuse(); + if (allow_broadcast_) + socket_->AllowBroadcast(); + + int result = socket_->Listen(net::IPEndPoint(address, port)); + + net::IPEndPoint bound_address; + PP_NetAddress_Private net_address = NetAddressPrivateImpl::kInvalidNetAddress; + if (result != net::OK || + socket_->GetLocalAddress(&bound_address) != net::OK || + !NetAddressPrivateImpl::IPEndPointToNetAddress(bound_address.address(), + bound_address.port(), + &net_address)) { + SendBindError(context, PP_ERROR_FAILED); + } else { + SendBindReply(context, PP_OK, net_address); + } +} + +void PepperUDPSocketPrivateMessageFilter::DoSendTo( + const ppapi::host::ReplyMessageContext& context, + const std::string& data, + const PP_NetAddress_Private& addr) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(socket_.get()); + + if (closed_) { + SendSendToError(context, PP_ERROR_FAILED); + return; + } + + if (sendto_buffer_.get()) { + SendSendToError(context, PP_ERROR_INPROGRESS); + return; + } + + if (data.empty() || + data.size() > static_cast<size_t>(std::numeric_limits<int>::max())) { + SendSendToError(context, PP_ERROR_BADARGUMENT); + return; + } + size_t num_bytes = data.size(); + if (num_bytes > static_cast<size_t>( + ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize)) { + // Size of |data| is checked on the plugin side. + NOTREACHED(); + num_bytes = static_cast<size_t>( + ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize); + } + sendto_buffer_ = new net::IOBufferWithSize(num_bytes); + memcpy(sendto_buffer_->data(), data.data(), num_bytes); + + net::IPAddressNumber address; + int port; + if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { + SendSendToError(context, PP_ERROR_FAILED); + return; + } + + int result = socket_->SendTo( + sendto_buffer_, sendto_buffer_->size(), net::IPEndPoint(address, port), + base::Bind(&PepperUDPSocketPrivateMessageFilter::OnSendToCompleted, this, + context)); + if (result != net::ERR_IO_PENDING) + OnSendToCompleted(context, result); +} + +void PepperUDPSocketPrivateMessageFilter::Close() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (socket_.get() && !closed_) + socket_->Close(); + closed_ = true; +} + +void PepperUDPSocketPrivateMessageFilter::OnRecvFromCompleted( + const ppapi::host::ReplyMessageContext& context, + int32_t result) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(recvfrom_buffer_.get()); + + // Convert IPEndPoint we get back from RecvFrom to a PP_NetAddress_Private, + // to send back. + PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress; + if (result < 0 || + !NetAddressPrivateImpl::IPEndPointToNetAddress( + recvfrom_address_.address(), + recvfrom_address_.port(), + &addr)) { + SendRecvFromError(context, PP_ERROR_FAILED); + } else { + SendRecvFromReply(context, PP_OK, + std::string(recvfrom_buffer_->data(), result), addr); + } + + recvfrom_buffer_ = NULL; +} + +void PepperUDPSocketPrivateMessageFilter::OnSendToCompleted( + const ppapi::host::ReplyMessageContext& context, + int32_t result) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(sendto_buffer_.get()); + if (result < 0) + SendSendToError(context, PP_ERROR_FAILED); + else + SendSendToReply(context, PP_OK, result); + sendto_buffer_ = NULL; +} + +void PepperUDPSocketPrivateMessageFilter::SendBindReply( + const ppapi::host::ReplyMessageContext& context, + int32_t result, + const PP_NetAddress_Private& addr) { + ppapi::host::ReplyMessageContext reply_context(context); + reply_context.params.set_result(result); + SendReply(reply_context, PpapiPluginMsg_UDPSocketPrivate_BindReply(addr)); +} + +void PepperUDPSocketPrivateMessageFilter::SendRecvFromReply( + const ppapi::host::ReplyMessageContext& context, + int32_t result, + const std::string& data, + const PP_NetAddress_Private& addr) { + ppapi::host::ReplyMessageContext reply_context(context); + reply_context.params.set_result(result); + SendReply(reply_context, + PpapiPluginMsg_UDPSocketPrivate_RecvFromReply(data, addr)); +} + +void PepperUDPSocketPrivateMessageFilter::SendSendToReply( + const ppapi::host::ReplyMessageContext& context, + int32_t result, + int32_t bytes_written) { + ppapi::host::ReplyMessageContext reply_context(context); + reply_context.params.set_result(result); + SendReply(reply_context, + PpapiPluginMsg_UDPSocketPrivate_SendToReply(bytes_written)); +} + +void PepperUDPSocketPrivateMessageFilter::SendBindError( + const ppapi::host::ReplyMessageContext& context, + int32_t result) { + SendBindReply(context, result, NetAddressPrivateImpl::kInvalidNetAddress); +} + +void PepperUDPSocketPrivateMessageFilter::SendRecvFromError( + const ppapi::host::ReplyMessageContext& context, + int32_t result) { + SendRecvFromReply(context, result, "", + NetAddressPrivateImpl::kInvalidNetAddress); +} + +void PepperUDPSocketPrivateMessageFilter::SendSendToError( + const ppapi::host::ReplyMessageContext& context, + int32_t result) { + SendSendToReply(context, result, 0); +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_private_host.h b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h index 7634ba3..eb62a1f 100644 --- a/content/browser/renderer_host/pepper/pepper_udp_socket_private_host.h +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h @@ -2,8 +2,8 @@ // 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_PEPPER_UDP_SOCKET_PRIVATE_HOST_H_ -#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_PRIVATE_HOST_H_ +#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_PRIVATE_MESSAGE_FILTER_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_PRIVATE_MESSAGE_FILTER_H_ #include <string> @@ -12,12 +12,13 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" #include "content/common/content_export.h" +#include "content/public/common/process_type.h" #include "net/base/completion_callback.h" #include "net/base/ip_endpoint.h" +#include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_stdint.h" -#include "ppapi/host/resource_host.h" +#include "ppapi/host/resource_message_filter.h" struct PP_NetAddress_Private; @@ -38,22 +39,23 @@ namespace content { class BrowserPpapiHostImpl; struct SocketPermissionRequest; -class CONTENT_EXPORT PepperUDPSocketPrivateHost - : public ppapi::host::ResourceHost { +class CONTENT_EXPORT PepperUDPSocketPrivateMessageFilter + : public ppapi::host::ResourceMessageFilter { public: - PepperUDPSocketPrivateHost(BrowserPpapiHostImpl* host, - PP_Instance instance, - PP_Resource resource); - virtual ~PepperUDPSocketPrivateHost(); + PepperUDPSocketPrivateMessageFilter(BrowserPpapiHostImpl* host, + PP_Instance instance); - // ppapi::host::ResourceHost implementation. + protected: + virtual ~PepperUDPSocketPrivateMessageFilter(); + + private: + // ppapi::host::ResourceMessageFilter overrides. + virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage( + const IPC::Message& message) OVERRIDE; virtual int32_t OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) OVERRIDE; - private: - typedef base::Callback<void(bool allowed)> RequestCallback; - int32_t OnMsgSetBoolSocketFeature( const ppapi::host::HostMessageContext* context, int32_t name, @@ -67,29 +69,35 @@ class CONTENT_EXPORT PepperUDPSocketPrivateHost const PP_NetAddress_Private& addr); int32_t OnMsgClose(const ppapi::host::HostMessageContext* context); - void DoBind(const PP_NetAddress_Private& addr, bool allowed); - void DoSendTo(const PP_NetAddress_Private& addr, bool allowed); + void DoBind(const ppapi::host::ReplyMessageContext& context, + const PP_NetAddress_Private& addr); + void DoSendTo(const ppapi::host::ReplyMessageContext& context, + const std::string& data, + const PP_NetAddress_Private& addr); void Close(); - void OnBindCompleted(int result); - void OnRecvFromCompleted(int result); - void OnSendToCompleted(int result); + void OnRecvFromCompleted(const ppapi::host::ReplyMessageContext& context, + int32_t result); + void OnSendToCompleted(const ppapi::host::ReplyMessageContext& context, + int32_t result); - void SendBindReply(bool succeeded, + void SendBindReply(const ppapi::host::ReplyMessageContext& context, + int32_t result, const PP_NetAddress_Private& addr); - void SendRecvFromReply(bool succeeded, + void SendRecvFromReply(const ppapi::host::ReplyMessageContext& context, + int32_t result, const std::string& data, const PP_NetAddress_Private& addr); - void SendSendToReply(bool succeeded, int32_t bytes_written); + void SendSendToReply(const ppapi::host::ReplyMessageContext& context, + int32_t result, + int32_t bytes_written); - void SendBindError(); - void SendRecvFromError(); - void SendSendToError(); - - void CheckSocketPermissionsAndReply(const SocketPermissionRequest& params, - const RequestCallback& callback); - - bool closed() { return closed_; } + void SendBindError(const ppapi::host::ReplyMessageContext& context, + int32_t result); + void SendRecvFromError(const ppapi::host::ReplyMessageContext& context, + int32_t result); + void SendSendToError(const ppapi::host::ReplyMessageContext& context, + int32_t result); bool allow_address_reuse_; bool allow_broadcast_; @@ -101,19 +109,14 @@ class CONTENT_EXPORT PepperUDPSocketPrivateHost scoped_refptr<net::IOBufferWithSize> sendto_buffer_; net::IPEndPoint recvfrom_address_; - net::IPEndPoint bound_address_; - - scoped_ptr<ppapi::host::ReplyMessageContext> bind_context_; - scoped_ptr<ppapi::host::ReplyMessageContext> recv_from_context_; - scoped_ptr<ppapi::host::ReplyMessageContext> send_to_context_; - - BrowserPpapiHostImpl* host_; - base::WeakPtrFactory<PepperUDPSocketPrivateHost> weak_factory_; + ProcessType plugin_process_type_; + int render_process_id_; + int render_view_id_; - DISALLOW_COPY_AND_ASSIGN(PepperUDPSocketPrivateHost); + DISALLOW_COPY_AND_ASSIGN(PepperUDPSocketPrivateMessageFilter); }; } // namespace content -#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_PRIVATE_HOST_H_ +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_UDP_SOCKET_PRIVATE_MESSAGE_FILTER_H_ diff --git a/content/content_browser.gypi b/content/content_browser.gypi index d3b9393..866bf9b 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -738,8 +738,8 @@ 'browser/renderer_host/pepper/pepper_tcp_server_socket.h', 'browser/renderer_host/pepper/pepper_tcp_socket.cc', 'browser/renderer_host/pepper/pepper_tcp_socket.h', - 'browser/renderer_host/pepper/pepper_udp_socket_private_host.cc', - 'browser/renderer_host/pepper/pepper_udp_socket_private_host.h', + 'browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc', + 'browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.h', 'browser/renderer_host/popup_menu_helper_mac.h', 'browser/renderer_host/popup_menu_helper_mac.mm', 'browser/renderer_host/quota_dispatcher_host.cc', |