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