diff options
author | perkj@chromium.org <perkj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-13 14:04:54 +0000 |
---|---|---|
committer | perkj@chromium.org <perkj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-13 14:04:54 +0000 |
commit | f2be130d5f3bfa2ff258203f10f839dfd6f75ddf (patch) | |
tree | 52e7855bce69772627c07ba3fd48bf31cd5fcfbe /content/renderer/media | |
parent | 8f0173231670e57f2ba57bba6fcb9d9591f80f00 (diff) | |
download | chromium_src-f2be130d5f3bfa2ff258203f10f839dfd6f75ddf.zip chromium_src-f2be130d5f3bfa2ff258203f10f839dfd6f75ddf.tar.gz chromium_src-f2be130d5f3bfa2ff258203f10f839dfd6f75ddf.tar.bz2 |
Glue code for hooking up PeerConnection DataChannels.
Note: This cl is dependent on a libjingle roll and an updated WebKit version.
WebRtc issue http://code.google.com/p/webrtc/issues/detail?id=876
BUG= 165426
TEST= manual test with the test page in https://codereview.chromium.org/11316187/
Review URL: https://chromiumcodereview.appspot.com/11411195
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@172875 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/media')
7 files changed, 257 insertions, 7 deletions
diff --git a/content/renderer/media/mock_peer_connection_impl.cc b/content/renderer/media/mock_peer_connection_impl.cc index d64214e..602c034 100644 --- a/content/renderer/media/mock_peer_connection_impl.cc +++ b/content/renderer/media/mock_peer_connection_impl.cc @@ -57,6 +57,56 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface { StreamVector streams_; }; +class MockDataChannel : public webrtc::DataChannelInterface { + public: + MockDataChannel(const std::string& label, + const webrtc::DataChannelInit* config) + : label_(label), + reliable_(config->reliable), + state_(webrtc::DataChannelInterface::kConnecting) { + } + + virtual void RegisterObserver( + webrtc::DataChannelObserver* observer) OVERRIDE { + } + + virtual void UnregisterObserver() OVERRIDE { + } + + virtual const std::string& label() const OVERRIDE { + return label_; + } + + virtual bool reliable() const OVERRIDE { + return reliable_; + } + + virtual DataState state() const OVERRIDE { + return state_; + } + + virtual uint64 buffered_amount() const OVERRIDE { + NOTIMPLEMENTED(); + return 0; + } + + virtual void Close() OVERRIDE { + state_ = webrtc::DataChannelInterface::kClosing; + } + + virtual bool Send(const webrtc::DataBuffer& buffer) OVERRIDE { + return state_ == webrtc::DataChannelInterface::kOpen; + } + + protected: + ~MockDataChannel() {} + + private: + std::string label_; + bool reliable_; + webrtc::DataChannelInterface::DataState state_; +}; + const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer"; const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer"; @@ -118,11 +168,9 @@ bool MockPeerConnectionImpl::SendDtmf( } talk_base::scoped_refptr<webrtc::DataChannelInterface> -MockPeerConnectionImpl::CreateDataChannel( - const std::string& label, - const webrtc::DataChannelInit* config) { - NOTIMPLEMENTED(); - return NULL; +MockPeerConnectionImpl::CreateDataChannel(const std::string& label, + const webrtc::DataChannelInit* config) { + return new talk_base::RefCountedObject<MockDataChannel>(label, config); } bool MockPeerConnectionImpl::GetStats( diff --git a/content/renderer/media/mock_peer_connection_impl.h b/content/renderer/media/mock_peer_connection_impl.h index 163c608..626786b 100644 --- a/content/renderer/media/mock_peer_connection_impl.h +++ b/content/renderer/media/mock_peer_connection_impl.h @@ -36,8 +36,9 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface { const std::string& tones, int duration, const webrtc::AudioTrackInterface* play_track) OVERRIDE; virtual talk_base::scoped_refptr<webrtc::DataChannelInterface> - CreateDataChannel(const std::string& label, - const webrtc::DataChannelInit* config) OVERRIDE; + CreateDataChannel(const std::string& label, + const webrtc::DataChannelInit* config) OVERRIDE; + virtual bool GetStats(webrtc::StatsObserver* observer, webrtc::MediaStreamTrackInterface* track) OVERRIDE; virtual ReadyState ready_state() OVERRIDE; diff --git a/content/renderer/media/rtc_data_channel_handler.cc b/content/renderer/media/rtc_data_channel_handler.cc new file mode 100644 index 0000000..4b0006a --- /dev/null +++ b/content/renderer/media/rtc_data_channel_handler.cc @@ -0,0 +1,110 @@ +// 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/rtc_data_channel_handler.h" + +#include <string> + +#include "base/logging.h" +#include "base/utf_string_conversions.h" + +namespace content { + +RtcDataChannelHandler::RtcDataChannelHandler( + webrtc::DataChannelInterface* channel) + : channel_(channel), + webkit_client_(NULL) { + DVLOG(1) << "::ctor"; + channel_->RegisterObserver(this); +} + +RtcDataChannelHandler::~RtcDataChannelHandler() { + DVLOG(1) << "::dtor"; + channel_->UnregisterObserver(); +} + +void RtcDataChannelHandler::setClient( + WebKit::WebRTCDataChannelHandlerClient* client) { + webkit_client_ = client; +} + +WebKit::WebString RtcDataChannelHandler::label() { + return UTF8ToUTF16(channel_->label()); +} + +bool RtcDataChannelHandler::isReliable() { + return channel_->reliable(); +} + +unsigned long RtcDataChannelHandler::bufferedAmount() { + return channel_->buffered_amount(); +} + +bool RtcDataChannelHandler::sendStringData(const WebKit::WebString& data) { + std::string utf8_buffer = UTF16ToUTF8(data); + webrtc::DataBuffer buffer; + buffer.binary = false; + buffer.data.SetData(utf8_buffer.c_str(), utf8_buffer.length()); + return channel_->Send(buffer); +} + +bool RtcDataChannelHandler::sendRawData(const char* data, size_t length) { + webrtc::DataBuffer buffer; + buffer.data.SetData(data, length); + buffer.binary = true; + return channel_->Send(buffer); +} + +void RtcDataChannelHandler::close() { + channel_->Close(); +} + +void RtcDataChannelHandler::OnStateChange() { + if (!webkit_client_) { + LOG(ERROR) << "WebRTCDataChannelHandlerClient not set."; + return; + } + DVLOG(1) << "OnStateChange " << channel_->state(); + switch (channel_->state()) { + case webrtc::DataChannelInterface::kConnecting: + webkit_client_->didChangeReadyState( + WebKit::WebRTCDataChannelHandlerClient::ReadyStateConnecting); + break; + case webrtc::DataChannelInterface::kOpen: + webkit_client_->didChangeReadyState( + WebKit::WebRTCDataChannelHandlerClient::ReadyStateOpen); + break; + case webrtc::DataChannelInterface::kClosing: + webkit_client_->didChangeReadyState( + WebKit::WebRTCDataChannelHandlerClient::ReadyStateClosing); + break; + case webrtc::DataChannelInterface::kClosed: + webkit_client_->didChangeReadyState( + WebKit::WebRTCDataChannelHandlerClient::ReadyStateClosed); + break; + default: + NOTREACHED(); + break; + } +} + +void RtcDataChannelHandler::OnMessage(const webrtc::DataBuffer& buffer) { + if (!webkit_client_) { + LOG(ERROR) << "WebRTCDataChannelHandlerClient not set."; + return; + } + + if (buffer.binary) { + webkit_client_->didReceiveRawData(buffer.data.data(), buffer.data.length()); + } else { + string16 utf16; + if (!UTF8ToUTF16(buffer.data.data(), buffer.data.length(), &utf16)) { + LOG(ERROR) << "Failed convert received data to UTF16"; + return; + } + webkit_client_->didReceiveStringData(utf16); + } +} + +} // namespace content diff --git a/content/renderer/media/rtc_data_channel_handler.h b/content/renderer/media/rtc_data_channel_handler.h new file mode 100644 index 0000000..2047ffe --- /dev/null +++ b/content/renderer/media/rtc_data_channel_handler.h @@ -0,0 +1,52 @@ +// 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_RTC_DATA_CHANNEL_HANDLER_H_ +#define CONTENT_RENDERER_MEDIA_RTC_DATA_CHANNEL_HANDLER_H_ + +#include "base/memory/ref_counted.h" +#include "base/threading/non_thread_safe.h" +#include "content/common/content_export.h" +#include "third_party/libjingle/source/talk/app/webrtc/peerconnectioninterface.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCDataChannelHandler.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCDataChannelHandlerClient.h" + +namespace content { + +// RtcDataChannelHandler is a delegate for the RTC PeerConnection DataChannel +// API messages going between WebKit and native PeerConnection DataChannels in +// libjingle. Instances of this class are owned by WebKit. +// WebKit call all of these methods on the main render thread. +// Callbacks to the webrtc::DataChannelObserver implementation also occur on +// the main render thread. +class CONTENT_EXPORT RtcDataChannelHandler + : NON_EXPORTED_BASE(public WebKit::WebRTCDataChannelHandler), + NON_EXPORTED_BASE(public webrtc::DataChannelObserver), + NON_EXPORTED_BASE(public base::NonThreadSafe) { + public: + explicit RtcDataChannelHandler(webrtc::DataChannelInterface* channel); + virtual ~RtcDataChannelHandler(); + + // WebKit::WebRTCDataChannelHandler implementation. + virtual void setClient( + WebKit::WebRTCDataChannelHandlerClient* client) OVERRIDE; + virtual WebKit::WebString label() OVERRIDE; + virtual bool isReliable() OVERRIDE; + virtual unsigned long bufferedAmount() OVERRIDE; + virtual bool sendStringData(const WebKit::WebString& data) OVERRIDE; + virtual bool sendRawData(const char* data, size_t length) OVERRIDE; + virtual void close() OVERRIDE; + + // webrtc::DataChannelObserver implementation. + virtual void OnStateChange() OVERRIDE; + virtual void OnMessage(const webrtc::DataBuffer& buffer) OVERRIDE; + + private: + scoped_refptr<webrtc::DataChannelInterface> channel_; + WebKit::WebRTCDataChannelHandlerClient* webkit_client_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_RTC_DATA_CHANNEL_HANDLER_H_ diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc index cbcc7e8..1d92fc4 100644 --- a/content/renderer/media/rtc_peer_connection_handler.cc +++ b/content/renderer/media/rtc_peer_connection_handler.cc @@ -11,6 +11,7 @@ #include "base/memory/scoped_ptr.h" #include "base/utf_string_conversions.h" #include "content/renderer/media/media_stream_dependency_factory.h" +#include "content/renderer/media/rtc_data_channel_handler.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. @@ -463,6 +464,22 @@ void RTCPeerConnectionHandler::getStats(LocalRTCStatsRequest* request) { native_peer_connection_->GetStats(observer, track); } +WebKit::WebRTCDataChannelHandler* RTCPeerConnectionHandler::createDataChannel( + const WebKit::WebString& label, bool reliable) { + DVLOG(1) << "createDataChannel label " << UTF16ToUTF8(label); + + webrtc::DataChannelInit config; + config.reliable = reliable; + + talk_base::scoped_refptr<webrtc::DataChannelInterface> webrtc_channel( + native_peer_connection_->CreateDataChannel(UTF16ToUTF8(label), &config)); + if (!webrtc_channel) { + DLOG(ERROR) << "Could not create native data channel."; + return NULL; + } + return new RtcDataChannelHandler(webrtc_channel); +} + void RTCPeerConnectionHandler::stop() { DVLOG(1) << "RTCPeerConnectionHandler::stop"; native_peer_connection_ = NULL; @@ -540,6 +557,13 @@ void RTCPeerConnectionHandler::OnIceComplete() { client_->didGenerateICECandidate(web_candidate); } +void RTCPeerConnectionHandler::OnDataChannel( + webrtc::DataChannelInterface* data_channel) { + DVLOG(1) << "RTCPeerConnectionHandler::OnDataChannel " + << data_channel->label(); + client_->didAddRemoteDataChannel(new RtcDataChannelHandler(data_channel)); +} + void RTCPeerConnectionHandler::OnRenegotiationNeeded() { client_->negotiationNeeded(); } diff --git a/content/renderer/media/rtc_peer_connection_handler.h b/content/renderer/media/rtc_peer_connection_handler.h index dd9fee1..98a02f9 100644 --- a/content/renderer/media/rtc_peer_connection_handler.h +++ b/content/renderer/media/rtc_peer_connection_handler.h @@ -125,6 +125,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler // We will be deleted by WebKit after stop has been returned. virtual void stop() OVERRIDE; + virtual WebKit::WebRTCDataChannelHandler* createDataChannel( + const WebKit::WebString& label, + bool reliable) OVERRIDE; + // webrtc::PeerConnectionObserver implementation virtual void OnError() OVERRIDE; virtual void OnStateChange(StateType state_changed) OVERRIDE; @@ -133,6 +137,8 @@ class CONTENT_EXPORT RTCPeerConnectionHandler virtual void OnIceCandidate( const webrtc::IceCandidateInterface* candidate) OVERRIDE; virtual void OnIceComplete() OVERRIDE; + virtual void OnDataChannel( + webrtc::DataChannelInterface* data_channel) OVERRIDE; virtual void OnRenegotiationNeeded() OVERRIDE; // Delegate functions to allow for mocking of WebKit interfaces. diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc index 3ac8de1..cb9142a 100644 --- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc +++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc @@ -18,6 +18,7 @@ #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" +#include "third_party/WebKit/Source/Platform/chromium/public/WebRTCDataChannelHandler.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" @@ -456,4 +457,12 @@ TEST_F(RTCPeerConnectionHandlerTest, OnRenegotiationNeeded) { EXPECT_TRUE(mock_client_->renegotiate()); } +TEST_F(RTCPeerConnectionHandlerTest, CreateDataChannel) { + WebKit::WebString label = "d1"; + scoped_ptr<WebKit::WebRTCDataChannelHandler> channel( + pc_handler_->createDataChannel("d1", true)); + EXPECT_TRUE(channel.get() != NULL); + EXPECT_EQ(label, channel->label()); +} + } // namespace content |