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.
5 #include "content/renderer/p2p/socket_dispatcher.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_impl.h"
15 #include "content/renderer/render_view_impl.h"
16 #include "ipc/ipc_sender.h"
20 P2PSocketDispatcher::P2PSocketDispatcher(
21 base::MessageLoopProxy
* ipc_message_loop
)
22 : message_loop_(ipc_message_loop
),
23 network_notifications_started_(false),
24 network_list_observers_(
25 new ObserverListThreadSafe
<NetworkListObserver
>()),
29 P2PSocketDispatcher::~P2PSocketDispatcher() {
30 network_list_observers_
->AssertEmpty();
31 for (IDMap
<P2PSocketClientImpl
>::iterator
i(&clients_
); !i
.IsAtEnd();
33 i
.GetCurrentValue()->Detach();
37 void P2PSocketDispatcher::AddNetworkListObserver(
38 NetworkListObserver
* network_list_observer
) {
39 network_list_observers_
->AddObserver(network_list_observer
);
40 network_notifications_started_
= true;
41 SendP2PMessage(new P2PHostMsg_StartNetworkNotifications());
44 void P2PSocketDispatcher::RemoveNetworkListObserver(
45 NetworkListObserver
* network_list_observer
) {
46 network_list_observers_
->RemoveObserver(network_list_observer
);
49 void P2PSocketDispatcher::Send(IPC::Message
* message
) {
50 DCHECK(message_loop_
->BelongsToCurrentThread());
52 DLOG(WARNING
) << "P2PSocketDispatcher::Send() - Sender closed.";
57 sender_
->Send(message
);
60 bool P2PSocketDispatcher::OnMessageReceived(const IPC::Message
& message
) {
62 IPC_BEGIN_MESSAGE_MAP(P2PSocketDispatcher
, message
)
63 IPC_MESSAGE_HANDLER(P2PMsg_NetworkListChanged
, OnNetworkListChanged
)
64 IPC_MESSAGE_HANDLER(P2PMsg_GetHostAddressResult
, OnGetHostAddressResult
)
65 IPC_MESSAGE_HANDLER(P2PMsg_OnSocketCreated
, OnSocketCreated
)
66 IPC_MESSAGE_HANDLER(P2PMsg_OnIncomingTcpConnection
, OnIncomingTcpConnection
)
67 IPC_MESSAGE_HANDLER(P2PMsg_OnSendComplete
, OnSendComplete
)
68 IPC_MESSAGE_HANDLER(P2PMsg_OnError
, OnError
)
69 IPC_MESSAGE_HANDLER(P2PMsg_OnDataReceived
, OnDataReceived
)
70 IPC_MESSAGE_UNHANDLED(handled
= false)
75 void P2PSocketDispatcher::OnFilterAdded(IPC::Sender
* sender
) {
76 DVLOG(1) << "P2PSocketDispatcher::OnFilterAdded()";
80 void P2PSocketDispatcher::OnFilterRemoved() {
84 void P2PSocketDispatcher::OnChannelClosing() {
88 base::MessageLoopProxy
* P2PSocketDispatcher::message_loop() {
89 return message_loop_
.get();
92 int P2PSocketDispatcher::RegisterClient(P2PSocketClientImpl
* client
) {
93 DCHECK(message_loop_
->BelongsToCurrentThread());
94 return clients_
.Add(client
);
97 void P2PSocketDispatcher::UnregisterClient(int id
) {
98 DCHECK(message_loop_
->BelongsToCurrentThread());
102 void P2PSocketDispatcher::SendP2PMessage(IPC::Message
* msg
) {
103 if (!message_loop_
->BelongsToCurrentThread()) {
104 message_loop_
->PostTask(FROM_HERE
,
105 base::Bind(&P2PSocketDispatcher::Send
,
112 int P2PSocketDispatcher::RegisterHostAddressRequest(
113 P2PAsyncAddressResolver
* request
) {
114 DCHECK(message_loop_
->BelongsToCurrentThread());
115 return host_address_requests_
.Add(request
);
118 void P2PSocketDispatcher::UnregisterHostAddressRequest(int id
) {
119 DCHECK(message_loop_
->BelongsToCurrentThread());
120 host_address_requests_
.Remove(id
);
123 void P2PSocketDispatcher::OnNetworkListChanged(
124 const net::NetworkInterfaceList
& networks
) {
125 network_list_observers_
->Notify(
126 &NetworkListObserver::OnNetworkListChanged
, networks
);
129 void P2PSocketDispatcher::OnGetHostAddressResult(
131 const net::IPAddressList
& addresses
) {
132 P2PAsyncAddressResolver
* request
= host_address_requests_
.Lookup(request_id
);
134 VLOG(1) << "Received P2P message for socket that doesn't exist.";
138 request
->OnResponse(addresses
);
141 void P2PSocketDispatcher::OnSocketCreated(
142 int socket_id
, const net::IPEndPoint
& address
) {
143 P2PSocketClientImpl
* client
= GetClient(socket_id
);
145 client
->OnSocketCreated(address
);
149 void P2PSocketDispatcher::OnIncomingTcpConnection(
150 int socket_id
, const net::IPEndPoint
& address
) {
151 P2PSocketClientImpl
* client
= GetClient(socket_id
);
153 client
->OnIncomingTcpConnection(address
);
157 void P2PSocketDispatcher::OnSendComplete(int socket_id
) {
158 P2PSocketClientImpl
* client
= GetClient(socket_id
);
160 client
->OnSendComplete();
164 void P2PSocketDispatcher::OnError(int socket_id
) {
165 P2PSocketClientImpl
* client
= GetClient(socket_id
);
171 void P2PSocketDispatcher::OnDataReceived(
172 int socket_id
, const net::IPEndPoint
& address
,
173 const std::vector
<char>& data
,
174 const base::TimeTicks
& timestamp
) {
175 P2PSocketClientImpl
* client
= GetClient(socket_id
);
177 client
->OnDataReceived(address
, data
, timestamp
);
181 P2PSocketClientImpl
* P2PSocketDispatcher::GetClient(int socket_id
) {
182 P2PSocketClientImpl
* client
= clients_
.Lookup(socket_id
);
183 if (client
== NULL
) {
184 // This may happen if the socket was closed, but the browser side
185 // hasn't processed the close message by the time it sends the
186 // message to the renderer.
187 VLOG(1) << "Received P2P message for socket that doesn't exist.";
194 } // namespace content