11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "remoting/protocol/fake_datagram_socket.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/single_thread_task_runner.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/thread_task_runner_handle.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/address_list.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/io_buffer.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/net_errors.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/net_util.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gtest/include/gtest/gtest.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace remoting { 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace protocol { 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFakeDatagramSocket::FakeDatagramSocket() 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : input_pos_(0), 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_(base::ThreadTaskRunnerHandle::Get()), 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this) { 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFakeDatagramSocket::~FakeDatagramSocket() { 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(task_runner_->BelongsToCurrentThread()); 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FakeDatagramSocket::AppendInputPacket(const std::string& data) { 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(task_runner_->BelongsToCurrentThread()); 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci input_packets_.push_back(data); 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Complete pending read if any. 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!read_callback_.is_null()) { 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(input_pos_, static_cast<int>(input_packets_.size()) - 1); 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int result = CopyReadData(read_buffer_.get(), read_buffer_size_); 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_buffer_ = NULL; 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::CompletionCallback callback = read_callback_; 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_callback_.Reset(); 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(result); 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FakeDatagramSocket::PairWith(FakeDatagramSocket* peer_socket) { 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(task_runner_->BelongsToCurrentThread()); 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci peer_socket_ = peer_socket->GetWeakPtr(); 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci peer_socket->peer_socket_ = GetWeakPtr(); 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::WeakPtr<FakeDatagramSocket> FakeDatagramSocket::GetWeakPtr() { 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return weak_factory_.GetWeakPtr(); 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint FakeDatagramSocket::Read(net::IOBuffer* buf, int buf_len, 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::CompletionCallback& callback) { 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(task_runner_->BelongsToCurrentThread()); 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (input_pos_ < static_cast<int>(input_packets_.size())) { 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return CopyReadData(buf, buf_len); 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_buffer_ = buf; 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_buffer_size_ = buf_len; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_callback_ = callback; 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::ERR_IO_PENDING; 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint FakeDatagramSocket::Write(net::IOBuffer* buf, int buf_len, 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::CompletionCallback& callback) { 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(task_runner_->BelongsToCurrentThread()); 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci written_packets_.push_back(std::string()); 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci written_packets_.back().assign(buf->data(), buf->data() + buf_len); 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (peer_socket_.get()) { 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_->PostTask( 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&FakeDatagramSocket::AppendInputPacket, 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci peer_socket_, 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string(buf->data(), buf->data() + buf_len))); 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return buf_len; 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint FakeDatagramSocket::SetReceiveBufferSize(int32 size) { 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTIMPLEMENTED(); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::ERR_NOT_IMPLEMENTED; 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint FakeDatagramSocket::SetSendBufferSize(int32 size) { 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTIMPLEMENTED(); 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::ERR_NOT_IMPLEMENTED; 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint FakeDatagramSocket::CopyReadData(net::IOBuffer* buf, int buf_len) { 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int size = std::min( 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buf_len, static_cast<int>(input_packets_[input_pos_].size())); 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci memcpy(buf->data(), &(*input_packets_[input_pos_].begin()), size); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++input_pos_; 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return size; 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFakeDatagramChannelFactory::FakeDatagramChannelFactory() 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : task_runner_(base::ThreadTaskRunnerHandle::Get()), 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci asynchronous_create_(false), 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fail_create_(false), 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this) { 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFakeDatagramChannelFactory::~FakeDatagramChannelFactory() { 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (ChannelsMap::iterator it = channels_.begin(); it != channels_.end(); 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++it) { 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(it->second == NULL); 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FakeDatagramChannelFactory::PairWith( 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FakeDatagramChannelFactory* peer_factory) { 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci peer_factory_ = peer_factory->weak_factory_.GetWeakPtr(); 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci peer_factory_->peer_factory_ = weak_factory_.GetWeakPtr(); 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFakeDatagramSocket* FakeDatagramChannelFactory::GetFakeChannel( 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& name) { 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return channels_[name].get(); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FakeDatagramChannelFactory::CreateChannel( 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& name, 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ChannelCreatedCallback& callback) { 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(channels_[name] == NULL); 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<FakeDatagramSocket> channel(new FakeDatagramSocket()); 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channels_[name] = channel->GetWeakPtr(); 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (peer_factory_) { 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FakeDatagramSocket* peer_socket = peer_factory_->GetFakeChannel(name); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (peer_socket) 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channel->PairWith(peer_socket); 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (fail_create_) 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channel.reset(); 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (asynchronous_create_) { 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_->PostTask( 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&FakeDatagramChannelFactory::NotifyChannelCreated, 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_.GetWeakPtr(), base::Passed(&channel), 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci name, callback)); 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyChannelCreated(channel.Pass(), name, callback); 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FakeDatagramChannelFactory::NotifyChannelCreated( 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<FakeDatagramSocket> owned_socket, 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& name, 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ChannelCreatedCallback& callback) { 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (channels_.find(name) != channels_.end()) 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(owned_socket.PassAs<net::Socket>()); 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FakeDatagramChannelFactory::CancelChannelCreation( 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& name) { 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channels_.erase(name); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace protocol 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace remoting 171