OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/test/utility/udp_proxy.h" | 5 #include "media/cast/test/utility/udp_proxy.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/linked_ptr.h" | 8 #include "base/memory/linked_ptr.h" |
9 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
10 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" |
11 #include "base/threading/thread.h" | 11 #include "base/threading/thread.h" |
| 12 #include "base/time/default_tick_clock.h" |
12 #include "net/base/io_buffer.h" | 13 #include "net/base/io_buffer.h" |
13 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
14 #include "net/udp/udp_socket.h" | 15 #include "net/udp/udp_socket.h" |
15 | 16 |
16 namespace media { | 17 namespace media { |
17 namespace cast { | 18 namespace cast { |
18 namespace test { | 19 namespace test { |
19 | 20 |
20 const size_t kMaxPacketSize = 65536; | 21 const size_t kMaxPacketSize = 65536; |
21 | 22 |
22 PacketPipe::PacketPipe() {} | 23 PacketPipe::PacketPipe() {} |
23 PacketPipe::~PacketPipe() {} | 24 PacketPipe::~PacketPipe() {} |
24 void PacketPipe::InitOnIOThread( | 25 void PacketPipe::InitOnIOThread( |
25 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { | 26 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 27 base::TickClock* clock) { |
26 task_runner_ = task_runner; | 28 task_runner_ = task_runner; |
| 29 clock_ = clock; |
27 if (pipe_) { | 30 if (pipe_) { |
28 pipe_->InitOnIOThread(task_runner); | 31 pipe_->InitOnIOThread(task_runner, clock); |
29 } | 32 } |
30 } | 33 } |
31 void PacketPipe::AppendToPipe(scoped_ptr<PacketPipe> pipe) { | 34 void PacketPipe::AppendToPipe(scoped_ptr<PacketPipe> pipe) { |
32 if (pipe_) { | 35 if (pipe_) { |
33 pipe_->AppendToPipe(pipe.Pass()); | 36 pipe_->AppendToPipe(pipe.Pass()); |
34 } else { | 37 } else { |
35 pipe_ = pipe.Pass(); | 38 pipe_ = pipe.Pass(); |
36 } | 39 } |
37 } | 40 } |
38 | 41 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 seconds_between_extra_delay_(seconds_between_extra_delay), | 179 seconds_between_extra_delay_(seconds_between_extra_delay), |
177 weak_factory_(this) {} | 180 weak_factory_(this) {} |
178 | 181 |
179 virtual void Send(scoped_ptr<transport::Packet> packet) OVERRIDE { | 182 virtual void Send(scoped_ptr<transport::Packet> packet) OVERRIDE { |
180 buffer_.push_back(linked_ptr<transport::Packet>(packet.release())); | 183 buffer_.push_back(linked_ptr<transport::Packet>(packet.release())); |
181 if (buffer_.size() == 1) { | 184 if (buffer_.size() == 1) { |
182 Schedule(); | 185 Schedule(); |
183 } | 186 } |
184 } | 187 } |
185 virtual void InitOnIOThread( | 188 virtual void InitOnIOThread( |
186 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) OVERRIDE { | 189 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
187 PacketPipe::InitOnIOThread(task_runner); | 190 base::TickClock* clock) OVERRIDE { |
| 191 PacketPipe::InitOnIOThread(task_runner, clock); |
188 // As we start the stream, assume that we are in a random | 192 // As we start the stream, assume that we are in a random |
189 // place between two extra delays, thus multiplier = 1.0; | 193 // place between two extra delays, thus multiplier = 1.0; |
190 ScheduleExtraDelay(1.0); | 194 ScheduleExtraDelay(1.0); |
191 } | 195 } |
192 | 196 |
193 private: | 197 private: |
194 void ScheduleExtraDelay(double mult) { | 198 void ScheduleExtraDelay(double mult) { |
195 double seconds = seconds_between_extra_delay_ * mult * base::RandDouble(); | 199 double seconds = seconds_between_extra_delay_ * mult * base::RandDouble(); |
196 int64 microseconds = static_cast<int64>(seconds * 1E6); | 200 int64 microseconds = static_cast<int64>(seconds * 1E6); |
197 task_runner_->PostDelayedTask( | 201 task_runner_->PostDelayedTask( |
198 FROM_HERE, | 202 FROM_HERE, |
199 base::Bind(&RandomSortedDelay::CauseExtraDelay, | 203 base::Bind(&RandomSortedDelay::CauseExtraDelay, |
200 weak_factory_.GetWeakPtr()), | 204 weak_factory_.GetWeakPtr()), |
201 base::TimeDelta::FromMicroseconds(microseconds)); | 205 base::TimeDelta::FromMicroseconds(microseconds)); |
202 } | 206 } |
203 | 207 |
204 void CauseExtraDelay() { | 208 void CauseExtraDelay() { |
205 block_until_ = base::TimeTicks::Now() + | 209 block_until_ = clock_->NowTicks() + |
206 base::TimeDelta::FromMicroseconds( | 210 base::TimeDelta::FromMicroseconds( |
207 static_cast<int64>(extra_delay_ * 1E6)); | 211 static_cast<int64>(extra_delay_ * 1E6)); |
208 // An extra delay just happened, wait up to seconds_between_extra_delay_*2 | 212 // An extra delay just happened, wait up to seconds_between_extra_delay_*2 |
209 // before scheduling another one to make the average equal to | 213 // before scheduling another one to make the average equal to |
210 // seconds_between_extra_delay_. | 214 // seconds_between_extra_delay_. |
211 ScheduleExtraDelay(2.0); | 215 ScheduleExtraDelay(2.0); |
212 } | 216 } |
213 | 217 |
214 void Schedule() { | 218 void Schedule() { |
215 double seconds = base::RandDouble() * random_delay_; | 219 double seconds = base::RandDouble() * random_delay_; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 | 261 |
258 class NetworkGlitchPipe : public PacketPipe { | 262 class NetworkGlitchPipe : public PacketPipe { |
259 public: | 263 public: |
260 NetworkGlitchPipe(double average_work_time, double average_outage_time) | 264 NetworkGlitchPipe(double average_work_time, double average_outage_time) |
261 : works_(false), | 265 : works_(false), |
262 max_work_time_(average_work_time * 2), | 266 max_work_time_(average_work_time * 2), |
263 max_outage_time_(average_outage_time * 2), | 267 max_outage_time_(average_outage_time * 2), |
264 weak_factory_(this) {} | 268 weak_factory_(this) {} |
265 | 269 |
266 virtual void InitOnIOThread( | 270 virtual void InitOnIOThread( |
267 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) OVERRIDE { | 271 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
268 PacketPipe::InitOnIOThread(task_runner); | 272 base::TickClock* clock) OVERRIDE { |
| 273 PacketPipe::InitOnIOThread(task_runner, clock); |
269 Flip(); | 274 Flip(); |
270 } | 275 } |
271 | 276 |
272 virtual void Send(scoped_ptr<transport::Packet> packet) OVERRIDE { | 277 virtual void Send(scoped_ptr<transport::Packet> packet) OVERRIDE { |
273 if (works_) { | 278 if (works_) { |
274 pipe_->Send(packet.Pass()); | 279 pipe_->Send(packet.Pass()); |
275 } | 280 } |
276 } | 281 } |
277 | 282 |
278 private: | 283 private: |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 private: | 463 private: |
459 void Start(base::WaitableEvent* start_event, | 464 void Start(base::WaitableEvent* start_event, |
460 net::NetLog* net_log) { | 465 net::NetLog* net_log) { |
461 socket_.reset(new net::UDPSocket(net::DatagramSocket::DEFAULT_BIND, | 466 socket_.reset(new net::UDPSocket(net::DatagramSocket::DEFAULT_BIND, |
462 net::RandIntCallback(), | 467 net::RandIntCallback(), |
463 net_log, | 468 net_log, |
464 net::NetLog::Source())); | 469 net::NetLog::Source())); |
465 BuildPipe(&to_dest_pipe_, new PacketSender(socket_.get(), &destination_)); | 470 BuildPipe(&to_dest_pipe_, new PacketSender(socket_.get(), &destination_)); |
466 BuildPipe(&from_dest_pipe_, | 471 BuildPipe(&from_dest_pipe_, |
467 new PacketSender(socket_.get(), &return_address_)); | 472 new PacketSender(socket_.get(), &return_address_)); |
468 to_dest_pipe_->InitOnIOThread(base::MessageLoopProxy::current()); | 473 to_dest_pipe_->InitOnIOThread(base::MessageLoopProxy::current(), |
469 from_dest_pipe_->InitOnIOThread(base::MessageLoopProxy::current()); | 474 &tick_clock_); |
| 475 from_dest_pipe_->InitOnIOThread(base::MessageLoopProxy::current(), |
| 476 &tick_clock_); |
470 | 477 |
471 VLOG(0) << "From:" << local_port_.ToString(); | 478 VLOG(0) << "From:" << local_port_.ToString(); |
472 VLOG(0) << "To:" << destination_.ToString(); | 479 VLOG(0) << "To:" << destination_.ToString(); |
473 | 480 |
474 CHECK_GE(socket_->Bind(local_port_), 0); | 481 CHECK_GE(socket_->Bind(local_port_), 0); |
475 | 482 |
476 start_event->Signal(); | 483 start_event->Signal(); |
477 PollRead(); | 484 PollRead(); |
478 } | 485 } |
479 | 486 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 base::Bind(&UDPProxyImpl::ReadCallback, | 525 base::Bind(&UDPProxyImpl::ReadCallback, |
519 base::Unretained(this), | 526 base::Unretained(this), |
520 recv_buf)); | 527 recv_buf)); |
521 if (len == net::ERR_IO_PENDING) | 528 if (len == net::ERR_IO_PENDING) |
522 break; | 529 break; |
523 ProcessPacket(recv_buf, len); | 530 ProcessPacket(recv_buf, len); |
524 } | 531 } |
525 } | 532 } |
526 | 533 |
527 | 534 |
| 535 base::DefaultTickClock tick_clock_; |
528 net::IPEndPoint local_port_; | 536 net::IPEndPoint local_port_; |
529 net::IPEndPoint destination_; | 537 net::IPEndPoint destination_; |
530 net::IPEndPoint recv_address_; | 538 net::IPEndPoint recv_address_; |
531 net::IPEndPoint return_address_; | 539 net::IPEndPoint return_address_; |
532 base::Thread proxy_thread_; | 540 base::Thread proxy_thread_; |
533 scoped_ptr<net::UDPSocket> socket_; | 541 scoped_ptr<net::UDPSocket> socket_; |
534 scoped_ptr<PacketPipe> to_dest_pipe_; | 542 scoped_ptr<PacketPipe> to_dest_pipe_; |
535 scoped_ptr<PacketPipe> from_dest_pipe_; | 543 scoped_ptr<PacketPipe> from_dest_pipe_; |
536 scoped_ptr<transport::Packet> packet_; | 544 scoped_ptr<transport::Packet> packet_; |
537 }; | 545 }; |
538 | 546 |
539 scoped_ptr<UDPProxy> UDPProxy::Create( | 547 scoped_ptr<UDPProxy> UDPProxy::Create( |
540 const net::IPEndPoint& local_port, | 548 const net::IPEndPoint& local_port, |
541 const net::IPEndPoint& destination, | 549 const net::IPEndPoint& destination, |
542 scoped_ptr<PacketPipe> to_dest_pipe, | 550 scoped_ptr<PacketPipe> to_dest_pipe, |
543 scoped_ptr<PacketPipe> from_dest_pipe, | 551 scoped_ptr<PacketPipe> from_dest_pipe, |
544 net::NetLog* net_log) { | 552 net::NetLog* net_log) { |
545 scoped_ptr<UDPProxy> ret(new UDPProxyImpl(local_port, | 553 scoped_ptr<UDPProxy> ret(new UDPProxyImpl(local_port, |
546 destination, | 554 destination, |
547 to_dest_pipe.Pass(), | 555 to_dest_pipe.Pass(), |
548 from_dest_pipe.Pass(), | 556 from_dest_pipe.Pass(), |
549 net_log)); | 557 net_log)); |
550 return ret.Pass(); | 558 return ret.Pass(); |
551 } | 559 } |
552 | 560 |
553 } // namespace test | 561 } // namespace test |
554 } // namespace cast | 562 } // namespace cast |
555 } // namespace media | 563 } // namespace media |
OLD | NEW |