1 // Copyright 2014 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 "remoting/protocol/fake_datagram_socket.h"
8 #include "base/callback_helpers.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "net/base/address_list.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h"
14 #include "net/base/net_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
20 FakeDatagramSocket::FakeDatagramSocket()
22 task_runner_(base::ThreadTaskRunnerHandle::Get()),
26 FakeDatagramSocket::~FakeDatagramSocket() {
27 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
30 void FakeDatagramSocket::AppendInputPacket(const std::string
& data
) {
31 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
32 input_packets_
.push_back(data
);
34 // Complete pending read if any.
35 if (!read_callback_
.is_null()) {
36 DCHECK_EQ(input_pos_
, static_cast<int>(input_packets_
.size()) - 1);
37 int result
= CopyReadData(read_buffer_
.get(), read_buffer_size_
);
38 read_buffer_
= nullptr;
40 base::ResetAndReturn(&read_callback_
).Run(result
);
44 void FakeDatagramSocket::PairWith(FakeDatagramSocket
* peer_socket
) {
45 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
46 peer_socket_
= peer_socket
->GetWeakPtr();
47 peer_socket
->peer_socket_
= GetWeakPtr();
50 base::WeakPtr
<FakeDatagramSocket
> FakeDatagramSocket::GetWeakPtr() {
51 return weak_factory_
.GetWeakPtr();
54 int FakeDatagramSocket::Recv(const scoped_refptr
<net::IOBuffer
>& buf
,
56 const net::CompletionCallback
& callback
) {
57 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
58 if (input_pos_
< static_cast<int>(input_packets_
.size())) {
59 return CopyReadData(buf
, buf_len
);
62 read_buffer_size_
= buf_len
;
63 read_callback_
= callback
;
64 return net::ERR_IO_PENDING
;
68 int FakeDatagramSocket::Send(const scoped_refptr
<net::IOBuffer
>& buf
,
70 const net::CompletionCallback
& callback
) {
71 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
72 EXPECT_FALSE(send_pending_
);
76 task_runner_
->PostTask(
78 base::Bind(&FakeDatagramSocket::DoAsyncSend
, weak_factory_
.GetWeakPtr(),
79 buf
, buf_len
, callback
));
80 return net::ERR_IO_PENDING
;
82 return DoSend(buf
, buf_len
);
86 void FakeDatagramSocket::DoAsyncSend(const scoped_refptr
<net::IOBuffer
>& buf
,
88 const net::CompletionCallback
& callback
) {
89 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
91 EXPECT_TRUE(send_pending_
);
92 send_pending_
= false;
93 callback
.Run(DoSend(buf
, buf_len
));
96 int FakeDatagramSocket::DoSend(const scoped_refptr
<net::IOBuffer
>& buf
,
98 EXPECT_TRUE(task_runner_
->BelongsToCurrentThread());
100 if (next_send_error_
!= net::OK
) {
101 int r
= next_send_error_
;
102 next_send_error_
= net::OK
;
106 written_packets_
.push_back(std::string());
107 written_packets_
.back().assign(buf
->data(), buf
->data() + buf_len
);
109 if (peer_socket_
.get()) {
110 task_runner_
->PostTask(
112 base::Bind(&FakeDatagramSocket::AppendInputPacket
, peer_socket_
,
113 std::string(buf
->data(), buf
->data() + buf_len
)));
119 int FakeDatagramSocket::CopyReadData(const scoped_refptr
<net::IOBuffer
>& buf
,
122 buf_len
, static_cast<int>(input_packets_
[input_pos_
].size()));
123 memcpy(buf
->data(), &(*input_packets_
[input_pos_
].begin()), size
);
128 FakeDatagramChannelFactory::FakeDatagramChannelFactory()
129 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
130 asynchronous_create_(false),
132 weak_factory_(this) {
135 FakeDatagramChannelFactory::~FakeDatagramChannelFactory() {
136 for (ChannelsMap::iterator it
= channels_
.begin(); it
!= channels_
.end();
138 EXPECT_TRUE(it
->second
== nullptr);
142 void FakeDatagramChannelFactory::PairWith(
143 FakeDatagramChannelFactory
* peer_factory
) {
144 peer_factory_
= peer_factory
->weak_factory_
.GetWeakPtr();
145 peer_factory_
->peer_factory_
= weak_factory_
.GetWeakPtr();
148 FakeDatagramSocket
* FakeDatagramChannelFactory::GetFakeChannel(
149 const std::string
& name
) {
150 return channels_
[name
].get();
153 void FakeDatagramChannelFactory::CreateChannel(
154 const std::string
& name
,
155 const ChannelCreatedCallback
& callback
) {
156 EXPECT_TRUE(channels_
[name
] == nullptr);
158 scoped_ptr
<FakeDatagramSocket
> channel(new FakeDatagramSocket());
159 channels_
[name
] = channel
->GetWeakPtr();
162 FakeDatagramSocket
* peer_socket
= peer_factory_
->GetFakeChannel(name
);
164 channel
->PairWith(peer_socket
);
170 if (asynchronous_create_
) {
171 task_runner_
->PostTask(
173 base::Bind(&FakeDatagramChannelFactory::NotifyChannelCreated
,
174 weak_factory_
.GetWeakPtr(), base::Passed(&channel
),
177 NotifyChannelCreated(channel
.Pass(), name
, callback
);
181 void FakeDatagramChannelFactory::NotifyChannelCreated(
182 scoped_ptr
<FakeDatagramSocket
> owned_socket
,
183 const std::string
& name
,
184 const ChannelCreatedCallback
& callback
) {
185 if (channels_
.find(name
) != channels_
.end())
186 callback
.Run(owned_socket
.Pass());
189 void FakeDatagramChannelFactory::CancelChannelCreation(
190 const std::string
& name
) {
191 channels_
.erase(name
);
194 } // namespace protocol
195 } // namespace remoting