Home | History | Annotate | Download | only in proxy
      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