Update talk to 56092586.
R=jiayl@webrtc.org, mallinath@webrtc.org Review URL: https://webrtc-codereview.appspot.com/3359004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5078 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
3779c1cb0a
commit
07a6fbe83d
@ -38,6 +38,10 @@ namespace webrtc {
|
||||
static size_t kMaxQueuedReceivedDataPackets = 100;
|
||||
static size_t kMaxQueuedSendDataPackets = 100;
|
||||
|
||||
enum {
|
||||
MSG_CHANNELREADY,
|
||||
};
|
||||
|
||||
talk_base::scoped_refptr<DataChannel> DataChannel::Create(
|
||||
DataChannelProviderInterface* provider,
|
||||
cricket::DataChannelType dct,
|
||||
@ -95,6 +99,15 @@ bool DataChannel::Init(const DataChannelInit* config) {
|
||||
// Try to connect to the transport in case the transport channel already
|
||||
// exists.
|
||||
OnTransportChannelCreated();
|
||||
|
||||
// Checks if the transport is ready to send because the initial channel
|
||||
// ready signal may have been sent before the DataChannel creation.
|
||||
// This has to be done async because the upper layer objects (e.g.
|
||||
// Chrome glue and WebKit) are not wired up properly until after this
|
||||
// function returns.
|
||||
if (provider_->ReadyToSendData()) {
|
||||
talk_base::Thread::Current()->Post(this, MSG_CHANNELREADY, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -217,6 +230,14 @@ void DataChannel::SetSendSsrc(uint32 send_ssrc) {
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
void DataChannel::OnMessage(talk_base::Message* msg) {
|
||||
switch (msg->message_id) {
|
||||
case MSG_CHANNELREADY:
|
||||
OnChannelReady(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The underlaying data engine is closing.
|
||||
// This function makes sure the DataChannel is disconnected and changes state to
|
||||
// kClosed.
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "talk/app/webrtc/datachannelinterface.h"
|
||||
#include "talk/app/webrtc/proxy.h"
|
||||
#include "talk/base/messagehandler.h"
|
||||
#include "talk/base/scoped_ref_ptr.h"
|
||||
#include "talk/base/sigslot.h"
|
||||
#include "talk/media/base/mediachannel.h"
|
||||
@ -60,6 +61,8 @@ class DataChannelProviderInterface {
|
||||
virtual void RemoveRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) = 0;
|
||||
// Removes the data channel SID from the transport for SCTP.
|
||||
virtual void RemoveSctpDataStream(uint32 sid) = 0;
|
||||
// Returns true if the transport channel is ready to send data.
|
||||
virtual bool ReadyToSendData() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~DataChannelProviderInterface() {}
|
||||
@ -81,7 +84,8 @@ class DataChannelProviderInterface {
|
||||
// kClosed: Both UpdateReceiveSsrc and UpdateSendSsrc has been called with
|
||||
// SSRC==0.
|
||||
class DataChannel : public DataChannelInterface,
|
||||
public sigslot::has_slots<> {
|
||||
public sigslot::has_slots<>,
|
||||
public talk_base::MessageHandler {
|
||||
public:
|
||||
static talk_base::scoped_refptr<DataChannel> Create(
|
||||
DataChannelProviderInterface* provider,
|
||||
@ -109,6 +113,9 @@ class DataChannel : public DataChannelInterface,
|
||||
virtual DataState state() const { return state_; }
|
||||
virtual bool Send(const DataBuffer& buffer);
|
||||
|
||||
// talk_base::MessageHandler override.
|
||||
virtual void OnMessage(talk_base::Message* msg);
|
||||
|
||||
// Called if the underlying data engine is closing.
|
||||
void OnDataEngineClose();
|
||||
|
||||
|
@ -39,11 +39,12 @@ class SctpDataChannelTest : public testing::Test {
|
||||
}
|
||||
|
||||
void SetChannelReady() {
|
||||
provider_.set_transport_available(true);
|
||||
webrtc_data_channel_->OnTransportChannelCreated();
|
||||
if (webrtc_data_channel_->id() < 0) {
|
||||
webrtc_data_channel_->SetSctpSid(0);
|
||||
}
|
||||
webrtc_data_channel_->OnChannelReady(true);
|
||||
provider_.set_ready_to_send(true);
|
||||
}
|
||||
|
||||
webrtc::DataChannelInit init_;
|
||||
@ -53,27 +54,28 @@ class SctpDataChannelTest : public testing::Test {
|
||||
|
||||
// Verifies that the data channel is connected to the transport after creation.
|
||||
TEST_F(SctpDataChannelTest, ConnectedToTransportOnCreated) {
|
||||
EXPECT_TRUE(provider_.IsConnected(webrtc_data_channel_.get()));
|
||||
// The sid is not set yet, so it should not have added the streams.
|
||||
EXPECT_FALSE(provider_.IsSendStreamAdded(webrtc_data_channel_->id()));
|
||||
EXPECT_FALSE(provider_.IsRecvStreamAdded(webrtc_data_channel_->id()));
|
||||
provider_.set_transport_available(true);
|
||||
talk_base::scoped_refptr<DataChannel> dc = DataChannel::Create(
|
||||
&provider_, cricket::DCT_SCTP, "test1", &init_);
|
||||
|
||||
webrtc_data_channel_->SetSctpSid(0);
|
||||
EXPECT_TRUE(provider_.IsSendStreamAdded(webrtc_data_channel_->id()));
|
||||
EXPECT_TRUE(provider_.IsRecvStreamAdded(webrtc_data_channel_->id()));
|
||||
EXPECT_TRUE(provider_.IsConnected(dc.get()));
|
||||
// The sid is not set yet, so it should not have added the streams.
|
||||
EXPECT_FALSE(provider_.IsSendStreamAdded(dc->id()));
|
||||
EXPECT_FALSE(provider_.IsRecvStreamAdded(dc->id()));
|
||||
|
||||
dc->SetSctpSid(0);
|
||||
EXPECT_TRUE(provider_.IsSendStreamAdded(dc->id()));
|
||||
EXPECT_TRUE(provider_.IsRecvStreamAdded(dc->id()));
|
||||
}
|
||||
|
||||
// Verifies that the data channel is connected to the transport if the transport
|
||||
// is not available initially and becomes available later.
|
||||
TEST_F(SctpDataChannelTest, ConnectedAfterTransportBecomesAvailable) {
|
||||
provider_.set_transport_available(false);
|
||||
talk_base::scoped_refptr<DataChannel> dc = DataChannel::Create(
|
||||
&provider_, cricket::DCT_SCTP, "test1", &init_);
|
||||
EXPECT_FALSE(provider_.IsConnected(dc.get()));
|
||||
EXPECT_FALSE(provider_.IsConnected(webrtc_data_channel_.get()));
|
||||
|
||||
provider_.set_transport_available(true);
|
||||
dc->OnTransportChannelCreated();
|
||||
EXPECT_TRUE(provider_.IsConnected(dc.get()));
|
||||
webrtc_data_channel_->OnTransportChannelCreated();
|
||||
EXPECT_TRUE(provider_.IsConnected(webrtc_data_channel_.get()));
|
||||
}
|
||||
|
||||
// Tests the state of the data channel.
|
||||
@ -81,6 +83,7 @@ TEST_F(SctpDataChannelTest, StateTransition) {
|
||||
EXPECT_EQ(webrtc::DataChannelInterface::kConnecting,
|
||||
webrtc_data_channel_->state());
|
||||
SetChannelReady();
|
||||
|
||||
EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state());
|
||||
webrtc_data_channel_->Close();
|
||||
EXPECT_EQ(webrtc::DataChannelInterface::kClosed,
|
||||
@ -132,3 +135,16 @@ TEST_F(SctpDataChannelTest, OpenMessageSent) {
|
||||
EXPECT_EQ(provider_.last_send_data_params().ssrc,
|
||||
static_cast<uint32>(webrtc_data_channel_->id()));
|
||||
}
|
||||
|
||||
// Tests that the DataChannel created after transport gets ready can enter OPEN
|
||||
// state.
|
||||
TEST_F(SctpDataChannelTest, LateCreatedChannelTransitionToOpen) {
|
||||
SetChannelReady();
|
||||
webrtc::DataChannelInit init;
|
||||
init.id = 1;
|
||||
talk_base::scoped_refptr<DataChannel> dc =
|
||||
DataChannel::Create(&provider_, cricket::DCT_SCTP, "test1", &init);
|
||||
EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, dc->state());
|
||||
EXPECT_TRUE_WAIT(webrtc::DataChannelInterface::kOpen == dc->state(),
|
||||
1000);
|
||||
}
|
||||
|
@ -276,8 +276,6 @@ bool MediaStreamSignaling::AddDataChannelFromOpenMessage(
|
||||
}
|
||||
data_channels_[label] = channel;
|
||||
stream_observer_->OnAddDataChannel(channel);
|
||||
// It's immediately ready to use.
|
||||
channel->OnChannelReady(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,15 @@
|
||||
class FakeDataChannelProvider : public webrtc::DataChannelProviderInterface {
|
||||
public:
|
||||
FakeDataChannelProvider()
|
||||
: id_allocation_should_fail_(false),
|
||||
send_blocked_(false),
|
||||
transport_available_(true) {}
|
||||
: send_blocked_(false),
|
||||
transport_available_(false),
|
||||
ready_to_send_(false) {}
|
||||
virtual ~FakeDataChannelProvider() {}
|
||||
|
||||
virtual bool SendData(const cricket::SendDataParams& params,
|
||||
const talk_base::Buffer& payload,
|
||||
cricket::SendDataResult* result) OVERRIDE {
|
||||
ASSERT(ready_to_send_ && transport_available_);
|
||||
if (send_blocked_) {
|
||||
*result = cricket::SDR_BLOCK;
|
||||
return false;
|
||||
@ -45,6 +46,7 @@ class FakeDataChannelProvider : public webrtc::DataChannelProviderInterface {
|
||||
last_send_data_params_ = params;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool ConnectDataChannel(webrtc::DataChannel* data_channel) OVERRIDE {
|
||||
ASSERT(connected_channels_.find(data_channel) == connected_channels_.end());
|
||||
if (!transport_available_) {
|
||||
@ -54,55 +56,98 @@ class FakeDataChannelProvider : public webrtc::DataChannelProviderInterface {
|
||||
connected_channels_.insert(data_channel);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void DisconnectDataChannel(
|
||||
webrtc::DataChannel* data_channel) OVERRIDE {
|
||||
ASSERT(connected_channels_.find(data_channel) != connected_channels_.end());
|
||||
LOG(LS_INFO) << "DataChannel disconnected " << data_channel;
|
||||
connected_channels_.erase(data_channel);
|
||||
}
|
||||
|
||||
virtual void AddRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) OVERRIDE {
|
||||
if (!transport_available_) {
|
||||
return;
|
||||
}
|
||||
send_ssrcs_.insert(send_ssrc);
|
||||
recv_ssrcs_.insert(recv_ssrc);
|
||||
}
|
||||
|
||||
virtual void AddSctpDataStream(uint32 sid) OVERRIDE {
|
||||
if (!transport_available_) {
|
||||
return;
|
||||
}
|
||||
AddRtpDataStream(sid, sid);
|
||||
}
|
||||
|
||||
virtual void RemoveRtpDataStream(
|
||||
uint32 send_ssrc, uint32 recv_ssrc) OVERRIDE {
|
||||
send_ssrcs_.erase(send_ssrc);
|
||||
recv_ssrcs_.erase(recv_ssrc);
|
||||
}
|
||||
|
||||
virtual void RemoveSctpDataStream(uint32 sid) OVERRIDE {
|
||||
RemoveRtpDataStream(sid, sid);
|
||||
}
|
||||
|
||||
virtual bool ReadyToSendData() const OVERRIDE {
|
||||
return ready_to_send_;
|
||||
}
|
||||
|
||||
// Set true to emulate the SCTP stream being blocked by congestion control.
|
||||
void set_send_blocked(bool blocked) {
|
||||
send_blocked_ = blocked;
|
||||
if (!blocked) {
|
||||
std::set<webrtc::DataChannel*>::iterator it;
|
||||
for (it = connected_channels_.begin();
|
||||
it != connected_channels_.end();
|
||||
++it) {
|
||||
(*it)->OnChannelReady(true);
|
||||
}
|
||||
cricket::SendDataParams last_send_data_params() const {
|
||||
return last_send_data_params_;
|
||||
}
|
||||
void set_id_allocaiton_should_fail(bool fail) {
|
||||
id_allocation_should_fail_ = fail;
|
||||
}
|
||||
|
||||
// Set true to emulate the transport channel creation, e.g. after
|
||||
// setLocalDescription/setRemoteDescription called with data content.
|
||||
void set_transport_available(bool available) {
|
||||
transport_available_ = available;
|
||||
}
|
||||
|
||||
// Set true to emulate the transport ReadyToSendData signal when the transport
|
||||
// becomes writable for the first time.
|
||||
void set_ready_to_send(bool ready) {
|
||||
ASSERT(transport_available_);
|
||||
ready_to_send_ = ready;
|
||||
if (ready) {
|
||||
std::set<webrtc::DataChannel*>::iterator it;
|
||||
for (it = connected_channels_.begin();
|
||||
it != connected_channels_.end();
|
||||
++it) {
|
||||
(*it)->OnChannelReady(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cricket::SendDataParams last_send_data_params() const {
|
||||
return last_send_data_params_;
|
||||
}
|
||||
|
||||
bool IsConnected(webrtc::DataChannel* data_channel) const {
|
||||
return connected_channels_.find(data_channel) != connected_channels_.end();
|
||||
}
|
||||
|
||||
bool IsSendStreamAdded(uint32 stream) const {
|
||||
return send_ssrcs_.find(stream) != send_ssrcs_.end();
|
||||
}
|
||||
|
||||
bool IsRecvStreamAdded(uint32 stream) const {
|
||||
return recv_ssrcs_.find(stream) != recv_ssrcs_.end();
|
||||
}
|
||||
|
||||
private:
|
||||
cricket::SendDataParams last_send_data_params_;
|
||||
bool id_allocation_should_fail_;
|
||||
bool send_blocked_;
|
||||
bool transport_available_;
|
||||
bool ready_to_send_;
|
||||
std::set<webrtc::DataChannel*> connected_channels_;
|
||||
std::set<uint32> send_ssrcs_;
|
||||
std::set<uint32> recv_ssrcs_;
|
||||
|
@ -1024,6 +1024,10 @@ void WebRtcSession::RemoveSctpDataStream(uint32 sid) {
|
||||
RemoveRtpDataStream(sid, sid);
|
||||
}
|
||||
|
||||
bool WebRtcSession::ReadyToSendData() const {
|
||||
return data_channel_.get() && data_channel_->ready_to_send_data();
|
||||
}
|
||||
|
||||
talk_base::scoped_refptr<DataChannel> WebRtcSession::CreateDataChannel(
|
||||
const std::string& label,
|
||||
const DataChannelInit* config) {
|
||||
|
@ -194,6 +194,7 @@ class WebRtcSession : public cricket::BaseSession,
|
||||
virtual void AddSctpDataStream(uint32 sid) OVERRIDE;
|
||||
virtual void RemoveRtpDataStream(uint32 send_ssrc, uint32 recv_ssrc) OVERRIDE;
|
||||
virtual void RemoveSctpDataStream(uint32 sid) OVERRIDE;
|
||||
virtual bool ReadyToSendData() const OVERRIDE;
|
||||
|
||||
talk_base::scoped_refptr<DataChannel> CreateDataChannel(
|
||||
const std::string& label,
|
||||
|
@ -198,7 +198,7 @@ inline bool ImplicitCastToBool(bool result) { return result; }
|
||||
// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and
|
||||
// libjingle are merged.
|
||||
#if !defined(WARN_UNUSED_RESULT)
|
||||
#if defined(COMPILER_GCC)
|
||||
#if defined(__GNUC__)
|
||||
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
#else
|
||||
#define WARN_UNUSED_RESULT
|
||||
|
@ -2477,7 +2477,8 @@ DataChannel::DataChannel(talk_base::Thread* thread,
|
||||
bool rtcp)
|
||||
// MediaEngine is NULL
|
||||
: BaseChannel(thread, NULL, media_channel, session, content_name, rtcp),
|
||||
data_channel_type_(cricket::DCT_NONE) {
|
||||
data_channel_type_(cricket::DCT_NONE),
|
||||
ready_to_send_data_(false) {
|
||||
}
|
||||
|
||||
DataChannel::~DataChannel() {
|
||||
@ -2701,7 +2702,8 @@ void DataChannel::OnMessage(talk_base::Message *pmsg) {
|
||||
case MSG_READYTOSENDDATA: {
|
||||
DataChannelReadyToSendMessageData* data =
|
||||
static_cast<DataChannelReadyToSendMessageData*>(pmsg->pdata);
|
||||
SignalReadyToSendData(data->data());
|
||||
ready_to_send_data_ = data->data();
|
||||
SignalReadyToSendData(ready_to_send_data_);
|
||||
delete data;
|
||||
break;
|
||||
}
|
||||
|
@ -610,6 +610,11 @@ class DataChannel : public BaseChannel {
|
||||
void StartMediaMonitor(int cms);
|
||||
void StopMediaMonitor();
|
||||
|
||||
// Should be called on the signaling thread only.
|
||||
bool ready_to_send_data() const {
|
||||
return ready_to_send_data_;
|
||||
}
|
||||
|
||||
sigslot::signal2<DataChannel*, const DataMediaInfo&> SignalMediaMonitor;
|
||||
sigslot::signal2<DataChannel*, const std::vector<ConnectionInfo>&>
|
||||
SignalConnectionMonitor;
|
||||
@ -714,6 +719,7 @@ class DataChannel : public BaseChannel {
|
||||
// TODO(pthatcher): Make a separate SctpDataChannel and
|
||||
// RtpDataChannel instead of using this.
|
||||
DataChannelType data_channel_type_;
|
||||
bool ready_to_send_data_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
Loading…
x
Reference in New Issue
Block a user