summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/content_renderer.gypi4
-rw-r--r--content/content_tests.gypi3
-rw-r--r--content/renderer/media/media_stream_center.cc39
-rw-r--r--content/renderer/media/media_stream_center.h6
-rw-r--r--content/renderer/media/media_stream_dependency_factory.cc11
-rw-r--r--content/renderer/media/media_stream_dependency_factory.h6
-rw-r--r--content/renderer/media/media_stream_impl.cc88
-rw-r--r--content/renderer/media/media_stream_impl.h28
-rw-r--r--content/renderer/media/media_stream_impl_unittest.cc68
-rw-r--r--content/renderer/media/mock_media_stream_dependency_factory.cc76
-rw-r--r--content/renderer/media/mock_media_stream_dependency_factory.h5
-rw-r--r--content/renderer/media/mock_media_stream_impl.cc3
-rw-r--r--content/renderer/media/mock_media_stream_impl.h3
-rw-r--r--content/renderer/media/mock_peer_connection_impl.cc52
-rw-r--r--content/renderer/media/mock_peer_connection_impl.h25
-rw-r--r--content/renderer/media/mock_web_peer_connection_00_handler_client.cc56
-rw-r--r--content/renderer/media/mock_web_peer_connection_00_handler_client.h51
-rw-r--r--content/renderer/media/peer_connection_handler.cc120
-rw-r--r--content/renderer/media/peer_connection_handler.h49
-rw-r--r--content/renderer/media/peer_connection_handler_base.cc123
-rw-r--r--content/renderer/media/peer_connection_handler_base.h71
-rw-r--r--content/renderer/media/peer_connection_handler_jsep.cc368
-rw-r--r--content/renderer/media/peer_connection_handler_jsep.h85
-rw-r--r--content/renderer/media/peer_connection_handler_jsep_unittest.cc231
-rw-r--r--content/renderer/render_view_impl.cc28
-rw-r--r--content/renderer/render_view_impl.h4
-rw-r--r--content/renderer/renderer_webkitplatformsupport_impl.cc14
-rw-r--r--content/renderer/renderer_webkitplatformsupport_impl.h2
28 files changed, 1391 insertions, 228 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index e3ca2ea..d64fe40 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -269,6 +269,10 @@
'renderer/media/media_stream_impl.cc',
'renderer/media/peer_connection_handler.cc',
'renderer/media/peer_connection_handler.h',
+ 'renderer/media/peer_connection_handler_base.cc',
+ 'renderer/media/peer_connection_handler_base.h',
+ 'renderer/media/peer_connection_handler_jsep.cc',
+ 'renderer/media/peer_connection_handler_jsep.h',
'renderer/media/video_capture_module_impl.cc',
'renderer/media/video_capture_module_impl.h',
'renderer/media/webrtc_audio_device_impl.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index 6ef791f..47a94f4 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -127,6 +127,8 @@
'renderer/media/mock_media_stream_impl.h',
'renderer/media/mock_peer_connection_impl.cc',
'renderer/media/mock_peer_connection_impl.h',
+ 'renderer/media/mock_web_peer_connection_00_handler_client.cc',
+ 'renderer/media/mock_web_peer_connection_00_handler_client.h',
'renderer/media/mock_web_peer_connection_handler_client.cc',
'renderer/media/mock_web_peer_connection_handler_client.h',
'test/webrtc_audio_device_test.cc',
@@ -299,6 +301,7 @@
'sources': [
'renderer/media/media_stream_dispatcher_unittest.cc',
'renderer/media/media_stream_impl_unittest.cc',
+ 'renderer/media/peer_connection_handler_jsep_unittest.cc',
'renderer/media/peer_connection_handler_unittest.cc',
'renderer/media/rtc_video_decoder_unittest.cc',
'renderer/media/webrtc_audio_device_unittest.cc',
diff --git a/content/renderer/media/media_stream_center.cc b/content/renderer/media/media_stream_center.cc
index 172a151..2e5a43b 100644
--- a/content/renderer/media/media_stream_center.cc
+++ b/content/renderer/media/media_stream_center.cc
@@ -4,10 +4,17 @@
#include "content/renderer/media/media_stream_center.h"
+#include <string>
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "third_party/libjingle/source/talk/app/webrtc/jsep.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICECandidateDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamCenterClient.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/WebMediaStreamSourcesRequest.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSessionDescriptionDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
namespace content {
@@ -41,4 +48,36 @@ void MediaStreamCenter::didConstructMediaStream(
const WebKit::WebMediaStreamDescriptor& stream) {
}
+WebKit::WebString MediaStreamCenter::constructSDP(
+ const WebKit::WebICECandidateDescriptor& candidate) {
+ webrtc::IceCandidateInterface* native_candidate =
+ webrtc::CreateIceCandidate(UTF16ToUTF8(candidate.label()),
+ UTF16ToUTF8(candidate.candidateLine()));
+ std::string sdp;
+ if (!native_candidate->ToString(&sdp))
+ LOG(ERROR) << "Could not create SDP string";
+ return UTF8ToUTF16(sdp);
+}
+
+WebKit::WebString MediaStreamCenter::constructSDP(
+ const WebKit::WebSessionDescriptionDescriptor& description) {
+ webrtc::SessionDescriptionInterface* native_desc =
+ webrtc::CreateSessionDescription(UTF16ToUTF8(description.initialSDP()));
+ if (!native_desc)
+ return WebKit::WebString();
+
+ for (size_t i = 0; i < description.numberOfAddedCandidates(); ++i) {
+ WebKit::WebICECandidateDescriptor candidate = description.candidate(i);
+ webrtc::IceCandidateInterface* native_candidate =
+ webrtc::CreateIceCandidate(UTF16ToUTF8(candidate.label()),
+ UTF16ToUTF8(candidate.candidateLine()));
+ native_desc->AddCandidate(native_candidate);
+ }
+
+ std::string sdp;
+ if (!native_desc->ToString(&sdp))
+ LOG(ERROR) << "Could not create SDP string";
+ return UTF8ToUTF16(sdp);
+}
+
} // namespace content
diff --git a/content/renderer/media/media_stream_center.h b/content/renderer/media/media_stream_center.h
index 11c1fc4..d7020fd 100644
--- a/content/renderer/media/media_stream_center.h
+++ b/content/renderer/media/media_stream_center.h
@@ -38,6 +38,12 @@ class CONTENT_EXPORT MediaStreamCenter
virtual void didConstructMediaStream(
const WebKit::WebMediaStreamDescriptor& stream) OVERRIDE;
+ virtual WebKit::WebString constructSDP(
+ const WebKit::WebICECandidateDescriptor& candidate) OVERRIDE;
+
+ virtual WebKit::WebString constructSDP(
+ const WebKit::WebSessionDescriptionDescriptor& description) OVERRIDE;
+
private:
// Weak pointer, owned by WebKit.
WebKit::WebMediaStreamCenterClient* client_;
diff --git a/content/renderer/media/media_stream_dependency_factory.cc b/content/renderer/media/media_stream_dependency_factory.cc
index f245485..2c8d997 100644
--- a/content/renderer/media/media_stream_dependency_factory.cc
+++ b/content/renderer/media/media_stream_dependency_factory.cc
@@ -137,3 +137,14 @@ MediaStreamDependencyFactory::CreateLocalAudioTrack(
webrtc::AudioDeviceModule* audio_device) {
return pc_factory_->CreateLocalAudioTrack(label, audio_device);
}
+
+webrtc::SessionDescriptionInterface*
+MediaStreamDependencyFactory::CreateSessionDescription(const std::string& sdp) {
+ return webrtc::CreateSessionDescription(sdp);
+}
+
+webrtc::IceCandidateInterface* MediaStreamDependencyFactory::CreateIceCandidate(
+ const std::string& label,
+ const std::string& sdp) {
+ return webrtc::CreateIceCandidate(label, sdp);
+}
diff --git a/content/renderer/media/media_stream_dependency_factory.h b/content/renderer/media/media_stream_dependency_factory.h
index 9bf0e80..559b8d9 100644
--- a/content/renderer/media/media_stream_dependency_factory.h
+++ b/content/renderer/media/media_stream_dependency_factory.h
@@ -74,6 +74,12 @@ class CONTENT_EXPORT MediaStreamDependencyFactory {
CreateLocalAudioTrack(const std::string& label,
webrtc::AudioDeviceModule* audio_device);
+ virtual webrtc::SessionDescriptionInterface* CreateSessionDescription(
+ const std::string& sdp);
+ virtual webrtc::IceCandidateInterface* CreateIceCandidate(
+ const std::string& label,
+ const std::string& sdp);
+
private:
talk_base::scoped_refptr<webrtc::PeerConnectionFactoryInterface> pc_factory_;
diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
index 072def1..4940433 100644
--- a/content/renderer/media/media_stream_impl.cc
+++ b/content/renderer/media/media_stream_impl.cc
@@ -14,6 +14,7 @@
#include "content/renderer/media/media_stream_dependency_factory.h"
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/peer_connection_handler.h"
+#include "content/renderer/media/peer_connection_handler_jsep.h"
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/media/video_capture_module_impl.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
@@ -81,15 +82,13 @@ MediaStreamImpl::MediaStreamImpl(
p2p_socket_dispatcher_(p2p_socket_dispatcher),
network_manager_(NULL),
vc_manager_(vc_manager),
- peer_connection_handler_(NULL),
- message_loop_proxy_(base::MessageLoopProxy::current()),
signaling_thread_(NULL),
worker_thread_(NULL),
chrome_worker_thread_("Chrome_libJingle_WorkerThread") {
}
MediaStreamImpl::~MediaStreamImpl() {
- DCHECK(!peer_connection_handler_);
+ DCHECK(peer_connection_handlers_.empty());
if (dependency_factory_.get())
dependency_factory_->ReleasePeerConnectionFactory();
if (network_manager_) {
@@ -112,30 +111,46 @@ MediaStreamImpl::~MediaStreamImpl() {
WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler(
WebKit::WebPeerConnectionHandlerClient* client) {
DCHECK(CalledOnValidThread());
- if (peer_connection_handler_) {
- DVLOG(1) << "A PeerConnection already exists";
+ if (!EnsurePeerConnectionFactory())
return NULL;
- }
+
+ PeerConnectionHandler* pc_handler = new PeerConnectionHandler(
+ client,
+ this,
+ dependency_factory_.get());
+ peer_connection_handlers_.push_back(pc_handler);
+
+ return pc_handler;
+}
+
+WebKit::WebPeerConnection00Handler*
+MediaStreamImpl::CreatePeerConnectionHandlerJsep(
+ WebKit::WebPeerConnection00HandlerClient* client) {
+ DCHECK(CalledOnValidThread());
if (!EnsurePeerConnectionFactory())
return NULL;
- peer_connection_handler_ = new PeerConnectionHandler(
+ PeerConnectionHandlerJsep* pc_handler = new PeerConnectionHandlerJsep(
client,
this,
dependency_factory_.get());
+ peer_connection_handlers_.push_back(pc_handler);
- return peer_connection_handler_;
+ return pc_handler;
}
-void MediaStreamImpl::ClosePeerConnection() {
+void MediaStreamImpl::ClosePeerConnection(
+ PeerConnectionHandlerBase* pc_handler) {
DCHECK(CalledOnValidThread());
- video_renderer_ = NULL;
- peer_connection_handler_ = NULL;
- // TODO(grunell): This is a temporary workaround for an error in native
- // PeerConnection where added live tracks are not seen on the remote side.
- MediaStreamTrackPtrMap::const_iterator it = local_tracks_.begin();
- for (; it != local_tracks_.end(); ++it)
- it->second->set_state(webrtc::MediaStreamTrackInterface::kEnded);
+ VideoRendererMap::iterator vr_it = video_renderers_.begin();
+ while (vr_it != video_renderers_.end()) {
+ if (vr_it->second.second == pc_handler) {
+ video_renderers_.erase(vr_it++);
+ } else {
+ ++vr_it;
+ }
+ }
+ peer_connection_handlers_.remove(pc_handler);
}
webrtc::MediaStreamTrackInterface* MediaStreamImpl::GetLocalMediaStreamTrack(
@@ -144,8 +159,8 @@ webrtc::MediaStreamTrackInterface* MediaStreamImpl::GetLocalMediaStreamTrack(
MediaStreamTrackPtrMap::iterator it = local_tracks_.find(label);
if (it == local_tracks_.end())
return NULL;
- MediaStreamTrackPtr stream = it->second;
- return stream.get();
+ MediaStreamTrackPtr track = it->second;
+ return track.get();
}
void MediaStreamImpl::requestUserMedia(
@@ -236,27 +251,34 @@ scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder(
capability);
} else {
// It's a remote stream.
- if (!video_renderer_.get())
- video_renderer_ = new talk_base::RefCountedObject<VideoRendererWrapper>();
- if (video_renderer_->renderer()) {
- // The renderer is used by PeerConnection, release it first.
- if (peer_connection_handler_) {
- peer_connection_handler_->SetVideoRenderer(
- UTF16ToUTF8(descriptor.label()),
- NULL);
+ std::string desc_label = UTF16ToUTF8(descriptor.label());
+ PeerConnectionHandlerBase* pc_handler = NULL;
+ std::list<PeerConnectionHandlerBase*>::iterator it;
+ for (it = peer_connection_handlers_.begin();
+ it != peer_connection_handlers_.end(); ++it) {
+ if ((*it)->HasStream(desc_label)) {
+ pc_handler = *it;
+ break;
}
- video_renderer_->SetVideoDecoder(NULL);
}
+ DCHECK(it != peer_connection_handlers_.end());
+ // TODO(grunell): We are not informed when a renderer should be deleted.
+ // When this has been fixed, ensure we delete it. For now, we hold on
+ // to all renderers until a PeerConnectionHandler is closed or we are
+ // deleted (then all renderers are deleted), so it sort of leaks.
+ // TODO(grunell): There is no support for multiple decoders per stream, this
+ // code will need to be updated when that is supported.
+ talk_base::scoped_refptr<VideoRendererWrapper> video_renderer =
+ new talk_base::RefCountedObject<VideoRendererWrapper>();
RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder(
message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"),
url.spec());
decoder = rtc_video_decoder;
- video_renderer_->SetVideoDecoder(rtc_video_decoder);
- if (peer_connection_handler_) {
- peer_connection_handler_->SetVideoRenderer(
- UTF16ToUTF8(descriptor.label()),
- video_renderer_);
- }
+ video_renderer->SetVideoDecoder(rtc_video_decoder);
+ pc_handler->SetVideoRenderer(desc_label, video_renderer);
+ video_renderers_.erase(desc_label); // Remove old renderer if exists.
+ video_renderers_.insert(
+ std::make_pair(desc_label, std::make_pair(video_renderer, pc_handler)));
}
return decoder;
}
diff --git a/content/renderer/media/media_stream_impl.h b/content/renderer/media/media_stream_impl.h
index 7a59582..a9c2db7 100644
--- a/content/renderer/media/media_stream_impl.h
+++ b/content/renderer/media/media_stream_impl.h
@@ -8,6 +8,7 @@
#include <list>
#include <map>
#include <string>
+#include <utility>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
@@ -42,13 +43,15 @@ class Thread;
}
namespace WebKit {
+class WebPeerConnection00Handler;
+class WebPeerConnection00HandlerClient;
class WebPeerConnectionHandler;
class WebPeerConnectionHandlerClient;
}
class MediaStreamDispatcher;
class MediaStreamDependencyFactory;
-class PeerConnectionHandler;
+class PeerConnectionHandlerBase;
class VideoCaptureImplManager;
class RTCVideoDecoder;
@@ -74,7 +77,9 @@ class CONTENT_EXPORT MediaStreamImpl
virtual WebKit::WebPeerConnectionHandler* CreatePeerConnectionHandler(
WebKit::WebPeerConnectionHandlerClient* client);
- virtual void ClosePeerConnection();
+ virtual WebKit::WebPeerConnection00Handler* CreatePeerConnectionHandlerJsep(
+ WebKit::WebPeerConnection00HandlerClient* client);
+ virtual void ClosePeerConnection(PeerConnectionHandlerBase* pc_handler);
virtual webrtc::MediaStreamTrackInterface* GetLocalMediaStreamTrack(
const std::string& label);
@@ -117,6 +122,7 @@ class CONTENT_EXPORT MediaStreamImpl
private:
FRIEND_TEST_ALL_PREFIXES(MediaStreamImplTest, Basic);
+ FRIEND_TEST_ALL_PREFIXES(MediaStreamImplTest, MultiplePeerConnections);
class VideoRendererWrapper : public webrtc::VideoRendererWrapperInterface {
public:
@@ -159,10 +165,10 @@ class CONTENT_EXPORT MediaStreamImpl
scoped_refptr<VideoCaptureImplManager> vc_manager_;
- // peer_connection_handler_ is a weak reference, owned by WebKit. It's valid
- // until stop is called on it (which will call ClosePeerConnection on us).
- // TODO(grunell): Support several PeerConnectionsHandlers.
- PeerConnectionHandler* peer_connection_handler_;
+ // peer_connection_handlers_ contains raw references, owned by WebKit. A
+ // pointer is valid until stop is called on the object (which will call
+ // ClosePeerConnection on us and we remove the pointer).
+ std::list<PeerConnectionHandlerBase*> peer_connection_handlers_;
// We keep a list of the generated local tracks, so that we can add capture
// devices when generated and also use them for recording.
@@ -171,8 +177,14 @@ class CONTENT_EXPORT MediaStreamImpl
typedef std::map<std::string, MediaStreamTrackPtr> MediaStreamTrackPtrMap;
MediaStreamTrackPtrMap local_tracks_;
- talk_base::scoped_refptr<VideoRendererWrapper> video_renderer_;
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+ // Native PeerConnection only supports 1:1 mapping between MediaStream and
+ // video tag/renderer, so we restrict to this too. The key in
+ // VideoRendererMap is the stream label.
+ typedef talk_base::scoped_refptr<VideoRendererWrapper> VideoRendererPtr;
+ typedef std::pair<VideoRendererPtr, PeerConnectionHandlerBase*>
+ VideoRendererPair;
+ typedef std::map<std::string, VideoRendererPair> VideoRendererMap;
+ VideoRendererMap video_renderers_;
// PeerConnection threads. signaling_thread_ is created from the
// "current" chrome thread.
diff --git a/content/renderer/media/media_stream_impl_unittest.cc b/content/renderer/media/media_stream_impl_unittest.cc
index 110c69d..f00aa04 100644
--- a/content/renderer/media/media_stream_impl_unittest.cc
+++ b/content/renderer/media/media_stream_impl_unittest.cc
@@ -7,10 +7,14 @@
#include "content/renderer/media/media_stream_impl.h"
#include "content/renderer/media/mock_media_stream_dependency_factory.h"
#include "content/renderer/media/mock_media_stream_dispatcher.h"
+#include "content/renderer/media/mock_web_peer_connection_00_handler_client.h"
#include "content/renderer/media/mock_web_peer_connection_handler_client.h"
+#include "content/renderer/media/peer_connection_handler.h"
+#include "content/renderer/media/peer_connection_handler_jsep.h"
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/p2p/socket_dispatcher.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnection00Handler.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnectionHandler.h"
// Disabled due to http://crbug.com/112408 .
@@ -38,9 +42,67 @@ TEST(MediaStreamImplTest, DISABLED_Basic) {
WebKit::MockWebPeerConnectionHandlerClient client;
WebKit::WebPeerConnectionHandler* pc_handler =
ms_impl->CreatePeerConnectionHandler(&client);
- EXPECT_TRUE(ms_impl->peer_connection_handler_);
+ EXPECT_EQ(1u, ms_impl->peer_connection_handlers_.size());
- ms_impl->ClosePeerConnection();
- EXPECT_FALSE(ms_impl->peer_connection_handler_);
+ // Delete PC handler explicitly after closing to mimic WebKit behavior.
+ ms_impl->ClosePeerConnection(
+ static_cast<PeerConnectionHandler*>(pc_handler));
+ EXPECT_TRUE(ms_impl->peer_connection_handlers_.empty());
delete pc_handler;
+
+ WebKit::MockWebPeerConnection00HandlerClient client_jsep;
+ WebKit::WebPeerConnection00Handler* pc_handler_jsep =
+ ms_impl->CreatePeerConnectionHandlerJsep(&client_jsep);
+ EXPECT_EQ(1u, ms_impl->peer_connection_handlers_.size());
+
+ // Delete PC handler explicitly after closing to mimic WebKit behavior.
+ ms_impl->ClosePeerConnection(
+ static_cast<PeerConnectionHandlerJsep*>(pc_handler_jsep));
+ EXPECT_TRUE(ms_impl->peer_connection_handlers_.empty());
+ delete pc_handler_jsep;
+}
+
+// Disabled due to http://crbug.com/112408 .
+TEST(MediaStreamImplTest, DISABLED_MultiplePeerConnections) {
+ MessageLoop loop;
+
+ // Create our test object.
+ scoped_ptr<MockMediaStreamDispatcher> ms_dispatcher(
+ new MockMediaStreamDispatcher());
+ scoped_ptr<content::P2PSocketDispatcher> p2p_socket_dispatcher(
+ new content::P2PSocketDispatcher(NULL));
+ scoped_refptr<VideoCaptureImplManager> vc_manager(
+ new VideoCaptureImplManager());
+ MockMediaStreamDependencyFactory* dependency_factory =
+ new MockMediaStreamDependencyFactory();
+ scoped_refptr<MediaStreamImpl> ms_impl(new MediaStreamImpl(
+ ms_dispatcher.get(),
+ p2p_socket_dispatcher.get(),
+ vc_manager.get(),
+ dependency_factory));
+
+ // TODO(grunell): Add tests for WebKit::WebUserMediaClient and
+ // MediaStreamDispatcherEventHandler implementations.
+
+ WebKit::MockWebPeerConnectionHandlerClient client;
+ WebKit::WebPeerConnectionHandler* pc_handler =
+ ms_impl->CreatePeerConnectionHandler(&client);
+ EXPECT_EQ(1u, ms_impl->peer_connection_handlers_.size());
+
+ WebKit::MockWebPeerConnection00HandlerClient client_jsep;
+ WebKit::WebPeerConnection00Handler* pc_handler_jsep =
+ ms_impl->CreatePeerConnectionHandlerJsep(&client_jsep);
+ EXPECT_EQ(2u, ms_impl->peer_connection_handlers_.size());
+
+ // Delete PC handler explicitly after closing to mimic WebKit behavior.
+ ms_impl->ClosePeerConnection(
+ static_cast<PeerConnectionHandler*>(pc_handler));
+ EXPECT_EQ(1u, ms_impl->peer_connection_handlers_.size());
+ delete pc_handler;
+
+ // Delete PC handler explicitly after closing to mimic WebKit behavior.
+ ms_impl->ClosePeerConnection(
+ static_cast<PeerConnectionHandlerJsep*>(pc_handler_jsep));
+ EXPECT_TRUE(ms_impl->peer_connection_handlers_.empty());
+ delete pc_handler_jsep;
}
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.cc b/content/renderer/media/mock_media_stream_dependency_factory.cc
index 2d76882..7d54d11 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.cc
+++ b/content/renderer/media/mock_media_stream_dependency_factory.cc
@@ -123,6 +123,65 @@ void MockLocalVideoTrack::UnregisterObserver(ObserverInterface* observer) {
NOTIMPLEMENTED();
}
+class MockSessionDescription : public SessionDescriptionInterface {
+ public:
+ MockSessionDescription(const std::string& sdp)
+ : sdp_(sdp) {
+ }
+ virtual ~MockSessionDescription() {}
+ virtual const cricket::SessionDescription* description() const OVERRIDE {
+ NOTIMPLEMENTED();
+ return NULL;
+ }
+ virtual bool AddCandidate(const IceCandidateInterface* candidate) OVERRIDE {
+ NOTIMPLEMENTED();
+ return false;
+ }
+ virtual size_t number_of_mediasections() const OVERRIDE {
+ NOTIMPLEMENTED();
+ return 0;
+ }
+ virtual const IceCandidateColletion* candidates(
+ size_t mediasection_index) const OVERRIDE {
+ NOTIMPLEMENTED();
+ return NULL;
+ }
+ virtual bool ToString(std::string* out) const OVERRIDE {
+ *out = sdp_;
+ return true;
+ }
+
+ private:
+ std::string sdp_;
+};
+
+class MockIceCandidate : public IceCandidateInterface {
+ public:
+ MockIceCandidate(const std::string& label, const std::string& sdp)
+ : label_(label),
+ sdp_(sdp) {
+ }
+ virtual ~MockIceCandidate() {}
+ virtual std::string label() const OVERRIDE {
+ return label_;
+ }
+ virtual const cricket::Candidate& candidate() const OVERRIDE {
+ // This function should never be called. It will intentionally crash. The
+ // base class forces us to return a reference.
+ NOTREACHED();
+ cricket::Candidate* candidate = NULL;
+ return *candidate;
+ }
+ virtual bool ToString(std::string* out) const OVERRIDE {
+ *out = sdp_;
+ return true;
+ }
+
+ private:
+ std::string label_;
+ std::string sdp_;
+};
+
} // namespace webrtc
MockMediaStreamDependencyFactory::MockMediaStreamDependencyFactory()
@@ -154,7 +213,7 @@ MockMediaStreamDependencyFactory::CreatePeerConnection(
const std::string& config,
webrtc::PeerConnectionObserver* observer) {
DCHECK(mock_pc_factory_created_);
- return new talk_base::RefCountedObject<webrtc::MockPeerConnectionImpl>();
+ return new talk_base::RefCountedObject<webrtc::MockPeerConnectionImpl>(this);
}
talk_base::scoped_refptr<webrtc::PeerConnectionInterface>
@@ -162,7 +221,7 @@ MockMediaStreamDependencyFactory::CreateRoapPeerConnection(
const std::string& config,
webrtc::PeerConnectionObserver* observer) {
DCHECK(mock_pc_factory_created_);
- return new talk_base::RefCountedObject<webrtc::MockPeerConnectionImpl>();
+ return new talk_base::RefCountedObject<webrtc::MockPeerConnectionImpl>(this);
}
talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface>
@@ -189,3 +248,16 @@ MockMediaStreamDependencyFactory::CreateLocalAudioTrack(
NOTIMPLEMENTED();
return NULL;
}
+
+webrtc::SessionDescriptionInterface*
+MockMediaStreamDependencyFactory::CreateSessionDescription(
+ const std::string& sdp) {
+ return new webrtc::MockSessionDescription(sdp);
+}
+
+webrtc::IceCandidateInterface*
+MockMediaStreamDependencyFactory::CreateIceCandidate(
+ const std::string& label,
+ const std::string& sdp) {
+ return new webrtc::MockIceCandidate(label, sdp);
+}
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.h b/content/renderer/media/mock_media_stream_dependency_factory.h
index f482ce5..2a8737a 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.h
+++ b/content/renderer/media/mock_media_stream_dependency_factory.h
@@ -77,6 +77,11 @@ class MockMediaStreamDependencyFactory : public MediaStreamDependencyFactory {
CreateLocalAudioTrack(
const std::string& label,
webrtc::AudioDeviceModule* audio_device) OVERRIDE;
+ virtual webrtc::SessionDescriptionInterface* CreateSessionDescription(
+ const std::string& sdp) OVERRIDE;
+ virtual webrtc::IceCandidateInterface* CreateIceCandidate(
+ const std::string& label,
+ const std::string& sdp) OVERRIDE;
private:
bool mock_pc_factory_created_;
diff --git a/content/renderer/media/mock_media_stream_impl.cc b/content/renderer/media/mock_media_stream_impl.cc
index 4996e95..8ce04de 100644
--- a/content/renderer/media/mock_media_stream_impl.cc
+++ b/content/renderer/media/mock_media_stream_impl.cc
@@ -21,7 +21,8 @@ MockMediaStreamImpl::CreatePeerConnectionHandler(
return NULL;
}
-void MockMediaStreamImpl::ClosePeerConnection() {
+void MockMediaStreamImpl::ClosePeerConnection(
+ PeerConnectionHandlerBase* pc_handler) {
}
webrtc::MediaStreamTrackInterface*
diff --git a/content/renderer/media/mock_media_stream_impl.h b/content/renderer/media/mock_media_stream_impl.h
index 8340b9e..f751ed7 100644
--- a/content/renderer/media/mock_media_stream_impl.h
+++ b/content/renderer/media/mock_media_stream_impl.h
@@ -17,7 +17,8 @@ class MockMediaStreamImpl : public MediaStreamImpl {
virtual WebKit::WebPeerConnectionHandler* CreatePeerConnectionHandler(
WebKit::WebPeerConnectionHandlerClient* client) OVERRIDE;
- virtual void ClosePeerConnection() OVERRIDE;
+ virtual void ClosePeerConnection(
+ PeerConnectionHandlerBase* pc_handler) OVERRIDE;
virtual webrtc::MediaStreamTrackInterface* GetLocalMediaStreamTrack(
const std::string& label) OVERRIDE;
diff --git a/content/renderer/media/mock_peer_connection_impl.cc b/content/renderer/media/mock_peer_connection_impl.cc
index ccfae44..7f68eae 100644
--- a/content/renderer/media/mock_peer_connection_impl.cc
+++ b/content/renderer/media/mock_peer_connection_impl.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/renderer/media/mock_media_stream_dependency_factory.h"
#include "content/renderer/media/mock_peer_connection_impl.h"
#include <vector>
@@ -36,10 +37,19 @@ class MockStreamCollection : public StreamCollectionInterface {
std::vector<talk_base::scoped_refptr<MediaStreamInterface> > streams_;
};
-MockPeerConnectionImpl::MockPeerConnectionImpl()
- : stream_changes_committed_(false),
+const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer";
+
+MockPeerConnectionImpl::MockPeerConnectionImpl(
+ MockMediaStreamDependencyFactory* factory)
+ : dependency_factory_(factory),
+ stream_changes_committed_(false),
local_streams_(new talk_base::RefCountedObject<MockStreamCollection>),
- remote_streams_(new talk_base::RefCountedObject<MockStreamCollection>) {
+ remote_streams_(new talk_base::RefCountedObject<MockStreamCollection>),
+ hint_audio_(false),
+ hint_video_(false),
+ action_(kAnswer),
+ ice_options_(kOnlyRelay),
+ ready_state_(kNew) {
}
MockPeerConnectionImpl::~MockPeerConnectionImpl() {}
@@ -85,8 +95,7 @@ void MockPeerConnectionImpl::Close() {
}
MockPeerConnectionImpl::ReadyState MockPeerConnectionImpl::ready_state() {
- NOTIMPLEMENTED();
- return kNew;
+ return ready_state_;
}
MockPeerConnectionImpl::SdpState MockPeerConnectionImpl::sdp_state() {
@@ -95,53 +104,54 @@ MockPeerConnectionImpl::SdpState MockPeerConnectionImpl::sdp_state() {
}
bool MockPeerConnectionImpl::StartIce(IceOptions options) {
- NOTIMPLEMENTED();
- return false;
+ ice_options_ = options;
+ return true;
}
webrtc::SessionDescriptionInterface* MockPeerConnectionImpl::CreateOffer(
const webrtc::MediaHints& hints) {
- NOTIMPLEMENTED();
- return NULL;
+ hint_audio_ = hints.has_audio();
+ hint_video_ = hints.has_video();
+ return dependency_factory_->CreateSessionDescription(kDummyOffer);
}
webrtc::SessionDescriptionInterface* MockPeerConnectionImpl::CreateAnswer(
const webrtc::MediaHints& hints,
const webrtc::SessionDescriptionInterface* offer) {
- NOTIMPLEMENTED();
- return NULL;
+ hint_audio_ = hints.has_audio();
+ hint_video_ = hints.has_video();
+ offer->ToString(&description_sdp_);
+ return dependency_factory_->CreateSessionDescription(description_sdp_);
}
bool MockPeerConnectionImpl::SetLocalDescription(
Action action,
webrtc::SessionDescriptionInterface* desc) {
- NOTIMPLEMENTED();
- return false;
+ action_ = action;
+ return desc->ToString(&description_sdp_);
}
bool MockPeerConnectionImpl::SetRemoteDescription(
Action action,
webrtc::SessionDescriptionInterface* desc) {
- NOTIMPLEMENTED();
- return false;
+ action_ = action;
+ return desc->ToString(&description_sdp_);
}
bool MockPeerConnectionImpl::ProcessIceMessage(
const webrtc::IceCandidateInterface* ice_candidate) {
- NOTIMPLEMENTED();
- return false;
+ ice_label_ = ice_candidate->label();
+ return ice_candidate->ToString(&ice_sdp_);
}
const webrtc::SessionDescriptionInterface*
MockPeerConnectionImpl::local_description() const {
- NOTIMPLEMENTED();
- return NULL;
+ return dependency_factory_->CreateSessionDescription(description_sdp_);
}
const webrtc::SessionDescriptionInterface*
MockPeerConnectionImpl::remote_description() const {
- NOTIMPLEMENTED();
- return NULL;
+ return dependency_factory_->CreateSessionDescription(description_sdp_);
}
void MockPeerConnectionImpl::AddRemoteStream(MediaStreamInterface* stream) {
diff --git a/content/renderer/media/mock_peer_connection_impl.h b/content/renderer/media/mock_peer_connection_impl.h
index 2993ce4..60afd6c 100644
--- a/content/renderer/media/mock_peer_connection_impl.h
+++ b/content/renderer/media/mock_peer_connection_impl.h
@@ -11,13 +11,15 @@
#include "base/compiler_specific.h"
#include "third_party/libjingle/source/talk/app/webrtc/peerconnection.h"
+class MockMediaStreamDependencyFactory;
+
namespace webrtc {
class MockStreamCollection;
class MockPeerConnectionImpl : public PeerConnectionInterface {
public:
- MockPeerConnectionImpl();
+ MockPeerConnectionImpl(MockMediaStreamDependencyFactory* factory);
// PeerConnectionInterface implementation.
virtual void ProcessSignalingMessage(const std::string& msg) OVERRIDE;
@@ -54,20 +56,41 @@ class MockPeerConnectionImpl : public PeerConnectionInterface {
void AddRemoteStream(MediaStreamInterface* stream);
void ClearStreamChangesCommitted() { stream_changes_committed_ = false; }
+ void SetReadyState(ReadyState state) { ready_state_ = state; }
const std::string& signaling_message() const { return signaling_message_; }
const std::string& stream_label() const { return stream_label_; }
bool stream_changes_committed() const { return stream_changes_committed_; }
+ bool hint_audio() const { return hint_audio_; }
+ bool hint_video() const { return hint_video_; }
+ Action action() const { return action_; }
+ const std::string& description_sdp() const { return description_sdp_; }
+ IceOptions ice_options() const { return ice_options_; }
+ const std::string& ice_label() const { return ice_label_; }
+ const std::string& ice_sdp() const { return ice_sdp_; }
+
+ static const char kDummyOffer[];
protected:
virtual ~MockPeerConnectionImpl();
private:
+ // Used for creating MockSessionDescription.
+ MockMediaStreamDependencyFactory* dependency_factory_;
+
std::string signaling_message_;
std::string stream_label_;
bool stream_changes_committed_;
talk_base::scoped_refptr<MockStreamCollection> local_streams_;
talk_base::scoped_refptr<MockStreamCollection> remote_streams_;
+ bool hint_audio_;
+ bool hint_video_;
+ Action action_;
+ std::string description_sdp_;
+ IceOptions ice_options_;
+ std::string ice_label_;
+ std::string ice_sdp_;
+ ReadyState ready_state_;
DISALLOW_COPY_AND_ASSIGN(MockPeerConnectionImpl);
};
diff --git a/content/renderer/media/mock_web_peer_connection_00_handler_client.cc b/content/renderer/media/mock_web_peer_connection_00_handler_client.cc
new file mode 100644
index 0000000..770e3fb7
--- /dev/null
+++ b/content/renderer/media/mock_web_peer_connection_00_handler_client.cc
@@ -0,0 +1,56 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "content/renderer/media/mock_web_peer_connection_00_handler_client.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICECandidateDescriptor.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamDescriptor.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
+
+namespace WebKit {
+
+MockWebPeerConnection00HandlerClient::
+MockWebPeerConnection00HandlerClient()
+ : ready_state_(ReadyStateNew),
+ more_to_follow_(false) {
+}
+
+MockWebPeerConnection00HandlerClient::
+~MockWebPeerConnection00HandlerClient() {}
+
+void MockWebPeerConnection00HandlerClient::didGenerateICECandidate(
+ const WebICECandidateDescriptor& candidate,
+ bool more_to_follow) {
+ if (candidate.isNull()) {
+ candidate_label_.clear();
+ candidate_sdp_.clear();
+ } else {
+ candidate_label_ = UTF16ToUTF8(candidate.label());
+ candidate_sdp_ = UTF16ToUTF8(candidate.candidateLine());
+ }
+ more_to_follow_ = more_to_follow;
+}
+
+void MockWebPeerConnection00HandlerClient::didChangeReadyState(
+ ReadyState state) {
+ ready_state_ = state;
+}
+
+void MockWebPeerConnection00HandlerClient::didChangeICEState(ICEState state) {
+ NOTIMPLEMENTED();
+}
+
+void MockWebPeerConnection00HandlerClient::didAddRemoteStream(
+ const WebMediaStreamDescriptor& stream_descriptor) {
+ stream_label_ = UTF16ToUTF8(stream_descriptor.label());
+}
+
+void MockWebPeerConnection00HandlerClient::didRemoveRemoteStream(
+ const WebMediaStreamDescriptor& stream_descriptor) {
+ DCHECK(stream_label_ == UTF16ToUTF8(stream_descriptor.label()));
+ stream_label_.clear();
+}
+
+} // namespace WebKit
diff --git a/content/renderer/media/mock_web_peer_connection_00_handler_client.h b/content/renderer/media/mock_web_peer_connection_00_handler_client.h
new file mode 100644
index 0000000..7f3de5c
--- /dev/null
+++ b/content/renderer/media/mock_web_peer_connection_00_handler_client.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_MOCK_WEB_JSEP_PEER_CONNECTION_HANDLER_CLIENT_H_
+#define CONTENT_RENDERER_MEDIA_MOCK_WEB_JSEP_PEER_CONNECTION_HANDLER_CLIENT_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnection00HandlerClient.h"
+
+namespace WebKit {
+
+class MockWebPeerConnection00HandlerClient
+ : public WebPeerConnection00HandlerClient {
+ public:
+ MockWebPeerConnection00HandlerClient();
+ virtual ~MockWebPeerConnection00HandlerClient();
+
+ // WebPeerConnection00HandlerClient implementation.
+ virtual void didGenerateICECandidate(
+ const WebICECandidateDescriptor& candidate,
+ bool more_to_follow) OVERRIDE;
+ virtual void didChangeReadyState(ReadyState state) OVERRIDE;
+ virtual void didChangeICEState(ICEState state) OVERRIDE;
+ virtual void didAddRemoteStream(
+ const WebMediaStreamDescriptor& stream_descriptor) OVERRIDE;
+ virtual void didRemoveRemoteStream(
+ const WebMediaStreamDescriptor& stream_descriptor) OVERRIDE;
+
+ const std::string& stream_label() const { return stream_label_; }
+ ReadyState ready_state() const { return ready_state_; }
+ const std::string& candidate_label() const { return candidate_label_; }
+ const std::string& candidate_sdp() const { return candidate_sdp_; }
+ bool more_to_follow() const { return more_to_follow_; }
+
+ private:
+ std::string stream_label_;
+ ReadyState ready_state_;
+ std::string candidate_label_;
+ std::string candidate_sdp_;
+ bool more_to_follow_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockWebPeerConnection00HandlerClient);
+};
+
+} // namespace WebKit
+
+#endif // CONTENT_RENDERER_MEDIA_MOCK_WEB_JSEP_PEER_CONNECTION_HANDLER_CLIENT_H_
diff --git a/content/renderer/media/peer_connection_handler.cc b/content/renderer/media/peer_connection_handler.cc
index 74acf2e..747e95f 100644
--- a/content/renderer/media/peer_connection_handler.cc
+++ b/content/renderer/media/peer_connection_handler.cc
@@ -22,32 +22,13 @@ PeerConnectionHandler::PeerConnectionHandler(
WebKit::WebPeerConnectionHandlerClient* client,
MediaStreamImpl* msi,
MediaStreamDependencyFactory* dependency_factory)
- : client_(client),
- media_stream_impl_(msi),
- dependency_factory_(dependency_factory),
- message_loop_proxy_(base::MessageLoopProxy::current()) {
+ : PeerConnectionHandlerBase(msi, dependency_factory),
+ client_(client) {
}
PeerConnectionHandler::~PeerConnectionHandler() {
}
-void PeerConnectionHandler::SetVideoRenderer(
- const std::string& stream_label,
- webrtc::VideoRendererWrapperInterface* renderer) {
- webrtc::MediaStreamInterface* stream =
- native_peer_connection_->remote_streams()->find(stream_label);
- webrtc::VideoTracks* video_tracks = stream->video_tracks();
- // We assume there is only one enabled video track.
- for (size_t i = 0; i < video_tracks->count(); ++i) {
- webrtc::VideoTrackInterface* video_track = video_tracks->at(i);
- if (video_track->enabled()) {
- video_track->SetRenderer(renderer);
- return;
- }
- }
- DVLOG(1) << "No enabled video track.";
-}
-
void PeerConnectionHandler::initialize(
const WebKit::WebString& server_configuration,
const WebKit::WebString& username) {
@@ -60,7 +41,8 @@ void PeerConnectionHandler::initialize(
void PeerConnectionHandler::produceInitialOffer(
const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>&
pending_add_streams) {
- AddStreams(pending_add_streams);
+ for (size_t i = 0; i < pending_add_streams.size(); ++i)
+ AddStream(pending_add_streams[i]);
native_peer_connection_->CommitStreamChanges();
}
@@ -77,8 +59,10 @@ void PeerConnectionHandler::processPendingStreams(
pending_add_streams,
const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>&
pending_remove_streams) {
- AddStreams(pending_add_streams);
- RemoveStreams(pending_remove_streams);
+ for (size_t i = 0; i < pending_add_streams.size(); ++i)
+ AddStream(pending_add_streams[i]);
+ for (size_t i = 0; i < pending_remove_streams.size(); ++i)
+ RemoveStream(pending_remove_streams[i]);
native_peer_connection_->CommitStreamChanges();
}
@@ -94,7 +78,7 @@ void PeerConnectionHandler::stop() {
// close. We need to investigate further. Not calling Close() on native
// PeerConnection is OK for now.
native_peer_connection_ = NULL;
- media_stream_impl_->ClosePeerConnection();
+ media_stream_impl_->ClosePeerConnection(this);
}
void PeerConnectionHandler::OnError() {
@@ -154,54 +138,13 @@ void PeerConnectionHandler::OnRemoveStream(
void PeerConnectionHandler::OnIceCandidate(
const webrtc::IceCandidateInterface* candidate) {
- // TODO(grunell): Implement.
- NOTIMPLEMENTED();
+ // Not used by ROAP PeerConnection.
+ NOTREACHED();
}
void PeerConnectionHandler::OnIceComplete() {
- // TODO(grunell): Implement.
- NOTIMPLEMENTED();
-}
-
-void PeerConnectionHandler::AddStreams(
- const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>& streams) {
- for (size_t i = 0; i < streams.size(); ++i) {
- talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface> stream =
- dependency_factory_->CreateLocalMediaStream(
- UTF16ToUTF8(streams[i].label()));
- WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector;
- streams[i].sources(source_vector);
-
- // Get and add all tracks.
- for (size_t j = 0; j < source_vector.size(); ++j) {
- webrtc::MediaStreamTrackInterface* track =
- media_stream_impl_->GetLocalMediaStreamTrack(
- UTF16ToUTF8(source_vector[j].id()));
- DCHECK(track);
- if (source_vector[j].type() == WebKit::WebMediaStreamSource::TypeVideo) {
- stream->AddTrack(static_cast<webrtc::VideoTrackInterface*>(track));
- } else {
- stream->AddTrack(static_cast<webrtc::AudioTrackInterface*>(track));
- }
- }
-
- native_peer_connection_->AddStream(stream);
- }
-}
-
-void PeerConnectionHandler::RemoveStreams(
- const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>& streams) {
- talk_base::scoped_refptr<webrtc::StreamCollectionInterface> native_streams =
- native_peer_connection_->local_streams();
- // TODO(perkj): Change libJingle PeerConnection::RemoveStream API to take a
- // label as input instead of stream and return bool.
- for (size_t i = 0; i < streams.size() && native_streams != NULL; ++i) {
- webrtc::LocalMediaStreamInterface* stream =
- static_cast<webrtc::LocalMediaStreamInterface*>(native_streams->find(
- UTF16ToUTF8(streams[i].label())));
- DCHECK(stream);
- native_peer_connection_->RemoveStream(stream);
- }
+ // Not used by ROAP PeerConnection.
+ NOTREACHED();
}
void PeerConnectionHandler::OnAddStreamCallback(
@@ -227,40 +170,3 @@ void PeerConnectionHandler::OnRemoveStreamCallback(
remote_streams_.erase(it);
client_->didRemoveRemoteStream(descriptor);
}
-
-WebKit::WebMediaStreamDescriptor
-PeerConnectionHandler::CreateWebKitStreamDescriptor(
- webrtc::MediaStreamInterface* stream) {
- webrtc::AudioTracks* audio_tracks = stream->audio_tracks();
- webrtc::VideoTracks* video_tracks = stream->video_tracks();
- WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector(
- audio_tracks->count() + video_tracks->count());
-
- // Add audio tracks.
- size_t i = 0;
- for (; i < audio_tracks->count(); ++i) {
- webrtc::AudioTrackInterface* audio_track = audio_tracks->at(i);
- DCHECK(audio_track);
- source_vector[i].initialize(
- // TODO(grunell): Set id to something unique.
- UTF8ToUTF16(audio_track->label()),
- WebKit::WebMediaStreamSource::TypeAudio,
- UTF8ToUTF16(audio_track->label()));
- }
-
- // Add video tracks.
- for (i = 0; i < video_tracks->count(); ++i) {
- webrtc::VideoTrackInterface* video_track = video_tracks->at(i);
- DCHECK(video_track);
- source_vector[audio_tracks->count() + i].initialize(
- // TODO(grunell): Set id to something unique.
- UTF8ToUTF16(video_track->label()),
- WebKit::WebMediaStreamSource::TypeVideo,
- UTF8ToUTF16(video_track->label()));
- }
-
- WebKit::WebMediaStreamDescriptor descriptor;
- descriptor.initialize(UTF8ToUTF16(stream->label()), source_vector);
-
- return descriptor;
-}
diff --git a/content/renderer/media/peer_connection_handler.h b/content/renderer/media/peer_connection_handler.h
index aa969a1..e9a50e8 100644
--- a/content/renderer/media/peer_connection_handler.h
+++ b/content/renderer/media/peer_connection_handler.h
@@ -5,28 +5,21 @@
#ifndef CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_H_
#define CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_H_
-#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop_proxy.h"
#include "content/common/content_export.h"
-#include "third_party/libjingle/source/talk/app/webrtc/mediastream.h"
-#include "third_party/libjingle/source/talk/app/webrtc/peerconnection.h"
+#include "content/renderer/media/peer_connection_handler_base.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnectionHandler.h"
-class MediaStreamDependencyFactory;
-class MediaStreamImpl;
-
-// PeerConnectionHandler is a delegate for the PeerConnection API messages going
-// between WebKit and native PeerConnection in libjingle. It's owned by
-// WebKit.
+// PeerConnectionHandler is a delegate for the ROAP PeerConnection API messages
+// going between WebKit and native PeerConnection in libjingle. It's owned by
+// WebKit. ROAP PeerConnection will be removed soon.
class CONTENT_EXPORT PeerConnectionHandler
- : NON_EXPORTED_BASE(public WebKit::WebPeerConnectionHandler),
- NON_EXPORTED_BASE(public webrtc::PeerConnectionObserver) {
+ : public PeerConnectionHandlerBase,
+ NON_EXPORTED_BASE(public WebKit::WebPeerConnectionHandler) {
public:
PeerConnectionHandler(
WebKit::WebPeerConnectionHandlerClient* client,
@@ -34,11 +27,6 @@ class CONTENT_EXPORT PeerConnectionHandler
MediaStreamDependencyFactory* dependency_factory);
virtual ~PeerConnectionHandler();
- // Set the video renderer for the specified stream.
- virtual void SetVideoRenderer(
- const std::string& stream_label,
- webrtc::VideoRendererWrapperInterface* renderer);
-
// WebKit::WebPeerConnectionHandler implementation
virtual void initialize(
const WebKit::WebString& server_configuration,
@@ -71,37 +59,12 @@ class CONTENT_EXPORT PeerConnectionHandler
private:
FRIEND_TEST_ALL_PREFIXES(PeerConnectionHandlerTest, Basic);
- void AddStreams(
- const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>& streams);
- void RemoveStreams(
- const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>& streams);
void OnAddStreamCallback(webrtc::MediaStreamInterface* stream);
void OnRemoveStreamCallback(webrtc::MediaStreamInterface* stream);
- WebKit::WebMediaStreamDescriptor CreateWebKitStreamDescriptor(
- webrtc::MediaStreamInterface* stream);
// client_ is a weak pointer, and is valid until stop() has returned.
WebKit::WebPeerConnectionHandlerClient* client_;
- // media_stream_impl_ is a weak pointer, and is valid for the lifetime of this
- // class. Calls to it must be done on the render thread.
- MediaStreamImpl* media_stream_impl_;
-
- // dependency_factory_ is a weak pointer, and is valid for the lifetime of
- // MediaStreamImpl.
- MediaStreamDependencyFactory* dependency_factory_;
-
- // native_peer_connection_ is the native PeerConnection object,
- // it handles the ICE processing and media engine.
- talk_base::scoped_refptr<webrtc::PeerConnectionInterface>
- native_peer_connection_;
-
- typedef std::map<webrtc::MediaStreamInterface*,
- WebKit::WebMediaStreamDescriptor> RemoteStreamMap;
- RemoteStreamMap remote_streams_;
-
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
-
DISALLOW_COPY_AND_ASSIGN(PeerConnectionHandler);
};
diff --git a/content/renderer/media/peer_connection_handler_base.cc b/content/renderer/media/peer_connection_handler_base.cc
new file mode 100644
index 0000000..cf82ffe
--- /dev/null
+++ b/content/renderer/media/peer_connection_handler_base.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/peer_connection_handler_base.h"
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "content/renderer/media/media_stream_dependency_factory.h"
+#include "content/renderer/media/media_stream_impl.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"
+
+PeerConnectionHandlerBase::PeerConnectionHandlerBase(
+ MediaStreamImpl* msi,
+ MediaStreamDependencyFactory* dependency_factory)
+ : media_stream_impl_(msi),
+ dependency_factory_(dependency_factory),
+ message_loop_proxy_(base::MessageLoopProxy::current()) {
+}
+
+PeerConnectionHandlerBase::~PeerConnectionHandlerBase() {
+}
+
+bool PeerConnectionHandlerBase::HasStream(const std::string& stream_label) {
+ webrtc::MediaStreamInterface* stream =
+ native_peer_connection_->remote_streams()->find(stream_label);
+ return stream != NULL;
+}
+
+void PeerConnectionHandlerBase::SetVideoRenderer(
+ const std::string& stream_label,
+ webrtc::VideoRendererWrapperInterface* renderer) {
+ webrtc::MediaStreamInterface* stream =
+ native_peer_connection_->remote_streams()->find(stream_label);
+ webrtc::VideoTracks* video_tracks = stream->video_tracks();
+ // We assume there is only one enabled video track.
+ for (size_t i = 0; i < video_tracks->count(); ++i) {
+ webrtc::VideoTrackInterface* video_track = video_tracks->at(i);
+ if (video_track->enabled()) {
+ video_track->SetRenderer(renderer);
+ return;
+ }
+ }
+ DVLOG(1) << "No enabled video track.";
+}
+
+void PeerConnectionHandlerBase::AddStream(
+ const WebKit::WebMediaStreamDescriptor& stream) {
+ talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface> native_stream =
+ dependency_factory_->CreateLocalMediaStream(UTF16ToUTF8(stream.label()));
+ WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector;
+ stream.sources(source_vector);
+
+ // Get and add all tracks.
+ for (size_t i = 0; i < source_vector.size(); ++i) {
+ webrtc::MediaStreamTrackInterface* track = media_stream_impl_
+ ->GetLocalMediaStreamTrack(UTF16ToUTF8(source_vector[i].id()));
+ DCHECK(track);
+ if (source_vector[i].type() == WebKit::WebMediaStreamSource::TypeVideo) {
+ native_stream->AddTrack(static_cast<webrtc::VideoTrackInterface*>(track));
+ } else {
+ DCHECK(source_vector[i].type() ==
+ WebKit::WebMediaStreamSource::TypeAudio);
+ native_stream->AddTrack(static_cast<webrtc::AudioTrackInterface*>(track));
+ }
+ }
+
+ native_peer_connection_->AddStream(native_stream);
+}
+
+void PeerConnectionHandlerBase::RemoveStream(
+ const WebKit::WebMediaStreamDescriptor& stream) {
+ talk_base::scoped_refptr<webrtc::StreamCollectionInterface> native_streams =
+ native_peer_connection_->local_streams();
+ if (!native_streams)
+ return;
+ // TODO(perkj): Change libJingle PeerConnection::RemoveStream API to take a
+ // label as input instead of stream and return bool.
+ webrtc::LocalMediaStreamInterface* native_stream =
+ static_cast<webrtc::LocalMediaStreamInterface*>(native_streams->find(
+ UTF16ToUTF8(stream.label())));
+ DCHECK(native_stream);
+ native_peer_connection_->RemoveStream(native_stream);
+}
+
+WebKit::WebMediaStreamDescriptor
+PeerConnectionHandlerBase::CreateWebKitStreamDescriptor(
+ webrtc::MediaStreamInterface* stream) {
+ webrtc::AudioTracks* audio_tracks = stream->audio_tracks();
+ webrtc::VideoTracks* video_tracks = stream->video_tracks();
+ WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector(
+ audio_tracks->count() + video_tracks->count());
+
+ // Add audio tracks.
+ size_t i = 0;
+ for (; i < audio_tracks->count(); ++i) {
+ webrtc::AudioTrackInterface* audio_track = audio_tracks->at(i);
+ DCHECK(audio_track);
+ source_vector[i].initialize(
+ // TODO(grunell): Set id to something unique.
+ UTF8ToUTF16(audio_track->label()),
+ WebKit::WebMediaStreamSource::TypeAudio,
+ UTF8ToUTF16(audio_track->label()));
+ }
+
+ // Add video tracks.
+ for (i = 0; i < video_tracks->count(); ++i) {
+ webrtc::VideoTrackInterface* video_track = video_tracks->at(i);
+ DCHECK(video_track);
+ source_vector[audio_tracks->count() + i].initialize(
+ // TODO(grunell): Set id to something unique.
+ UTF8ToUTF16(video_track->label()),
+ WebKit::WebMediaStreamSource::TypeVideo,
+ UTF8ToUTF16(video_track->label()));
+ }
+
+ WebKit::WebMediaStreamDescriptor descriptor;
+ descriptor.initialize(UTF8ToUTF16(stream->label()), source_vector);
+
+ return descriptor;
+}
diff --git a/content/renderer/media/peer_connection_handler_base.h b/content/renderer/media/peer_connection_handler_base.h
new file mode 100644
index 0000000..4ae027f
--- /dev/null
+++ b/content/renderer/media/peer_connection_handler_base.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_BASE_H_
+#define CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_BASE_H_
+
+#include <map>
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop_proxy.h"
+#include "content/common/content_export.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediastream.h"
+#include "third_party/libjingle/source/talk/app/webrtc/peerconnection.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamDescriptor.h"
+
+class MediaStreamDependencyFactory;
+class MediaStreamImpl;
+
+// PeerConnectionHandlerBase is the base class of a delegate for the
+// PeerConnection (JSEP or ROAP) API messages going between WebKit and native
+// PeerConnection in libjingle. ROAP PeerConnection will be removed soon.
+class CONTENT_EXPORT PeerConnectionHandlerBase
+ : NON_EXPORTED_BASE(public webrtc::PeerConnectionObserver) {
+ public:
+ PeerConnectionHandlerBase(
+ MediaStreamImpl* msi,
+ MediaStreamDependencyFactory* dependency_factory);
+
+ // Checks if a remote stream belongs to this PeerConnection.
+ virtual bool HasStream(const std::string& stream_label);
+
+ // Set the video renderer for the specified stream.
+ virtual void SetVideoRenderer(
+ const std::string& stream_label,
+ webrtc::VideoRendererWrapperInterface* renderer);
+
+ protected:
+ virtual ~PeerConnectionHandlerBase();
+
+ void AddStream(const WebKit::WebMediaStreamDescriptor& stream);
+ void RemoveStream(const WebKit::WebMediaStreamDescriptor& stream);
+ WebKit::WebMediaStreamDescriptor CreateWebKitStreamDescriptor(
+ webrtc::MediaStreamInterface* stream);
+
+ // media_stream_impl_ is a raw pointer, and is valid for the lifetime of this
+ // class. Calls to it must be done on the render thread.
+ MediaStreamImpl* media_stream_impl_;
+
+ // dependency_factory_ is a raw pointer, and is valid for the lifetime of
+ // MediaStreamImpl.
+ MediaStreamDependencyFactory* dependency_factory_;
+
+ // native_peer_connection_ is the native PeerConnection object,
+ // it handles the ICE processing and media engine.
+ talk_base::scoped_refptr<webrtc::PeerConnectionInterface>
+ native_peer_connection_;
+
+ typedef std::map<webrtc::MediaStreamInterface*,
+ WebKit::WebMediaStreamDescriptor> RemoteStreamMap;
+ RemoteStreamMap remote_streams_;
+
+ // The message loop we are created on and on which to make calls to WebKit.
+ // This should be the render thread message loop.
+ scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(PeerConnectionHandlerBase);
+};
+
+#endif // CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_BASE_H_
diff --git a/content/renderer/media/peer_connection_handler_jsep.cc b/content/renderer/media/peer_connection_handler_jsep.cc
new file mode 100644
index 0000000..b524abe
--- /dev/null
+++ b/content/renderer/media/peer_connection_handler_jsep.cc
@@ -0,0 +1,368 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/peer_connection_handler_jsep.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
+#include "content/renderer/media/media_stream_dependency_factory.h"
+#include "content/renderer/media/media_stream_impl.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICECandidateDescriptor.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICEOptions.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnection00HandlerClient.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaHints.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/WebSessionDescriptionDescriptor.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
+
+PeerConnectionHandlerJsep::PeerConnectionHandlerJsep(
+ WebKit::WebPeerConnection00HandlerClient* client,
+ MediaStreamImpl* msi,
+ MediaStreamDependencyFactory* dependency_factory)
+ : PeerConnectionHandlerBase(msi, dependency_factory),
+ client_(client) {
+}
+
+PeerConnectionHandlerJsep::~PeerConnectionHandlerJsep() {
+}
+
+void PeerConnectionHandlerJsep::initialize(
+ const WebKit::WebString& server_configuration,
+ const WebKit::WebString& username) {
+ native_peer_connection_ = dependency_factory_->CreatePeerConnection(
+ UTF16ToUTF8(server_configuration),
+ this);
+ CHECK(native_peer_connection_);
+}
+
+WebKit::WebSessionDescriptionDescriptor PeerConnectionHandlerJsep::createOffer(
+ const WebKit::WebMediaHints& hints) {
+ WebKit::WebSessionDescriptionDescriptor offer;
+
+ webrtc::MediaHints native_hints(hints.audio(), hints.video());
+ scoped_ptr<webrtc::SessionDescriptionInterface> native_offer(
+ native_peer_connection_->CreateOffer(native_hints));
+ if (!native_offer.get()) {
+ LOG(ERROR) << "Failed to create native offer";
+ return offer;
+ }
+
+ offer = CreateWebKitSessionDescription(native_offer.get());
+ return offer;
+}
+
+WebKit::WebSessionDescriptionDescriptor PeerConnectionHandlerJsep::createAnswer(
+ const WebKit::WebString& offer,
+ const WebKit::WebMediaHints& hints) {
+ WebKit::WebSessionDescriptionDescriptor answer;
+
+ webrtc::MediaHints native_hints(hints.audio(), hints.video());
+ scoped_ptr<webrtc::SessionDescriptionInterface> native_offer(
+ dependency_factory_->CreateSessionDescription(UTF16ToUTF8(offer)));
+ if (!native_offer.get()) {
+ LOG(ERROR) << "Failed to create native offer";
+ return answer;
+ }
+
+ scoped_ptr<webrtc::SessionDescriptionInterface> native_answer(
+ native_peer_connection_->CreateAnswer(native_hints, native_offer.get()));
+ if (!native_answer.get()) {
+ LOG(ERROR) << "Failed to create native answer";
+ return answer;
+ }
+
+ answer = CreateWebKitSessionDescription(native_answer.get());
+ return answer;
+}
+
+bool PeerConnectionHandlerJsep::setLocalDescription(
+ Action action,
+ const WebKit::WebSessionDescriptionDescriptor& description) {
+ webrtc::PeerConnectionInterface::Action native_action;
+ if (!GetNativeAction(action, &native_action))
+ return false;
+
+ webrtc::SessionDescriptionInterface* native_desc =
+ CreateNativeSessionDescription(description);
+ if (!native_desc)
+ return false;
+
+ return native_peer_connection_->SetLocalDescription(native_action,
+ native_desc);
+}
+
+bool PeerConnectionHandlerJsep::setRemoteDescription(
+ Action action,
+ const WebKit::WebSessionDescriptionDescriptor& description) {
+ webrtc::PeerConnectionInterface::Action native_action;
+ if (!GetNativeAction(action, &native_action))
+ return false;
+
+ webrtc::SessionDescriptionInterface* native_desc =
+ CreateNativeSessionDescription(description);
+ if (!native_desc)
+ return false;
+
+ return native_peer_connection_->SetRemoteDescription(native_action,
+ native_desc);
+}
+
+WebKit::WebSessionDescriptionDescriptor
+PeerConnectionHandlerJsep::localDescription() {
+ const webrtc::SessionDescriptionInterface* native_desc =
+ native_peer_connection_->local_description();
+ WebKit::WebSessionDescriptionDescriptor description =
+ CreateWebKitSessionDescription(native_desc);
+ return description;
+}
+
+WebKit::WebSessionDescriptionDescriptor
+PeerConnectionHandlerJsep::remoteDescription() {
+ const webrtc::SessionDescriptionInterface* native_desc =
+ native_peer_connection_->remote_description();
+ WebKit::WebSessionDescriptionDescriptor description =
+ CreateWebKitSessionDescription(native_desc);
+ return description;
+}
+
+bool PeerConnectionHandlerJsep::startIce(const WebKit::WebICEOptions& options) {
+ webrtc::PeerConnectionInterface::IceOptions native_options;
+ switch (options.candidateTypeToUse()) {
+ case WebKit::WebICEOptions::CandidateTypeAll:
+ native_options = webrtc::PeerConnectionInterface::kUseAll;
+ break;
+ case WebKit::WebICEOptions::CandidateTypeNoRelay:
+ native_options = webrtc::PeerConnectionInterface::kNoRelay;
+ break;
+ case WebKit::WebICEOptions::CandidateTypeOnlyRelay:
+ native_options = webrtc::PeerConnectionInterface::kOnlyRelay;
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+ native_peer_connection_->StartIce(native_options);
+ return true;
+}
+
+bool PeerConnectionHandlerJsep::processIceMessage(
+ const WebKit::WebICECandidateDescriptor& candidate) {
+ scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
+ dependency_factory_->CreateIceCandidate(
+ UTF16ToUTF8(candidate.label()),
+ UTF16ToUTF8(candidate.candidateLine())));
+ if (!native_candidate.get()) {
+ LOG(ERROR) << "Could not create native ICE candidate";
+ return false;
+ }
+
+ bool return_value =
+ native_peer_connection_->ProcessIceMessage(native_candidate.get());
+ if (!return_value)
+ LOG(ERROR) << "Error processing ICE message";
+ return return_value;
+}
+
+void PeerConnectionHandlerJsep::addStream(
+ const WebKit::WebMediaStreamDescriptor& stream) {
+ AddStream(stream);
+ native_peer_connection_->CommitStreamChanges();
+}
+
+void PeerConnectionHandlerJsep::removeStream(
+ const WebKit::WebMediaStreamDescriptor& stream) {
+ RemoveStream(stream);
+ native_peer_connection_->CommitStreamChanges();
+}
+
+void PeerConnectionHandlerJsep::stop() {
+ // TODO(ronghuawu): There's an issue with signaling messages being sent during
+ // close. We need to investigate further. Not calling Close() on native
+ // PeerConnection is OK for now.
+ native_peer_connection_ = NULL;
+ media_stream_impl_->ClosePeerConnection(this);
+}
+
+void PeerConnectionHandlerJsep::OnError() {
+ // TODO(grunell): Implement.
+ NOTIMPLEMENTED();
+}
+
+void PeerConnectionHandlerJsep::OnMessage(const std::string& msg) {
+ // TODO(grunell): Implement.
+ NOTIMPLEMENTED();
+}
+
+void PeerConnectionHandlerJsep::OnSignalingMessage(const std::string& msg) {
+ // Not used by JSEP PeerConnection.
+ NOTREACHED();
+}
+
+void PeerConnectionHandlerJsep::OnStateChange(StateType state_changed) {
+ switch (state_changed) {
+ case kReadyState:
+ WebKit::WebPeerConnection00HandlerClient::ReadyState ready_state;
+ switch (native_peer_connection_->ready_state()) {
+ case webrtc::PeerConnectionInterface::kNew:
+ ready_state = WebKit::WebPeerConnection00HandlerClient::ReadyStateNew;
+ break;
+ case webrtc::PeerConnectionInterface::kNegotiating:
+ ready_state =
+ WebKit::WebPeerConnection00HandlerClient::ReadyStateNegotiating;
+ break;
+ case webrtc::PeerConnectionInterface::kActive:
+ ready_state =
+ WebKit::WebPeerConnection00HandlerClient::ReadyStateActive;
+ break;
+ case webrtc::PeerConnectionInterface::kClosing:
+ // Not used by JSEP.
+ NOTREACHED();
+ return;
+ case webrtc::PeerConnectionInterface::kClosed:
+ ready_state =
+ WebKit::WebPeerConnection00HandlerClient::ReadyStateClosed;
+ break;
+ default:
+ NOTREACHED();
+ return;
+ }
+ client_->didChangeReadyState(ready_state);
+ break;
+ case kIceState:
+ // TODO(grunell): Implement when available in native PeerConnection.
+ NOTIMPLEMENTED();
+ break;
+ case kSdpState:
+ // Not used by JSEP.
+ NOTREACHED();
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void PeerConnectionHandlerJsep::OnAddStream(
+ webrtc::MediaStreamInterface* stream) {
+ if (!stream)
+ return;
+
+ DCHECK(remote_streams_.find(stream) == remote_streams_.end());
+ WebKit::WebMediaStreamDescriptor descriptor =
+ CreateWebKitStreamDescriptor(stream);
+ remote_streams_.insert(
+ std::pair<webrtc::MediaStreamInterface*,
+ WebKit::WebMediaStreamDescriptor>(stream, descriptor));
+ client_->didAddRemoteStream(descriptor);
+}
+
+void PeerConnectionHandlerJsep::OnRemoveStream(
+ webrtc::MediaStreamInterface* stream) {
+ if (!stream)
+ return;
+
+ RemoteStreamMap::iterator it = remote_streams_.find(stream);
+ if (it == remote_streams_.end()) {
+ NOTREACHED() << "Stream not found";
+ return;
+ }
+ WebKit::WebMediaStreamDescriptor descriptor = it->second;
+ DCHECK(!descriptor.isNull());
+ remote_streams_.erase(it);
+ client_->didRemoveRemoteStream(descriptor);
+}
+
+void PeerConnectionHandlerJsep::OnIceCandidate(
+ const webrtc::IceCandidateInterface* candidate) {
+ WebKit::WebICECandidateDescriptor web_candidate;
+
+ std::string label = candidate->label();
+ std::string sdp;
+ if (!candidate->ToString(&sdp)) {
+ LOG(ERROR) << "Could not get SDP string";
+ return;
+ }
+
+ web_candidate.initialize(UTF8ToUTF16(label), UTF8ToUTF16(sdp));
+
+ // moreToFollow parameter isn't supported in native PeerConnection, so we
+ // always use true here, and then false in OnIceComplete().
+ client_->didGenerateICECandidate(web_candidate, true);
+}
+
+void PeerConnectionHandlerJsep::OnIceComplete() {
+ // moreToFollow parameter isn't supported in native PeerConnection, so we
+ // send an empty WebIseCandidate with moreToFollow=false.
+ WebKit::WebICECandidateDescriptor web_candidate;
+ client_->didGenerateICECandidate(web_candidate, false);
+}
+
+webrtc::SessionDescriptionInterface*
+PeerConnectionHandlerJsep::CreateNativeSessionDescription(
+ const WebKit::WebSessionDescriptionDescriptor& description) {
+ std::string initial_sdp = UTF16ToUTF8(description.initialSDP());
+ webrtc::SessionDescriptionInterface* native_desc =
+ dependency_factory_->CreateSessionDescription(initial_sdp);
+ if (!native_desc) {
+ LOG(ERROR) << "Failed to create native session description";
+ return NULL;
+ }
+
+ for (size_t i = 0; i < description.numberOfAddedCandidates(); ++i) {
+ WebKit::WebICECandidateDescriptor candidate = description.candidate(i);
+ scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
+ dependency_factory_->CreateIceCandidate(
+ UTF16ToUTF8(candidate.label()),
+ UTF16ToUTF8(candidate.candidateLine())));
+ if (!native_desc->AddCandidate(native_candidate.get()))
+ LOG(ERROR) << "Failed to add candidate to native session description";
+ }
+
+ return native_desc;
+}
+
+WebKit::WebSessionDescriptionDescriptor
+PeerConnectionHandlerJsep::CreateWebKitSessionDescription(
+ const webrtc::SessionDescriptionInterface* native_desc) {
+ WebKit::WebSessionDescriptionDescriptor description;
+ if (!native_desc) {
+ VLOG(1) << "Native session description is null";
+ return description;
+ }
+
+ std::string sdp;
+ if (!native_desc->ToString(&sdp)) {
+ LOG(ERROR) << "Failed to get SDP string of native session description";
+ return description;
+ }
+
+ description.initialize(UTF8ToUTF16(sdp));
+ return description;
+}
+
+bool PeerConnectionHandlerJsep::GetNativeAction(
+ const Action action,
+ webrtc::PeerConnectionInterface::Action* native_action) {
+ switch (action) {
+ case ActionSDPOffer:
+ *native_action = webrtc::PeerConnectionInterface::kOffer;
+ break;
+ case ActionSDPPRanswer:
+ VLOG(1) << "Action PRANSWER not supported yet";
+ return false;
+ case ActionSDPAnswer:
+ *native_action = webrtc::PeerConnectionInterface::kAnswer;
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+ return true;
+}
diff --git a/content/renderer/media/peer_connection_handler_jsep.h b/content/renderer/media/peer_connection_handler_jsep.h
new file mode 100644
index 0000000..463b05e
--- /dev/null
+++ b/content/renderer/media/peer_connection_handler_jsep.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_JSEP_H_
+#define CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_JSEP_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
+#include "content/common/content_export.h"
+#include "content/renderer/media/peer_connection_handler_base.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnection00Handler.h"
+
+// PeerConnectionHandlerJsep is a delegate for the JSEP PeerConnection API
+// messages going between WebKit and native PeerConnection in libjingle. It's
+// owned by WebKit.
+class CONTENT_EXPORT PeerConnectionHandlerJsep
+ : public PeerConnectionHandlerBase,
+ NON_EXPORTED_BASE(public WebKit::WebPeerConnection00Handler) {
+ public:
+ PeerConnectionHandlerJsep(
+ WebKit::WebPeerConnection00HandlerClient* client,
+ MediaStreamImpl* msi,
+ MediaStreamDependencyFactory* dependency_factory);
+ virtual ~PeerConnectionHandlerJsep();
+
+ // WebKit::WebPeerConnection00Handler implementation
+ virtual void initialize(
+ const WebKit::WebString& server_configuration,
+ const WebKit::WebString& username) OVERRIDE;
+ virtual WebKit::WebSessionDescriptionDescriptor createOffer(
+ const WebKit::WebMediaHints& hints) OVERRIDE;
+ virtual WebKit::WebSessionDescriptionDescriptor createAnswer(
+ const WebKit::WebString& offer,
+ const WebKit::WebMediaHints& hints) OVERRIDE;
+ virtual bool setLocalDescription(
+ Action action,
+ const WebKit::WebSessionDescriptionDescriptor& description) OVERRIDE;
+ virtual bool setRemoteDescription(
+ Action action,
+ const WebKit::WebSessionDescriptionDescriptor& description) OVERRIDE;
+ virtual WebKit::WebSessionDescriptionDescriptor localDescription() OVERRIDE;
+ virtual WebKit::WebSessionDescriptionDescriptor remoteDescription() OVERRIDE;
+ virtual bool startIce(const WebKit::WebICEOptions& options) OVERRIDE;
+ virtual bool processIceMessage(
+ const WebKit::WebICECandidateDescriptor& candidate) OVERRIDE;
+ virtual void addStream(
+ const WebKit::WebMediaStreamDescriptor& stream) OVERRIDE;
+ virtual void removeStream(
+ const WebKit::WebMediaStreamDescriptor& stream) OVERRIDE;
+ // We will be deleted by WebKit after stop has been returned.
+ virtual void stop() OVERRIDE;
+
+ // webrtc::PeerConnectionObserver implementation
+ virtual void OnError() OVERRIDE;
+ virtual void OnMessage(const std::string& msg) OVERRIDE;
+ virtual void OnSignalingMessage(const std::string& msg) OVERRIDE;
+ virtual void OnStateChange(StateType state_changed) OVERRIDE;
+ virtual void OnAddStream(webrtc::MediaStreamInterface* stream) OVERRIDE;
+ virtual void OnRemoveStream(webrtc::MediaStreamInterface* stream) OVERRIDE;
+ virtual void OnIceCandidate(
+ const webrtc::IceCandidateInterface* candidate) OVERRIDE;
+ virtual void OnIceComplete() OVERRIDE;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(PeerConnectionHandlerJsepTest, Basic);
+
+ webrtc::SessionDescriptionInterface* CreateNativeSessionDescription(
+ const WebKit::WebSessionDescriptionDescriptor& description);
+ WebKit::WebSessionDescriptionDescriptor CreateWebKitSessionDescription(
+ const webrtc::SessionDescriptionInterface* native_desc);
+ bool GetNativeAction(
+ const Action action,
+ webrtc::PeerConnectionInterface::Action* native_action);
+
+ // client_ is a weak pointer, and is valid until stop() has returned.
+ WebKit::WebPeerConnection00HandlerClient* client_;
+
+ DISALLOW_COPY_AND_ASSIGN(PeerConnectionHandlerJsep);
+};
+
+#endif // CONTENT_RENDERER_MEDIA_PEER_CONNECTION_HANDLER_JSEP_H_
diff --git a/content/renderer/media/peer_connection_handler_jsep_unittest.cc b/content/renderer/media/peer_connection_handler_jsep_unittest.cc
new file mode 100644
index 0000000..03f3eb6
--- /dev/null
+++ b/content/renderer/media/peer_connection_handler_jsep_unittest.cc
@@ -0,0 +1,231 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "base/utf_string_conversions.h"
+#include "content/renderer/media/mock_media_stream_dependency_factory.h"
+#include "content/renderer/media/mock_media_stream_impl.h"
+#include "content/renderer/media/mock_web_peer_connection_00_handler_client.h"
+#include "content/renderer/media/mock_peer_connection_impl.h"
+#include "content/renderer/media/peer_connection_handler_jsep.h"
+#include "content/renderer/media/rtc_video_decoder.h"
+#include "jingle/glue/thread_wrapper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libjingle/source/talk/app/webrtc/peerconnection.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICECandidateDescriptor.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICEOptions.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaHints.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/WebSessionDescriptionDescriptor.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
+
+namespace webrtc {
+
+class MockVideoRendererWrapper : public VideoRendererWrapperInterface {
+ public:
+ virtual cricket::VideoRenderer* renderer() OVERRIDE { return NULL; }
+
+ protected:
+ virtual ~MockVideoRendererWrapper() {}
+};
+
+} // namespace webrtc
+
+TEST(PeerConnectionHandlerJsepTest, Basic) {
+ MessageLoop loop;
+
+ scoped_ptr<WebKit::MockWebPeerConnection00HandlerClient> mock_client(
+ new WebKit::MockWebPeerConnection00HandlerClient());
+ scoped_refptr<MockMediaStreamImpl> mock_ms_impl(new MockMediaStreamImpl());
+ scoped_ptr<MockMediaStreamDependencyFactory> mock_dependency_factory(
+ new MockMediaStreamDependencyFactory());
+ mock_dependency_factory->CreatePeerConnectionFactory(NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ scoped_ptr<PeerConnectionHandlerJsep> pc_handler(
+ new PeerConnectionHandlerJsep(mock_client.get(),
+ mock_ms_impl.get(),
+ mock_dependency_factory.get()));
+
+ WebKit::WebString server_config(
+ WebKit::WebString::fromUTF8("STUN stun.l.google.com:19302"));
+ WebKit::WebString username;
+ pc_handler->initialize(server_config, username);
+ EXPECT_TRUE(pc_handler->native_peer_connection_.get());
+ webrtc::MockPeerConnectionImpl* mock_peer_connection =
+ static_cast<webrtc::MockPeerConnectionImpl*>(
+ pc_handler->native_peer_connection_.get());
+
+ // Create offer.
+ WebKit::WebMediaHints hints;
+ hints.initialize(true, true);
+ WebKit::WebSessionDescriptionDescriptor offer =
+ pc_handler->createOffer(hints);
+ EXPECT_FALSE(offer.isNull());
+ EXPECT_EQ(std::string(mock_peer_connection->kDummyOffer),
+ UTF16ToUTF8(offer.initialSDP()));
+ EXPECT_EQ(hints.audio(), mock_peer_connection->hint_audio());
+ EXPECT_EQ(hints.video(), mock_peer_connection->hint_video());
+
+ // Create answer.
+ WebKit::WebString offer_string = "offer";
+ hints.reset();
+ hints.initialize(false, false);
+ WebKit::WebSessionDescriptionDescriptor answer =
+ pc_handler->createAnswer(offer_string, hints);
+ EXPECT_FALSE(answer.isNull());
+ EXPECT_EQ(UTF16ToUTF8(offer_string), UTF16ToUTF8(answer.initialSDP()));
+ EXPECT_EQ(UTF16ToUTF8(offer_string), mock_peer_connection->description_sdp());
+ EXPECT_EQ(hints.audio(), mock_peer_connection->hint_audio());
+ EXPECT_EQ(hints.video(), mock_peer_connection->hint_video());
+
+ // Set local description.
+ PeerConnectionHandlerJsep::Action action =
+ PeerConnectionHandlerJsep::ActionSDPOffer;
+ WebKit::WebSessionDescriptionDescriptor description;
+ WebKit::WebString sdp = "test sdp";
+ description.initialize(sdp);
+ EXPECT_TRUE(pc_handler->setLocalDescription(action, description));
+ EXPECT_EQ(webrtc::PeerConnectionInterface::kOffer,
+ mock_peer_connection->action());
+ EXPECT_EQ(UTF16ToUTF8(sdp), mock_peer_connection->description_sdp());
+
+ // Get local description.
+ description.reset();
+ description = pc_handler->localDescription();
+ EXPECT_FALSE(description.isNull());
+ EXPECT_EQ(UTF16ToUTF8(sdp), UTF16ToUTF8(description.initialSDP()));
+
+ // Set remote description.
+ action = PeerConnectionHandlerJsep::ActionSDPAnswer;
+ sdp = "test sdp 2";
+ description.reset();
+ description.initialize(sdp);
+ EXPECT_TRUE(pc_handler->setRemoteDescription(action, description));
+ EXPECT_EQ(webrtc::PeerConnectionInterface::kAnswer,
+ mock_peer_connection->action());
+ EXPECT_EQ(UTF16ToUTF8(sdp), mock_peer_connection->description_sdp());
+
+ // Get remote description.
+ description.reset();
+ description = pc_handler->remoteDescription();
+ EXPECT_FALSE(description.isNull());
+ EXPECT_EQ(UTF16ToUTF8(sdp), UTF16ToUTF8(description.initialSDP()));
+
+ // Start ICE.
+ WebKit::WebICEOptions options;
+ options.initialize(WebKit::WebICEOptions::CandidateTypeAll);
+ EXPECT_TRUE(pc_handler->startIce(options));
+ EXPECT_EQ(webrtc::PeerConnectionInterface::kUseAll,
+ mock_peer_connection->ice_options());
+
+ // Process ICE message.
+ WebKit::WebICECandidateDescriptor candidate;
+ WebKit::WebString label = "test label";
+ sdp = "test sdp";
+ candidate.initialize(label, sdp);
+ EXPECT_TRUE(pc_handler->processIceMessage(candidate));
+ EXPECT_EQ(UTF16ToUTF8(label), mock_peer_connection->ice_label());
+ EXPECT_EQ(UTF16ToUTF8(sdp), mock_peer_connection->ice_sdp());
+
+ // Add stream.
+ // TODO(grunell): Add an audio track as well.
+ std::string stream_label("stream-label");
+ std::string video_track_label("video-label");
+ talk_base::scoped_refptr<webrtc::LocalVideoTrackInterface> local_video_track(
+ mock_dependency_factory->CreateLocalVideoTrack(video_track_label, NULL));
+ mock_ms_impl->AddTrack(video_track_label, local_video_track);
+ WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector(
+ static_cast<size_t>(1));
+ source_vector[0].initialize(WebKit::WebString::fromUTF8(video_track_label),
+ WebKit::WebMediaStreamSource::TypeVideo,
+ WebKit::WebString::fromUTF8("RemoteVideo"));
+ WebKit::WebMediaStreamDescriptor local_stream;
+ local_stream.initialize(UTF8ToUTF16(stream_label), source_vector);
+ pc_handler->addStream(local_stream);
+ EXPECT_EQ(stream_label, mock_peer_connection->stream_label());
+ EXPECT_TRUE(mock_peer_connection->stream_changes_committed());
+
+ // On add stream.
+ std::string remote_stream_label(stream_label);
+ remote_stream_label += "-remote";
+ std::string remote_video_track_label(video_track_label);
+ remote_video_track_label += "-remote";
+ // We use a local stream as a remote since for testing purposes we really
+ // only need the MediaStreamInterface.
+ talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface> remote_stream(
+ mock_dependency_factory->CreateLocalMediaStream(remote_stream_label));
+ talk_base::scoped_refptr<webrtc::LocalVideoTrackInterface> remote_video_track(
+ mock_dependency_factory->CreateLocalVideoTrack(remote_video_track_label,
+ NULL));
+ remote_video_track->set_enabled(true);
+ remote_stream->AddTrack(remote_video_track);
+ mock_peer_connection->AddRemoteStream(remote_stream);
+ pc_handler->OnAddStream(remote_stream);
+ EXPECT_EQ(remote_stream_label, mock_client->stream_label());
+
+ // Set renderer.
+ talk_base::scoped_refptr<webrtc::MockVideoRendererWrapper> renderer(
+ new talk_base::RefCountedObject<webrtc::MockVideoRendererWrapper>());
+ pc_handler->SetVideoRenderer(remote_stream_label, renderer);
+ EXPECT_EQ(renderer, static_cast<webrtc::MockLocalVideoTrack*>(
+ remote_video_track.get())->renderer());
+
+ // Remove stream.
+ WebKit::WebVector<WebKit::WebMediaStreamDescriptor> empty_streams(
+ static_cast<size_t>(0));
+ pc_handler->removeStream(local_stream);
+ EXPECT_EQ("", mock_peer_connection->stream_label());
+ mock_peer_connection->ClearStreamChangesCommitted();
+ EXPECT_TRUE(!mock_peer_connection->stream_changes_committed());
+
+ // On remove stream.
+ pc_handler->OnRemoveStream(remote_stream);
+ EXPECT_TRUE(mock_client->stream_label().empty());
+
+ // Add stream again.
+ pc_handler->addStream(local_stream);
+ EXPECT_EQ(stream_label, mock_peer_connection->stream_label());
+ EXPECT_TRUE(mock_peer_connection->stream_changes_committed());
+
+ // On state change.
+ mock_peer_connection->SetReadyState(webrtc::PeerConnectionInterface::kActive);
+ webrtc::PeerConnectionObserver::StateType state =
+ webrtc::PeerConnectionObserver::kReadyState;
+ pc_handler->OnStateChange(state);
+ EXPECT_EQ(WebKit::WebPeerConnection00HandlerClient::ReadyStateActive,
+ mock_client->ready_state());
+
+ // On ICE candidate.
+ std::string candidate_label = "test label";
+ std::string candidate_sdp = "test sdp";
+ webrtc::IceCandidateInterface* native_candidate =
+ mock_dependency_factory->CreateIceCandidate(candidate_label,
+ candidate_sdp);
+ pc_handler->OnIceCandidate(native_candidate);
+ EXPECT_EQ(candidate_label, mock_client->candidate_label());
+ EXPECT_EQ(candidate_sdp, mock_client->candidate_sdp());
+ EXPECT_TRUE(mock_client->more_to_follow());
+
+ // On ICE complete.
+ pc_handler->OnIceComplete();
+ EXPECT_TRUE(mock_client->candidate_label().empty());
+ EXPECT_TRUE(mock_client->candidate_sdp().empty());
+ EXPECT_FALSE(mock_client->more_to_follow());
+
+ // Stop.
+ pc_handler->stop();
+ EXPECT_FALSE(pc_handler->native_peer_connection_.get());
+
+ // PC handler is expected to be deleted when stop calls
+ // MediaStreamImpl::ClosePeerConnection. We own and delete it here instead of
+ // in the mock.
+ pc_handler.reset();
+}
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index b498938..c110235 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -137,6 +137,8 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebDragData.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsContext3D.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnection00Handler.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnection00HandlerClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnectionHandler.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPeerConnectionHandlerClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPoint.h"
@@ -228,6 +230,10 @@ using WebKit::WebNavigationType;
using WebKit::WebNode;
using WebKit::WebPageSerializer;
using WebKit::WebPageSerializerClient;
+using WebKit::WebPeerConnection00Handler;
+using WebKit::WebPeerConnection00HandlerClient;
+using WebKit::WebPeerConnectionHandler;
+using WebKit::WebPeerConnectionHandlerClient;
using WebKit::WebPlugin;
using WebKit::WebPluginAction;
using WebKit::WebPluginContainer;
@@ -644,17 +650,22 @@ RenderViewImpl* RenderViewImpl::Create(
guest);
}
-WebKit::WebPeerConnectionHandler* RenderViewImpl::CreatePeerConnectionHandler(
- WebKit::WebPeerConnectionHandlerClient* client) {
- const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
- if (!cmd_line->HasSwitch(switches::kEnableMediaStream))
- return NULL;
+WebPeerConnectionHandler* RenderViewImpl::CreatePeerConnectionHandler(
+ WebPeerConnectionHandlerClient* client) {
EnsureMediaStreamImpl();
if (!media_stream_impl_.get())
return NULL;
return media_stream_impl_->CreatePeerConnectionHandler(client);
}
+WebPeerConnection00Handler* RenderViewImpl::CreatePeerConnectionHandlerJsep(
+ WebPeerConnection00HandlerClient* client) {
+ EnsureMediaStreamImpl();
+ if (!media_stream_impl_.get())
+ return NULL;
+ return media_stream_impl_->CreatePeerConnectionHandlerJsep(client);
+}
+
void RenderViewImpl::AddObserver(RenderViewObserver* observer) {
observers_.AddObserver(observer);
}
@@ -3276,6 +3287,10 @@ void RenderViewImpl::CheckPreferredSize() {
}
void RenderViewImpl::EnsureMediaStreamImpl() {
+ const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
+ if (!cmd_line->HasSwitch(switches::kEnableMediaStream))
+ return;
+
#if defined(ENABLE_P2P_APIS)
if (!p2p_socket_dispatcher_)
p2p_socket_dispatcher_ = new content::P2PSocketDispatcher(this);
@@ -5144,9 +5159,6 @@ WebKit::WebPageVisibilityState RenderViewImpl::visibilityState() const {
}
WebKit::WebUserMediaClient* RenderViewImpl::userMediaClient() {
- const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
- if (!cmd_line->HasSwitch(switches::kEnableMediaStream))
- return NULL;
EnsureMediaStreamImpl();
return media_stream_impl_;
}
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index cacdcb2..432fe7ec 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -124,6 +124,8 @@ class WebDragData;
class WebGeolocationClient;
class WebIconURL;
class WebImage;
+class WebPeerConnection00Handler;
+class WebPeerConnection00HandlerClient;
class WebMediaPlayer;
class WebMediaPlayerClient;
class WebMouseEvent;
@@ -233,6 +235,8 @@ class RenderViewImpl : public RenderWidget,
WebKit::WebPeerConnectionHandler* CreatePeerConnectionHandler(
WebKit::WebPeerConnectionHandlerClient* client);
+ WebKit::WebPeerConnection00Handler* CreatePeerConnectionHandlerJsep(
+ WebKit::WebPeerConnection00HandlerClient* client);
// Functions to add and remove observers for this object.
void AddObserver(content::RenderViewObserver* observer);
diff --git a/content/renderer/renderer_webkitplatformsupport_impl.cc b/content/renderer/renderer_webkitplatformsupport_impl.cc
index 44e3e5c..2e94f71 100644
--- a/content/renderer/renderer_webkitplatformsupport_impl.cc
+++ b/content/renderer/renderer_webkitplatformsupport_impl.cc
@@ -89,6 +89,8 @@ using WebKit::WebIDBKeyPath;
using WebKit::WebKitPlatformSupport;
using WebKit::WebMediaStreamCenter;
using WebKit::WebMediaStreamCenterClient;
+using WebKit::WebPeerConnection00Handler;
+using WebKit::WebPeerConnection00HandlerClient;
using WebKit::WebPeerConnectionHandler;
using WebKit::WebPeerConnectionHandlerClient;
using WebKit::WebSerializedScriptValue;
@@ -726,6 +728,18 @@ RendererWebKitPlatformSupportImpl::createPeerConnectionHandler(
return render_view->CreatePeerConnectionHandler(client);
}
+WebPeerConnection00Handler*
+RendererWebKitPlatformSupportImpl::createPeerConnection00Handler(
+ WebPeerConnection00HandlerClient* client) {
+ WebFrame* web_frame = WebFrame::frameForCurrentContext();
+ if (!web_frame)
+ return NULL;
+ RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_frame->view());
+ if (!render_view)
+ return NULL;
+ return render_view->CreatePeerConnectionHandlerJsep(client);
+}
+
//------------------------------------------------------------------------------
WebMediaStreamCenter*
diff --git a/content/renderer/renderer_webkitplatformsupport_impl.h b/content/renderer/renderer_webkitplatformsupport_impl.h
index 3b8bd2d..43e202dd 100644
--- a/content/renderer/renderer_webkitplatformsupport_impl.h
+++ b/content/renderer/renderer_webkitplatformsupport_impl.h
@@ -95,6 +95,8 @@ class CONTENT_EXPORT RendererWebKitPlatformSupportImpl
std::vector<webkit::WebPluginInfo>* plugins) OVERRIDE;
virtual WebKit::WebPeerConnectionHandler* createPeerConnectionHandler(
WebKit::WebPeerConnectionHandlerClient* client) OVERRIDE;
+ virtual WebKit::WebPeerConnection00Handler* createPeerConnection00Handler(
+ WebKit::WebPeerConnection00HandlerClient* client) OVERRIDE;
virtual WebKit::WebMediaStreamCenter* createMediaStreamCenter(
WebKit::WebMediaStreamCenterClient* client) OVERRIDE;