blob: 4cdbd82162a3add4d2dc0e9bbb1c90f8c88ca238 [file] [log] [blame]
Steve Anton3871f6f2018-01-26 18:25:531/*
2 * Copyright 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton10542f22019-01-11 17:11:0011#ifndef PC_TEST_FAKE_PEER_CONNECTION_FOR_STATS_H_
12#define PC_TEST_FAKE_PEER_CONNECTION_FOR_STATS_H_
Steve Anton3871f6f2018-01-26 18:25:5313
14#include <map>
15#include <memory>
16#include <set>
17#include <string>
18#include <utility>
19#include <vector>
20
Steve Anton10542f22019-01-11 17:11:0021#include "media/base/fake_media_engine.h"
22#include "pc/stream_collection.h"
23#include "pc/test/fake_data_channel_provider.h"
24#include "pc/test/fake_peer_connection_base.h"
Steve Anton3871f6f2018-01-26 18:25:5325
26namespace webrtc {
27
28// Fake VoiceMediaChannel where the result of GetStats can be configured.
29class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel {
30 public:
Tommic9625f02021-05-06 20:03:1931 explicit FakeVoiceMediaChannelForStats(TaskQueueBase* network_thread)
32 : cricket::FakeVoiceMediaChannel(nullptr,
33 cricket::AudioOptions(),
34 network_thread) {}
Steve Anton3871f6f2018-01-26 18:25:5335
36 void SetStats(const cricket::VoiceMediaInfo& voice_info) {
37 stats_ = voice_info;
38 }
39
40 // VoiceMediaChannel overrides.
Niels Möller6b4d9622020-09-14 08:47:5041 bool GetStats(cricket::VoiceMediaInfo* info,
42 bool get_and_clear_legacy_stats) override {
Steve Anton3871f6f2018-01-26 18:25:5343 if (stats_) {
44 *info = *stats_;
45 return true;
46 }
47 return false;
48 }
49
50 private:
Danil Chapovalov66cadcc2018-06-19 14:47:4351 absl::optional<cricket::VoiceMediaInfo> stats_;
Steve Anton3871f6f2018-01-26 18:25:5352};
53
54// Fake VideoMediaChannel where the result of GetStats can be configured.
55class FakeVideoMediaChannelForStats : public cricket::FakeVideoMediaChannel {
56 public:
Tommic9625f02021-05-06 20:03:1957 explicit FakeVideoMediaChannelForStats(TaskQueueBase* network_thread)
58 : cricket::FakeVideoMediaChannel(nullptr,
59 cricket::VideoOptions(),
60 network_thread) {}
Steve Anton3871f6f2018-01-26 18:25:5361
62 void SetStats(const cricket::VideoMediaInfo& video_info) {
63 stats_ = video_info;
64 }
65
66 // VideoMediaChannel overrides.
67 bool GetStats(cricket::VideoMediaInfo* info) override {
68 if (stats_) {
69 *info = *stats_;
70 return true;
71 }
72 return false;
73 }
74
75 private:
Danil Chapovalov66cadcc2018-06-19 14:47:4376 absl::optional<cricket::VideoMediaInfo> stats_;
Steve Anton3871f6f2018-01-26 18:25:5377};
78
79constexpr bool kDefaultRtcpMuxRequired = true;
80constexpr bool kDefaultSrtpRequired = true;
81
Tomas Gunnarsson6cd50812021-04-06 09:26:4782class VoiceChannelForTesting : public cricket::VoiceChannel {
83 public:
84 VoiceChannelForTesting(rtc::Thread* worker_thread,
85 rtc::Thread* network_thread,
86 rtc::Thread* signaling_thread,
87 std::unique_ptr<cricket::VoiceMediaChannel> channel,
88 const std::string& content_name,
89 bool srtp_required,
90 webrtc::CryptoOptions crypto_options,
91 rtc::UniqueRandomIdGenerator* ssrc_generator,
92 std::string transport_name)
93 : VoiceChannel(worker_thread,
94 network_thread,
95 signaling_thread,
96 std::move(channel),
97 content_name,
98 srtp_required,
99 std::move(crypto_options),
100 ssrc_generator),
101 test_transport_name_(std::move(transport_name)) {}
102
103 private:
104 const std::string& transport_name() const override {
105 return test_transport_name_;
106 }
107
108 const std::string test_transport_name_;
109};
110
111class VideoChannelForTesting : public cricket::VideoChannel {
112 public:
113 VideoChannelForTesting(rtc::Thread* worker_thread,
114 rtc::Thread* network_thread,
115 rtc::Thread* signaling_thread,
116 std::unique_ptr<cricket::VideoMediaChannel> channel,
117 const std::string& content_name,
118 bool srtp_required,
119 webrtc::CryptoOptions crypto_options,
120 rtc::UniqueRandomIdGenerator* ssrc_generator,
121 std::string transport_name)
122 : VideoChannel(worker_thread,
123 network_thread,
124 signaling_thread,
125 std::move(channel),
126 content_name,
127 srtp_required,
128 std::move(crypto_options),
129 ssrc_generator),
130 test_transport_name_(std::move(transport_name)) {}
131
132 private:
133 const std::string& transport_name() const override {
134 return test_transport_name_;
135 }
136
137 const std::string test_transport_name_;
138};
139
Steve Anton3871f6f2018-01-26 18:25:53140// This class is intended to be fed into the StatsCollector and
141// RTCStatsCollector so that the stats functionality can be unit tested.
142// Individual tests can configure this fake as needed to simulate scenarios
143// under which to test the stats collectors.
144class FakePeerConnectionForStats : public FakePeerConnectionBase {
145 public:
146 // TODO(steveanton): Add support for specifying separate threads to test
147 // multi-threading correctness.
148 FakePeerConnectionForStats()
149 : network_thread_(rtc::Thread::Current()),
150 worker_thread_(rtc::Thread::Current()),
Steve Anton5b387312018-02-03 00:00:20151 signaling_thread_(rtc::Thread::Current()),
152 local_streams_(StreamCollection::Create()),
153 remote_streams_(StreamCollection::Create()) {}
154
155 rtc::scoped_refptr<StreamCollection> mutable_local_streams() {
156 return local_streams_;
157 }
158
159 rtc::scoped_refptr<StreamCollection> mutable_remote_streams() {
160 return remote_streams_;
161 }
162
Steve Antonefe4c922019-03-27 17:26:06163 rtc::scoped_refptr<RtpSenderInterface> AddSender(
164 rtc::scoped_refptr<RtpSenderInternal> sender) {
Steve Anton57858b32018-02-15 23:19:50165 // TODO(steveanton): Switch tests to use RtpTransceivers directly.
166 auto sender_proxy = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
167 signaling_thread_, sender);
168 GetOrCreateFirstTransceiverOfType(sender->media_type())
169 ->internal()
170 ->AddSender(sender_proxy);
Steve Antonefe4c922019-03-27 17:26:06171 return sender_proxy;
Steve Anton5b387312018-02-03 00:00:20172 }
173
Steve Antonefe4c922019-03-27 17:26:06174 void RemoveSender(rtc::scoped_refptr<RtpSenderInterface> sender) {
175 GetOrCreateFirstTransceiverOfType(sender->media_type())
176 ->internal()
177 ->RemoveSender(sender);
178 }
179
180 rtc::scoped_refptr<RtpReceiverInterface> AddReceiver(
181 rtc::scoped_refptr<RtpReceiverInternal> receiver) {
Steve Anton57858b32018-02-15 23:19:50182 // TODO(steveanton): Switch tests to use RtpTransceivers directly.
183 auto receiver_proxy =
184 RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
Tommi4ccdf9322021-05-17 12:50:10185 signaling_thread_, worker_thread_, receiver);
Steve Anton57858b32018-02-15 23:19:50186 GetOrCreateFirstTransceiverOfType(receiver->media_type())
187 ->internal()
188 ->AddReceiver(receiver_proxy);
Steve Antonefe4c922019-03-27 17:26:06189 return receiver_proxy;
190 }
191
192 void RemoveReceiver(rtc::scoped_refptr<RtpReceiverInterface> receiver) {
193 GetOrCreateFirstTransceiverOfType(receiver->media_type())
194 ->internal()
195 ->RemoveReceiver(receiver);
Steve Anton5b387312018-02-03 00:00:20196 }
Steve Anton3871f6f2018-01-26 18:25:53197
198 FakeVoiceMediaChannelForStats* AddVoiceChannel(
199 const std::string& mid,
Steve Anton5b387312018-02-03 00:00:20200 const std::string& transport_name) {
Steve Anton3871f6f2018-01-26 18:25:53201 RTC_DCHECK(!voice_channel_);
Karl Wiberg918f50c2018-07-05 09:40:33202 auto voice_media_channel =
Tommic9625f02021-05-06 20:03:19203 std::make_unique<FakeVoiceMediaChannelForStats>(network_thread_);
Steve Anton3871f6f2018-01-26 18:25:53204 auto* voice_media_channel_ptr = voice_media_channel.get();
Tomas Gunnarsson6cd50812021-04-06 09:26:47205 voice_channel_ = std::make_unique<VoiceChannelForTesting>(
Amit Hilbuchbcd39d42019-01-26 01:13:56206 worker_thread_, network_thread_, signaling_thread_,
Zhi Huange830e682018-03-30 17:48:35207 std::move(voice_media_channel), mid, kDefaultSrtpRequired,
Tomas Gunnarsson6cd50812021-04-06 09:26:47208 webrtc::CryptoOptions(), &ssrc_generator_, transport_name);
Steve Anton57858b32018-02-15 23:19:50209 GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
210 ->internal()
211 ->SetChannel(voice_channel_.get());
Steve Anton3871f6f2018-01-26 18:25:53212 return voice_media_channel_ptr;
213 }
214
215 FakeVideoMediaChannelForStats* AddVideoChannel(
216 const std::string& mid,
Steve Anton5b387312018-02-03 00:00:20217 const std::string& transport_name) {
Steve Anton3871f6f2018-01-26 18:25:53218 RTC_DCHECK(!video_channel_);
Karl Wiberg918f50c2018-07-05 09:40:33219 auto video_media_channel =
Tommic9625f02021-05-06 20:03:19220 std::make_unique<FakeVideoMediaChannelForStats>(network_thread_);
Steve Anton3871f6f2018-01-26 18:25:53221 auto video_media_channel_ptr = video_media_channel.get();
Tomas Gunnarsson6cd50812021-04-06 09:26:47222 video_channel_ = std::make_unique<VideoChannelForTesting>(
Steve Anton3871f6f2018-01-26 18:25:53223 worker_thread_, network_thread_, signaling_thread_,
Zhi Huange830e682018-03-30 17:48:35224 std::move(video_media_channel), mid, kDefaultSrtpRequired,
Tomas Gunnarsson6cd50812021-04-06 09:26:47225 webrtc::CryptoOptions(), &ssrc_generator_, transport_name);
Steve Anton57858b32018-02-15 23:19:50226 GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
227 ->internal()
228 ->SetChannel(video_channel_.get());
Steve Anton3871f6f2018-01-26 18:25:53229 return video_media_channel_ptr;
230 }
231
Steve Anton3871f6f2018-01-26 18:25:53232 void AddSctpDataChannel(const std::string& label) {
233 AddSctpDataChannel(label, InternalDataChannelInit());
234 }
235
236 void AddSctpDataChannel(const std::string& label,
237 const InternalDataChannelInit& init) {
Tomas Gunnarsson7d3cfbf2020-06-15 11:47:42238 // TODO(bugs.webrtc.org/11547): Supply a separate network thread.
Taylor Brandstetter3a034e12020-07-09 22:32:34239 AddSctpDataChannel(SctpDataChannel::Create(&data_channel_provider_, label,
240 init, rtc::Thread::Current(),
241 rtc::Thread::Current()));
Steve Anton5b387312018-02-03 00:00:20242 }
243
Taylor Brandstetter3a034e12020-07-09 22:32:34244 void AddSctpDataChannel(rtc::scoped_refptr<SctpDataChannel> data_channel) {
Steve Anton5b387312018-02-03 00:00:20245 sctp_data_channels_.push_back(data_channel);
Steve Anton3871f6f2018-01-26 18:25:53246 }
247
248 void SetTransportStats(const std::string& transport_name,
249 const cricket::TransportChannelStats& channel_stats) {
Steve Anton5b387312018-02-03 00:00:20250 SetTransportStats(
251 transport_name,
252 std::vector<cricket::TransportChannelStats>{channel_stats});
253 }
254
255 void SetTransportStats(
256 const std::string& transport_name,
257 const std::vector<cricket::TransportChannelStats>& channel_stats_list) {
Steve Anton3871f6f2018-01-26 18:25:53258 cricket::TransportStats transport_stats;
259 transport_stats.transport_name = transport_name;
Steve Anton5b387312018-02-03 00:00:20260 transport_stats.channel_stats = channel_stats_list;
Steve Anton3871f6f2018-01-26 18:25:53261 transport_stats_by_name_[transport_name] = transport_stats;
262 }
263
264 void SetCallStats(const Call::Stats& call_stats) { call_stats_ = call_stats; }
265
266 void SetLocalCertificate(
267 const std::string& transport_name,
268 rtc::scoped_refptr<rtc::RTCCertificate> certificate) {
269 local_certificates_by_transport_[transport_name] = certificate;
270 }
271
Taylor Brandstetterc3928662018-02-23 21:04:51272 void SetRemoteCertChain(const std::string& transport_name,
273 std::unique_ptr<rtc::SSLCertChain> chain) {
274 remote_cert_chains_by_transport_[transport_name] = std::move(chain);
Steve Anton3871f6f2018-01-26 18:25:53275 }
276
Steve Anton5b387312018-02-03 00:00:20277 // PeerConnectionInterface overrides.
278
279 rtc::scoped_refptr<StreamCollectionInterface> local_streams() override {
280 return local_streams_;
281 }
282
283 rtc::scoped_refptr<StreamCollectionInterface> remote_streams() override {
284 return remote_streams_;
285 }
286
287 std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
288 const override {
Steve Anton57858b32018-02-15 23:19:50289 std::vector<rtc::scoped_refptr<RtpSenderInterface>> senders;
290 for (auto transceiver : transceivers_) {
291 for (auto sender : transceiver->internal()->senders()) {
292 senders.push_back(sender);
293 }
294 }
295 return senders;
Steve Anton5b387312018-02-03 00:00:20296 }
297
298 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceivers()
299 const override {
Steve Anton57858b32018-02-15 23:19:50300 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> receivers;
301 for (auto transceiver : transceivers_) {
302 for (auto receiver : transceiver->internal()->receivers()) {
303 receivers.push_back(receiver);
304 }
305 }
306 return receivers;
Steve Anton5b387312018-02-03 00:00:20307 }
308
Steve Anton3871f6f2018-01-26 18:25:53309 // PeerConnectionInternal overrides.
310
311 rtc::Thread* network_thread() const override { return network_thread_; }
312
313 rtc::Thread* worker_thread() const override { return worker_thread_; }
314
315 rtc::Thread* signaling_thread() const override { return signaling_thread_; }
316
Steve Antonb8867112018-02-13 18:07:54317 std::vector<
318 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
319 GetTransceiversInternal() const override {
320 return transceivers_;
321 }
322
Taylor Brandstetter3a034e12020-07-09 22:32:34323 std::vector<DataChannelStats> GetDataChannelStats() const override {
Tomas Gunnarsson2e94de52020-06-16 14:54:10324 RTC_DCHECK_RUN_ON(signaling_thread());
Taylor Brandstetter3a034e12020-07-09 22:32:34325 std::vector<DataChannelStats> stats;
Tomas Gunnarsson2e94de52020-06-16 14:54:10326 for (const auto& channel : sctp_data_channels_)
327 stats.push_back(channel->GetStats());
328 return stats;
Steve Anton3871f6f2018-01-26 18:25:53329 }
330
Qingsi Wang72a43a12018-02-21 00:03:18331 cricket::CandidateStatsList GetPooledCandidateStats() const override {
332 return {};
333 }
334
Steve Anton5dfde182018-02-06 18:34:40335 std::map<std::string, cricket::TransportStats> GetTransportStatsByNames(
336 const std::set<std::string>& transport_names) override {
Tomas Gunnarssonbfd9ba82021-04-18 09:55:57337 RTC_DCHECK_RUN_ON(network_thread_);
Steve Anton5dfde182018-02-06 18:34:40338 std::map<std::string, cricket::TransportStats> transport_stats_by_name;
339 for (const std::string& transport_name : transport_names) {
340 transport_stats_by_name[transport_name] =
341 GetTransportStatsByName(transport_name);
Steve Anton3871f6f2018-01-26 18:25:53342 }
Steve Anton5dfde182018-02-06 18:34:40343 return transport_stats_by_name;
Steve Anton3871f6f2018-01-26 18:25:53344 }
345
346 Call::Stats GetCallStats() override { return call_stats_; }
347
348 bool GetLocalCertificate(
349 const std::string& transport_name,
350 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
351 auto it = local_certificates_by_transport_.find(transport_name);
352 if (it != local_certificates_by_transport_.end()) {
353 *certificate = it->second;
354 return true;
355 } else {
356 return false;
357 }
358 }
359
Taylor Brandstetterc3928662018-02-23 21:04:51360 std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain(
Steve Anton3871f6f2018-01-26 18:25:53361 const std::string& transport_name) override {
Taylor Brandstetterc3928662018-02-23 21:04:51362 auto it = remote_cert_chains_by_transport_.find(transport_name);
363 if (it != remote_cert_chains_by_transport_.end()) {
Steve Antonf25303e2018-10-16 22:23:31364 return it->second->Clone();
Steve Anton3871f6f2018-01-26 18:25:53365 } else {
366 return nullptr;
367 }
368 }
369
370 private:
Steve Anton3871f6f2018-01-26 18:25:53371 cricket::TransportStats GetTransportStatsByName(
372 const std::string& transport_name) {
373 auto it = transport_stats_by_name_.find(transport_name);
374 if (it != transport_stats_by_name_.end()) {
375 // If specific transport stats have been specified, return those.
376 return it->second;
377 }
378 // Otherwise, generate some dummy stats.
379 cricket::TransportChannelStats channel_stats;
Steve Anton5b387312018-02-03 00:00:20380 channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
Steve Anton3871f6f2018-01-26 18:25:53381 cricket::TransportStats transport_stats;
382 transport_stats.transport_name = transport_name;
383 transport_stats.channel_stats.push_back(channel_stats);
384 return transport_stats;
385 }
386
Steve Anton57858b32018-02-15 23:19:50387 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
388 GetOrCreateFirstTransceiverOfType(cricket::MediaType media_type) {
389 for (auto transceiver : transceivers_) {
390 if (transceiver->internal()->media_type() == media_type) {
391 return transceiver;
392 }
393 }
394 auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Tommi99c8a802021-04-27 13:00:00395 signaling_thread_,
396 new RtpTransceiver(media_type, channel_manager_.get()));
Steve Anton57858b32018-02-15 23:19:50397 transceivers_.push_back(transceiver);
398 return transceiver;
399 }
400
Steve Anton3871f6f2018-01-26 18:25:53401 rtc::Thread* const network_thread_;
402 rtc::Thread* const worker_thread_;
403 rtc::Thread* const signaling_thread_;
404
Tommi99c8a802021-04-27 13:00:00405 std::unique_ptr<cricket::ChannelManager> channel_manager_ =
406 cricket::ChannelManager::Create(nullptr /* MediaEngineInterface */,
407 true,
408 worker_thread_,
409 network_thread_);
410
Steve Anton5b387312018-02-03 00:00:20411 rtc::scoped_refptr<StreamCollection> local_streams_;
412 rtc::scoped_refptr<StreamCollection> remote_streams_;
413
Steve Antonb8867112018-02-13 18:07:54414 std::vector<
415 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
416 transceivers_;
Steve Anton5b387312018-02-03 00:00:20417
Steve Anton3871f6f2018-01-26 18:25:53418 FakeDataChannelProvider data_channel_provider_;
419
420 std::unique_ptr<cricket::VoiceChannel> voice_channel_;
421 std::unique_ptr<cricket::VideoChannel> video_channel_;
Steve Anton3871f6f2018-01-26 18:25:53422
Taylor Brandstetter3a034e12020-07-09 22:32:34423 std::vector<rtc::scoped_refptr<SctpDataChannel>> sctp_data_channels_;
Steve Anton3871f6f2018-01-26 18:25:53424
425 std::map<std::string, cricket::TransportStats> transport_stats_by_name_;
426
427 Call::Stats call_stats_;
428
429 std::map<std::string, rtc::scoped_refptr<rtc::RTCCertificate>>
430 local_certificates_by_transport_;
Taylor Brandstetterc3928662018-02-23 21:04:51431 std::map<std::string, std::unique_ptr<rtc::SSLCertChain>>
432 remote_cert_chains_by_transport_;
Amit Hilbuchbcd39d42019-01-26 01:13:56433
434 rtc::UniqueRandomIdGenerator ssrc_generator_;
Steve Anton3871f6f2018-01-26 18:25:53435};
436
437} // namespace webrtc
438
Steve Anton10542f22019-01-11 17:11:00439#endif // PC_TEST_FAKE_PEER_CONNECTION_FOR_STATS_H_