diff options
author | mtilburg@adobe.com <mtilburg@adobe.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-26 22:12:56 +0000 |
---|---|---|
committer | mtilburg@adobe.com <mtilburg@adobe.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-26 22:12:56 +0000 |
commit | 7813eb0bc4ed845c361493ef3e1f0290fe16c3b0 (patch) | |
tree | f0c740d8a536c7a4c120016af0c99c43a9ae83e8 /ppapi | |
parent | a3e2de75e309b527cd694b16d23100bbec1710d9 (diff) | |
download | chromium_src-7813eb0bc4ed845c361493ef3e1f0290fe16c3b0.zip chromium_src-7813eb0bc4ed845c361493ef3e1f0290fe16c3b0.tar.gz chromium_src-7813eb0bc4ed845c361493ef3e1f0290fe16c3b0.tar.bz2 |
Add Pepper API to use UDP
author: mtilburg@adobe.com
BUG=none
TEST=tested with pepper flash
Review URL: http://codereview.chromium.org/8036036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102817 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/api/private/ppb_flash_udp_socket.idl | 59 | ||||
-rw-r--r-- | ppapi/c/private/ppb_flash_udp_socket.h | 76 | ||||
-rw-r--r-- | ppapi/cpp/private/flash_udp_socket.cc | 72 | ||||
-rw-r--r-- | ppapi/cpp/private/flash_udp_socket.h | 40 | ||||
-rw-r--r-- | ppapi/ppapi_cpp.gypi | 1 | ||||
-rw-r--r-- | ppapi/ppapi_proxy.gypi | 2 | ||||
-rw-r--r-- | ppapi/ppapi_shared.gypi | 2 | ||||
-rw-r--r-- | ppapi/proxy/interface_id.h | 1 | ||||
-rw-r--r-- | ppapi/proxy/interface_list.cc | 3 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 35 | ||||
-rw-r--r-- | ppapi/proxy/ppb_flash_udp_socket_proxy.cc | 390 | ||||
-rw-r--r-- | ppapi/proxy/ppb_flash_udp_socket_proxy.h | 60 | ||||
-rw-r--r-- | ppapi/proxy/resource_creation_proxy.cc | 6 | ||||
-rw-r--r-- | ppapi/proxy/resource_creation_proxy.h | 1 | ||||
-rw-r--r-- | ppapi/shared_impl/resource.h | 1 | ||||
-rw-r--r-- | ppapi/thunk/ppb_flash_udp_socket_api.h | 34 | ||||
-rw-r--r-- | ppapi/thunk/ppb_flash_udp_socket_thunk.cc | 98 | ||||
-rw-r--r-- | ppapi/thunk/resource_creation_api.h | 1 | ||||
-rw-r--r-- | ppapi/thunk/thunk.h | 2 |
19 files changed, 884 insertions, 0 deletions
diff --git a/ppapi/api/private/ppb_flash_udp_socket.idl b/ppapi/api/private/ppb_flash_udp_socket.idl new file mode 100644 index 0000000..7328db8 --- /dev/null +++ b/ppapi/api/private/ppb_flash_udp_socket.idl @@ -0,0 +1,59 @@ +/* Copyright (c) 2011 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * This file defines the <code>PPB_Flash_UDPSocket</code> interface. + */ + +label Chrome { + M16 = 0.1 +}; + +interface PPB_Flash_UDPSocket { + /** + * Creates a UDP socket resource. + */ + PP_Resource Create([in] PP_Instance instance_id); + + /** + * Determines if a given resource is a UDP socket. + */ + PP_Bool IsFlashUDPSocket([in] PP_Resource resource_id); + + /* Creates a socket and binds to the address given by |addr|. */ + int32_t Bind([in] PP_Resource udp_socket, + [in] PP_Flash_NetAddress addr, + [in] PP_CompletionCallback callback); + + /* Performs a non-blocking recvfrom call on socket. + * Bind must be called first. |callback| is invoked when recvfrom + * reads data. You must call GetRecvFromAddress to recover the + * address the data was retrieved from. + */ + int32_t RecvFrom([in] PP_Resource udp_socket, + [out] str_t buffer, + [in] int32_t num_bytes, + [in] PP_CompletionCallback callback); + + /* Upon successful completion of RecvFrom, the address that the data + * was received from is stored in |addr|. + */ + PP_Bool GetRecvFromAddress([in] PP_Resource udp_socket, + [out] PP_Flash_NetAddress addr); + + /* Performs a non-blocking sendto call on the socket created and + * bound(has already called Bind). The callback |callback| is + * invoked when sendto completes. + */ + int32_t SendTo([in] PP_Resource udp_socket, + [in] str_t buffer, + [in] int32_t num_bytes, + [in] PP_Flash_NetAddress addr, + [in] PP_CompletionCallback callback); + + /* Cancels all pending reads and writes, and closes the socket. */ + void Close([in] PP_Resource udp_socket); +}; + diff --git a/ppapi/c/private/ppb_flash_udp_socket.h b/ppapi/c/private/ppb_flash_udp_socket.h new file mode 100644 index 0000000..0909363 --- /dev/null +++ b/ppapi/c/private/ppb_flash_udp_socket.h @@ -0,0 +1,76 @@ +/* Copyright (c) 2011 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* From ppb_flash_udp_socket.idl modified Mon Sep 26 09:04:41 2011. */ + +#ifndef PPAPI_C_PRIVATE_PPB_FLASH_UDP_SOCKET_H_ +#define PPAPI_C_PRIVATE_PPB_FLASH_UDP_SOCKET_H_ + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_macros.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/c/private/ppb_flash_tcp_socket.h" + +#define PPB_FLASH_UDPSOCKET_INTERFACE_0_1 "PPB_Flash_UDPSocket;0.1" +#define PPB_FLASH_UDPSOCKET_INTERFACE PPB_FLASH_UDPSOCKET_INTERFACE_0_1 + +/** + * @file + * This file defines the <code>PPB_Flash_UDPSocket</code> interface. + */ + + +/** + * @addtogroup Interfaces + * @{ + */ +struct PPB_Flash_UDPSocket { + /** + * Creates a UDP socket resource. + */ + PP_Resource (*Create)(PP_Instance instance_id); + /** + * Determines if a given resource is a UDP socket. + */ + PP_Bool (*IsFlashUDPSocket)(PP_Resource resource_id); + /* Creates a socket and binds to the address given by |addr|. */ + int32_t (*Bind)(PP_Resource udp_socket, + const struct PP_Flash_NetAddress* addr, + struct PP_CompletionCallback callback); + /* Performs a non-blocking recvfrom call on socket. + * Bind must be called first. |callback| is invoked when recvfrom + * reads data. You must call GetRecvFromAddress to recover the + * address the data was retrieved from. + */ + int32_t (*RecvFrom)(PP_Resource udp_socket, + char* buffer, + int32_t num_bytes, + struct PP_CompletionCallback callback); + /* Upon successful completion of RecvFrom, the address that the data + * was received from is stored in |addr|. + */ + PP_Bool (*GetRecvFromAddress)(PP_Resource udp_socket, + struct PP_Flash_NetAddress* addr); + /* Performs a non-blocking sendto call on the socket created and + * bound(has already called Bind). The callback |callback| is + * invoked when sendto completes. + */ + int32_t (*SendTo)(PP_Resource udp_socket, + const char* buffer, + int32_t num_bytes, + const struct PP_Flash_NetAddress* addr, + struct PP_CompletionCallback callback); + /* Cancels all pending reads and writes, and closes the socket. */ + void (*Close)(PP_Resource udp_socket); +}; +/** + * @} + */ + +#endif /* PPAPI_C_PRIVATE_PPB_FLASH_UDP_SOCKET_H_ */ + diff --git a/ppapi/cpp/private/flash_udp_socket.cc b/ppapi/cpp/private/flash_udp_socket.cc new file mode 100644 index 0000000..1ac36a3 --- /dev/null +++ b/ppapi/cpp/private/flash_udp_socket.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/cpp/private/flash_udp_socket.h" + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/module_impl.h" + +namespace pp { + +namespace { + +template <> const char* interface_name<PPB_Flash_UDPSocket>() { + return PPB_FLASH_UDPSOCKET_INTERFACE; +} + +} // namespace + +namespace flash { + +UDPSocket::UDPSocket(Instance* instance) { + if (has_interface<PPB_Flash_UDPSocket>() && instance) { + PassRefFromConstructor(get_interface<PPB_Flash_UDPSocket>()->Create( + instance->pp_instance())); + } +} + +int32_t UDPSocket::Bind(const PP_Flash_NetAddress* addr, + const CompletionCallback& callback) { + if (!has_interface<PPB_Flash_UDPSocket>()) + return PP_ERROR_NOINTERFACE; + return get_interface<PPB_Flash_UDPSocket>()->Bind( + pp_resource(), addr, callback.pp_completion_callback()); +} + +int32_t UDPSocket::RecvFrom(char* buffer, + int32_t num_bytes, + const CompletionCallback& callback) { + if (!has_interface<PPB_Flash_UDPSocket>()) + return PP_ERROR_NOINTERFACE; + return get_interface<PPB_Flash_UDPSocket>()->RecvFrom( + pp_resource(), buffer, num_bytes, callback.pp_completion_callback()); +} + +bool UDPSocket::GetRecvFromAddress(PP_Flash_NetAddress* addr) { + if (!has_interface<PPB_Flash_UDPSocket>()) + return false; + + PP_Bool result = get_interface<PPB_Flash_UDPSocket>()->GetRecvFromAddress( + pp_resource(), addr); + return PP_ToBool(result); +} + +int32_t UDPSocket::SendTo(const char* buffer, + int32_t num_bytes, + const struct PP_Flash_NetAddress* addr, + const CompletionCallback& callback) { + if (!has_interface<PPB_Flash_UDPSocket>()) + return PP_ERROR_NOINTERFACE; + return get_interface<PPB_Flash_UDPSocket>()->SendTo( + pp_resource(), buffer, num_bytes, addr, + callback.pp_completion_callback()); +} + +} // namespace flash +} // namespace pp + diff --git a/ppapi/cpp/private/flash_udp_socket.h b/ppapi/cpp/private/flash_udp_socket.h new file mode 100644 index 0000000..e472c00 --- /dev/null +++ b/ppapi/cpp/private/flash_udp_socket.h @@ -0,0 +1,40 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_CPP_PRIVATE_FLASH_UDP_SOCKET_H_ +#define PPAPI_CPP_PRIVATE_FLASH_UDP_SOCKET_H_ + +#include "ppapi/c/pp_stdint.h" +#include "ppapi/c/private/ppb_flash_udp_socket.h" +#include "ppapi/cpp/resource.h" + +namespace pp { + +class CompletionCallback; +class Instance; + +namespace flash { + +class UDPSocket : public Resource { + public: + explicit UDPSocket(Instance* instance); + + int32_t Bind(const PP_Flash_NetAddress* addr, + const CompletionCallback& callback); + int32_t RecvFrom(char* buffer, + int32_t num_bytes, + const CompletionCallback& callback); + bool GetRecvFromAddress(PP_Flash_NetAddress* addr); + int32_t SendTo(const char* buffer, + int32_t num_bytes, + const PP_Flash_NetAddress* addr, + const CompletionCallback& callback); + void Close(); +}; + +} // namespace flash +} // namespace pp + +#endif // PPAPI_CPP_PRIVATE_FLASH_UDP_SOCKET_H_ + diff --git a/ppapi/ppapi_cpp.gypi b/ppapi/ppapi_cpp.gypi index 4edbf0d..6a7914b0 100644 --- a/ppapi/ppapi_cpp.gypi +++ b/ppapi/ppapi_cpp.gypi @@ -99,6 +99,7 @@ 'c/private/ppb_flash_menu.h', 'c/private/ppb_flash_net_connector.h', 'c/private/ppb_flash_tcp_socket.h', + 'c/private/ppb_flash_udp_socket.h', 'c/private/ppb_gpu_blacklist_private.h', 'c/private/ppb_instance_private.h', 'c/private/ppb_nacl_private.h', diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index f8f236f..30cdf37 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -90,6 +90,8 @@ 'proxy/ppb_flash_net_connector_proxy.h', 'proxy/ppb_flash_tcp_socket_proxy.cc', 'proxy/ppb_flash_tcp_socket_proxy.h', + 'proxy/ppb_flash_udp_socket_proxy.cc', + 'proxy/ppb_flash_udp_socket_proxy.h', 'proxy/ppb_font_proxy.cc', 'proxy/ppb_font_proxy.h', 'proxy/ppb_graphics_2d_proxy.cc', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index 1f30063..3817748 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -127,6 +127,8 @@ 'thunk/ppb_flash_net_connector_thunk.cc', 'thunk/ppb_flash_tcp_socket_api.h', 'thunk/ppb_flash_tcp_socket_thunk.cc', + 'thunk/ppb_flash_udp_socket_api.h', + 'thunk/ppb_flash_udp_socket_thunk.cc', 'thunk/ppb_font_api.h', 'thunk/ppb_font_thunk.cc', 'thunk/ppb_fullscreen_thunk.cc', diff --git a/ppapi/proxy/interface_id.h b/ppapi/proxy/interface_id.h index 1254adc..c18a02e 100644 --- a/ppapi/proxy/interface_id.h +++ b/ppapi/proxy/interface_id.h @@ -32,6 +32,7 @@ enum InterfaceID { INTERFACE_ID_PPB_FLASH_MENU, INTERFACE_ID_PPB_FLASH_NETCONNECTOR, INTERFACE_ID_PPB_FLASH_TCPSOCKET, + INTERFACE_ID_PPB_FLASH_UDPSOCKET, INTERFACE_ID_PPB_FONT, INTERFACE_ID_PPB_GRAPHICS_2D, INTERFACE_ID_PPB_GRAPHICS_3D, diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index afec017..3ae9529 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -45,6 +45,7 @@ #include "ppapi/c/private/ppb_flash_menu.h" #include "ppapi/c/private/ppb_flash_net_connector.h" #include "ppapi/c/private/ppb_flash_tcp_socket.h" +#include "ppapi/c/private/ppb_flash_udp_socket.h" #include "ppapi/c/private/ppb_pdf.h" #include "ppapi/c/trusted/ppb_broker_trusted.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" @@ -66,6 +67,7 @@ #include "ppapi/proxy/ppb_flash_menu_proxy.h" #include "ppapi/proxy/ppb_flash_net_connector_proxy.h" #include "ppapi/proxy/ppb_flash_tcp_socket_proxy.h" +#include "ppapi/proxy/ppb_flash_udp_socket_proxy.h" #include "ppapi/proxy/ppb_font_proxy.h" #include "ppapi/proxy/ppb_graphics_2d_proxy.h" #include "ppapi/proxy/ppb_graphics_3d_proxy.h" @@ -183,6 +185,7 @@ InterfaceList::InterfaceList() { AddPPB(PPB_Flash_Menu_Proxy::GetInfo()); AddPPB(PPB_Flash_Proxy::GetInfo()); AddPPB(PPB_Flash_TCPSocket_Proxy::GetInfo()); + AddPPB(PPB_Flash_UDPSocket_Proxy::GetInfo()); AddPPB(PPB_Instance_Proxy::GetInfoPrivate()); AddPPB(PPB_PDF_Proxy::GetInfo()); AddPPB(PPB_Testing_Proxy::GetInfo()); diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index cd54b60..e0b8d5b 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -263,6 +263,23 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBFlashTCPSocket_WriteACK, bool /* succeeded */, int32_t /* bytes_written */) +// PPB_Flash_UDPSocket +IPC_MESSAGE_ROUTED3(PpapiMsg_PPBFlashUDPSocket_BindACK, + uint32 /* plugin_dispatcher_id */, + uint32 /* socket_id */, + bool /* succeeded */) +IPC_MESSAGE_ROUTED5(PpapiMsg_PPBFlashUDPSocket_RecvFromACK, + uint32 /* plugin_dispatcher_id */, + uint32 /* socket_id */, + bool /* succeeded */, + std::string /* data */, + PP_Flash_NetAddress /* remote_addr */) +IPC_MESSAGE_ROUTED4(PpapiMsg_PPBFlashUDPSocket_SendToACK, + uint32 /* plugin_dispatcher_id */, + uint32 /* socket_id */, + bool /* succeeded */, + int32_t /* bytes_written */) + // PPB_Graphics2D. IPC_MESSAGE_ROUTED2(PpapiMsg_PPBGraphics2D_FlushACK, ppapi::HostResource /* graphics_2d */, @@ -729,6 +746,24 @@ IPC_MESSAGE_CONTROL2(PpapiHostMsg_PPBFlashTCPSocket_Write, IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBFlashTCPSocket_Disconnect, uint32 /* socket_id */) +// PPB_Flash_UDPSocket +IPC_SYNC_MESSAGE_CONTROL2_1(PpapiHostMsg_PPBFlashUDPSocket_Create, + int32 /* routing_id */, + uint32 /* plugin_dispatcher_id */, + uint32 /* socket_id */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_PPBFlashUDPSocket_Bind, + uint32 /* socket_id */, + PP_Flash_NetAddress /* net_addr */) +IPC_MESSAGE_CONTROL2(PpapiHostMsg_PPBFlashUDPSocket_RecvFrom, + uint32 /* socket_id */, + int32_t /* num_bytes */) +IPC_MESSAGE_CONTROL3(PpapiHostMsg_PPBFlashUDPSocket_SendTo, + uint32 /* socket_id */, + std::string /* data */, + PP_Flash_NetAddress /* net_addr */) +IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBFlashUDPSocket_Close, + uint32 /* socket_id */) + // PPB_Font. IPC_SYNC_MESSAGE_CONTROL0_1(PpapiHostMsg_PPBFont_GetFontFamilies, std::string /* result */) diff --git a/ppapi/proxy/ppb_flash_udp_socket_proxy.cc b/ppapi/proxy/ppb_flash_udp_socket_proxy.cc new file mode 100644 index 0000000..ffeef4a --- /dev/null +++ b/ppapi/proxy/ppb_flash_udp_socket_proxy.cc @@ -0,0 +1,390 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/proxy/ppb_flash_udp_socket_proxy.h" + +#include <algorithm> +#include <cstring> +#include <map> + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "base/task.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource_tracker.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/resource.h" +#include "ppapi/thunk/ppb_flash_udp_socket_api.h" +#include "ppapi/thunk/thunk.h" + +using ppapi::thunk::PPB_Flash_UDPSocket_API; + +namespace ppapi { +namespace proxy { + +const int32_t kFlashUDPSocketMaxReadSize = 1024 * 1024; +const int32_t kFlashUDPSocketMaxWriteSize = 1024 * 1024; + +namespace { + +class FlashUDPSocket; + +typedef std::map<uint32, FlashUDPSocket*> IDToSocketMap; +IDToSocketMap* g_id_to_socket = NULL; + +class AbortCallbackTask : public Task { + public: + explicit AbortCallbackTask(PP_CompletionCallback callback) + : callback_(callback) {} + virtual ~AbortCallbackTask() {} + virtual void Run() { + if (callback_.func) + PP_RunCompletionCallback(&callback_, PP_ERROR_ABORTED); + } + + private: + PP_CompletionCallback callback_; +}; + +InterfaceProxy* CreateFlashUDPSocketProxy(Dispatcher* dispatcher) { + return new PPB_Flash_UDPSocket_Proxy(dispatcher); +} + +class FlashUDPSocket : public PPB_Flash_UDPSocket_API, + public Resource { + public: + FlashUDPSocket(const HostResource& resource, uint32 socket_id); + virtual ~FlashUDPSocket(); + + // ResourceObjectBase overrides. + virtual PPB_Flash_UDPSocket_API* AsPPB_Flash_UDPSocket_API() OVERRIDE; + + // PPB_Flash_UDPSocket_API implementation. + virtual int32_t Bind(const PP_Flash_NetAddress* addr, + PP_CompletionCallback callback) OVERRIDE; + virtual int32_t RecvFrom(char* buffer, + int32_t num_bytes, + PP_CompletionCallback callback) OVERRIDE; + virtual PP_Bool GetRecvFromAddress(PP_Flash_NetAddress* addr) OVERRIDE; + + virtual int32_t SendTo(const char* buffer, + int32_t num_bytes, + const PP_Flash_NetAddress* addr, + PP_CompletionCallback callback) OVERRIDE; + virtual void Close() OVERRIDE; + + // Notifications from the proxy. + void OnBindCompleted(bool succeeded); + void OnRecvFromCompleted(bool succeeded, + const std::string& data, + const PP_Flash_NetAddress& addr); + void OnSendToCompleted(bool succeeded, + int32_t bytes_written); + + private: + void PostAbortAndClearIfNecessary(PP_CompletionCallback* callback); + + PluginDispatcher* GetDispatcher() const { + return PluginDispatcher::GetForResource(this); + } + + uint32 socket_id_; + + bool binded_; + bool closed_; + + PP_CompletionCallback bind_callback_; + PP_CompletionCallback recvfrom_callback_; + PP_CompletionCallback sendto_callback_; + + char* read_buffer_; + int32_t bytes_to_read_; + + PP_Flash_NetAddress recvfrom_addr_; + + DISALLOW_COPY_AND_ASSIGN(FlashUDPSocket); +}; + +FlashUDPSocket::FlashUDPSocket(const HostResource& resource, + uint32 socket_id) + : Resource(resource), + socket_id_(socket_id), + binded_(false), + closed_(false), + bind_callback_(PP_BlockUntilComplete()), + recvfrom_callback_(PP_BlockUntilComplete()), + sendto_callback_(PP_BlockUntilComplete()), + read_buffer_(NULL), + bytes_to_read_(-1) { + DCHECK(socket_id != 0); + + recvfrom_addr_.size = 0; + memset(recvfrom_addr_.data, 0, sizeof(recvfrom_addr_.data)); + + if (!g_id_to_socket) + g_id_to_socket = new IDToSocketMap(); + DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end()); + (*g_id_to_socket)[socket_id] = this; +} + +FlashUDPSocket::~FlashUDPSocket() { + Close(); +} + +PPB_Flash_UDPSocket_API* FlashUDPSocket::AsPPB_Flash_UDPSocket_API() { + return this; +} + +int32_t FlashUDPSocket::Bind(const PP_Flash_NetAddress* addr, + PP_CompletionCallback callback) { + if (!addr || !callback.func) + return PP_ERROR_BADARGUMENT; + if (binded_ || closed_) + return PP_ERROR_FAILED; + if (bind_callback_.func) + return PP_ERROR_INPROGRESS; + + bind_callback_ = callback; + + GetDispatcher()->SendToBrowser( + new PpapiHostMsg_PPBFlashUDPSocket_Bind(socket_id_, *addr)); + + return PP_OK_COMPLETIONPENDING; +} + +int32_t FlashUDPSocket::RecvFrom(char* buffer, + int32_t num_bytes, + PP_CompletionCallback callback) { + if (!buffer || num_bytes <= 0 || !callback.func) + return PP_ERROR_BADARGUMENT; + if (!binded_) + return PP_ERROR_FAILED; + if (recvfrom_callback_.func) + return PP_ERROR_INPROGRESS; + + read_buffer_ = buffer; + bytes_to_read_ = std::min(num_bytes, kFlashUDPSocketMaxReadSize); + recvfrom_callback_ = callback; + + // Send the request, the browser will call us back via RecvFromACK. + GetDispatcher()->SendToBrowser( + new PpapiHostMsg_PPBFlashUDPSocket_RecvFrom( + socket_id_, num_bytes)); + return PP_OK_COMPLETIONPENDING; +} + +PP_Bool FlashUDPSocket::GetRecvFromAddress(PP_Flash_NetAddress* addr) { + if (!addr) + return PP_FALSE; + + *addr = recvfrom_addr_; + return PP_TRUE; +} + +int32_t FlashUDPSocket::SendTo(const char* buffer, + int32_t num_bytes, + const PP_Flash_NetAddress* addr, + PP_CompletionCallback callback) { + if (!buffer || num_bytes <= 0 || !addr || !callback.func) + return PP_ERROR_BADARGUMENT; + if (!binded_) + return PP_ERROR_FAILED; + if (sendto_callback_.func) + return PP_ERROR_INPROGRESS; + + if (num_bytes > kFlashUDPSocketMaxWriteSize) + num_bytes = kFlashUDPSocketMaxWriteSize; + + sendto_callback_ = callback; + + // Send the request, the browser will call us back via SendToACK. + GetDispatcher()->SendToBrowser( + new PpapiHostMsg_PPBFlashUDPSocket_SendTo( + socket_id_, std::string(buffer, num_bytes), *addr)); + + return PP_OK_COMPLETIONPENDING; +} + +void FlashUDPSocket::Close() { + if(closed_) + return; + + binded_ = false; + closed_ = true; + + // After removed from the mapping, this object won't receive any notfications + // from the proxy. + DCHECK(g_id_to_socket->find(socket_id_) != g_id_to_socket->end()); + g_id_to_socket->erase(socket_id_); + + GetDispatcher()->SendToBrowser( + new PpapiHostMsg_PPBFlashUDPSocket_Close(socket_id_)); + socket_id_ = 0; + + PostAbortAndClearIfNecessary(&bind_callback_); + PostAbortAndClearIfNecessary(&recvfrom_callback_); + PostAbortAndClearIfNecessary(&sendto_callback_); +} + +void FlashUDPSocket::OnBindCompleted(bool succeeded) { + if (!bind_callback_.func) { + NOTREACHED(); + return; + } + + if (succeeded) + binded_ = true; + + PP_RunAndClearCompletionCallback(&bind_callback_, + succeeded ? PP_OK : PP_ERROR_FAILED); +} + +void FlashUDPSocket::OnRecvFromCompleted(bool succeeded, + const std::string& data, + const PP_Flash_NetAddress& addr) { + if (!recvfrom_callback_.func || !read_buffer_) { + NOTREACHED(); + return; + } + + if (succeeded) { + CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_); + if (!data.empty()) + memcpy(read_buffer_, data.c_str(), data.size()); + } + read_buffer_ = NULL; + bytes_to_read_ = -1; + recvfrom_addr_ = addr; + + PP_RunAndClearCompletionCallback( + &recvfrom_callback_, + succeeded ? static_cast<int32_t>(data.size()) : + static_cast<int32_t>(PP_ERROR_FAILED)); +} + +void FlashUDPSocket::OnSendToCompleted(bool succeeded, + int32_t bytes_written) { + if (!sendto_callback_.func) { + NOTREACHED(); + return; + } + + PP_RunAndClearCompletionCallback( + &sendto_callback_, + succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED)); +} + +void FlashUDPSocket::PostAbortAndClearIfNecessary( + PP_CompletionCallback* callback) { + DCHECK(callback); + + if (callback->func) { + MessageLoop::current()->PostTask(FROM_HERE, + new AbortCallbackTask(*callback)); + *callback = PP_BlockUntilComplete(); + } +} +} // namespace + +PPB_Flash_UDPSocket_Proxy::PPB_Flash_UDPSocket_Proxy(Dispatcher* dispatcher) + : InterfaceProxy(dispatcher) { +} + +PPB_Flash_UDPSocket_Proxy::~PPB_Flash_UDPSocket_Proxy() { +} + +// static +const InterfaceProxy::Info* PPB_Flash_UDPSocket_Proxy::GetInfo() { + static const Info info = { + ::ppapi::thunk::GetPPB_Flash_UDPSocket_Thunk(), + PPB_FLASH_UDPSOCKET_INTERFACE, + INTERFACE_ID_PPB_FLASH_UDPSOCKET, + false, + &CreateFlashUDPSocketProxy, + }; + return &info; +} + +// static +PP_Resource PPB_Flash_UDPSocket_Proxy::CreateProxyResource( + PP_Instance instance) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); + if (!dispatcher) + return 0; + + uint32 socket_id = 0; + dispatcher->SendToBrowser(new PpapiHostMsg_PPBFlashUDPSocket_Create( + INTERFACE_ID_PPB_FLASH_UDPSOCKET, dispatcher->plugin_dispatcher_id(), + &socket_id)); + if (socket_id == 0) + return 0; + + return (new FlashUDPSocket(HostResource::MakeInstanceOnly(instance), + socket_id))->GetReference(); +} + +bool PPB_Flash_UDPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPB_Flash_UDPSocket_Proxy, msg) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_BindACK, + OnMsgBindACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_RecvFromACK, + OnMsgRecvFromACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_SendToACK, + OnMsgSendToACK) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void PPB_Flash_UDPSocket_Proxy::OnMsgBindACK( + uint32 /* plugin_dispatcher_id */, + uint32 socket_id, + bool succeeded) { + if (!g_id_to_socket) { + NOTREACHED(); + return; + } + IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); + if (iter == g_id_to_socket->end()) + return; + iter->second->OnBindCompleted(succeeded); +} + +void PPB_Flash_UDPSocket_Proxy::OnMsgRecvFromACK( + uint32 /* plugin_dispatcher_id */, + uint32 socket_id, + bool succeeded, + const std::string& data, + const PP_Flash_NetAddress& addr) { + if (!g_id_to_socket) { + NOTREACHED(); + return; + } + IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); + if (iter == g_id_to_socket->end()) + return; + iter->second->OnRecvFromCompleted(succeeded, data, addr); +} + +void PPB_Flash_UDPSocket_Proxy::OnMsgSendToACK( + uint32 /* plugin_dispatcher_id */, + uint32 socket_id, + bool succeeded, + int32_t bytes_written) { + if (!g_id_to_socket) { + NOTREACHED(); + return; + } + IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); + if (iter == g_id_to_socket->end()) + return; + iter->second->OnSendToCompleted(succeeded, bytes_written); +} + +} // namespace proxy +} // namespace ppapi + diff --git a/ppapi/proxy/ppb_flash_udp_socket_proxy.h b/ppapi/proxy/ppb_flash_udp_socket_proxy.h new file mode 100644 index 0000000..abeefdb --- /dev/null +++ b/ppapi/proxy/ppb_flash_udp_socket_proxy.h @@ -0,0 +1,60 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_PROXY_PPB_FLASH_UDP_SOCKET_PROXY_H_ +#define PPAPI_PROXY_PPB_FLASH_UDP_SOCKET_PROXY_H_ + +#include <string> + +#include "base/basictypes.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/private/ppb_flash_udp_socket.h" +#include "ppapi/proxy/interface_proxy.h" + +namespace ppapi { +namespace proxy { + +// The maximum number of bytes that each PpapiHostMsg_PPBFlashUDPSocket_RecvFrom +// message is allowed to request. +extern const int32_t kFlashUDPSocketMaxReadSize; +// The maximum number of bytes that each PpapiHostMsg_PPBFlashUDPSocket_SendTo +// message is allowed to carry. +extern const int32_t kFlashUDPSocketMaxWriteSize; + +class PPB_Flash_UDPSocket_Proxy : public InterfaceProxy { + public: + PPB_Flash_UDPSocket_Proxy(Dispatcher* dispatcher); + virtual ~PPB_Flash_UDPSocket_Proxy(); + + static const Info* GetInfo(); + + static PP_Resource CreateProxyResource(PP_Instance instance); + + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + private: + // Browser->plugin message handlers. + void OnMsgBindACK(uint32 plugin_dispatcher_id, + uint32 socket_id, + bool succeeded); + void OnMsgRecvFromACK(uint32 plugin_dispatcher_id, + uint32 socket_id, + bool succeeded, + const std::string& data, + const PP_Flash_NetAddress& addr); + void OnMsgSendToACK(uint32 plugin_dispatcher_id, + uint32 socket_id, + bool succeeded, + int32_t bytes_written); + + DISALLOW_COPY_AND_ASSIGN(PPB_Flash_UDPSocket_Proxy); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_PPB_FLASH_UDP_SOCKET_PROXY_H_ + diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index b340eca..a0b4b6a 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -21,6 +21,7 @@ #include "ppapi/proxy/ppb_flash_menu_proxy.h" #include "ppapi/proxy/ppb_flash_net_connector_proxy.h" #include "ppapi/proxy/ppb_flash_tcp_socket_proxy.h" +#include "ppapi/proxy/ppb_flash_udp_socket_proxy.h" #include "ppapi/proxy/ppb_font_proxy.h" #include "ppapi/proxy/ppb_graphics_2d_proxy.h" #include "ppapi/proxy/ppb_graphics_3d_proxy.h" @@ -156,6 +157,11 @@ PP_Resource ResourceCreationProxy::CreateFlashTCPSocket( return PPB_Flash_TCPSocket_Proxy::CreateProxyResource(instance); } +PP_Resource ResourceCreationProxy::CreateFlashUDPSocket( + PP_Instance instance) { + return PPB_Flash_UDPSocket_Proxy::CreateProxyResource(instance); +} + PP_Resource ResourceCreationProxy::CreateFontObject( PP_Instance instance, const PP_FontDescription_Dev* description) { diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index 2f27f1f..1fdac1c 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -71,6 +71,7 @@ class ResourceCreationProxy : public InterfaceProxy, const PP_Flash_Menu* menu_data) OVERRIDE; virtual PP_Resource CreateFlashNetConnector(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateFlashTCPSocket(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateFlashUDPSocket(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateFontObject( PP_Instance instance, const PP_FontDescription_Dev* description) OVERRIDE; diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h index 677d8a9..2d9a850 100644 --- a/ppapi/shared_impl/resource.h +++ b/ppapi/shared_impl/resource.h @@ -32,6 +32,7 @@ F(PPB_Flash_Menu_API) \ F(PPB_Flash_NetConnector_API) \ F(PPB_Flash_TCPSocket_API) \ + F(PPB_Flash_UDPSocket_API) \ F(PPB_Font_API) \ F(PPB_Graphics2D_API) \ F(PPB_Graphics3D_API) \ diff --git a/ppapi/thunk/ppb_flash_udp_socket_api.h b/ppapi/thunk/ppb_flash_udp_socket_api.h new file mode 100644 index 0000000..afc7738 --- /dev/null +++ b/ppapi/thunk/ppb_flash_udp_socket_api.h @@ -0,0 +1,34 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_THUNK_PPB_FLASH_UDP_SOCKET_API_H_ +#define PPAPI_THUNK_PPB_FLASH_UDP_SOCKET_API_H_ + +#include "ppapi/c/private/ppb_flash_udp_socket.h" + +namespace ppapi { +namespace thunk { + +class PPB_Flash_UDPSocket_API { + public: + virtual ~PPB_Flash_UDPSocket_API() {} + + virtual int32_t Bind(const PP_Flash_NetAddress* addr, + PP_CompletionCallback callback) = 0; + virtual int32_t RecvFrom(char* buffer, + int32_t num_bytes, + PP_CompletionCallback callback) = 0; + virtual PP_Bool GetRecvFromAddress(PP_Flash_NetAddress* addr) = 0; + virtual int32_t SendTo(const char* buffer, + int32_t num_bytes, + const PP_Flash_NetAddress* addr, + PP_CompletionCallback callback) = 0; + virtual void Close() = 0; +}; + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_PPB_FLASH_UDP_SOCKET_API_H_ + diff --git a/ppapi/thunk/ppb_flash_udp_socket_thunk.cc b/ppapi/thunk/ppb_flash_udp_socket_thunk.cc new file mode 100644 index 0000000..ee2e13c --- /dev/null +++ b/ppapi/thunk/ppb_flash_udp_socket_thunk.cc @@ -0,0 +1,98 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_flash_udp_socket.h" +#include "ppapi/thunk/common.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_flash_udp_socket_api.h" +#include "ppapi/thunk/resource_creation_api.h" +#include "ppapi/thunk/thunk.h" + +namespace ppapi { +namespace thunk { + +namespace { + +PP_Resource Create(PP_Instance instance) { + EnterFunction<ResourceCreationAPI> enter(instance, true); + if (enter.failed()) + return 0; + return enter.functions()->CreateFlashUDPSocket(instance); +} + +PP_Bool IsFlashUDPSocket(PP_Resource resource) { + EnterResource<PPB_Flash_UDPSocket_API> enter(resource, false); + return PP_FromBool(enter.succeeded()); +} + +int32_t Bind(PP_Resource udp_socket, + const PP_Flash_NetAddress *addr, + PP_CompletionCallback callback) { + EnterResource<PPB_Flash_UDPSocket_API> enter(udp_socket, true); + if (enter.failed()) + return MayForceCallback(callback, PP_ERROR_BADRESOURCE); + int32_t result = enter.object()->Bind(addr, callback); + return MayForceCallback(callback, result); +} + +int32_t RecvFrom(PP_Resource udp_socket, + char* buffer, + int32_t num_bytes, + PP_CompletionCallback callback) { + EnterResource<PPB_Flash_UDPSocket_API> enter(udp_socket, true); + if (enter.failed()) + return MayForceCallback(callback, PP_ERROR_BADRESOURCE); + int32_t result = enter.object()->RecvFrom(buffer, + num_bytes, + callback); + return MayForceCallback(callback, result); +} + +PP_Bool GetRecvFromAddress(PP_Resource udp_socket, + PP_Flash_NetAddress* addr) { + EnterResource<PPB_Flash_UDPSocket_API> enter(udp_socket, true); + if (enter.failed()) + return PP_FALSE; + return enter.object()->GetRecvFromAddress(addr); +} + +int32_t SendTo(PP_Resource udp_socket, + const char* buffer, + int32_t num_bytes, + const PP_Flash_NetAddress* addr, + PP_CompletionCallback callback) { + EnterResource<PPB_Flash_UDPSocket_API> enter(udp_socket, true); + if (enter.failed()) + return MayForceCallback(callback, PP_ERROR_BADRESOURCE); + int32_t result = enter.object()->SendTo(buffer, num_bytes, addr, callback); + return MayForceCallback(callback, result); +} + +void Close(PP_Resource udp_socket) { + EnterResource<PPB_Flash_UDPSocket_API> enter(udp_socket, true); + if (enter.succeeded()) + enter.object()->Close(); +} + +const PPB_Flash_UDPSocket g_ppb_flash_udp_socket_thunk = { + &Create, + &IsFlashUDPSocket, + &Bind, + &RecvFrom, + &GetRecvFromAddress, + &SendTo, + &Close +}; + +} // namespace + +const PPB_Flash_UDPSocket* GetPPB_Flash_UDPSocket_Thunk() { + return &g_ppb_flash_udp_socket_thunk; +} + +} // namespace thunk +} // namespace ppapi + diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index 5c92f38..1fbd93f 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h @@ -71,6 +71,7 @@ class ResourceCreationAPI { const PP_Flash_Menu* menu_data) = 0; virtual PP_Resource CreateFlashNetConnector(PP_Instance instance) = 0; virtual PP_Resource CreateFlashTCPSocket(PP_Instance instace) = 0; + virtual PP_Resource CreateFlashUDPSocket(PP_Instance instace) = 0; // Note: can't be called CreateFont due to Windows #defines. virtual PP_Resource CreateFontObject( PP_Instance instance, diff --git a/ppapi/thunk/thunk.h b/ppapi/thunk/thunk.h index e33a5ee..fe90eff 100644 --- a/ppapi/thunk/thunk.h +++ b/ppapi/thunk/thunk.h @@ -35,6 +35,7 @@ struct PPB_FileIOTrusted; struct PPB_Flash_Menu; struct PPB_Flash_NetConnector; struct PPB_Flash_TCPSocket; +struct PPB_Flash_UDPSocket; struct PPB_Graphics3D; struct PPB_Graphics3DTrusted; struct PPB_ImageDataTrusted; @@ -60,6 +61,7 @@ PPAPI_THUNK_EXPORT const PPB_Flash_Menu* GetPPB_Flash_Menu_Thunk(); PPAPI_THUNK_EXPORT const PPB_Flash_NetConnector* GetPPB_Flash_NetConnector_Thunk(); PPAPI_THUNK_EXPORT const PPB_Flash_TCPSocket* GetPPB_Flash_TCPSocket_Thunk(); +PPAPI_THUNK_EXPORT const PPB_Flash_UDPSocket* GetPPB_Flash_UDPSocket_Thunk(); PPAPI_THUNK_EXPORT const PPB_Graphics3DTrusted* GetPPB_Graphics3DTrusted_Thunk(); PPAPI_THUNK_EXPORT const PPB_ImageDataTrusted* GetPPB_ImageDataTrusted_Thunk(); |