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 3 // found in the LICENSE file. 4 5 #include "ppapi/proxy/tcp_server_socket_private_resource.h" 6 7 #include "ppapi/proxy/plugin_dispatcher.h" 8 #include "ppapi/proxy/ppapi_messages.h" 9 #include "ppapi/proxy/ppb_tcp_socket_private_proxy.h" 10 11 namespace ppapi { 12 namespace proxy { 13 14 TCPServerSocketPrivateResource::TCPServerSocketPrivateResource( 15 Connection connection, 16 PP_Instance instance) 17 : PluginResource(connection, instance), 18 state_(STATE_BEFORE_LISTENING), 19 local_addr_(), 20 plugin_dispatcher_id_(0) { 21 SendCreate(BROWSER, PpapiHostMsg_TCPServerSocket_CreatePrivate()); 22 23 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); 24 if (dispatcher) 25 plugin_dispatcher_id_ = dispatcher->plugin_dispatcher_id(); 26 else 27 NOTREACHED(); 28 } 29 30 TCPServerSocketPrivateResource::~TCPServerSocketPrivateResource() { 31 } 32 33 thunk::PPB_TCPServerSocket_Private_API* 34 TCPServerSocketPrivateResource::AsPPB_TCPServerSocket_Private_API() { 35 return this; 36 } 37 38 int32_t TCPServerSocketPrivateResource::Listen( 39 const PP_NetAddress_Private* addr, 40 int32_t backlog, 41 scoped_refptr<TrackedCallback> callback) { 42 if (!addr) 43 return PP_ERROR_BADARGUMENT; 44 if (state_ != STATE_BEFORE_LISTENING) 45 return PP_ERROR_FAILED; 46 if (TrackedCallback::IsPending(listen_callback_)) 47 return PP_ERROR_INPROGRESS; 48 49 listen_callback_ = callback; 50 51 // Send the request, the browser will call us back via ListenACK 52 Call<PpapiPluginMsg_TCPServerSocket_ListenReply>( 53 BROWSER, 54 PpapiHostMsg_TCPServerSocket_Listen(*addr, backlog), 55 base::Bind(&TCPServerSocketPrivateResource::OnPluginMsgListenReply, 56 base::Unretained(this))); 57 return PP_OK_COMPLETIONPENDING; 58 } 59 60 int32_t TCPServerSocketPrivateResource::Accept( 61 PP_Resource* tcp_socket, 62 scoped_refptr<TrackedCallback> callback) { 63 if (!tcp_socket) 64 return PP_ERROR_BADARGUMENT; 65 if (state_ != STATE_LISTENING) 66 return PP_ERROR_FAILED; 67 if (TrackedCallback::IsPending(accept_callback_)) 68 return PP_ERROR_INPROGRESS; 69 70 accept_callback_ = callback; 71 72 Call<PpapiPluginMsg_TCPServerSocket_AcceptReply>( 73 BROWSER, 74 PpapiHostMsg_TCPServerSocket_Accept(plugin_dispatcher_id_), 75 base::Bind(&TCPServerSocketPrivateResource::OnPluginMsgAcceptReply, 76 base::Unretained(this), tcp_socket)); 77 return PP_OK_COMPLETIONPENDING; 78 } 79 80 int32_t TCPServerSocketPrivateResource::GetLocalAddress( 81 PP_NetAddress_Private* addr) { 82 if (!addr) 83 return PP_ERROR_BADARGUMENT; 84 if (state_ != STATE_LISTENING) 85 return PP_ERROR_FAILED; 86 *addr = local_addr_; 87 return PP_OK; 88 } 89 90 void TCPServerSocketPrivateResource::StopListening() { 91 if (state_ == STATE_CLOSED) 92 return; 93 state_ = STATE_CLOSED; 94 Post(BROWSER, PpapiHostMsg_TCPServerSocket_StopListening()); 95 if (TrackedCallback::IsPending(listen_callback_)) 96 listen_callback_->PostAbort(); 97 if (TrackedCallback::IsPending(accept_callback_)) 98 accept_callback_->PostAbort(); 99 } 100 101 void TCPServerSocketPrivateResource::OnPluginMsgListenReply( 102 const ResourceMessageReplyParams& params, 103 const PP_NetAddress_Private& local_addr) { 104 if (state_ != STATE_BEFORE_LISTENING || 105 !TrackedCallback::IsPending(listen_callback_)) { 106 return; 107 } 108 if (params.result() == PP_OK) { 109 local_addr_ = local_addr; 110 state_ = STATE_LISTENING; 111 } 112 listen_callback_->Run(params.result()); 113 } 114 115 void TCPServerSocketPrivateResource::OnPluginMsgAcceptReply( 116 PP_Resource* tcp_socket, 117 const ResourceMessageReplyParams& params, 118 uint32 accepted_socket_id, 119 const PP_NetAddress_Private& local_addr, 120 const PP_NetAddress_Private& remote_addr) { 121 DCHECK(tcp_socket); 122 if (state_ != STATE_LISTENING || 123 !TrackedCallback::IsPending(accept_callback_)) { 124 return; 125 } 126 if (params.result() == PP_OK) { 127 *tcp_socket = 128 PPB_TCPSocket_Private_Proxy::CreateProxyResourceForConnectedSocket( 129 pp_instance(), 130 accepted_socket_id, 131 local_addr, 132 remote_addr); 133 } 134 accept_callback_->Run(params.result()); 135 } 136 137 } // namespace proxy 138 } // namespace ppapi 139