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 |