tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 142a49eca33a5b2a77315e4ed65b428ed204b416
parent 4e54bfb07729ccb6a65cd72a3e0e99b6e7f67cd3
Author: Dan Baker <dbaker@mozilla.com>
Date:   Mon,  1 Dec 2025 20:58:48 -0700

Bug 2000941 - Vendor libwebrtc from 85c183fd32

Upstream commit: https://webrtc.googlesource.com/src/+/85c183fd32c2a2372322c57eae31601949847ffd
    Move some of JsepSessionDescription impl to SessionDescriptionInternal

    This change begins transforming `SessionDescriptionInterface` from a
    pure interface into a class with a concrete base implementation. This
    is the first step toward making the class thread-aware.

    A new `SessionDescriptionInternal` class is introduced to house the
    common data members (SDP type, session ID, version, and the internal
    `description_` pointer). `SessionDescriptionInterface` is updated to
    inherit from this new base. To start with, all members in this class
    are const, initialized at construction time.

    Consequently:
    - Pure virtual getters in `SessionDescriptionInterface` (like
      `GetType`, `session_id`, etc.) are now implemented in the header by
      forwarding to the `SessionDescriptionInternal` base.
    - `JsepSessionDescription` is simplified, removing its duplicate data
      members and relying on the inherited implementation.
    - A `SequenceChecker` is added to the internal base to begin
      enforcing thread constraints. For now, checks are not enforced
      but a method is added that allows for resetting the thread checker.
      This method will be needed in corner cases, mostly internally at api/
      ownership transition points.

    Bug: webrtc:442220720
    Change-Id: Ibe65d9045313723913f306c4ebc97500e516a1c7
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/409380
    Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
    Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#45658}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/api/BUILD.gn | 2++
Mthird_party/libwebrtc/api/DEPS | 1+
Mthird_party/libwebrtc/api/jsep.h | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mthird_party/libwebrtc/api/jsep_session_description.h | 14--------------
Mthird_party/libwebrtc/api/test/DEPS | 3+++
Mthird_party/libwebrtc/api/test/mock_session_description_interface.h | 4+++-
Mthird_party/libwebrtc/moz-patch-stack/s0027.patch | 16++++++++--------
Mthird_party/libwebrtc/moz-patch-stack/s0102.patch | 2+-
Mthird_party/libwebrtc/pc/jsep_session_description.cc | 73++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
10 files changed, 145 insertions(+), 60 deletions(-)

diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor @@ -1,4 +1,4 @@ # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc -libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T03:55:23.939638+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T03:58:33.271617+00:00. # base of lastest vendoring -9c45144f9b +85c183fd32 diff --git a/third_party/libwebrtc/api/BUILD.gn b/third_party/libwebrtc/api/BUILD.gn @@ -402,6 +402,7 @@ if (!build_with_mozilla) { "../rtc_base:ssl", "../rtc_base:ssl_adapter", "../rtc_base:stringutils", + "../rtc_base/system:no_unique_address", "adaptation:resource_adaptation_api", "audio:audio_device", "audio:audio_frame_processor", @@ -1424,6 +1425,7 @@ if (rtc_include_tests) { deps = [ ":candidate", ":libjingle_peerconnection_api", + "../pc:session_description", "../test:test_support", "//third_party/abseil-cpp/absl/strings:string_view", ] diff --git a/third_party/libwebrtc/api/DEPS b/third_party/libwebrtc/api/DEPS @@ -106,6 +106,7 @@ specific_include_rules = { "jsep\.h": [ "+absl/strings/has_absl_stringify.h", "+absl/strings/str_format.h", + "+rtc_base/system/no_unique_address.h", ], "local_network_access_permission\.h": [ diff --git a/third_party/libwebrtc/api/jsep.h b/third_party/libwebrtc/api/jsep.h @@ -34,6 +34,8 @@ #include "api/candidate.h" #include "api/ref_count.h" #include "api/rtc_error.h" +#include "api/sequence_checker.h" +#include "rtc_base/system/no_unique_address.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { @@ -206,13 +208,67 @@ void AbslStringify(Sink& sink, SdpType sdp_type) { RTC_EXPORT std::optional<SdpType> SdpTypeFromString( const std::string& type_str); +// TODO: bugs.webrtc.org/442220720 - This class is temporarily here while +// SessionDescriptionInterface transforms from a pure interface into a simple +// non-virtual class. The purpose of `SessionDescriptionInternal` is to provide +// protected methods to classes currently inheriting from +// SessionDescriptionInterface, the basic implementation that satisified the +// interface. Once the migration of the implementation is complete, the +// SessionDescriptionInterface class can be made non-virtual, final and +// SessionDescriptionInternal can effectively be renamed to +// SessionDescriptionInterface. The reason for all of this is that access to and +// modification of the internal state needs to be made thread aware so that +// concurrent operations aren't executed on different threads or that the +// state can be declared const when no known modifications are pending. +class SessionDescriptionInternal { + public: + explicit SessionDescriptionInternal( + SdpType type, + absl_nullable std::unique_ptr<SessionDescription> description, + absl::string_view id, + absl::string_view version); + + ~SessionDescriptionInternal(); + + // Resets the internal sequence_checker_ to not be attached to a particular + // thread. Used when transfering object ownership between threads. Must be + // called by the thread that currently owns the object before transferring the + // ownership. + void RelinquishThreadOwnership(); + + protected: + // Only meant for the SessionDescriptionInterface implementation. + SdpType sdp_type() const { return sdp_type_; } + absl::string_view id() const { return id_; } + absl::string_view version() const { return version_; } + const SessionDescription* description() const { return description_.get(); } + SessionDescription* description() { return description_.get(); } + size_t mediasection_count() const; + + protected: + // This method is necessarily `protected`, and not private, while + // the SessionDescriptionInterface implementation is being consolidated + // into a single class. + SequenceChecker& sequence_checker() { return sequence_checker_; } + + private: + RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_{ + SequenceChecker::kDetached}; + + const SdpType sdp_type_; + const std::string id_; + const std::string version_; + absl_nullable const std::unique_ptr<SessionDescription> description_; +}; + // Class representation of an SDP session description. // // An instance of this interface is supposed to be owned by one class at a time // and is therefore not expected to be thread safe. // // An instance can be created by CreateSessionDescription. -class RTC_EXPORT SessionDescriptionInterface { +class RTC_EXPORT SessionDescriptionInterface + : public SessionDescriptionInternal { public: // String representations of the supported SDP types. static const char kOffer[]; @@ -227,21 +283,24 @@ class RTC_EXPORT SessionDescriptionInterface { virtual std::unique_ptr<SessionDescriptionInterface> Clone() const = 0; // Only for use internally. - virtual SessionDescription* description() = 0; - virtual const SessionDescription* description() const = 0; + virtual SessionDescription* description() { + return SessionDescriptionInternal::description(); + } + virtual const SessionDescription* description() const { + return SessionDescriptionInternal::description(); + } // Get the session id and session version, which are defined based on // RFC 4566 for the SDP o= line. - virtual std::string session_id() const = 0; - virtual std::string session_version() const = 0; + virtual std::string session_id() const { return std::string(id()); } + virtual std::string session_version() const { return std::string(version()); } // Returns the type of this session description as an SdpType. Descriptions of // the various types are found in the SdpType documentation. - virtual SdpType GetType() const = 0; + virtual SdpType GetType() const { return sdp_type(); } - // kOffer/kPrAnswer/kAnswer // TODO(steveanton): Remove this in favor of `GetType` that returns SdpType. - virtual std::string type() const = 0; + virtual std::string type() const { return SdpTypeToString(sdp_type()); } // Adds the specified candidate to the description. // @@ -261,7 +320,9 @@ class RTC_EXPORT SessionDescriptionInterface { virtual bool RemoveCandidate(const IceCandidate* candidate) = 0; // Returns the number of m= sections in the session description. - virtual size_t number_of_mediasections() const = 0; + virtual size_t number_of_mediasections() const { + return mediasection_count(); + } // Returns a collection of all candidates that belong to a certain m= // section. @@ -283,6 +344,13 @@ class RTC_EXPORT SessionDescriptionInterface { } sink.Append("--- END SDP ---\n"); } + + protected: + explicit SessionDescriptionInterface( + SdpType type, + std::unique_ptr<SessionDescription> description, + absl::string_view id, + absl::string_view version); }; // Creates a SessionDescriptionInterface based on the SDP string and the type. diff --git a/third_party/libwebrtc/api/jsep_session_description.h b/third_party/libwebrtc/api/jsep_session_description.h @@ -47,27 +47,13 @@ class JsepSessionDescription final : public SessionDescriptionInterface { JsepSessionDescription& operator=(const JsepSessionDescription&) = delete; std::unique_ptr<SessionDescriptionInterface> Clone() const override; - - SessionDescription* description() override { return description_.get(); } - const SessionDescription* description() const override { - return description_.get(); - } - std::string session_id() const override { return session_id_; } - std::string session_version() const override { return session_version_; } - SdpType GetType() const override { return type_; } - std::string type() const override { return SdpTypeToString(type_); } bool AddCandidate(const IceCandidate* candidate) override; bool RemoveCandidate(const IceCandidate* candidate) override; - size_t number_of_mediasections() const override; const IceCandidateCollection* candidates( size_t mediasection_index) const override; bool ToString(std::string* out) const override; private: - const std::unique_ptr<SessionDescription> description_; - const std::string session_id_; - const std::string session_version_; - const SdpType type_; std::vector<IceCandidateCollection> candidate_collection_; bool IsValidMLineIndex(int index) const; diff --git a/third_party/libwebrtc/api/test/DEPS b/third_party/libwebrtc/api/test/DEPS @@ -61,6 +61,9 @@ specific_include_rules = { "mock_peerconnectioninterface\.h": [ "+rtc_base/thread.h", ], + "mock_session_description_interface\.h": [ + "+pc/session_description.h", + ], "videocodec_test_fixture\.h": [ "+modules/video_coding/codecs/h264/include/h264_globals.h", ], diff --git a/third_party/libwebrtc/api/test/mock_session_description_interface.h b/third_party/libwebrtc/api/test/mock_session_description_interface.h @@ -17,6 +17,7 @@ #include <type_traits> #include "api/jsep.h" +#include "pc/session_description.h" #include "test/gmock.h" namespace webrtc { @@ -27,7 +28,8 @@ class [[deprecated( "interface.")]] MockSessionDescriptionInterface : public SessionDescriptionInterface { public: - MockSessionDescriptionInterface() = default; + MockSessionDescriptionInterface() + : SessionDescriptionInterface(SdpType::kRollback, nullptr, "", "") {} MOCK_METHOD(std::unique_ptr<SessionDescriptionInterface>, Clone, (), diff --git a/third_party/libwebrtc/moz-patch-stack/s0027.patch b/third_party/libwebrtc/moz-patch-stack/s0027.patch @@ -203,7 +203,7 @@ index 3efce2dd19..cbfc05f243 100644 } diff --git a/api/BUILD.gn b/api/BUILD.gn -index 47f3e23450..462739dea8 100644 +index 1c02e38171..7758d17af0 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -44,6 +44,9 @@ rtc_library("enable_media") { @@ -287,7 +287,7 @@ index 47f3e23450..462739dea8 100644 visibility = [ "*" ] cflags = [] sources = [ -@@ -422,6 +450,7 @@ rtc_library("libjingle_peerconnection_api") { +@@ -423,6 +451,7 @@ rtc_library("libjingle_peerconnection_api") { "../rtc_base/system:rtc_export", ] } @@ -295,7 +295,7 @@ index 47f3e23450..462739dea8 100644 rtc_library("frame_transformer_interface") { visibility = [ "*" ] -@@ -644,6 +673,7 @@ rtc_source_set("peer_network_dependencies") { +@@ -645,6 +674,7 @@ rtc_source_set("peer_network_dependencies") { } rtc_source_set("peer_connection_quality_test_fixture_api") { @@ -303,7 +303,7 @@ index 47f3e23450..462739dea8 100644 visibility = [ "*" ] testonly = true sources = [ "test/peerconnection_quality_test_fixture.h" ] -@@ -688,6 +718,7 @@ rtc_source_set("peer_connection_quality_test_fixture_api") { +@@ -689,6 +719,7 @@ rtc_source_set("peer_connection_quality_test_fixture_api") { "//third_party/abseil-cpp/absl/strings:string_view", ] } @@ -311,7 +311,7 @@ index 47f3e23450..462739dea8 100644 rtc_library("frame_generator_api") { visibility = [ "*" ] -@@ -793,6 +824,7 @@ rtc_library("create_frame_generator") { +@@ -794,6 +825,7 @@ rtc_library("create_frame_generator") { ] } @@ -319,7 +319,7 @@ index 47f3e23450..462739dea8 100644 rtc_library("create_peer_connection_quality_test_frame_generator") { visibility = [ "*" ] testonly = true -@@ -810,6 +842,7 @@ rtc_library("create_peer_connection_quality_test_frame_generator") { +@@ -811,6 +843,7 @@ rtc_library("create_peer_connection_quality_test_frame_generator") { "units:time_delta", ] } @@ -327,7 +327,7 @@ index 47f3e23450..462739dea8 100644 rtc_source_set("data_channel_event_observer_interface") { visibility = [ "*" ] -@@ -1002,6 +1035,7 @@ rtc_source_set("refcountedbase") { +@@ -1003,6 +1036,7 @@ rtc_source_set("refcountedbase") { } rtc_library("ice_transport_factory") { @@ -335,7 +335,7 @@ index 47f3e23450..462739dea8 100644 visibility = [ "*" ] sources = [ "ice_transport_factory.cc", -@@ -1025,6 +1059,7 @@ rtc_library("ice_transport_factory") { +@@ -1026,6 +1060,7 @@ rtc_library("ice_transport_factory") { "rtc_event_log", ] } diff --git a/third_party/libwebrtc/moz-patch-stack/s0102.patch b/third_party/libwebrtc/moz-patch-stack/s0102.patch @@ -126,7 +126,7 @@ index 771e0b196a..7e1e8353ab 100644 "Generated during 'gn gen' by //BUILD.gn.", "", diff --git a/api/BUILD.gn b/api/BUILD.gn -index 462739dea8..c6bf3e1bce 100644 +index 7758d17af0..129e246104 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -8,8 +8,8 @@ diff --git a/third_party/libwebrtc/pc/jsep_session_description.cc b/third_party/libwebrtc/pc/jsep_session_description.cc @@ -150,20 +150,50 @@ std::unique_ptr<SessionDescriptionInterface> CreateRollbackSessionDescription( SdpType::kRollback, /*description=*/nullptr, session_id, session_version); } -JsepSessionDescription::JsepSessionDescription(SdpType type) : type_(type) {} +SessionDescriptionInternal::SessionDescriptionInternal( + SdpType type, + std::unique_ptr<SessionDescription> description, + absl::string_view id, + absl::string_view version) + : sdp_type_(type), + id_(id), + version_(version), + description_(std::move(description)) { + RTC_DCHECK(description_ || sdp_type_ == SdpType::kRollback); +} -JsepSessionDescription::JsepSessionDescription( +SessionDescriptionInternal::~SessionDescriptionInternal() = default; + +size_t SessionDescriptionInternal::mediasection_count() const { + return description_ ? description_->contents().size() : 0u; +} + +void SessionDescriptionInternal::RelinquishThreadOwnership() { + sequence_checker_.Detach(); +} + +SessionDescriptionInterface::SessionDescriptionInterface( SdpType type, std::unique_ptr<SessionDescription> description, + absl::string_view id, + absl::string_view version) + : SessionDescriptionInternal(type, std::move(description), id, version) {} + +JsepSessionDescription::JsepSessionDescription(SdpType type) + : SessionDescriptionInterface(type, nullptr, "", "") {} + +JsepSessionDescription::JsepSessionDescription( + SdpType type, + std::unique_ptr<SessionDescription> desc, absl::string_view session_id, absl::string_view session_version, std::vector<IceCandidateCollection> candidates) - : description_(std::move(description)), - session_id_(session_id), - session_version_(session_version), - type_(type), + : SessionDescriptionInterface(type, + std::move(desc), + session_id, + session_version), candidate_collection_(std::move(candidates)) { - RTC_DCHECK(description_ || type == SdpType::kRollback); + RTC_DCHECK(description() || type == SdpType::kRollback); RTC_DCHECK(candidate_collection_.empty() || candidate_collection_.size() == number_of_mediasections()); candidate_collection_.resize(number_of_mediasections()); @@ -174,9 +204,8 @@ JsepSessionDescription::~JsepSessionDescription() {} std::unique_ptr<SessionDescriptionInterface> JsepSessionDescription::Clone() const { return std::make_unique<JsepSessionDescription>( - GetType(), description_.get() ? description_->Clone() : nullptr, - session_id_, session_version_, - CloneCandidateCollection(candidate_collection_)); + sdp_type(), description() ? description()->Clone() : nullptr, id(), + version(), CloneCandidateCollection(candidate_collection_)); } bool JsepSessionDescription::AddCandidate(const IceCandidate* candidate) { @@ -187,9 +216,9 @@ bool JsepSessionDescription::AddCandidate(const IceCandidate* candidate) { return false; } const std::string& mediasection_mid = - description_->contents()[mediasection_index].mid(); + description()->contents()[mediasection_index].mid(); const TransportInfo* transport_info = - description_->GetTransportInfoByName(mediasection_mid); + description()->GetTransportInfoByName(mediasection_mid); if (!transport_info) { return false; } @@ -219,7 +248,7 @@ bool JsepSessionDescription::AddCandidate(const IceCandidate* candidate) { std::move(updated_candidate_wrapper)); UpdateConnectionAddress( candidate_collection_[mediasection_index], - description_->contents()[mediasection_index].media_description()); + description()->contents()[mediasection_index].media_description()); } return true; @@ -235,16 +264,10 @@ bool JsepSessionDescription::RemoveCandidate(const IceCandidate* candidate) { } UpdateConnectionAddress( candidate_collection_[mediasection_index], - description_->contents()[mediasection_index].media_description()); + description()->contents()[mediasection_index].media_description()); return true; } -size_t JsepSessionDescription::number_of_mediasections() const { - if (!description_) - return 0; - return description_->contents().size(); -} - const IceCandidateCollection* JsepSessionDescription::candidates( size_t mediasection_index) const { if (mediasection_index >= candidate_collection_.size()) @@ -253,7 +276,7 @@ const IceCandidateCollection* JsepSessionDescription::candidates( } bool JsepSessionDescription::ToString(std::string* out) const { - if (!description_ || !out) { + if (!description() || !out) { return false; } *out = SdpSerialize(*this); @@ -261,14 +284,14 @@ bool JsepSessionDescription::ToString(std::string* out) const { } bool JsepSessionDescription::IsValidMLineIndex(int index) const { - RTC_DCHECK(description_); + RTC_DCHECK(description()); return index >= 0 && - index < static_cast<int>(description_->contents().size()); + index < static_cast<int>(description()->contents().size()); } bool JsepSessionDescription::GetMediasectionIndex(const IceCandidate* candidate, size_t* index) const { - if (!candidate || !index || !description_) { + if (!candidate || !index || !description()) { return false; } @@ -283,7 +306,7 @@ bool JsepSessionDescription::GetMediasectionIndex(const IceCandidate* candidate, } int JsepSessionDescription::GetMediasectionIndex(absl::string_view mid) const { - const auto& contents = description_->contents(); + const auto& contents = description()->contents(); auto it = std::find_if(contents.begin(), contents.end(), [&](const auto& content) { return mid == content.mid(); });