Fix crash on app list start page contents not existing.
[chromium-blink-merge.git] / content / renderer / p2p / socket_dispatcher.cc
blob06f6b1e2b5474aad922344bee2e52670a17578d1
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"
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_sender.h"
18 namespace content {
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 sender_(NULL) {
29 P2PSocketDispatcher::~P2PSocketDispatcher() {
30 network_list_observers_->AssertEmpty();
31 for (IDMap<P2PSocketClientImpl>::iterator i(&clients_); !i.IsAtEnd();
32 i.Advance()) {
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());
51 if (!sender_) {
52 DLOG(WARNING) << "P2PSocketDispatcher::Send() - Sender closed.";
53 delete message;
54 return;
57 sender_->Send(message);
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;
75 void P2PSocketDispatcher::OnFilterAdded(IPC::Sender* sender) {
76 DVLOG(1) << "P2PSocketDispatcher::OnFilterAdded()";
77 sender_ = sender;
80 void P2PSocketDispatcher::OnFilterRemoved() {
81 sender_ = NULL;
84 void P2PSocketDispatcher::OnChannelClosing() {
85 sender_ = NULL;
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());
99 clients_.Remove(id);
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;
109 Send(msg);
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 FROM_HERE, &NetworkListObserver::OnNetworkListChanged, networks);
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 DVLOG(1) << "Received P2P message for socket that doesn't exist.";
135 return;
138 request->OnResponse(addresses);
141 void P2PSocketDispatcher::OnSocketCreated(
142 int socket_id,
143 const net::IPEndPoint& local_address,
144 const net::IPEndPoint& remote_address) {
145 P2PSocketClientImpl* client = GetClient(socket_id);
146 if (client) {
147 client->OnSocketCreated(local_address, remote_address);
151 void P2PSocketDispatcher::OnIncomingTcpConnection(
152 int socket_id, const net::IPEndPoint& address) {
153 P2PSocketClientImpl* client = GetClient(socket_id);
154 if (client) {
155 client->OnIncomingTcpConnection(address);
159 void P2PSocketDispatcher::OnSendComplete(
160 int socket_id,
161 const P2PSendPacketMetrics& send_metrics) {
162 P2PSocketClientImpl* client = GetClient(socket_id);
163 if (client) {
164 client->OnSendComplete(send_metrics);
168 void P2PSocketDispatcher::OnError(int socket_id) {
169 P2PSocketClientImpl* client = GetClient(socket_id);
170 if (client) {
171 client->OnError();
175 void P2PSocketDispatcher::OnDataReceived(
176 int socket_id, const net::IPEndPoint& address,
177 const std::vector<char>& data,
178 const base::TimeTicks& timestamp) {
179 P2PSocketClientImpl* client = GetClient(socket_id);
180 if (client) {
181 client->OnDataReceived(address, data, timestamp);
185 P2PSocketClientImpl* P2PSocketDispatcher::GetClient(int socket_id) {
186 P2PSocketClientImpl* client = clients_.Lookup(socket_id);
187 if (client == NULL) {
188 // This may happen if the socket was closed, but the browser side
189 // hasn't processed the close message by the time it sends the
190 // message to the renderer.
191 DVLOG(1) << "Received P2P message for socket that doesn't exist.";
192 return NULL;
195 return client;
198 } // namespace content