Make SdpOfferAnswerHandler be owned, not contained.
And add a Create() method to the class.
This makes it possible to experiment with subclassing the
SdpOfferAnswer object without modifying the PeerConnection.
Bug: webrtc:11995
Change-Id: I0a7c91a8999858ddcb1ea59ac4eb9a3b0663b0f6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/190288
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32501}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 4512b82..4a6c85c 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -443,7 +443,6 @@
tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
call_(std::move(call)),
call_ptr_(call_.get()),
- sdp_handler_(this),
data_channel_controller_(this),
message_handler_(signaling_thread()) {}
@@ -451,7 +450,9 @@
TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.PrepareForShutdown();
+ if (sdp_handler_) {
+ sdp_handler_->PrepareForShutdown();
+ }
// Need to stop transceivers before destroying the stats collector because
// AudioRtpSender has a reference to the StatsCollector it will update when
@@ -468,13 +469,15 @@
stats_collector_ = nullptr;
}
- // Don't destroy BaseChannels until after stats has been cleaned up so that
- // the last stats request can still read from the channels.
- sdp_handler_.DestroyAllChannels();
+ if (sdp_handler_) {
+ // Don't destroy BaseChannels until after stats has been cleaned up so that
+ // the last stats request can still read from the channels.
+ sdp_handler_->DestroyAllChannels();
- RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
+ RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
- sdp_handler_.ResetSessionDescFactory();
+ sdp_handler_->ResetSessionDescFactory();
+ }
transport_controller_.reset();
// port_allocator_ lives on the network thread and should be destroyed there.
@@ -625,11 +628,14 @@
stats_ = std::make_unique<StatsCollector>(this);
stats_collector_ = RTCStatsCollector::Create(this);
+ sdp_handler_ =
+ SdpOfferAnswerHandler::Create(this, configuration, dependencies);
+
rtp_manager_ = std::make_unique<RtpTransmissionManager>(
IsUnifiedPlan(), signaling_thread(), worker_thread(), channel_manager(),
&usage_pattern_, observer_, stats_.get(), [this]() {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.UpdateNegotiationNeeded();
+ sdp_handler_->UpdateNegotiationNeeded();
});
// Add default audio/video transceivers for Plan B SDP.
@@ -641,7 +647,6 @@
RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_VIDEO)));
}
- sdp_handler_.Initialize(configuration, &dependencies);
int delay_ms = configuration.report_usage_pattern_delay_ms
? *configuration.report_usage_pattern_delay_ms
@@ -661,7 +666,7 @@
RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
"Plan SdpSemantics. Please use GetSenders "
"instead.";
- return sdp_handler_.local_streams();
+ return sdp_handler_->local_streams();
}
rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
@@ -669,7 +674,7 @@
RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
"Plan SdpSemantics. Please use GetReceivers "
"instead.";
- return sdp_handler_.remote_streams();
+ return sdp_handler_->remote_streams();
}
bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
@@ -677,7 +682,7 @@
RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
"SdpSemantics. Please use AddTrack instead.";
TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
- return sdp_handler_.AddStream(local_stream);
+ return sdp_handler_->AddStream(local_stream);
}
void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
@@ -686,7 +691,7 @@
"Plan SdpSemantics. Please use RemoveTrack "
"instead.";
TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
- sdp_handler_.RemoveStream(local_stream);
+ sdp_handler_->RemoveStream(local_stream);
}
RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
@@ -713,7 +718,7 @@
}
auto sender_or_error = rtp_manager()->AddTrack(track, stream_ids);
if (sender_or_error.ok()) {
- sdp_handler_.UpdateNegotiationNeeded();
+ sdp_handler_->UpdateNegotiationNeeded();
stats_->AddTrack(track);
}
return sender_or_error;
@@ -763,7 +768,7 @@
"Couldn't find sender " + sender->id() + " to remove.");
}
}
- sdp_handler_.UpdateNegotiationNeeded();
+ sdp_handler_->UpdateNegotiationNeeded();
return RTCError::OK();
}
@@ -917,7 +922,7 @@
transceiver->internal()->set_direction(init.direction);
if (update_negotiation_needed) {
- sdp_handler_.UpdateNegotiationNeeded();
+ sdp_handler_->UpdateNegotiationNeeded();
}
return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
@@ -926,7 +931,7 @@
void PeerConnection::OnNegotiationNeeded() {
RTC_DCHECK_RUN_ON(signaling_thread());
RTC_DCHECK(!IsClosed());
- sdp_handler_.UpdateNegotiationNeeded();
+ sdp_handler_->UpdateNegotiationNeeded();
}
rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
@@ -1102,7 +1107,7 @@
PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.signaling_state();
+ return sdp_handler_->signaling_state();
}
PeerConnectionInterface::IceConnectionState
@@ -1168,7 +1173,7 @@
// Trigger the onRenegotiationNeeded event for every new RTP DataChannel, or
// the first SCTP DataChannel.
if (data_channel_type() == cricket::DCT_RTP || first_datachannel) {
- sdp_handler_.UpdateNegotiationNeeded();
+ sdp_handler_->UpdateNegotiationNeeded();
}
NoteUsageEvent(UsageEvent::DATA_ADDED);
return channel;
@@ -1176,59 +1181,59 @@
void PeerConnection::RestartIce() {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.RestartIce();
+ sdp_handler_->RestartIce();
}
void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
const RTCOfferAnswerOptions& options) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.CreateOffer(observer, options);
+ sdp_handler_->CreateOffer(observer, options);
}
void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
const RTCOfferAnswerOptions& options) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.CreateAnswer(observer, options);
+ sdp_handler_->CreateAnswer(observer, options);
}
void PeerConnection::SetLocalDescription(
SetSessionDescriptionObserver* observer,
SessionDescriptionInterface* desc_ptr) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.SetLocalDescription(observer, desc_ptr);
+ sdp_handler_->SetLocalDescription(observer, desc_ptr);
}
void PeerConnection::SetLocalDescription(
std::unique_ptr<SessionDescriptionInterface> desc,
rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.SetLocalDescription(std::move(desc), observer);
+ sdp_handler_->SetLocalDescription(std::move(desc), observer);
}
void PeerConnection::SetLocalDescription(
SetSessionDescriptionObserver* observer) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.SetLocalDescription(observer);
+ sdp_handler_->SetLocalDescription(observer);
}
void PeerConnection::SetLocalDescription(
rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.SetLocalDescription(observer);
+ sdp_handler_->SetLocalDescription(observer);
}
void PeerConnection::SetRemoteDescription(
SetSessionDescriptionObserver* observer,
SessionDescriptionInterface* desc_ptr) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.SetRemoteDescription(observer, desc_ptr);
+ sdp_handler_->SetRemoteDescription(observer, desc_ptr);
}
void PeerConnection::SetRemoteDescription(
std::unique_ptr<SessionDescriptionInterface> desc,
rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.SetRemoteDescription(std::move(desc), observer);
+ sdp_handler_->SetRemoteDescription(std::move(desc), observer);
}
PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
@@ -1393,21 +1398,21 @@
bool PeerConnection::AddIceCandidate(
const IceCandidateInterface* ice_candidate) {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.AddIceCandidate(ice_candidate);
+ return sdp_handler_->AddIceCandidate(ice_candidate);
}
void PeerConnection::AddIceCandidate(
std::unique_ptr<IceCandidateInterface> candidate,
std::function<void(RTCError)> callback) {
RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_.AddIceCandidate(std::move(candidate), callback);
+ sdp_handler_->AddIceCandidate(std::move(candidate), callback);
}
bool PeerConnection::RemoveIceCandidates(
const std::vector<cricket::Candidate>& candidates) {
TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.RemoveIceCandidates(candidates);
+ return sdp_handler_->RemoveIceCandidates(candidates);
}
RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
@@ -1558,36 +1563,36 @@
const SessionDescriptionInterface* PeerConnection::local_description() const {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.local_description();
+ return sdp_handler_->local_description();
}
const SessionDescriptionInterface* PeerConnection::remote_description() const {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.remote_description();
+ return sdp_handler_->remote_description();
}
const SessionDescriptionInterface* PeerConnection::current_local_description()
const {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.current_local_description();
+ return sdp_handler_->current_local_description();
}
const SessionDescriptionInterface* PeerConnection::current_remote_description()
const {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.current_remote_description();
+ return sdp_handler_->current_remote_description();
}
const SessionDescriptionInterface* PeerConnection::pending_local_description()
const {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.pending_local_description();
+ return sdp_handler_->pending_local_description();
}
const SessionDescriptionInterface* PeerConnection::pending_remote_description()
const {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.pending_remote_description();
+ return sdp_handler_->pending_remote_description();
}
void PeerConnection::Close() {
@@ -1608,7 +1613,7 @@
connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
Observer()->OnConnectionChange(connection_state_);
- sdp_handler_.Close();
+ sdp_handler_->Close();
NoteUsageEvent(UsageEvent::CLOSE_CALLED);
@@ -1626,14 +1631,14 @@
// Don't destroy BaseChannels until after stats has been cleaned up so that
// the last stats request can still read from the channels.
- sdp_handler_.DestroyAllChannels();
+ sdp_handler_->DestroyAllChannels();
// The event log is used in the transport controller, which must be outlived
// by the former. CreateOffer by the peer connection is implemented
// asynchronously and if the peer connection is closed without resetting the
// WebRTC session description factory, the session description factory would
// call the transport controller.
- sdp_handler_.ResetSessionDescFactory();
+ sdp_handler_->ResetSessionDescFactory();
transport_controller_.reset();
rtp_manager_->Close();
@@ -1933,8 +1938,9 @@
absl::optional<rtc::SSLRole> dtls_role;
if (sctp_mid_s_) {
dtls_role = transport_controller_->GetDtlsRole(*sctp_mid_s_);
- if (!dtls_role && sdp_handler_.is_caller().has_value()) {
- dtls_role = *sdp_handler_.is_caller() ? rtc::SSL_SERVER : rtc::SSL_CLIENT;
+ if (!dtls_role && sdp_handler_->is_caller().has_value()) {
+ dtls_role =
+ *sdp_handler_->is_caller() ? rtc::SSL_SERVER : rtc::SSL_CLIENT;
}
*role = *dtls_role;
return true;
@@ -2072,7 +2078,7 @@
bool PeerConnection::IceRestartPending(const std::string& content_name) const {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.IceRestartPending(content_name);
+ return sdp_handler_->IceRestartPending(content_name);
}
bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
@@ -2140,7 +2146,7 @@
// Use transport_name as the candidate media id.
std::unique_ptr<JsepIceCandidate> candidate(
new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
- sdp_handler_.AddLocalIceCandidate(candidate.get());
+ sdp_handler_->AddLocalIceCandidate(candidate.get());
OnIceCandidate(std::move(candidate));
}
}
@@ -2162,7 +2168,7 @@
return;
}
}
- sdp_handler_.RemoveLocalIceCandidates(candidates);
+ sdp_handler_->RemoveLocalIceCandidates(candidates);
OnIceCandidatesRemoved(candidates);
}
@@ -2341,7 +2347,7 @@
bool PeerConnection::SrtpRequired() const {
return (dtls_enabled_ ||
- sdp_handler_.webrtc_session_desc_factory()->SdesPolicy() ==
+ sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() ==
cricket::SEC_REQUIRED);
}
@@ -2553,7 +2559,7 @@
bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.ShouldFireNegotiationNeededEvent(event_id);
+ return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
}
void PeerConnection::RequestUsagePatternReportForTesting() {
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index 76788d9..35567c1 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -337,7 +337,7 @@
PeerConnectionObserver* Observer() const;
bool IsClosed() const {
RTC_DCHECK_RUN_ON(signaling_thread());
- return sdp_handler_.signaling_state() == PeerConnectionInterface::kClosed;
+ return sdp_handler_->signaling_state() == PeerConnectionInterface::kClosed;
}
// Get current SSL role used by SCTP's underlying transport.
bool GetSctpSslRole(rtc::SSLRole* role);
@@ -683,8 +683,9 @@
absl::optional<std::string> sctp_mid_s_ RTC_GUARDED_BY(signaling_thread());
absl::optional<std::string> sctp_mid_n_ RTC_GUARDED_BY(network_thread());
- // The machinery for handling offers and answers.
- SdpOfferAnswerHandler sdp_handler_ RTC_GUARDED_BY(signaling_thread());
+ // The machinery for handling offers and answers. Const after initialization.
+ std::unique_ptr<SdpOfferAnswerHandler> sdp_handler_
+ RTC_GUARDED_BY(signaling_thread());
bool dtls_enabled_ RTC_GUARDED_BY(signaling_thread()) = false;
diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc
index 51a0428..b625848 100644
--- a/pc/sdp_offer_answer.cc
+++ b/pc/sdp_offer_answer.cc
@@ -18,6 +18,7 @@
#include <utility>
#include "absl/algorithm/container.h"
+#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/crypto/crypto_options.h"
@@ -949,9 +950,19 @@
SdpOfferAnswerHandler::~SdpOfferAnswerHandler() {}
+// Static
+std::unique_ptr<SdpOfferAnswerHandler> SdpOfferAnswerHandler::Create(
+ PeerConnection* pc,
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ PeerConnectionDependencies& dependencies) {
+ auto handler = absl::WrapUnique(new SdpOfferAnswerHandler(pc));
+ handler->Initialize(configuration, dependencies);
+ return handler;
+}
+
void SdpOfferAnswerHandler::Initialize(
const PeerConnectionInterface::RTCConfiguration& configuration,
- PeerConnectionDependencies* dependencies) {
+ PeerConnectionDependencies& dependencies) {
RTC_DCHECK_RUN_ON(signaling_thread());
video_options_.screencast_min_bitrate_kbps =
configuration.screencast_min_bitrate;
@@ -982,7 +993,7 @@
webrtc_session_desc_factory_ =
std::make_unique<WebRtcSessionDescriptionFactory>(
signaling_thread(), channel_manager(), this, pc_->session_id(),
- pc_->dtls_enabled(), std::move(dependencies->cert_generator),
+ pc_->dtls_enabled(), std::move(dependencies.cert_generator),
certificate, &ssrc_generator_);
webrtc_session_desc_factory_->SignalCertificateReady.connect(
this, &SdpOfferAnswerHandler::OnCertificateReady);
@@ -995,9 +1006,9 @@
pc_->GetCryptoOptions().srtp.enable_encrypted_rtp_header_extensions);
webrtc_session_desc_factory_->set_is_unified_plan(IsUnifiedPlan());
- if (dependencies->video_bitrate_allocator_factory) {
+ if (dependencies.video_bitrate_allocator_factory) {
video_bitrate_allocator_factory_ =
- std::move(dependencies->video_bitrate_allocator_factory);
+ std::move(dependencies.video_bitrate_allocator_factory);
} else {
video_bitrate_allocator_factory_ =
CreateBuiltinVideoBitrateAllocatorFactory();
diff --git a/pc/sdp_offer_answer.h b/pc/sdp_offer_answer.h
index e468414..4e6e48f 100644
--- a/pc/sdp_offer_answer.h
+++ b/pc/sdp_offer_answer.h
@@ -88,14 +88,13 @@
class SdpOfferAnswerHandler : public SdpStateProvider,
public sigslot::has_slots<> {
public:
- explicit SdpOfferAnswerHandler(PeerConnection* pc);
~SdpOfferAnswerHandler();
- // Called from PeerConnection's Initialize() function. Can only be called
- // once. Modifies dependencies.
- void Initialize(
+ // Creates an SdpOfferAnswerHandler. Modifies dependencies.
+ static std::unique_ptr<SdpOfferAnswerHandler> Create(
+ PeerConnection* pc,
const PeerConnectionInterface::RTCConfiguration& configuration,
- PeerConnectionDependencies* dependencies);
+ PeerConnectionDependencies& dependencies);
void ResetSessionDescFactory() {
RTC_DCHECK_RUN_ON(signaling_thread());
@@ -215,6 +214,14 @@
// move this type of logic to JsepTransportController/JsepTransport.
class LocalIceCredentialsToReplace;
+ // Only called by the Create() function.
+ explicit SdpOfferAnswerHandler(PeerConnection* pc);
+ // Called from the `Create()` function. Can only be called
+ // once. Modifies dependencies.
+ void Initialize(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ PeerConnectionDependencies& dependencies);
+
rtc::Thread* signaling_thread() const;
// Non-const versions of local_description()/remote_description(), for use
// internally.