diff --git a/talk/app/webrtc/peerconnection.cc b/talk/app/webrtc/peerconnection.cc index bb5f0d40a..ec2059380 100644 --- a/talk/app/webrtc/peerconnection.cc +++ b/talk/app/webrtc/peerconnection.cc @@ -85,12 +85,11 @@ struct SetSessionDescriptionMsg : public talk_base::MessageData { }; struct GetStatsMsg : public talk_base::MessageData { - GetStatsMsg(webrtc::StatsObserver* observer, - webrtc::MediaStreamTrackInterface* track) - : observer(observer), track(track) { + explicit GetStatsMsg(webrtc::StatsObserver* observer) + : observer(observer) { } + webrtc::StatsReports reports; talk_base::scoped_refptr observer; - talk_base::scoped_refptr track; }; // |in_str| should be of format @@ -447,15 +446,17 @@ talk_base::scoped_refptr PeerConnection::CreateDtmfSender( bool PeerConnection::GetStats(StatsObserver* observer, MediaStreamTrackInterface* track, StatsOutputLevel level) { - ASSERT(signaling_thread()->IsCurrent()); if (!VERIFY(observer != NULL)) { LOG(LS_ERROR) << "GetStats - observer is NULL."; return false; } stats_->UpdateStats(level); - signaling_thread()->Post(this, MSG_GETSTATS, - new GetStatsMsg(observer, track)); + talk_base::scoped_ptr msg(new GetStatsMsg(observer)); + if (!stats_->GetStats(track, &(msg->reports))) { + return false; + } + signaling_thread()->Post(this, MSG_GETSTATS, msg.release()); return true; } @@ -701,9 +702,7 @@ void PeerConnection::OnMessage(talk_base::Message* msg) { } case MSG_GETSTATS: { GetStatsMsg* param = static_cast(msg->pdata); - StatsReports reports; - stats_->GetStats(param->track, &reports); - param->observer->OnComplete(reports); + param->observer->OnComplete(param->reports); delete param; break; } diff --git a/talk/app/webrtc/peerconnectioninterface.h b/talk/app/webrtc/peerconnectioninterface.h index 171c10b8b..ed4033c17 100644 --- a/talk/app/webrtc/peerconnectioninterface.h +++ b/talk/app/webrtc/peerconnectioninterface.h @@ -113,18 +113,7 @@ class StreamCollectionInterface : public talk_base::RefCountInterface { class StatsObserver : public talk_base::RefCountInterface { public: - // TODO(tommi): Remove. - virtual void OnComplete(const std::vector& reports) {} - - // TODO(tommi): Make pure virtual and remove implementation. - virtual void OnComplete(const StatsReports& reports) { - std::vector report_copies; - for (size_t i = 0; i < reports.size(); ++i) - report_copies.push_back(StatsReportCopyable(*reports[i])); - std::vector* r = - reinterpret_cast*>(&report_copies); - OnComplete(*r); - } + virtual void OnComplete(const std::vector& reports) = 0; protected: virtual ~StatsObserver() {} diff --git a/talk/app/webrtc/statscollector.cc b/talk/app/webrtc/statscollector.cc index 751e1fc13..b165841aa 100644 --- a/talk/app/webrtc/statscollector.cc +++ b/talk/app/webrtc/statscollector.cc @@ -234,6 +234,7 @@ void StatsReport::ReplaceValue(StatsReport::StatsValueName name, } namespace { +typedef std::map StatsMap; double GetTimeNow() { return talk_base::Timing::WallTimeNow() * talk_base::kNumMillisecsPerSec; @@ -293,16 +294,17 @@ bool ExtractValueFromReport( return false; } -void AddTrackReport(StatsSet* reports, const std::string& track_id) { +void AddTrackReport(StatsMap* reports, const std::string& track_id) { // Adds an empty track report. - StatsReport* report = reports->FindOrAddNew( - StatsId(StatsReport::kStatsReportTypeTrack, track_id)); - report->type = StatsReport::kStatsReportTypeTrack; - report->AddValue(StatsReport::kStatsValueNameTrackId, track_id); + StatsReport report; + report.type = StatsReport::kStatsReportTypeTrack; + report.id = StatsId(StatsReport::kStatsReportTypeTrack, track_id); + report.AddValue(StatsReport::kStatsValueNameTrackId, track_id); + (*reports)[report.id] = report; } template -void CreateTrackReports(const TrackVector& tracks, StatsSet* reports) { +void CreateTrackReports(const TrackVector& tracks, StatsMap* reports) { for (size_t j = 0; j < tracks.size(); ++j) { webrtc::MediaStreamTrackInterface* track = tracks[j]; AddTrackReport(reports, track->id()); @@ -467,7 +469,7 @@ void ExtractStats(const cricket::BandwidthEstimationInfo& info, double stats_gathering_started, PeerConnectionInterface::StatsOutputLevel level, StatsReport* report) { - ASSERT(report->id == StatsReport::kStatsReportVideoBweId); + report->id = StatsReport::kStatsReportVideoBweId; report->type = StatsReport::kStatsReportTypeBwe; // Clear out stats from previous GatherStats calls if any. @@ -581,9 +583,9 @@ void StatsCollector::AddLocalAudioTrack(AudioTrackInterface* audio_track, // Create the kStatsReportTypeTrack report for the new track if there is no // report yet. - StatsReport* found = reports_.Find( + StatsMap::iterator it = reports_.find( StatsId(StatsReport::kStatsReportTypeTrack, audio_track->id())); - if (!found) + if (it == reports_.end()) AddTrackReport(&reports_, audio_track->id()); } @@ -601,46 +603,49 @@ void StatsCollector::RemoveLocalAudioTrack(AudioTrackInterface* audio_track, ASSERT(false); } -void StatsCollector::GetStats(MediaStreamTrackInterface* track, +bool StatsCollector::GetStats(MediaStreamTrackInterface* track, StatsReports* reports) { ASSERT(reports != NULL); - ASSERT(reports->empty()); + reports->clear(); + StatsMap::iterator it; if (!track) { - StatsSet::const_iterator it; - for (it = reports_.begin(); it != reports_.end(); ++it) - reports->push_back(&(*it)); - return; + for (it = reports_.begin(); it != reports_.end(); ++it) { + reports->push_back(it->second); + } + return true; } - StatsReport* report = - reports_.Find(StatsId(StatsReport::kStatsReportTypeSession, - session_->id())); - if (report) - reports->push_back(report); + it = reports_.find(StatsId(StatsReport::kStatsReportTypeSession, + session_->id())); + if (it != reports_.end()) { + reports->push_back(it->second); + } - report = reports_.Find( - StatsId(StatsReport::kStatsReportTypeTrack, track->id())); + it = reports_.find(StatsId(StatsReport::kStatsReportTypeTrack, track->id())); - if (!report) - return; + if (it == reports_.end()) { + LOG(LS_WARNING) << "No StatsReport is available for "<< track->id(); + return false; + } - reports->push_back(report); + reports->push_back(it->second); std::string track_id; - for (StatsSet::const_iterator it = reports_.begin(); it != reports_.end(); - ++it) { - if (it->type != StatsReport::kStatsReportTypeSsrc) + for (it = reports_.begin(); it != reports_.end(); ++it) { + if (it->second.type != StatsReport::kStatsReportTypeSsrc) { continue; - - if (ExtractValueFromReport(*it, + } + if (ExtractValueFromReport(it->second, StatsReport::kStatsValueNameTrackId, &track_id)) { if (track_id == track->id()) { - reports->push_back(&(*it)); + reports->push_back(it->second); } } } + + return true; } void @@ -667,13 +672,13 @@ StatsReport* StatsCollector::PrepareLocalReport( const std::string& transport_id, TrackDirection direction) { const std::string ssrc_id = talk_base::ToString(ssrc); - StatsReport* report = reports_.Find( - StatsId(StatsReport::kStatsReportTypeSsrc, ssrc_id, direction)); + StatsMap::iterator it = reports_.find(StatsId( + StatsReport::kStatsReportTypeSsrc, ssrc_id, direction)); // Use the ID of the track that is currently mapped to the SSRC, if any. std::string track_id; if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) { - if (!report) { + if (it == reports_.end()) { // The ssrc is not used by any track or existing report, return NULL // in such case to indicate no report is prepared for the ssrc. return NULL; @@ -681,13 +686,13 @@ StatsReport* StatsCollector::PrepareLocalReport( // The ssrc is not used by any existing track. Keeps the old track id // since we want to report the stats for inactive ssrc. - ExtractValueFromReport(*report, + ExtractValueFromReport(it->second, StatsReport::kStatsValueNameTrackId, &track_id); } - report = GetOrCreateReport( - StatsReport::kStatsReportTypeSsrc, ssrc_id, direction); + StatsReport* report = GetOrCreateReport(StatsReport::kStatsReportTypeSsrc, + ssrc_id, direction); // Clear out stats from previous GatherStats calls if any. // This is required since the report will be returned for the new values. @@ -710,13 +715,13 @@ StatsReport* StatsCollector::PrepareRemoteReport( const std::string& transport_id, TrackDirection direction) { const std::string ssrc_id = talk_base::ToString(ssrc); - StatsReport* report = reports_.Find( - StatsId(StatsReport::kStatsReportTypeRemoteSsrc, ssrc_id, direction)); + StatsMap::iterator it = reports_.find(StatsId( + StatsReport::kStatsReportTypeRemoteSsrc, ssrc_id, direction)); // Use the ID of the track that is currently mapped to the SSRC, if any. std::string track_id; if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) { - if (!report) { + if (it == reports_.end()) { // The ssrc is not used by any track or existing report, return NULL // in such case to indicate no report is prepared for the ssrc. return NULL; @@ -724,12 +729,12 @@ StatsReport* StatsCollector::PrepareRemoteReport( // The ssrc is not used by any existing track. Keeps the old track id // since we want to report the stats for inactive ssrc. - ExtractValueFromReport(*report, + ExtractValueFromReport(it->second, StatsReport::kStatsValueNameTrackId, &track_id); } - report = GetOrCreateReport( + StatsReport* report = GetOrCreateReport( StatsReport::kStatsReportTypeRemoteSsrc, ssrc_id, direction); // Clear out stats from previous GatherStats calls if any. @@ -773,17 +778,18 @@ std::string StatsCollector::AddOneCertificateReport( talk_base::Base64::EncodeFromArray( der_buffer.data(), der_buffer.length(), &der_base64); - StatsReport* report = reports_.FindOrAddNew( - StatsId(StatsReport::kStatsReportTypeCertificate, fingerprint)); - report->type = StatsReport::kStatsReportTypeCertificate; - report->timestamp = stats_gathering_started_; - report->AddValue(StatsReport::kStatsValueNameFingerprint, fingerprint); - report->AddValue(StatsReport::kStatsValueNameFingerprintAlgorithm, - digest_algorithm); - report->AddValue(StatsReport::kStatsValueNameDer, der_base64); + StatsReport report; + report.type = StatsReport::kStatsReportTypeCertificate; + report.id = StatsId(report.type, fingerprint); + report.timestamp = stats_gathering_started_; + report.AddValue(StatsReport::kStatsValueNameFingerprint, fingerprint); + report.AddValue(StatsReport::kStatsValueNameFingerprintAlgorithm, + digest_algorithm); + report.AddValue(StatsReport::kStatsValueNameDer, der_base64); if (!issuer_id.empty()) - report->AddValue(StatsReport::kStatsValueNameIssuerId, issuer_id); - return report->id; + report.AddValue(StatsReport::kStatsValueNameIssuerId, issuer_id); + reports_[report.id] = report; + return report.id; } std::string StatsCollector::AddCertificateReports( @@ -813,13 +819,15 @@ std::string StatsCollector::AddCertificateReports( void StatsCollector::ExtractSessionInfo() { // Extract information from the base session. - StatsReport* report = reports_.FindOrAddNew(StatsId( - StatsReport::kStatsReportTypeSession, session_->id())); - report->type = StatsReport::kStatsReportTypeSession; - report->timestamp = stats_gathering_started_; - report->values.clear(); - report->AddBoolean(StatsReport::kStatsValueNameInitiator, - session_->initiator()); + StatsReport report; + report.id = StatsId(StatsReport::kStatsReportTypeSession, session_->id()); + report.type = StatsReport::kStatsReportTypeSession; + report.timestamp = stats_gathering_started_; + report.values.clear(); + report.AddBoolean(StatsReport::kStatsValueNameInitiator, + session_->initiator()); + + reports_[report.id] = report; cricket::SessionStats stats; if (session_->GetStats(&stats)) { @@ -849,58 +857,61 @@ void StatsCollector::ExtractSessionInfo() { = transport_iter->second.channel_stats.begin(); channel_iter != transport_iter->second.channel_stats.end(); ++channel_iter) { + StatsReport channel_report; std::ostringstream ostc; ostc << "Channel-" << transport_iter->second.content_name << "-" << channel_iter->component; - StatsReport* channel_report = reports_.FindOrAddNew(ostc.str()); - channel_report->type = StatsReport::kStatsReportTypeComponent; - channel_report->timestamp = stats_gathering_started_; - channel_report->AddValue(StatsReport::kStatsValueNameComponent, - channel_iter->component); + channel_report.id = ostc.str(); + channel_report.type = StatsReport::kStatsReportTypeComponent; + channel_report.timestamp = stats_gathering_started_; + channel_report.AddValue(StatsReport::kStatsValueNameComponent, + channel_iter->component); if (!local_cert_report_id.empty()) - channel_report->AddValue( + channel_report.AddValue( StatsReport::kStatsValueNameLocalCertificateId, local_cert_report_id); if (!remote_cert_report_id.empty()) - channel_report->AddValue( + channel_report.AddValue( StatsReport::kStatsValueNameRemoteCertificateId, remote_cert_report_id); + reports_[channel_report.id] = channel_report; for (size_t i = 0; i < channel_iter->connection_infos.size(); ++i) { + StatsReport report; + const cricket::ConnectionInfo& info + = channel_iter->connection_infos[i]; std::ostringstream ost; ost << "Conn-" << transport_iter->first << "-" << channel_iter->component << "-" << i; - StatsReport* report = reports_.FindOrAddNew(ost.str()); - report->type = StatsReport::kStatsReportTypeCandidatePair; - report->timestamp = stats_gathering_started_; + report.id = ost.str(); + report.type = StatsReport::kStatsReportTypeCandidatePair; + report.timestamp = stats_gathering_started_; // Link from connection to its containing channel. - report->AddValue(StatsReport::kStatsValueNameChannelId, - channel_report->id); - - const cricket::ConnectionInfo& info = - channel_iter->connection_infos[i]; - report->AddValue(StatsReport::kStatsValueNameBytesSent, - info.sent_total_bytes); - report->AddValue(StatsReport::kStatsValueNameBytesReceived, - info.recv_total_bytes); - report->AddBoolean(StatsReport::kStatsValueNameWritable, - info.writable); - report->AddBoolean(StatsReport::kStatsValueNameReadable, - info.readable); - report->AddBoolean(StatsReport::kStatsValueNameActiveConnection, - info.best_connection); - report->AddValue(StatsReport::kStatsValueNameLocalAddress, - info.local_candidate.address().ToString()); - report->AddValue(StatsReport::kStatsValueNameRemoteAddress, - info.remote_candidate.address().ToString()); - report->AddValue(StatsReport::kStatsValueNameRtt, info.rtt); - report->AddValue(StatsReport::kStatsValueNameTransportType, - info.local_candidate.protocol()); - report->AddValue(StatsReport::kStatsValueNameLocalCandidateType, - info.local_candidate.type()); - report->AddValue(StatsReport::kStatsValueNameRemoteCandidateType, - info.remote_candidate.type()); + report.AddValue(StatsReport::kStatsValueNameChannelId, + channel_report.id); + report.AddValue(StatsReport::kStatsValueNameBytesSent, + info.sent_total_bytes); + report.AddValue(StatsReport::kStatsValueNameBytesReceived, + info.recv_total_bytes); + report.AddBoolean(StatsReport::kStatsValueNameWritable, + info.writable); + report.AddBoolean(StatsReport::kStatsValueNameReadable, + info.readable); + report.AddBoolean(StatsReport::kStatsValueNameActiveConnection, + info.best_connection); + report.AddValue(StatsReport::kStatsValueNameLocalAddress, + info.local_candidate.address().ToString()); + report.AddValue(StatsReport::kStatsValueNameRemoteAddress, + info.remote_candidate.address().ToString()); + report.AddValue(StatsReport::kStatsValueNameRtt, info.rtt); + report.AddValue(StatsReport::kStatsValueNameTransportType, + info.local_candidate.protocol()); + report.AddValue(StatsReport::kStatsValueNameLocalCandidateType, + info.local_candidate.type()); + report.AddValue(StatsReport::kStatsValueNameRemoteCandidateType, + info.remote_candidate.type()); + reports_[report.id] = report; } } } @@ -957,8 +968,7 @@ void StatsCollector::ExtractVideoInfo( if (video_info.bw_estimations.size() != 1) { LOG(LS_ERROR) << "BWEs count: " << video_info.bw_estimations.size(); } else { - StatsReport* report = - reports_.FindOrAddNew(StatsReport::kStatsReportVideoBweId); + StatsReport* report = &reports_[StatsReport::kStatsReportVideoBweId]; ExtractStats( video_info.bw_estimations[0], stats_gathering_started_, level, report); } @@ -969,7 +979,13 @@ StatsReport* StatsCollector::GetReport(const std::string& type, TrackDirection direction) { ASSERT(type == StatsReport::kStatsReportTypeSsrc || type == StatsReport::kStatsReportTypeRemoteSsrc); - return reports_.Find(StatsId(type, id, direction)); + std::string statsid = StatsId(type, id, direction); + StatsReport* report = NULL; + std::map::iterator it = reports_.find(statsid); + if (it != reports_.end()) + report = &(it->second); + + return report; } StatsReport* StatsCollector::GetOrCreateReport(const std::string& type, @@ -980,8 +996,8 @@ StatsReport* StatsCollector::GetOrCreateReport(const std::string& type, StatsReport* report = GetReport(type, id, direction); if (report == NULL) { std::string statsid = StatsId(type, id, direction); - report = reports_.FindOrAddNew(statsid); - ASSERT(report->id == statsid); + report = &reports_[statsid]; // Create new element. + report->id = statsid; report->type = type; } diff --git a/talk/app/webrtc/statscollector.h b/talk/app/webrtc/statscollector.h index adfbfeef3..a444da482 100644 --- a/talk/app/webrtc/statscollector.h +++ b/talk/app/webrtc/statscollector.h @@ -72,11 +72,7 @@ class StatsCollector { // be called before this function to get the most recent stats. |selector| is // a track label or empty string. The most recent reports are stored in // |reports|. - // TODO(tommi): Change this contract to accept a callback object instead - // of filling in |reports|. As is, there's a requirement that the caller - // uses |reports| immediately without allowing any async activity on - // the thread (message handling etc) and then discard the results. - void GetStats(MediaStreamTrackInterface* track, + bool GetStats(MediaStreamTrackInterface* track, StatsReports* reports); // Prepare an SSRC report for the given ssrc. Used internally @@ -125,7 +121,7 @@ class StatsCollector { TrackDirection direction); // A map from the report id to the report. - StatsSet reports_; + std::map reports_; // Raw pointer to the session the statistics are gathered from. WebRtcSession* const session_; double stats_gathering_started_; diff --git a/talk/app/webrtc/statscollector_unittest.cc b/talk/app/webrtc/statscollector_unittest.cc index 58caf2892..fc0ca0ed7 100644 --- a/talk/app/webrtc/statscollector_unittest.cc +++ b/talk/app/webrtc/statscollector_unittest.cc @@ -168,10 +168,10 @@ std::string ExtractStatsValue(const std::string& type, return kNoReports; } for (size_t i = 0; i < reports.size(); ++i) { - if (reports[i]->type != type) + if (reports[i].type != type) continue; std::string ret; - if (GetValue(reports[i], name, &ret)) { + if (GetValue(&reports[i], name, &ret)) { return ret; } } @@ -184,10 +184,10 @@ std::string ExtractStatsValue(const std::string& type, const StatsReport* FindNthReportByType( const StatsReports& reports, const std::string& type, int n) { for (size_t i = 0; i < reports.size(); ++i) { - if (reports[i]->type == type) { + if (reports[i].type == type) { n--; if (n == 0) - return reports[i]; + return &reports[i]; } } return NULL; @@ -196,8 +196,8 @@ const StatsReport* FindNthReportByType( const StatsReport* FindReportById(const StatsReports& reports, const std::string& id) { for (size_t i = 0; i < reports.size(); ++i) { - if (reports[i]->id == id) { - return reports[i]; + if (reports[i].id == id) { + return &reports[i]; } } return NULL; @@ -433,7 +433,7 @@ void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) { class StatsCollectorTest : public testing::Test { protected: StatsCollectorTest() - : media_engine_(new cricket::FakeMediaEngine()), + : media_engine_(new cricket::FakeMediaEngine), channel_manager_( new cricket::ChannelManager(media_engine_, new cricket::FakeDeviceManager(), @@ -443,8 +443,6 @@ class StatsCollectorTest : public testing::Test { EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Return(false)); } - ~StatsCollectorTest() {} - // This creates a standard setup with a transport called "trspname" // having one transport channel // and the specified virtual connection name. @@ -788,7 +786,7 @@ TEST_F(StatsCollectorTest, TrackObjectExistsWithoutUpdateStats) { stats.GetStats(NULL, &reports); EXPECT_EQ((size_t)1, reports.size()); EXPECT_EQ(std::string(StatsReport::kStatsReportTypeTrack), - reports[0]->type); + reports[0].type); std::string trackValue = ExtractStatsValue(StatsReport::kStatsReportTypeTrack, @@ -834,7 +832,6 @@ TEST_F(StatsCollectorTest, TrackAndSsrcObjectExistAfterUpdateSsrcStats) { EXPECT_TRUE(track_report); // Get report for the specific |track|. - reports.clear(); stats.GetStats(track_, &reports); // |reports| should contain at least one session report, one track report, // and one ssrc report. @@ -1336,7 +1333,7 @@ TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) { webrtc::StatsCollector stats(&session_); // Implementation under test. // Ignore unused callback (logspam). EXPECT_CALL(session_, GetTransport(_)) - .WillRepeatedly(Return(static_cast(NULL))); + .WillOnce(Return(static_cast(NULL))); MockVoiceMediaChannel* media_channel = new MockVoiceMediaChannel(); // The content_name known by the voice channel. const std::string kVcName("vcname"); @@ -1399,7 +1396,6 @@ TEST_F(StatsCollectorTest, LocalAndRemoteTracksWithSameSsrc) { VerifyVoiceSenderInfoReport(track_report, voice_sender_info); // Get stats for the remote track. - reports.clear(); stats.GetStats(remote_track.get(), &reports); track_report = FindNthReportByType(reports, StatsReport::kStatsReportTypeSsrc, 1); @@ -1456,7 +1452,6 @@ TEST_F(StatsCollectorTest, TwoLocalTracksWithSameSsrc) { cricket::VoiceSenderInfo new_voice_sender_info; InitVoiceSenderInfo(&new_voice_sender_info); cricket::VoiceMediaInfo new_stats_read; - reports.clear(); SetupAndVerifyAudioTrackStats( new_audio_track.get(), stream_.get(), &stats, &voice_channel, kVcName, media_channel, &new_voice_sender_info, NULL, &new_stats_read, &reports); diff --git a/talk/app/webrtc/statstypes.h b/talk/app/webrtc/statstypes.h index 033ed3503..828b9f5f4 100644 --- a/talk/app/webrtc/statstypes.h +++ b/talk/app/webrtc/statstypes.h @@ -31,7 +31,6 @@ #ifndef TALK_APP_WEBRTC_STATSTYPES_H_ #define TALK_APP_WEBRTC_STATSTYPES_H_ -#include #include #include @@ -40,45 +39,15 @@ namespace webrtc { -// TODO(tommi): Move all the implementation that's in this file and -// statscollector.cc related to these types, into a new, statstypes.cc file. - class StatsReport { - protected: - // TODO(tommi): Disallow copy ctor etc completely once not needed. - explicit StatsReport(const StatsReport& src) - : id(src.id), - type(src.type), - timestamp(src.timestamp), - values(src.values) {} - - StatsReport& operator=(const StatsReport& src) { - ASSERT(id == src.id); - type = src.type; - timestamp = src.timestamp; - values = src.values; - return *this; - } - - // Constructor is protected to force use of StatsSet. - explicit StatsReport(const std::string& id) : id(id), timestamp(0) {} - public: - // Operators provided for STL container/algorithm support. - bool operator<(const StatsReport& other) const { return id < other.id; } - bool operator==(const StatsReport& other) const { return id == other.id; } - // Special support for being able to use std::find on a container - // without requiring a new StatsReport instance. - bool operator==(const std::string& other_id) const { return id == other_id; } + StatsReport() : timestamp(0) { } // TODO(tommi): Change this to be an enum type that holds all the // kStatsValueName constants. typedef const char* StatsValueName; - // The unique identifier for this object. - // This is used as a key for this report in ordered containers, - // so it must never be changed. - const std::string id; // See below for contents. + std::string id; // See below for contents. std::string type; // See below for contents. struct Value { @@ -270,65 +239,7 @@ class StatsReport { static const char kStatsValueNameDecodingPLCCNG[]; }; -// This class is provided for the cases where we need to keep -// snapshots of reports around. This is an edge case. -// TODO(tommi): Move into the private section of StatsSet. -class StatsReportCopyable : public StatsReport { - public: - StatsReportCopyable(const std::string& id) : StatsReport(id) {} - explicit StatsReportCopyable(const StatsReport& src) - : StatsReport(src) {} - - using StatsReport::operator=; -}; - -// Typedef for an array of const StatsReport pointers. -// Ownership of the pointers held by this implementation is assumed to lie -// elsewhere and lifetime guarantees are made by the implementation that uses -// this type. In the StatsCollector, object ownership lies with the StatsSet -// class. -typedef std::vector StatsReports; - -// A map from the report id to the report. -// This class wraps an STL container and provides a limited set of -// functionality in order to keep things simple. -// TODO(tommi): Use a thread checker here (currently not in libjingle). -class StatsSet { - public: - StatsSet() {} - ~StatsSet() {} - - typedef std::set Container; - typedef Container::iterator iterator; - typedef Container::const_iterator const_iterator; - - const_iterator begin() const { return list_.begin(); } - const_iterator end() const { return list_.end(); } - - // Creates a new report object with |id| that does not already - // exist in the list of reports. - StatsReport* InsertNew(const std::string& id) { - ASSERT(Find(id) == NULL); - const StatsReport* ret = &(*list_.insert(StatsReportCopyable(id)).first); - return const_cast(ret); - } - - StatsReport* FindOrAddNew(const std::string& id) { - StatsReport* ret = Find(id); - return ret ? ret : InsertNew(id); - } - - // Looks for a report with the given |id|. If one is not found, NULL - // will be returned. - StatsReport* Find(const std::string& id) { - const_iterator it = std::find(begin(), end(), id); - return it == end() ? NULL : - const_cast(static_cast(&(*it))); - } - - private: - Container list_; -}; +typedef std::vector StatsReports; } // namespace webrtc diff --git a/talk/app/webrtc/test/mockpeerconnectionobservers.h b/talk/app/webrtc/test/mockpeerconnectionobservers.h index 2bb187ee1..3ae2162bc 100644 --- a/talk/app/webrtc/test/mockpeerconnectionobservers.h +++ b/talk/app/webrtc/test/mockpeerconnectionobservers.h @@ -120,13 +120,9 @@ class MockStatsObserver : public webrtc::StatsObserver { MockStatsObserver() : called_(false) {} virtual ~MockStatsObserver() {} - virtual void OnComplete(const StatsReports& reports) { + virtual void OnComplete(const std::vector& reports) { called_ = true; - reports_.clear(); - reports_.reserve(reports.size()); - StatsReports::const_iterator it; - for (it = reports.begin(); it != reports.end(); ++it) - reports_.push_back(StatsReportCopyable(*(*it))); + reports_ = reports; } bool called() const { return called_; } @@ -152,7 +148,7 @@ class MockStatsObserver : public webrtc::StatsObserver { } private: - int GetSsrcStatsValue(StatsReport::StatsValueName name) { + int GetSsrcStatsValue(const std::string name) { if (reports_.empty()) { return 0; } @@ -171,7 +167,7 @@ class MockStatsObserver : public webrtc::StatsObserver { } bool called_; - std::vector reports_; + std::vector reports_; }; } // namespace webrtc