summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/renderer/media/mock_media_stream_dependency_factory.cc2
-rw-r--r--content/renderer/media/mock_peer_connection_impl.cc37
-rw-r--r--content/renderer/media/peer_connection_handler_base.cc36
-rw-r--r--content/renderer/media/peer_connection_handler_base.h3
-rw-r--r--content/renderer/media/rtc_peer_connection_handler.cc148
-rw-r--r--content/renderer/media/rtc_peer_connection_handler.h55
-rw-r--r--content/renderer/media/rtc_peer_connection_handler_unittest.cc146
7 files changed, 417 insertions, 10 deletions
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.cc b/content/renderer/media/mock_media_stream_dependency_factory.cc
index 3584c79..cb17df2 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.cc
+++ b/content/renderer/media/mock_media_stream_dependency_factory.cc
@@ -29,9 +29,11 @@ class MockMediaStreamTrackList
virtual size_t count() const OVERRIDE {
return tracks_.size();
}
+
virtual TrackType* at(size_t index) OVERRIDE {
return tracks_[index];
}
+
void AddTrack(TrackType* track) {
tracks_.push_back(track);
}
diff --git a/content/renderer/media/mock_peer_connection_impl.cc b/content/renderer/media/mock_peer_connection_impl.cc
index bb3783c..1c243d7 100644
--- a/content/renderer/media/mock_peer_connection_impl.cc
+++ b/content/renderer/media/mock_peer_connection_impl.cc
@@ -109,13 +109,6 @@ bool MockPeerConnectionImpl::SendDtmf(
return false;
}
-bool MockPeerConnectionImpl::GetStats(
- webrtc::StatsObserver* observer,
- webrtc::MediaStreamTrackInterface* track) {
- NOTIMPLEMENTED();
- return false;
-}
-
void MockPeerConnectionImpl::RemoveStream(
MediaStreamInterface* local_stream) {
DCHECK_EQ(stream_label_, local_stream->label());
@@ -123,6 +116,36 @@ void MockPeerConnectionImpl::RemoveStream(
local_streams_->RemoveStream(local_stream);
}
+bool MockPeerConnectionImpl::GetStats(
+ webrtc::StatsObserver* observer,
+ webrtc::MediaStreamTrackInterface* track) {
+ std::vector<webrtc::StatsReport> reports;
+ webrtc::StatsReport report;
+ report.id = "1234";
+ report.type = "ssrc";
+ report.local.timestamp = 42;
+ webrtc::StatsElement::Value value;
+ value.name = "trackname";
+ value.value = "trackvalue";
+ report.local.values.push_back(value);
+ reports.push_back(report);
+ // If selector is given, we pass back one report.
+ // If selector is not given, we pass back two.
+ if (!track) {
+ report.id = "nontrack";
+ report.type = "generic";
+ report.local.timestamp = 44;
+ value.name = "somename";
+ value.value = "somevalue";
+ report.local.values.push_back(value);
+ reports.push_back(report);
+ }
+ // Note that the callback is synchronous, not asynchronous; it will
+ // happen before the request call completes.
+ observer->OnComplete(reports);
+ return true;
+}
+
MockPeerConnectionImpl::ReadyState MockPeerConnectionImpl::ready_state() {
return ready_state_;
}
diff --git a/content/renderer/media/peer_connection_handler_base.cc b/content/renderer/media/peer_connection_handler_base.cc
index fb38a1b..c72a824 100644
--- a/content/renderer/media/peer_connection_handler_base.cc
+++ b/content/renderer/media/peer_connection_handler_base.cc
@@ -8,12 +8,14 @@
#include "base/utf_string_conversions.h"
#include "content/renderer/media/media_stream_dependency_factory.h"
#include "content/renderer/media/media_stream_extra_data.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamComponent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
namespace content {
+// TODO(hta): Unify implementations of these functions from MediaStreamCenter
static webrtc::LocalMediaStreamInterface* GetLocalNativeMediaStream(
const WebKit::WebMediaStreamDescriptor& stream) {
MediaStreamExtraData* extra_data =
@@ -23,6 +25,18 @@ static webrtc::LocalMediaStreamInterface* GetLocalNativeMediaStream(
return NULL;
}
+template <class TrackList>
+static webrtc::MediaStreamTrackInterface* GetLocalTrack(
+ const std::string& source_id,
+ TrackList* tracks) {
+ // TODO(hta): Look at MediaStreamTrackInterface - lookup by ID belongs below.
+ for (size_t i = 0; i < tracks->count(); ++i) {
+ if (tracks->at(i)->label() == source_id)
+ return tracks->at(i);
+ }
+ return NULL;
+}
+
PeerConnectionHandlerBase::PeerConnectionHandlerBase(
MediaStreamDependencyFactory* dependency_factory)
: dependency_factory_(dependency_factory),
@@ -88,4 +102,26 @@ PeerConnectionHandlerBase::CreateWebKitStreamDescriptor(
return descriptor;
}
+webrtc::MediaStreamTrackInterface*
+PeerConnectionHandlerBase::GetLocalNativeMediaStreamTrack(
+ const WebKit::WebMediaStreamDescriptor& stream,
+ const WebKit::WebMediaStreamComponent& component) {
+ std::string source_id = UTF16ToUTF8(component.source().id());
+ webrtc::MediaStreamInterface* native_stream
+ = GetLocalNativeMediaStream(stream);
+ if (!native_stream) {
+ return NULL;
+ }
+ if (component.source().type() == WebKit::WebMediaStreamSource::TypeAudio) {
+ return GetLocalTrack<webrtc::AudioTracks>(
+ source_id, native_stream->audio_tracks());
+ }
+ if (component.source().type() == WebKit::WebMediaStreamSource::TypeVideo) {
+ return GetLocalTrack<webrtc::VideoTracks>(
+ source_id, native_stream->video_tracks());
+ }
+ NOTIMPLEMENTED(); // We have an unknown type of media stream track.
+ return NULL;
+}
+
} // namespace content
diff --git a/content/renderer/media/peer_connection_handler_base.h b/content/renderer/media/peer_connection_handler_base.h
index 7ccf42a..5399893 100644
--- a/content/renderer/media/peer_connection_handler_base.h
+++ b/content/renderer/media/peer_connection_handler_base.h
@@ -36,6 +36,9 @@ class CONTENT_EXPORT PeerConnectionHandlerBase
void RemoveStream(const WebKit::WebMediaStreamDescriptor& stream);
WebKit::WebMediaStreamDescriptor CreateWebKitStreamDescriptor(
webrtc::MediaStreamInterface* stream);
+ webrtc::MediaStreamTrackInterface* GetLocalNativeMediaStreamTrack(
+ const WebKit::WebMediaStreamDescriptor& stream,
+ const WebKit::WebMediaStreamComponent& component);
// dependency_factory_ is a raw pointer, and is valid for the lifetime of
// MediaStreamImpl.
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc
index 33bb7c4a..cbcc7e8 100644
--- a/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -13,11 +13,14 @@
#include "content/renderer/media/media_stream_dependency_factory.h"
#include "content/renderer/media/rtc_media_constraints.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaConstraints.h"
+// TODO(hta): Move the following include to WebRTCStatsRequest.h file.
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamComponent.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCConfiguration.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCICECandidate.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectionHandlerClient.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescription.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescriptionRequest.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCStatsRequest.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCVoidRequest.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
@@ -152,6 +155,111 @@ class SetSessionDescriptionRequest
WebKit::WebRTCVoidRequest webkit_request_;
};
+// Class mapping responses from calls to libjingle
+// GetStats into a WebKit::WebRTCStatsCallback.
+class StatsResponse : public webrtc::StatsObserver {
+ public:
+ explicit StatsResponse(const scoped_refptr<LocalRTCStatsRequest>& request)
+ : request_(request),
+ response_(request_->createResponse()) {}
+
+ virtual void OnComplete(const std::vector<webrtc::StatsReport>& reports) {
+ for (std::vector<webrtc::StatsReport>::const_iterator it = reports.begin();
+ it != reports.end(); ++it) {
+ int idx = response_->addReport();
+ if (it->local.values.size() > 0) {
+ AddElement(idx, true, it->id, it->type, it->local);
+ }
+ if (it->remote.values.size() > 0) {
+ AddElement(idx, false, it->id, it->type, it->remote);
+ }
+ }
+ request_->requestSucceeded(response_);
+ }
+
+ private:
+ void AddElement(int idx,
+ bool is_local,
+ const std::string& id,
+ const std::string& type,
+ const webrtc::StatsElement& element) {
+ response_->addElement(idx, is_local, element.timestamp);
+ // TODO(hta): Make a better disposition of id and type.
+ AddStatistic(idx, is_local, "id", id);
+ AddStatistic(idx, is_local, "type", type);
+ for (webrtc::StatsElement::Values::const_iterator value_it =
+ element.values.begin();
+ value_it != element.values.end(); ++value_it) {
+ AddStatistic(idx, is_local, value_it->name, value_it->value);
+ }
+ }
+
+ void AddStatistic(int idx, bool is_local, const std::string& name,
+ const std::string& value) {
+ response_->addStatistic(idx, is_local,
+ WebKit::WebString::fromUTF8(name),
+ WebKit::WebString::fromUTF8(value));
+ }
+
+ talk_base::scoped_refptr<LocalRTCStatsRequest> request_;
+ talk_base::scoped_refptr<LocalRTCStatsResponse> response_;
+};
+
+// Implementation of LocalRTCStatsRequest
+LocalRTCStatsRequest::LocalRTCStatsRequest(WebKit::WebRTCStatsRequest impl)
+ : impl_(impl),
+ response_(NULL) {
+}
+
+LocalRTCStatsRequest::LocalRTCStatsRequest() {}
+LocalRTCStatsRequest::~LocalRTCStatsRequest() {}
+
+bool LocalRTCStatsRequest::hasSelector() const {
+ return impl_.hasSelector();
+}
+
+WebKit::WebMediaStreamDescriptor LocalRTCStatsRequest::stream() const {
+ return impl_.stream();
+}
+
+WebKit::WebMediaStreamComponent LocalRTCStatsRequest::component() const {
+ return impl_.component();
+}
+
+scoped_refptr<LocalRTCStatsResponse> LocalRTCStatsRequest::createResponse() {
+ DCHECK(!response_);
+ response_ = new talk_base::RefCountedObject<LocalRTCStatsResponse>(
+ impl_.createResponse());
+ return response_.get();
+}
+
+void LocalRTCStatsRequest::requestSucceeded(
+ const LocalRTCStatsResponse* response) {
+ impl_.requestSucceeded(response->webKitStatsResponse());
+}
+
+// Implementation of LocalRTCStatsResponse
+WebKit::WebRTCStatsResponse LocalRTCStatsResponse::webKitStatsResponse() const {
+ return impl_;
+}
+
+size_t LocalRTCStatsResponse::addReport() {
+ return impl_.addReport();
+}
+
+void LocalRTCStatsResponse::addElement(size_t report,
+ bool is_local,
+ double timestamp) {
+ impl_.addElement(report, is_local, timestamp);
+}
+
+void LocalRTCStatsResponse::addStatistic(size_t report,
+ bool is_local,
+ WebKit::WebString name,
+ WebKit::WebString value) {
+ impl_.addStatistic(report, is_local, name, value);
+}
+
RTCPeerConnectionHandler::RTCPeerConnectionHandler(
WebKit::WebRTCPeerConnectionHandlerClient* client,
MediaStreamDependencyFactory* dependency_factory)
@@ -315,6 +423,46 @@ void RTCPeerConnectionHandler::removeStream(
RemoveStream(stream);
}
+void RTCPeerConnectionHandler::getStats(
+ const WebKit::WebRTCStatsRequest& request) {
+ scoped_refptr<LocalRTCStatsRequest> inner_request(
+ new talk_base::RefCountedObject<LocalRTCStatsRequest>(request));
+ getStats(inner_request);
+}
+
+void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest* request) {
+ talk_base::scoped_refptr<webrtc::StatsObserver> observer(
+ new talk_base::RefCountedObject<StatsResponse>(request));
+ webrtc::MediaStreamTrackInterface* track = NULL;
+ if (!native_peer_connection_) {
+ DVLOG(1) << "GetStats cannot verify selector on closed connection";
+ // TODO(hta): Consider how to get an error back.
+ std::vector<webrtc::StatsReport> no_reports;
+ observer->OnComplete(no_reports);
+ return;
+ }
+
+ if (request->hasSelector()) {
+ // Verify that stream is a member of local_streams
+ if (native_peer_connection_->local_streams()
+ ->find(UTF16ToUTF8(request->stream().label()))) {
+ track = GetLocalNativeMediaStreamTrack(request->stream(),
+ request->component());
+ } else {
+ DVLOG(1) << "GetStats: Stream label not present in PC";
+ }
+
+ if (!track) {
+ DVLOG(1) << "GetStats: Track not found.";
+ // TODO(hta): Consider how to get an error back.
+ std::vector<webrtc::StatsReport> no_reports;
+ observer->OnComplete(no_reports);
+ return;
+ }
+ }
+ native_peer_connection_->GetStats(observer, track);
+}
+
void RTCPeerConnectionHandler::stop() {
DVLOG(1) << "RTCPeerConnectionHandler::stop";
native_peer_connection_ = NULL;
diff --git a/content/renderer/media/rtc_peer_connection_handler.h b/content/renderer/media/rtc_peer_connection_handler.h
index 01db449..dd9fee1 100644
--- a/content/renderer/media/rtc_peer_connection_handler.h
+++ b/content/renderer/media/rtc_peer_connection_handler.h
@@ -10,6 +10,8 @@
#include "content/common/content_export.h"
#include "content/renderer/media/peer_connection_handler_base.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectionHandler.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCStatsRequest.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCStatsResponse.h"
namespace WebKit {
class WebFrame;
@@ -17,10 +19,55 @@ class WebFrame;
namespace content {
+// Mockable wrapper for WebKit::WebRTCStatsResponse
+class CONTENT_EXPORT LocalRTCStatsResponse
+ : public talk_base::RefCountInterface {
+ public:
+ explicit LocalRTCStatsResponse(const WebKit::WebRTCStatsResponse& impl)
+ : impl_(impl) {
+ }
+ // Constructor for testing.
+ LocalRTCStatsResponse() {}
+
+ virtual WebKit::WebRTCStatsResponse webKitStatsResponse() const;
+ virtual size_t addReport();
+ virtual void addElement(size_t report, bool is_local, double timestamp);
+ virtual void addStatistic(size_t report, bool is_local,
+ WebKit::WebString name, WebKit::WebString value);
+
+ protected:
+ virtual ~LocalRTCStatsResponse() {}
+
+ private:
+ WebKit::WebRTCStatsResponse impl_;
+};
+
+// Mockable wrapper for WebKit::WebRTCStatsRequest
+class CONTENT_EXPORT LocalRTCStatsRequest
+ : public talk_base::RefCountInterface {
+ public:
+ explicit LocalRTCStatsRequest(WebKit::WebRTCStatsRequest impl);
+ // Constructor for testing.
+ LocalRTCStatsRequest();
+
+ virtual bool hasSelector() const;
+ virtual WebKit::WebMediaStreamDescriptor stream() const;
+ virtual WebKit::WebMediaStreamComponent component() const;
+ virtual void requestSucceeded(const LocalRTCStatsResponse* response);
+ virtual scoped_refptr<LocalRTCStatsResponse> createResponse();
+
+ protected:
+ virtual ~LocalRTCStatsRequest();
+
+ private:
+ WebKit::WebRTCStatsRequest impl_;
+ talk_base::scoped_refptr<LocalRTCStatsResponse> response_;
+};
+
// RTCPeerConnectionHandler is a delegate for the RTC PeerConnection API
// messages going between WebKit and native PeerConnection in libjingle. It's
// owned by WebKit.
-// WebKit call all of these methods on the main render thread.
+// WebKit calls all of these methods on the main render thread.
// Callbacks to the webrtc::PeerConnectionObserver implementation also occur on
// the main render thread.
class CONTENT_EXPORT RTCPeerConnectionHandler
@@ -73,6 +120,8 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
const WebKit::WebMediaConstraints& options) OVERRIDE;
virtual void removeStream(
const WebKit::WebMediaStreamDescriptor& stream) OVERRIDE;
+ virtual void getStats(
+ const WebKit::WebRTCStatsRequest& request) OVERRIDE;
// We will be deleted by WebKit after stop has been returned.
virtual void stop() OVERRIDE;
@@ -86,6 +135,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
virtual void OnIceComplete() OVERRIDE;
virtual void OnRenegotiationNeeded() OVERRIDE;
+ // Delegate functions to allow for mocking of WebKit interfaces.
+ // getStats takes ownership of request parameter.
+ virtual void getStats(LocalRTCStatsRequest* request);
+
private:
webrtc::SessionDescriptionInterface* CreateNativeSessionDescription(
const WebKit::WebRTCSessionDescription& description);
diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
index 71c6a3b..3ac8de1 100644
--- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc
+++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -14,6 +14,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaConstraints.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamComponent.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamDescriptor.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSource.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCConfiguration.h"
@@ -21,6 +22,7 @@
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCPeerConnectionHandlerClient.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescription.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCSessionDescriptionRequest.h"
+#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCStatsRequest.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCVoidRequest.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
@@ -29,6 +31,90 @@ static const char kDummySdpType[] = "dummy type";
namespace content {
+class MockRTCStatsResponse : public LocalRTCStatsResponse {
+ public:
+ MockRTCStatsResponse()
+ : report_count_(0),
+ element_count_(0),
+ statistic_count_(0) {
+ }
+
+ virtual size_t addReport() OVERRIDE {
+ ++report_count_;
+ return report_count_;
+ }
+
+ virtual void addElement(size_t report, bool isLocal, double timestamp)
+ OVERRIDE {
+ ++element_count_;
+ }
+
+ virtual void addStatistic(size_t report, bool isLocal,
+ WebKit::WebString name, WebKit::WebString value)
+ OVERRIDE {
+ ++statistic_count_;
+ }
+ int report_count() const { return report_count_; }
+
+ private:
+ int report_count_;
+ int element_count_;
+ int statistic_count_;
+};
+
+// Mocked wrapper for WebKit::WebRTCStatsRequest
+class MockRTCStatsRequest : public LocalRTCStatsRequest {
+ public:
+ MockRTCStatsRequest()
+ : has_selector_(false),
+ stream_(),
+ request_succeeded_called_(false) {}
+
+ virtual bool hasSelector() const OVERRIDE {
+ return has_selector_;
+ }
+ virtual WebKit::WebMediaStreamDescriptor stream() const OVERRIDE {
+ return stream_;
+ }
+ virtual WebKit::WebMediaStreamComponent component() const OVERRIDE {
+ return component_;
+ }
+ virtual scoped_refptr<LocalRTCStatsResponse> createResponse() OVERRIDE {
+ DCHECK(!response_);
+ response_ = new talk_base::RefCountedObject<MockRTCStatsResponse>();
+ return response_;
+ }
+
+ virtual void requestSucceeded(const LocalRTCStatsResponse* response)
+ OVERRIDE {
+ EXPECT_EQ(response, response_.get());
+ request_succeeded_called_ = true;
+ }
+
+ // Function for setting whether or not a selector is available.
+ void setSelector(const WebKit::WebMediaStreamDescriptor& stream,
+ const WebKit::WebMediaStreamComponent& component) {
+ has_selector_ = true;
+ stream_ = stream;
+ component_ = component;
+ }
+
+ // Function for inspecting the result of a stats request.
+ MockRTCStatsResponse* result() {
+ if (request_succeeded_called_) {
+ return response_.get();
+ } else {
+ return NULL;
+ }
+ }
+ private:
+ bool has_selector_;
+ WebKit::WebMediaStreamDescriptor stream_;
+ WebKit::WebMediaStreamComponent component_;
+ scoped_refptr<MockRTCStatsResponse> response_;
+ bool request_succeeded_called_;
+};
+
class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler {
public:
RTCPeerConnectionHandlerUnderTest(
@@ -82,7 +168,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
WebKit::WebVector<WebKit::WebMediaStreamSource> audio_sources(
static_cast<size_t>(1));
- audio_sources[0].initialize(WebKit::WebString::fromUTF8(video_track_label),
+ audio_sources[0].initialize(WebKit::WebString::fromUTF8(audio_track_label),
WebKit::WebMediaStreamSource::TypeAudio,
WebKit::WebString::fromUTF8("audio_track"));
WebKit::WebVector<WebKit::WebMediaStreamSource> video_sources(
@@ -142,7 +228,7 @@ TEST_F(RTCPeerConnectionHandlerTest, CreateOffer) {
EXPECT_TRUE(mock_peer_connection_->created_session_description() != NULL);
}
-TEST_F(RTCPeerConnectionHandlerTest, CreateAnser) {
+TEST_F(RTCPeerConnectionHandlerTest, CreateAnswer) {
WebKit::WebRTCSessionDescriptionRequest request;
WebKit::WebMediaConstraints options;
// TODO(perkj): Can WebKit::WebRTCSessionDescriptionRequest be changed so
@@ -219,6 +305,62 @@ TEST_F(RTCPeerConnectionHandlerTest, addAndRemoveStream) {
EXPECT_EQ(0u, mock_peer_connection_->local_streams()->count());
}
+TEST_F(RTCPeerConnectionHandlerTest, GetStatsNoSelector) {
+ scoped_refptr<MockRTCStatsRequest> request(
+ new talk_base::RefCountedObject<MockRTCStatsRequest>());
+ pc_handler_->getStats(request.get());
+ // Note that callback gets executed synchronously by mock.
+ ASSERT_TRUE(request->result());
+ EXPECT_LT(1, request->result()->report_count());
+}
+
+TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithSelector) {
+ std::string stream_label = "local_stream";
+ WebKit::WebMediaStreamDescriptor local_stream(
+ CreateLocalMediaStream(stream_label));
+ WebKit::WebMediaConstraints constraints;
+ pc_handler_->addStream(local_stream, constraints);
+ WebKit::WebVector<WebKit::WebMediaStreamComponent> components;
+ local_stream.audioSources(components);
+ ASSERT_LE(1ul, components.size());
+
+ scoped_refptr<MockRTCStatsRequest> request(
+ new talk_base::RefCountedObject<MockRTCStatsRequest>());
+ request->setSelector(local_stream, components[0]);
+ pc_handler_->getStats(request.get());
+ EXPECT_EQ(1, request->result()->report_count());
+}
+
+TEST_F(RTCPeerConnectionHandlerTest, GetStatsAfterStop) {
+ scoped_refptr<MockRTCStatsRequest> request(
+ new talk_base::RefCountedObject<MockRTCStatsRequest>());
+ pc_handler_->stop();
+ pc_handler_->getStats(request.get());
+ // Note that callback gets executed synchronously by mock.
+ ASSERT_TRUE(request->result());
+ // Note - returning no stats is a temporary workaround.
+ EXPECT_EQ(0, request->result()->report_count());
+}
+
+TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithBadSelector) {
+ // The setup is the same as above, but the stream is not added to the
+ // PeerConnection.
+ std::string stream_label = "local_stream_2";
+ WebKit::WebMediaStreamDescriptor local_stream(
+ CreateLocalMediaStream(stream_label));
+ WebKit::WebMediaConstraints constraints;
+ WebKit::WebVector<WebKit::WebMediaStreamComponent> components;
+ local_stream.audioSources(components);
+ WebKit::WebMediaStreamComponent component = components[0];
+ EXPECT_EQ(0u, mock_peer_connection_->local_streams()->count());
+
+ scoped_refptr<MockRTCStatsRequest> request(
+ new talk_base::RefCountedObject<MockRTCStatsRequest>());
+ request->setSelector(local_stream, component);
+ pc_handler_->getStats(request.get());
+ EXPECT_EQ(0, request->result()->report_count());
+}
+
TEST_F(RTCPeerConnectionHandlerTest, OnStateChange) {
// Ready states.
webrtc::PeerConnectionObserver::StateType state =