Index: webrtc/api/statscollector_unittest.cc |
diff --git a/webrtc/api/statscollector_unittest.cc b/webrtc/api/statscollector_unittest.cc |
index 00b50b69c04835f4a8ac01813f606b7af1939085..9243aedd1b52875adfcabb9430a6d784b5b25c75 100644 |
--- a/webrtc/api/statscollector_unittest.cc |
+++ b/webrtc/api/statscollector_unittest.cc |
@@ -165,6 +165,48 @@ class FakeAudioTrack |
rtc::scoped_refptr<FakeAudioProcessor> processor_; |
}; |
+// This fake audio processor is used to verify that the undesired initial values |
+// (-1) will be filtered out. |
+class FakeAudioProcessorWithInitValue : public webrtc::AudioProcessorInterface { |
+ public: |
+ FakeAudioProcessorWithInitValue() {} |
+ ~FakeAudioProcessorWithInitValue() {} |
+ |
+ private: |
+ void GetStats(AudioProcessorInterface::AudioProcessorStats* stats) override { |
+ stats->typing_noise_detected = false; |
+ stats->echo_return_loss = -100; |
+ stats->echo_return_loss_enhancement = -100; |
+ stats->echo_delay_median_ms = -1; |
+ stats->aec_quality_min = -1.0f; |
+ stats->echo_delay_std_ms = -1; |
+ } |
+}; |
+ |
+class FakeAudioTrackWithInitValue |
+ : public webrtc::MediaStreamTrack<webrtc::AudioTrackInterface> { |
+ public: |
+ explicit FakeAudioTrackWithInitValue(const std::string& id) |
+ : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(id), |
+ processor_( |
+ new rtc::RefCountedObject<FakeAudioProcessorWithInitValue>()) {} |
+ std::string kind() const override { return "audio"; } |
+ webrtc::AudioSourceInterface* GetSource() const override { return NULL; } |
+ void AddSink(webrtc::AudioTrackSinkInterface* sink) override {} |
+ void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {} |
+ bool GetSignalLevel(int* level) override { |
+ *level = 1; |
+ return true; |
+ } |
+ rtc::scoped_refptr<webrtc::AudioProcessorInterface> GetAudioProcessor() |
+ override { |
+ return processor_; |
+ } |
+ |
+ private: |
+ rtc::scoped_refptr<FakeAudioProcessorWithInitValue> processor_; |
+}; |
+ |
bool GetValue(const StatsReport* report, |
StatsReport::StatsValueName name, |
std::string* value) { |
@@ -444,7 +486,8 @@ void InitVoiceSenderInfo(cricket::VoiceSenderInfo* voice_sender_info) { |
} |
void UpdateVoiceSenderInfoFromAudioTrack( |
- FakeAudioTrack* audio_track, cricket::VoiceSenderInfo* voice_sender_info) { |
+ AudioTrackInterface* audio_track, |
+ cricket::VoiceSenderInfo* voice_sender_info) { |
audio_track->GetSignalLevel(&voice_sender_info->audio_level); |
webrtc::AudioProcessorInterface::AudioProcessorStats audio_processor_stats; |
audio_track->GetAudioProcessor()->GetStats(&audio_processor_stats); |
@@ -778,6 +821,29 @@ class StatsCollectorTest : public testing::Test { |
std::vector<rtc::scoped_refptr<DataChannel>> data_channels_; |
}; |
+TEST_F(StatsCollectorTest, FilterOutNegativeDataChannelId) { |
+ const std::string label = "hacks"; |
+ // The data channel id is from the Config which is -1 initially. |
+ const int id = -1; |
+ const std::string state = DataChannelInterface::DataStateString( |
+ DataChannelInterface::DataState::kConnecting); |
+ |
+ AddDataChannel(cricket::DCT_SCTP, label, id); |
+ StatsCollectorForTest stats(&pc_); |
+ |
+ stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard); |
+ |
+ StatsReports reports; |
+ stats.GetStats(NULL, &reports); |
+ |
+ const StatsReport* report = |
+ FindNthReportByType(reports, StatsReport::kStatsReportTypeDataChannel, 1); |
+ |
+ std::string value_in_report; |
+ EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameDataChannelId, |
+ &value_in_report)); |
+} |
+ |
// Verify that ExtractDataInfo populates reports. |
TEST_F(StatsCollectorTest, ExtractDataInfo) { |
const std::string label = "hacks"; |
@@ -1500,6 +1566,113 @@ TEST_F(StatsCollectorTest, UnsupportedDigestIgnored) { |
std::move(remote_cert), std::vector<std::string>()); |
} |
+// This test verifies that the audio/video related stats which are -1 initially |
+// will be filtered out. |
+TEST_F(StatsCollectorTest, FilterOutNegativeInitialValues) { |
+ StatsCollectorForTest stats(&pc_); |
+ |
+ EXPECT_CALL(session_, GetLocalCertificate(_, _)) |
+ .WillRepeatedly(Return(false)); |
+ EXPECT_CALL(session_, GetRemoteSSLCertificate_ReturnsRawPointer(_)) |
+ .WillRepeatedly(Return(nullptr)); |
+ |
+ MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel(); |
+ // The transport_name known by the voice channel. |
+ const std::string kVcName("vcname"); |
+ cricket::VoiceChannel voice_channel(worker_thread_, network_thread_, |
+ media_engine_, media_channel, nullptr, |
+ kVcName, false); |
+ |
+ // Create a local stream with a local audio track and adds it to the stats. |
+ if (stream_ == NULL) |
+ stream_ = webrtc::MediaStream::Create("streamlabel"); |
+ |
+ rtc::scoped_refptr<FakeAudioTrackWithInitValue> local_track( |
+ new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kLocalTrackId)); |
+ stream_->AddTrack(local_track); |
+ EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _)) |
+ .WillOnce(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true))); |
+ stats.AddStream(stream_); |
+ stats.AddLocalAudioTrack(local_track.get(), kSsrcOfTrack); |
+ |
+ // Create a remote stream with a remote audio track and adds it to the stats. |
+ rtc::scoped_refptr<webrtc::MediaStream> remote_stream( |
+ webrtc::MediaStream::Create("remotestreamlabel")); |
+ rtc::scoped_refptr<FakeAudioTrackWithInitValue> remote_track( |
+ new rtc::RefCountedObject<FakeAudioTrackWithInitValue>(kRemoteTrackId)); |
+ EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _)) |
+ .WillOnce(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true))); |
+ remote_stream->AddTrack(remote_track); |
+ stats.AddStream(remote_stream); |
+ |
+ // Instruct the session to return stats containing the transport channel. |
+ InitSessionStats(kVcName); |
+ EXPECT_CALL(session_, GetTransportStats(_)) |
+ .WillRepeatedly(DoAll(SetArgPointee<0>(session_stats_), Return(true))); |
+ |
+ cricket::VoiceSenderInfo voice_sender_info; |
+ voice_sender_info.add_ssrc(kSsrcOfTrack); |
+ // These values are set to -1 initially in audio_send_stream. |
+ // The voice_sender_info will read the values from audio_send_stream. |
+ voice_sender_info.rtt_ms = -1; |
+ voice_sender_info.packets_lost = -1; |
+ voice_sender_info.jitter_ms = -1; |
+ |
+ // Some of the contents in |voice_sender_info| needs to be updated from the |
+ // |audio_track_|. |
+ UpdateVoiceSenderInfoFromAudioTrack(local_track.get(), &voice_sender_info); |
+ |
+ cricket::VoiceReceiverInfo voice_receiver_info; |
+ voice_receiver_info.add_ssrc(kSsrcOfTrack); |
+ voice_receiver_info.capture_start_ntp_time_ms = -1; |
+ voice_receiver_info.audio_level = -1; |
+ |
+ // Constructs an ssrc stats update. |
+ cricket::VoiceMediaInfo stats_read; |
+ stats_read.senders.push_back(voice_sender_info); |
+ stats_read.receivers.push_back(voice_receiver_info); |
+ |
+ EXPECT_CALL(session_, voice_channel()).WillRepeatedly(Return(&voice_channel)); |
+ EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull()); |
+ EXPECT_CALL(*media_channel, GetStats(_)) |
+ .WillRepeatedly(DoAll(SetArgPointee<0>(stats_read), Return(true))); |
+ |
+ StatsReports reports; |
+ stats.UpdateStats(PeerConnectionInterface::kStatsOutputLevelStandard); |
+ |
+ // Get stats for the local track. |
+ stats.GetStats(local_track.get(), &reports); |
+ const StatsReport* report = |
+ FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1); |
+ EXPECT_TRUE(report); |
+ // The -1 will not be added to the stats report. |
+ std::string value_in_report; |
+ EXPECT_FALSE( |
+ GetValue(report, StatsReport::kStatsValueNameRtt, &value_in_report)); |
+ EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNamePacketsLost, |
+ &value_in_report)); |
+ EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameJitterReceived, |
+ &value_in_report)); |
+ EXPECT_FALSE(GetValue(report, |
+ StatsReport::kStatsValueNameEchoCancellationQualityMin, |
+ &value_in_report)); |
+ EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayMedian, |
+ &value_in_report)); |
+ EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameEchoDelayStdDev, |
+ &value_in_report)); |
+ |
+ // Get stats for the remote track. |
+ reports.clear(); |
+ stats.GetStats(remote_track.get(), &reports); |
+ report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1); |
+ EXPECT_TRUE(report); |
+ EXPECT_FALSE(GetValue(report, |
+ StatsReport::kStatsValueNameCaptureStartNtpTimeMs, |
+ &value_in_report)); |
+ EXPECT_FALSE(GetValue(report, StatsReport::kStatsValueNameAudioInputLevel, |
+ &value_in_report)); |
+} |
+ |
// This test verifies that a local stats object can get statistics via |
// AudioTrackInterface::GetStats() method. |
TEST_F(StatsCollectorTest, GetStatsFromLocalAudioTrack) { |