1 // Copyright (c) 2017 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 "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/check.h"
11 #include "base/memory/scoped_refptr.h"
12 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
17 #include "third_party/blink/public/platform/web_string.h"
18 #include "third_party/blink/public/web/web_heap.h"
19 #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h"
20 #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h"
21 #include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h"
22 #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
23 #include "third_party/blink/renderer/platform/mediastream/media_stream_component.h"
24 #include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
25 #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h"
26 #include "third_party/webrtc/api/stats/rtc_stats_report.h"
27 #include "third_party/webrtc/api/stats/rtcstats_objects.h"
28 #include "third_party/webrtc/api/test/mock_rtpreceiver.h"
29
30 namespace blink {
31
32 class RTCRtpReceiverImplTest : public ::testing::Test {
33 public:
SetUp()34 void SetUp() override {
35 dependency_factory_.reset(new blink::MockPeerConnectionDependencyFactory());
36 main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
37 track_map_ = base::MakeRefCounted<blink::WebRtcMediaStreamTrackAdapterMap>(
38 dependency_factory_.get(), main_thread_);
39 peer_connection_ = new rtc::RefCountedObject<blink::MockPeerConnectionImpl>(
40 dependency_factory_.get(), nullptr);
41 }
42
TearDown()43 void TearDown() override {
44 receiver_.reset();
45 // Syncing up with the signaling thread ensures any pending operations on
46 // that thread are executed. If they post back to the main thread, such as
47 // the sender's destructor traits, this is allowed to execute before the
48 // test shuts down the threads.
49 SyncWithSignalingThread();
50 blink::WebHeap::CollectAllGarbageForTesting();
51 }
52
53 // Wait for the signaling thread to perform any queued tasks, executing tasks
54 // posted to the current thread in the meantime while waiting.
SyncWithSignalingThread() const55 void SyncWithSignalingThread() const {
56 base::RunLoop run_loop;
57 dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask(
58 FROM_HERE, run_loop.QuitClosure());
59 run_loop.Run();
60 }
61
CreateReceiver(scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,bool force_encoded_audio_insertable_streams=false,bool force_encoded_video_insertable_streams=false)62 std::unique_ptr<RTCRtpReceiverImpl> CreateReceiver(
63 scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
64 bool force_encoded_audio_insertable_streams = false,
65 bool force_encoded_video_insertable_streams = false) {
66 std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
67 track_ref;
68 base::RunLoop run_loop;
69 dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask(
70 FROM_HERE,
71 base::BindOnce(&RTCRtpReceiverImplTest::CreateReceiverOnSignalingThread,
72 base::Unretained(this), std::move(webrtc_track),
73 base::Unretained(&track_ref),
74 base::Unretained(&run_loop)));
75 run_loop.Run();
76 DCHECK(mock_webrtc_receiver_);
77 DCHECK(track_ref);
78 blink::RtpReceiverState state(
79 main_thread_, dependency_factory_->GetWebRtcSignalingTaskRunner(),
80 mock_webrtc_receiver_.get(), std::move(track_ref), {});
81 state.Initialize();
82 return std::make_unique<RTCRtpReceiverImpl>(
83 peer_connection_.get(), std::move(state),
84 force_encoded_audio_insertable_streams,
85 force_encoded_video_insertable_streams);
86 }
87
GetStats()88 scoped_refptr<blink::TestWebRTCStatsReportObtainer> GetStats() {
89 scoped_refptr<blink::TestWebRTCStatsReportObtainer> obtainer =
90 base::MakeRefCounted<TestWebRTCStatsReportObtainer>();
91 receiver_->GetStats(obtainer->GetStatsCallbackWrapper(), {});
92 return obtainer;
93 }
94
95 protected:
CreateReceiverOnSignalingThread(scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> * track_ref,base::RunLoop * run_loop)96 void CreateReceiverOnSignalingThread(
97 scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
98 std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>*
99 track_ref,
100 base::RunLoop* run_loop) {
101 mock_webrtc_receiver_ =
102 new rtc::RefCountedObject<webrtc::MockRtpReceiver>();
103 *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track);
104 run_loop->Quit();
105 }
106
107 ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_;
108
109 std::unique_ptr<blink::MockPeerConnectionDependencyFactory>
110 dependency_factory_;
111 scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
112 scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_;
113 rtc::scoped_refptr<blink::MockPeerConnectionImpl> peer_connection_;
114 rtc::scoped_refptr<webrtc::MockRtpReceiver> mock_webrtc_receiver_;
115 std::unique_ptr<RTCRtpReceiverImpl> receiver_;
116 };
117
TEST_F(RTCRtpReceiverImplTest,CreateReceiver)118 TEST_F(RTCRtpReceiverImplTest, CreateReceiver) {
119 scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track =
120 blink::MockWebRtcAudioTrack::Create("webrtc_track");
121 receiver_ = CreateReceiver(webrtc_track);
122 EXPECT_FALSE(!receiver_->Track());
123 EXPECT_EQ(receiver_->Track()->Id().Utf8(), webrtc_track->id());
124 EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track);
125 EXPECT_FALSE(receiver_->GetEncodedAudioStreamTransformer());
126 EXPECT_FALSE(receiver_->GetEncodedVideoStreamTransformer());
127 }
128
TEST_F(RTCRtpReceiverImplTest,ShallowCopy)129 TEST_F(RTCRtpReceiverImplTest, ShallowCopy) {
130 scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track =
131 blink::MockWebRtcAudioTrack::Create("webrtc_track");
132 receiver_ = CreateReceiver(webrtc_track);
133 auto copy = std::make_unique<RTCRtpReceiverImpl>(*receiver_);
134 EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track);
135 const auto& webrtc_receiver = receiver_->state().webrtc_receiver();
136 auto web_track_unique_id = receiver_->Track()->UniqueId();
137 // Copy is identical to original.
138 EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver);
139 EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track);
140 EXPECT_EQ(copy->Track()->UniqueId(), web_track_unique_id);
141 // Copy keeps the internal state alive.
142 receiver_.reset();
143 EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver);
144 EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track);
145 EXPECT_EQ(copy->Track()->UniqueId(), web_track_unique_id);
146 }
147
TEST_F(RTCRtpReceiverImplTest,GetStats)148 TEST_F(RTCRtpReceiverImplTest, GetStats) {
149 scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track =
150 blink::MockWebRtcAudioTrack::Create("webrtc_track");
151 receiver_ = CreateReceiver(webrtc_track);
152
153 // Make the mock return a blink version of the |webtc_report|. The mock does
154 // not perform any stats filtering, we just set it to a dummy value.
155 rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report =
156 webrtc::RTCStatsReport::Create(0u);
157 webrtc_report->AddStats(
158 std::make_unique<webrtc::RTCInboundRTPStreamStats>("stats-id", 1234u));
159 peer_connection_->SetGetStatsReport(webrtc_report);
160
161 auto obtainer = GetStats();
162 // Make sure the operation is async.
163 EXPECT_FALSE(obtainer->report());
164 // Wait for the report, this performs the necessary run-loop.
165 auto* report = obtainer->WaitForReport();
166 EXPECT_TRUE(report);
167
168 // Verify dummy value.
169 EXPECT_EQ(report->Size(), 1u);
170 auto stats = report->GetStats(blink::WebString::FromUTF8("stats-id"));
171 EXPECT_TRUE(stats);
172 EXPECT_EQ(stats->Timestamp(), 1.234);
173 }
174
TEST_F(RTCRtpReceiverImplTest,CreateReceiverWithInsertableStreams)175 TEST_F(RTCRtpReceiverImplTest, CreateReceiverWithInsertableStreams) {
176 scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track =
177 blink::MockWebRtcAudioTrack::Create("webrtc_track");
178 receiver_ = CreateReceiver(webrtc_track,
179 /*force_encoded_audio_insertable_streams=*/true,
180 /*force_encoded_video_insertable_streams=*/true);
181 EXPECT_TRUE(receiver_->GetEncodedAudioStreamTransformer());
182 // There should be no video transformer in audio receivers.
183 EXPECT_FALSE(receiver_->GetEncodedVideoStreamTransformer());
184 }
185
186 } // namespace blink
187