diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/peerconnection')
65 files changed, 1303 insertions, 757 deletions
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn index 48f247fe314..ac8dae244ed 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn @@ -3,6 +3,7 @@ # found in the LICENSE file. import("//third_party/blink/renderer/modules/modules.gni") +import("//third_party/webrtc/webrtc.gni") blink_modules_sources("peerconnection") { sources = [ @@ -156,6 +157,15 @@ blink_modules_sources("peerconnection") { source_set("test_support") { testonly = true + # TODO(crbug.com/1173961): avoid depending on testonly webrtc targets. + if (rtc_include_tests) { + # This target uses some webrtc targets that are not part of + # "webrtc_component". This target relies on the fact that including a header + # that is not tracked by GN works without raising any warning. However it + # leads to build errors if rtc_include_tests = true. + check_includes = false + } + sources = [ "fake_rtc_rtp_transceiver_impl.cc", "fake_rtc_rtp_transceiver_impl.h", diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/DIR_METADATA b/chromium/third_party/blink/renderer/modules/peerconnection/DIR_METADATA new file mode 100644 index 00000000000..7fdbb5e4bdd --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/DIR_METADATA @@ -0,0 +1,3 @@ +monorail { + component: "Blink>WebRTC" +}
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS b/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS index b2a8f2b2cb5..cf2e30ab384 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS +++ b/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS @@ -4,5 +4,3 @@ hta@chromium.org orphis@chromium.org steveanton@chromium.org tommi@chromium.org - -# COMPONENT: Blink>WebRTC diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h index 09da798acdf..afc0d8c1b16 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h @@ -6,7 +6,9 @@ #include "base/memory/scoped_refptr.h" #include "base/single_thread_task_runner.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/persistent.h" +#include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/webrtc/api/dtls_transport_interface.h" // The DtlsTransportProxy class takes care of thread-jumping when diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc index b235aaa2fb3..41e7cc11171 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h" +#include <utility> + #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h" @@ -24,8 +26,7 @@ IceTransportProxy::IceTransportProxy( delegate_(delegate), feature_handle_for_scheduler_(frame.GetFrameScheduler()->RegisterFeature( SchedulingPolicy::Feature::kWebRTC, - {SchedulingPolicy::DisableAggressiveThrottling(), - SchedulingPolicy::RecordMetricsForBackForwardCache()})) { + {SchedulingPolicy::DisableAggressiveThrottling()})) { DCHECK(host_thread_); DCHECK(delegate_); DCHECK(adapter_factory); @@ -37,11 +38,10 @@ IceTransportProxy::IceTransportProxy( // (configured above) will ensure it gets deleted on the host thread. host_.reset(new IceTransportHost(proxy_thread_, host_thread_, weak_ptr_factory_.GetWeakPtr())); - PostCrossThreadTask( - *host_thread_, FROM_HERE, - CrossThreadBindOnce(&IceTransportHost::Initialize, - CrossThreadUnretained(host_.get()), - WTF::Passed(std::move(adapter_factory)))); + PostCrossThreadTask(*host_thread_, FROM_HERE, + CrossThreadBindOnce(&IceTransportHost::Initialize, + CrossThreadUnretained(host_.get()), + std::move(adapter_factory))); } IceTransportProxy::~IceTransportProxy() { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h index b999131ed61..b0d876054bc 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h @@ -8,7 +8,9 @@ #include "base/memory/scoped_refptr.h" #include "base/single_thread_task_runner.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/persistent.h" +#include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/webrtc/api/sctp_transport_interface.h" // The SctpTransportProxy class takes care of thread-jumping when diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc index 4f84dd281ec..d515f5003e0 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc @@ -252,4 +252,19 @@ FakeRTCRtpTransceiverImpl::FiredDirection() const { return base::nullopt; } +webrtc::RTCError FakeRTCRtpTransceiverImpl::SetOfferedRtpHeaderExtensions( + Vector<webrtc::RtpHeaderExtensionCapability> header_extensions) { + return webrtc::RTCError(webrtc::RTCErrorType::UNSUPPORTED_OPERATION); +} + +Vector<webrtc::RtpHeaderExtensionCapability> +FakeRTCRtpTransceiverImpl::HeaderExtensionsNegotiated() const { + return {}; +} + +Vector<webrtc::RtpHeaderExtensionCapability> +FakeRTCRtpTransceiverImpl::HeaderExtensionsToOffer() const { + return {}; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h index 9c19b3ed405..54fbe8fd967 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h @@ -111,6 +111,12 @@ class FakeRTCRtpTransceiverImpl : public RTCRtpTransceiverPlatform { const override; base::Optional<webrtc::RtpTransceiverDirection> FiredDirection() const override; + webrtc::RTCError SetOfferedRtpHeaderExtensions( + Vector<webrtc::RtpHeaderExtensionCapability> header_extensions) override; + Vector<webrtc::RtpHeaderExtensionCapability> HeaderExtensionsNegotiated() + const override; + Vector<webrtc::RtpHeaderExtensionCapability> HeaderExtensionsToOffer() + const override; private: base::Optional<std::string> mid_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.cc b/chromium/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.cc index 4a3403cd438..b06cc772f03 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.cc @@ -3,8 +3,11 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_capability.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.h" + +#include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_capabilities.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_codec_capability.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_header_extension_capability.h" #include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h b/chromium/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h index 04a63aa27e2..07376aeb544 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/identifiability_metrics.h @@ -5,11 +5,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_IDENTIFIABILITY_METRICS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_IDENTIFIABILITY_METRICS_H_ -#include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.h" - namespace blink { +class RTCRtpCapabilities; +class IdentifiableTokenBuilder; + void IdentifiabilityAddRTCRtpCapabilitiesToBuilder( IdentifiableTokenBuilder& builder, const RTCRtpCapabilities& capabilities); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc index 6563f22ec08..976efbd3a05 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc @@ -15,6 +15,7 @@ #include "media/base/timestamp_constants.h" #include "media/base/video_frame.h" #include "media/base/video_util.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/webrtc/track_observer.h" @@ -51,7 +52,7 @@ class WebRtcEncodedVideoFrame : public EncodedVideoFrame { public: explicit WebRtcEncodedVideoFrame(const webrtc::RecordableEncodedFrame& frame) : buffer_(frame.encoded_buffer()), - codec_(FromWebRtcVideoCodec(frame.codec())), + codec_(WebRtcToMediaVideoCodec(frame.codec())), is_key_frame_(frame.is_key_frame()), resolution_(frame.resolution().width, frame.resolution().height) { if (frame.color_space()) { @@ -74,19 +75,6 @@ class WebRtcEncodedVideoFrame : public EncodedVideoFrame { gfx::Size Resolution() const override { return resolution_; } private: - static media::VideoCodec FromWebRtcVideoCodec(webrtc::VideoCodecType codec) { - switch (codec) { - case webrtc::kVideoCodecVP8: - return media::kCodecVP8; - case webrtc::kVideoCodecVP9: - return media::kCodecVP9; - case webrtc::kVideoCodecH264: - return media::kCodecH264; - default: - return media::kUnknownVideoCodec; - } - } - rtc::scoped_refptr<const webrtc::EncodedImageBufferInterface> buffer_; media::VideoCodec codec_; bool is_key_frame_; @@ -136,22 +124,17 @@ class MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate EncodedVideoFrameCB encoded_frame_callback_; // Timestamp of the first received frame. - base::TimeDelta start_timestamp_; - - // WebRTC Chromium timestamp diff - const base::TimeDelta time_diff_; - - // Timestamp of the first received encoded frame. - base::TimeDelta start_timestamp_encoded_; - - // WebRTC Chromium timestamp diff - const base::TimeDelta time_diff_encoded_; + base::Optional<base::TimeTicks> start_timestamp_; // WebRTC real time clock, needed to determine NTP offset. webrtc::Clock* clock_; // Offset between NTP clock and WebRTC clock. const int64_t ntp_offset_; + + // Determined from a feature flag; if set WebRTC won't forward an unspecified + // color space. + const bool ignore_unspecified_color_space_; }; MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate:: @@ -162,18 +145,11 @@ MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate:: : io_task_runner_(io_task_runner), frame_callback_(std::move(new_frame_callback)), encoded_frame_callback_(std::move(encoded_frame_callback)), - start_timestamp_(media::kNoTimestamp), - // TODO(qiangchen): There can be two differences between clocks: 1) - // the offset, 2) the rate (i.e., one clock runs faster than the other). - // See http://crbug/516700 - time_diff_(base::TimeTicks::Now() - base::TimeTicks() - - base::TimeDelta::FromMicroseconds(rtc::TimeMicros())), - start_timestamp_encoded_(media::kNoTimestamp), - time_diff_encoded_(base::TimeTicks::Now() - base::TimeTicks() - - base::TimeDelta::FromMicroseconds(rtc::TimeMicros())), clock_(webrtc::Clock::GetRealTimeClock()), ntp_offset_(clock_->TimeInMilliseconds() - - clock_->CurrentNtpInMilliseconds()) {} + clock_->CurrentNtpInMilliseconds()), + ignore_unspecified_color_space_(base::FeatureList::IsEnabled( + features::kWebRtcIgnoreUnspecifiedColorSpace)) {} MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate:: ~RemoteVideoSourceDelegate() = default; @@ -182,17 +158,14 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( const webrtc::VideoFrame& incoming_frame) { const bool render_immediately = incoming_frame.timestamp_us() == 0; const base::TimeTicks current_time = base::TimeTicks::Now(); - const base::TimeDelta incoming_timestamp = - render_immediately - ? current_time - base::TimeTicks() - : base::TimeDelta::FromMicroseconds(incoming_frame.timestamp_us()); const base::TimeTicks render_time = - render_immediately ? base::TimeTicks() + incoming_timestamp - : base::TimeTicks() + incoming_timestamp + time_diff_; - if (start_timestamp_ == media::kNoTimestamp) - start_timestamp_ = incoming_timestamp; - const base::TimeDelta elapsed_timestamp = - incoming_timestamp - start_timestamp_; + render_immediately + ? current_time + : base::TimeTicks() + base::TimeDelta::FromMicroseconds( + incoming_frame.timestamp_us()); + if (!start_timestamp_) + start_timestamp_ = render_time; + const base::TimeDelta elapsed_timestamp = render_time - *start_timestamp_; TRACE_EVENT2("webrtc", "RemoteVideoSourceDelegate::RenderFrame", "Ideal Render Instant", render_time.ToInternalValue(), "Timestamp", elapsed_timestamp.InMicroseconds()); @@ -284,11 +257,23 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( // Rotation may be explicitly set sometimes. if (incoming_frame.rotation() != webrtc::kVideoRotation_0) { - video_frame->metadata()->rotation = + video_frame->metadata().transformation = WebRtcToMediaVideoRotation(incoming_frame.rotation()); } - if (incoming_frame.color_space()) { + // The second clause of the condition is controlled by the feature flag + // WebRtcIgnoreUnspecifiedColorSpace. If the feature is enabled we won't try + // to guess a color space if the webrtc::ColorSpace is unspecified. If the + // feature is disabled (default), an unspecified color space will get + // converted into a gfx::ColorSpace set to BT709. + if (incoming_frame.color_space() && + !(ignore_unspecified_color_space_ && + incoming_frame.color_space()->primaries() == + webrtc::ColorSpace::PrimaryID::kUnspecified && + incoming_frame.color_space()->transfer() == + webrtc::ColorSpace::TransferID::kUnspecified && + incoming_frame.color_space()->matrix() == + webrtc::ColorSpace::MatrixID::kUnspecified)) { video_frame->set_color_space( WebRtcToMediaVideoColorSpace(*incoming_frame.color_space()) .ToGfxColorSpace()); @@ -297,36 +282,33 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( // Run render smoothness algorithm only when we don't have to render // immediately. if (!render_immediately) - video_frame->metadata()->reference_time = render_time; + video_frame->metadata().reference_time = render_time; if (incoming_frame.max_composition_delay_in_frames()) { - video_frame->metadata()->maximum_composition_delay_in_frames = + video_frame->metadata().maximum_composition_delay_in_frames = *incoming_frame.max_composition_delay_in_frames(); } - video_frame->metadata()->decode_end_time = current_time; + video_frame->metadata().decode_end_time = current_time; // RTP_TIMESTAMP, PROCESSING_TIME, and CAPTURE_BEGIN_TIME are all exposed // through the JavaScript callback mechanism // video.requestVideoFrameCallback(). - video_frame->metadata()->rtp_timestamp = + video_frame->metadata().rtp_timestamp = static_cast<double>(incoming_frame.timestamp()); if (incoming_frame.processing_time()) { - video_frame->metadata()->processing_time = - base::TimeDelta::FromMicroseconds( - incoming_frame.processing_time()->Elapsed().us()); + video_frame->metadata().processing_time = base::TimeDelta::FromMicroseconds( + incoming_frame.processing_time()->Elapsed().us()); } // Set capture time to the NTP time, which is the estimated capture time // converted to the local clock. if (incoming_frame.ntp_time_ms() > 0) { const base::TimeTicks capture_time = - base::TimeTicks() + - base::TimeDelta::FromMilliseconds(incoming_frame.ntp_time_ms() + - ntp_offset_) + - time_diff_; - video_frame->metadata()->capture_begin_time = capture_time; + base::TimeTicks() + base::TimeDelta::FromMilliseconds( + incoming_frame.ntp_time_ms() + ntp_offset_); + video_frame->metadata().capture_begin_time = capture_time; } // Set receive time to arrival of last packet. @@ -341,8 +323,8 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( ->receive_time_ms(); const base::TimeTicks receive_time = base::TimeTicks() + - base::TimeDelta::FromMilliseconds(last_packet_arrival_ms) + time_diff_; - video_frame->metadata()->receive_time = receive_time; + base::TimeDelta::FromMilliseconds(last_packet_arrival_ms); + video_frame->metadata().receive_time = receive_time; } // Use our computed render time as estimated capture time. If timestamp_us() @@ -361,21 +343,18 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate:: base::TimeTicks estimated_capture_time) { DCHECK(io_task_runner_->BelongsToCurrentThread()); TRACE_EVENT0("webrtc", "RemoteVideoSourceDelegate::DoRenderFrameOnIOThread"); - frame_callback_.Run(std::move(video_frame), estimated_capture_time); + frame_callback_.Run(std::move(video_frame), {}, estimated_capture_time); } void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( const webrtc::RecordableEncodedFrame& frame) { const bool render_immediately = frame.render_time().us() == 0; const base::TimeTicks current_time = base::TimeTicks::Now(); - const base::TimeDelta incoming_timestamp = - render_immediately - ? current_time - base::TimeTicks() - : base::TimeDelta::FromMicroseconds(frame.render_time().us()); const base::TimeTicks render_time = render_immediately - ? base::TimeTicks() + incoming_timestamp - : base::TimeTicks() + incoming_timestamp + time_diff_encoded_; + ? current_time + : base::TimeTicks() + + base::TimeDelta::FromMicroseconds(frame.render_time().us()); // Use our computed render time as estimated capture time. If render_time() // is set by WebRTC, it's based on the RTP timestamps in the frame's packets, @@ -494,6 +473,11 @@ void MediaStreamRemoteVideoSource::RequestRefreshFrame() { } } +base::WeakPtr<MediaStreamVideoSource> MediaStreamRemoteVideoSource::GetWeakPtr() + const { + return weak_factory_.GetWeakPtr(); +} + void MediaStreamRemoteVideoSource::OnEncodedSinkEnabled() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!observer_ || !observer_->track()) { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.h b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.h index 353f59bb0db..c9f27497713 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.h @@ -36,6 +36,7 @@ class MODULES_EXPORT MediaStreamRemoteVideoSource // MediaStreamVideoSource overrides. bool SupportsEncodedOutput() const override; void RequestRefreshFrame() override; + base::WeakPtr<MediaStreamVideoSource> GetWeakPtr() const override; protected: // Implements MediaStreamVideoSource. @@ -60,6 +61,8 @@ class MODULES_EXPORT MediaStreamRemoteVideoSource scoped_refptr<RemoteVideoSourceDelegate> delegate_; std::unique_ptr<TrackObserver> observer_; + base::WeakPtrFactory<MediaStreamVideoSource> weak_factory_{this}; + DISALLOW_COPY_AND_ASSIGN(MediaStreamRemoteVideoSource); }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc index c786417779c..70815a0eba5 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc @@ -13,8 +13,10 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/test/gmock_callback_support.h" +#include "base/test/scoped_feature_list.h" #include "media/base/video_frame.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h" @@ -36,14 +38,6 @@ namespace blink { namespace { -// On Linux the clock in WebRTC and Chromium are more or less the same. -// On Windows they are not the same and the accuracy of the measured time -// difference is typically in the range [-1, 1] ms. However, for certain builds -// such as ASAN it can be in the order of 10-20 ms. Since this is compensated -// for both here and in MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate -// we need to use the worst case difference between these two measurements. -float kChromiumWebRtcMaxTimeDiffMs = 40.0f; - using base::test::RunOnceClosure; using ::testing::_; using ::testing::Gt; @@ -76,9 +70,8 @@ class MediaStreamRemoteVideoSourceTest : public ::testing::Test { webrtc_video_source_(blink::MockWebRtcVideoTrackSource::Create( /*supports_encoded_output=*/true)), webrtc_video_track_( - blink::MockWebRtcVideoTrack::Create("test", webrtc_video_source_)), - time_diff_(base::TimeTicks::Now() - base::TimeTicks() - - base::TimeDelta::FromMicroseconds(rtc::TimeMicros())) {} + blink::MockWebRtcVideoTrack::Create("test", webrtc_video_source_)) { + } void SetUp() override { scoped_refptr<base::SingleThreadTaskRunner> main_thread = @@ -286,21 +279,82 @@ TEST_F(MediaStreamRemoteVideoSourceTest, PreservesColorSpace) { track->RemoveSink(&sink); } -// These tests depend on measuring the difference between the internal WebRTC -// clock and Chromium's clock. Due to this they are performance sensitive and -// appear to be flaky for builds with ASAN enabled. -#if defined(ADDRESS_SANITIZER) -#define MAYBE_PopulateRequestAnimationFrameMetadata \ - DISABLED_PopulateRequestAnimationFrameMetadata -#define MAYBE_ReferenceTimeEqualsTimestampUs \ - DISABLED_ReferenceTimeEqualsTimestampUs -#else -#define MAYBE_PopulateRequestAnimationFrameMetadata \ - PopulateRequestAnimationFrameMetadata -#define MAYBE_ReferenceTimeEqualsTimestampUs ReferenceTimeEqualsTimestampUs -#endif TEST_F(MediaStreamRemoteVideoSourceTest, - MAYBE_PopulateRequestAnimationFrameMetadata) { + UnspecifiedColorSpaceIsTreatedAsBt709) { + std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack()); + blink::MockMediaStreamVideoSink sink; + track->AddSink(&sink, sink.GetDeliverFrameCB(), false); + + base::RunLoop run_loop; + EXPECT_CALL(sink, OnVideoFrame) + .WillOnce(RunOnceClosure(run_loop.QuitClosure())); + rtc::scoped_refptr<webrtc::I420Buffer> buffer( + new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240)); + webrtc::ColorSpace kColorSpace(webrtc::ColorSpace::PrimaryID::kUnspecified, + webrtc::ColorSpace::TransferID::kUnspecified, + webrtc::ColorSpace::MatrixID::kUnspecified, + webrtc::ColorSpace::RangeID::kLimited); + const webrtc::VideoFrame& input_frame = + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(buffer) + .set_timestamp_ms(0) + .set_rotation(webrtc::kVideoRotation_0) + .set_color_space(kColorSpace) + .build(); + source()->SinkInterfaceForTesting()->OnFrame(input_frame); + run_loop.Run(); + + EXPECT_EQ(1, sink.number_of_frames()); + scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); + EXPECT_TRUE(output_frame); + EXPECT_TRUE(output_frame->ColorSpace() == + gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT709, + gfx::ColorSpace::TransferID::BT709, + gfx::ColorSpace::MatrixID::BT709, + gfx::ColorSpace::RangeID::LIMITED)); + track->RemoveSink(&sink); +} + +TEST_F(MediaStreamRemoteVideoSourceTest, UnspecifiedColorSpaceIsIgnored) { + base::test::ScopedFeatureList scoped_feauture_list; + scoped_feauture_list.InitAndEnableFeature( + blink::features::kWebRtcIgnoreUnspecifiedColorSpace); + std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack()); + blink::MockMediaStreamVideoSink sink; + track->AddSink(&sink, sink.GetDeliverFrameCB(), false); + + base::RunLoop run_loop; + EXPECT_CALL(sink, OnVideoFrame) + .WillOnce(RunOnceClosure(run_loop.QuitClosure())); + rtc::scoped_refptr<webrtc::I420Buffer> buffer( + new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240)); + webrtc::ColorSpace kColorSpace(webrtc::ColorSpace::PrimaryID::kUnspecified, + webrtc::ColorSpace::TransferID::kUnspecified, + webrtc::ColorSpace::MatrixID::kUnspecified, + webrtc::ColorSpace::RangeID::kLimited); + const webrtc::VideoFrame& input_frame = + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(buffer) + .set_timestamp_ms(0) + .set_rotation(webrtc::kVideoRotation_0) + .set_color_space(kColorSpace) + .build(); + source()->SinkInterfaceForTesting()->OnFrame(input_frame); + run_loop.Run(); + + EXPECT_EQ(1, sink.number_of_frames()); + scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); + EXPECT_TRUE(output_frame); + EXPECT_TRUE(output_frame->ColorSpace() == + gfx::ColorSpace(gfx::ColorSpace::PrimaryID::INVALID, + gfx::ColorSpace::TransferID::INVALID, + gfx::ColorSpace::MatrixID::INVALID, + gfx::ColorSpace::RangeID::INVALID)); + track->RemoveSink(&sink); +} + +TEST_F(MediaStreamRemoteVideoSourceTest, + PopulateRequestAnimationFrameMetadata) { std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack()); blink::MockMediaStreamVideoSink sink; track->AddSink(&sink, sink.GetDeliverFrameCB(), false); @@ -327,22 +381,19 @@ TEST_F(MediaStreamRemoteVideoSourceTest, clock->CurrentNtpInMilliseconds() - clock->TimeInMilliseconds(); const webrtc::Timestamp kCaptureTimeNtp = kCaptureTime + webrtc::TimeDelta::Millis(ntp_offset); - // Expected capture time in Chromium epoch. + // Expected capture time. base::TimeTicks kExpectedCaptureTime = - base::TimeTicks() + base::TimeDelta::FromMilliseconds(kCaptureTime.ms()) + - time_diff(); + base::TimeTicks() + base::TimeDelta::FromMilliseconds(kCaptureTime.ms()); webrtc::RtpPacketInfos::vector_type packet_infos; for (int i = 0; i < 4; ++i) { packet_infos.emplace_back(kSsrc, kCsrcs, kRtpTimestamp, absl::nullopt, absl::nullopt, kProcessingStart.ms() - 100 + i); } - // Expected receive time should be the same as the last arrival time, in - // Chromium epoch. + // Expected receive time should be the same as the last arrival time. base::TimeTicks kExpectedReceiveTime = base::TimeTicks() + - base::TimeDelta::FromMilliseconds(kProcessingStart.ms() - 100 + 3) + - time_diff(); + base::TimeDelta::FromMilliseconds(kProcessingStart.ms() - 100 + 3); webrtc::VideoFrame input_frame = webrtc::VideoFrame::Builder() @@ -360,25 +411,32 @@ TEST_F(MediaStreamRemoteVideoSourceTest, scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); EXPECT_TRUE(output_frame); - EXPECT_FLOAT_EQ(output_frame->metadata()->processing_time->InSecondsF(), + EXPECT_FLOAT_EQ(output_frame->metadata().processing_time->InSecondsF(), kProcessingTime); + // The NTP offset is estimated both here and in the code that is tested. + // Therefore, we cannot exactly determine what capture_begin_time will be set + // to. + // TODO(kron): Find a lower tolerance without causing the test to be flaky or + // make the clock injectable so that a fake clock can be used in the test. + constexpr float kNtpOffsetToleranceMs = 40.0; EXPECT_NEAR( - (*output_frame->metadata()->capture_begin_time - kExpectedCaptureTime) + (*output_frame->metadata().capture_begin_time - kExpectedCaptureTime) .InMillisecondsF(), - 0.0f, kChromiumWebRtcMaxTimeDiffMs); + 0.0f, kNtpOffsetToleranceMs); - EXPECT_NEAR((*output_frame->metadata()->receive_time - kExpectedReceiveTime) - .InMillisecondsF(), - 0.0f, kChromiumWebRtcMaxTimeDiffMs); + EXPECT_FLOAT_EQ( + (*output_frame->metadata().receive_time - kExpectedReceiveTime) + .InMillisecondsF(), + 0.0f); - EXPECT_EQ(static_cast<uint32_t>(*output_frame->metadata()->rtp_timestamp), + EXPECT_EQ(static_cast<uint32_t>(*output_frame->metadata().rtp_timestamp), kRtpTimestamp); track->RemoveSink(&sink); } -TEST_F(MediaStreamRemoteVideoSourceTest, MAYBE_ReferenceTimeEqualsTimestampUs) { +TEST_F(MediaStreamRemoteVideoSourceTest, ReferenceTimeEqualsTimestampUs) { std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack()); blink::MockMediaStreamVideoSink sink; track->AddSink(&sink, sink.GetDeliverFrameCB(), false); @@ -402,14 +460,29 @@ TEST_F(MediaStreamRemoteVideoSourceTest, MAYBE_ReferenceTimeEqualsTimestampUs) { scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); EXPECT_TRUE(output_frame); - EXPECT_NEAR((*output_frame->metadata()->reference_time - - (base::TimeTicks() + - base::TimeDelta::FromMicroseconds(kTimestampUs) + time_diff())) - .InMillisecondsF(), - 0.0f, kChromiumWebRtcMaxTimeDiffMs); + EXPECT_FLOAT_EQ( + (*output_frame->metadata().reference_time - + (base::TimeTicks() + base::TimeDelta::FromMicroseconds(kTimestampUs))) + .InMillisecondsF(), + 0.0f); track->RemoveSink(&sink); } +TEST_F(MediaStreamRemoteVideoSourceTest, BaseTimeTicksAndRtcMicrosAreTheSame) { + base::TimeTicks first_chromium_timestamp = base::TimeTicks::Now(); + base::TimeTicks webrtc_timestamp = + base::TimeTicks() + base::TimeDelta::FromMicroseconds(rtc::TimeMicros()); + base::TimeTicks second_chromium_timestamp = base::TimeTicks::Now(); + + // Test that the timestamps are correctly ordered, which they can only be if + // the clocks are the same (assuming at least one of the clocks is functioning + // correctly). + EXPECT_GE((webrtc_timestamp - first_chromium_timestamp).InMillisecondsF(), + 0.0f); + EXPECT_GE((second_chromium_timestamp - webrtc_timestamp).InMillisecondsF(), + 0.0f); +} + // This is a special case that is used to signal "render immediately". TEST_F(MediaStreamRemoteVideoSourceTest, NoTimestampUsMeansNoReferenceTime) { std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack()); @@ -432,7 +505,7 @@ TEST_F(MediaStreamRemoteVideoSourceTest, NoTimestampUsMeansNoReferenceTime) { scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); EXPECT_TRUE(output_frame); - EXPECT_FALSE(output_frame->metadata()->reference_time.has_value()); + EXPECT_FALSE(output_frame->metadata().reference_time.has_value()); track->RemoveSink(&sink); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc index 098a06383df..0fb4c27e624 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc @@ -77,8 +77,10 @@ class MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter // destroyed. void ReleaseSourceOnMainThread(); - void OnVideoFrameOnIO(scoped_refptr<media::VideoFrame> frame, - base::TimeTicks estimated_capture_time); + void OnVideoFrameOnIO( + scoped_refptr<media::VideoFrame> frame, + std::vector<scoped_refptr<media::VideoFrame>> scaled_frames, + base::TimeTicks estimated_capture_time); private: friend class WTF::ThreadSafeRefCounted<WebRtcVideoSourceAdapter>; @@ -141,8 +143,13 @@ void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::OnVideoFrameOnIO( scoped_refptr<media::VideoFrame> frame, + std::vector<scoped_refptr<media::VideoFrame>> scaled_frames, base::TimeTicks estimated_capture_time) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); + // TODO(https://crbug.com/1157072): When WebRTC makes use of + // media::VideoFrameFeedback to tell the capturer to deliver |scaled_frames| + // in the encoder's desired resolution, pass along these frames and make use + // of them inside WebRTC. PostCrossThreadTask( *libjingle_worker_thread_.get(), FROM_HERE, CrossThreadBindOnce(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread, @@ -176,7 +183,8 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink( // by removing the need for and dependency on a cricket::VideoCapturer. video_source_ = scoped_refptr<WebRtcVideoTrackSource>( new rtc::RefCountedObject<WebRtcVideoTrackSource>( - is_screencast, needs_denoising, feedback_cb)); + is_screencast, needs_denoising, feedback_cb, + factory->GetGpuFactories())); // TODO(pbos): Consolidate the local video track with the source proxy and // move into PeerConnectionDependencyFactory. This now separately holds on a diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc index 509ea0f3846..51f6076a1de 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc @@ -8,6 +8,7 @@ #include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h" +#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h" #include "third_party/webrtc/api/media_stream_interface.h" #include "third_party/webrtc/api/scoped_refptr.h" @@ -307,51 +308,6 @@ void MockWebRtcVideoTrackSource::AddOrUpdateSink( void MockWebRtcVideoTrackSource::RemoveSink( rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) {} -class MockSessionDescription : public SessionDescriptionInterface { - public: - MockSessionDescription(const std::string& type, const std::string& sdp) - : type_(type), sdp_(sdp) {} - ~MockSessionDescription() override {} - cricket::SessionDescription* description() override { - NOTIMPLEMENTED(); - return nullptr; - } - const cricket::SessionDescription* description() const override { - NOTIMPLEMENTED(); - return nullptr; - } - std::string session_id() const override { - NOTIMPLEMENTED(); - return std::string(); - } - std::string session_version() const override { - NOTIMPLEMENTED(); - return std::string(); - } - std::string type() const override { return type_; } - bool AddCandidate(const IceCandidateInterface* candidate) override { - NOTIMPLEMENTED(); - return false; - } - size_t number_of_mediasections() const override { - NOTIMPLEMENTED(); - return 0; - } - const IceCandidateCollection* candidates( - size_t mediasection_index) const override { - NOTIMPLEMENTED(); - return nullptr; - } - - bool ToString(std::string* out) const override { - *out = sdp_; - return true; - } - - private: - std::string type_; - std::string sdp_; -}; class MockIceCandidate : public IceCandidateInterface { public: @@ -392,7 +348,8 @@ scoped_refptr<webrtc::PeerConnectionInterface> MockPeerConnectionDependencyFactory::CreatePeerConnection( const webrtc::PeerConnectionInterface::RTCConfiguration& config, blink::WebLocalFrame* frame, - webrtc::PeerConnectionObserver* observer) { + webrtc::PeerConnectionObserver* observer, + ExceptionState& exception_state) { return new rtc::RefCountedObject<MockPeerConnectionImpl>(this, observer); } @@ -416,16 +373,6 @@ MockPeerConnectionDependencyFactory::CreateLocalVideoTrack( return track; } -SessionDescriptionInterface* -MockPeerConnectionDependencyFactory::CreateSessionDescription( - const String& type, - const String& sdp, - webrtc::SdpParseError* error) { - if (fail_to_create_session_description_) - return nullptr; - return new MockSessionDescription(type.Utf8(), sdp.Utf8()); -} - webrtc::IceCandidateInterface* MockPeerConnectionDependencyFactory::CreateIceCandidate(const String& sdp_mid, int sdp_mline_index, diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h index 0d583f46883..c904047a342 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h @@ -171,7 +171,8 @@ class MockPeerConnectionDependencyFactory scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection( const webrtc::PeerConnectionInterface::RTCConfiguration& config, blink::WebLocalFrame* frame, - webrtc::PeerConnectionObserver* observer) override; + webrtc::PeerConnectionObserver* observer, + ExceptionState& exception_state) override; scoped_refptr<webrtc::VideoTrackSourceInterface> CreateVideoTrackSourceProxy( webrtc::VideoTrackSourceInterface* source) override; scoped_refptr<webrtc::MediaStreamInterface> CreateLocalMediaStream( @@ -179,10 +180,6 @@ class MockPeerConnectionDependencyFactory scoped_refptr<webrtc::VideoTrackInterface> CreateLocalVideoTrack( const String& id, webrtc::VideoTrackSourceInterface* source) override; - webrtc::SessionDescriptionInterface* CreateSessionDescription( - const String& type, - const String& sdp, - webrtc::SdpParseError* error) override; webrtc::IceCandidateInterface* CreateIceCandidate(const String& sdp_mid, int sdp_mline_index, const String& sdp) override; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc index fc9f9eb0d21..5bd05d8b733 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc @@ -10,10 +10,11 @@ #include <vector> #include "base/check_op.h" +#include "base/containers/contains.h" #include "base/notreached.h" -#include "base/stl_util.h" #include "third_party/blink/renderer/modules/peerconnection/mock_data_channel_impl.h" #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h" #include "third_party/blink/renderer/platform/peerconnection/webrtc_util.h" #include "third_party/webrtc/api/rtp_receiver_interface.h" #include "third_party/webrtc/rtc_base/ref_counted_object.h" @@ -324,8 +325,7 @@ const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer"; MockPeerConnectionImpl::MockPeerConnectionImpl( MockPeerConnectionDependencyFactory* factory, webrtc::PeerConnectionObserver* observer) - : dependency_factory_(factory), - remote_streams_(new rtc::RefCountedObject<MockStreamCollection>), + : remote_streams_(new rtc::RefCountedObject<MockStreamCollection>), hint_audio_(false), hint_video_(false), getstats_result_(true), @@ -503,18 +503,16 @@ void MockPeerConnectionImpl::CreateOffer( CreateSessionDescriptionObserver* observer, const RTCOfferAnswerOptions& options) { DCHECK(observer); - created_sessiondescription_.reset( - dependency_factory_->CreateSessionDescription("unknown", kDummyOffer, - nullptr)); + created_sessiondescription_ = + MockParsedSessionDescription("unknown", kDummyAnswer).release(); } void MockPeerConnectionImpl::CreateAnswer( CreateSessionDescriptionObserver* observer, const RTCOfferAnswerOptions& options) { DCHECK(observer); - created_sessiondescription_.reset( - dependency_factory_->CreateSessionDescription("unknown", kDummyAnswer, - nullptr)); + created_sessiondescription_ = + MockParsedSessionDescription("unknown", kDummyAnswer).release(); } void MockPeerConnectionImpl::SetLocalDescriptionWorker( diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h index 4adc6ce92bb..fcd6afac877 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h @@ -386,9 +386,6 @@ class MockPeerConnectionImpl : public webrtc::DummyPeerConnection { ~MockPeerConnectionImpl() override; private: - // Used for creating MockSessionDescription. - MockPeerConnectionDependencyFactory* dependency_factory_; - std::string stream_label_; std::vector<std::string> local_stream_ids_; rtc::scoped_refptr<MockStreamCollection> remote_streams_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc index da6d4bb9522..c5c9995962c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc @@ -236,6 +236,18 @@ class MockRTCPeerConnectionHandlerPlatform::DummyRTCRtpTransceiverPlatform const override { return base::nullopt; } + webrtc::RTCError SetOfferedRtpHeaderExtensions( + Vector<webrtc::RtpHeaderExtensionCapability> header_extensions) override { + return webrtc::RTCError(webrtc::RTCErrorType::UNSUPPORTED_OPERATION); + } + Vector<webrtc::RtpHeaderExtensionCapability> HeaderExtensionsNegotiated() + const override { + return {}; + } + Vector<webrtc::RtpHeaderExtensionCapability> HeaderExtensionsToOffer() + const override { + return {}; + } private: scoped_refptr<DummyTransceiverInternal> internal_; @@ -251,7 +263,8 @@ MockRTCPeerConnectionHandlerPlatform::~MockRTCPeerConnectionHandlerPlatform() = bool MockRTCPeerConnectionHandlerPlatform::Initialize( const webrtc::PeerConnectionInterface::RTCConfiguration&, const MediaConstraints&, - WebLocalFrame*) { + WebLocalFrame*, + ExceptionState&) { return true; } @@ -280,11 +293,11 @@ void MockRTCPeerConnectionHandlerPlatform::SetLocalDescription( void MockRTCPeerConnectionHandlerPlatform::SetLocalDescription( RTCVoidRequest*, - RTCSessionDescriptionPlatform*) {} + ParsedSessionDescription) {} void MockRTCPeerConnectionHandlerPlatform::SetRemoteDescription( RTCVoidRequest*, - RTCSessionDescriptionPlatform*) {} + ParsedSessionDescription) {} const webrtc::PeerConnectionInterface::RTCConfiguration& MockRTCPeerConnectionHandlerPlatform::GetConfiguration() const { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h index 1a9cb0ff6e0..d82ad3682a5 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h @@ -17,6 +17,65 @@ namespace blink { +class MockSessionDescription : public webrtc::SessionDescriptionInterface { + public: + MockSessionDescription(const std::string& type, const std::string& sdp) + : type_(type), sdp_(sdp) {} + ~MockSessionDescription() override = default; + cricket::SessionDescription* description() override { + NOTIMPLEMENTED(); + return nullptr; + } + const cricket::SessionDescription* description() const override { + NOTIMPLEMENTED(); + return nullptr; + } + std::string session_id() const override { + NOTIMPLEMENTED(); + return std::string(); + } + std::string session_version() const override { + NOTIMPLEMENTED(); + return std::string(); + } + std::string type() const override { return type_; } + bool AddCandidate(const webrtc::IceCandidateInterface* candidate) override { + NOTIMPLEMENTED(); + return false; + } + size_t number_of_mediasections() const override { + NOTIMPLEMENTED(); + return 0; + } + const webrtc::IceCandidateCollection* candidates( + size_t mediasection_index) const override { + NOTIMPLEMENTED(); + return nullptr; + } + + bool ToString(std::string* out) const override { + *out = sdp_; + return true; + } + + private: + std::string type_; + std::string sdp_; +}; + +// Class for creating a ParsedSessionDescription without running the parser. +// It returns an empty (but non-null) description object. +class MockParsedSessionDescription : public ParsedSessionDescription { + public: + MockParsedSessionDescription(const String& type, const String& sdp) + : ParsedSessionDescription(type, sdp) { + description_ = + std::make_unique<MockSessionDescription>(type.Utf8(), sdp.Utf8()); + } + // Constructor for creating an error-returning session description. + MockParsedSessionDescription() : ParsedSessionDescription("error", "error") {} +}; + // TODO(https://crbug.com/908461): This is currently implemented as NO-OPs or to // create dummy objects whose methods return default values. Consider renaming // the class, changing it to be GMOCK friendly or deleting it. @@ -29,7 +88,8 @@ class MockRTCPeerConnectionHandlerPlatform : public RTCPeerConnectionHandler { bool Initialize(const webrtc::PeerConnectionInterface::RTCConfiguration&, const MediaConstraints&, - WebLocalFrame*) override; + WebLocalFrame*, + ExceptionState&) override; void Stop() override; void StopAndUnregister() override; @@ -44,10 +104,8 @@ class MockRTCPeerConnectionHandlerPlatform : public RTCPeerConnectionHandler { void CreateAnswer(RTCSessionDescriptionRequest*, RTCAnswerOptionsPlatform*) override; void SetLocalDescription(RTCVoidRequest*) override; - void SetLocalDescription(RTCVoidRequest*, - RTCSessionDescriptionPlatform*) override; - void SetRemoteDescription(RTCVoidRequest*, - RTCSessionDescriptionPlatform*) override; + void SetLocalDescription(RTCVoidRequest*, ParsedSessionDescription) override; + void SetRemoteDescription(RTCVoidRequest*, ParsedSessionDescription) override; const webrtc::PeerConnectionInterface::RTCConfiguration& GetConfiguration() const override; webrtc::RTCErrorType SetConfiguration( @@ -81,7 +139,6 @@ class MockRTCPeerConnectionHandlerPlatform : public RTCPeerConnectionHandler { void TrackIceConnectionStateChange( RTCPeerConnectionHandler::IceConnectionStateVersion version, webrtc::PeerConnectionInterface::IceConnectionState state) override; - private: class DummyRTCRtpTransceiverPlatform; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc index d765ec01b04..91a0720a9c3 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc @@ -19,6 +19,7 @@ #include "build/build_config.h" #include "crypto/openssl_util.h" #include "jingle/glue/thread_wrapper.h" +#include "media/base/decoder_factory.h" #include "media/base/media_permission.h" #include "media/media_buildflags.h" #include "media/video/gpu_video_accelerator_factories.h" @@ -32,6 +33,7 @@ #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.h" +#include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h" #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" @@ -115,6 +117,9 @@ PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( create_p2p_socket_dispatcher ? new P2PSocketDispatcher() : nullptr), chrome_signaling_thread_("WebRTC_Signaling"), chrome_network_thread_("WebRTC_Network") { + if (base::FeatureList::IsEnabled(features::kWebRtcDistinctWorkerThread)) { + chrome_worker_thread_.emplace("WebRTC_Worker"); + } TryScheduleStunProbeTrial(); } @@ -162,10 +167,12 @@ void PeerConnectionDependencyFactory::WillDestroyCurrentMessageLoop() { void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { DCHECK(!pc_factory_.get()); DCHECK(!signaling_thread_); + DCHECK(!worker_thread_); DCHECK(!network_thread_); DCHECK(!network_manager_); DCHECK(!socket_factory_); DCHECK(!chrome_signaling_thread_.IsRunning()); + DCHECK(!chrome_worker_thread_ || !chrome_worker_thread_->IsRunning()); DCHECK(!chrome_network_thread_.IsRunning()); DVLOG(1) << "PeerConnectionDependencyFactory::CreatePeerConnectionFactory()"; @@ -195,6 +202,19 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { return; } + base::WaitableEvent start_worker_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + if (chrome_worker_thread_) { + CHECK(chrome_worker_thread_->Start()); + PostCrossThreadTask( + *chrome_worker_thread_->task_runner().get(), FROM_HERE, + CrossThreadBindOnce( + &PeerConnectionDependencyFactory::InitializeWorkerThread, + CrossThreadUnretained(this), CrossThreadUnretained(&worker_thread_), + CrossThreadUnretained(&start_worker_event))); + } + CHECK(chrome_signaling_thread_.Start()); CHECK(chrome_network_thread_.Start()); @@ -222,6 +242,13 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { create_network_manager_event.Wait(); CHECK(network_thread_); + // Wait for the worker thread, since `InitializeSignalingThread` needs to + // refer to `worker_thread_`. + if (chrome_worker_thread_) { + start_worker_event.Wait(); + CHECK(worker_thread_); + } + base::WaitableEvent start_signaling_event( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -231,6 +258,7 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { &PeerConnectionDependencyFactory::InitializeSignalingThread, CrossThreadUnretained(this), CrossThreadUnretained(Platform::Current()->GetGpuFactories()), + CrossThreadUnretained(Platform::Current()->GetMediaDecoderFactory()), CrossThreadUnretained(&start_signaling_event))); start_signaling_event.Wait(); @@ -239,6 +267,7 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { void PeerConnectionDependencyFactory::InitializeSignalingThread( media::GpuVideoAcceleratorFactories* gpu_factories, + media::DecoderFactory* media_decoder_factory, base::WaitableEvent* event) { DCHECK(chrome_signaling_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(network_thread_); @@ -287,10 +316,12 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread( socket_factory_.reset(new IpcPacketSocketFactory(p2p_socket_dispatcher_.get(), traffic_annotation)); + gpu_factories_ = gpu_factories; std::unique_ptr<webrtc::VideoEncoderFactory> webrtc_encoder_factory = blink::CreateWebrtcVideoEncoderFactory(gpu_factories); std::unique_ptr<webrtc::VideoDecoderFactory> webrtc_decoder_factory = - blink::CreateWebrtcVideoDecoderFactory(gpu_factories); + blink::CreateWebrtcVideoDecoderFactory(gpu_factories, + media_decoder_factory); // Enable Multiplex codec in SDP optionally. if (base::FeatureList::IsEnabled(blink::features::kWebRtcMultiplexCodec)) { @@ -308,7 +339,7 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread( } webrtc::PeerConnectionFactoryDependencies pcf_deps; - pcf_deps.worker_thread = signaling_thread_; + pcf_deps.worker_thread = worker_thread_ ? worker_thread_ : signaling_thread_; pcf_deps.signaling_thread = signaling_thread_; pcf_deps.network_thread = network_thread_; pcf_deps.task_queue_factory = CreateWebRtcTaskQueueFactory(); @@ -346,7 +377,8 @@ scoped_refptr<webrtc::PeerConnectionInterface> PeerConnectionDependencyFactory::CreatePeerConnection( const webrtc::PeerConnectionInterface::RTCConfiguration& config, blink::WebLocalFrame* web_frame, - webrtc::PeerConnectionObserver* observer) { + webrtc::PeerConnectionObserver* observer, + ExceptionState& exception_state) { CHECK(web_frame); CHECK(observer); if (!GetPcFactory().get()) @@ -357,9 +389,16 @@ PeerConnectionDependencyFactory::CreatePeerConnection( webrtc::PeerConnectionDependencies dependencies(observer); dependencies.allocator = CreatePortAllocator(web_frame); dependencies.async_resolver_factory = CreateAsyncResolverFactory(); - return GetPcFactory() - ->CreatePeerConnection(config, std::move(dependencies)) - .get(); + auto pc_or_error = GetPcFactory()->CreatePeerConnectionOrError( + config, std::move(dependencies)); + if (pc_or_error.ok()) { + // Convert from rtc::scoped_refptr to scoped_refptr + return pc_or_error.value().get(); + } else { + // Convert error + ThrowExceptionFromRTCError(pc_or_error.error(), exception_state); + return nullptr; + } } std::unique_ptr<cricket::PortAllocator> @@ -499,14 +538,6 @@ PeerConnectionDependencyFactory::CreateLocalVideoTrack( return GetPcFactory()->CreateVideoTrack(id.Utf8(), source).get(); } -webrtc::SessionDescriptionInterface* -PeerConnectionDependencyFactory::CreateSessionDescription( - const String& type, - const String& sdp, - webrtc::SdpParseError* error) { - return webrtc::CreateSessionDescription(type.Utf8(), sdp.Utf8(), error); -} - webrtc::IceCandidateInterface* PeerConnectionDependencyFactory::CreateIceCandidate(const String& sdp_mid, int sdp_mline_index, @@ -522,6 +553,15 @@ PeerConnectionDependencyFactory::GetWebRtcAudioDevice() { return audio_device_.get(); } +void PeerConnectionDependencyFactory::InitializeWorkerThread( + rtc::Thread** thread, + base::WaitableEvent* event) { + jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); + jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); + *thread = jingle_glue::JingleThreadWrapper::current(); + event->Signal(); +} + void PeerConnectionDependencyFactory::TryScheduleStunProbeTrial() { base::Optional<WebString> params = Platform::Current()->WebRtcStunProbeTrialParameter(); @@ -646,4 +686,8 @@ PeerConnectionDependencyFactory::GetReceiverCapabilities(const String& kind) { return nullptr; } +media::GpuVideoAcceleratorFactories* +PeerConnectionDependencyFactory::GetGpuFactories() { + return gpu_factories_; +} } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h index 7092f910303..7d21b78a8a4 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h @@ -11,6 +11,7 @@ #include "base/threading/thread.h" #include "base/threading/thread_checker.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/webrtc/api/peer_connection_interface.h" #include "third_party/webrtc/p2p/stunprober/stun_prober.h" @@ -24,6 +25,7 @@ class PortAllocator; } namespace media { +class DecoderFactory; class GpuVideoAcceleratorFactories; } @@ -78,7 +80,8 @@ class MODULES_EXPORT PeerConnectionDependencyFactory virtual scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection( const webrtc::PeerConnectionInterface::RTCConfiguration& config, blink::WebLocalFrame* web_frame, - webrtc::PeerConnectionObserver* observer); + webrtc::PeerConnectionObserver* observer, + ExceptionState& exception_state); // Creates a PortAllocator that uses Chrome IPC sockets and enforces privacy // controls according to the permissions granted on the page. @@ -89,13 +92,6 @@ class MODULES_EXPORT PeerConnectionDependencyFactory virtual std::unique_ptr<webrtc::AsyncResolverFactory> CreateAsyncResolverFactory(); - // Creates a libjingle representation of a Session description. Used by a - // RTCPeerConnectionHandler instance. - virtual webrtc::SessionDescriptionInterface* CreateSessionDescription( - const String& type, - const String& sdp, - webrtc::SdpParseError* error); - // Creates a libjingle representation of an ice candidate. virtual webrtc::IceCandidateInterface* CreateIceCandidate( const String& sdp_mid, @@ -120,6 +116,8 @@ class MODULES_EXPORT PeerConnectionDependencyFactory virtual scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcSignalingTaskRunner(); + media::GpuVideoAcceleratorFactories* GetGpuFactories(); + protected: PeerConnectionDependencyFactory(bool create_p2p_socket_dispatcher); @@ -147,8 +145,11 @@ class MODULES_EXPORT PeerConnectionDependencyFactory void InitializeSignalingThread( media::GpuVideoAcceleratorFactories* gpu_factories, + media::DecoderFactory* media_decoder_factory, base::WaitableEvent* event); + void InitializeWorkerThread(rtc::Thread** thread, base::WaitableEvent* event); + void CreateIpcNetworkManagerOnNetworkThread( base::WaitableEvent* event, std::unique_ptr<MdnsResponderAdapter> mdns_responder, @@ -170,11 +171,15 @@ class MODULES_EXPORT PeerConnectionDependencyFactory std::unique_ptr<blink::StunProberTrial> stun_trial_; + media::GpuVideoAcceleratorFactories* gpu_factories_; + // PeerConnection threads. signaling_thread_ is created from the // "current" chrome thread. rtc::Thread* signaling_thread_ = nullptr; + rtc::Thread* worker_thread_ = nullptr; rtc::Thread* network_thread_ = nullptr; base::Thread chrome_signaling_thread_; + base::Optional<base::Thread> chrome_worker_thread_; base::Thread chrome_network_thread_; THREAD_CHECKER(thread_checker_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc index aa9ceb39621..6cfa167f8e1 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc @@ -12,11 +12,10 @@ #include <utility> #include <vector> -#include "base/power_monitor/power_observer.h" -#include "base/stl_util.h" +#include "base/containers/contains.h" #include "base/values.h" -#include "third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h" #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/web/web_document.h" @@ -726,9 +725,7 @@ void PeerConnectionTracker::OnSuspend() { void PeerConnectionTracker::OnThermalStateChange( mojom::blink::DeviceThermalState thermal_state) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_); - mojo::EnumTraits<mojom::blink::DeviceThermalState, - base::PowerObserver::DeviceThermalState>:: - FromMojom(thermal_state, ¤t_thermal_state_); + current_thermal_state_ = thermal_state; for (auto& entry : peer_connection_local_id_map_) { entry.key->OnThermalStateChange(current_thermal_state_); } @@ -808,8 +805,7 @@ void PeerConnectionTracker::RegisterPeerConnection( peer_connection_local_id_map_.insert(pc_handler, lid); - if (current_thermal_state_ != - base::PowerObserver::DeviceThermalState::kUnknown) { + if (current_thermal_state_ != mojom::blink::DeviceThermalState::kUnknown) { pc_handler->OnThermalStateChange(current_thermal_state_); } } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h index 7000bc48ea4..ee047f78b08 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h @@ -7,7 +7,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/power_monitor/power_observer.h" #include "base/threading/thread_checker.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -282,8 +281,8 @@ class MODULES_EXPORT PeerConnectionTracker // This map stores the local ID assigned to each RTCPeerConnectionHandler. typedef WTF::HashMap<RTCPeerConnectionHandler*, int> PeerConnectionLocalIdMap; PeerConnectionLocalIdMap peer_connection_local_id_map_; - base::PowerObserver::DeviceThermalState current_thermal_state_ = - base::PowerObserver::DeviceThermalState::kUnknown; + mojom::blink::DeviceThermalState current_thermal_state_ = + mojom::blink::DeviceThermalState::kUnknown; // This keeps track of the next available local ID. int next_local_id_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc index 6991518346c..7c7a0c14c7c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc @@ -127,8 +127,7 @@ class MockPeerConnectionHandler : public RTCPeerConnectionHandler { /*force_encoded_audio_insertable_streams=*/false, /*force_encoded_video_insertable_streams=*/false) {} MOCK_METHOD0(CloseClientPeerConnection, void()); - MOCK_METHOD1(OnThermalStateChange, - void(base::PowerObserver::DeviceThermalState)); + MOCK_METHOD1(OnThermalStateChange, void(mojom::blink::DeviceThermalState)); private: blink::MockPeerConnectionDependencyFactory dependency_factory_; @@ -195,35 +194,30 @@ TEST_F(PeerConnectionTrackerTest, OnThermalStateChange) { CreateTrackerWithMocks(); CreateAndRegisterPeerConnectionHandler(); - EXPECT_CALL( - *mock_handler_, - OnThermalStateChange(base::PowerObserver::DeviceThermalState::kUnknown)) + EXPECT_CALL(*mock_handler_, + OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown)) .Times(1); - tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kUnknown); + tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown); - EXPECT_CALL( - *mock_handler_, - OnThermalStateChange(base::PowerObserver::DeviceThermalState::kNominal)) + EXPECT_CALL(*mock_handler_, + OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal)) .Times(1); - tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kNominal); + tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal); - EXPECT_CALL( - *mock_handler_, - OnThermalStateChange(base::PowerObserver::DeviceThermalState::kFair)) + EXPECT_CALL(*mock_handler_, + OnThermalStateChange(mojom::blink::DeviceThermalState::kFair)) .Times(1); - tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kFair); + tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kFair); - EXPECT_CALL( - *mock_handler_, - OnThermalStateChange(base::PowerObserver::DeviceThermalState::kSerious)) + EXPECT_CALL(*mock_handler_, + OnThermalStateChange(mojom::blink::DeviceThermalState::kSerious)) .Times(1); - tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kSerious); + tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kSerious); - EXPECT_CALL( - *mock_handler_, - OnThermalStateChange(base::PowerObserver::DeviceThermalState::kCritical)) + EXPECT_CALL(*mock_handler_, + OnThermalStateChange(mojom::blink::DeviceThermalState::kCritical)) .Times(1); - tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kCritical); + tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kCritical); } TEST_F(PeerConnectionTrackerTest, ReportInitialThermalState) { @@ -241,14 +235,14 @@ TEST_F(PeerConnectionTrackerTest, ReportInitialThermalState) { base::RunLoop().RunUntilIdle(); // Report a known thermal state. - EXPECT_CALL(handler0, OnThermalStateChange( - base::PowerObserver::DeviceThermalState::kNominal)) + EXPECT_CALL(handler0, + OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal)) .Times(1); - tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kNominal); + tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal); // Handlers registered late will get the event upon registering. - EXPECT_CALL(handler1, OnThermalStateChange( - base::PowerObserver::DeviceThermalState::kNominal)) + EXPECT_CALL(handler1, + OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal)) .Times(1); EXPECT_CALL(*mock_host_, AddPeerConnection(_)).Times(1); tracker_->RegisterPeerConnection( @@ -257,13 +251,13 @@ TEST_F(PeerConnectionTrackerTest, ReportInitialThermalState) { base::RunLoop().RunUntilIdle(); // Report the unknown thermal state. - EXPECT_CALL(handler0, OnThermalStateChange( - base::PowerObserver::DeviceThermalState::kUnknown)) + EXPECT_CALL(handler0, + OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown)) .Times(1); - EXPECT_CALL(handler1, OnThermalStateChange( - base::PowerObserver::DeviceThermalState::kUnknown)) + EXPECT_CALL(handler1, + OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown)) .Times(1); - tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kUnknown); + tracker_->OnThermalStateChange(mojom::blink::DeviceThermalState::kUnknown); // Handlers registered late get no event. EXPECT_CALL(handler2, OnThermalStateChange(_)).Times(0); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc index 5925cd58e4e..63c40095a65 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc @@ -205,7 +205,7 @@ void RTCDataChannel::Observer::OnMessage(const webrtc::DataBuffer& buffer) { *main_thread_, FROM_HERE, CrossThreadBindOnce(&RTCDataChannel::Observer::OnMessageImpl, scoped_refptr<Observer>(this), - WTF::Passed(std::move(new_buffer)))); + std::move(new_buffer))); } void RTCDataChannel::Observer::OnStateChangeImpl( @@ -417,15 +417,14 @@ void RTCDataChannel::send(DOMArrayBuffer* data, void RTCDataChannel::send(NotShared<DOMArrayBufferView> data, ExceptionState& exception_state) { - if (!(base::CheckedNumeric<unsigned>(buffered_amount_) + - data.View()->byteLength()) + if (!(base::CheckedNumeric<unsigned>(buffered_amount_) + data->byteLength()) .IsValid()) { ThrowBufferOverflowException(&exception_state); return; } - buffered_amount_ += data.View()->byteLength(); - if (!SendRawData(static_cast<const char*>(data.View()->BaseAddress()), - data.View()->byteLength())) { + buffered_amount_ += data->byteLength(); + if (!SendRawData(static_cast<const char*>(data->BaseAddress()), + data->byteLength())) { // TODO(https://crbug.com/937848): Don't throw an exception if data is // queued. ThrowCouldNotSendDataException(&exception_state); @@ -505,6 +504,7 @@ bool RTCDataChannel::HasPendingActivity() const { void RTCDataChannel::Trace(Visitor* visitor) const { visitor->Trace(scheduled_events_); + visitor->Trace(scheduled_event_timer_); EventTargetWithInlineData::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h index 5e068fe2a0d..2a8320dec07 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h @@ -176,7 +176,7 @@ class MODULES_EXPORT RTCDataChannel final enum BinaryType { kBinaryTypeBlob, kBinaryTypeArrayBuffer }; BinaryType binary_type_; - TaskRunnerTimer<RTCDataChannel> scheduled_event_timer_; + HeapTaskRunnerTimer<RTCDataChannel> scheduled_event_timer_; HeapVector<Member<Event>> scheduled_events_; FRIEND_TEST_ALL_PREFIXES(RTCDataChannelTest, Open); FRIEND_TEST_ALL_PREFIXES(RTCDataChannelTest, Close); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc index bc5de51d17e..be026790138 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc @@ -18,6 +18,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/testing/null_execution_context.h" #include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" @@ -44,8 +45,7 @@ void RunSynchronous(base::TestSimpleTaskRunner* thread, std::move(closure).Run(); event->Signal(); }, - WTF::Passed(std::move(closure)), - CrossThreadUnretained(&waitable_event))); + std::move(closure), CrossThreadUnretained(&waitable_event))); waitable_event.Wait(); } @@ -214,11 +214,18 @@ class MockDataChannel : public webrtc::DataChannelInterface { class RTCDataChannelTest : public ::testing::Test { public: RTCDataChannelTest() : signaling_thread_(new base::TestSimpleTaskRunner()) {} + ~RTCDataChannelTest() override { + execution_context_->NotifyContextDestroyed(); + } scoped_refptr<base::TestSimpleTaskRunner> signaling_thread() { return signaling_thread_; } + protected: + Persistent<NullExecutionContext> execution_context_ = + MakeGarbageCollected<NullExecutionContext>(); + private: scoped_refptr<base::TestSimpleTaskRunner> signaling_thread_; @@ -237,8 +244,7 @@ TEST_F(RTCDataChannelTest, ChangeStateEarly) { std::unique_ptr<MockPeerConnectionHandler> pc( new MockPeerConnectionHandler(signaling_thread())); auto* channel = MakeGarbageCollected<RTCDataChannel>( - MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(), - pc.get()); + execution_context_, webrtc_channel.get(), pc.get()); // In RTCDataChannel::Create, the state change update is posted from the // signaling thread to the main thread. Wait for posted the task to be @@ -255,8 +261,7 @@ TEST_F(RTCDataChannelTest, BufferedAmount) { std::unique_ptr<MockPeerConnectionHandler> pc( new MockPeerConnectionHandler(signaling_thread())); auto* channel = MakeGarbageCollected<RTCDataChannel>( - MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(), - pc.get()); + execution_context_, webrtc_channel.get(), pc.get()); webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen); String message(std::string(100, 'A').c_str()); @@ -273,8 +278,7 @@ TEST_F(RTCDataChannelTest, BufferedAmountLow) { std::unique_ptr<MockPeerConnectionHandler> pc( new MockPeerConnectionHandler(signaling_thread())); auto* channel = MakeGarbageCollected<RTCDataChannel>( - MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(), - pc.get()); + execution_context_, webrtc_channel.get(), pc.get()); webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen); channel->setBufferedAmountLowThreshold(1); @@ -295,8 +299,7 @@ TEST_F(RTCDataChannelTest, Open) { std::unique_ptr<MockPeerConnectionHandler> pc( new MockPeerConnectionHandler(signaling_thread())); auto* channel = MakeGarbageCollected<RTCDataChannel>( - MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(), - pc.get()); + execution_context_, webrtc_channel.get(), pc.get()); channel->OnStateChange(webrtc::DataChannelInterface::kOpen); EXPECT_EQ("open", channel->readyState()); } @@ -307,8 +310,7 @@ TEST_F(RTCDataChannelTest, Close) { std::unique_ptr<MockPeerConnectionHandler> pc( new MockPeerConnectionHandler(signaling_thread())); auto* channel = MakeGarbageCollected<RTCDataChannel>( - MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(), - pc.get()); + execution_context_, webrtc_channel.get(), pc.get()); channel->OnStateChange(webrtc::DataChannelInterface::kClosed); EXPECT_EQ("closed", channel->readyState()); } @@ -319,8 +321,7 @@ TEST_F(RTCDataChannelTest, Message) { std::unique_ptr<MockPeerConnectionHandler> pc( new MockPeerConnectionHandler(signaling_thread())); auto* channel = MakeGarbageCollected<RTCDataChannel>( - MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(), - pc.get()); + execution_context_, webrtc_channel.get(), pc.get()); std::unique_ptr<webrtc::DataBuffer> message(new webrtc::DataBuffer("A")); channel->OnMessage(std::move(message)); @@ -334,8 +335,7 @@ TEST_F(RTCDataChannelTest, SendAfterContextDestroyed) { std::unique_ptr<MockPeerConnectionHandler> pc( new MockPeerConnectionHandler(signaling_thread())); auto* channel = MakeGarbageCollected<RTCDataChannel>( - MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(), - pc.get()); + execution_context_, webrtc_channel.get(), pc.get()); webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen); channel->ContextDestroyed(); @@ -353,8 +353,7 @@ TEST_F(RTCDataChannelTest, CloseAfterContextDestroyed) { std::unique_ptr<MockPeerConnectionHandler> pc( new MockPeerConnectionHandler(signaling_thread())); auto* channel = MakeGarbageCollected<RTCDataChannel>( - MakeGarbageCollected<NullExecutionContext>(), webrtc_channel.get(), - pc.get()); + execution_context_, webrtc_channel.get(), pc.get()); webrtc_channel->ChangeState(webrtc::DataChannelInterface::kOpen); channel->ContextDestroyed(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc index ad703c4bdea..c9e7862d503 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink_test.cc @@ -15,6 +15,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h" +#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc index c6f30c34756..2caca05c398 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc @@ -7,6 +7,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h" +#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/wtf/vector.h" diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc index 614d16e9a43..3f6d24941ad 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc @@ -15,6 +15,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream_default_writer.h" +#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc index 63f012e9acd..ade8bb77ed2 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc @@ -7,6 +7,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h" +#include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/webrtc/api/frame_transformer_interface.h" diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc index 497509c2467..c8a127df90f 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc @@ -77,50 +77,8 @@ class DtlsIceTransportAdapterCrossThreadFactory rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_; }; -class DefaultIceTransportAdapterCrossThreadFactory - : public IceTransportAdapterCrossThreadFactory { - public: - void InitializeOnMainThread(LocalFrame& frame) override { - DCHECK(!port_allocator_); - DCHECK(!async_resolver_factory_); - - auto* rtc_dependency_factory = - blink::PeerConnectionDependencyFactory::GetInstance(); - port_allocator_ = rtc_dependency_factory->CreatePortAllocator( - frame.Client()->GetWebFrame()); - async_resolver_factory_ = - rtc_dependency_factory->CreateAsyncResolverFactory(); - } - - std::unique_ptr<IceTransportAdapter> ConstructOnWorkerThread( - IceTransportAdapter::Delegate* delegate) override { - DCHECK(port_allocator_); - DCHECK(async_resolver_factory_); - return std::make_unique<IceTransportAdapterImpl>( - delegate, std::move(port_allocator_), - std::move(async_resolver_factory_)); - } - - private: - std::unique_ptr<cricket::PortAllocator> port_allocator_; - std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory_; -}; - } // namespace -RTCIceTransport* RTCIceTransport::Create(ExecutionContext* context) { - scoped_refptr<base::SingleThreadTaskRunner> proxy_thread = - context->GetTaskRunner(TaskType::kNetworking); - - PeerConnectionDependencyFactory::GetInstance()->EnsureInitialized(); - scoped_refptr<base::SingleThreadTaskRunner> host_thread = - PeerConnectionDependencyFactory::GetInstance() - ->GetWebRtcNetworkTaskRunner(); - return MakeGarbageCollected<RTCIceTransport>( - context, std::move(proxy_thread), std::move(host_thread), - std::make_unique<DefaultIceTransportAdapterCrossThreadFactory>()); -} - RTCIceTransport* RTCIceTransport::Create( ExecutionContext* context, rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport, diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h index 884b804e197..8fcceafbb6f 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h @@ -56,7 +56,6 @@ class MODULES_EXPORT RTCIceTransport final kDisposed, }; - static RTCIceTransport* Create(ExecutionContext* context); static RTCIceTransport* Create( ExecutionContext* context, rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport_channel, diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl index 7894ce1bcb2..38989386176 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl @@ -32,8 +32,6 @@ enum RTCIceGatheringState { Exposed=Window, SecureContext ] interface RTCIceTransport : EventTarget { - // Constructor from https://w3c.github.io/webrtc-ice/#rtcicetransport* - [CallWith=ExecutionContext, Measure] constructor(); // TODO(github.com/w3c/webrtc-ice/issues/4): role is non-null in the // WebRTC-PC specification. [Measure] readonly attribute RTCIceRole? role; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index b38cf32bb33..0d0337a867c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc @@ -50,12 +50,12 @@ #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h" #include "third_party/blink/renderer/bindings/modules/v8/media_stream_track_or_string.h" -#include "third_party/blink/renderer/bindings/modules/v8/rtc_ice_candidate_init_or_rtc_ice_candidate.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_answer_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_configuration.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel_init.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_server.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_offer_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h" @@ -178,17 +178,10 @@ bool CallErrorCallbackIfSignalingStateClosed( return false; } -bool IsIceCandidateMissingSdp( - const RTCIceCandidateInitOrRTCIceCandidate& candidate) { - if (candidate.IsRTCIceCandidateInit()) { - const RTCIceCandidateInit* ice_candidate_init = - candidate.GetAsRTCIceCandidateInit(); - return ice_candidate_init->sdpMid().IsNull() && - !ice_candidate_init->hasSdpMLineIndexNonNull(); - } - - DCHECK(candidate.IsRTCIceCandidate()); - return false; +bool IsIceCandidateMissingSdpMidAndMLineIndex( + const RTCIceCandidateInit* candidate) { + return (candidate->sdpMid().IsNull() && + !candidate->hasSdpMLineIndexNonNull()); } RTCOfferOptionsPlatform* ConvertToRTCOfferOptionsPlatform( @@ -214,26 +207,18 @@ RTCAnswerOptionsPlatform* ConvertToRTCAnswerOptionsPlatform( RTCIceCandidatePlatform* ConvertToRTCIceCandidatePlatform( ExecutionContext* context, - const RTCIceCandidateInitOrRTCIceCandidate& candidate) { - DCHECK(!candidate.IsNull()); - if (candidate.IsRTCIceCandidateInit()) { - const RTCIceCandidateInit* ice_candidate_init = - candidate.GetAsRTCIceCandidateInit(); - // TODO(guidou): Change default value to -1. crbug.com/614958. - uint16_t sdp_m_line_index = 0; - if (ice_candidate_init->hasSdpMLineIndexNonNull()) { - sdp_m_line_index = ice_candidate_init->sdpMLineIndexNonNull(); - } else { - UseCounter::Count(context, - WebFeature::kRTCIceCandidateDefaultSdpMLineIndex); - } - return MakeGarbageCollected<RTCIceCandidatePlatform>( - ice_candidate_init->candidate(), ice_candidate_init->sdpMid(), - sdp_m_line_index, ice_candidate_init->usernameFragment()); + const RTCIceCandidateInit* candidate) { + // TODO(guidou): Change default value to -1. crbug.com/614958. + uint16_t sdp_m_line_index = 0; + if (candidate->hasSdpMLineIndexNonNull()) { + sdp_m_line_index = candidate->sdpMLineIndexNonNull(); + } else { + UseCounter::Count(context, + WebFeature::kRTCIceCandidateDefaultSdpMLineIndex); } - - DCHECK(candidate.IsRTCIceCandidate()); - return candidate.GetAsRTCIceCandidate()->PlatformCandidate(); + return MakeGarbageCollected<RTCIceCandidatePlatform>( + candidate->candidate(), candidate->sdpMid(), sdp_m_line_index, + candidate->usernameFragment()); } enum SdpSemanticRequested { @@ -324,6 +309,22 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration( if (configuration->hasSdpSemantics()) { if (configuration->sdpSemantics() == "plan-b") { web_configuration.sdp_semantics = webrtc::SdpSemantics::kPlanB; + if (!RuntimeEnabledFeatures::RTCExtendDeadlineForPlanBRemovalEnabled( + context)) { + // TODO(https://crbug.com/857004): In M93, replace this deprecation + // warning with the throwing of an exception (Reverse Origin Trial is + // required to continue to use Plan B). + Deprecation::CountDeprecation( + context, WebFeature::kRTCPeerConnectionSdpSemanticsPlanB); + } else { + // TODO(https://crbug.com/857004): In M96, replace this deprecation + // warning with the throwing of an exception (Reverse Origin Trial has + // ended). + Deprecation::CountDeprecation( + context, + WebFeature:: + kRTCPeerConnectionSdpSemanticsPlanBWithReverseOriginTrial); + } } else { DCHECK_EQ(configuration->sdpSemantics(), "unified-plan"); web_configuration.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; @@ -536,17 +537,19 @@ bool ContainsLegacyRtpDataChannel(String sdp) { return sdp.Find("google-data/90000") != kNotFound; } +bool ContainsCandidate(String sdp) { + return sdp.Find("a=candidate") != kNotFound; +} + enum class SdpFormat { kSimple, kComplexPlanB, kComplexUnifiedPlan, }; -base::Optional<SdpFormat> DeduceSdpFormat(const String& type, - const String& sdp) { - std::unique_ptr<webrtc::SessionDescriptionInterface> session_description( - webrtc::CreateSessionDescription(type.Utf8().c_str(), sdp.Utf8().c_str(), - nullptr)); +base::Optional<SdpFormat> DeduceSdpFormat( + const ParsedSessionDescription& parsed_sdp) { + auto* session_description = parsed_sdp.description(); if (!session_description) return base::nullopt; size_t num_audio_mlines = 0u; @@ -604,11 +607,11 @@ RTCSetSessionDescriptionOperation GetRTCVoidRequestOperationType( const char kOnlySupportedInUnifiedPlanMessage[] = "This operation is only supported in 'unified-plan'."; -SdpUsageCategory DeduceSdpUsageCategory(const String& sdp_type, - const String& sdp, - bool sdp_semantics_specified, - webrtc::SdpSemantics sdp_semantics) { - auto sdp_format = DeduceSdpFormat(sdp_type, sdp); +SdpUsageCategory DeduceSdpUsageCategory( + const ParsedSessionDescription& parsed_sdp, + bool sdp_semantics_specified, + webrtc::SdpSemantics sdp_semantics) { + auto sdp_format = DeduceSdpFormat(parsed_sdp); if (!sdp_format) return SdpUsageCategory::kUnknown; switch (*sdp_format) { @@ -707,9 +710,21 @@ RTCPeerConnection* RTCPeerConnection::Create( if (exception_state.HadException()) return nullptr; + SdpSemanticRequested sdp_semantics_requested = + GetSdpSemanticRequested(rtc_configuration); UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpSemanticRequested", - GetSdpSemanticRequested(rtc_configuration), - kSdpSemanticRequestedMax); + sdp_semantics_requested, kSdpSemanticRequestedMax); + + if (sdp_semantics_requested == kSdpSemanticRequestedPlanB) { + UseCounter::Count(context, + WebFeature::kRTCPeerConnectionConstructedWithPlanB); + } else { + // Unified Plan is the default. + DCHECK(sdp_semantics_requested == kSdpSemanticRequestedDefault || + sdp_semantics_requested == kSdpSemanticRequestedUnifiedPlan); + UseCounter::Count(context, + WebFeature::kRTCPeerConnectionConstructedWithUnifiedPlan); + } UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.OfferExtmapAllowMixed", GetOfferExtmapAllowMixedSetting(rtc_configuration)); @@ -760,12 +775,8 @@ RTCPeerConnection::RTCPeerConnection( peer_handler_unregistered_(true), closed_(true), suppress_events_(true), - has_data_channels_(false), sdp_semantics_(configuration.sdp_semantics), sdp_semantics_specified_(sdp_semantics_specified), - blink_webrtc_time_diff_( - base::TimeTicks::Now() - base::TimeTicks() - - base::TimeDelta::FromMicroseconds(rtc::TimeMicros())), force_encoded_audio_insertable_streams_( force_encoded_audio_insertable_streams), force_encoded_video_insertable_streams_( @@ -804,23 +815,16 @@ RTCPeerConnection::RTCPeerConnection( } auto* web_frame = - static_cast<WebLocalFrame*>(WebFrame::FromFrame(window->GetFrame())); - if (!peer_handler_->Initialize(configuration, constraints, web_frame)) { - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "Failed to initialize native PeerConnection."); + static_cast<WebLocalFrame*>(WebFrame::FromCoreFrame(window->GetFrame())); + if (!peer_handler_->Initialize(configuration, constraints, web_frame, + exception_state)) { + DCHECK(exception_state.HadException()); return; } // The RTCPeerConnection was successfully constructed. closed_ = false; peer_handler_unregistered_ = false; suppress_events_ = false; - - feature_handle_for_scheduler_ = - window->GetFrame()->GetFrameScheduler()->RegisterFeature( - SchedulingPolicy::Feature::kWebRTC, - SchedulingPolicy{ - SchedulingPolicy::RecordMetricsForBackForwardCache()}); } RTCPeerConnection::~RTCPeerConnection() { @@ -1072,25 +1076,21 @@ ScriptPromise RTCPeerConnection::CreateAnswer( DOMException* RTCPeerConnection::checkSdpForStateErrors( ExecutionContext* context, - const RTCSessionDescriptionInit* session_description_init, - String* sdp) { + const ParsedSessionDescription& parsed_sdp) { if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) { return MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, kSignalingStateClosedMessage); } - *sdp = session_description_init->sdp(); - if (session_description_init->type() == "offer") { - if (sdp->IsNull() || sdp->IsEmpty()) { - *sdp = last_offer_; - } else if (session_description_init->sdp() != last_offer_) { - if (FingerprintMismatch(last_offer_, *sdp)) { + if (parsed_sdp.type() == "offer") { + if (parsed_sdp.sdp() != last_offer_) { + if (FingerprintMismatch(last_offer_, parsed_sdp.sdp())) { return MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidModificationError, kModifiedSdpMessage); } else { UseCounter::Count(context, WebFeature::kRTCLocalSdpModification); - if (ContainsLegacySimulcast(*sdp)) { + if (ContainsLegacySimulcast(parsed_sdp.sdp())) { UseCounter::Count(context, WebFeature::kRTCLocalSdpModificationSimulcast); } @@ -1098,17 +1098,14 @@ DOMException* RTCPeerConnection::checkSdpForStateErrors( // TODO(https://crbug.com/823036): Return failure for all modification. } } - } else if (session_description_init->type() == "answer" || - session_description_init->type() == "pranswer") { - if (sdp->IsNull() || sdp->IsEmpty()) { - *sdp = last_answer_; - } else if (session_description_init->sdp() != last_answer_) { - if (FingerprintMismatch(last_answer_, *sdp)) { + } else if (parsed_sdp.type() == "answer" || parsed_sdp.type() == "pranswer") { + if (parsed_sdp.sdp() != last_answer_) { + if (FingerprintMismatch(last_answer_, parsed_sdp.sdp())) { return MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidModificationError, kModifiedSdpMessage); } else { UseCounter::Count(context, WebFeature::kRTCLocalSdpModification); - if (ContainsLegacySimulcast(*sdp)) { + if (ContainsLegacySimulcast(parsed_sdp.sdp())) { UseCounter::Count(context, WebFeature::kRTCLocalSdpModificationSimulcast); } @@ -1121,12 +1118,8 @@ DOMException* RTCPeerConnection::checkSdpForStateErrors( } base::Optional<ComplexSdpCategory> RTCPeerConnection::CheckForComplexSdp( - const RTCSessionDescriptionInit* session_description_init) const { - if (!session_description_init->hasType()) - return base::nullopt; - - base::Optional<SdpFormat> sdp_format = DeduceSdpFormat( - session_description_init->type(), session_description_init->sdp()); + const ParsedSessionDescription& parsed_sdp) const { + base::Optional<SdpFormat> sdp_format = DeduceSdpFormat(parsed_sdp); if (!sdp_format) { return sdp_semantics_specified_ ? ComplexSdpCategory::kErrorExplicitSemantics @@ -1146,10 +1139,10 @@ base::Optional<ComplexSdpCategory> RTCPeerConnection::CheckForComplexSdp( return base::nullopt; } -void RTCPeerConnection::MaybeWarnAboutUnsafeSdp( - const RTCSessionDescriptionInit* session_description_init) const { +void RTCPeerConnection::RecordSdpCategoryAndMaybeEmitWarnings( + const ParsedSessionDescription& parsed_sdp) const { base::Optional<ComplexSdpCategory> complex_sdp_category = - CheckForComplexSdp(session_description_init); + CheckForComplexSdp(parsed_sdp); if (!complex_sdp_category || !GetExecutionContext()) return; @@ -1162,6 +1155,36 @@ void RTCPeerConnection::MaybeWarnAboutUnsafeSdp( GetExecutionContext(), WebFeature::kRTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics); } + + // kComplexPlanB/kComplexUnifiedPlan or null. + base::Optional<SdpFormat> complex_sdp_format; + switch (*complex_sdp_category) { + case ComplexSdpCategory::kPlanBExplicitSemantics: + case ComplexSdpCategory::kPlanBImplicitSemantics: + complex_sdp_format = SdpFormat::kComplexPlanB; + break; + case ComplexSdpCategory::kUnifiedPlanExplicitSemantics: + case ComplexSdpCategory::kUnifiedPlanImplicitSemantics: + complex_sdp_format = SdpFormat::kComplexUnifiedPlan; + break; + case ComplexSdpCategory::kErrorImplicitSemantics: + case ComplexSdpCategory::kErrorExplicitSemantics: + complex_sdp_format = base::nullopt; + break; + } + // Complex SDP use counters go up when complex SDP is used on an + // RTCPeerConnection configured for that SDP format. + if (complex_sdp_format.has_value()) { + if (sdp_semantics_ == webrtc::SdpSemantics::kPlanB && + complex_sdp_format.value() == SdpFormat::kComplexPlanB) { + UseCounter::Count(GetExecutionContext(), + WebFeature::kRTCPeerConnectionUsingComplexPlanB); + } else if (sdp_semantics_ == webrtc::SdpSemantics::kUnifiedPlan && + complex_sdp_format.value() == SdpFormat::kComplexUnifiedPlan) { + UseCounter::Count(GetExecutionContext(), + WebFeature::kRTCPeerConnectionUsingComplexUnifiedPlan); + } + } } HeapHashSet<Member<RTCIceTransport>> RTCPeerConnection::ActiveIceTransports() @@ -1310,11 +1333,14 @@ void RTCPeerConnection::UpdateIceConnectionState() { void RTCPeerConnection::ReportSetSdpUsage( SetSdpOperationType operation_type, - const RTCSessionDescriptionInit* session_description_init) const { + const ParsedSessionDescription& parsed_sdp) const { + if (!parsed_sdp.description()) { + LOG(ERROR) << "ReportSetSdpUsage called on SDP that failed parsing"; + return; + } SdpUsageCategory sdp_usage = DeduceSdpUsageCategory( - session_description_init->type(), session_description_init->sdp(), - sdp_semantics_specified_, sdp_semantics_); - if (session_description_init->type() == "offer") { + parsed_sdp, sdp_semantics_specified_, sdp_semantics_); + if (parsed_sdp.description()->GetType() == webrtc::SdpType::kOffer) { switch (operation_type) { case SetSdpOperationType::kSetLocalDescription: UMA_HISTOGRAM_ENUMERATION( @@ -1325,8 +1351,9 @@ void RTCPeerConnection::ReportSetSdpUsage( "WebRTC.PeerConnection.SdpComplexUsage.SetRemoteOffer", sdp_usage); break; } - } else if (session_description_init->type() == "answer" || - session_description_init->type() == "pranswer") { + } else if (parsed_sdp.description()->GetType() == webrtc::SdpType::kAnswer || + parsed_sdp.description()->GetType() == + webrtc::SdpType::kPrAnswer) { switch (operation_type) { case SetSdpOperationType::kSetLocalDescription: UMA_HISTOGRAM_ENUMERATION( @@ -1366,14 +1393,25 @@ ScriptPromise RTCPeerConnection::setLocalDescription( if (!session_description_init->hasType()) { return setLocalDescription(script_state); } - String sdp; + String sdp = session_description_init->sdp(); + // https://w3c.github.io/webrtc-pc/#dom-peerconnection-setlocaldescription + // step 4.4 and 4.5: If SDP is empty, return the last created offer or answer. + if (sdp.IsNull() || sdp.IsEmpty()) { + if (session_description_init->type() == "offer") { + sdp = last_offer_; + } else if (session_description_init->type() == "answer" || + session_description_init->type() == "pranswer") { + sdp = last_answer_; + } + } + ParsedSessionDescription parsed_sdp = + ParsedSessionDescription::Parse(session_description_init->type(), sdp); if (session_description_init->type() != "rollback") { - MaybeWarnAboutUnsafeSdp(session_description_init); - ReportSetSdpUsage(SetSdpOperationType::kSetLocalDescription, - session_description_init); + RecordSdpCategoryAndMaybeEmitWarnings(parsed_sdp); + ReportSetSdpUsage(SetSdpOperationType::kSetLocalDescription, parsed_sdp); DOMException* exception = checkSdpForStateErrors( - ExecutionContext::From(script_state), session_description_init, &sdp); + ExecutionContext::From(script_state), parsed_sdp); if (exception) { exception_state.ThrowDOMException( static_cast<DOMExceptionCode>(exception->code()), @@ -1394,9 +1432,7 @@ ScriptPromise RTCPeerConnection::setLocalDescription( GetRTCVoidRequestOperationType(SetSdpOperationType::kSetLocalDescription, *session_description_init), this, resolver, "RTCPeerConnection", "setLocalDescription"); - peer_handler_->SetLocalDescription( - request, MakeGarbageCollected<RTCSessionDescriptionPlatform>( - session_description_init->type(), sdp)); + peer_handler_->SetLocalDescription(request, std::move(parsed_sdp)); return promise; } @@ -1411,10 +1447,22 @@ ScriptPromise RTCPeerConnection::setLocalDescription( } DCHECK(script_state->ContextIsValid()); + String sdp = session_description_init->sdp(); + // https://w3c.github.io/webrtc-pc/#dom-peerconnection-setlocaldescription + // step 4.4 and 4.5: If SDP is empty, return the last created offer or answer. + if (sdp.IsNull() || sdp.IsEmpty()) { + if (session_description_init->type() == "offer") { + sdp = last_offer_; + } else if (session_description_init->type() == "answer" || + session_description_init->type() == "pranswer") { + sdp = last_answer_; + } + } + ParsedSessionDescription parsed_sdp = + ParsedSessionDescription::Parse(session_description_init->type(), sdp); if (session_description_init->type() != "rollback") { - MaybeWarnAboutUnsafeSdp(session_description_init); - ReportSetSdpUsage(SetSdpOperationType::kSetLocalDescription, - session_description_init); + RecordSdpCategoryAndMaybeEmitWarnings(parsed_sdp); + ReportSetSdpUsage(SetSdpOperationType::kSetLocalDescription, parsed_sdp); } ExecutionContext* context = ExecutionContext::From(script_state); UseCounter::Count(context, WebFeature::kRTCPeerConnectionSetLocalDescription); @@ -1434,10 +1482,8 @@ ScriptPromise RTCPeerConnection::setLocalDescription( WebFeature:: kRTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback); } - String sdp; if (session_description_init->type() != "rollback") { - DOMException* exception = - checkSdpForStateErrors(context, session_description_init, &sdp); + DOMException* exception = checkSdpForStateErrors(context, parsed_sdp); if (exception) { if (error_callback) AsyncCallErrorCallback(error_callback, exception); @@ -1451,10 +1497,7 @@ ScriptPromise RTCPeerConnection::setLocalDescription( GetRTCVoidRequestOperationType(SetSdpOperationType::kSetLocalDescription, *session_description_init), this, success_callback, error_callback); - peer_handler_->SetLocalDescription( - request, - MakeGarbageCollected<RTCSessionDescriptionPlatform>( - session_description_init->type(), session_description_init->sdp())); + peer_handler_->SetLocalDescription(request, std::move(parsed_sdp)); return ScriptPromise::CastUndefined(script_state); } @@ -1482,10 +1525,11 @@ ScriptPromise RTCPeerConnection::setRemoteDescription( } DCHECK(script_state->ContextIsValid()); + ParsedSessionDescription parsed_sdp = + ParsedSessionDescription::Parse(session_description_init); if (session_description_init->type() != "rollback") { - MaybeWarnAboutUnsafeSdp(session_description_init); - ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription, - session_description_init); + RecordSdpCategoryAndMaybeEmitWarnings(parsed_sdp); + ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription, parsed_sdp); } if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) { @@ -1506,16 +1550,17 @@ ScriptPromise RTCPeerConnection::setRemoteDescription( ExecutionContext* context = ExecutionContext::From(script_state); UseCounter::Count(context, WebFeature::kRTCLegacyRtpDataChannelNegotiated); } + + if (ContainsCandidate(session_description_init->sdp())) + DisableBackForwardCache(context); + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); auto* request = MakeGarbageCollected<RTCVoidRequestPromiseImpl>( GetRTCVoidRequestOperationType(SetSdpOperationType::kSetRemoteDescription, *session_description_init), this, resolver, "RTCPeerConnection", "setRemoteDescription"); - peer_handler_->SetRemoteDescription( - request, - MakeGarbageCollected<RTCSessionDescriptionPlatform>( - session_description_init->type(), session_description_init->sdp())); + peer_handler_->SetRemoteDescription(request, std::move(parsed_sdp)); return promise; } @@ -1530,10 +1575,11 @@ ScriptPromise RTCPeerConnection::setRemoteDescription( } DCHECK(script_state->ContextIsValid()); + ParsedSessionDescription parsed_sdp = + ParsedSessionDescription::Parse(session_description_init); if (session_description_init->type() != "rollback") { - MaybeWarnAboutUnsafeSdp(session_description_init); - ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription, - session_description_init); + RecordSdpCategoryAndMaybeEmitWarnings(parsed_sdp); + ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription, parsed_sdp); } ExecutionContext* context = ExecutionContext::From(script_state); UseCounter::Count(context, @@ -1554,10 +1600,14 @@ ScriptPromise RTCPeerConnection::setRemoteDescription( WebFeature:: kRTCPeerConnectionSetRemoteDescriptionLegacyNoFailureCallback); } + if (ContainsLegacyRtpDataChannel(session_description_init->sdp())) { UseCounter::Count(context, WebFeature::kRTCLegacyRtpDataChannelNegotiated); } + if (ContainsCandidate(session_description_init->sdp())) + DisableBackForwardCache(context); + if (CallErrorCallbackIfSignalingStateClosed(signaling_state_, error_callback)) return ScriptPromise::CastUndefined(script_state); @@ -1568,10 +1618,7 @@ ScriptPromise RTCPeerConnection::setRemoteDescription( GetRTCVoidRequestOperationType(SetSdpOperationType::kSetRemoteDescription, *session_description_init), this, success_callback, error_callback); - peer_handler_->SetRemoteDescription( - request, - MakeGarbageCollected<RTCSessionDescriptionPlatform>( - session_description_init->type(), session_description_init->sdp())); + peer_handler_->SetRemoteDescription(request, std::move(parsed_sdp)); return ScriptPromise::CastUndefined(script_state); } @@ -1855,8 +1902,9 @@ ScriptPromise RTCPeerConnection::generateCertificate( ScriptPromise RTCPeerConnection::addIceCandidate( ScriptState* script_state, - const RTCIceCandidateInitOrRTCIceCandidate& candidate, + const RTCIceCandidateInit* candidate, ExceptionState& exception_state) { + DCHECK(script_state->ContextIsValid()); if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, @@ -1864,23 +1912,25 @@ ScriptPromise RTCPeerConnection::addIceCandidate( return ScriptPromise(); } - if (IsIceCandidateMissingSdp(candidate)) { - exception_state.ThrowTypeError( - "Candidate missing values for both sdpMid and sdpMLineIndex"); - return ScriptPromise(); - } - RTCIceCandidatePlatform* platform_candidate = ConvertToRTCIceCandidatePlatform(ExecutionContext::From(script_state), candidate); // Temporary mitigation to avoid throwing an exception when candidate is - // empty. + // empty or nothing was passed. // TODO(crbug.com/978582): Remove this mitigation when the WebRTC layer - // handles the empty candidate field correctly. + // handles the empty candidate field or the null candidate correctly. if (platform_candidate->Candidate().IsEmpty()) return ScriptPromise::CastUndefined(script_state); + if (IsIceCandidateMissingSdpMidAndMLineIndex(candidate)) { + exception_state.ThrowTypeError( + "Candidate missing values for both sdpMid and sdpMLineIndex"); + return ScriptPromise(); + } + + DisableBackForwardCache(GetExecutionContext()); + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); auto* request = MakeGarbageCollected<RTCVoidRequestPromiseImpl>( @@ -1891,17 +1941,18 @@ ScriptPromise RTCPeerConnection::addIceCandidate( ScriptPromise RTCPeerConnection::addIceCandidate( ScriptState* script_state, - const RTCIceCandidateInitOrRTCIceCandidate& candidate, + const RTCIceCandidateInit* candidate, V8VoidFunction* success_callback, V8RTCPeerConnectionErrorCallback* error_callback, ExceptionState& exception_state) { + DCHECK(script_state->ContextIsValid()); DCHECK(success_callback); DCHECK(error_callback); if (CallErrorCallbackIfSignalingStateClosed(signaling_state_, error_callback)) return ScriptPromise::CastUndefined(script_state); - if (IsIceCandidateMissingSdp(candidate)) { + if (IsIceCandidateMissingSdpMidAndMLineIndex(candidate)) { exception_state.ThrowTypeError( "Candidate missing values for both sdpMid and sdpMLineIndex"); return ScriptPromise(); @@ -1914,10 +1965,12 @@ ScriptPromise RTCPeerConnection::addIceCandidate( // Temporary mitigation to avoid throwing an exception when candidate is // empty. // TODO(crbug.com/978582): Remove this mitigation when the WebRTC layer - // handles the empty candidate field correctly. + // handles the empty candidate field or the null candidate correctly. if (platform_candidate->Candidate().IsEmpty()) return ScriptPromise::CastUndefined(script_state); + DisableBackForwardCache(GetExecutionContext()); + auto* request = MakeGarbageCollected<RTCVoidRequestImpl>( GetExecutionContext(), base::nullopt, this, success_callback, error_callback); @@ -2553,7 +2606,6 @@ RTCDataChannel* RTCPeerConnection::createDataChannel( } auto* channel = MakeGarbageCollected<RTCDataChannel>( GetExecutionContext(), std::move(webrtc_channel), peer_handler_.get()); - has_data_channels_ = true; return channel; } @@ -2792,8 +2844,12 @@ void RTCPeerConnection::RegisterTrack(MediaStreamTrack* track) { } void RTCPeerConnection::NoteSdpCreated(const RTCSessionDescription& desc) { + // TODO(https://bugs.webrtc.org/12215): Don't re-parse the description here, + // it's passed in as a parsed structure into + // CreateSessionDescriptionRequest::OnSuccess. SdpUsageCategory sdp_usage = DeduceSdpUsageCategory( - desc.type(), desc.sdp(), sdp_semantics_specified_, sdp_semantics_); + ParsedSessionDescription::Parse(desc.type(), desc.sdp()), + sdp_semantics_specified_, sdp_semantics_); if (desc.type() == "offer") { last_offer_ = desc.sdp(); UMA_HISTOGRAM_ENUMERATION( @@ -2808,7 +2864,7 @@ void RTCPeerConnection::NoteSdpCreated(const RTCSessionDescription& desc) { void RTCPeerConnection::OnStreamAddTrack(MediaStream* stream, MediaStreamTrack* track) { ExceptionState exception_state(v8::Isolate::GetCurrent(), - ExceptionState::kExecutionContext, nullptr, + ExceptionState::kUnknownContext, nullptr, nullptr); MediaStreamVector streams; streams.push_back(stream); @@ -2824,7 +2880,7 @@ void RTCPeerConnection::OnStreamRemoveTrack(MediaStream* stream, auto* sender = FindSenderForTrackAndStream(track, stream); if (sender) { ExceptionState exception_state(v8::Isolate::GetCurrent(), - ExceptionState::kExecutionContext, nullptr, + ExceptionState::kUnknownContext, nullptr, nullptr); removeTrack(sender, exception_state); // If removeTrack() failed most likely the connection is closed. The @@ -3287,7 +3343,6 @@ void RTCPeerConnection::DidAddRemoteDataChannel( auto* blink_channel = MakeGarbageCollected<RTCDataChannel>( GetExecutionContext(), std::move(channel), peer_handler_.get()); - has_data_channels_ = true; blink_channel->SetStateToOpenWithoutEvent(); MaybeDispatchEvent(MakeGarbageCollected<RTCDataChannelEvent>( event_type_names::kDatachannel, blink_channel)); @@ -3518,8 +3573,14 @@ void RTCPeerConnection::CloseInternal() { if (sctp_transport_) { sctp_transport_->Close(); } - for (auto& dtls_transport_iter : dtls_transports_by_native_transport_) { - dtls_transport_iter.value->Close(); + // Since Close() can trigger JS-level callbacks, iterate over a copy + // of the transports list. + auto dtls_transports_copy = dtls_transports_by_native_transport_; + for (auto& dtls_transport_iter : dtls_transports_copy) { + // Since "value" is a WeakPtr, check if it's still valid. + if (dtls_transport_iter.value) { + dtls_transport_iter.value->Close(); + } } feature_handle_for_scheduler_.reset(); @@ -3616,11 +3677,6 @@ void RTCPeerConnection::Trace(Visitor* visitor) const { MediaStreamObserver::Trace(visitor); } -base::TimeTicks RTCPeerConnection::WebRtcTimestampToBlinkTimestamp( - base::TimeTicks webrtc_monotonic_time) const { - return webrtc_monotonic_time + blink_webrtc_time_diff_; -} - // static void RTCPeerConnection::SetRtcPeerConnectionHandlerFactoryForTesting( RtcPeerConnectionHandlerFactoryCallback callback) { @@ -3637,4 +3693,12 @@ int RTCPeerConnection::PeerConnectionCountLimit() { return kMaxPeerConnections; } +void RTCPeerConnection::DisableBackForwardCache(ExecutionContext* context) { + LocalDOMWindow* window = To<LocalDOMWindow>(context); + feature_handle_for_scheduler_ = + window->GetFrame()->GetFrameScheduler()->RegisterFeature( + SchedulingPolicy::Feature::kWebRTC, + SchedulingPolicy{SchedulingPolicy::DisableBackForwardCache()}); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h index 4e9fb847e5f..241dc8e4c62 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h @@ -68,7 +68,7 @@ class RTCDtlsTransport; class RTCDTMFSender; class RTCDataChannel; class RTCDataChannelInit; -class RTCIceCandidateInitOrRTCIceCandidate; +class RTCIceCandidateInit; class RTCIceTransport; class RTCOfferOptions; class RTCPeerConnectionTest; @@ -103,8 +103,7 @@ enum class SdpUsageCategory { }; MODULES_EXPORT SdpUsageCategory -DeduceSdpUsageCategory(const String& sdp_type, - const String& sdp, +DeduceSdpUsageCategory(const ParsedSessionDescription& parsed_sdp, bool sdp_semantics_specified, webrtc::SdpSemantics sdp_semantics); @@ -212,10 +211,10 @@ class MODULES_EXPORT RTCPeerConnection final ExceptionState&); ScriptPromise addIceCandidate(ScriptState*, - const RTCIceCandidateInitOrRTCIceCandidate&, + const RTCIceCandidateInit*, ExceptionState&); ScriptPromise addIceCandidate(ScriptState*, - const RTCIceCandidateInitOrRTCIceCandidate&, + const RTCIceCandidateInit*, V8VoidFunction*, V8RTCPeerConnectionErrorCallback*, ExceptionState&); @@ -319,9 +318,8 @@ class MODULES_EXPORT RTCPeerConnection final kSetLocalDescription, kSetRemoteDescription, }; - void ReportSetSdpUsage( - SetSdpOperationType operation_type, - const RTCSessionDescriptionInit* session_description_init) const; + void ReportSetSdpUsage(SetSdpOperationType operation_type, + const ParsedSessionDescription& parsed_sdp) const; // MediaStreamObserver void OnStreamAddTrack(MediaStream*, MediaStreamTrack*) override; @@ -389,7 +387,7 @@ class MODULES_EXPORT RTCPeerConnection final // explicitly specifying the SDP format, there may be errors if the // application assumes a format that differs from the actual default format. base::Optional<ComplexSdpCategory> CheckForComplexSdp( - const RTCSessionDescriptionInit* session_description_init) const; + const ParsedSessionDescription&) const; const CallSetupStateTracker& call_setup_state_tracker() const; void NoteCallSetupStateEventPending( @@ -568,16 +566,18 @@ class MODULES_EXPORT RTCPeerConnection final void CloseInternal(); - void RecordRapporMetrics(); - DOMException* checkSdpForStateErrors(ExecutionContext*, - const RTCSessionDescriptionInit*, - String* sdp); - void MaybeWarnAboutUnsafeSdp( - const RTCSessionDescriptionInit* session_description_init) const; + const ParsedSessionDescription&); + void RecordSdpCategoryAndMaybeEmitWarnings( + const ParsedSessionDescription&) const; HeapHashSet<Member<RTCIceTransport>> ActiveIceTransports() const; + // Disables the back-forward cache usage. This is called when it becomes + // possible for a connection to happen, as a page with connections cannot be + // put into the cache so far. + void DisableBackForwardCache(ExecutionContext* context); + Member<RTCSessionDescription> pending_local_description_; Member<RTCSessionDescription> current_local_description_; Member<RTCSessionDescription> pending_remote_description_; @@ -660,7 +660,7 @@ class MODULES_EXPORT RTCPeerConnection final String last_answer_; Member<RTCSctpTransport> sctp_transport_; - bool has_data_channels_; // For RAPPOR metrics + // In Plan B, senders and receivers are added or removed independently of one // another. In Unified Plan, senders and receivers are created in pairs as // transceivers. Transceivers may become inactive, but are never removed. diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl index a977ad2ebdf..d88ca64f20b 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl @@ -80,7 +80,7 @@ enum RTCPeerConnectionState { readonly attribute RTCSessionDescription? remoteDescription; readonly attribute RTCSessionDescription? currentRemoteDescription; readonly attribute RTCSessionDescription? pendingRemoteDescription; - [CallWith=ScriptState, RaisesException, MeasureAs=RTCPeerConnectionAddIceCandidatePromise] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate); + [CallWith=ScriptState, RaisesException, MeasureAs=RTCPeerConnectionAddIceCandidatePromise] Promise<void> addIceCandidate(optional RTCIceCandidateInit candidate = {}); readonly attribute RTCSignalingState signalingState; readonly attribute RTCIceGatheringState iceGatheringState; readonly attribute RTCIceConnectionState iceConnectionState; @@ -109,7 +109,7 @@ enum RTCPeerConnectionState { // TODO(guidou): The failureCallback argument should be non-optional. // TODO(crbug.com/841185): |failureCallback| is not nullable in the spec. [CallWith=ScriptState] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, optional RTCPeerConnectionErrorCallback? failureCallback); - [CallWith=ScriptState, RaisesException, MeasureAs=RTCPeerConnectionAddIceCandidateLegacy] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback); + [CallWith=ScriptState, RaisesException, MeasureAs=RTCPeerConnectionAddIceCandidateLegacy] Promise<void> addIceCandidate(RTCIceCandidateInit candidate, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback); // getStats() has a standardized version and a legacy non-standard version. // diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc index aaf34b44fac..a48ff12ee49 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc @@ -27,6 +27,7 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_init.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h" #include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h" @@ -344,8 +345,11 @@ class StatsResponse : public webrtc::StatsObserver { public: class MemberIterator : public RTCLegacyStatsMemberIterator { public: - MemberIterator(const StatsReport::Values::const_iterator& it, - const StatsReport::Values::const_iterator& end) + MemberIterator( + const std::vector<StatsReport::Values::value_type>::const_iterator& + it, + const std::vector<StatsReport::Values::value_type>::const_iterator& + end) : it_(it), end_(end) {} // RTCLegacyStatsMemberIterator @@ -378,8 +382,8 @@ class StatsResponse : public webrtc::StatsObserver { } private: - StatsReport::Values::const_iterator it_; - StatsReport::Values::const_iterator end_; + std::vector<StatsReport::Values::value_type>::const_iterator it_; + std::vector<StatsReport::Values::value_type>::const_iterator end_; }; explicit Report(const StatsReport* report) @@ -387,7 +391,7 @@ class StatsResponse : public webrtc::StatsObserver { type_(report->type()), type_name_(report->TypeToString()), timestamp_(report->timestamp()), - values_(report->values()) {} + values_(report->values().begin(), report->values().end()) {} ~Report() override { // Since the values vector holds pointers to const objects that are bound @@ -411,7 +415,7 @@ class StatsResponse : public webrtc::StatsObserver { const StatsReport::StatsType type_; const std::string type_name_; const double timestamp_; - const StatsReport::Values values_; + const std::vector<StatsReport::Values::value_type> values_; }; static void DeleteReports(std::vector<Report*>* reports) { @@ -602,6 +606,42 @@ bool IsHostnameCandidate(const RTCIceCandidatePlatform& candidate) { } // namespace +// Implementation of ParsedSessionDescription +ParsedSessionDescription::ParsedSessionDescription(const String& sdp_type, + const String& sdp) + : type_(sdp_type), sdp_(sdp) {} + +// static +ParsedSessionDescription ParsedSessionDescription::Parse( + const RTCSessionDescriptionInit* session_description_init) { + ParsedSessionDescription temp(session_description_init->type(), + session_description_init->sdp()); + temp.DoParse(); + return temp; +} + +// static +ParsedSessionDescription ParsedSessionDescription::Parse( + const RTCSessionDescriptionPlatform* session_description_platform) { + ParsedSessionDescription temp(session_description_platform->GetType(), + session_description_platform->Sdp()); + temp.DoParse(); + return temp; +} + +// static +ParsedSessionDescription ParsedSessionDescription::Parse(const String& sdp_type, + const String& sdp) { + ParsedSessionDescription temp(sdp_type, sdp); + temp.DoParse(); + return temp; +} + +void ParsedSessionDescription::DoParse() { + description_.reset(webrtc::CreateSessionDescription( + type_.Utf8().c_str(), sdp_.Utf8().c_str(), &error_)); +} + // Implementation of LocalRTCStatsRequest. LocalRTCStatsRequest::LocalRTCStatsRequest(RTCStatsRequest* impl) : impl_(impl) {} @@ -1106,7 +1146,8 @@ bool RTCPeerConnectionHandler::Initialize( const webrtc::PeerConnectionInterface::RTCConfiguration& server_configuration, const MediaConstraints& options, - WebLocalFrame* frame) { + WebLocalFrame* frame, + ExceptionState& exception_state) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(frame); frame_ = frame; @@ -1140,7 +1181,7 @@ bool RTCPeerConnectionHandler::Initialize( peer_connection_observer_ = MakeGarbageCollected<Observer>(weak_factory_.GetWeakPtr(), task_runner_); native_peer_connection_ = dependency_factory_->CreatePeerConnection( - configuration_, frame_, peer_connection_observer_); + configuration_, frame_, peer_connection_observer_, exception_state); if (!native_peer_connection_.get()) { LOG(ERROR) << "Failed to initialize native PeerConnection."; return false; @@ -1159,7 +1200,8 @@ bool RTCPeerConnectionHandler::InitializeForTest( const webrtc::PeerConnectionInterface::RTCConfiguration& server_configuration, const MediaConstraints& options, - const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker) { + const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker, + ExceptionState& exception_state) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); CHECK(!initialize_called_); @@ -1172,7 +1214,7 @@ bool RTCPeerConnectionHandler::InitializeForTest( CopyConstraintsIntoRtcConfiguration(options, &configuration_); native_peer_connection_ = dependency_factory_->CreatePeerConnection( - configuration_, nullptr, peer_connection_observer_); + configuration_, nullptr, peer_connection_observer_, exception_state); if (!native_peer_connection_.get()) { LOG(ERROR) << "Failed to initialize native PeerConnection."; return false; @@ -1341,24 +1383,22 @@ void RTCPeerConnectionHandler::SetLocalDescription( void RTCPeerConnectionHandler::SetLocalDescription( blink::RTCVoidRequest* request, - RTCSessionDescriptionPlatform* description) { + ParsedSessionDescription parsed_sdp) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setLocalDescription"); - String sdp = description->Sdp(); - String type = description->GetType(); + String sdp = parsed_sdp.sdp(); + String type = parsed_sdp.type(); if (peer_connection_tracker_) { peer_connection_tracker_->TrackSetSessionDescription( this, sdp, type, PeerConnectionTracker::SOURCE_LOCAL); } - webrtc::SdpParseError error; - // Since CreateNativeSessionDescription uses the dependency factory, we need - // to make this call on the current thread to be safe. - std::unique_ptr<webrtc::SessionDescriptionInterface> native_desc( - CreateNativeSessionDescription(sdp, type, &error)); + const webrtc::SessionDescriptionInterface* native_desc = + parsed_sdp.description(); if (!native_desc) { + webrtc::SdpParseError error(parsed_sdp.error()); StringBuilder reason_str; reason_str.Append("Failed to parse SessionDescription. "); reason_str.Append(error.line.c_str()); @@ -1381,9 +1421,9 @@ void RTCPeerConnectionHandler::SetLocalDescription( return; } - if (!first_local_description_ && IsOfferOrAnswer(native_desc.get())) { + if (!first_local_description_ && IsOfferOrAnswer(native_desc)) { first_local_description_ = - std::make_unique<FirstSessionDescription>(native_desc.get()); + std::make_unique<FirstSessionDescription>(native_desc); if (first_remote_description_) { ReportFirstSessionDescriptions(*first_local_description_, *first_remote_description_); @@ -1415,30 +1455,27 @@ void RTCPeerConnectionHandler::SetLocalDescription( rtc::scoped_refptr< webrtc::SetLocalDescriptionObserverInterface>)>( &webrtc::PeerConnectionInterface::SetLocalDescription), - native_peer_connection_, WTF::Passed(std::move(native_desc)), - webrtc_observer), + native_peer_connection_, parsed_sdp.release(), webrtc_observer), CrossThreadUnretained("SetLocalDescription"))); } void RTCPeerConnectionHandler::SetRemoteDescription( blink::RTCVoidRequest* request, - RTCSessionDescriptionPlatform* description) { + ParsedSessionDescription parsed_sdp) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setRemoteDescription"); - String sdp = description->Sdp(); - String type = description->GetType(); + String sdp = parsed_sdp.sdp(); + String type = parsed_sdp.type(); if (peer_connection_tracker_) { peer_connection_tracker_->TrackSetSessionDescription( this, sdp, type, PeerConnectionTracker::SOURCE_REMOTE); } - webrtc::SdpParseError error; - // Since CreateNativeSessionDescription uses the dependency factory, we need - // to make this call on the current thread to be safe. - std::unique_ptr<webrtc::SessionDescriptionInterface> native_desc( - CreateNativeSessionDescription(sdp, type, &error)); + webrtc::SdpParseError error(parsed_sdp.error()); + const webrtc::SessionDescriptionInterface* native_desc = + parsed_sdp.description(); if (!native_desc) { StringBuilder reason_str; reason_str.Append("Failed to parse SessionDescription. "); @@ -1463,9 +1500,9 @@ void RTCPeerConnectionHandler::SetRemoteDescription( return; } - if (!first_remote_description_ && IsOfferOrAnswer(native_desc.get())) { - first_remote_description_.reset( - new FirstSessionDescription(native_desc.get())); + if (!first_remote_description_ && IsOfferOrAnswer(native_desc)) { + first_remote_description_ = + std::make_unique<FirstSessionDescription>(native_desc); if (first_local_description_) { ReportFirstSessionDescriptions(*first_local_description_, *first_remote_description_); @@ -1497,8 +1534,7 @@ void RTCPeerConnectionHandler::SetRemoteDescription( rtc::scoped_refptr< webrtc::SetRemoteDescriptionObserverInterface>)>( &webrtc::PeerConnectionInterface::SetRemoteDescription), - native_peer_connection_, WTF::Passed(std::move(native_desc)), - webrtc_observer), + native_peer_connection_, parsed_sdp.release(), webrtc_observer), CrossThreadUnretained("SetRemoteDescription"))); } @@ -2066,7 +2102,7 @@ ThermalUmaListener* RTCPeerConnectionHandler::thermal_uma_listener() const { } void RTCPeerConnectionHandler::OnThermalStateChange( - base::PowerObserver::DeviceThermalState thermal_state) { + mojom::blink::DeviceThermalState thermal_state) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (is_closed_) return; @@ -2456,7 +2492,9 @@ void RTCPeerConnectionHandler::OnModifyTransceivers( previous_state.stopped() != transceiver_states[i].stopped() || previous_state.direction() != transceiver_states[i].direction() || previous_state.current_direction() != - transceiver_states[i].current_direction(); + transceiver_states[i].current_direction() || + previous_state.header_extensions_negotiated() != + transceiver_states[i].header_extensions_negotiated(); } // Update the transceiver. @@ -2564,20 +2602,6 @@ void RTCPeerConnectionHandler::OnInterestingUsage(int usage_pattern) { client_->DidNoteInterestingUsage(usage_pattern); } -webrtc::SessionDescriptionInterface* -RTCPeerConnectionHandler::CreateNativeSessionDescription( - const String& sdp, - const String& type, - webrtc::SdpParseError* error) { - webrtc::SessionDescriptionInterface* native_desc = - dependency_factory_->CreateSessionDescription(type, sdp, error); - - LOG_IF(ERROR, !native_desc) << "Failed to create native session description." - << " Type: " << type << " SDP: " << sdp; - - return native_desc; -} - RTCPeerConnectionHandler::FirstSessionDescription::FirstSessionDescription( const webrtc::SessionDescriptionInterface* sdesc) { DCHECK(sdesc); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h index 13c92ab732f..dd93da030f4 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h @@ -15,8 +15,8 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" -#include "base/power_monitor/power_observer.h" #include "base/single_thread_task_runner.h" +#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/peerconnection/media_stream_track_metrics.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h" @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h" #include "third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h" #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" @@ -52,10 +53,60 @@ class RTCAnswerOptionsPlatform; class RTCLegacyStats; class RTCOfferOptionsPlatform; class RTCPeerConnectionHandlerClient; +class RTCSessionDescriptionInit; class RTCVoidRequest; class SetLocalDescriptionRequest; class WebLocalFrame; +// Helper class for passing pre-parsed session descriptions to functions. +// Create a ParsedSessionDescription by calling one of the Parse functions. +// The function allows you to access its input SDP string, as well as the +// parsed form. If parse failed, description() returns null, and error() +// returns an error description. The class can't be modified or reused, +// but can be neutered by calling release(). +class MODULES_EXPORT ParsedSessionDescription { + public: + static ParsedSessionDescription Parse(const RTCSessionDescriptionInit*); + static ParsedSessionDescription Parse(const RTCSessionDescriptionPlatform*); + static ParsedSessionDescription Parse(const String& type, const String& sdp); + + // Moveable, but not copyable. + ParsedSessionDescription(ParsedSessionDescription&& other) = default; + ParsedSessionDescription& operator=(ParsedSessionDescription&& other) = + default; + ParsedSessionDescription(const ParsedSessionDescription&) = delete; + ParsedSessionDescription operator=(const ParsedSessionDescription&) = delete; + + const webrtc::SessionDescriptionInterface* description() const { + return description_.get(); + } + const webrtc::SdpParseError& error() const { return error_; } + const String& type() const { return type_; } + const String& sdp() const { return sdp_; } + + std::unique_ptr<webrtc::SessionDescriptionInterface> release() { + return std::unique_ptr<webrtc::SessionDescriptionInterface>( + description_.release()); + } + + protected: + // The constructor will not parse the SDP. + // It is protected, not private, in order to allow it to be used to construct + // mock objects. + ParsedSessionDescription(const String& type, const String& sdp); + // The mock object also needs access to the description. + std::unique_ptr<webrtc::SessionDescriptionInterface> description_; + + private: + // Does the actual parsing. Only called from the static Parse methods. + void DoParse(); + + String type_; + String sdp_; + + webrtc::SdpParseError error_; +}; + // Mockable wrapper for blink::RTCStatsResponseBase class MODULES_EXPORT LocalRTCStatsResponse : public rtc::RefCountInterface { public: @@ -124,14 +175,16 @@ class MODULES_EXPORT RTCPeerConnectionHandler { const webrtc::PeerConnectionInterface::RTCConfiguration& server_configuration, const MediaConstraints& options, - const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker); + const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker, + ExceptionState& exception_state); // RTCPeerConnectionHandlerPlatform implementation virtual bool Initialize( const webrtc::PeerConnectionInterface::RTCConfiguration& server_configuration, const MediaConstraints& options, - WebLocalFrame* web_frame); + WebLocalFrame* web_frame, + ExceptionState& exception_state); virtual void Stop(); virtual void StopAndUnregister(); @@ -149,10 +202,12 @@ class MODULES_EXPORT RTCPeerConnectionHandler { blink::RTCAnswerOptionsPlatform* options); virtual void SetLocalDescription(blink::RTCVoidRequest* request); + // Set local and remote description. + // The parsed_sdp argument must be passed in with std::move. virtual void SetLocalDescription(blink::RTCVoidRequest* request, - RTCSessionDescriptionPlatform* description); + ParsedSessionDescription parsed_sdp); virtual void SetRemoteDescription(blink::RTCVoidRequest* request, - RTCSessionDescriptionPlatform* description); + ParsedSessionDescription parsed_sdp); virtual const webrtc::PeerConnectionInterface::RTCConfiguration& GetConfiguration() const; @@ -211,7 +266,7 @@ class MODULES_EXPORT RTCPeerConnectionHandler { // Invoked when a new thermal state is received from the OS. // Virtual for testing purposes. virtual void OnThermalStateChange( - base::PowerObserver::DeviceThermalState thermal_state); + mojom::blink::DeviceThermalState thermal_state); // Start recording an event log. void StartEventLog(int output_period_ms); @@ -317,11 +372,6 @@ class MODULES_EXPORT RTCPeerConnectionHandler { kFailure, }; - webrtc::SessionDescriptionInterface* CreateNativeSessionDescription( - const String& sdp, - const String& type, - webrtc::SdpParseError* error); - RTCSessionDescriptionPlatform* GetRTCSessionDescriptionPlatformOnSignalingThread( CrossThreadOnceFunction<const webrtc::SessionDescriptionInterface*()> @@ -473,8 +523,8 @@ class MODULES_EXPORT RTCPeerConnectionHandler { scoped_refptr<ThermalResource> thermal_resource_ = nullptr; // ThermalUmaListener is only tracked on peer connection that add a track. std::unique_ptr<ThermalUmaListener> thermal_uma_listener_ = nullptr; - base::PowerObserver::DeviceThermalState last_thermal_state_ = - base::PowerObserver::DeviceThermalState::kUnknown; + mojom::blink::DeviceThermalState last_thermal_state_ = + mojom::blink::DeviceThermalState::kUnknown; // Record info about the first SessionDescription from the local and // remote side to record UMA stats once both are set. We only check diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc index 8f05c347ac7..5c821af2657 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc @@ -41,6 +41,7 @@ #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h" #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h" #include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h" +#include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.h" #include "third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h" #include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h" #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h" @@ -295,9 +296,10 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test { webrtc::PeerConnectionInterface::RTCConfiguration config; config.sdp_semantics = webrtc::SdpSemantics::kPlanB; MediaConstraints constraints; - EXPECT_TRUE(pc_handler_->InitializeForTest( - config, constraints, mock_tracker_.get()->AsWeakPtr())); - + DummyExceptionStateForTesting exception_state; + EXPECT_TRUE(pc_handler_->InitializeForTest(config, constraints, + mock_tracker_.get()->AsWeakPtr(), + exception_state)); mock_peer_connection_ = pc_handler_->native_peer_connection(); ASSERT_TRUE(mock_peer_connection_); EXPECT_CALL(*mock_peer_connection_, Close()); @@ -661,8 +663,6 @@ TEST_F(RTCPeerConnectionHandlerTest, CreateAnswer) { } TEST_F(RTCPeerConnectionHandlerTest, setLocalDescription) { - auto* description = MakeGarbageCollected<RTCSessionDescriptionPlatform>( - kDummySdpType, kDummySdp); // PeerConnectionTracker::TrackSetSessionDescription is expected to be called // before |mock_peer_connection| is called. testing::InSequence sequence; @@ -672,7 +672,9 @@ TEST_F(RTCPeerConnectionHandlerTest, setLocalDescription) { PeerConnectionTracker::SOURCE_LOCAL)); EXPECT_CALL(*mock_peer_connection_, SetLocalDescriptionForMock(_, _)); - pc_handler_->SetLocalDescription(nullptr /*RTCVoidRequest*/, description); + pc_handler_->SetLocalDescription( + nullptr /*RTCVoidRequest*/, + MockParsedSessionDescription(kDummySdpType, kDummySdp)); RunMessageLoopsUntilIdle(); std::string sdp_string; @@ -705,14 +707,12 @@ TEST_F(RTCPeerConnectionHandlerTest, setLocalDescriptionParseError) { // Used to simulate a parse failure. mock_dependency_factory_->SetFailToCreateSessionDescription(true); - pc_handler_->SetLocalDescription(nullptr /*RTCVoidRequest*/, description); + pc_handler_->SetLocalDescription( + nullptr /*RTCVoidRequest*/, ParsedSessionDescription::Parse(description)); RunMessageLoopsUntilIdle(); } TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescription) { - auto* description = MakeGarbageCollected<RTCSessionDescriptionPlatform>( - kDummySdpType, kDummySdp); - // PeerConnectionTracker::TrackSetSessionDescription is expected to be called // before |mock_peer_connection| is called. testing::InSequence sequence; @@ -722,7 +722,9 @@ TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescription) { PeerConnectionTracker::SOURCE_REMOTE)); EXPECT_CALL(*mock_peer_connection_, SetRemoteDescriptionForMock(_, _)); - pc_handler_->SetRemoteDescription(nullptr /*RTCVoidRequest*/, description); + pc_handler_->SetRemoteDescription( + nullptr /*RTCVoidRequest*/, + MockParsedSessionDescription(kDummySdpType, kDummySdp)); RunMessageLoopsUntilIdle(); std::string sdp_string; @@ -755,7 +757,8 @@ TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescriptionParseError) { // Used to simulate a parse failure. mock_dependency_factory_->SetFailToCreateSessionDescription(true); - pc_handler_->SetRemoteDescription(nullptr /*RTCVoidRequest*/, description); + pc_handler_->SetRemoteDescription( + nullptr /*RTCVoidRequest*/, ParsedSessionDescription::Parse(description)); RunMessageLoopsUntilIdle(); } @@ -1289,7 +1292,7 @@ TEST_F(RTCPeerConnectionHandlerTest, CheckInsertableStreamsConfig) { TEST_F(RTCPeerConnectionHandlerTest, ThermalResourceDefaultValue) { EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty()); pc_handler_->OnThermalStateChange( - base::PowerObserver::DeviceThermalState::kCritical); + mojom::blink::DeviceThermalState::kCritical); #if defined(OS_MAC) bool expect_disabled = false; #else @@ -1308,7 +1311,7 @@ TEST_F(RTCPeerConnectionHandlerTest, EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty()); pc_handler_->OnThermalStateChange( - base::PowerObserver::DeviceThermalState::kCritical); + mojom::blink::DeviceThermalState::kCritical); // A ThermalResource is created in response to the thermal signal. EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty()); } @@ -1322,7 +1325,7 @@ TEST_F(RTCPeerConnectionHandlerTest, EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty()); // ThermalResource is created and injected on the fly. pc_handler_->OnThermalStateChange( - base::PowerObserver::DeviceThermalState::kCritical); + mojom::blink::DeviceThermalState::kCritical); auto resources = mock_peer_connection_->adaptation_resources(); ASSERT_EQ(1u, resources.size()); auto thermal_resource = resources[0]; @@ -1334,8 +1337,7 @@ TEST_F(RTCPeerConnectionHandlerTest, EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, resource_listener.latest_measurement()); // ThermalResource responds to new measurements. - pc_handler_->OnThermalStateChange( - base::PowerObserver::DeviceThermalState::kNominal); + pc_handler_->OnThermalStateChange(mojom::blink::DeviceThermalState::kNominal); EXPECT_EQ(2u, resource_listener.measurement_count()); EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, resource_listener.latest_measurement()); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc index 4f44d82f0a0..9034298078c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc @@ -57,8 +57,8 @@ RTCPeerConnectionIceErrorEvent::RTCPeerConnectionIceErrorEvent( host_candidate_ = initializer->hostCandidate(); if (initializer->hasUrl()) url_ = initializer->url(); - if (initializer->hasStatusText()) - error_text_ = initializer->statusText(); + if (initializer->hasErrorText()) + error_text_ = initializer->errorText(); } RTCPeerConnectionIceErrorEvent::~RTCPeerConnectionIceErrorEvent() = default; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl index a0734029421..98344f95bd7 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl @@ -10,5 +10,5 @@ dictionary RTCPeerConnectionIceErrorEventInit : EventInit { DOMString hostCandidate; DOMString url; required unsigned short errorCode; - USVString statusText; -};
\ No newline at end of file + USVString errorText; +}; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc index 1e6208438d5..8b5a528dbd1 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc @@ -43,6 +43,8 @@ namespace blink { class RTCOfferOptionsPlatform; +namespace { + static const char* kOfferSdpUnifiedPlanSingleAudioSingleVideo = "v=0\r\n" "o=- 6676943034916303038 2 IN IP4 127.0.0.1\r\n" @@ -376,6 +378,15 @@ static const char* kOfferSdpPlanBMultipleAudioTracks = "a=ssrc:4092260337 mslabel:46f8615e-7599-49f3-9a45-3cf0faf58614\r\n" "a=ssrc:4092260337 label:6b5f436e-f85d-40a1-83e4-acec63ca4b82\r\n"; +RTCSessionDescriptionInit* CreateSdp(String type, String sdp) { + auto* sdp_init = RTCSessionDescriptionInit::Create(); + sdp_init->setType(type); + sdp_init->setSdp(sdp); + return sdp_init; +} + +} // namespace + class RTCPeerConnectionTest : public testing::Test { public: RTCPeerConnection* CreatePC( @@ -584,22 +595,27 @@ TEST_F(RTCPeerConnectionTest, CheckForComplexSdpWithSdpSemanticsPlanB) { RTCSessionDescriptionInit* sdp = RTCSessionDescriptionInit::Create(); sdp->setType("offer"); sdp->setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kUnifiedPlanExplicitSemantics); sdp->setSdp(kOfferSdpPlanBMultipleAudioTracks); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kPlanBExplicitSemantics); sdp->setSdp("invalid sdp"); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kErrorExplicitSemantics); // No Complex SDP is detected if only a single track per m= section is used. sdp->setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo); - ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value()); + ASSERT_FALSE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); sdp->setSdp(kOfferSdpPlanBSingleAudioSingleVideo); - ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value()); + ASSERT_FALSE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); } TEST_F(RTCPeerConnectionTest, CheckForComplexSdpWithSdpSemanticsUnifiedPlan) { @@ -608,22 +624,27 @@ TEST_F(RTCPeerConnectionTest, CheckForComplexSdpWithSdpSemanticsUnifiedPlan) { RTCSessionDescriptionInit* sdp = RTCSessionDescriptionInit::Create(); sdp->setType("offer"); sdp->setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kUnifiedPlanExplicitSemantics); sdp->setSdp(kOfferSdpPlanBMultipleAudioTracks); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kPlanBExplicitSemantics); sdp->setSdp("invalid sdp"); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kErrorExplicitSemantics); // No Complex SDP is detected if only a single track per m= section is used. sdp->setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo); - ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value()); + ASSERT_FALSE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); sdp->setSdp(kOfferSdpPlanBSingleAudioSingleVideo); - ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value()); + ASSERT_FALSE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); } TEST_F(RTCPeerConnectionTest, CheckForComplexSdpWithSdpSemanticsUnspecified) { @@ -632,22 +653,27 @@ TEST_F(RTCPeerConnectionTest, CheckForComplexSdpWithSdpSemanticsUnspecified) { RTCSessionDescriptionInit* sdp = RTCSessionDescriptionInit::Create(); sdp->setType("offer"); sdp->setSdp(kOfferSdpPlanBMultipleAudioTracks); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kPlanBImplicitSemantics); sdp->setSdp(kOfferSdpUnifiedPlanMultipleAudioTracks); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kUnifiedPlanImplicitSemantics); sdp->setSdp("invalid sdp"); - ASSERT_TRUE(pc->CheckForComplexSdp(sdp).has_value()); - ASSERT_EQ(pc->CheckForComplexSdp(sdp), + ASSERT_TRUE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); + ASSERT_EQ(pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)), ComplexSdpCategory::kErrorImplicitSemantics); // No Complex SDP is detected if only a single track per m= section is used. sdp->setSdp(kOfferSdpUnifiedPlanSingleAudioSingleVideo); - ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value()); + ASSERT_FALSE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); sdp->setSdp(kOfferSdpPlanBSingleAudioSingleVideo); - ASSERT_FALSE(pc->CheckForComplexSdp(sdp).has_value()); + ASSERT_FALSE( + pc->CheckForComplexSdp(ParsedSessionDescription::Parse(sdp)).has_value()); } TEST_F(RTCPeerConnectionTest, CheckInsertableStreamsConfig) { @@ -746,12 +772,12 @@ class FakeRTCPeerConnectionHandlerPlatform } void SetLocalDescription(RTCVoidRequest* request, - RTCSessionDescriptionPlatform*) override { + ParsedSessionDescription) override { PostToCompleteRequest<RTCVoidRequest>(async_operation_action_, request); } void SetRemoteDescription(RTCVoidRequest* request, - RTCSessionDescriptionPlatform*) override { + ParsedSessionDescription) override { PostToCompleteRequest<RTCVoidRequest>(async_operation_action_, request); } @@ -1058,22 +1084,26 @@ TEST(DeduceSdpUsageCategory, SimplePlanBIsAlwaysSafe) { // If the default is Plan B. EXPECT_EQ( SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", kOfferSdpPlanBSingleAudioSingleVideo, + DeduceSdpUsageCategory(ParsedSessionDescription::Parse( + "offer", kOfferSdpPlanBSingleAudioSingleVideo), false, webrtc::SdpSemantics::kPlanB)); // If the default is Unified Plan. EXPECT_EQ( SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", kOfferSdpPlanBSingleAudioSingleVideo, + DeduceSdpUsageCategory(ParsedSessionDescription::Parse( + "offer", kOfferSdpPlanBSingleAudioSingleVideo), false, webrtc::SdpSemantics::kUnifiedPlan)); // If sdpSemantics is explicitly set to Plan B. EXPECT_EQ( SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", kOfferSdpPlanBSingleAudioSingleVideo, + DeduceSdpUsageCategory(ParsedSessionDescription::Parse( + "offer", kOfferSdpPlanBSingleAudioSingleVideo), true, webrtc::SdpSemantics::kPlanB)); // If sdpSemantics is explicitly set to Unified Plan. EXPECT_EQ( SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", kOfferSdpPlanBSingleAudioSingleVideo, + DeduceSdpUsageCategory(ParsedSessionDescription::Parse( + "offer", kOfferSdpPlanBSingleAudioSingleVideo), true, webrtc::SdpSemantics::kUnifiedPlan)); } @@ -1082,72 +1112,175 @@ TEST(DeduceSdpUsageCategory, SimplePlanBIsAlwaysSafe) { TEST(DeduceSdpUsageCategory, SimpleUnifiedPlanIsAlwaysSafe) { // If the default is Plan B. EXPECT_EQ(SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", - kOfferSdpUnifiedPlanSingleAudioSingleVideo, - false, webrtc::SdpSemantics::kPlanB)); + DeduceSdpUsageCategory( + ParsedSessionDescription::Parse( + "offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo), + false, webrtc::SdpSemantics::kPlanB)); // If the default is Unified Plan. EXPECT_EQ(SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", - kOfferSdpUnifiedPlanSingleAudioSingleVideo, - false, webrtc::SdpSemantics::kUnifiedPlan)); + DeduceSdpUsageCategory( + ParsedSessionDescription::Parse( + "offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo), + false, webrtc::SdpSemantics::kUnifiedPlan)); // If sdpSemantics is explicitly set to Plan B. EXPECT_EQ(SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", - kOfferSdpUnifiedPlanSingleAudioSingleVideo, - true, webrtc::SdpSemantics::kPlanB)); + DeduceSdpUsageCategory( + ParsedSessionDescription::Parse( + "offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo), + true, webrtc::SdpSemantics::kPlanB)); // If sdpSemantics is explicitly set to Unified Plan. EXPECT_EQ(SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", - kOfferSdpUnifiedPlanSingleAudioSingleVideo, - true, webrtc::SdpSemantics::kUnifiedPlan)); + DeduceSdpUsageCategory( + ParsedSessionDescription::Parse( + "offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo), + true, webrtc::SdpSemantics::kUnifiedPlan)); } // Test that complex SDP is always unsafe when relying on default sdpSemantics. TEST(DeduceSdpUsageCategory, ComplexSdpIsAlwaysUnsafeWithDefaultSdpSemantics) { // If the default is Plan B and the SDP is complex Plan B. - EXPECT_EQ(SdpUsageCategory::kUnsafe, - DeduceSdpUsageCategory("offer", kOfferSdpPlanBMultipleAudioTracks, - false, webrtc::SdpSemantics::kPlanB)); - // If the default is Plan B and the SDP is complex Unified Plan. EXPECT_EQ( SdpUsageCategory::kUnsafe, - DeduceSdpUsageCategory("offer", kOfferSdpUnifiedPlanMultipleAudioTracks, + DeduceSdpUsageCategory(ParsedSessionDescription::Parse( + "offer", kOfferSdpPlanBMultipleAudioTracks), false, webrtc::SdpSemantics::kPlanB)); - // If the default is Unified Plan and the SDP is complex Plan B. + // If the default is Plan B and the SDP is complex Unified Plan. EXPECT_EQ(SdpUsageCategory::kUnsafe, - DeduceSdpUsageCategory("offer", kOfferSdpPlanBMultipleAudioTracks, - false, webrtc::SdpSemantics::kUnifiedPlan)); - // If the default is Unified Plan and the SDP is complex UNified Plan. + DeduceSdpUsageCategory( + ParsedSessionDescription::Parse( + "offer", kOfferSdpUnifiedPlanMultipleAudioTracks), + false, webrtc::SdpSemantics::kPlanB)); + // If the default is Unified Plan and the SDP is complex Plan B. EXPECT_EQ( SdpUsageCategory::kUnsafe, - DeduceSdpUsageCategory("offer", kOfferSdpUnifiedPlanMultipleAudioTracks, + DeduceSdpUsageCategory(ParsedSessionDescription::Parse( + "offer", kOfferSdpPlanBMultipleAudioTracks), false, webrtc::SdpSemantics::kUnifiedPlan)); + // If the default is Unified Plan and the SDP is complex UNified Plan. + EXPECT_EQ(SdpUsageCategory::kUnsafe, + DeduceSdpUsageCategory( + ParsedSessionDescription::Parse( + "offer", kOfferSdpUnifiedPlanMultipleAudioTracks), + false, webrtc::SdpSemantics::kUnifiedPlan)); } // Test that when sdpSemantics is explicitly set, complex SDP is safe if it is // of the same format and unsafe if the format is different. TEST(DeduceSdpUsageCategory, ComplexSdpIsSafeIfMatchingExplicitSdpSemantics) { // If sdpSemantics is explicitly set to Plan B and the SDP is complex Plan B. - EXPECT_EQ(SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", kOfferSdpPlanBMultipleAudioTracks, - true, webrtc::SdpSemantics::kPlanB)); - // If sdpSemantics is explicitly set to Unified Plan and the SDP is complex - // Unified Plan. EXPECT_EQ( SdpUsageCategory::kSafe, - DeduceSdpUsageCategory("offer", kOfferSdpUnifiedPlanMultipleAudioTracks, - true, webrtc::SdpSemantics::kUnifiedPlan)); + DeduceSdpUsageCategory(ParsedSessionDescription::Parse( + "offer", kOfferSdpPlanBMultipleAudioTracks), + true, webrtc::SdpSemantics::kPlanB)); + // If sdpSemantics is explicitly set to Unified Plan and the SDP is complex + // Unified Plan. + EXPECT_EQ(SdpUsageCategory::kSafe, + DeduceSdpUsageCategory( + ParsedSessionDescription::Parse( + "offer", kOfferSdpUnifiedPlanMultipleAudioTracks), + true, webrtc::SdpSemantics::kUnifiedPlan)); // If the sdpSemantics is explicitly set to Plan B but the SDP is complex // Unified Plan. - EXPECT_EQ( - SdpUsageCategory::kUnsafe, - DeduceSdpUsageCategory("offer", kOfferSdpUnifiedPlanMultipleAudioTracks, - true, webrtc::SdpSemantics::kPlanB)); + EXPECT_EQ(SdpUsageCategory::kUnsafe, + DeduceSdpUsageCategory( + ParsedSessionDescription::Parse( + "offer", kOfferSdpUnifiedPlanMultipleAudioTracks), + true, webrtc::SdpSemantics::kPlanB)); // If the sdpSemantics is explicitly set to Unified Plan but the SDP is // complex Plan B. - EXPECT_EQ(SdpUsageCategory::kUnsafe, - DeduceSdpUsageCategory("offer", kOfferSdpPlanBMultipleAudioTracks, - true, webrtc::SdpSemantics::kUnifiedPlan)); + EXPECT_EQ( + SdpUsageCategory::kUnsafe, + DeduceSdpUsageCategory(ParsedSessionDescription::Parse( + "offer", kOfferSdpPlanBMultipleAudioTracks), + true, webrtc::SdpSemantics::kUnifiedPlan)); +} + +TEST_F(RTCPeerConnectionTest, SdpSemanticsUseCounters) { + // Constructor with default sdpSemantics (= Unified Plan). + { + V8TestingScope scope; + RTCPeerConnection* pc = CreatePC(scope, /*sdp_semantics=*/base::nullopt); + // Use counters reflect the constructor's sdpSemantics. + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionConstructedWithPlanB)); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionConstructedWithUnifiedPlan)); + // Setting simple Unified Plan SDP does not affect use counters. + pc->setRemoteDescription( + scope.GetScriptState(), + CreateSdp("offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo), + scope.GetExceptionState()); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexPlanB)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexUnifiedPlan)); + // Setting complex Unified Plan SDP does affect use counters. + pc->setRemoteDescription( + scope.GetScriptState(), + CreateSdp("offer", kOfferSdpUnifiedPlanMultipleAudioTracks), + scope.GetExceptionState()); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexPlanB)); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexUnifiedPlan)); + } + // Constructor with {sdpSemantics:"plan-b"}. + { + V8TestingScope scope; + RTCPeerConnection* pc = CreatePC(scope, "plan-b"); + // Use counters reflect the constructor's sdpSemantics. + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionConstructedWithPlanB)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionConstructedWithUnifiedPlan)); + // Setting simple Plan B SDP does not affect use counters. + pc->setRemoteDescription( + scope.GetScriptState(), + CreateSdp("offer", kOfferSdpPlanBSingleAudioSingleVideo), + scope.GetExceptionState()); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexPlanB)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexUnifiedPlan)); + // Setting complex Plan B SDP does affect use counters. + pc->setRemoteDescription( + scope.GetScriptState(), + CreateSdp("offer", kOfferSdpPlanBMultipleAudioTracks), + scope.GetExceptionState()); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexPlanB)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexUnifiedPlan)); + } + // Constructor with {sdpSemantics:"unified-plan"}. + { + V8TestingScope scope; + RTCPeerConnection* pc = CreatePC(scope, "unified-plan"); + // Use counters reflect the constructor's sdpSemantics. + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionConstructedWithPlanB)); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionConstructedWithUnifiedPlan)); + // Setting simple Unified Plan SDP does not affect use counters. + pc->setRemoteDescription( + scope.GetScriptState(), + CreateSdp("offer", kOfferSdpUnifiedPlanSingleAudioSingleVideo), + scope.GetExceptionState()); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexPlanB)); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexUnifiedPlan)); + // Setting complex Unified Plan SDP does affect use counters. + pc->setRemoteDescription( + scope.GetScriptState(), + CreateSdp("offer", kOfferSdpUnifiedPlanMultipleAudioTracks), + scope.GetExceptionState()); + EXPECT_FALSE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexPlanB)); + EXPECT_TRUE(scope.GetDocument().IsUseCounted( + WebFeature::kRTCPeerConnectionUsingComplexUnifiedPlan)); + } } TEST_F(RTCPeerConnectionTest, MediaStreamTrackStopsThrottling) { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl index 388f11b49ac..8d77b3a3e52 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl @@ -5,4 +5,5 @@ // https://w3c.github.io/webrtc-pc/#rtcrtpheaderextensioncapability* dictionary RTCRtpHeaderExtensionCapability { DOMString uri; -};
\ No newline at end of file + RTCRtpTransceiverDirection direction = "sendrecv"; +}; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc index 173e1965cbc..c60eba5d8f7 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc @@ -115,9 +115,7 @@ RTCRtpReceiver::getSynchronizationSources(ScriptState* script_state, RTCRtpSynchronizationSource* synchronization_source = MakeGarbageCollected<RTCRtpSynchronizationSource>(); synchronization_source->setTimestamp( - time_converter - .MonotonicTimeToPseudoWallTime( - pc_->WebRtcTimestampToBlinkTimestamp(web_source->Timestamp())) + time_converter.MonotonicTimeToPseudoWallTime(web_source->Timestamp()) .InMilliseconds()); synchronization_source->setSource(web_source->Source()); if (web_source->AudioLevel()) @@ -154,9 +152,7 @@ RTCRtpReceiver::getContributingSources(ScriptState* script_state, RTCRtpContributingSource* contributing_source = MakeGarbageCollected<RTCRtpContributingSource>(); contributing_source->setTimestamp( - time_converter - .MonotonicTimeToPseudoWallTime( - pc_->WebRtcTimestampToBlinkTimestamp(web_source->Timestamp())) + time_converter.MonotonicTimeToPseudoWallTime(web_source->Timestamp()) .InMilliseconds()); contributing_source->setSource(web_source->Source()); if (web_source->AudioLevel()) diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h index d737060220d..5316a5100b1 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h @@ -151,7 +151,7 @@ class MODULES_EXPORT RTCRtpReceiverImpl : public RTCRtpReceiverPlatform { }; class MODULES_EXPORT RTCRtpReceiverOnlyTransceiver - : public RTCRtpTransceiverPlatform { + : public RTCRtpPlanBTransceiverPlatform { public: RTCRtpReceiverOnlyTransceiver( std::unique_ptr<RTCRtpReceiverPlatform> receiver); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h index 42ffd6c1ff4..1ec13b811fd 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h @@ -170,7 +170,7 @@ class MODULES_EXPORT RTCRtpSenderImpl : public blink::RTCRtpSenderPlatform { }; class MODULES_EXPORT RTCRtpSenderOnlyTransceiver - : public RTCRtpTransceiverPlatform { + : public RTCRtpPlanBTransceiverPlatform { public: explicit RTCRtpSenderOnlyTransceiver( std::unique_ptr<blink::RTCRtpSenderPlatform> sender); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc index fc46e57ab85..ddc698d1552 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc @@ -4,10 +4,12 @@ #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_header_extension_capability.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h" +#include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -69,6 +71,21 @@ bool TransceiverDirectionFromString( return false; } +bool OptionalTransceiverDirectionFromStringWithStopped( + const String& direction_string, + absl::optional<webrtc::RtpTransceiverDirection>* direction_out) { + if (direction_string == "stopped") { + *direction_out = webrtc::RtpTransceiverDirection::kStopped; + return true; + } + base::Optional<webrtc::RtpTransceiverDirection> base_direction; + bool result = + TransceiverDirectionFromString(direction_string, &base_direction); + if (base_direction) + *direction_out = *base_direction; + return result; +} + } // namespace webrtc::RtpTransceiverInit ToRtpTransceiverInit( @@ -268,6 +285,74 @@ void RTCRtpTransceiver::setCodecPreferences( } } +void RTCRtpTransceiver::setOfferedRtpHeaderExtensions( + const HeapVector<Member<RTCRtpHeaderExtensionCapability>>& + header_extensions_to_offer, + ExceptionState& exception_state) { + Vector<webrtc::RtpHeaderExtensionCapability> webrtc_hdr_exts; + auto webrtc_offered_exts = platform_transceiver_->HeaderExtensionsToOffer(); + int id = 1; + for (const auto& hdr_ext : header_extensions_to_offer) { + // Handle invalid requests for mandatory extensions as per + // https://w3c.github.io/webrtc-extensions/#rtcrtptransceiver-interface + // Step 2.1 (not handled on the WebRTC level). + if (hdr_ext->uri().IsEmpty()) { + exception_state.ThrowTypeError("The extension URL cannot be empty."); + return; + } + + absl::optional<webrtc::RtpTransceiverDirection> direction; + if (!OptionalTransceiverDirectionFromStringWithStopped(hdr_ext->direction(), + &direction) || + !direction) { + exception_state.ThrowTypeError("Invalid RTCRtpTransceiverDirection."); + return; + } + const int id_to_store = direction ? id++ : 0; + webrtc_hdr_exts.emplace_back(hdr_ext->uri().Ascii(), id_to_store, + *direction); + } + webrtc::RTCError status = + platform_transceiver_->SetOfferedRtpHeaderExtensions( + std::move(webrtc_hdr_exts)); + if (status.type() == webrtc::RTCErrorType::UNSUPPORTED_PARAMETER) { + // TODO(crbug.com/1051821): support DOMExceptionCode::kNotSupportedError in + // rtc_error_util.h/cc and get rid of this manually handled case. + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + status.message()); + return; + } else if (status.type() != webrtc::RTCErrorType::NONE) { + ThrowExceptionFromRTCError(status, exception_state); + return; + } +} + +HeapVector<Member<RTCRtpHeaderExtensionCapability>> +RTCRtpTransceiver::headerExtensionsToOffer() const { + auto webrtc_exts = platform_transceiver_->HeaderExtensionsToOffer(); + HeapVector<Member<RTCRtpHeaderExtensionCapability>> exts; + for (const auto& webrtc_ext : webrtc_exts) { + auto* ext = MakeGarbageCollected<RTCRtpHeaderExtensionCapability>(); + ext->setDirection(TransceiverDirectionToString(webrtc_ext.direction)); + ext->setUri(webrtc_ext.uri.c_str()); + exts.push_back(ext); + } + return exts; +} + +HeapVector<Member<RTCRtpHeaderExtensionCapability>> +RTCRtpTransceiver::headerExtensionsNegotiated() const { + auto webrtc_exts = platform_transceiver_->HeaderExtensionsNegotiated(); + HeapVector<Member<RTCRtpHeaderExtensionCapability>> exts; + for (const auto& webrtc_ext : webrtc_exts) { + auto* ext = MakeGarbageCollected<RTCRtpHeaderExtensionCapability>(); + ext->setDirection(TransceiverDirectionToString(webrtc_ext.direction)); + ext->setUri(webrtc_ext.uri.c_str()); + exts.push_back(ext); + } + return exts; +} + void RTCRtpTransceiver::Trace(Visitor* visitor) const { visitor->Trace(pc_); visitor->Trace(sender_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h index ce7a658e6f6..b30e360f41d 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h @@ -22,6 +22,7 @@ namespace blink { class RTCPeerConnection; +class RTCRtpHeaderExtensionCapability; class RTCRtpReceiver; class RTCRtpSender; @@ -68,6 +69,15 @@ class RTCRtpTransceiver final : public ScriptWrappable { bool DirectionHasRecv() const; bool FiredDirectionHasRecv() const; + void setOfferedRtpHeaderExtensions( + const HeapVector<Member<RTCRtpHeaderExtensionCapability>>& + header_extensions_to_offer, + ExceptionState& exception_state); + HeapVector<Member<RTCRtpHeaderExtensionCapability>> headerExtensionsToOffer() + const; + HeapVector<Member<RTCRtpHeaderExtensionCapability>> + headerExtensionsNegotiated() const; + void Trace(Visitor*) const override; private: diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl index d642fd2dd72..f02719c0837 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl @@ -23,4 +23,9 @@ interface RTCRtpTransceiver { readonly attribute RTCRtpTransceiverDirection? currentDirection; [Measure, RuntimeEnabled=RTCRtpTransceiverStop, RaisesException] void stop(); [RaisesException] void setCodecPreferences(sequence<RTCRtpCodecCapability> codecs); + [RaisesException, RuntimeEnabled=RTCRtpHeaderExtensionControl] void setOfferedRtpHeaderExtensions( + sequence<RTCRtpHeaderExtensionCapability> + headerExtensionsToOffer); + [RuntimeEnabled=RTCRtpHeaderExtensionControl] readonly attribute FrozenArray<RTCRtpHeaderExtensionCapability> headerExtensionsToOffer; + [RuntimeEnabled=RTCRtpHeaderExtensionControl] readonly attribute FrozenArray<RTCRtpHeaderExtensionCapability> headerExtensionsNegotiated; }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc index f88d1933307..600c9a265f2 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc @@ -21,7 +21,9 @@ RtpTransceiverState::RtpTransceiverState( bool stopped, webrtc::RtpTransceiverDirection direction, base::Optional<webrtc::RtpTransceiverDirection> current_direction, - base::Optional<webrtc::RtpTransceiverDirection> fired_direction) + base::Optional<webrtc::RtpTransceiverDirection> fired_direction, + WTF::Vector<webrtc::RtpHeaderExtensionCapability> + header_extensions_negotiated) : main_task_runner_(std::move(main_task_runner)), signaling_task_runner_(std::move(signaling_task_runner)), webrtc_transceiver_(std::move(webrtc_transceiver)), @@ -32,7 +34,8 @@ RtpTransceiverState::RtpTransceiverState( stopped_(std::move(stopped)), direction_(std::move(direction)), current_direction_(std::move(current_direction)), - fired_direction_(std::move(fired_direction)) { + fired_direction_(std::move(fired_direction)), + header_extensions_negotiated_(std::move(header_extensions_negotiated)) { DCHECK(main_task_runner_); DCHECK(signaling_task_runner_); DCHECK(webrtc_transceiver_); @@ -49,7 +52,9 @@ RtpTransceiverState::RtpTransceiverState(RtpTransceiverState&& other) stopped_(std::move(other.stopped_)), direction_(std::move(other.direction_)), current_direction_(std::move(other.current_direction_)), - fired_direction_(std::move(other.fired_direction_)) { + fired_direction_(std::move(other.fired_direction_)), + header_extensions_negotiated_( + std::move(other.header_extensions_negotiated_)) { // Explicitly null |other|'s task runners for use in destructor. other.main_task_runner_ = nullptr; other.signaling_task_runner_ = nullptr; @@ -80,6 +85,9 @@ RtpTransceiverState& RtpTransceiverState::operator=( direction_ = std::move(other.direction_); current_direction_ = std::move(other.current_direction_); fired_direction_ = std::move(other.fired_direction_); + header_extensions_negotiated_ = + std::move(other.header_extensions_negotiated_); + return *this; } @@ -178,6 +186,11 @@ RtpTransceiverState::fired_direction() const { return fired_direction_; } +const Vector<webrtc::RtpHeaderExtensionCapability>& +RtpTransceiverState::header_extensions_negotiated() const { + return header_extensions_negotiated_; +} + class RTCRtpTransceiverImpl::RTCRtpTransceiverInternal : public WTF::ThreadSafeRefCounted< RTCRtpTransceiverImpl::RTCRtpTransceiverInternal, @@ -268,6 +281,23 @@ class RTCRtpTransceiverImpl::RTCRtpTransceiverInternal return webrtc_transceiver_->SetCodecPreferences(codec_preferences); } + webrtc::RTCError SetOfferedRtpHeaderExtensions( + std::vector<webrtc::RtpHeaderExtensionCapability> + header_extensions_to_offer) { + return webrtc_transceiver_->SetOfferedRtpHeaderExtensions( + header_extensions_to_offer); + } + + Vector<webrtc::RtpHeaderExtensionCapability> HeaderExtensionsNegotiated() + const { + return state_.header_extensions_negotiated(); + } + + std::vector<webrtc::RtpHeaderExtensionCapability> HeaderExtensionsToOffer() + const { + return webrtc_transceiver_->HeaderExtensionsToOffer(); + } + private: friend class WTF::ThreadSafeRefCounted<RTCRtpTransceiverInternal, RTCRtpTransceiverInternalTraits>; @@ -420,4 +450,28 @@ webrtc::RTCError RTCRtpTransceiverImpl::SetCodecPreferences( std_codec_preferences.begin()); return internal_->setCodecPreferences(std_codec_preferences); } + +webrtc::RTCError RTCRtpTransceiverImpl::SetOfferedRtpHeaderExtensions( + Vector<webrtc::RtpHeaderExtensionCapability> header_extensions_to_offer) { + std::vector<webrtc::RtpHeaderExtensionCapability> std_header_extensions; + std::move(header_extensions_to_offer.begin(), + header_extensions_to_offer.end(), + std::back_inserter(std_header_extensions)); + return internal_->SetOfferedRtpHeaderExtensions(std_header_extensions); +} + +Vector<webrtc::RtpHeaderExtensionCapability> +RTCRtpTransceiverImpl::HeaderExtensionsNegotiated() const { + return internal_->HeaderExtensionsNegotiated(); +} + +Vector<webrtc::RtpHeaderExtensionCapability> +RTCRtpTransceiverImpl::HeaderExtensionsToOffer() const { + auto std_extensions = internal_->HeaderExtensionsToOffer(); + Vector<webrtc::RtpHeaderExtensionCapability> extensions; + std::move(std_extensions.begin(), std_extensions.end(), + std::back_inserter(extensions)); + return extensions; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h index 78f26335752..ef125e171f8 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.h @@ -66,7 +66,9 @@ class MODULES_EXPORT RtpTransceiverState { bool stopped, webrtc::RtpTransceiverDirection direction, base::Optional<webrtc::RtpTransceiverDirection> current_direction, - base::Optional<webrtc::RtpTransceiverDirection> fired_direction); + base::Optional<webrtc::RtpTransceiverDirection> fired_direction, + Vector<webrtc::RtpHeaderExtensionCapability> + header_extensions_negotiated); RtpTransceiverState(RtpTransceiverState&&); RtpTransceiverState(const RtpTransceiverState&) = delete; ~RtpTransceiverState(); @@ -94,6 +96,8 @@ class MODULES_EXPORT RtpTransceiverState { void set_direction(webrtc::RtpTransceiverDirection); base::Optional<webrtc::RtpTransceiverDirection> current_direction() const; base::Optional<webrtc::RtpTransceiverDirection> fired_direction() const; + const Vector<webrtc::RtpHeaderExtensionCapability>& + header_extensions_negotiated() const; private: scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; @@ -107,6 +111,7 @@ class MODULES_EXPORT RtpTransceiverState { webrtc::RtpTransceiverDirection direction_; base::Optional<webrtc::RtpTransceiverDirection> current_direction_; base::Optional<webrtc::RtpTransceiverDirection> fired_direction_; + Vector<webrtc::RtpHeaderExtensionCapability> header_extensions_negotiated_; }; // RTCRtpTransceiverImpl::set_state() performs differently depending on the @@ -185,6 +190,12 @@ class MODULES_EXPORT RTCRtpTransceiverImpl : public RTCRtpTransceiverPlatform { webrtc::RTCError Stop() override; webrtc::RTCError SetCodecPreferences( Vector<webrtc::RtpCodecCapability>) override; + webrtc::RTCError SetOfferedRtpHeaderExtensions( + Vector<webrtc::RtpHeaderExtensionCapability> header_extensions) override; + Vector<webrtc::RtpHeaderExtensionCapability> HeaderExtensionsNegotiated() + const override; + Vector<webrtc::RtpHeaderExtensionCapability> HeaderExtensionsToOffer() + const override; private: class RTCRtpTransceiverInternal; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc index 4b9ac9fc495..f9c39fe1f9b 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc @@ -146,7 +146,7 @@ class RTCRtpTransceiverImplTest : public ::testing::Test { blink::ToBaseOptional(webrtc_transceiver->mid()), webrtc_transceiver->stopped(), webrtc_transceiver->direction(), blink::ToBaseOptional(webrtc_transceiver->current_direction()), - blink::ToBaseOptional(webrtc_transceiver->fired_direction())); + blink::ToBaseOptional(webrtc_transceiver->fired_direction()), {}); } protected: diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc index 28a108e0bb8..23f74767657 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc @@ -35,7 +35,7 @@ ThermalResource::ThermalResource( : task_runner_(std::move(task_runner)) {} void ThermalResource::OnThermalMeasurement( - base::PowerObserver::DeviceThermalState measurement) { + mojom::blink::DeviceThermalState measurement) { base::AutoLock auto_lock(lock_); measurement_ = measurement; ++measurement_id_; @@ -50,8 +50,7 @@ void ThermalResource::SetResourceListener(webrtc::ResourceListener* listener) { base::AutoLock auto_lock(lock_); DCHECK(!listener_ || !listener) << "Must not overwrite existing listener."; listener_ = listener; - if (listener_ && - measurement_ != base::PowerObserver::DeviceThermalState::kUnknown) { + if (listener_ && measurement_ != mojom::blink::DeviceThermalState::kUnknown) { ReportMeasurementWhileHoldingLock(measurement_id_); } } @@ -68,16 +67,16 @@ void ThermalResource::ReportMeasurementWhileHoldingLock(size_t measurement_id) { if (measurement_id != measurement_id_ || !listener_) return; switch (measurement_) { - case base::PowerObserver::DeviceThermalState::kUnknown: + case mojom::blink::DeviceThermalState::kUnknown: // Stop repeating measurements. return; - case base::PowerObserver::DeviceThermalState::kNominal: - case base::PowerObserver::DeviceThermalState::kFair: + case mojom::blink::DeviceThermalState::kNominal: + case mojom::blink::DeviceThermalState::kFair: listener_->OnResourceUsageStateMeasured( this, webrtc::ResourceUsageState::kUnderuse); break; - case base::PowerObserver::DeviceThermalState::kSerious: - case base::PowerObserver::DeviceThermalState::kCritical: + case mojom::blink::DeviceThermalState::kSerious: + case mojom::blink::DeviceThermalState::kCritical: listener_->OnResourceUsageStateMeasured( this, webrtc::ResourceUsageState::kOveruse); break; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h index 281caaf0a3b..0f0d1c89b63 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h @@ -7,10 +7,10 @@ #include "base/feature_list.h" #include "base/memory/scoped_refptr.h" -#include "base/power_monitor/power_observer.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/thread_annotations.h" +#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/webrtc/api/adaptation/resource.h" @@ -46,8 +46,7 @@ class MODULES_EXPORT ThermalResource : public webrtc::Resource { scoped_refptr<base::SequencedTaskRunner> task_runner); ~ThermalResource() override = default; - void OnThermalMeasurement( - base::PowerObserver::DeviceThermalState measurement); + void OnThermalMeasurement(mojom::blink::DeviceThermalState measurement); // webrtc::Resource implementation. std::string Name() const override; @@ -61,8 +60,8 @@ class MODULES_EXPORT ThermalResource : public webrtc::Resource { const scoped_refptr<base::SequencedTaskRunner> task_runner_; base::Lock lock_; webrtc::ResourceListener* listener_ GUARDED_BY(&lock_) = nullptr; - base::PowerObserver::DeviceThermalState measurement_ GUARDED_BY(&lock_) = - base::PowerObserver::DeviceThermalState::kUnknown; + mojom::blink::DeviceThermalState measurement_ GUARDED_BY(&lock_) = + mojom::blink::DeviceThermalState::kUnknown; size_t measurement_id_ GUARDED_BY(&lock_) = 0u; }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc index 628a170c583..4e1dd30825b 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc @@ -50,8 +50,7 @@ TEST_F(ThermalResourceTest, NoMeasurementsByDefault) { TEST_F(ThermalResourceTest, NominalTriggersUnderuse) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kNominal); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kNominal); EXPECT_EQ(1u, listener_.measurement_count()); EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, listener_.latest_measurement()); @@ -59,8 +58,7 @@ TEST_F(ThermalResourceTest, NominalTriggersUnderuse) { TEST_F(ThermalResourceTest, FairTriggersUnderuse) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kFair); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kFair); EXPECT_EQ(1u, listener_.measurement_count()); EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, listener_.latest_measurement()); @@ -68,8 +66,7 @@ TEST_F(ThermalResourceTest, FairTriggersUnderuse) { TEST_F(ThermalResourceTest, SeriousTriggersOveruse) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kSerious); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious); EXPECT_EQ(1u, listener_.measurement_count()); EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, listener_.latest_measurement()); @@ -77,8 +74,7 @@ TEST_F(ThermalResourceTest, SeriousTriggersOveruse) { TEST_F(ThermalResourceTest, CriticalTriggersOveruse) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kCritical); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kCritical); EXPECT_EQ(1u, listener_.measurement_count()); EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, listener_.latest_measurement()); @@ -86,15 +82,13 @@ TEST_F(ThermalResourceTest, CriticalTriggersOveruse) { TEST_F(ThermalResourceTest, UnknownDoesNotTriggerUsage) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kUnknown); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kUnknown); EXPECT_EQ(0u, listener_.measurement_count()); } TEST_F(ThermalResourceTest, MeasurementsRepeatEvery10Seconds) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kSerious); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious); size_t expected_count = listener_.measurement_count(); // First Interval. @@ -130,8 +124,7 @@ TEST_F(ThermalResourceTest, MeasurementsRepeatEvery10Seconds) { TEST_F(ThermalResourceTest, NewMeasurementInvalidatesInFlightRepetition) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kSerious); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious); task_runner_->FastForwardBy( base::TimeDelta::FromMilliseconds(kReportIntervalMs)); @@ -146,8 +139,7 @@ TEST_F(ThermalResourceTest, NewMeasurementInvalidatesInFlightRepetition) { EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, listener_.latest_measurement()); // Trigger kUnderuse. - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kNominal); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kNominal); EXPECT_EQ(3u, listener_.measurement_count()); EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, listener_.latest_measurement()); @@ -169,15 +161,13 @@ TEST_F(ThermalResourceTest, NewMeasurementInvalidatesInFlightRepetition) { TEST_F(ThermalResourceTest, UnknownStopsRepeatedMeasurements) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kSerious); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious); task_runner_->FastForwardBy( base::TimeDelta::FromMilliseconds(kReportIntervalMs)); // The measurement is repeating. EXPECT_EQ(2u, listener_.measurement_count()); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kUnknown); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kUnknown); task_runner_->FastForwardBy( base::TimeDelta::FromMilliseconds(kReportIntervalMs)); // No more measurements. @@ -186,8 +176,7 @@ TEST_F(ThermalResourceTest, UnknownStopsRepeatedMeasurements) { TEST_F(ThermalResourceTest, UnregisteringStopsRepeatedMeasurements) { resource_->SetResourceListener(&listener_); - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kSerious); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious); task_runner_->FastForwardBy( base::TimeDelta::FromMilliseconds(kReportIntervalMs)); // The measurement is repeating. @@ -201,8 +190,7 @@ TEST_F(ThermalResourceTest, UnregisteringStopsRepeatedMeasurements) { } TEST_F(ThermalResourceTest, RegisteringLateTriggersRepeatedMeasurements) { - resource_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kSerious); + resource_->OnThermalMeasurement(mojom::blink::DeviceThermalState::kSerious); task_runner_->FastForwardBy( base::TimeDelta::FromMilliseconds(kReportIntervalMs)); EXPECT_EQ(0u, listener_.measurement_count()); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc index d1e63fac5a5..5bdc0787dd3 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc @@ -10,8 +10,8 @@ #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_macros.h" #include "base/notreached.h" -#include "base/power_monitor/power_observer.h" #include "base/sequenced_task_runner.h" +#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h" namespace blink { @@ -27,16 +27,15 @@ enum class ThermalStateUMA { kMaxValue = kCritical, }; -ThermalStateUMA ToThermalStateUMA( - base::PowerObserver::DeviceThermalState state) { +ThermalStateUMA ToThermalStateUMA(mojom::blink::DeviceThermalState state) { switch (state) { - case base::PowerObserver::DeviceThermalState::kNominal: + case mojom::blink::DeviceThermalState::kNominal: return ThermalStateUMA::kNominal; - case base::PowerObserver::DeviceThermalState::kFair: + case mojom::blink::DeviceThermalState::kFair: return ThermalStateUMA::kFair; - case base::PowerObserver::DeviceThermalState::kSerious: + case mojom::blink::DeviceThermalState::kSerious: return ThermalStateUMA::kSerious; - case base::PowerObserver::DeviceThermalState::kCritical: + case mojom::blink::DeviceThermalState::kCritical: return ThermalStateUMA::kCritical; default: NOTREACHED(); @@ -58,13 +57,13 @@ std::unique_ptr<ThermalUmaListener> ThermalUmaListener::Create( ThermalUmaListener::ThermalUmaListener( scoped_refptr<base::SequencedTaskRunner> task_runner) : task_runner_(std::move(task_runner)), - current_thermal_state_(base::PowerObserver::DeviceThermalState::kUnknown), + current_thermal_state_(mojom::blink::DeviceThermalState::kUnknown), weak_ptr_factor_(this) { DCHECK(task_runner_); } void ThermalUmaListener::OnThermalMeasurement( - base::PowerObserver::DeviceThermalState measurement) { + mojom::blink::DeviceThermalState measurement) { base::AutoLock crit(lock_); current_thermal_state_ = measurement; } @@ -79,8 +78,7 @@ void ThermalUmaListener::ScheduleReport() { void ThermalUmaListener::ReportStats() { { base::AutoLock crit(lock_); - if (current_thermal_state_ != - base::PowerObserver::DeviceThermalState::kUnknown) { + if (current_thermal_state_ != mojom::blink::DeviceThermalState::kUnknown) { UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ThermalState", ToThermalStateUMA(current_thermal_state_)); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h index a4006a304ca..16e9fd6bcbd 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h @@ -10,10 +10,10 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" -#include "base/power_monitor/power_observer.h" #include "base/synchronization/lock.h" #include "base/thread_annotations.h" #include "base/time/time.h" +#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" @@ -29,8 +29,7 @@ class MODULES_EXPORT ThermalUmaListener { scoped_refptr<base::SequencedTaskRunner> task_runner); ~ThermalUmaListener() = default; - void OnThermalMeasurement( - base::PowerObserver::DeviceThermalState measurement); + void OnThermalMeasurement(mojom::blink::DeviceThermalState measurement); private: void ReportStats(); @@ -38,8 +37,7 @@ class MODULES_EXPORT ThermalUmaListener { base::Lock lock_; scoped_refptr<base::SequencedTaskRunner> task_runner_; - base::PowerObserver::DeviceThermalState current_thermal_state_ - GUARDED_BY(&lock_); + mojom::blink::DeviceThermalState current_thermal_state_ GUARDED_BY(&lock_); base::WeakPtrFactory<ThermalUmaListener> weak_ptr_factor_; }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc index 4e3bc30cfb2..aa144e98d3f 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc @@ -4,10 +4,10 @@ #include <memory> -#include "base/power_monitor/power_observer.h" #include "base/test/metrics/histogram_tester.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/peerconnection/peer_connection_tracker.mojom-blink.h" #include "third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" @@ -48,7 +48,7 @@ TEST_F(ThermalUmaListenerTest, NoMeasurementsHasNoHistograms) { TEST_F(ThermalUmaListenerTest, HistogramAfterSignal) { thermal_uma_listener_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kFair); + mojom::blink::DeviceThermalState::kFair); task_runner_->FastForwardBy(kStatsReportingPeriod); EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), @@ -57,7 +57,7 @@ TEST_F(ThermalUmaListenerTest, HistogramAfterSignal) { TEST_F(ThermalUmaListenerTest, DeletionCancelsListener) { thermal_uma_listener_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kFair); + mojom::blink::DeviceThermalState::kFair); task_runner_->FastForwardBy(2 * kStatsReportingPeriod); EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), testing::ElementsAre(Bucket(1, 2))); @@ -70,10 +70,10 @@ TEST_F(ThermalUmaListenerTest, DeletionCancelsListener) { TEST_F(ThermalUmaListenerTest, RecordsMostRecentState) { thermal_uma_listener_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kFair); + mojom::blink::DeviceThermalState::kFair); task_runner_->FastForwardBy(kStatsReportingPeriod / 2); thermal_uma_listener_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kSerious); + mojom::blink::DeviceThermalState::kSerious); task_runner_->FastForwardBy(kStatsReportingPeriod / 2); EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), @@ -82,16 +82,16 @@ TEST_F(ThermalUmaListenerTest, RecordsMostRecentState) { TEST_F(ThermalUmaListenerTest, HistogramBucketsIncludesPreviousPeriod) { thermal_uma_listener_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kNominal); + mojom::blink::DeviceThermalState::kNominal); task_runner_->FastForwardBy(kStatsReportingPeriod); thermal_uma_listener_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kFair); + mojom::blink::DeviceThermalState::kFair); task_runner_->FastForwardBy(kStatsReportingPeriod); thermal_uma_listener_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kSerious); + mojom::blink::DeviceThermalState::kSerious); task_runner_->FastForwardBy(kStatsReportingPeriod); thermal_uma_listener_->OnThermalMeasurement( - base::PowerObserver::DeviceThermalState::kCritical); + mojom::blink::DeviceThermalState::kCritical); task_runner_->FastForwardBy(kStatsReportingPeriod); EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.cc b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.cc index 254aa55d1e7..c139887b67f 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.cc @@ -9,6 +9,18 @@ #include "third_party/webrtc/api/sctp_transport_interface.h" namespace blink { +namespace { + +Vector<webrtc::RtpHeaderExtensionCapability> GetHeaderExtensionsNegotiated( + const webrtc::RtpTransceiverInterface* webrtc_transceiver) { + auto std_extensions = webrtc_transceiver->HeaderExtensionsNegotiated(); + Vector<webrtc::RtpHeaderExtensionCapability> extensions; + std::move(std_extensions.begin(), std_extensions.end(), + std::back_inserter(extensions)); + return extensions; +} + +} // namespace TransceiverStateSurfacer::TransceiverStateSurfacer( scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, @@ -112,14 +124,16 @@ void TransceiverStateSurfacer::Initialize( main_task_runner_, signaling_task_runner_, webrtc_receiver.get(), std::move(receiver_track_ref), std::move(receiver_stream_ids)); } + // Create the transceiver state. - transceiver_states_.push_back(blink::RtpTransceiverState( + transceiver_states_.emplace_back( main_task_runner_, signaling_task_runner_, webrtc_transceiver.get(), std::move(sender_state), std::move(receiver_state), blink::ToBaseOptional(webrtc_transceiver->mid()), webrtc_transceiver->stopped(), webrtc_transceiver->direction(), blink::ToBaseOptional(webrtc_transceiver->current_direction()), - blink::ToBaseOptional(webrtc_transceiver->fired_direction()))); + blink::ToBaseOptional(webrtc_transceiver->fired_direction()), + GetHeaderExtensionsNegotiated(webrtc_transceiver)); } is_initialized_ = true; } @@ -147,7 +161,7 @@ SurfaceSenderStateOnly::SurfaceSenderStateOnly( DCHECK(sender_); } -SurfaceSenderStateOnly::~SurfaceSenderStateOnly() {} +SurfaceSenderStateOnly::~SurfaceSenderStateOnly() = default; cricket::MediaType SurfaceSenderStateOnly::media_type() const { return sender_->media_type(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h index 5ffde75e8be..0300f2cd57c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h @@ -51,7 +51,7 @@ class MODULES_EXPORT TransceiverStateSurfacer { blink::WebRTCSctpTransportSnapshot SctpTransportSnapshot(); std::vector<blink::RtpTransceiverState> ObtainStates(); - protected: + private: scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; bool is_initialized_; @@ -66,7 +66,8 @@ class MODULES_EXPORT TransceiverStateSurfacer { class MODULES_EXPORT SurfaceSenderStateOnly : public rtc::RefCountedObject<webrtc::RtpTransceiverInterface> { public: - SurfaceSenderStateOnly(rtc::scoped_refptr<webrtc::RtpSenderInterface> sender); + explicit SurfaceSenderStateOnly( + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender); ~SurfaceSenderStateOnly() override; cricket::MediaType media_type() const override; @@ -90,7 +91,7 @@ class MODULES_EXPORT SurfaceSenderStateOnly class MODULES_EXPORT SurfaceReceiverStateOnly : public rtc::RefCountedObject<webrtc::RtpTransceiverInterface> { public: - SurfaceReceiverStateOnly( + explicit SurfaceReceiverStateOnly( rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver); ~SurfaceReceiverStateOnly() override; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc index adc1f716281..3fa8c413ea6 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc @@ -50,8 +50,10 @@ class TransceiverStateSurfacerTest : public ::testing::Test { dependency_factory_.get(), main_task_runner_); surfacer_.reset(new TransceiverStateSurfacer(main_task_runner_, signaling_task_runner())); + DummyExceptionStateForTesting exception_state; peer_connection_ = dependency_factory_->CreatePeerConnection( - webrtc::PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr); + webrtc::PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr, + exception_state); EXPECT_CALL( *(static_cast<blink::MockPeerConnectionImpl*>(peer_connection_.get())), GetSctpTransport()) diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc index 319046e8da5..38da10aced9 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_audio_renderer_test.cc @@ -17,6 +17,7 @@ #include "media/base/mock_audio_renderer_sink.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/platform/audio/web_audio_device_source_type.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_renderer.h" #include "third_party/blink/public/platform/platform.h" @@ -34,6 +35,7 @@ #include "third_party/webrtc/api/media_stream_interface.h" using testing::_; +using testing::DoAll; using testing::InvokeWithoutArgs; using testing::Return; using testing::SaveArg; @@ -144,12 +146,12 @@ class MAYBE_WebRtcAudioRendererTest : public testing::Test { /*opener=*/nullptr, mojo::NullAssociatedReceiver(), *agent_group_scheduler_)), - web_local_frame_(blink::WebLocalFrame::CreateMainFrame( - web_view_, - &web_local_frame_client_, - nullptr, - base::UnguessableToken::Create(), - /*policy_container=*/nullptr)) + web_local_frame_( + blink::WebLocalFrame::CreateMainFrame(web_view_, + &web_local_frame_client_, + nullptr, + LocalFrameToken(), + /*policy_container=*/nullptr)) #endif { MediaStreamSourceVector dummy_components; @@ -207,6 +209,7 @@ class MAYBE_WebRtcAudioRendererTest : public testing::Test { } void TearDown() override { + base::RunLoop().RunUntilIdle(); renderer_proxy_ = nullptr; renderer_ = nullptr; stream_descriptor_ = nullptr; @@ -231,7 +234,7 @@ class MAYBE_WebRtcAudioRendererTest : public testing::Test { }; // Verify that the renderer will be stopped if the only proxy is stopped. -TEST_F(MAYBE_WebRtcAudioRendererTest, StopRenderer) { +TEST_F(MAYBE_WebRtcAudioRendererTest, DISABLED_StopRenderer) { SetupRenderer(kDefaultOutputDeviceId); renderer_proxy_->Start(); @@ -244,7 +247,7 @@ TEST_F(MAYBE_WebRtcAudioRendererTest, StopRenderer) { // Verify that the renderer will not be stopped unless the last proxy is // stopped. -TEST_F(MAYBE_WebRtcAudioRendererTest, MultipleRenderers) { +TEST_F(MAYBE_WebRtcAudioRendererTest, DISABLED_MultipleRenderers) { SetupRenderer(kDefaultOutputDeviceId); renderer_proxy_->Start(); @@ -278,7 +281,7 @@ TEST_F(MAYBE_WebRtcAudioRendererTest, MultipleRenderers) { // Verify that the sink of the renderer is using the expected sample rate and // buffer size. -TEST_F(MAYBE_WebRtcAudioRendererTest, VerifySinkParameters) { +TEST_F(MAYBE_WebRtcAudioRendererTest, DISABLED_VerifySinkParameters) { SetupRenderer(kDefaultOutputDeviceId); renderer_proxy_->Start(); #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \ diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer.cc index 77f65fb2915..99819240484 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_set_description_observer.cc @@ -13,10 +13,7 @@ std::unique_ptr<webrtc::SessionDescriptionInterface> CopySessionDescription( const webrtc::SessionDescriptionInterface* description) { if (!description) return nullptr; - std::string sdp; - description->ToString(&sdp); - return std::unique_ptr<webrtc::SessionDescriptionInterface>( - webrtc::CreateSessionDescription(description->type(), sdp, nullptr)); + return description->Clone(); } WebRtcSetDescriptionObserver::States::States() |