Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / p2p / socket_dispatcher.cc
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_impl.h"
15 #include "content/renderer/render_view_impl.h"
16 #include "ipc/ipc_channel.h"
17
18 namespace content {
19
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>()),
26       channel_(NULL) {
27 }
28
29 P2PSocketDispatcher::~P2PSocketDispatcher() {
30   network_list_observers_->AssertEmpty();
31   for (IDMap<P2PSocketClientImpl>::iterator i(&clients_); !i.IsAtEnd();
32        i.Advance()) {
33     i.GetCurrentValue()->Detach();
34   }
35 }
36
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());
42 }
43
44 void P2PSocketDispatcher::RemoveNetworkListObserver(
45     NetworkListObserver* network_list_observer) {
46   network_list_observers_->RemoveObserver(network_list_observer);
47 }
48
49 void P2PSocketDispatcher::Send(IPC::Message* message) {
50   DCHECK(message_loop_->BelongsToCurrentThread());
51   if (!channel_) {
52     DLOG(WARNING) << "P2PSocketDispatcher::Send() - Channel closed.";
53     delete message;
54     return;
55   }
56
57   channel_->Send(message);
58 }
59
60 bool P2PSocketDispatcher::OnMessageReceived(const IPC::Message& message) {
61   bool handled = true;
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)
71   IPC_END_MESSAGE_MAP()
72   return handled;
73 }
74
75 void P2PSocketDispatcher::OnFilterAdded(IPC::Channel* channel) {
76   DVLOG(1) << "P2PSocketDispatcher::OnFilterAdded()";
77   channel_ = channel;
78 }
79
80 void P2PSocketDispatcher::OnFilterRemoved() {
81   channel_ = NULL;
82 }
83
84 void P2PSocketDispatcher::OnChannelClosing() {
85   channel_ = NULL;
86 }
87
88 base::MessageLoopProxy* P2PSocketDispatcher::message_loop() {
89   return message_loop_.get();
90 }
91
92 int P2PSocketDispatcher::RegisterClient(P2PSocketClientImpl* client) {
93   DCHECK(message_loop_->BelongsToCurrentThread());
94   return clients_.Add(client);
95 }
96
97 void P2PSocketDispatcher::UnregisterClient(int id) {
98   DCHECK(message_loop_->BelongsToCurrentThread());
99   clients_.Remove(id);
100 }
101
102 void P2PSocketDispatcher::SendP2PMessage(IPC::Message* msg) {
103   if (!message_loop_->BelongsToCurrentThread()) {
104     message_loop_->PostTask(FROM_HERE,
105                             base::Bind(&P2PSocketDispatcher::Send,
106                                        this, msg));
107     return;
108   }
109   Send(msg);
110 }
111
112 int P2PSocketDispatcher::RegisterHostAddressRequest(
113     P2PAsyncAddressResolver* request) {
114   DCHECK(message_loop_->BelongsToCurrentThread());
115   return host_address_requests_.Add(request);
116 }
117
118 void P2PSocketDispatcher::UnregisterHostAddressRequest(int id) {
119   DCHECK(message_loop_->BelongsToCurrentThread());
120   host_address_requests_.Remove(id);
121 }
122
123 void P2PSocketDispatcher::OnNetworkListChanged(
124     const net::NetworkInterfaceList& networks) {
125   network_list_observers_->Notify(
126       &NetworkListObserver::OnNetworkListChanged, networks);
127 }
128
129 void P2PSocketDispatcher::OnGetHostAddressResult(
130     int32 request_id,
131     const net::IPAddressList& addresses) {
132   P2PAsyncAddressResolver* request = host_address_requests_.Lookup(request_id);
133   if (!request) {
134     VLOG(1) << "Received P2P message for socket that doesn't exist.";
135     return;
136   }
137
138   request->OnResponse(addresses);
139 }
140
141 void P2PSocketDispatcher::OnSocketCreated(
142     int socket_id, const net::IPEndPoint& address) {
143   P2PSocketClientImpl* client = GetClient(socket_id);
144   if (client) {
145     client->OnSocketCreated(address);
146   }
147 }
148
149 void P2PSocketDispatcher::OnIncomingTcpConnection(
150     int socket_id, const net::IPEndPoint& address) {
151   P2PSocketClientImpl* client = GetClient(socket_id);
152   if (client) {
153     client->OnIncomingTcpConnection(address);
154   }
155 }
156
157 void P2PSocketDispatcher::OnSendComplete(int socket_id) {
158   P2PSocketClientImpl* client = GetClient(socket_id);
159   if (client) {
160     client->OnSendComplete();
161   }
162 }
163
164 void P2PSocketDispatcher::OnError(int socket_id) {
165   P2PSocketClientImpl* client = GetClient(socket_id);
166   if (client) {
167     client->OnError();
168   }
169 }
170
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);
176   if (client) {
177     client->OnDataReceived(address, data, timestamp);
178   }
179 }
180
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.";
188     return NULL;
189   }
190
191   return client;
192 }
193
194 }  // namespace content