MD Downloads: center "Open downloads folder" when there's no downloads
[chromium-blink-merge.git] / remoting / protocol / fake_datagram_socket.cc
blob010cb36b186725b08c1e5c5e319e5a6129e5a2f4
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"
7 #include "base/bind.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"
17 namespace remoting {
18 namespace protocol {
20 FakeDatagramSocket::FakeDatagramSocket()
21 : input_pos_(0),
22 task_runner_(base::ThreadTaskRunnerHandle::Get()),
23 weak_factory_(this) {
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,
55 int buf_len,
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);
60 } else {
61 read_buffer_ = buf;
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,
69 int buf_len,
70 const net::CompletionCallback& callback) {
71 EXPECT_TRUE(task_runner_->BelongsToCurrentThread());
72 EXPECT_FALSE(send_pending_);
74 if (async_send_) {
75 send_pending_ = true;
76 task_runner_->PostTask(
77 FROM_HERE,
78 base::Bind(&FakeDatagramSocket::DoAsyncSend, weak_factory_.GetWeakPtr(),
79 buf, buf_len, callback));
80 return net::ERR_IO_PENDING;
81 } else {
82 return DoSend(buf, buf_len);
86 void FakeDatagramSocket::DoAsyncSend(const scoped_refptr<net::IOBuffer>& buf,
87 int buf_len,
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,
97 int buf_len) {
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;
103 return r;
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(
111 FROM_HERE,
112 base::Bind(&FakeDatagramSocket::AppendInputPacket, peer_socket_,
113 std::string(buf->data(), buf->data() + buf_len)));
116 return buf_len;
119 int FakeDatagramSocket::CopyReadData(const scoped_refptr<net::IOBuffer>& buf,
120 int buf_len) {
121 int size = std::min(
122 buf_len, static_cast<int>(input_packets_[input_pos_].size()));
123 memcpy(buf->data(), &(*input_packets_[input_pos_].begin()), size);
124 ++input_pos_;
125 return size;
128 FakeDatagramChannelFactory::FakeDatagramChannelFactory()
129 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
130 asynchronous_create_(false),
131 fail_create_(false),
132 weak_factory_(this) {
135 FakeDatagramChannelFactory::~FakeDatagramChannelFactory() {
136 for (ChannelsMap::iterator it = channels_.begin(); it != channels_.end();
137 ++it) {
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();
161 if (peer_factory_) {
162 FakeDatagramSocket* peer_socket = peer_factory_->GetFakeChannel(name);
163 if (peer_socket)
164 channel->PairWith(peer_socket);
167 if (fail_create_)
168 channel.reset();
170 if (asynchronous_create_) {
171 task_runner_->PostTask(
172 FROM_HERE,
173 base::Bind(&FakeDatagramChannelFactory::NotifyChannelCreated,
174 weak_factory_.GetWeakPtr(), base::Passed(&channel),
175 name, callback));
176 } else {
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