Fix some nits from the two previous plugin power saver CLs.
[chromium-blink-merge.git] / content / renderer / p2p / socket_client_impl.cc
blob1425151089cf42930e66dfd190dff516af893b44
1 // Copyright 2013 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_client_impl.h"
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/time/time.h"
10 #include "content/common/p2p_messages.h"
11 #include "content/renderer/p2p/socket_client_delegate.h"
12 #include "content/renderer/p2p/socket_dispatcher.h"
13 #include "content/renderer/render_thread_impl.h"
14 #include "crypto/random.h"
16 namespace {
18 uint64 GetUniqueId(uint32 random_socket_id, uint32 packet_id) {
19 uint64 uid = random_socket_id;
20 uid <<= 32;
21 uid |= packet_id;
22 return uid;
25 } // namespace
27 namespace content {
29 P2PSocketClientImpl::P2PSocketClientImpl(P2PSocketDispatcher* dispatcher)
30 : dispatcher_(dispatcher),
31 ipc_message_loop_(dispatcher->message_loop()),
32 delegate_message_loop_(base::MessageLoopProxy::current()),
33 socket_id_(0), delegate_(NULL),
34 state_(STATE_UNINITIALIZED),
35 random_socket_id_(0),
36 next_packet_id_(0) {
37 crypto::RandBytes(&random_socket_id_, sizeof(random_socket_id_));
40 P2PSocketClientImpl::~P2PSocketClientImpl() {
41 CHECK(state_ == STATE_CLOSED || state_ == STATE_UNINITIALIZED);
44 void P2PSocketClientImpl::Init(
45 P2PSocketType type,
46 const net::IPEndPoint& local_address,
47 const P2PHostAndIPEndPoint& remote_address,
48 P2PSocketClientDelegate* delegate) {
49 DCHECK(delegate_message_loop_->BelongsToCurrentThread());
50 DCHECK(delegate);
51 // |delegate_| is only accessesed on |delegate_message_loop_|.
52 delegate_ = delegate;
54 ipc_message_loop_->PostTask(
55 FROM_HERE, base::Bind(&P2PSocketClientImpl::DoInit,
56 this,
57 type,
58 local_address,
59 remote_address));
62 void P2PSocketClientImpl::DoInit(P2PSocketType type,
63 const net::IPEndPoint& local_address,
64 const P2PHostAndIPEndPoint& remote_address) {
65 DCHECK_EQ(state_, STATE_UNINITIALIZED);
66 state_ = STATE_OPENING;
67 socket_id_ = dispatcher_->RegisterClient(this);
68 dispatcher_->SendP2PMessage(new P2PHostMsg_CreateSocket(
69 type, socket_id_, local_address, remote_address));
72 void P2PSocketClientImpl::SendWithDscp(
73 const net::IPEndPoint& address,
74 const std::vector<char>& data,
75 const rtc::PacketOptions& options) {
76 if (!ipc_message_loop_->BelongsToCurrentThread()) {
77 ipc_message_loop_->PostTask(
78 FROM_HERE, base::Bind(
79 &P2PSocketClientImpl::SendWithDscp, this, address, data, options));
80 return;
83 // Can send data only when the socket is open.
84 DCHECK(state_ == STATE_OPEN || state_ == STATE_ERROR);
85 if (state_ == STATE_OPEN) {
86 uint64 unique_id = GetUniqueId(random_socket_id_, ++next_packet_id_);
87 TRACE_EVENT_ASYNC_BEGIN0("p2p", "Send", unique_id);
88 dispatcher_->SendP2PMessage(new P2PHostMsg_Send(socket_id_, address, data,
89 options, unique_id));
93 void P2PSocketClientImpl::Send(const net::IPEndPoint& address,
94 const std::vector<char>& data) {
95 rtc::PacketOptions options(rtc::DSCP_DEFAULT);
96 SendWithDscp(address, data, options);
99 void P2PSocketClientImpl::SetOption(P2PSocketOption option,
100 int value) {
101 if (!ipc_message_loop_->BelongsToCurrentThread()) {
102 ipc_message_loop_->PostTask(
103 FROM_HERE, base::Bind(
104 &P2PSocketClientImpl::SetOption, this, option, value));
105 return;
108 DCHECK(state_ == STATE_OPEN || state_ == STATE_ERROR);
109 if (state_ == STATE_OPEN) {
110 dispatcher_->SendP2PMessage(new P2PHostMsg_SetOption(socket_id_,
111 option, value));
115 void P2PSocketClientImpl::Close() {
116 DCHECK(delegate_message_loop_->BelongsToCurrentThread());
118 delegate_ = NULL;
120 ipc_message_loop_->PostTask(
121 FROM_HERE, base::Bind(&P2PSocketClientImpl::DoClose, this));
124 void P2PSocketClientImpl::DoClose() {
125 DCHECK(ipc_message_loop_->BelongsToCurrentThread());
126 if (dispatcher_) {
127 if (state_ == STATE_OPEN || state_ == STATE_OPENING ||
128 state_ == STATE_ERROR) {
129 dispatcher_->SendP2PMessage(new P2PHostMsg_DestroySocket(socket_id_));
131 dispatcher_->UnregisterClient(socket_id_);
134 state_ = STATE_CLOSED;
137 int P2PSocketClientImpl::GetSocketID() const {
138 return socket_id_;
141 void P2PSocketClientImpl::SetDelegate(P2PSocketClientDelegate* delegate) {
142 DCHECK(delegate_message_loop_->BelongsToCurrentThread());
143 delegate_ = delegate;
146 void P2PSocketClientImpl::OnSocketCreated(
147 const net::IPEndPoint& local_address,
148 const net::IPEndPoint& remote_address) {
149 DCHECK(ipc_message_loop_->BelongsToCurrentThread());
150 DCHECK_EQ(state_, STATE_OPENING);
151 state_ = STATE_OPEN;
153 delegate_message_loop_->PostTask(
154 FROM_HERE,
155 base::Bind(&P2PSocketClientImpl::DeliverOnSocketCreated, this,
156 local_address, remote_address));
159 void P2PSocketClientImpl::DeliverOnSocketCreated(
160 const net::IPEndPoint& local_address,
161 const net::IPEndPoint& remote_address) {
162 DCHECK(delegate_message_loop_->BelongsToCurrentThread());
163 if (delegate_)
164 delegate_->OnOpen(local_address, remote_address);
167 void P2PSocketClientImpl::OnIncomingTcpConnection(
168 const net::IPEndPoint& address) {
169 DCHECK(ipc_message_loop_->BelongsToCurrentThread());
170 DCHECK_EQ(state_, STATE_OPEN);
172 scoped_refptr<P2PSocketClientImpl> new_client =
173 new P2PSocketClientImpl(dispatcher_);
174 new_client->socket_id_ = dispatcher_->RegisterClient(new_client.get());
175 new_client->state_ = STATE_OPEN;
176 new_client->delegate_message_loop_ = delegate_message_loop_;
178 dispatcher_->SendP2PMessage(new P2PHostMsg_AcceptIncomingTcpConnection(
179 socket_id_, address, new_client->socket_id_));
181 delegate_message_loop_->PostTask(
182 FROM_HERE, base::Bind(
183 &P2PSocketClientImpl::DeliverOnIncomingTcpConnection,
184 this, address, new_client));
187 void P2PSocketClientImpl::DeliverOnIncomingTcpConnection(
188 const net::IPEndPoint& address,
189 scoped_refptr<P2PSocketClient> new_client) {
190 DCHECK(delegate_message_loop_->BelongsToCurrentThread());
191 if (delegate_) {
192 delegate_->OnIncomingTcpConnection(address, new_client.get());
193 } else {
194 // Just close the socket if there is no delegate to accept it.
195 new_client->Close();
199 void P2PSocketClientImpl::OnSendComplete() {
200 DCHECK(ipc_message_loop_->BelongsToCurrentThread());
202 delegate_message_loop_->PostTask(
203 FROM_HERE, base::Bind(&P2PSocketClientImpl::DeliverOnSendComplete, this));
206 void P2PSocketClientImpl::DeliverOnSendComplete() {
207 DCHECK(delegate_message_loop_->BelongsToCurrentThread());
208 if (delegate_)
209 delegate_->OnSendComplete();
212 void P2PSocketClientImpl::OnError() {
213 DCHECK(ipc_message_loop_->BelongsToCurrentThread());
214 state_ = STATE_ERROR;
216 delegate_message_loop_->PostTask(
217 FROM_HERE, base::Bind(&P2PSocketClientImpl::DeliverOnError, this));
220 void P2PSocketClientImpl::DeliverOnError() {
221 DCHECK(delegate_message_loop_->BelongsToCurrentThread());
222 if (delegate_)
223 delegate_->OnError();
226 void P2PSocketClientImpl::OnDataReceived(const net::IPEndPoint& address,
227 const std::vector<char>& data,
228 const base::TimeTicks& timestamp) {
229 DCHECK(ipc_message_loop_->BelongsToCurrentThread());
230 DCHECK_EQ(STATE_OPEN, state_);
231 delegate_message_loop_->PostTask(
232 FROM_HERE,
233 base::Bind(&P2PSocketClientImpl::DeliverOnDataReceived,
234 this,
235 address,
236 data,
237 timestamp));
240 void P2PSocketClientImpl::DeliverOnDataReceived(
241 const net::IPEndPoint& address, const std::vector<char>& data,
242 const base::TimeTicks& timestamp) {
243 DCHECK(delegate_message_loop_->BelongsToCurrentThread());
244 if (delegate_)
245 delegate_->OnDataReceived(address, data, timestamp);
248 void P2PSocketClientImpl::Detach() {
249 DCHECK(ipc_message_loop_->BelongsToCurrentThread());
250 dispatcher_ = NULL;
251 OnError();
254 } // namespace content