Home | History | Annotate | Download | only in p2p
      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/renderer/p2p/socket_dispatcher.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/memory/ref_counted.h"
      9 #include "base/message_loop/message_loop_proxy.h"
     10 #include "content/child/child_process.h"
     11 #include "content/common/p2p_messages.h"
     12 #include "content/renderer/p2p/host_address_request.h"
     13 #include "content/renderer/p2p/network_list_observer.h"
     14 #include "content/renderer/p2p/socket_client.h"
     15 #include "content/renderer/render_view_impl.h"
     16 
     17 namespace content {
     18 
     19 P2PSocketDispatcher::P2PSocketDispatcher(
     20     base::MessageLoopProxy* ipc_message_loop)
     21     : message_loop_(ipc_message_loop),
     22       network_notifications_started_(false),
     23       network_list_observers_(
     24           new ObserverListThreadSafe<NetworkListObserver>()),
     25       channel_(NULL) {
     26 }
     27 
     28 P2PSocketDispatcher::~P2PSocketDispatcher() {
     29   network_list_observers_->AssertEmpty();
     30   for (IDMap<P2PSocketClient>::iterator i(&clients_); !i.IsAtEnd();
     31        i.Advance()) {
     32     i.GetCurrentValue()->Detach();
     33   }
     34 }
     35 
     36 void P2PSocketDispatcher::AddNetworkListObserver(
     37     NetworkListObserver* network_list_observer) {
     38   network_list_observers_->AddObserver(network_list_observer);
     39   network_notifications_started_ = true;
     40   SendP2PMessage(new P2PHostMsg_StartNetworkNotifications());
     41 }
     42 
     43 void P2PSocketDispatcher::RemoveNetworkListObserver(
     44     NetworkListObserver* network_list_observer) {
     45   network_list_observers_->RemoveObserver(network_list_observer);
     46 }
     47 
     48 void P2PSocketDispatcher::Send(IPC::Message* message) {
     49   DCHECK(message_loop_->BelongsToCurrentThread());
     50   if (!channel_) {
     51     DLOG(WARNING) << "P2PSocketDispatcher::Send() - Channel closed.";
     52     delete message;
     53     return;
     54   }
     55 
     56   channel_->Send(message);
     57 }
     58 
     59 bool P2PSocketDispatcher::OnMessageReceived(const IPC::Message& message) {
     60   bool handled = true;
     61   IPC_BEGIN_MESSAGE_MAP(P2PSocketDispatcher, message)
     62     IPC_MESSAGE_HANDLER(P2PMsg_NetworkListChanged, OnNetworkListChanged)
     63     IPC_MESSAGE_HANDLER(P2PMsg_GetHostAddressResult, OnGetHostAddressResult)
     64     IPC_MESSAGE_HANDLER(P2PMsg_OnSocketCreated, OnSocketCreated)
     65     IPC_MESSAGE_HANDLER(P2PMsg_OnIncomingTcpConnection, OnIncomingTcpConnection)
     66     IPC_MESSAGE_HANDLER(P2PMsg_OnSendComplete, OnSendComplete)
     67     IPC_MESSAGE_HANDLER(P2PMsg_OnError, OnError)
     68     IPC_MESSAGE_HANDLER(P2PMsg_OnDataReceived, OnDataReceived)
     69     IPC_MESSAGE_UNHANDLED(handled = false)
     70   IPC_END_MESSAGE_MAP()
     71   return handled;
     72 }
     73 
     74 void P2PSocketDispatcher::OnFilterAdded(IPC::Channel* channel) {
     75   DVLOG(1) << "P2PSocketDispatcher::OnFilterAdded()";
     76   channel_ = channel;
     77 }
     78 
     79 void P2PSocketDispatcher::OnFilterRemoved() {
     80   channel_ = NULL;
     81 }
     82 
     83 void P2PSocketDispatcher::OnChannelClosing() {
     84   channel_ = NULL;
     85 }
     86 
     87 base::MessageLoopProxy* P2PSocketDispatcher::message_loop() {
     88   return message_loop_.get();
     89 }
     90 
     91 int P2PSocketDispatcher::RegisterClient(P2PSocketClient* client) {
     92   DCHECK(message_loop_->BelongsToCurrentThread());
     93   return clients_.Add(client);
     94 }
     95 
     96 void P2PSocketDispatcher::UnregisterClient(int id) {
     97   DCHECK(message_loop_->BelongsToCurrentThread());
     98   clients_.Remove(id);
     99 }
    100 
    101 void P2PSocketDispatcher::SendP2PMessage(IPC::Message* msg) {
    102   if (!message_loop_->BelongsToCurrentThread()) {
    103     message_loop_->PostTask(FROM_HERE,
    104                             base::Bind(&P2PSocketDispatcher::Send,
    105                                        this, msg));
    106     return;
    107   }
    108   Send(msg);
    109 }
    110 
    111 int P2PSocketDispatcher::RegisterHostAddressRequest(
    112     P2PHostAddressRequest* request) {
    113   DCHECK(message_loop_->BelongsToCurrentThread());
    114   return host_address_requests_.Add(request);
    115 }
    116 
    117 void P2PSocketDispatcher::UnregisterHostAddressRequest(int id) {
    118   DCHECK(message_loop_->BelongsToCurrentThread());
    119   host_address_requests_.Remove(id);
    120 }
    121 
    122 void P2PSocketDispatcher::OnNetworkListChanged(
    123     const net::NetworkInterfaceList& networks) {
    124   network_list_observers_->Notify(
    125       &NetworkListObserver::OnNetworkListChanged, networks);
    126 }
    127 
    128 void P2PSocketDispatcher::OnGetHostAddressResult(
    129     int32 request_id,
    130     const net::IPAddressNumber& address) {
    131   P2PHostAddressRequest* request = host_address_requests_.Lookup(request_id);
    132   if (!request) {
    133     VLOG(1) << "Received P2P message for socket that doesn't exist.";
    134     return;
    135   }
    136 
    137   request->OnResponse(address);
    138 }
    139 
    140 void P2PSocketDispatcher::OnSocketCreated(
    141     int socket_id, const net::IPEndPoint& address) {
    142   P2PSocketClient* client = GetClient(socket_id);
    143   if (client) {
    144     client->OnSocketCreated(address);
    145   }
    146 }
    147 
    148 void P2PSocketDispatcher::OnIncomingTcpConnection(
    149     int socket_id, const net::IPEndPoint& address) {
    150   P2PSocketClient* client = GetClient(socket_id);
    151   if (client) {
    152     client->OnIncomingTcpConnection(address);
    153   }
    154 }
    155 
    156 void P2PSocketDispatcher::OnSendComplete(int socket_id) {
    157   P2PSocketClient* client = GetClient(socket_id);
    158   if (client) {
    159     client->OnSendComplete();
    160   }
    161 }
    162 
    163 void P2PSocketDispatcher::OnError(int socket_id) {
    164   P2PSocketClient* client = GetClient(socket_id);
    165   if (client) {
    166     client->OnError();
    167   }
    168 }
    169 
    170 void P2PSocketDispatcher::OnDataReceived(
    171     int socket_id, const net::IPEndPoint& address,
    172     const std::vector<char>& data) {
    173   P2PSocketClient* client = GetClient(socket_id);
    174   if (client) {
    175     client->OnDataReceived(address, data);
    176   }
    177 }
    178 
    179 P2PSocketClient* P2PSocketDispatcher::GetClient(int socket_id) {
    180   P2PSocketClient* client = clients_.Lookup(socket_id);
    181   if (client == NULL) {
    182     // This may happen if the socket was closed, but the browser side
    183     // hasn't processed the close message by the time it sends the
    184     // message to the renderer.
    185     VLOG(1) << "Received P2P message for socket that doesn't exist.";
    186     return NULL;
    187   }
    188 
    189   return client;
    190 }
    191 
    192 }  // namespace content
    193