Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1417)

Side by Side Diff: ppapi/proxy/ppb_flash_udp_socket_proxy.cc

Issue 8036036: Add Pepper API to use UDP (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/ppb_flash_udp_socket_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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_udp_socket_proxy.h"
6
7 #include <algorithm>
8 #include <cstring>
9 #include <map>
10
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop.h"
14 #include "base/task.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/proxy/plugin_dispatcher.h"
17 #include "ppapi/proxy/plugin_resource_tracker.h"
18 #include "ppapi/proxy/ppapi_messages.h"
19 #include "ppapi/shared_impl/resource.h"
20 #include "ppapi/thunk/ppb_flash_udp_socket_api.h"
21 #include "ppapi/thunk/thunk.h"
22
23 using ppapi::thunk::PPB_Flash_UDPSocket_API;
24
25 namespace ppapi {
26 namespace proxy {
27
28 const int32_t kFlashUDPSocketMaxReadSize = 1024 * 1024;
29 const int32_t kFlashUDPSocketMaxWriteSize = 1024 * 1024;
30
31 namespace {
32
33 class FlashUDPSocket;
34
35 typedef std::map<uint32, FlashUDPSocket*> IDToSocketMap;
36 IDToSocketMap* g_id_to_socket = NULL;
37
38 class AbortCallbackTask : public Task {
39 public:
40 explicit AbortCallbackTask(PP_CompletionCallback callback)
41 : callback_(callback) {}
42 virtual ~AbortCallbackTask() {}
43 virtual void Run() {
44 if (callback_.func)
45 PP_RunCompletionCallback(&callback_, PP_ERROR_ABORTED);
46 }
47
48 private:
49 PP_CompletionCallback callback_;
50 };
51
52 InterfaceProxy* CreateFlashUDPSocketProxy(Dispatcher* dispatcher) {
53 return new PPB_Flash_UDPSocket_Proxy(dispatcher);
54 }
55
56 class FlashUDPSocket : public PPB_Flash_UDPSocket_API,
57 public Resource {
58 public:
59 FlashUDPSocket(const HostResource& resource, uint32 socket_id);
60 virtual ~FlashUDPSocket();
61
62 // ResourceObjectBase overrides.
63 virtual PPB_Flash_UDPSocket_API* AsPPB_Flash_UDPSocket_API() OVERRIDE;
64
65 // PPB_Flash_UDPSocket_API implementation.
66 virtual int32_t Bind(const PP_Flash_NetAddress* addr,
67 PP_CompletionCallback callback) OVERRIDE;
68 virtual int32_t RecvFrom(char* buffer,
69 int32_t num_bytes,
70 PP_CompletionCallback callback) OVERRIDE;
71 virtual PP_Bool GetRecvFromAddress(PP_Flash_NetAddress* addr) OVERRIDE;
72
73 virtual int32_t SendTo(const char* buffer,
74 int32_t num_bytes,
75 const PP_Flash_NetAddress* addr,
76 PP_CompletionCallback callback) OVERRIDE;
77 virtual void Close() OVERRIDE;
78
79 // Notifications from the proxy.
80 void OnBindCompleted(bool succeeded);
81 void OnRecvFromCompleted(bool succeeded,
82 const std::string& data,
83 const PP_Flash_NetAddress& addr);
84 void OnSendToCompleted(bool succeeded,
85 int32_t bytes_written);
86
87 private:
88 void PostAbortAndClearIfNecessary(PP_CompletionCallback* callback);
89
90 PluginDispatcher* GetDispatcher() const {
91 return PluginDispatcher::GetForResource(this);
92 }
93
94 uint32 socket_id_;
95
96 bool binded_;
97 bool closed_;
98
99 PP_CompletionCallback bind_callback_;
100 PP_CompletionCallback recvfrom_callback_;
101 PP_CompletionCallback sendto_callback_;
102
103 char* read_buffer_;
104 int32_t bytes_to_read_;
105
106 PP_Flash_NetAddress recvfrom_addr_;
107
108 DISALLOW_COPY_AND_ASSIGN(FlashUDPSocket);
109 };
110
111 FlashUDPSocket::FlashUDPSocket(const HostResource& resource,
112 uint32 socket_id)
113 : Resource(resource),
114 socket_id_(socket_id),
115 binded_(false),
116 closed_(false),
117 bind_callback_(PP_BlockUntilComplete()),
118 recvfrom_callback_(PP_BlockUntilComplete()),
119 sendto_callback_(PP_BlockUntilComplete()),
120 read_buffer_(NULL),
121 bytes_to_read_(-1) {
122 DCHECK(socket_id != 0);
123
124 recvfrom_addr_.size = 0;
125 memset(recvfrom_addr_.data, 0, sizeof(recvfrom_addr_.data));
126
127 if (!g_id_to_socket)
128 g_id_to_socket = new IDToSocketMap();
129 DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end());
130 (*g_id_to_socket)[socket_id] = this;
131 }
132
133 FlashUDPSocket::~FlashUDPSocket() {
134 Close();
135 }
136
137 PPB_Flash_UDPSocket_API* FlashUDPSocket::AsPPB_Flash_UDPSocket_API() {
138 return this;
139 }
140
141 int32_t FlashUDPSocket::Bind(const PP_Flash_NetAddress* addr,
142 PP_CompletionCallback callback) {
143 if (!addr || !callback.func)
144 return PP_ERROR_BADARGUMENT;
145 if (binded_ || closed_)
146 return PP_ERROR_FAILED;
147 if (bind_callback_.func)
148 return PP_ERROR_INPROGRESS;
149
150 bind_callback_ = callback;
151
152 GetDispatcher()->SendToBrowser(
153 new PpapiHostMsg_PPBFlashUDPSocket_Bind(socket_id_, *addr));
154
155 return PP_OK_COMPLETIONPENDING;
156 }
157
158 int32_t FlashUDPSocket::RecvFrom(char* buffer,
159 int32_t num_bytes,
160 PP_CompletionCallback callback) {
161 if (!buffer || num_bytes <= 0 || !callback.func)
162 return PP_ERROR_BADARGUMENT;
163 if (!binded_)
164 return PP_ERROR_FAILED;
165 if (recvfrom_callback_.func)
166 return PP_ERROR_INPROGRESS;
167
168 read_buffer_ = buffer;
169 bytes_to_read_ = std::min(num_bytes, kFlashUDPSocketMaxReadSize);
170 recvfrom_callback_ = callback;
171
172 // Send the request, the browser will call us back via RecvFromACK.
173 GetDispatcher()->SendToBrowser(
174 new PpapiHostMsg_PPBFlashUDPSocket_RecvFrom(
175 socket_id_, num_bytes));
176 return PP_OK_COMPLETIONPENDING;
177 }
178
179 PP_Bool FlashUDPSocket::GetRecvFromAddress(PP_Flash_NetAddress* addr) {
180 if (!addr)
181 return PP_FALSE;
182
183 *addr = recvfrom_addr_;
184 return PP_TRUE;
185 }
186
187 int32_t FlashUDPSocket::SendTo(const char* buffer,
188 int32_t num_bytes,
189 const PP_Flash_NetAddress* addr,
190 PP_CompletionCallback callback) {
191 if (!buffer || num_bytes <= 0 || !addr || !callback.func)
192 return PP_ERROR_BADARGUMENT;
193 if (!binded_)
194 return PP_ERROR_FAILED;
195 if (sendto_callback_.func)
196 return PP_ERROR_INPROGRESS;
197
198 if (num_bytes > kFlashUDPSocketMaxWriteSize)
199 num_bytes = kFlashUDPSocketMaxWriteSize;
200
201 sendto_callback_ = callback;
202
203 // Send the request, the browser will call us back via SendToACK.
204 GetDispatcher()->SendToBrowser(
205 new PpapiHostMsg_PPBFlashUDPSocket_SendTo(
206 socket_id_, std::string(buffer, num_bytes), *addr));
207
208 return PP_OK_COMPLETIONPENDING;
209 }
210
211 void FlashUDPSocket::Close() {
212 if(closed_)
213 return;
214
215 binded_ = false;
216 closed_ = true;
217
218 // After removed from the mapping, this object won't receive any notfications
219 // from the proxy.
220 DCHECK(g_id_to_socket->find(socket_id_) != g_id_to_socket->end());
221 g_id_to_socket->erase(socket_id_);
222
223 GetDispatcher()->SendToBrowser(
224 new PpapiHostMsg_PPBFlashUDPSocket_Close(socket_id_));
225 socket_id_ = 0;
226
227 PostAbortAndClearIfNecessary(&bind_callback_);
228 PostAbortAndClearIfNecessary(&recvfrom_callback_);
229 PostAbortAndClearIfNecessary(&sendto_callback_);
230 }
231
232 void FlashUDPSocket::OnBindCompleted(bool succeeded) {
233 if (!bind_callback_.func) {
234 NOTREACHED();
235 return;
236 }
237
238 if (succeeded)
239 binded_ = true;
240
241 PP_RunAndClearCompletionCallback(&bind_callback_,
242 succeeded ? PP_OK : PP_ERROR_FAILED);
243 }
244
245 void FlashUDPSocket::OnRecvFromCompleted(bool succeeded,
246 const std::string& data,
247 const PP_Flash_NetAddress& addr) {
248 if (!recvfrom_callback_.func || !read_buffer_) {
249 NOTREACHED();
250 return;
251 }
252
253 if (succeeded) {
254 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
255 if (!data.empty())
256 memcpy(read_buffer_, data.c_str(), data.size());
257 }
258 read_buffer_ = NULL;
259 bytes_to_read_ = -1;
260 recvfrom_addr_ = addr;
261
262 PP_RunAndClearCompletionCallback(
263 &recvfrom_callback_,
264 succeeded ? static_cast<int32_t>(data.size()) :
265 static_cast<int32_t>(PP_ERROR_FAILED));
266 }
267
268 void FlashUDPSocket::OnSendToCompleted(bool succeeded,
269 int32_t bytes_written) {
270 if (!sendto_callback_.func) {
271 NOTREACHED();
272 return;
273 }
274
275 PP_RunAndClearCompletionCallback(
276 &sendto_callback_,
277 succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
278 }
279
280 void FlashUDPSocket::PostAbortAndClearIfNecessary(
281 PP_CompletionCallback* callback) {
282 DCHECK(callback);
283
284 if (callback->func) {
285 MessageLoop::current()->PostTask(FROM_HERE,
286 new AbortCallbackTask(*callback));
287 *callback = PP_BlockUntilComplete();
288 }
289 }
290 } // namespace
291
292 PPB_Flash_UDPSocket_Proxy::PPB_Flash_UDPSocket_Proxy(Dispatcher* dispatcher)
293 : InterfaceProxy(dispatcher) {
294 }
295
296 PPB_Flash_UDPSocket_Proxy::~PPB_Flash_UDPSocket_Proxy() {
297 }
298
299 // static
300 const InterfaceProxy::Info* PPB_Flash_UDPSocket_Proxy::GetInfo() {
301 static const Info info = {
302 ::ppapi::thunk::GetPPB_Flash_UDPSocket_Thunk(),
303 PPB_FLASH_UDPSOCKET_INTERFACE,
304 INTERFACE_ID_PPB_FLASH_UDPSOCKET,
305 false,
306 &CreateFlashUDPSocketProxy,
307 };
308 return &info;
309 }
310
311 // static
312 PP_Resource PPB_Flash_UDPSocket_Proxy::CreateProxyResource(
313 PP_Instance instance) {
314 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
315 if (!dispatcher)
316 return 0;
317
318 uint32 socket_id = 0;
319 dispatcher->SendToBrowser(new PpapiHostMsg_PPBFlashUDPSocket_Create(
320 INTERFACE_ID_PPB_FLASH_UDPSOCKET, dispatcher->plugin_dispatcher_id(),
321 &socket_id));
322 if (socket_id == 0)
323 return 0;
324
325 return (new FlashUDPSocket(HostResource::MakeInstanceOnly(instance),
326 socket_id))->GetReference();
327 }
328
329 bool PPB_Flash_UDPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) {
330 bool handled = true;
331 IPC_BEGIN_MESSAGE_MAP(PPB_Flash_UDPSocket_Proxy, msg)
332 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_BindACK,
333 OnMsgBindACK)
334 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_RecvFromACK,
335 OnMsgRecvFromACK)
336 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_SendToACK,
337 OnMsgSendToACK)
338 IPC_MESSAGE_UNHANDLED(handled = false)
339 IPC_END_MESSAGE_MAP()
340 return handled;
341 }
342
343 void PPB_Flash_UDPSocket_Proxy::OnMsgBindACK(
344 uint32 /* plugin_dispatcher_id */,
345 uint32 socket_id,
346 bool succeeded) {
347 if (!g_id_to_socket) {
348 NOTREACHED();
349 return;
350 }
351 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
352 if (iter == g_id_to_socket->end())
353 return;
354 iter->second->OnBindCompleted(succeeded);
355 }
356
357 void PPB_Flash_UDPSocket_Proxy::OnMsgRecvFromACK(
358 uint32 /* plugin_dispatcher_id */,
359 uint32 socket_id,
360 bool succeeded,
361 const std::string& data,
362 const PP_Flash_NetAddress& addr) {
363 if (!g_id_to_socket) {
364 NOTREACHED();
365 return;
366 }
367 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
368 if (iter == g_id_to_socket->end())
369 return;
370 iter->second->OnRecvFromCompleted(succeeded, data, addr);
371 }
372
373 void PPB_Flash_UDPSocket_Proxy::OnMsgSendToACK(
374 uint32 /* plugin_dispatcher_id */,
375 uint32 socket_id,
376 bool succeeded,
377 int32_t bytes_written) {
378 if (!g_id_to_socket) {
379 NOTREACHED();
380 return;
381 }
382 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
383 if (iter == g_id_to_socket->end())
384 return;
385 iter->second->OnSendToCompleted(succeeded, bytes_written);
386 }
387
388 } // namespace proxy
389 } // namespace ppapi
390
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_flash_udp_socket_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698