diff --git a/api/proxy.h b/api/proxy.h index 385992e659..b1ebe31acd 100644 --- a/api/proxy.h +++ b/api/proxy.h @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "api/scoped_refptr.h" @@ -396,6 +397,16 @@ class ConstMethodCall : public rtc::Message, public rtc::MessageHandler { return call.Marshal(RTC_FROM_HERE, worker_thread_); \ } +// For use when returning purely const state (set during construction). +// Use with caution. This method should only be used when the return value will +// always be the same. +#define BYPASS_PROXY_CONSTMETHOD0(r, method) \ + r method() const override { \ + static_assert(!std::is_pointer::value, "Type is a pointer"); \ + static_assert(!std::is_reference::value, "Type is a reference"); \ + return c_->method(); \ + } + } // namespace webrtc #endif // API_PROXY_H_ diff --git a/pc/data_channel.cc b/pc/data_channel.cc index 0b9af37544..795bf8d315 100644 --- a/pc/data_channel.cc +++ b/pc/data_channel.cc @@ -139,9 +139,9 @@ rtc::scoped_refptr DataChannel::Create( const std::string& label, const InternalDataChannelInit& config) { rtc::scoped_refptr channel( - new rtc::RefCountedObject(provider, dct, label)); - if (!channel->Init(config)) { - return NULL; + new rtc::RefCountedObject(config, provider, dct, label)); + if (!channel->Init()) { + return nullptr; } return channel; } @@ -152,11 +152,13 @@ bool DataChannel::IsSctpLike(cricket::DataChannelType type) { type == cricket::DCT_DATA_CHANNEL_TRANSPORT_SCTP; } -DataChannel::DataChannel(DataChannelProviderInterface* provider, +DataChannel::DataChannel(const InternalDataChannelInit& config, + DataChannelProviderInterface* provider, cricket::DataChannelType dct, const std::string& label) : internal_id_(GenerateUniqueId()), label_(label), + config_(config), observer_(nullptr), state_(kConnecting), messages_sent_(0), @@ -174,29 +176,28 @@ DataChannel::DataChannel(DataChannelProviderInterface* provider, send_ssrc_(0), receive_ssrc_(0) {} -bool DataChannel::Init(const InternalDataChannelInit& config) { +bool DataChannel::Init() { if (data_channel_type_ == cricket::DCT_RTP) { - if (config.reliable || config.id != -1 || config.maxRetransmits || - config.maxRetransmitTime) { + if (config_.reliable || config_.id != -1 || config_.maxRetransmits || + config_.maxRetransmitTime) { RTC_LOG(LS_ERROR) << "Failed to initialize the RTP data channel due to " "invalid DataChannelInit."; return false; } handshake_state_ = kHandshakeReady; } else if (IsSctpLike(data_channel_type_)) { - if (config.id < -1 || - (config.maxRetransmits && *config.maxRetransmits < 0) || - (config.maxRetransmitTime && *config.maxRetransmitTime < 0)) { + if (config_.id < -1 || + (config_.maxRetransmits && *config_.maxRetransmits < 0) || + (config_.maxRetransmitTime && *config_.maxRetransmitTime < 0)) { RTC_LOG(LS_ERROR) << "Failed to initialize the SCTP data channel due to " "invalid DataChannelInit."; return false; } - if (config.maxRetransmits && config.maxRetransmitTime) { + if (config_.maxRetransmits && config_.maxRetransmitTime) { RTC_LOG(LS_ERROR) << "maxRetransmits and maxRetransmitTime should not be both set."; return false; } - config_ = config; switch (config_.open_handshake_role) { case webrtc::InternalDataChannelInit::kNone: // pre-negotiated @@ -323,7 +324,7 @@ void DataChannel::SetSctpSid(int sid) { return; } - config_.id = sid; + const_cast(config_).id = sid; provider_->AddSctpDataStream(sid); } diff --git a/pc/data_channel.h b/pc/data_channel.h index 9a0a0aa2d3..1ee267924a 100644 --- a/pc/data_channel.h +++ b/pc/data_channel.h @@ -54,6 +54,8 @@ class DataChannelProviderInterface { virtual ~DataChannelProviderInterface() {} }; +// TODO(tommi): Change to not inherit from DataChannelInit but to have it as +// a const member. Block access to the 'id' member since it cannot be const. struct InternalDataChannelInit : public DataChannelInit { enum OpenHandshakeRole { kOpener, kAcker, kNone }; // The default role is kOpener because the default |negotiated| is false. @@ -229,7 +231,8 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> { static void ResetInternalIdAllocatorForTesting(int new_value); protected: - DataChannel(DataChannelProviderInterface* client, + DataChannel(const InternalDataChannelInit& config, + DataChannelProviderInterface* client, cricket::DataChannelType dct, const std::string& label); virtual ~DataChannel(); @@ -266,7 +269,7 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> { kHandshakeReady }; - bool Init(const InternalDataChannelInit& config); + bool Init(); void UpdateState(); void SetState(DataState state); void DisconnectFromProvider(); @@ -282,8 +285,8 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> { bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer); const int internal_id_; - std::string label_; - InternalDataChannelInit config_; + const std::string label_; + const InternalDataChannelInit config_; DataChannelObserver* observer_; DataState state_; RTCError error_; @@ -294,7 +297,7 @@ class DataChannel : public DataChannelInterface, public sigslot::has_slots<> { // Number of bytes of data that have been queued using Send(). Increased // before each transport send and decreased after each successful send. uint64_t buffered_amount_; - cricket::DataChannelType data_channel_type_; + const cricket::DataChannelType data_channel_type_; DataChannelProviderInterface* provider_; HandshakeState handshake_state_; bool connected_to_provider_; @@ -318,17 +321,18 @@ BEGIN_SIGNALING_PROXY_MAP(DataChannel) PROXY_SIGNALING_THREAD_DESTRUCTOR() PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*) PROXY_METHOD0(void, UnregisterObserver) -PROXY_CONSTMETHOD0(std::string, label) -PROXY_CONSTMETHOD0(bool, reliable) -PROXY_CONSTMETHOD0(bool, ordered) -PROXY_CONSTMETHOD0(uint16_t, maxRetransmitTime) -PROXY_CONSTMETHOD0(uint16_t, maxRetransmits) -PROXY_CONSTMETHOD0(absl::optional, maxRetransmitsOpt) -PROXY_CONSTMETHOD0(absl::optional, maxPacketLifeTime) -PROXY_CONSTMETHOD0(std::string, protocol) -PROXY_CONSTMETHOD0(bool, negotiated) +BYPASS_PROXY_CONSTMETHOD0(std::string, label) +BYPASS_PROXY_CONSTMETHOD0(bool, reliable) +BYPASS_PROXY_CONSTMETHOD0(bool, ordered) +BYPASS_PROXY_CONSTMETHOD0(uint16_t, maxRetransmitTime) +BYPASS_PROXY_CONSTMETHOD0(uint16_t, maxRetransmits) +BYPASS_PROXY_CONSTMETHOD0(absl::optional, maxRetransmitsOpt) +BYPASS_PROXY_CONSTMETHOD0(absl::optional, maxPacketLifeTime) +BYPASS_PROXY_CONSTMETHOD0(std::string, protocol) +BYPASS_PROXY_CONSTMETHOD0(bool, negotiated) +// Can't bypass the proxy since the id may change. PROXY_CONSTMETHOD0(int, id) -PROXY_CONSTMETHOD0(Priority, priority) +BYPASS_PROXY_CONSTMETHOD0(Priority, priority) PROXY_CONSTMETHOD0(DataState, state) PROXY_CONSTMETHOD0(RTCError, error) PROXY_CONSTMETHOD0(uint32_t, messages_sent) diff --git a/pc/test/mock_data_channel.h b/pc/test/mock_data_channel.h index 9ca018af14..63f0e6ce64 100644 --- a/pc/test/mock_data_channel.h +++ b/pc/test/mock_data_channel.h @@ -22,15 +22,20 @@ class MockDataChannel : public rtc::RefCountedObject { public: MockDataChannel(int id, DataState state) : MockDataChannel(id, "MockDataChannel", state, "udp", 0, 0, 0, 0) {} - MockDataChannel(int id, - const std::string& label, - DataState state, - const std::string& protocol, - uint32_t messages_sent, - uint64_t bytes_sent, - uint32_t messages_received, - uint64_t bytes_received) - : rtc::RefCountedObject(nullptr, cricket::DCT_NONE, label) { + MockDataChannel( + int id, + const std::string& label, + DataState state, + const std::string& protocol, + uint32_t messages_sent, + uint64_t bytes_sent, + uint32_t messages_received, + uint64_t bytes_received, + const InternalDataChannelInit& config = InternalDataChannelInit()) + : rtc::RefCountedObject(config, + nullptr, + cricket::DCT_NONE, + label) { EXPECT_CALL(*this, id()).WillRepeatedly(::testing::Return(id)); EXPECT_CALL(*this, state()).WillRepeatedly(::testing::Return(state)); EXPECT_CALL(*this, protocol()).WillRepeatedly(::testing::Return(protocol));