1 // Copyright 2016 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 "components/mirroring/browser/cast_remoting_sender.h"
6 
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h"
10 #include "base/macros.h"
11 #include "base/run_loop.h"
12 #include "base/time/default_tick_clock.h"
13 #include "content/public/test/browser_task_environment.h"
14 #include "media/cast/constants.h"
15 #include "media/cast/net/cast_transport.h"
16 #include "media/cast/test/utility/default_config.h"
17 #include "media/mojo/mojom/remoting.mojom.h"
18 #include "mojo/public/cpp/bindings/remote.h"
19 #include "mojo/public/cpp/system/data_pipe.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 
22 namespace mirroring {
23 
24 namespace {
25 
26 // Data pipe capacity is 1KB.
27 constexpr int kDataPipeCapacity = 1024;
28 
29 // Implements the CastTransport interface to capture output from the
30 // CastRemotingSender.
31 class FakeTransport : public media::cast::CastTransport {
32  public:
FakeTransport()33   FakeTransport() {}
~FakeTransport()34   ~FakeTransport() final {}
35 
TakeSentFrames(std::vector<media::cast::EncodedFrame> * frames)36   void TakeSentFrames(std::vector<media::cast::EncodedFrame>* frames) {
37     frames->swap(sent_frames_);
38     sent_frames_.clear();
39   }
40 
TakeCanceledFrameIds(std::vector<media::cast::FrameId> * frame_ids)41   void TakeCanceledFrameIds(std::vector<media::cast::FrameId>* frame_ids) {
42     frame_ids->swap(canceled_frame_ids_);
43     canceled_frame_ids_.clear();
44   }
45 
WaitForKickstart()46   media::cast::FrameId WaitForKickstart() {
47     base::RunLoop run_loop;
48     kickstarted_callback_ = run_loop.QuitClosure();
49     run_loop.Run();
50     return kickstarted_frame_id_;
51   }
52 
53  protected:
InsertFrame(uint32_t ssrc,const media::cast::EncodedFrame & frame)54   void InsertFrame(uint32_t ssrc,
55                    const media::cast::EncodedFrame& frame) final {
56     sent_frames_.push_back(frame);
57   }
58 
CancelSendingFrames(uint32_t ssrc,const std::vector<media::cast::FrameId> & frame_ids)59   void CancelSendingFrames(
60       uint32_t ssrc,
61       const std::vector<media::cast::FrameId>& frame_ids) final {
62     for (media::cast::FrameId frame_id : frame_ids)
63       canceled_frame_ids_.push_back(frame_id);
64   }
65 
ResendFrameForKickstart(uint32_t ssrc,media::cast::FrameId frame_id)66   void ResendFrameForKickstart(uint32_t ssrc,
67                                media::cast::FrameId frame_id) final {
68     kickstarted_frame_id_ = frame_id;
69     if (!kickstarted_callback_.is_null())
70       std::move(kickstarted_callback_).Run();
71   }
72 
73   // The rest of the interface is not used for these tests.
SendSenderReport(uint32_t ssrc,base::TimeTicks current_time,media::cast::RtpTimeTicks current_time_as_rtp_timestamp)74   void SendSenderReport(
75       uint32_t ssrc,
76       base::TimeTicks current_time,
77       media::cast::RtpTimeTicks current_time_as_rtp_timestamp) final {}
AddValidRtpReceiver(uint32_t rtp_sender_ssrc,uint32_t rtp_receiver_ssrc)78   void AddValidRtpReceiver(uint32_t rtp_sender_ssrc,
79                            uint32_t rtp_receiver_ssrc) final {}
InitializeRtpReceiverRtcpBuilder(uint32_t rtp_receiver_ssrc,const media::cast::RtcpTimeData & time_data)80   void InitializeRtpReceiverRtcpBuilder(
81       uint32_t rtp_receiver_ssrc,
82       const media::cast::RtcpTimeData& time_data) final {}
AddCastFeedback(const media::cast::RtcpCastMessage & cast_message,base::TimeDelta target_delay)83   void AddCastFeedback(const media::cast::RtcpCastMessage& cast_message,
84                        base::TimeDelta target_delay) final {}
AddPli(const media::cast::RtcpPliMessage & pli_message)85   void AddPli(const media::cast::RtcpPliMessage& pli_message) final {}
AddRtcpEvents(const media::cast::ReceiverRtcpEventSubscriber::RtcpEvents & e)86   void AddRtcpEvents(
87       const media::cast::ReceiverRtcpEventSubscriber::RtcpEvents& e) final {}
AddRtpReceiverReport(const media::cast::RtcpReportBlock & b)88   void AddRtpReceiverReport(const media::cast::RtcpReportBlock& b) final {}
SendRtcpFromRtpReceiver()89   void SendRtcpFromRtpReceiver() final {}
SetOptions(const base::DictionaryValue & options)90   void SetOptions(const base::DictionaryValue& options) final {}
91 
92  private:
93   std::vector<media::cast::EncodedFrame> sent_frames_;
94   std::vector<media::cast::FrameId> canceled_frame_ids_;
95 
96   base::RepeatingClosure kickstarted_callback_;
97   media::cast::FrameId kickstarted_frame_id_;
98 
99   DISALLOW_COPY_AND_ASSIGN(FakeTransport);
100 };
101 
102 }  // namespace
103 
104 class CastRemotingSenderTest : public ::testing::Test {
105  protected:
CastRemotingSenderTest()106   CastRemotingSenderTest()
107       : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP),
108         expecting_error_callback_run_(false) {
109     media::cast::FrameSenderConfig video_config =
110         media::cast::GetDefaultVideoSenderConfig();
111     video_config.rtp_payload_type = media::cast::RtpPayloadType::REMOTE_VIDEO;
112     transport_config_.ssrc = video_config.sender_ssrc;
113     transport_config_.rtp_stream_id = 5;
114     transport_config_.feedback_ssrc = video_config.receiver_ssrc;
115     transport_config_.rtp_payload_type = video_config.rtp_payload_type;
116     transport_config_.aes_key = video_config.aes_key;
117     transport_config_.aes_iv_mask = video_config.aes_iv_mask;
118     remoting_sender_.reset(new CastRemotingSender(
119         &transport_, transport_config_, base::TimeDelta::FromMilliseconds(1),
120         base::BindRepeating(&CastRemotingSenderTest::ReceivedLoggingEvents,
121                             base::Unretained(this))));
122     // Give CastRemotingSender a small RTT measurement to prevent kickstart
123     // testing from taking too long.
124     remoting_sender_->OnReceivedRtt(base::TimeDelta::FromMilliseconds(1));
125 
126     const MojoCreateDataPipeOptions data_pipe_options{
127         sizeof(MojoCreateDataPipeOptions), MOJO_CREATE_DATA_PIPE_FLAG_NONE, 1,
128         kDataPipeCapacity};
129     mojo::ScopedDataPipeConsumerHandle consumer_end;
130     CHECK_EQ(MOJO_RESULT_OK,
131              mojo::CreateDataPipe(&data_pipe_options, &producer_end_,
132                                   &consumer_end));
133 
134     CastRemotingSender::FindAndBind(
135         transport_config_.rtp_stream_id, std::move(consumer_end),
136         sender_.BindNewPipeAndPassReceiver(),
137         base::BindOnce(&CastRemotingSenderTest::OnError,
138                        base::Unretained(this)));
139 
140     RunPendingTasks();
141   }
142 
~CastRemotingSenderTest()143   ~CastRemotingSenderTest() override {}
144 
TearDown()145   void TearDown() final {
146     remoting_sender_.reset();
147     // Allow any pending tasks to run before destruction.
148     RunPendingTasks();
149   }
150 
151   // Allow pending tasks, such as Mojo method calls, to execute.
RunPendingTasks()152   static void RunPendingTasks() { base::RunLoop().RunUntilIdle(); }
153 
154  protected:
latest_acked_frame_id() const155   media::cast::FrameId latest_acked_frame_id() const {
156     return remoting_sender_->latest_acked_frame_id_;
157   }
158 
NumberOfFramesInFlight()159   int NumberOfFramesInFlight() {
160     return remoting_sender_->NumberOfFramesInFlight();
161   }
162 
GetSizeOfNextFrameData()163   size_t GetSizeOfNextFrameData() {
164     return remoting_sender_->next_frame_data_.size();
165   }
166 
IsFlowRestartPending() const167   bool IsFlowRestartPending() const {
168     return remoting_sender_->flow_restart_pending_;
169   }
170 
ProduceDataChunk(size_t offset,size_t size)171   bool ProduceDataChunk(size_t offset, size_t size) WARN_UNUSED_RESULT {
172     std::vector<uint8_t> fake_chunk(size);
173     for (size_t i = 0; i < size; ++i)
174       fake_chunk[i] = static_cast<uint8_t>(offset + i);
175     uint32_t num_bytes = fake_chunk.size();
176     return producer_end_->WriteData(fake_chunk.data(), &num_bytes,
177                                     MOJO_WRITE_DATA_FLAG_ALL_OR_NONE) ==
178            MOJO_RESULT_OK;
179   }
180 
SendFrame(uint32_t size)181   void SendFrame(uint32_t size) { remoting_sender_->SendFrame(size); }
182 
CancelInFlightData()183   void CancelInFlightData() { remoting_sender_->CancelInFlightData(); }
184 
TakeSentFrames(std::vector<media::cast::EncodedFrame> * frames)185   void TakeSentFrames(std::vector<media::cast::EncodedFrame>* frames) {
186     transport_.TakeSentFrames(frames);
187   }
188 
ExpectOneFrameWasSent(size_t expected_payload_size)189   bool ExpectOneFrameWasSent(size_t expected_payload_size) {
190     std::vector<media::cast::EncodedFrame> frames;
191     transport_.TakeSentFrames(&frames);
192     EXPECT_EQ(1u, frames.size());
193     if (frames.empty())
194       return false;
195     return ExpectCorrectFrameData(expected_payload_size, frames.front());
196   }
197 
AckUpToAndIncluding(media::cast::FrameId frame_id)198   void AckUpToAndIncluding(media::cast::FrameId frame_id) {
199     media::cast::RtcpCastMessage cast_feedback(transport_config_.feedback_ssrc);
200     cast_feedback.ack_frame_id = frame_id;
201     remoting_sender_->OnReceivedCastMessage(cast_feedback);
202   }
203 
AckOldestInFlightFrames(int count)204   void AckOldestInFlightFrames(int count) {
205     AckUpToAndIncluding(latest_acked_frame_id() + count);
206   }
207 
208   // Blocks the caller indefinitely, until a kickstart frame is sent, and then
209   // returns the FrameId of the kickstarted-frame.
WaitForKickstart()210   media::cast::FrameId WaitForKickstart() {
211     return transport_.WaitForKickstart();
212   }
213 
ExpectNoFramesCanceled()214   bool ExpectNoFramesCanceled() {
215     std::vector<media::cast::FrameId> frame_ids;
216     transport_.TakeCanceledFrameIds(&frame_ids);
217     return frame_ids.empty();
218   }
219 
ExpectFramesCanceled(media::cast::FrameId first_frame_id,media::cast::FrameId last_frame_id)220   bool ExpectFramesCanceled(media::cast::FrameId first_frame_id,
221                             media::cast::FrameId last_frame_id) {
222     std::vector<media::cast::FrameId> frame_ids;
223     transport_.TakeCanceledFrameIds(&frame_ids);
224     auto begin = frame_ids.begin();
225     auto end = frame_ids.end();
226     for (auto fid = first_frame_id; fid <= last_frame_id; ++fid) {
227       auto new_end = std::remove(begin, end, fid);
228       if (new_end == end)
229         return false;
230       end = new_end;
231     }
232     return begin == end;
233   }
234 
ExpectCorrectFrameData(size_t expected_payload_size,const media::cast::EncodedFrame & frame)235   static bool ExpectCorrectFrameData(size_t expected_payload_size,
236                                      const media::cast::EncodedFrame& frame) {
237     if (expected_payload_size != frame.data.size()) {
238       ADD_FAILURE() << "Expected frame data size != frame.data.size(): "
239                     << expected_payload_size << " vs " << frame.data.size();
240       return false;
241     }
242     for (size_t i = 0; i < expected_payload_size; ++i) {
243       if (static_cast<uint8_t>(frame.data[i]) != static_cast<uint8_t>(i)) {
244         ADD_FAILURE() << "Frame data byte mismatch at offset " << i;
245         return false;
246       }
247     }
248     return true;
249   }
250 
ReceivedLoggingEvents(const std::vector<media::cast::FrameEvent> & events)251   void ReceivedLoggingEvents(
252       const std::vector<media::cast::FrameEvent>& events) {
253     EXPECT_FALSE(events.empty());
254     ++num_times_logging_callback_called_;
255   }
256 
257   int num_times_logging_callback_called_ = 0;
258 
259  private:
OnError()260   void OnError() { CHECK(expecting_error_callback_run_); }
261 
262   content::BrowserTaskEnvironment task_environment_;
263   media::cast::CastTransportRtpConfig transport_config_;
264   FakeTransport transport_;
265   std::unique_ptr<CastRemotingSender> remoting_sender_;
266   mojo::Remote<media::mojom::RemotingDataStreamSender> sender_;
267   mojo::ScopedDataPipeProducerHandle producer_end_;
268   bool expecting_error_callback_run_;
269 
270  private:
271   DISALLOW_COPY_AND_ASSIGN(CastRemotingSenderTest);
272 };
273 
TEST_F(CastRemotingSenderTest,SendsFramesViaMojoDataPipe)274 TEST_F(CastRemotingSenderTest, SendsFramesViaMojoDataPipe) {
275   // One 256-byte chunk pushed through the data pipe to make one frame.
276   ASSERT_TRUE(ProduceDataChunk(0, 256));
277   SendFrame(256);
278   RunPendingTasks();
279   EXPECT_TRUE(ExpectOneFrameWasSent(256));
280   AckOldestInFlightFrames(1);
281   EXPECT_EQ(media::cast::FrameId::first(), latest_acked_frame_id());
282 
283   // Four 256-byte chunks pushed through the data pipe to make one frame.
284   SendFrame(1024);
285   for (int i = 0; i < 4; ++i) {
286     ASSERT_TRUE(ProduceDataChunk(i * 256, 256));
287   }
288   RunPendingTasks();
289   EXPECT_TRUE(ExpectOneFrameWasSent(1024));
290   AckOldestInFlightFrames(1);
291   EXPECT_EQ(media::cast::FrameId::first() + 1, latest_acked_frame_id());
292 
293   // 10 differently-sized chunks pushed through the data pipe to make one frame
294   // that is larger than the data pipe's total capacity.
295   SendFrame(6665);
296   size_t offset = 0;
297   for (int i = 0; i < 10; ++i) {
298     const size_t chunk_size = 500 + i * 37;
299     ASSERT_TRUE(ProduceDataChunk(offset, chunk_size));
300     RunPendingTasks();
301     offset += chunk_size;
302   }
303   RunPendingTasks();
304   EXPECT_TRUE(ExpectOneFrameWasSent(6665));
305   AckOldestInFlightFrames(1);
306   EXPECT_EQ(media::cast::FrameId::first() + 2, latest_acked_frame_id());
307 }
308 
TEST_F(CastRemotingSenderTest,SendsMultipleFramesWithDelayedAcks)309 TEST_F(CastRemotingSenderTest, SendsMultipleFramesWithDelayedAcks) {
310   // Send 4 frames.
311   for (int i = 0; i < 4; ++i) {
312     ASSERT_TRUE(ProduceDataChunk(0, 16));
313     SendFrame(16);
314   }
315   RunPendingTasks();
316   EXPECT_EQ(4, NumberOfFramesInFlight());
317   EXPECT_TRUE(ExpectNoFramesCanceled());
318 
319   // Ack one frame.
320   AckOldestInFlightFrames(1);
321   EXPECT_EQ(3, NumberOfFramesInFlight());
322   EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first(),
323                                    media::cast::FrameId::first()));
324 
325   // Ack all.
326   AckOldestInFlightFrames(3);
327   EXPECT_EQ(0, NumberOfFramesInFlight());
328   EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first() + 1,
329                                    media::cast::FrameId::first() + 3));
330 }
331 
TEST_F(CastRemotingSenderTest,KickstartsIfAckNotTimely)332 TEST_F(CastRemotingSenderTest, KickstartsIfAckNotTimely) {
333   EXPECT_EQ(0, num_times_logging_callback_called_);
334 
335   // Send first frame and don't Ack it. Expect the first frame to be
336   // kickstarted.
337   ASSERT_TRUE(ProduceDataChunk(0, 16));
338   SendFrame(16);
339   EXPECT_EQ(media::cast::FrameId::first(), WaitForKickstart());
340   EXPECT_EQ(1, NumberOfFramesInFlight());
341 
342   // Send 3 more frames and don't Ack them either. Expect the 4th frame to be
343   // kickstarted.
344   for (int i = 0; i < 3; ++i) {
345     ASSERT_TRUE(ProduceDataChunk(0, 16));
346     SendFrame(16);
347   }
348   EXPECT_EQ(media::cast::FrameId::first() + 3, WaitForKickstart());
349   EXPECT_EQ(4, NumberOfFramesInFlight());
350 
351   // Ack the first two frames and wait for another kickstart (for the 4th frame
352   // again).
353   AckOldestInFlightFrames(2);
354   EXPECT_EQ(2, NumberOfFramesInFlight());
355   EXPECT_EQ(media::cast::FrameId::first() + 3, WaitForKickstart());
356 
357   // This test takes enough time to trigger the logging callback.
358   EXPECT_GT(num_times_logging_callback_called_, 2);
359 }
360 
TEST_F(CastRemotingSenderTest,CancelsUnsentFrame)361 TEST_F(CastRemotingSenderTest, CancelsUnsentFrame) {
362   EXPECT_EQ(0u, GetSizeOfNextFrameData());
363   SendFrame(16);
364   SendFrame(32);
365   CancelInFlightData();
366   RunPendingTasks();
367 
368   // Provide the data. Both frames should not be sent out.
369   ASSERT_TRUE(ProduceDataChunk(0, 16));
370   RunPendingTasks();
371   ASSERT_TRUE(ProduceDataChunk(0, 32));
372   RunPendingTasks();
373   EXPECT_EQ(0, NumberOfFramesInFlight());
374 
375   // Since no frames were sent, none should have been passed to the
376   // CastTransport, and none should have been canceled.
377   std::vector<media::cast::EncodedFrame> frames;
378   TakeSentFrames(&frames);
379   EXPECT_TRUE(frames.empty());
380   EXPECT_TRUE(ExpectNoFramesCanceled());
381 }
382 
383 // http://crbug.com/647423
384 #define MAYBE_CancelsFramesInFlight DISABLED_CancelsFramesInFlight
TEST_F(CastRemotingSenderTest,MAYBE_CancelsFramesInFlight)385 TEST_F(CastRemotingSenderTest, MAYBE_CancelsFramesInFlight) {
386   EXPECT_TRUE(IsFlowRestartPending());
387 
388   // Send 10 frames.
389   for (int i = 0; i < 10; ++i) {
390     ASSERT_TRUE(ProduceDataChunk(0, 16));
391     SendFrame(16);
392   }
393   RunPendingTasks();
394   EXPECT_FALSE(IsFlowRestartPending());
395   EXPECT_EQ(10, NumberOfFramesInFlight());
396 
397   // Ack the first frame.
398   AckOldestInFlightFrames(1);
399   EXPECT_FALSE(IsFlowRestartPending());
400   EXPECT_EQ(9, NumberOfFramesInFlight());
401   EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first(),
402                                    media::cast::FrameId::first()));
403 
404   // Cancel all in-flight data. This should cause the remaining 9 frames to be
405   // canceled.
406   CancelInFlightData();
407   RunPendingTasks();
408   EXPECT_TRUE(IsFlowRestartPending());
409   EXPECT_EQ(0, NumberOfFramesInFlight());
410   EXPECT_TRUE(ExpectFramesCanceled(media::cast::FrameId::first() + 1,
411                                    media::cast::FrameId::first() + 9));
412 
413   // Send one more frame and ack it.
414   ASSERT_TRUE(ProduceDataChunk(0, 16));
415   SendFrame(16);
416   RunPendingTasks();
417   EXPECT_FALSE(IsFlowRestartPending());
418   EXPECT_EQ(1, NumberOfFramesInFlight());
419   AckOldestInFlightFrames(1);
420   EXPECT_EQ(0, NumberOfFramesInFlight());
421 
422   // Check that the dependency metadata was set correctly to indicate a frame
423   // that immediately follows a CancelInFlightData() operation.
424   std::vector<media::cast::EncodedFrame> frames;
425   TakeSentFrames(&frames);
426   ASSERT_EQ(11u, frames.size());
427   for (size_t i = 0; i < 11; ++i) {
428     const media::cast::EncodedFrame& frame = frames[i];
429     EXPECT_EQ(media::cast::FrameId::first() + i, frame.frame_id);
430     if (i == 0 || i == 10)
431       EXPECT_EQ(media::cast::EncodedFrame::KEY, frame.dependency);
432     else
433       EXPECT_EQ(media::cast::EncodedFrame::DEPENDENT, frame.dependency);
434   }
435 }
436 
TEST_F(CastRemotingSenderTest,WaitsForDataBeforeConsumingFromDataPipe)437 TEST_F(CastRemotingSenderTest, WaitsForDataBeforeConsumingFromDataPipe) {
438   // Queue up and issue Mojo calls to consume three frames. Since no data has
439   // been pushed into the pipe yet no frames should be sent.
440   for (int i = 0; i < 3; ++i) {
441     SendFrame(4);
442   }
443   RunPendingTasks();
444   EXPECT_TRUE(IsFlowRestartPending());
445   EXPECT_EQ(0, NumberOfFramesInFlight());
446 
447   // Push the data for one frame into the data pipe. This should trigger input
448   // processing and allow one frame to be sent.
449   ASSERT_TRUE(ProduceDataChunk(0, 4));
450   RunPendingTasks();  // Allow Mojo Watcher to signal CastRemotingSender.
451   EXPECT_FALSE(IsFlowRestartPending());
452   EXPECT_EQ(1, NumberOfFramesInFlight());
453 
454   // Now push the data for the other two frames into the data pipe and expect
455   // two more frames to be sent.
456   ASSERT_TRUE(ProduceDataChunk(0, 4));
457   ASSERT_TRUE(ProduceDataChunk(0, 4));
458   RunPendingTasks();  // Allow Mojo Watcher to signal CastRemotingSender.
459   EXPECT_FALSE(IsFlowRestartPending());
460   EXPECT_EQ(3, NumberOfFramesInFlight());
461 }
462 
TEST_F(CastRemotingSenderTest,WaitsForDataThenDiscardsCanceledData)463 TEST_F(CastRemotingSenderTest, WaitsForDataThenDiscardsCanceledData) {
464   // Queue up and issue Mojo calls to consume data chunks and send three
465   // frames. Since no data has been pushed into the pipe yet no frames should be
466   // sent.
467   for (int i = 0; i < 3; ++i) {
468     SendFrame(4);
469   }
470   RunPendingTasks();
471   EXPECT_EQ(0, NumberOfFramesInFlight());
472 
473   // Cancel all in-flight data.
474   CancelInFlightData();
475   RunPendingTasks();
476 
477   // Now, push the data for one frame into the data pipe. Because of the
478   // cancellation, no frames should be sent.
479   ASSERT_TRUE(ProduceDataChunk(0, 4));
480   RunPendingTasks();  // Allow Mojo Watcher to signal CastRemotingSender.
481   EXPECT_EQ(0, NumberOfFramesInFlight());
482 
483   // Now push the data for the other two frames into the data pipe and still no
484   // frames should be sent.
485   ASSERT_TRUE(ProduceDataChunk(0, 4));
486   ASSERT_TRUE(ProduceDataChunk(0, 4));
487   RunPendingTasks();  // Allow Mojo Watcher to signal CastRemotingSender.
488   EXPECT_EQ(0, NumberOfFramesInFlight());
489 
490   // Now issue calls to send another frame and then push the data for it into
491   // the data pipe. Expect to see the frame gets sent since it was provided
492   // after the CancelInFlightData().
493   SendFrame(4);
494   RunPendingTasks();
495   EXPECT_EQ(0, NumberOfFramesInFlight());
496   ASSERT_TRUE(ProduceDataChunk(0, 4));
497   RunPendingTasks();  // Allow Mojo Watcher to signal CastRemotingSender.
498   EXPECT_EQ(1, NumberOfFramesInFlight());
499 }
500 
TEST_F(CastRemotingSenderTest,StopsConsumingWhileTooManyFramesAreInFlight)501 TEST_F(CastRemotingSenderTest, StopsConsumingWhileTooManyFramesAreInFlight) {
502   EXPECT_TRUE(IsFlowRestartPending());
503 
504   // Send out the maximum possible number of unacked frames, but don't ack any
505   // yet.
506   for (int i = 0; i < media::cast::kMaxUnackedFrames; ++i) {
507     ASSERT_TRUE(ProduceDataChunk(0, 4));
508     SendFrame(4);
509   }
510   RunPendingTasks();
511   EXPECT_FALSE(IsFlowRestartPending());
512   EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
513   // Note: All frames should have been sent to the Transport, and so
514   // CastRemotingSender's single-frame data buffer should be empty.
515   EXPECT_EQ(0u, GetSizeOfNextFrameData());
516 
517   // When the client provides one more frame, CastRemotingSender will begin
518   // queuing input operations instead of sending the the frame to the
519   // CastTransport.
520   ASSERT_TRUE(ProduceDataChunk(0, 4));
521   SendFrame(4);
522   RunPendingTasks();
523   EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
524   // Note: The unsent frame resides in CastRemotingSender's single-frame data
525   // buffer.
526   EXPECT_EQ(4u, GetSizeOfNextFrameData());
527 
528   // Ack the the first frame and expect sending to resume, with one more frame
529   // being sent to the CastTransport.
530   AckOldestInFlightFrames(1);
531   EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
532   // Note: Only one frame was backlogged, and so CastRemotingSender's
533   // single-frame data buffer should be empty.
534   EXPECT_EQ(0u, GetSizeOfNextFrameData());
535 
536   // Attempting to send another frame will once again cause CastRemotingSender
537   // to queue input operations.
538   ASSERT_TRUE(ProduceDataChunk(0, 4));
539   SendFrame(4);
540   RunPendingTasks();
541   EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
542   // Note: Once again, CastRemotingSender's single-frame data buffer contains an
543   // unsent frame.
544   EXPECT_EQ(4u, GetSizeOfNextFrameData());
545 
546   // Send more frames: Some number of frames will queue-up inside the Mojo data
547   // pipe (the exact number depends on the data pipe's capacity, and how Mojo
548   // manages memory internally). At some point, attempting to produce and push
549   // another frame will fail because the data pipe is full.
550   int num_frames_in_data_pipe = 0;
551   while (ProduceDataChunk(0, 768)) {
552     ++num_frames_in_data_pipe;
553     SendFrame(768);
554     RunPendingTasks();
555     EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
556     // Note: CastRemotingSender's single-frame data buffer should still contain
557     // the unsent 4-byte frame.
558     EXPECT_EQ(4u, GetSizeOfNextFrameData());
559   }
560   EXPECT_LT(0, num_frames_in_data_pipe);
561 
562   // Ack one frame at a time until the backlog in the Mojo data pipe has
563   // cleared.
564   int remaining_frames_in_data_pipe = num_frames_in_data_pipe;
565   while (remaining_frames_in_data_pipe > 0) {
566     AckOldestInFlightFrames(1);
567     RunPendingTasks();
568     --remaining_frames_in_data_pipe;
569     EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
570     EXPECT_EQ(768u, GetSizeOfNextFrameData());
571   }
572 
573   // Ack one more frame. There should no longer be a backlog on the input side
574   // of things.
575   AckOldestInFlightFrames(1);
576   RunPendingTasks();  // No additional Mojo method calls should be made here.
577   EXPECT_EQ(media::cast::kMaxUnackedFrames, NumberOfFramesInFlight());
578   // The single-frame data buffer should be empty to indicate no input backlog.
579   EXPECT_EQ(0u, GetSizeOfNextFrameData());
580 
581   // Ack all but one frame.
582   AckOldestInFlightFrames(NumberOfFramesInFlight() - 1);
583   EXPECT_EQ(1, NumberOfFramesInFlight());
584   // ..and one more frame can be sent immediately.
585   ASSERT_TRUE(ProduceDataChunk(0, 4));
586   SendFrame(4);
587   RunPendingTasks();
588   EXPECT_EQ(2, NumberOfFramesInFlight());
589   // ...and ack these last two frames.
590   AckOldestInFlightFrames(2);
591   EXPECT_EQ(0, NumberOfFramesInFlight());
592 
593   // Finally, examine all frames that were sent to the CastTransport, and
594   // confirm their metadata and data is valid.
595   std::vector<media::cast::EncodedFrame> frames;
596   TakeSentFrames(&frames);
597   const size_t total_frames_sent =
598       media::cast::kMaxUnackedFrames + 2 + num_frames_in_data_pipe + 1;
599   ASSERT_EQ(total_frames_sent, frames.size());
600   media::cast::RtpTimeTicks last_rtp_timestamp =
601       media::cast::RtpTimeTicks() - media::cast::RtpTimeDelta::FromTicks(1);
602   for (size_t i = 0; i < total_frames_sent; ++i) {
603     const media::cast::EncodedFrame& frame = frames[i];
604     EXPECT_EQ(media::cast::FrameId::first() + i, frame.frame_id);
605     if (i == 0) {
606       EXPECT_EQ(media::cast::EncodedFrame::KEY, frame.dependency);
607       EXPECT_EQ(media::cast::FrameId::first() + i, frame.referenced_frame_id);
608     } else {
609       EXPECT_EQ(media::cast::EncodedFrame::DEPENDENT, frame.dependency);
610       EXPECT_EQ(media::cast::FrameId::first() + i - 1,
611                 frame.referenced_frame_id);
612     }
613 
614     // RTP timestamp must be monotonically increasing.
615     EXPECT_GT(frame.rtp_timestamp, last_rtp_timestamp);
616     last_rtp_timestamp = frame.rtp_timestamp;
617 
618     size_t expected_frame_size = 4;
619     if ((i >= media::cast::kMaxUnackedFrames + 2u) &&
620         (i < media::cast::kMaxUnackedFrames + 2u + num_frames_in_data_pipe)) {
621       expected_frame_size = 768;
622     }
623     EXPECT_TRUE(ExpectCorrectFrameData(expected_frame_size, frame));
624   }
625 }
626 
627 }  // namespace mirroring
628