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

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

Issue 7745005: Initial work for UDP Pepper API (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: A few more changes after self-review Created 9 years, 3 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
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 class FlashUDPSocket;
32
33 namespace {
34
35 typedef std::map<uint32, FlashUDPSocket*> IDToSocketMap;
36 IDToSocketMap* g_id_to_socket = NULL;
brettw 2011/09/16 17:50:17 I was looking at this and I think we can avoid thi
mtilburg 2011/09/21 01:46:43 Brett- this sounds good... can I recommend I chang
yzshen1 2011/09/21 18:46:03 I could do it if you would like me to. I have to c
mtilburg 2011/09/22 13:53:23 Doesn't matter to me, if you have the change alrea
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 const void* target_interface) {
54 return new PPB_Flash_UDPSocket_Proxy(dispatcher, target_interface);
55 }
56
57 } // namespace
58
59 class FlashUDPSocket : public PPB_Flash_UDPSocket_API,
60 public Resource {
61 public:
62 FlashUDPSocket(const HostResource& resource,
63 uint32 socket_id,
64 int32_t family);
65 virtual ~FlashUDPSocket();
66
67 // ResourceObjectBase overrides.
68 virtual PPB_Flash_UDPSocket_API* AsPPB_Flash_UDPSocket_API() OVERRIDE;
69
70 // PPB_Flash_UDPSocket_API implementation.
71
72 virtual int32_t Bind(const PP_Flash_NetAddress* addr,
73 PP_CompletionCallback callback) OVERRIDE;
74 virtual int32_t RecvFrom(char* buffer,
75 int32_t num_bytes,
76 PP_CompletionCallback callback) OVERRIDE;
77 virtual PP_Bool GetRecvFromAddress(PP_Flash_NetAddress* addr) OVERRIDE;
78
79 virtual int32_t SendTo(const char* buffer,
80 int32_t num_bytes,
81 const PP_Flash_NetAddress* addr,
82 PP_CompletionCallback callback) OVERRIDE;
83 virtual void Disconnect() OVERRIDE;
84
85 // Notifications from the proxy.
86 void OnBindCompleted(bool succeeded,
87 int32_t result);
88 void OnRecvFromCompleted(bool succeeded,
89 const std::string& data,
90 const PP_Flash_NetAddress& addr);
91 void OnSendToCompleted(bool succeeded,
92 int32_t bytes_written);
93
94 private:
95 enum ConnectionState {
96 // Before a connection is successfully established (including a connect
97 // request is pending or a previous connect request failed).
98 BEFORE_CONNECT,
99 CONNECTED,
100 DISCONNECTED
101 };
102
103 void PostAbortAndClearIfNecessary(PP_CompletionCallback* callback);
104
105 PluginDispatcher* GetDispatcher() const {
106 return PluginDispatcher::GetForResource(this);
107 }
108
109 uint32 socket_id_;
110 int32_t family_;
yzshen1 2011/09/17 02:10:07 This is not used.
mtilburg 2011/09/21 01:46:43 Done.
111
112 ConnectionState connection_state_;
113
114 PP_CompletionCallback bind_callback_;
115 PP_CompletionCallback recvfrom_callback_;
116 PP_CompletionCallback sendto_callback_;
117
118 char* read_buffer_;
119 int32_t bytes_to_read_;
120
121 PP_Flash_NetAddress recvfrom_addr_;
122
123 DISALLOW_COPY_AND_ASSIGN(FlashUDPSocket);
124 };
125
126 FlashUDPSocket::FlashUDPSocket(const HostResource& resource,
127 uint32 socket_id,
128 int32_t family)
129 : Resource(resource),
130 socket_id_(socket_id),
131 family_(family),
132 connection_state_(BEFORE_CONNECT),
133 bind_callback_(PP_BlockUntilComplete()),
134 recvfrom_callback_(PP_BlockUntilComplete()),
135 sendto_callback_(PP_BlockUntilComplete()),
136 read_buffer_(NULL),
137 bytes_to_read_(-1) {
138 DCHECK(socket_id != 0);
139
140 recvfrom_addr_.size = 0;
141 memset(recvfrom_addr_.data, 0, sizeof(recvfrom_addr_.data));
142
143 if (!g_id_to_socket)
144 g_id_to_socket = new IDToSocketMap();
145 DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end());
146 (*g_id_to_socket)[socket_id] = this;
147 }
148
149 FlashUDPSocket::~FlashUDPSocket() {
150 Disconnect();
151 }
152
153 PPB_Flash_UDPSocket_API* FlashUDPSocket::AsPPB_Flash_UDPSocket_API() {
154 return this;
155 }
156
157 int32_t FlashUDPSocket::Bind(const PP_Flash_NetAddress* addr,
158 PP_CompletionCallback callback) {
159 bind_callback_ = callback;
yzshen1 2011/09/17 02:10:07 It is necessary to validate inputs. We could retur
mtilburg 2011/09/21 01:46:43 Done.
160
161 scoped_ptr<IPC::Message> msg_deletor(
162 new PpapiHostMsg_PPBFlashUDPSocket_Bind(socket_id_, *addr));
163
164 GetDispatcher()->SendToBrowser(msg_deletor.release());
yzshen1 2011/09/17 02:10:07 You could remove msg_deletor.
mtilburg 2011/09/21 01:46:43 I don't understand what you mean here, doesn't msg
yzshen1 2011/09/21 18:46:03 I mean, you can directly use GetDispatcher()->Sen
mtilburg 2011/09/22 13:53:23 Done.
165
166 return 0;
yzshen1 2011/09/17 02:10:07 It has to be PP_OK_COMPLETIONPENDING if this is a
mtilburg 2011/09/21 01:46:43 Done.
167 }
168
169 int32_t FlashUDPSocket::RecvFrom(char* buffer,
170 int32_t num_bytes,
171 PP_CompletionCallback callback) {
172 if (!buffer || num_bytes <= 0 || !callback.func)
173 return PP_ERROR_BADARGUMENT;
174
175 if ( recvfrom_callback_.func )
yzshen1 2011/09/17 02:10:07 Style: No space within ().
mtilburg 2011/09/21 01:46:43 Done.
176 return PP_ERROR_INPROGRESS;
177
178 read_buffer_ = buffer;
179 bytes_to_read_ = std::min(num_bytes, kFlashUDPSocketMaxReadSize);
180 recvfrom_callback_ = callback;
181
182 // Send the request, the browser will call us back via RecvFromACK.
183 GetDispatcher()->SendToBrowser(
184 new PpapiHostMsg_PPBFlashUDPSocket_RecvFrom(
185 socket_id_, num_bytes));
186 return PP_OK_COMPLETIONPENDING;
187 }
188
189 PP_Bool FlashUDPSocket::GetRecvFromAddress(PP_Flash_NetAddress* addr) {
190 if (!addr)
191 return PP_FALSE;
192
193 *addr = recvfrom_addr_;
194 return PP_TRUE;
195 }
196
197 int32_t FlashUDPSocket::SendTo(const char* buffer,
198 int32_t num_bytes,
199 const PP_Flash_NetAddress* addr,
200 PP_CompletionCallback callback) {
201 if (!callback.func)
yzshen1 2011/09/17 02:10:07 Also validate: buffer number_bytes addr whether th
mtilburg 2011/09/21 01:46:43 Done.
202 return PP_ERROR_BADARGUMENT;
203
yzshen1 2011/09/17 02:10:07 I think you want to consider kFlashUDPSocketMaxWri
mtilburg 2011/09/21 01:46:43 Done.
204 sendto_callback_ = callback;
205
206 // Send the request, the browser will call us back via SendToACK.
207 GetDispatcher()->SendToBrowser(
208 new PpapiHostMsg_PPBFlashUDPSocket_SendTo(
209 socket_id_, std::string(buffer, num_bytes), *addr));
210 return PP_OK_COMPLETIONPENDING;
211 }
212
213 void FlashUDPSocket::Disconnect() {
214 if (connection_state_ == DISCONNECTED)
yzshen1 2011/09/17 02:10:07 I would suggest that you remove the whole Connecti
mtilburg 2011/09/21 01:46:43 Done.
215 return;
216
217 connection_state_ = DISCONNECTED;
218
219 // After removed from the mapping, this object won't receive any notfications
220 // from the proxy.
221 DCHECK(g_id_to_socket->find(socket_id_) != g_id_to_socket->end());
222 g_id_to_socket->erase(socket_id_);
223
224 GetDispatcher()->SendToBrowser(
225 new PpapiHostMsg_PPBFlashUDPSocket_Disconnect(socket_id_));
226 socket_id_ = 0;
227
228 PostAbortAndClearIfNecessary(&bind_callback_);
229 PostAbortAndClearIfNecessary(&recvfrom_callback_);
230 PostAbortAndClearIfNecessary(&sendto_callback_);
231 }
232
233 void FlashUDPSocket::OnBindCompleted(bool succeeded, int32_t result) {
234 if (!bind_callback_.func) {
235 NOTREACHED();
236 return;
237 }
238
239 PP_RunAndClearCompletionCallback(&bind_callback_, result);
240 }
241
242 void FlashUDPSocket::OnRecvFromCompleted(bool succeeded,
243 const std::string& data,
244 const PP_Flash_NetAddress& addr) {
245 if (!recvfrom_callback_.func || !read_buffer_) {
246 NOTREACHED();
yzshen1 2011/09/17 02:10:07 Wrong indent.
mtilburg 2011/09/21 01:46:43 Done.
247 return;
248 }
249
250 if (succeeded) {
251 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
yzshen1 2011/09/17 02:10:07 Wrong indent.
mtilburg 2011/09/21 01:46:43 Done.
252 if (!data.empty())
253 memcpy(read_buffer_, data.c_str(), data.size());
254 }
255 read_buffer_ = NULL;
256 bytes_to_read_ = -1;
257 recvfrom_addr_ = addr;
258
259 PP_RunAndClearCompletionCallback(
260 &recvfrom_callback_,
261 succeeded ? static_cast<int32_t>(data.size()) :
262 static_cast<int32_t>(PP_ERROR_FAILED));
263 }
264
265 void FlashUDPSocket::OnSendToCompleted(bool succeeded,
266 int32_t bytes_written) {
yzshen1 2011/09/17 02:10:07 Maybe validate that sendto_callback_ exists as lin
mtilburg 2011/09/21 01:46:43 Done.
267 PP_RunAndClearCompletionCallback(
268 &sendto_callback_,
269 succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
270 }
271
272 void FlashUDPSocket::PostAbortAndClearIfNecessary(
273 PP_CompletionCallback* callback) {
274 DCHECK(callback);
275
276 if (callback->func) {
277 MessageLoop::current()->PostTask(FROM_HERE,
278 new AbortCallbackTask(*callback));
279 *callback = PP_BlockUntilComplete();
280 }
281 }
282
283 PPB_Flash_UDPSocket_Proxy::PPB_Flash_UDPSocket_Proxy(
284 Dispatcher* dispatcher,
285 const void* target_interface)
286 : InterfaceProxy(dispatcher, target_interface) {
287 }
288
289 PPB_Flash_UDPSocket_Proxy::~PPB_Flash_UDPSocket_Proxy() {
290 }
291
292 // static
293 const InterfaceProxy::Info* PPB_Flash_UDPSocket_Proxy::GetInfo() {
294 static const Info info = {
295 ::ppapi::thunk::GetPPB_Flash_UDPSocket_Thunk(),
296 PPB_FLASH_UDPSOCKET_INTERFACE,
297 INTERFACE_ID_PPB_FLASH_UDPSOCKET,
298 false,
299 &CreateFlashUDPSocketProxy,
300 };
301 return &info;
302 }
303
304 // static
305 PP_Resource PPB_Flash_UDPSocket_Proxy::CreateProxyResource(
306 PP_Instance instance,
307 int32_t family) {
308 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
309 if (!dispatcher)
310 return 0;
311
312 uint32 socket_id = 0;
313 dispatcher->SendToBrowser(new PpapiHostMsg_PPBFlashUDPSocket_Create(
314 INTERFACE_ID_PPB_FLASH_UDPSOCKET, dispatcher->plugin_dispatcher_id(),
315 family, &socket_id));
316 if (socket_id == 0)
317 return 0;
318
319 return (new FlashUDPSocket(HostResource::MakeInstanceOnly(instance),
320 socket_id, family))->GetReference();
321 }
322
323 bool PPB_Flash_UDPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) {
324 bool handled = true;
325 IPC_BEGIN_MESSAGE_MAP(PPB_Flash_UDPSocket_Proxy, msg)
326 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_BindACK,
327 OnMsgBindACK)
328 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_RecvFromACK,
329 OnMsgRecvFromACK)
330 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_SendToACK,
331 OnMsgSendToACK)
332 IPC_MESSAGE_UNHANDLED(handled = false)
333 IPC_END_MESSAGE_MAP()
334 return handled;
335 }
336 void PPB_Flash_UDPSocket_Proxy::OnMsgBindACK(
brettw 2011/09/16 17:50:17 Style nit: need blank line here.
mtilburg 2011/09/21 01:46:43 Done.
337 uint32 /* plugin_dispatcher_id */,
338 uint32 socket_id,
339 bool succeeded,
340 int32_t result) {
341 if (!g_id_to_socket) {
342 NOTREACHED();
343 return;
344 }
345 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
346 if (iter == g_id_to_socket->end())
347 return;
348 iter->second->OnBindCompleted(succeeded, result);
349 }
350
351 void PPB_Flash_UDPSocket_Proxy::OnMsgRecvFromACK(
352 uint32 /* plugin_dispatcher_id */,
353 uint32 socket_id,
354 bool succeeded,
355 const std::string& data,
356 const PP_Flash_NetAddress& addr) {
357 if (!g_id_to_socket) {
358 NOTREACHED();
359 return;
360 }
361 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
362 if (iter == g_id_to_socket->end())
363 return;
364 iter->second->OnRecvFromCompleted(succeeded, data, addr);
365 }
366
367 void PPB_Flash_UDPSocket_Proxy::OnMsgSendToACK(
368 uint32 /* plugin_dispatcher_id */,
369 uint32 socket_id,
370 bool succeeded,
371 int32_t bytes_written) {
372 if (!g_id_to_socket) {
373 NOTREACHED();
374 return;
375 }
376 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
377 if (iter == g_id_to_socket->end())
378 return;
379 iter->second->OnSendToCompleted(succeeded, bytes_written);
380 }
381
382 } // namespace proxy
383 } // namespace ppapi
384
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698