15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop.h"
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/default_tick_clock.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/media/cast_transport_host_filter.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "media/cast/logging/logging_defines.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CastTransportHostFilterTest : public testing::Test {
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CastTransportHostFilterTest()
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : browser_thread_bundle_(
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            content::TestBrowserThreadBundle::IO_MAINLOOP) {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    filter_ = new cast::CastTransportHostFilter();
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // 127.0.0.1:7 is the local echo service port, which
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // is probably not going to respond, but that's ok.
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TODO(hubbe): Open up an UDP port and make sure
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // we can send and receive packets.
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    net::IPAddressNumber receiver_address(4, 0);
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    receiver_address[0] = 127;
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    receiver_address[3] = 1;
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    receive_endpoint_ = net::IPEndPoint(receiver_address, 7);
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected:
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void FakeSend(const IPC::Message& message) {
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(filter_->OnMessageReceived(message));
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::DictionaryValue options_;
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::TestBrowserThreadBundle browser_thread_bundle_;
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<content::BrowserMessageFilter> filter_;
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::IPAddressNumber receiver_address_;
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  net::IPEndPoint receive_endpoint_;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CastTransportHostFilterTest, NewDelete) {
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kChannelId = 17;
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CastHostMsg_New new_msg(kChannelId, receive_endpoint_, options_);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CastHostMsg_Delete delete_msg(kChannelId);
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // New, then delete, as expected.
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(new_msg);
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(delete_msg);
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(new_msg);
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(delete_msg);
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(new_msg);
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(delete_msg);
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Now create/delete transport senders in the wrong order to make sure
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // this doesn't crash.
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(new_msg);
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(new_msg);
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(new_msg);
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(delete_msg);
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(delete_msg);
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(delete_msg);
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CastTransportHostFilterTest, NewMany) {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < 100; i++) {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CastHostMsg_New new_msg(i, receive_endpoint_, options_);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeSend(new_msg);
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 0; i < 60; i++) {
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CastHostMsg_Delete delete_msg(i);
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeSend(delete_msg);
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Leave some open, see what happens.
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CastTransportHostFilterTest, SimpleMessages) {
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create a cast transport sender.
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int32 kChannelId = 42;
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CastHostMsg_New new_msg(kChannelId, receive_endpoint_, options_);
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(new_msg);
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  media::cast::CastTransportRtpConfig audio_config;
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  audio_config.ssrc = 1;
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  audio_config.feedback_ssrc = 2;
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CastHostMsg_InitializeAudio init_audio_msg(kChannelId, audio_config);
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeSend(init_audio_msg);
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  media::cast::CastTransportRtpConfig video_config;
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  video_config.ssrc = 11;
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  video_config.feedback_ssrc = 12;
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CastHostMsg_InitializeVideo init_video_msg(kChannelId, video_config);
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeSend(init_video_msg);
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  media::cast::EncodedFrame audio_frame;
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_frame.dependency = media::cast::EncodedFrame::KEY;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  audio_frame.frame_id = 1;
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  audio_frame.referenced_frame_id = 1;
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  audio_frame.rtp_timestamp = 47;
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kSamples = 47;
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kBytesPerSample = 2;
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kChannels = 2;
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  audio_frame.data = std::string(kSamples * kBytesPerSample * kChannels, 'q');
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CastHostMsg_InsertFrame insert_audio_frame(1, kChannelId, audio_frame);
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FakeSend(insert_audio_frame);
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  media::cast::EncodedFrame video_frame;
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  video_frame.dependency = media::cast::EncodedFrame::KEY;
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  video_frame.frame_id = 1;
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  video_frame.referenced_frame_id = 1;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Let's make sure we try a few kb so multiple packets
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // are generated.
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kVideoDataSize = 4711;
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  video_frame.data = std::string(kVideoDataSize, 'p');
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CastHostMsg_InsertFrame insert_video_frame(11, kChannelId, video_frame);
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FakeSend(insert_video_frame);
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CastHostMsg_SendSenderReport rtcp_msg(
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kChannelId, 1, base::TimeTicks(), 2);
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(rtcp_msg);
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<uint32> frame_ids;
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  frame_ids.push_back(1);
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CastHostMsg_CancelSendingFrames cancel_msg(kChannelId, 1, frame_ids);
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FakeSend(cancel_msg);
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CastHostMsg_ResendFrameForKickstart kickstart_msg(kChannelId, 1, 1);
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FakeSend(kickstart_msg);
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CastHostMsg_Delete delete_msg(kChannelId);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeSend(delete_msg);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
138