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 "remoting/protocol/fake_session.h" 6 7 #include "base/bind.h" 8 #include "base/message_loop/message_loop.h" 9 #include "net/base/address_list.h" 10 #include "net/base/io_buffer.h" 11 #include "net/base/net_errors.h" 12 #include "net/base/net_util.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 namespace remoting { 16 namespace protocol { 17 18 const char kTestJid[] = "host1 (at) gmail.com/chromoting123"; 19 20 FakeSocket::FakeSocket() 21 : async_write_(false), 22 write_pending_(false), 23 write_limit_(0), 24 next_write_error_(net::OK), 25 next_read_error_(net::OK), 26 read_pending_(false), 27 read_buffer_size_(0), 28 input_pos_(0), 29 message_loop_(base::MessageLoop::current()), 30 weak_factory_(this) { 31 } 32 33 FakeSocket::~FakeSocket() { 34 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 35 } 36 37 void FakeSocket::AppendInputData(const std::vector<char>& data) { 38 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 39 input_data_.insert(input_data_.end(), data.begin(), data.end()); 40 // Complete pending read if any. 41 if (read_pending_) { 42 read_pending_ = false; 43 int result = std::min(read_buffer_size_, 44 static_cast<int>(input_data_.size() - input_pos_)); 45 CHECK(result > 0); 46 memcpy(read_buffer_->data(), 47 &(*input_data_.begin()) + input_pos_, result); 48 input_pos_ += result; 49 read_buffer_ = NULL; 50 read_callback_.Run(result); 51 } 52 } 53 54 void FakeSocket::PairWith(FakeSocket* peer_socket) { 55 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 56 peer_socket_ = peer_socket->weak_factory_.GetWeakPtr(); 57 peer_socket->peer_socket_ = weak_factory_.GetWeakPtr(); 58 } 59 60 int FakeSocket::Read(net::IOBuffer* buf, int buf_len, 61 const net::CompletionCallback& callback) { 62 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 63 64 if (next_read_error_ != net::OK) { 65 int r = next_read_error_; 66 next_read_error_ = net::OK; 67 return r; 68 } 69 70 if (input_pos_ < static_cast<int>(input_data_.size())) { 71 int result = std::min(buf_len, 72 static_cast<int>(input_data_.size()) - input_pos_); 73 memcpy(buf->data(), &(*input_data_.begin()) + input_pos_, result); 74 input_pos_ += result; 75 return result; 76 } else { 77 read_pending_ = true; 78 read_buffer_ = buf; 79 read_buffer_size_ = buf_len; 80 read_callback_ = callback; 81 return net::ERR_IO_PENDING; 82 } 83 } 84 85 int FakeSocket::Write(net::IOBuffer* buf, int buf_len, 86 const net::CompletionCallback& callback) { 87 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 88 EXPECT_FALSE(write_pending_); 89 90 if (write_limit_ > 0) 91 buf_len = std::min(write_limit_, buf_len); 92 93 if (async_write_) { 94 message_loop_->PostTask(FROM_HERE, base::Bind( 95 &FakeSocket::DoAsyncWrite, weak_factory_.GetWeakPtr(), 96 scoped_refptr<net::IOBuffer>(buf), buf_len, callback)); 97 write_pending_ = true; 98 return net::ERR_IO_PENDING; 99 } else { 100 if (next_write_error_ != net::OK) { 101 int r = next_write_error_; 102 next_write_error_ = net::OK; 103 return r; 104 } 105 106 DoWrite(buf, buf_len); 107 return buf_len; 108 } 109 } 110 111 void FakeSocket::DoAsyncWrite(scoped_refptr<net::IOBuffer> buf, int buf_len, 112 const net::CompletionCallback& callback) { 113 write_pending_ = false; 114 115 if (next_write_error_ != net::OK) { 116 int r = next_write_error_; 117 next_write_error_ = net::OK; 118 callback.Run(r); 119 return; 120 } 121 122 DoWrite(buf.get(), buf_len); 123 callback.Run(buf_len); 124 } 125 126 void FakeSocket::DoWrite(net::IOBuffer* buf, int buf_len) { 127 written_data_.insert(written_data_.end(), 128 buf->data(), buf->data() + buf_len); 129 130 if (peer_socket_.get()) { 131 message_loop_->PostTask( 132 FROM_HERE, 133 base::Bind(&FakeSocket::AppendInputData, 134 peer_socket_, 135 std::vector<char>(buf->data(), buf->data() + buf_len))); 136 } 137 } 138 139 bool FakeSocket::SetReceiveBufferSize(int32 size) { 140 NOTIMPLEMENTED(); 141 return false; 142 } 143 bool FakeSocket::SetSendBufferSize(int32 size) { 144 NOTIMPLEMENTED(); 145 return false; 146 } 147 148 int FakeSocket::Connect(const net::CompletionCallback& callback) { 149 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 150 return net::OK; 151 } 152 153 void FakeSocket::Disconnect() { 154 peer_socket_.reset(); 155 } 156 157 bool FakeSocket::IsConnected() const { 158 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 159 return true; 160 } 161 162 bool FakeSocket::IsConnectedAndIdle() const { 163 NOTIMPLEMENTED(); 164 return false; 165 } 166 167 int FakeSocket::GetPeerAddress(net::IPEndPoint* address) const { 168 net::IPAddressNumber ip(net::kIPv4AddressSize); 169 *address = net::IPEndPoint(ip, 0); 170 return net::OK; 171 } 172 173 int FakeSocket::GetLocalAddress(net::IPEndPoint* address) const { 174 NOTIMPLEMENTED(); 175 return net::ERR_FAILED; 176 } 177 178 const net::BoundNetLog& FakeSocket::NetLog() const { 179 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 180 return net_log_; 181 } 182 183 void FakeSocket::SetSubresourceSpeculation() { 184 NOTIMPLEMENTED(); 185 } 186 187 void FakeSocket::SetOmniboxSpeculation() { 188 NOTIMPLEMENTED(); 189 } 190 191 bool FakeSocket::WasEverUsed() const { 192 NOTIMPLEMENTED(); 193 return true; 194 } 195 196 bool FakeSocket::UsingTCPFastOpen() const { 197 NOTIMPLEMENTED(); 198 return true; 199 } 200 201 bool FakeSocket::WasNpnNegotiated() const { 202 return false; 203 } 204 205 net::NextProto FakeSocket::GetNegotiatedProtocol() const { 206 NOTIMPLEMENTED(); 207 return net::kProtoUnknown; 208 } 209 210 bool FakeSocket::GetSSLInfo(net::SSLInfo* ssl_info) { 211 return false; 212 } 213 214 FakeUdpSocket::FakeUdpSocket() 215 : read_pending_(false), 216 input_pos_(0), 217 message_loop_(base::MessageLoop::current()) { 218 } 219 220 FakeUdpSocket::~FakeUdpSocket() { 221 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 222 } 223 224 void FakeUdpSocket::AppendInputPacket(const char* data, int data_size) { 225 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 226 input_packets_.push_back(std::string()); 227 input_packets_.back().assign(data, data + data_size); 228 229 // Complete pending read if any. 230 if (read_pending_) { 231 read_pending_ = false; 232 int result = std::min(data_size, read_buffer_size_); 233 memcpy(read_buffer_->data(), data, result); 234 input_pos_ = input_packets_.size(); 235 read_callback_.Run(result); 236 read_buffer_ = NULL; 237 } 238 } 239 240 int FakeUdpSocket::Read(net::IOBuffer* buf, int buf_len, 241 const net::CompletionCallback& callback) { 242 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 243 if (input_pos_ < static_cast<int>(input_packets_.size())) { 244 int result = std::min( 245 buf_len, static_cast<int>(input_packets_[input_pos_].size())); 246 memcpy(buf->data(), &(*input_packets_[input_pos_].begin()), result); 247 ++input_pos_; 248 return result; 249 } else { 250 read_pending_ = true; 251 read_buffer_ = buf; 252 read_buffer_size_ = buf_len; 253 read_callback_ = callback; 254 return net::ERR_IO_PENDING; 255 } 256 } 257 258 int FakeUdpSocket::Write(net::IOBuffer* buf, int buf_len, 259 const net::CompletionCallback& callback) { 260 EXPECT_EQ(message_loop_, base::MessageLoop::current()); 261 written_packets_.push_back(std::string()); 262 written_packets_.back().assign(buf->data(), buf->data() + buf_len); 263 return buf_len; 264 } 265 266 bool FakeUdpSocket::SetReceiveBufferSize(int32 size) { 267 NOTIMPLEMENTED(); 268 return false; 269 } 270 bool FakeUdpSocket::SetSendBufferSize(int32 size) { 271 NOTIMPLEMENTED(); 272 return false; 273 } 274 275 FakeSession::FakeSession() 276 : event_handler_(NULL), 277 candidate_config_(CandidateSessionConfig::CreateDefault()), 278 config_(SessionConfig::ForTest()), 279 message_loop_(base::MessageLoop::current()), 280 async_creation_(false), 281 jid_(kTestJid), 282 error_(OK), 283 closed_(false), 284 weak_factory_(this) { 285 } 286 287 FakeSession::~FakeSession() { } 288 289 FakeSocket* FakeSession::GetStreamChannel(const std::string& name) { 290 return stream_channels_[name]; 291 } 292 293 FakeUdpSocket* FakeSession::GetDatagramChannel(const std::string& name) { 294 return datagram_channels_[name]; 295 } 296 297 void FakeSession::SetEventHandler(EventHandler* event_handler) { 298 event_handler_ = event_handler; 299 } 300 301 ErrorCode FakeSession::error() { 302 return error_; 303 } 304 305 const std::string& FakeSession::jid() { 306 return jid_; 307 } 308 309 const CandidateSessionConfig* FakeSession::candidate_config() { 310 return candidate_config_.get(); 311 } 312 313 const SessionConfig& FakeSession::config() { 314 return config_; 315 } 316 317 void FakeSession::set_config(const SessionConfig& config) { 318 config_ = config; 319 } 320 321 ChannelFactory* FakeSession::GetTransportChannelFactory() { 322 return this; 323 } 324 325 ChannelFactory* FakeSession::GetMultiplexedChannelFactory() { 326 return this; 327 } 328 329 void FakeSession::Close() { 330 closed_ = true; 331 } 332 333 void FakeSession::CreateStreamChannel( 334 const std::string& name, 335 const StreamChannelCallback& callback) { 336 scoped_ptr<FakeSocket> channel; 337 // If we are in the error state then we put NULL in the channels list, so that 338 // NotifyStreamChannelCallback() still calls the callback. 339 if (error_ == OK) 340 channel.reset(new FakeSocket()); 341 stream_channels_[name] = channel.release(); 342 343 if (async_creation_) { 344 message_loop_->PostTask(FROM_HERE, base::Bind( 345 &FakeSession::NotifyStreamChannelCallback, weak_factory_.GetWeakPtr(), 346 name, callback)); 347 } else { 348 NotifyStreamChannelCallback(name, callback); 349 } 350 } 351 352 void FakeSession::NotifyStreamChannelCallback( 353 const std::string& name, 354 const StreamChannelCallback& callback) { 355 if (stream_channels_.find(name) != stream_channels_.end()) 356 callback.Run(scoped_ptr<net::StreamSocket>(stream_channels_[name])); 357 } 358 359 void FakeSession::CreateDatagramChannel( 360 const std::string& name, 361 const DatagramChannelCallback& callback) { 362 scoped_ptr<FakeUdpSocket> channel; 363 // If we are in the error state then we put NULL in the channels list, so that 364 // NotifyStreamChannelCallback() still calls the callback. 365 if (error_ == OK) 366 channel.reset(new FakeUdpSocket()); 367 datagram_channels_[name] = channel.release(); 368 369 if (async_creation_) { 370 message_loop_->PostTask(FROM_HERE, base::Bind( 371 &FakeSession::NotifyDatagramChannelCallback, weak_factory_.GetWeakPtr(), 372 name, callback)); 373 } else { 374 NotifyDatagramChannelCallback(name, callback); 375 } 376 } 377 378 void FakeSession::NotifyDatagramChannelCallback( 379 const std::string& name, 380 const DatagramChannelCallback& callback) { 381 if (datagram_channels_.find(name) != datagram_channels_.end()) 382 callback.Run(scoped_ptr<net::Socket>(datagram_channels_[name])); 383 } 384 385 void FakeSession::CancelChannelCreation(const std::string& name) { 386 stream_channels_.erase(name); 387 datagram_channels_.erase(name); 388 } 389 390 } // namespace protocol 391 } // namespace remoting 392