socket_dispatcher.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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/socket_client.h" 14#include "content/renderer/render_view_impl.h" 15#include "webkit/glue/network_list_observer.h" 16 17namespace content { 18 19P2PSocketDispatcher::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<webkit_glue::NetworkListObserver>()), 25 channel_(NULL) { 26} 27 28P2PSocketDispatcher::~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 36void P2PSocketDispatcher::AddNetworkListObserver( 37 webkit_glue::NetworkListObserver* network_list_observer) { 38 network_list_observers_->AddObserver(network_list_observer); 39 network_notifications_started_ = true; 40 SendP2PMessage(new P2PHostMsg_StartNetworkNotifications()); 41} 42 43void P2PSocketDispatcher::RemoveNetworkListObserver( 44 webkit_glue::NetworkListObserver* network_list_observer) { 45 network_list_observers_->RemoveObserver(network_list_observer); 46} 47 48void 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 59bool 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 74void P2PSocketDispatcher::OnFilterAdded(IPC::Channel* channel) { 75 DVLOG(1) << "P2PSocketDispatcher::OnFilterAdded()"; 76 channel_ = channel; 77} 78 79void P2PSocketDispatcher::OnFilterRemoved() { 80 channel_ = NULL; 81} 82 83void P2PSocketDispatcher::OnChannelClosing() { 84 channel_ = NULL; 85} 86 87base::MessageLoopProxy* P2PSocketDispatcher::message_loop() { 88 return message_loop_.get(); 89} 90 91int P2PSocketDispatcher::RegisterClient(P2PSocketClient* client) { 92 DCHECK(message_loop_->BelongsToCurrentThread()); 93 return clients_.Add(client); 94} 95 96void P2PSocketDispatcher::UnregisterClient(int id) { 97 DCHECK(message_loop_->BelongsToCurrentThread()); 98 clients_.Remove(id); 99} 100 101void 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 111int P2PSocketDispatcher::RegisterHostAddressRequest( 112 P2PHostAddressRequest* request) { 113 DCHECK(message_loop_->BelongsToCurrentThread()); 114 return host_address_requests_.Add(request); 115} 116 117void P2PSocketDispatcher::UnregisterHostAddressRequest(int id) { 118 DCHECK(message_loop_->BelongsToCurrentThread()); 119 host_address_requests_.Remove(id); 120} 121 122void P2PSocketDispatcher::OnNetworkListChanged( 123 const net::NetworkInterfaceList& networks) { 124 network_list_observers_->Notify( 125 &webkit_glue::NetworkListObserver::OnNetworkListChanged, networks); 126} 127 128void 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 140void 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 148void 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 156void P2PSocketDispatcher::OnSendComplete(int socket_id) { 157 P2PSocketClient* client = GetClient(socket_id); 158 if (client) { 159 client->OnSendComplete(); 160 } 161} 162 163void P2PSocketDispatcher::OnError(int socket_id) { 164 P2PSocketClient* client = GetClient(socket_id); 165 if (client) { 166 client->OnError(); 167 } 168} 169 170void 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 179P2PSocketClient* 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