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

Side by Side Diff: content/browser/renderer_host/pepper/pepper_udp_socket_private_host.cc

Issue 11441012: PPB_UDPSocket_Private is switched to the new Pepper proxy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: PPB_UDPSocket_Shared is merged to UDPSocketPrivateResource. PepperUDPSocketPrivateShared is merged … Created 7 years, 12 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) 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 "content/browser/renderer_host/pepper/pepper_udp_socket_private_host.h"
6
7 #include <cstring>
8
9 #include "base/compiler_specific.h"
10 #include "base/logging.h"
11 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
12 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/common/process_type.h"
15 #include "content/public/common/socket_permission_request.h"
16 #include "ipc/ipc_message_macros.h"
17 #include "net/base/io_buffer.h"
18 #include "net/base/net_errors.h"
19 #include "net/udp/udp_server_socket.h"
20 #include "ppapi/c/pp_errors.h"
21 #include "ppapi/c/private/ppb_net_address_private.h"
22 #include "ppapi/c/private/ppb_udp_socket_private.h"
23 #include "ppapi/host/dispatch_host_message.h"
24 #include "ppapi/host/host_message_context.h"
25 #include "ppapi/host/ppapi_host.h"
26 #include "ppapi/proxy/ppapi_messages.h"
27 #include "ppapi/proxy/udp_socket_private_resource.h"
28 #include "ppapi/shared_impl/private/net_address_private_impl.h"
29
30 using ppapi::NetAddressPrivateImpl;
31
32 namespace content {
33
34 PepperUDPSocketPrivateHost::PepperUDPSocketPrivateHost(
35 BrowserPpapiHostImpl* host,
36 PP_Instance instance,
37 PP_Resource resource)
38 : ResourceHost(host->GetPpapiHost(), instance, resource),
39 allow_address_reuse_(false),
40 allow_broadcast_(false),
41 closed_(false),
42 host_(host),
43 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
44 DCHECK(host_);
45 }
46
47 PepperUDPSocketPrivateHost::~PepperUDPSocketPrivateHost() {
48 Close();
49 }
50
51 int32_t PepperUDPSocketPrivateHost::OnResourceMessageReceived(
52 const IPC::Message& msg,
53 ppapi::host::HostMessageContext* context) {
54 IPC_BEGIN_MESSAGE_MAP(PepperUDPSocketPrivateHost, msg)
55 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
56 PpapiHostMsg_UDPSocketPrivate_SetBoolSocketFeature,
57 OnMsgSetBoolSocketFeature)
58 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
59 PpapiHostMsg_UDPSocketPrivate_Bind,
60 OnMsgBind)
61 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
62 PpapiHostMsg_UDPSocketPrivate_RecvFrom,
63 OnMsgRecvFrom)
64 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocketPrivate_SendTo,
65 OnMsgSendTo)
66 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
67 PpapiHostMsg_UDPSocketPrivate_Close,
68 OnMsgClose)
69 IPC_END_MESSAGE_MAP()
70 return PP_ERROR_FAILED;
71 }
72
73 int32_t PepperUDPSocketPrivateHost::OnMsgSetBoolSocketFeature(
74 const ppapi::host::HostMessageContext* context,
75 int32_t name,
76 bool value) {
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
78 DCHECK(!socket_.get());
79 DCHECK(!closed());
80
81 switch(static_cast<PP_UDPSocketFeature_Private>(name)) {
82 case PP_UDPSOCKETFEATURE_ADDRESS_REUSE:
83 allow_address_reuse_ = value;
84 break;
85 case PP_UDPSOCKETFEATURE_BROADCAST:
86 allow_broadcast_ = value;
87 break;
88 default:
89 NOTREACHED();
90 break;
91 }
92 return PP_OK;
93 }
94
95 int32_t PepperUDPSocketPrivateHost::OnMsgBind(
96 const ppapi::host::HostMessageContext* context,
97 const PP_NetAddress_Private& addr) {
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
99 DCHECK(context);
100
101 if (bind_context_.get())
102 return PP_ERROR_INPROGRESS;
103 bind_context_.reset(
104 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
105
106 SocketPermissionRequest params =
107 pepper_socket_utils::CreateSocketPermissionRequest(
108 SocketPermissionRequest::UDP_BIND, addr);
109 CheckSocketPermissionsAndReply(params,
110 base::Bind(&PepperUDPSocketPrivateHost::DoBind,
111 weak_factory_.GetWeakPtr(),
112 addr));
113 return PP_OK_COMPLETIONPENDING;
114 }
115
116 int32_t PepperUDPSocketPrivateHost::OnMsgRecvFrom(
117 const ppapi::host::HostMessageContext* context,
118 int32_t num_bytes) {
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
120 DCHECK(context);
121 DCHECK(socket_.get());
122 DCHECK(!closed());
123
124 if (recv_from_context_.get())
125 return PP_ERROR_INPROGRESS;
126 recv_from_context_.reset(
127 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
128 if (recvfrom_buffer_.get())
129 return PP_ERROR_INPROGRESS;
130 if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize) {
131 NOTREACHED();
132 num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize;
133 }
134 recvfrom_buffer_ = new net::IOBuffer(num_bytes);
135 int result = socket_->RecvFrom(
136 recvfrom_buffer_, num_bytes, &recvfrom_address_,
137 base::Bind(&PepperUDPSocketPrivateHost::OnRecvFromCompleted,
138 weak_factory_.GetWeakPtr()));
139 if (result != net::ERR_IO_PENDING)
140 OnRecvFromCompleted(result);
141 return PP_OK_COMPLETIONPENDING;
142 }
143
144 int32_t PepperUDPSocketPrivateHost::OnMsgSendTo(
145 const ppapi::host::HostMessageContext* context,
146 const std::string& data,
147 const PP_NetAddress_Private& addr) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
149 DCHECK(context);
150
151 if (send_to_context_.get())
152 return PP_ERROR_INPROGRESS;
153 send_to_context_.reset(
154 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
155 SocketPermissionRequest params =
156 pepper_socket_utils::CreateSocketPermissionRequest(
157 SocketPermissionRequest::UDP_SEND_TO, addr);
158 CheckSocketPermissionsAndReply(params,
159 base::Bind(
160 &PepperUDPSocketPrivateHost::DoSendTo,
161 weak_factory_.GetWeakPtr(),
162 data,
dmichael (off chromium) 2013/01/10 05:57:16 This is going to implicitly do a copy, which you t
ygorshenin1 2013/01/10 11:36:12 Sure, thanks! Done. On 2013/01/10 05:57:16, dmich
163 addr));
164 return PP_OK_COMPLETIONPENDING;
165 }
166
167 int32_t PepperUDPSocketPrivateHost::OnMsgClose(
168 const ppapi::host::HostMessageContext* context) {
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
170 Close();
171 return PP_OK;
172 }
173
174 void PepperUDPSocketPrivateHost::DoBind(const PP_NetAddress_Private& addr,
175 bool allowed) {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
177 DCHECK(!closed());
178
179 if (!allowed) {
180 SendBindError();
181 return;
182 }
183
184 socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source()));
185
186 net::IPAddressNumber address;
187 int port;
188 if (!socket_.get() ||
189 !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
190 SendBindError();
191 return;
192 }
193
194 if (allow_address_reuse_)
195 socket_->AllowAddressReuse();
196 if (allow_broadcast_)
197 socket_->AllowBroadcast();
198
199 int result = socket_->Listen(net::IPEndPoint(address, port));
200
201 if (result == net::OK &&
202 socket_->GetLocalAddress(&bound_address_) != net::OK) {
203 SendBindError();
204 return;
205 }
206
207 OnBindCompleted(result);
208 }
209
210 void PepperUDPSocketPrivateHost::DoSendTo(const std::string& data,
211 const PP_NetAddress_Private& addr,
212 bool allowed) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
214 DCHECK(socket_.get());
215 DCHECK(!closed());
216
217 if (!allowed || sendto_buffer_.get() || data.empty()) {
218 SendSendToError();
219 return;
220 }
221
222 net::IPAddressNumber address;
223 int port;
224 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
225 SendSendToError();
226 return;
227 }
228
229 int data_size = data.size();
230 if (data_size > ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize) {
231 NOTREACHED();
232 data_size = ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize;
233 }
234
235 sendto_buffer_ = new net::IOBuffer(data_size);
236 memcpy(sendto_buffer_->data(), data.data(), data_size);
237 int result = socket_->SendTo(
238 sendto_buffer_, data_size, net::IPEndPoint(address, port),
239 base::Bind(&PepperUDPSocketPrivateHost::OnSendToCompleted,
240 weak_factory_.GetWeakPtr()));
241
242 if (result != net::ERR_IO_PENDING)
243 OnSendToCompleted(result);
244 }
245
246 void PepperUDPSocketPrivateHost::Close() {
247 if (socket_.get() && !closed_)
248 socket_->Close();
249 closed_ = true;
250 }
251
252 void PepperUDPSocketPrivateHost::OnBindCompleted(int result) {
253 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress;
254 if (result < 0 ||
255 !NetAddressPrivateImpl::IPEndPointToNetAddress(bound_address_.address(),
256 bound_address_.port(),
257 &addr)) {
258 SendBindError();
259 } else {
260 SendBindReply(true, addr);
261 }
262 }
263
264 void PepperUDPSocketPrivateHost::OnRecvFromCompleted(int result) {
265 DCHECK(recvfrom_buffer_.get());
266
267 // Convert IPEndPoint we get back from RecvFrom to a PP_NetAddress_Private,
268 // to send back.
269 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress;
270 if (result < 0 ||
271 !NetAddressPrivateImpl::IPEndPointToNetAddress(
272 recvfrom_address_.address(),
273 recvfrom_address_.port(),
274 &addr)) {
275 SendRecvFromError();
276 } else {
277 SendRecvFromReply(true,
278 std::string(recvfrom_buffer_->data(), result),
279 addr);
280 }
281
282 recvfrom_buffer_ = NULL;
283 }
284
285 void PepperUDPSocketPrivateHost::OnSendToCompleted(int result) {
286 DCHECK(sendto_buffer_.get());
287 if (result < 0)
288 SendSendToError();
289 else
290 SendSendToReply(true, result);
291 sendto_buffer_ = NULL;
292 }
293
294 void PepperUDPSocketPrivateHost::SendBindReply(
295 bool succeeded,
296 const PP_NetAddress_Private& addr) {
297 DCHECK(bind_context_.get());
298
299 scoped_ptr<ppapi::host::ReplyMessageContext> context(bind_context_.release());
300 host()->SendReply(*context,
301 PpapiPluginMsg_UDPSocketPrivate_BindReply(succeeded, addr));
302 }
303
304 void PepperUDPSocketPrivateHost::SendRecvFromReply(
305 bool succeeded,
306 const std::string& data,
307 const PP_NetAddress_Private& addr) {
308 DCHECK(recv_from_context_.get());
309
310 scoped_ptr<ppapi::host::ReplyMessageContext> context(
311 recv_from_context_.release());
312 host()->SendReply(*context,
313 PpapiPluginMsg_UDPSocketPrivate_RecvFromReply(succeeded,
314 data,
315 addr));
316 }
317
318 void PepperUDPSocketPrivateHost::SendSendToReply(bool succeeded,
dmichael (off chromium) 2013/01/10 05:57:16 Why have the succeeded parameter? You only call th
ygorshenin1 2013/01/10 11:36:12 Not exactly. These methods are also called from Se
dmichael (off chromium) 2013/01/10 17:30:47 I see, thanks for explaining.
319 int32_t bytes_written) {
320 DCHECK(send_to_context_.get());
321
322 scoped_ptr<ppapi::host::ReplyMessageContext> context(
323 send_to_context_.release());
324 host()->SendReply(*context,
325 PpapiPluginMsg_UDPSocketPrivate_SendToReply(succeeded,
326 bytes_written));
327 }
328
329 void PepperUDPSocketPrivateHost::CheckSocketPermissionsAndReply(
330 const SocketPermissionRequest& params,
331 const RequestCallback& callback) {
332 host_->PostOnUIThreadWithRenderViewHostAndReply(
333 FROM_HERE,
334 pp_instance(),
335 base::Bind(&pepper_socket_utils::CanUseSocketAPIs,
336 host_->plugin_process_type(), params),
337 callback);
338 }
339
340 void PepperUDPSocketPrivateHost::SendBindError() {
341 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress;
342 SendBindReply(false, addr);
dmichael (off chromium) 2013/01/10 05:57:16 Shouldn't you release the context in the error cas
ygorshenin1 2013/01/10 11:36:12 {send_to|recv_from|bind}_context_ are released in
343 }
344
345 void PepperUDPSocketPrivateHost::SendRecvFromError() {
346 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress;
347 SendRecvFromReply(false, "", addr);
348 }
349
350 void PepperUDPSocketPrivateHost::SendSendToError() {
351 SendSendToReply(false, 0);
352 }
353
354 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698