| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ppapi/proxy/ppb_flash_net_connector_proxy.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "ppapi/c/pp_errors.h" | |
| 11 #include "ppapi/c/private/ppb_flash_net_connector.h" | |
| 12 #include "ppapi/proxy/enter_proxy.h" | |
| 13 #include "ppapi/proxy/plugin_dispatcher.h" | |
| 14 #include "ppapi/proxy/ppapi_messages.h" | |
| 15 #include "ppapi/proxy/serialized_var.h" | |
| 16 #include "ppapi/shared_impl/tracked_callback.h" | |
| 17 #include "ppapi/thunk/enter.h" | |
| 18 #include "ppapi/thunk/ppb_flash_net_connector_api.h" | |
| 19 #include "ppapi/thunk/resource_creation_api.h" | |
| 20 #include "ppapi/thunk/thunk.h" | |
| 21 | |
| 22 using ppapi::thunk::EnterFunctionNoLock; | |
| 23 using ppapi::thunk::PPB_Flash_NetConnector_API; | |
| 24 using ppapi::thunk::ResourceCreationAPI; | |
| 25 | |
| 26 namespace ppapi { | |
| 27 namespace proxy { | |
| 28 | |
| 29 std::string NetAddressToString(const PP_NetAddress_Private& addr) { | |
| 30 return std::string(addr.data, std::min(static_cast<size_t>(addr.size), | |
| 31 sizeof(addr.data))); | |
| 32 } | |
| 33 | |
| 34 void StringToNetAddress(const std::string& str, PP_NetAddress_Private* addr) { | |
| 35 addr->size = std::min(str.size(), sizeof(addr->data)); | |
| 36 memcpy(addr->data, str.data(), addr->size); | |
| 37 } | |
| 38 | |
| 39 class FlashNetConnector : public PPB_Flash_NetConnector_API, | |
| 40 public Resource { | |
| 41 public: | |
| 42 explicit FlashNetConnector(const HostResource& resource); | |
| 43 virtual ~FlashNetConnector(); | |
| 44 | |
| 45 // Resource overrides. | |
| 46 virtual PPB_Flash_NetConnector_API* AsPPB_Flash_NetConnector_API() OVERRIDE; | |
| 47 | |
| 48 // PPB_Flash_NetConnector_API implementation. | |
| 49 virtual int32_t ConnectTcp(const char* host, | |
| 50 uint16_t port, | |
| 51 PP_FileHandle* socket_out, | |
| 52 PP_NetAddress_Private* local_addr_out, | |
| 53 PP_NetAddress_Private* remote_addr_out, | |
| 54 PP_CompletionCallback callback) OVERRIDE; | |
| 55 virtual int32_t ConnectTcpAddress(const PP_NetAddress_Private* addr, | |
| 56 PP_FileHandle* socket_out, | |
| 57 PP_NetAddress_Private* local_addr_out, | |
| 58 PP_NetAddress_Private* remote_addr_out, | |
| 59 PP_CompletionCallback callback) OVERRIDE; | |
| 60 | |
| 61 void ConnectComplete(int32_t result, | |
| 62 base::PlatformFile file, | |
| 63 const std::string& local_addr_as_string, | |
| 64 const std::string& remote_addr_as_string); | |
| 65 | |
| 66 private: | |
| 67 // Backend for both ConnectTcp and ConnectTcpAddress. To keep things generic, | |
| 68 // the message is passed in (on error, it's deleted). | |
| 69 int32_t ConnectWithMessage(IPC::Message* msg, | |
| 70 PP_FileHandle* socket_out, | |
| 71 PP_NetAddress_Private* local_addr_out, | |
| 72 PP_NetAddress_Private* remote_addr_out, | |
| 73 PP_CompletionCallback callback); | |
| 74 | |
| 75 scoped_refptr<TrackedCallback> callback_; | |
| 76 PP_FileHandle* socket_out_; | |
| 77 PP_NetAddress_Private* local_addr_out_; | |
| 78 PP_NetAddress_Private* remote_addr_out_; | |
| 79 }; | |
| 80 | |
| 81 FlashNetConnector::FlashNetConnector(const HostResource& resource) | |
| 82 : Resource(OBJECT_IS_PROXY, resource), | |
| 83 socket_out_(NULL), | |
| 84 local_addr_out_(NULL), | |
| 85 remote_addr_out_(NULL) { | |
| 86 } | |
| 87 | |
| 88 FlashNetConnector::~FlashNetConnector() { | |
| 89 } | |
| 90 | |
| 91 PPB_Flash_NetConnector_API* FlashNetConnector::AsPPB_Flash_NetConnector_API() { | |
| 92 return this; | |
| 93 } | |
| 94 | |
| 95 int32_t FlashNetConnector::ConnectTcp( | |
| 96 const char* host, | |
| 97 uint16_t port, | |
| 98 PP_FileHandle* socket_out, | |
| 99 PP_NetAddress_Private* local_addr_out, | |
| 100 PP_NetAddress_Private* remote_addr_out, | |
| 101 PP_CompletionCallback callback) { | |
| 102 return ConnectWithMessage( | |
| 103 new PpapiHostMsg_PPBFlashNetConnector_ConnectTcp( | |
| 104 API_ID_PPB_FLASH_NETCONNECTOR, host_resource(), host, port), | |
| 105 socket_out, local_addr_out, remote_addr_out, callback); | |
| 106 } | |
| 107 | |
| 108 int32_t FlashNetConnector::ConnectTcpAddress( | |
| 109 const PP_NetAddress_Private* addr, | |
| 110 PP_FileHandle* socket_out, | |
| 111 PP_NetAddress_Private* local_addr_out, | |
| 112 PP_NetAddress_Private* remote_addr_out, | |
| 113 PP_CompletionCallback callback) { | |
| 114 return ConnectWithMessage( | |
| 115 new PpapiHostMsg_PPBFlashNetConnector_ConnectTcpAddress( | |
| 116 API_ID_PPB_FLASH_NETCONNECTOR, | |
| 117 host_resource(), NetAddressToString(*addr)), | |
| 118 socket_out, local_addr_out, remote_addr_out, callback); | |
| 119 } | |
| 120 | |
| 121 void FlashNetConnector::ConnectComplete( | |
| 122 int32_t result, | |
| 123 base::PlatformFile file, | |
| 124 const std::string& local_addr_as_string, | |
| 125 const std::string& remote_addr_as_string) { | |
| 126 if (TrackedCallback::IsPending(callback_)) { | |
| 127 base::ClosePlatformFile(file); | |
| 128 return; | |
| 129 } | |
| 130 | |
| 131 *socket_out_ = static_cast<PP_FileHandle>(file); | |
| 132 StringToNetAddress(local_addr_as_string, local_addr_out_); | |
| 133 StringToNetAddress(remote_addr_as_string, remote_addr_out_); | |
| 134 | |
| 135 TrackedCallback::ClearAndRun(&callback_, result); | |
| 136 } | |
| 137 | |
| 138 int32_t FlashNetConnector::ConnectWithMessage( | |
| 139 IPC::Message* msg, | |
| 140 PP_FileHandle* socket_out, | |
| 141 PP_NetAddress_Private* local_addr_out, | |
| 142 PP_NetAddress_Private* remote_addr_out, | |
| 143 PP_CompletionCallback callback) { | |
| 144 scoped_ptr<IPC::Message> msg_deletor(msg); | |
| 145 if (TrackedCallback::IsPending(callback_)) | |
| 146 return PP_ERROR_INPROGRESS; // Can only have one pending request. | |
| 147 | |
| 148 // Send the request, it will call us back via ConnectACK. | |
| 149 PluginDispatcher::GetForResource(this)->Send(msg_deletor.release()); | |
| 150 | |
| 151 callback_ = new TrackedCallback(this, callback); | |
| 152 socket_out_ = socket_out; | |
| 153 local_addr_out_ = local_addr_out; | |
| 154 remote_addr_out_ = remote_addr_out; | |
| 155 return PP_OK_COMPLETIONPENDING; | |
| 156 } | |
| 157 | |
| 158 // Contains the data that the host interface will write to so we can send it | |
| 159 // to the plugin. This is created when a request is initiated, and deleted in | |
| 160 // the callback handler. | |
| 161 struct PPB_Flash_NetConnector_Proxy::ConnectCallbackInfo { | |
| 162 ConnectCallbackInfo(const HostResource& r) : resource(r), handle(0) { | |
| 163 memset(&local_addr, 0, sizeof(local_addr)); | |
| 164 memset(&remote_addr, 0, sizeof(remote_addr)); | |
| 165 } | |
| 166 | |
| 167 HostResource resource; | |
| 168 | |
| 169 PP_FileHandle handle; | |
| 170 PP_NetAddress_Private local_addr; | |
| 171 PP_NetAddress_Private remote_addr; | |
| 172 }; | |
| 173 | |
| 174 PPB_Flash_NetConnector_Proxy::PPB_Flash_NetConnector_Proxy( | |
| 175 Dispatcher* dispatcher) | |
| 176 : InterfaceProxy(dispatcher), | |
| 177 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
| 178 } | |
| 179 | |
| 180 PPB_Flash_NetConnector_Proxy::~PPB_Flash_NetConnector_Proxy() { | |
| 181 } | |
| 182 | |
| 183 // static | |
| 184 PP_Resource PPB_Flash_NetConnector_Proxy::CreateProxyResource( | |
| 185 PP_Instance instance) { | |
| 186 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | |
| 187 if (!dispatcher) | |
| 188 return 0; | |
| 189 | |
| 190 HostResource result; | |
| 191 dispatcher->Send(new PpapiHostMsg_PPBFlashNetConnector_Create( | |
| 192 API_ID_PPB_FLASH_NETCONNECTOR, instance, &result)); | |
| 193 if (result.is_null()) | |
| 194 return 0; | |
| 195 return (new FlashNetConnector(result))->GetReference(); | |
| 196 } | |
| 197 | |
| 198 bool PPB_Flash_NetConnector_Proxy::OnMessageReceived(const IPC::Message& msg) { | |
| 199 bool handled = true; | |
| 200 IPC_BEGIN_MESSAGE_MAP(PPB_Flash_NetConnector_Proxy, msg) | |
| 201 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashNetConnector_Create, | |
| 202 OnMsgCreate) | |
| 203 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashNetConnector_ConnectTcp, | |
| 204 OnMsgConnectTcp) | |
| 205 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlashNetConnector_ConnectTcpAddress, | |
| 206 OnMsgConnectTcpAddress) | |
| 207 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashNetConnector_ConnectACK, | |
| 208 OnMsgConnectACK) | |
| 209 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 210 IPC_END_MESSAGE_MAP() | |
| 211 return handled; | |
| 212 } | |
| 213 | |
| 214 void PPB_Flash_NetConnector_Proxy::OnMsgCreate(PP_Instance instance, | |
| 215 HostResource* result) { | |
| 216 thunk::EnterResourceCreation enter(instance); | |
| 217 if (enter.succeeded()) { | |
| 218 result->SetHostResource( | |
| 219 instance, | |
| 220 enter.functions()->CreateFlashNetConnector(instance)); | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 void PPB_Flash_NetConnector_Proxy::OnMsgConnectTcp( | |
| 225 const HostResource& resource, | |
| 226 const std::string& host, | |
| 227 uint16_t port) { | |
| 228 ConnectCallbackInfo* info = new ConnectCallbackInfo(resource); | |
| 229 pp::CompletionCallback callback = callback_factory_.NewOptionalCallback( | |
| 230 &PPB_Flash_NetConnector_Proxy::OnCompleteCallbackInHost, info); | |
| 231 | |
| 232 EnterHostFromHostResource<PPB_Flash_NetConnector_API> enter(resource); | |
| 233 int32_t result = PP_ERROR_BADRESOURCE; | |
| 234 if (enter.succeeded()) { | |
| 235 result = enter.object()->ConnectTcp( | |
| 236 host.c_str(), port, &info->handle, &info->local_addr, | |
| 237 &info->remote_addr, callback.pp_completion_callback()); | |
| 238 } | |
| 239 if (result != PP_OK_COMPLETIONPENDING) | |
| 240 OnCompleteCallbackInHost(result, info); | |
| 241 } | |
| 242 | |
| 243 void PPB_Flash_NetConnector_Proxy::OnMsgConnectTcpAddress( | |
| 244 const HostResource& resource, | |
| 245 const std::string& net_address_as_string) { | |
| 246 ConnectCallbackInfo* info = new ConnectCallbackInfo(resource); | |
| 247 pp::CompletionCallback callback = callback_factory_.NewOptionalCallback( | |
| 248 &PPB_Flash_NetConnector_Proxy::OnCompleteCallbackInHost, info); | |
| 249 | |
| 250 PP_NetAddress_Private net_address; | |
| 251 StringToNetAddress(net_address_as_string, &net_address); | |
| 252 | |
| 253 EnterHostFromHostResource<PPB_Flash_NetConnector_API> enter(resource); | |
| 254 int32_t result = PP_ERROR_BADRESOURCE; | |
| 255 if (enter.succeeded()) { | |
| 256 result = enter.object()->ConnectTcpAddress( | |
| 257 &net_address, &info->handle, &info->local_addr, &info->remote_addr, | |
| 258 callback.pp_completion_callback()); | |
| 259 } | |
| 260 if (result != PP_OK_COMPLETIONPENDING) | |
| 261 OnCompleteCallbackInHost(result, info); | |
| 262 } | |
| 263 | |
| 264 void PPB_Flash_NetConnector_Proxy::OnMsgConnectACK( | |
| 265 const HostResource& host_resource, | |
| 266 int32_t result, | |
| 267 IPC::PlatformFileForTransit handle, | |
| 268 const std::string& load_addr_as_string, | |
| 269 const std::string& remote_addr_as_string) { | |
| 270 base::PlatformFile platform_file = | |
| 271 IPC::PlatformFileForTransitToPlatformFile(handle); | |
| 272 | |
| 273 EnterPluginFromHostResource<PPB_Flash_NetConnector_API> enter(host_resource); | |
| 274 if (enter.failed()) { | |
| 275 base::ClosePlatformFile(platform_file); | |
| 276 return; | |
| 277 } | |
| 278 FlashNetConnector* object = static_cast<FlashNetConnector*>(enter.object()); | |
| 279 object->ConnectComplete(result, platform_file, | |
| 280 load_addr_as_string, remote_addr_as_string); | |
| 281 } | |
| 282 | |
| 283 void PPB_Flash_NetConnector_Proxy::OnCompleteCallbackInHost( | |
| 284 int32_t result, | |
| 285 ConnectCallbackInfo* info) { | |
| 286 // Callback must always delete the info. | |
| 287 scoped_ptr<ConnectCallbackInfo> info_deletor(info); | |
| 288 | |
| 289 if (result == PP_OK) { | |
| 290 dispatcher()->Send(new PpapiMsg_PPBFlashNetConnector_ConnectACK( | |
| 291 API_ID_PPB_FLASH_NETCONNECTOR, | |
| 292 info->resource, result, | |
| 293 dispatcher()->ShareHandleWithRemote( | |
| 294 static_cast<base::PlatformFile>(info->handle), true), | |
| 295 NetAddressToString(info->local_addr), | |
| 296 NetAddressToString(info->remote_addr))); | |
| 297 } else { | |
| 298 dispatcher()->Send(new PpapiMsg_PPBFlashNetConnector_ConnectACK( | |
| 299 API_ID_PPB_FLASH_NETCONNECTOR, | |
| 300 info->resource, result, | |
| 301 IPC::InvalidPlatformFileForTransit(), std::string(), std::string())); | |
| 302 } | |
| 303 } | |
| 304 | |
| 305 } // namespace proxy | |
| 306 } // namespace ppapi | |
| OLD | NEW |