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

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

Issue 704133005: Pepper: Add support for multicast in PPB_UDPSocket API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix typo: SetMulticastInterface -> SetMulticastTimeToLive Created 5 years, 9 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter. h" 5 #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter. h"
6 6
7 #include <cstring> 7 #include <cstring>
8 8
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 11 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
12 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" 12 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
13 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/content_browser_client.h"
14 #include "content/public/common/process_type.h" 15 #include "content/public/common/process_type.h"
15 #include "content/public/common/socket_permission_request.h" 16 #include "content/public/common/socket_permission_request.h"
16 #include "ipc/ipc_message_macros.h" 17 #include "ipc/ipc_message_macros.h"
17 #include "net/base/io_buffer.h" 18 #include "net/base/io_buffer.h"
18 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
19 #include "net/base/rand_callback.h" 20 #include "net/base/rand_callback.h"
20 #include "net/udp/udp_socket.h" 21 #include "net/udp/udp_socket.h"
21 #include "ppapi/c/pp_errors.h" 22 #include "ppapi/c/pp_errors.h"
22 #include "ppapi/c/private/ppb_net_address_private.h" 23 #include "ppapi/c/private/ppb_net_address_private.h"
23 #include "ppapi/host/dispatch_host_message.h" 24 #include "ppapi/host/dispatch_host_message.h"
(...skipping 29 matching lines...) Expand all
53 PepperUDPSocketMessageFilter::PendingSend::~PendingSend() { 54 PepperUDPSocketMessageFilter::PendingSend::~PendingSend() {
54 } 55 }
55 56
56 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( 57 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter(
57 BrowserPpapiHostImpl* host, 58 BrowserPpapiHostImpl* host,
58 PP_Instance instance, 59 PP_Instance instance,
59 bool private_api) 60 bool private_api)
60 : socket_options_(0), 61 : socket_options_(0),
61 rcvbuf_size_(0), 62 rcvbuf_size_(0),
62 sndbuf_size_(0), 63 sndbuf_size_(0),
64 multicast_ttl_(0),
65 can_use_multicast_(PP_ERROR_FAILED),
63 closed_(false), 66 closed_(false),
64 remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots), 67 remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots),
65 external_plugin_(host->external_plugin()), 68 external_plugin_(host->external_plugin()),
66 private_api_(private_api), 69 private_api_(private_api),
67 render_process_id_(0), 70 render_process_id_(0),
68 render_frame_id_(0) { 71 render_frame_id_(0) {
69 ++g_num_instances; 72 ++g_num_instances;
70 DCHECK(host); 73 DCHECK(host);
71 74
72 if (!host->GetRenderFrameIDsForInstance( 75 if (!host->GetRenderFrameIDsForInstance(
(...skipping 15 matching lines...) Expand all
88 scoped_refptr<base::TaskRunner> 91 scoped_refptr<base::TaskRunner>
89 PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( 92 PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage(
90 const IPC::Message& message) { 93 const IPC::Message& message) {
91 switch (message.type()) { 94 switch (message.type()) {
92 case PpapiHostMsg_UDPSocket_SetOption::ID: 95 case PpapiHostMsg_UDPSocket_SetOption::ID:
93 case PpapiHostMsg_UDPSocket_Close::ID: 96 case PpapiHostMsg_UDPSocket_Close::ID:
94 case PpapiHostMsg_UDPSocket_RecvSlotAvailable::ID: 97 case PpapiHostMsg_UDPSocket_RecvSlotAvailable::ID:
95 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 98 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
96 case PpapiHostMsg_UDPSocket_Bind::ID: 99 case PpapiHostMsg_UDPSocket_Bind::ID:
97 case PpapiHostMsg_UDPSocket_SendTo::ID: 100 case PpapiHostMsg_UDPSocket_SendTo::ID:
101 case PpapiHostMsg_UDPSocket_JoinGroup::ID:
102 case PpapiHostMsg_UDPSocket_LeaveGroup::ID:
98 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); 103 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
99 } 104 }
100 return NULL; 105 return NULL;
101 } 106 }
102 107
103 int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived( 108 int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived(
104 const IPC::Message& msg, 109 const IPC::Message& msg,
105 ppapi::host::HostMessageContext* context) { 110 ppapi::host::HostMessageContext* context) {
106 PPAPI_BEGIN_MESSAGE_MAP(PepperUDPSocketMessageFilter, msg) 111 PPAPI_BEGIN_MESSAGE_MAP(PepperUDPSocketMessageFilter, msg)
107 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SetOption, 112 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SetOption,
108 OnMsgSetOption) 113 OnMsgSetOption)
109 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_Bind, OnMsgBind) 114 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_Bind, OnMsgBind)
110 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SendTo, 115 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SendTo,
111 OnMsgSendTo) 116 OnMsgSendTo)
112 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_UDPSocket_Close, 117 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_UDPSocket_Close,
113 OnMsgClose) 118 OnMsgClose)
114 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( 119 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
115 PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable) 120 PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable)
121 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_JoinGroup,
122 OnMsgJoinGroup)
123 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_LeaveGroup,
124 OnMsgLeaveGroup)
116 PPAPI_END_MESSAGE_MAP() 125 PPAPI_END_MESSAGE_MAP()
117 return PP_ERROR_FAILED; 126 return PP_ERROR_FAILED;
118 } 127 }
119 128
120 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( 129 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption(
121 const ppapi::host::HostMessageContext* context, 130 const ppapi::host::HostMessageContext* context,
122 PP_UDPSocket_Option name, 131 PP_UDPSocket_Option name,
123 const ppapi::SocketOptionData& value) { 132 const ppapi::SocketOptionData& value) {
124 DCHECK_CURRENTLY_ON(BrowserThread::IO); 133 DCHECK_CURRENTLY_ON(BrowserThread::IO);
125 134
(...skipping 18 matching lines...) Expand all
144 } else { 153 } else {
145 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE; 154 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE;
146 } 155 }
147 return PP_OK; 156 return PP_OK;
148 } 157 }
149 case PP_UDPSOCKET_OPTION_BROADCAST: { 158 case PP_UDPSOCKET_OPTION_BROADCAST: {
150 bool boolean_value = false; 159 bool boolean_value = false;
151 if (!value.GetBool(&boolean_value)) 160 if (!value.GetBool(&boolean_value))
152 return PP_ERROR_BADARGUMENT; 161 return PP_ERROR_BADARGUMENT;
153 162
154 // If the socket is already connected, proxy the value to TCPSocket. 163 // If the socket is already bound, proxy the value to UDPSocket.
155 if (socket_.get()) 164 if (socket_.get())
156 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value)); 165 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value));
157 166
158 // UDPSocket instance is not yet created, so remember the value here. 167 // UDPSocket instance is not yet created, so remember the value here.
159 if (boolean_value) { 168 if (boolean_value) {
160 socket_options_ |= SOCKET_OPTION_BROADCAST; 169 socket_options_ |= SOCKET_OPTION_BROADCAST;
161 } else { 170 } else {
162 socket_options_ &= ~SOCKET_OPTION_BROADCAST; 171 socket_options_ &= ~SOCKET_OPTION_BROADCAST;
163 } 172 }
164 return PP_OK; 173 return PP_OK;
165 } 174 }
166 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: { 175 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: {
167 int32_t integer_value = 0; 176 int32_t integer_value = 0;
168 if (!value.GetInt32(&integer_value) || 177 if (!value.GetInt32(&integer_value) ||
169 integer_value <= 0 || 178 integer_value <= 0 ||
170 integer_value > 179 integer_value >
171 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) 180 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize)
172 return PP_ERROR_BADARGUMENT; 181 return PP_ERROR_BADARGUMENT;
173 182
174 // If the socket is already connected, proxy the value to UDPSocket. 183 // If the socket is already bound, proxy the value to UDPSocket.
175 if (socket_.get()) { 184 if (socket_.get()) {
176 return NetErrorToPepperError( 185 return NetErrorToPepperError(
177 socket_->SetSendBufferSize(integer_value)); 186 socket_->SetSendBufferSize(integer_value));
178 } 187 }
179 188
180 // UDPSocket instance is not yet created, so remember the value here. 189 // UDPSocket instance is not yet created, so remember the value here.
181 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE; 190 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE;
182 sndbuf_size_ = integer_value; 191 sndbuf_size_ = integer_value;
183 return PP_OK; 192 return PP_OK;
184 } 193 }
185 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { 194 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: {
186 int32_t integer_value = 0; 195 int32_t integer_value = 0;
187 if (!value.GetInt32(&integer_value) || 196 if (!value.GetInt32(&integer_value) ||
188 integer_value <= 0 || 197 integer_value <= 0 ||
189 integer_value > 198 integer_value >
190 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) 199 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize)
191 return PP_ERROR_BADARGUMENT; 200 return PP_ERROR_BADARGUMENT;
192 201
193 // If the socket is already connected, proxy the value to UDPSocket. 202 // If the socket is already bound, proxy the value to UDPSocket.
194 if (socket_.get()) { 203 if (socket_.get()) {
195 return NetErrorToPepperError( 204 return NetErrorToPepperError(
196 socket_->SetReceiveBufferSize(integer_value)); 205 socket_->SetReceiveBufferSize(integer_value));
197 } 206 }
198 207
199 // UDPSocket instance is not yet created, so remember the value here. 208 // UDPSocket instance is not yet created, so remember the value here.
200 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; 209 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
201 rcvbuf_size_ = integer_value; 210 rcvbuf_size_ = integer_value;
202 return PP_OK; 211 return PP_OK;
203 } 212 }
213 case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: {
214 bool boolean_value = false;
215 if (!value.GetBool(&boolean_value))
216 return PP_ERROR_BADARGUMENT;
217
218 // If the socket is already bound, proxy the value to UDPSocket.
219 if (socket_) {
220 if (can_use_multicast_ != PP_OK)
221 return can_use_multicast_;
222
223 return NetErrorToPepperError(
224 socket_->SetMulticastLoopbackMode(boolean_value));
225 }
226
227 // UDPSocket instance is not yet created, so remember the value here.
228 if (boolean_value) {
229 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP;
230 } else {
231 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP;
232 }
233 return PP_OK;
234 }
235 case PP_UDPSOCKET_OPTION_MULTICAST_TTL: {
236 int32_t integer_value = 0;
237 if (!value.GetInt32(&integer_value) ||
238 integer_value < 0 || integer_value > 255)
239 return PP_ERROR_BADARGUMENT;
240
241 // If the socket is already bound, proxy the value to UDPSocket.
242 if (socket_) {
243 if (can_use_multicast_ != PP_OK)
244 return can_use_multicast_;
245
246 return NetErrorToPepperError(
247 socket_->SetMulticastTimeToLive(integer_value));
248 }
249
250 // UDPSocket instance is not yet created, so remember the value here.
251 socket_options_ |= SOCKET_OPTION_MULTICAST_TTL;
252 multicast_ttl_ = integer_value;
253 return PP_OK;
254 }
204 default: { 255 default: {
205 NOTREACHED(); 256 NOTREACHED();
206 return PP_ERROR_BADARGUMENT; 257 return PP_ERROR_BADARGUMENT;
207 } 258 }
208 } 259 }
209 } 260 }
210 261
211 int32_t PepperUDPSocketMessageFilter::OnMsgBind( 262 int32_t PepperUDPSocketMessageFilter::OnMsgBind(
212 const ppapi::host::HostMessageContext* context, 263 const ppapi::host::HostMessageContext* context,
213 const PP_NetAddress_Private& addr) { 264 const PP_NetAddress_Private& addr) {
214 DCHECK_CURRENTLY_ON(BrowserThread::UI); 265 DCHECK_CURRENTLY_ON(BrowserThread::UI);
215 DCHECK(context); 266 DCHECK(context);
216 267
268 // Check for permissions to use multicast APIS. This check must be done while
269 // on the UI thread, so we cache the value here to be used later on.
270 PP_NetAddress_Private any_addr;
271 NetAddressPrivateImpl::GetAnyAddress(PP_FALSE, &any_addr);
272 can_use_multicast_ = CanUseMulticastAPI(any_addr);
273
217 SocketPermissionRequest request = 274 SocketPermissionRequest request =
218 pepper_socket_utils::CreateSocketPermissionRequest( 275 pepper_socket_utils::CreateSocketPermissionRequest(
219 SocketPermissionRequest::UDP_BIND, addr); 276 SocketPermissionRequest::UDP_BIND, addr);
220 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 277 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
221 private_api_, 278 private_api_,
222 &request, 279 &request,
223 render_process_id_, 280 render_process_id_,
224 render_frame_id_)) { 281 render_frame_id_)) {
225 return PP_ERROR_NOACCESS; 282 return PP_ERROR_NOACCESS;
226 } 283 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 336 }
280 337
281 if (!recvfrom_buffer_.get() && !closed_ && socket_.get()) { 338 if (!recvfrom_buffer_.get() && !closed_ && socket_.get()) {
282 DCHECK_EQ(1u, remaining_recv_slots_); 339 DCHECK_EQ(1u, remaining_recv_slots_);
283 DoRecvFrom(); 340 DoRecvFrom();
284 } 341 }
285 342
286 return PP_OK; 343 return PP_OK;
287 } 344 }
288 345
346 int32_t PepperUDPSocketMessageFilter::OnMsgJoinGroup(
347 const ppapi::host::HostMessageContext* context,
348 const PP_NetAddress_Private& addr) {
349 DCHECK_CURRENTLY_ON(BrowserThread::UI);
350
351 int32_t ret = CanUseMulticastAPI(addr);
352 if (ret != PP_OK)
353 return ret;
354
355 if (!socket_)
356 return PP_ERROR_FAILED;
357
358 net::IPAddressNumber group;
359 uint16 port;
360
361 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port))
362 return PP_ERROR_ADDRESS_INVALID;
363
364 return NetErrorToPepperError(socket_->JoinGroup(group));
365 }
366
367 int32_t PepperUDPSocketMessageFilter::OnMsgLeaveGroup(
368 const ppapi::host::HostMessageContext* context,
369 const PP_NetAddress_Private& addr) {
370 DCHECK_CURRENTLY_ON(BrowserThread::UI);
371
372 int32_t ret = CanUseMulticastAPI(addr);
373 if (ret != PP_OK)
374 return ret;
375
376 if (!socket_)
377 return PP_ERROR_FAILED;
378
379 net::IPAddressNumber group;
380 uint16 port;
381
382 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port))
383 return PP_ERROR_ADDRESS_INVALID;
384
385 return NetErrorToPepperError(socket_->LeaveGroup(group));
386 }
387
289 void PepperUDPSocketMessageFilter::DoBind( 388 void PepperUDPSocketMessageFilter::DoBind(
290 const ppapi::host::ReplyMessageContext& context, 389 const ppapi::host::ReplyMessageContext& context,
291 const PP_NetAddress_Private& addr) { 390 const PP_NetAddress_Private& addr) {
292 DCHECK_CURRENTLY_ON(BrowserThread::IO); 391 DCHECK_CURRENTLY_ON(BrowserThread::IO);
293 392
294 if (closed_ || socket_.get()) { 393 if (closed_ || socket_.get()) {
295 SendBindError(context, PP_ERROR_FAILED); 394 SendBindError(context, PP_ERROR_FAILED);
296 return; 395 return;
297 } 396 }
298 397
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 return; 435 return;
337 } 436 }
338 } 437 }
339 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { 438 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
340 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_); 439 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_);
341 if (net_result != net::OK) { 440 if (net_result != net::OK) {
342 SendBindError(context, NetErrorToPepperError(net_result)); 441 SendBindError(context, NetErrorToPepperError(net_result));
343 return; 442 return;
344 } 443 }
345 } 444 }
445 if (socket_options_ & SOCKET_OPTION_MULTICAST_LOOP) {
446 if (can_use_multicast_ != PP_OK) {
447 SendBindError(context, NetErrorToPepperError(can_use_multicast_));
448 return;
449 }
450
451 int net_result = socket->SetMulticastLoopbackMode(true);
452 if (net_result != net::OK) {
453 SendBindError(context, NetErrorToPepperError(net_result));
454 return;
455 }
456 }
457 if (socket_options_ & SOCKET_OPTION_MULTICAST_TTL) {
458 if (can_use_multicast_ != PP_OK) {
459 SendBindError(context, NetErrorToPepperError(can_use_multicast_));
460 return;
461 }
462
463 int net_result = socket->SetMulticastTimeToLive(multicast_ttl_);
464 if (net_result != net::OK) {
465 SendBindError(context, NetErrorToPepperError(net_result));
466 return;
467 }
468 }
346 469
347 { 470 {
348 int net_result = socket->Bind(end_point); 471 int net_result = socket->Bind(end_point);
349 if (net_result != net::OK) { 472 if (net_result != net::OK) {
350 SendBindError(context, NetErrorToPepperError(net_result)); 473 SendBindError(context, NetErrorToPepperError(net_result));
351 return; 474 return;
352 } 475 }
353 } 476 }
354 477
355 net::IPEndPoint bound_address; 478 net::IPEndPoint bound_address;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 SendRecvFromResult(result, std::string(), 686 SendRecvFromResult(result, std::string(),
564 NetAddressPrivateImpl::kInvalidNetAddress); 687 NetAddressPrivateImpl::kInvalidNetAddress);
565 } 688 }
566 689
567 void PepperUDPSocketMessageFilter::SendSendToError( 690 void PepperUDPSocketMessageFilter::SendSendToError(
568 const ppapi::host::ReplyMessageContext& context, 691 const ppapi::host::ReplyMessageContext& context,
569 int32_t result) { 692 int32_t result) {
570 SendSendToReply(context, result, 0); 693 SendSendToReply(context, result, 0);
571 } 694 }
572 695
696 int32_t PepperUDPSocketMessageFilter::CanUseMulticastAPI(
697 const PP_NetAddress_Private& addr) {
698 // Check for Dev API.
699 // TODO(etrunko): remove check when Multicast API reaches beta/stable.
700 // https://crbug.com/464452
701 ContentBrowserClient* content_browser_client = GetContentClient()->browser();
702 if (!content_browser_client->IsPluginAllowedToUseDevChannelAPIs(nullptr,
703 GURL())) {
704 return PP_ERROR_NOTSUPPORTED;
705 }
706
707 // Check for plugin permissions.
708 SocketPermissionRequest request =
709 pepper_socket_utils::CreateSocketPermissionRequest(
710 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, addr);
711 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
712 private_api_,
713 &request,
714 render_process_id_,
715 render_frame_id_)) {
716 return PP_ERROR_NOACCESS;
717 }
718
719 return PP_OK;
720 }
721
573 } // namespace content 722 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h ('k') | ppapi/api/ppb_udp_socket.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698