diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc | 533 |
1 files changed, 315 insertions, 218 deletions
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 6a70d3ba1f3..35aa9094e41 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 @@ -52,9 +52,16 @@ #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_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" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_callback.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_stats_callback.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -62,7 +69,7 @@ #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/deprecation.h" -#include "third_party/blink/renderer/core/frame/hosts_using_features.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/modules/crypto/crypto_result_impl.h" @@ -71,28 +78,21 @@ #include "third_party/blink/renderer/modules/mediastream/media_stream_event.h" #include "third_party/blink/renderer/modules/mediastream/user_media_controller.h" #include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_answer_options.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_configuration.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel_init.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_server.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_offer_options.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.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/modules/peerconnection/rtc_rtp_transceiver.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_init.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_session_description.h" -#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_init.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h" @@ -121,7 +121,6 @@ #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/webrtc/api/data_channel_interface.h" - #include "third_party/webrtc/api/dtls_transport_interface.h" #include "third_party/webrtc/api/jsep.h" #include "third_party/webrtc/api/peer_connection_interface.h" @@ -213,7 +212,7 @@ RTCAnswerOptionsPlatform* ConvertToRTCAnswerOptionsPlatform( : true); } -scoped_refptr<RTCIceCandidatePlatform> ConvertToRTCIceCandidatePlatform( +RTCIceCandidatePlatform* ConvertToRTCIceCandidatePlatform( ExecutionContext* context, const RTCIceCandidateInitOrRTCIceCandidate& candidate) { DCHECK(!candidate.IsNull()); @@ -228,7 +227,7 @@ scoped_refptr<RTCIceCandidatePlatform> ConvertToRTCIceCandidatePlatform( UseCounter::Count(context, WebFeature::kRTCIceCandidateDefaultSdpMLineIndex); } - return RTCIceCandidatePlatform::Create( + return MakeGarbageCollected<RTCIceCandidatePlatform>( ice_candidate_init->candidate(), ice_candidate_init->sdpMid(), sdp_m_line_index, ice_candidate_init->usernameFragment()); } @@ -354,7 +353,7 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration( WebVector<webrtc::PeerConnectionInterface::IceServer> ice_servers; for (const RTCIceServer* ice_server : configuration->iceServers()) { Vector<String> url_strings; - if (ice_server->hasURLs()) { + if (ice_server->hasUrls()) { UseCounter::Count(context, WebFeature::kRTCIceServerURLs); const StringOrStringSequence& urls = ice_server->urls(); if (urls.IsString()) { @@ -363,7 +362,7 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration( DCHECK(urls.IsStringSequence()); url_strings = urls.GetAsStringSequence(); } - } else if (ice_server->hasURL()) { + } else if (ice_server->hasUrl()) { UseCounter::Count(context, WebFeature::kRTCIceServerURL); url_strings.push_back(ice_server->url()); } else { @@ -526,6 +525,11 @@ bool FingerprintMismatch(String old_sdp, String new_sdp) { new_fingerprint_end - new_fingerprint_pos); } +bool ContainsLegacySimulcast(String sdp) { + // Looks for the non-spec simulcast that іs enabled via SDP munging. + return sdp.Find("\na=ssrc-group:SIM") != kNotFound; +} + enum class SdpFormat { kSimple, kComplexPlanB, @@ -628,7 +632,7 @@ bool RTCPeerConnection::EventWrapper::Setup() { return true; } -void RTCPeerConnection::EventWrapper::Trace(blink::Visitor* visitor) { +void RTCPeerConnection::EventWrapper::Trace(Visitor* visitor) { visitor->Trace(event_); } @@ -637,14 +641,19 @@ RTCPeerConnection* RTCPeerConnection::Create( const RTCConfiguration* rtc_configuration, const Dictionary& media_constraints, ExceptionState& exception_state) { + if (context->IsContextDestroyed()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "PeerConnections may not be created in detached documents."); + return nullptr; + } + // Count number of PeerConnections that could potentially be impacted by CSP - if (context) { - auto& security_context = context->GetSecurityContext(); - auto* content_security_policy = security_context.GetContentSecurityPolicy(); - if (content_security_policy && - content_security_policy->IsActiveForConnections()) { - UseCounter::Count(context, WebFeature::kRTCPeerConnectionWithActiveCsp); - } + auto& security_context = context->GetSecurityContext(); + auto* content_security_policy = security_context.GetContentSecurityPolicy(); + if (content_security_policy && + content_security_policy->IsActiveForConnections()) { + UseCounter::Count(context, WebFeature::kRTCPeerConnectionWithActiveCsp); } if (media_constraints.IsObject()) { @@ -676,7 +685,7 @@ RTCPeerConnection* RTCPeerConnection::Create( } MediaErrorState media_error_state; - WebMediaConstraints constraints = media_constraints_impl::Create( + MediaConstraints constraints = media_constraints_impl::Create( context, media_constraints, media_error_state); if (media_error_state.HadException()) { media_error_state.RaiseException(exception_state); @@ -685,7 +694,9 @@ RTCPeerConnection* RTCPeerConnection::Create( RTCPeerConnection* peer_connection = MakeGarbageCollected<RTCPeerConnection>( context, std::move(configuration), rtc_configuration->hasSdpSemantics(), - constraints, exception_state); + rtc_configuration->forceEncodedAudioInsertableStreams(), + rtc_configuration->forceEncodedVideoInsertableStreams(), constraints, + exception_state); if (exception_state.HadException()) return nullptr; @@ -699,13 +710,36 @@ RTCPeerConnection* RTCPeerConnection::Create( return peer_connection; } +RTCPeerConnection* RTCPeerConnection::Create( + ExecutionContext* context, + const RTCConfiguration* rtc_configuration, + const ScriptValue& media_constraints_value, + ExceptionState& exception_state) { + Dictionary media_constraints(context->GetIsolate(), + media_constraints_value.V8Value(), + exception_state); + if (exception_state.HadException()) + return nullptr; + + return Create(context, rtc_configuration, media_constraints, exception_state); +} + +RTCPeerConnection* RTCPeerConnection::Create( + ExecutionContext* context, + const RTCConfiguration* rtc_configuration, + ExceptionState& exception_state) { + return Create(context, rtc_configuration, Dictionary(), exception_state); +} + RTCPeerConnection::RTCPeerConnection( ExecutionContext* context, webrtc::PeerConnectionInterface::RTCConfiguration configuration, bool sdp_semantics_specified, - WebMediaConstraints constraints, + bool force_encoded_audio_insertable_streams, + bool force_encoded_video_insertable_streams, + MediaConstraints constraints, ExceptionState& exception_state) - : ContextLifecycleObserver(context), + : ExecutionContextLifecycleObserver(context), signaling_state_( webrtc::PeerConnectionInterface::SignalingState::kStable), ice_gathering_state_(webrtc::PeerConnectionInterface::kIceGatheringNew), @@ -720,8 +754,12 @@ RTCPeerConnection::RTCPeerConnection( sdp_semantics_specified_(sdp_semantics_specified), blink_webrtc_time_diff_( base::TimeTicks::Now() - base::TimeTicks() - - base::TimeDelta::FromMicroseconds(rtc::TimeMicros())) { - Document* document = To<Document>(GetExecutionContext()); + base::TimeDelta::FromMicroseconds(rtc::TimeMicros())), + force_encoded_audio_insertable_streams_( + force_encoded_audio_insertable_streams), + force_encoded_video_insertable_streams_( + force_encoded_video_insertable_streams) { + LocalDOMWindow* window = To<LocalDOMWindow>(context); InstanceCounters::IncrementCounter( InstanceCounters::kRTCPeerConnectionCounter); @@ -735,14 +773,6 @@ RTCPeerConnection::RTCPeerConnection( "Cannot create so many PeerConnections"); return; } - if (!document->GetFrame()) { - closed_ = true; - stopped_ = true; - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "PeerConnections may not be created in detached documents."); - return; - } // Tests might need a custom RtcPeerConnectionHandler implementation. if (!g_create_rpc_peer_connection_handler_callback_.Get().is_null()) { @@ -752,7 +782,9 @@ RTCPeerConnection::RTCPeerConnection( peer_handler_ = PeerConnectionDependencyFactory::GetInstance() ->CreateRTCPeerConnectionHandler( - this, document->GetTaskRunner(TaskType::kInternalMedia)); + this, window->GetTaskRunner(TaskType::kInternalMedia), + force_encoded_audio_insertable_streams_, + force_encoded_video_insertable_streams_); } if (!peer_handler_) { @@ -764,14 +796,9 @@ RTCPeerConnection::RTCPeerConnection( return; } - // TODO(crbug.com/787254): Can the frame be associated when - // calling RtcPeerConnectionHandler::Initialize()? - auto* web_local_frame = - static_cast<WebLocalFrame*>(WebFrame::FromFrame(document->GetFrame())); - if (web_local_frame) - peer_handler_->AssociateWithFrame(web_local_frame); - - if (!peer_handler_->Initialize(configuration, constraints)) { + auto* web_frame = + static_cast<WebLocalFrame*>(WebFrame::FromFrame(window->GetFrame())); + if (!peer_handler_->Initialize(configuration, constraints, web_frame)) { closed_ = true; stopped_ = true; exception_state.ThrowDOMException( @@ -781,7 +808,7 @@ RTCPeerConnection::RTCPeerConnection( } feature_handle_for_scheduler_ = - document->GetFrame()->GetFrameScheduler()->RegisterFeature( + window->GetFrame()->GetFrameScheduler()->RegisterFeature( SchedulingPolicy::Feature::kWebRTC, {SchedulingPolicy::DisableAggressiveThrottling(), SchedulingPolicy::RecordMetricsForBackForwardCache()}); @@ -800,45 +827,21 @@ RTCPeerConnection::~RTCPeerConnection() { } void RTCPeerConnection::Dispose() { - // Promptly clears a raw reference from content/ to an on-heap object + // Promptly clears the handler's pointer to |this| // so that content/ doesn't access it in a lazy sweeping phase. - peer_handler_.reset(); - - // UMA for CallSetupStates. This metric is reported regardless of whether or - // not getUserMedia() has been called in this document. - UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CallSetupState.OffererState", - call_setup_state_tracker_.offerer_state()); - UMA_HISTOGRAM_ENUMERATION( - "WebRTC.PeerConnection.CallSetupState.AnswererState", - call_setup_state_tracker_.answerer_state()); - UMA_HISTOGRAM_ENUMERATION( - "WebRTC.PeerConnection.CallSetupState.CallSetupState", - call_setup_state_tracker_.GetCallSetupState()); - // UMA for CallSetupStates only for documents that have performed - // getUserMedia(). This heuristic hints that the peer connection is likely - // used in a media/conferencing context, which is a use case that may be - // particularly sensitive to the Plan B vs Unified Plan switch. - if (call_setup_state_tracker_.document_uses_media()) { - UMA_HISTOGRAM_ENUMERATION( - "WebRTC.PeerConnection.CallSetupStateWithGum.OffererState", - call_setup_state_tracker_.offerer_state()); - UMA_HISTOGRAM_ENUMERATION( - "WebRTC.PeerConnection.CallSetupStateWithGum.AnswererState", - call_setup_state_tracker_.answerer_state()); - UMA_HISTOGRAM_ENUMERATION( - "WebRTC.PeerConnection.CallSetupStateWithGum.CallSetupState", - call_setup_state_tracker_.GetCallSetupState()); + if (peer_handler_) { + peer_handler_->StopAndUnregister(); } } ScriptPromise RTCPeerConnection::createOffer(ScriptState* script_state, - const RTCOfferOptions* options) { + const RTCOfferOptions* options, + ExceptionState& exception_state) { if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError, - kSignalingStateClosedMessage)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kSignalingStateClosedMessage); + return ScriptPromise(); } call_setup_state_tracker_.NoteOffererStateEvent( OffererState::kCreateOfferPending, HasDocumentMedia()); @@ -865,6 +868,31 @@ ScriptPromise RTCPeerConnection::createOffer( ScriptState* script_state, V8RTCSessionDescriptionCallback* success_callback, V8RTCPeerConnectionErrorCallback* error_callback, + const ScriptValue& rtc_offer_options_value, + ExceptionState& exception_state) { + Dictionary rtc_offer_options(script_state->GetIsolate(), + rtc_offer_options_value.V8Value(), + exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + return CreateOffer(script_state, success_callback, error_callback, + rtc_offer_options, exception_state); +} + +ScriptPromise RTCPeerConnection::createOffer( + ScriptState* script_state, + V8RTCSessionDescriptionCallback* success_callback, + V8RTCPeerConnectionErrorCallback* error_callback, + ExceptionState& exception_state) { + return CreateOffer(script_state, success_callback, error_callback, + Dictionary(), exception_state); +} + +ScriptPromise RTCPeerConnection::CreateOffer( + ScriptState* script_state, + V8RTCSessionDescriptionCallback* success_callback, + V8RTCPeerConnectionErrorCallback* error_callback, const Dictionary& rtc_offer_options, ExceptionState& exception_state) { DCHECK(success_callback); @@ -887,7 +915,7 @@ ScriptPromise RTCPeerConnection::createOffer( RTCCreateSessionDescriptionOperation::kCreateOffer, this, success_callback, error_callback); - WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers; + Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers; if (offer_options) { if (offer_options->OfferToReceiveAudio() != -1 || offer_options->OfferToReceiveVideo() != -1) { @@ -901,7 +929,7 @@ ScriptPromise RTCPeerConnection::createOffer( platform_transceivers = peer_handler_->CreateOffer(request, offer_options); } else { MediaErrorState media_error_state; - WebMediaConstraints constraints = media_constraints_impl::Create( + MediaConstraints constraints = media_constraints_impl::Create( context, rtc_offer_options, media_error_state); // Report constraints parsing errors via the callback, but ignore // unknown/unsupported constraints as they would be silently discarded by @@ -931,13 +959,13 @@ ScriptPromise RTCPeerConnection::createOffer( } ScriptPromise RTCPeerConnection::createAnswer(ScriptState* script_state, - const RTCAnswerOptions* options) { + const RTCAnswerOptions* options, + ExceptionState& exception_state) { if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError, - kSignalingStateClosedMessage)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kSignalingStateClosedMessage); + return ScriptPromise(); } call_setup_state_tracker_.NoteAnswererStateEvent( @@ -957,6 +985,30 @@ ScriptPromise RTCPeerConnection::createAnswer( ScriptState* script_state, V8RTCSessionDescriptionCallback* success_callback, V8RTCPeerConnectionErrorCallback* error_callback, + const ScriptValue& media_constraints_value, + ExceptionState& exception_state) { + Dictionary media_constraints(script_state->GetIsolate(), + media_constraints_value.V8Value(), + exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + return CreateAnswer(script_state, success_callback, error_callback, + media_constraints); +} + +ScriptPromise RTCPeerConnection::createAnswer( + ScriptState* script_state, + V8RTCSessionDescriptionCallback* success_callback, + V8RTCPeerConnectionErrorCallback* error_callback, + ExceptionState&) { + return CreateAnswer(script_state, success_callback, error_callback, + Dictionary()); +} + +ScriptPromise RTCPeerConnection::CreateAnswer( + ScriptState* script_state, + V8RTCSessionDescriptionCallback* success_callback, + V8RTCPeerConnectionErrorCallback* error_callback, const Dictionary& media_constraints) { DCHECK(success_callback); DCHECK(error_callback); @@ -975,7 +1027,7 @@ ScriptPromise RTCPeerConnection::createAnswer( return ScriptPromise::CastUndefined(script_state); MediaErrorState media_error_state; - WebMediaConstraints constraints = media_constraints_impl::Create( + MediaConstraints constraints = media_constraints_impl::Create( context, media_constraints, media_error_state); // Report constraints parsing errors via the callback, but ignore // unknown/unsupported constraints as they would be silently discarded by @@ -1019,6 +1071,10 @@ DOMException* RTCPeerConnection::checkSdpForStateErrors( DOMExceptionCode::kInvalidModificationError, kModifiedSdpMessage); } else { UseCounter::Count(context, WebFeature::kRTCLocalSdpModification); + if (ContainsLegacySimulcast(*sdp)) { + UseCounter::Count(context, + WebFeature::kRTCLocalSdpModificationSimulcast); + } return nullptr; // TODO(https://crbug.com/823036): Return failure for all modification. } @@ -1033,6 +1089,10 @@ DOMException* RTCPeerConnection::checkSdpForStateErrors( DOMExceptionCode::kInvalidModificationError, kModifiedSdpMessage); } else { UseCounter::Count(context, WebFeature::kRTCLocalSdpModification); + if (ContainsLegacySimulcast(*sdp)) { + UseCounter::Count(context, + WebFeature::kRTCLocalSdpModificationSimulcast); + } return nullptr; // TODO(https://crbug.com/823036): Return failure for all modification. } @@ -1072,12 +1132,12 @@ void RTCPeerConnection::MaybeWarnAboutUnsafeSdp( const RTCSessionDescriptionInit* session_description_init) const { base::Optional<ComplexSdpCategory> complex_sdp_category = CheckForComplexSdp(session_description_init); - if (!complex_sdp_category) + if (!complex_sdp_category || !GetExecutionContext()) return; - Document* document = To<Document>(GetExecutionContext()); - RTCPeerConnectionController::From(*document).MaybeReportComplexSdp( - *complex_sdp_category); + LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext()); + RTCPeerConnectionController::From(*window->document()) + .MaybeReportComplexSdp(*complex_sdp_category); if (*complex_sdp_category == ComplexSdpCategory::kPlanBImplicitSemantics) { Deprecation::CountDeprecation( @@ -1211,8 +1271,10 @@ void RTCPeerConnection::GenerateCertificateCompleted( } bool RTCPeerConnection::HasDocumentMedia() const { + if (!GetExecutionContext()) + return false; UserMediaController* user_media_controller = UserMediaController::From( - To<Document>(GetExecutionContext())->GetFrame()); + To<LocalDOMWindow>(GetExecutionContext())->GetFrame()); return user_media_controller && user_media_controller->HasRequestedUserMedia(); } @@ -1222,7 +1284,7 @@ void RTCPeerConnection::UpdateIceConnectionState() { auto new_state = ComputeIceConnectionState(); if (ice_connection_state_ != new_state) { peer_handler_->TrackIceConnectionStateChange( - WebRTCPeerConnectionHandler::IceConnectionStateVersion::kDefault, + RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion::kDefault, new_state); } ChangeIceConnectionState(new_state); @@ -1273,7 +1335,8 @@ ScriptPromise RTCPeerConnection::setLocalDescription( ScriptPromise RTCPeerConnection::setLocalDescription( ScriptState* script_state, - const RTCSessionDescriptionInit* session_description_init) { + const RTCSessionDescriptionInit* session_description_init, + ExceptionState& exception_state) { if (session_description_init->type().IsNull() && session_description_init->sdp().IsNull()) { return setLocalDescription(script_state); @@ -1287,7 +1350,10 @@ ScriptPromise RTCPeerConnection::setLocalDescription( DOMException* exception = checkSdpForStateErrors( ExecutionContext::From(script_state), session_description_init, &sdp); if (exception) { - return ScriptPromise::RejectWithDOMException(script_state, exception); + exception_state.ThrowDOMException( + static_cast<DOMExceptionCode>(exception->code()), + exception->message()); + return ScriptPromise(); } } NoteCallSetupStateEventPending(SetSdpOperationType::kSetLocalDescription, @@ -1381,7 +1447,8 @@ RTCSessionDescription* RTCPeerConnection::pendingLocalDescription() { ScriptPromise RTCPeerConnection::setRemoteDescription( ScriptState* script_state, - const RTCSessionDescriptionInit* session_description_init) { + const RTCSessionDescriptionInit* session_description_init, + ExceptionState& exception_state) { if (session_description_init->type() != "rollback") { MaybeWarnAboutUnsafeSdp(session_description_init); ReportSetSdpUsage(SetSdpOperationType::kSetRemoteDescription, @@ -1389,10 +1456,9 @@ ScriptPromise RTCPeerConnection::setRemoteDescription( } if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError, - kSignalingStateClosedMessage)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kSignalingStateClosedMessage); + return ScriptPromise(); } NoteCallSetupStateEventPending(SetSdpOperationType::kSetRemoteDescription, @@ -1547,7 +1613,7 @@ RTCConfiguration* RTCPeerConnection::getConfiguration( } urls.SetStringSequence(std::move(url_vector)); - ice_server->setURLs(urls); + ice_server->setUrls(urls); ice_server->setUsername(webrtc_server.username.c_str()); ice_server->setCredential(webrtc_server.password.c_str()); ice_servers.push_back(ice_server); @@ -1627,23 +1693,28 @@ ScriptPromise RTCPeerConnection::generateCertificate( // Normalize |keygenAlgorithm| with WebCrypto, making sure it is a recognized // AlgorithmIdentifier. WebCryptoAlgorithm crypto_algorithm; - AlgorithmError error; - if (!NormalizeAlgorithm(keygen_algorithm, kWebCryptoOperationGenerateKey, - crypto_algorithm, &error)) { - // Reject generateCertificate with the same error as was produced by - // WebCrypto. |result| is garbage collected, no need to delete. - auto* result = MakeGarbageCollected<CryptoResultImpl>(script_state); - ScriptPromise promise = result->Promise(); - result->CompleteWithError(error.error_type, error.error_details); - return promise; + if (!NormalizeAlgorithm(script_state->GetIsolate(), keygen_algorithm, + kWebCryptoOperationGenerateKey, crypto_algorithm, + exception_state)) { + return ScriptPromise(); } // Check if |keygenAlgorithm| contains the optional DOMTimeStamp |expires| // attribute. base::Optional<DOMTimeStamp> expires; - if (keygen_algorithm.IsDictionary()) { - Dictionary keygen_algorithm_dict = keygen_algorithm.GetAsDictionary(); - if (keygen_algorithm_dict.HasProperty("expires", exception_state)) { + if (keygen_algorithm.IsObject()) { + Dictionary keygen_algorithm_dict(script_state->GetIsolate(), + keygen_algorithm.GetAsObject().V8Value(), + exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + bool has_expires = + keygen_algorithm_dict.HasProperty("expires", exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + if (has_expires) { v8::Local<v8::Value> expires_value; keygen_algorithm_dict.Get("expires", expires_value); if (expires_value->IsNumber()) { @@ -1658,9 +1729,6 @@ ScriptPromise RTCPeerConnection::generateCertificate( } } } - if (exception_state.HadException()) { - return ScriptPromise(); - } // Convert from WebCrypto representation to recognized WebRTCKeyParams. WebRTC // supports a small subset of what are valid AlgorithmIdentifiers. @@ -1682,10 +1750,9 @@ ScriptPromise RTCPeerConnection::generateCertificate( crypto_algorithm.RsaHashedKeyGenParams()->ModulusLengthBits(); key_params = rtc::KeyParams::RSA(modulus_length, public_exponent); } else { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError, - unsupported_params_string)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + unsupported_params_string); + return ScriptPromise(); } break; case kWebCryptoAlgorithmIdEcdsa: @@ -1695,19 +1762,17 @@ ScriptPromise RTCPeerConnection::generateCertificate( kWebCryptoNamedCurveP256) { key_params = rtc::KeyParams::ECDSA(rtc::EC_NIST_P256); } else { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError, - unsupported_params_string)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + unsupported_params_string); + return ScriptPromise(); } break; default: - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError, - "The 1st argument provided is an " - "AlgorithmIdentifier, but the " - "algorithm is not supported.")); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + "The 1st argument provided is an " + "AlgorithmIdentifier, but the " + "algorithm is not supported."); + return ScriptPromise(); break; } DCHECK(key_params.has_value()); @@ -1717,10 +1782,9 @@ ScriptPromise RTCPeerConnection::generateCertificate( // |keyParams| was successfully constructed, but does the certificate // generator support these parameters? if (!certificate_generator->IsSupportedKeyParams(key_params.value())) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - unsupported_params_string)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + unsupported_params_string); + return ScriptPromise(); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -1755,10 +1819,9 @@ ScriptPromise RTCPeerConnection::addIceCandidate( ExceptionState& exception_state) { if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError, - kSignalingStateClosedMessage)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kSignalingStateClosedMessage); + return ScriptPromise(); } if (IsIceCandidateMissingSdp(candidate)) { @@ -1767,7 +1830,7 @@ ScriptPromise RTCPeerConnection::addIceCandidate( return ScriptPromise(); } - scoped_refptr<RTCIceCandidatePlatform> platform_candidate = + RTCIceCandidatePlatform* platform_candidate = ConvertToRTCIceCandidatePlatform(ExecutionContext::From(script_state), candidate); @@ -1804,7 +1867,7 @@ ScriptPromise RTCPeerConnection::addIceCandidate( return ScriptPromise(); } - scoped_refptr<RTCIceCandidatePlatform> platform_candidate = + RTCIceCandidatePlatform* platform_candidate = ConvertToRTCIceCandidatePlatform(ExecutionContext::From(script_state), candidate); @@ -1905,6 +1968,29 @@ String RTCPeerConnection::connectionState() const { return String(); } +base::Optional<bool> RTCPeerConnection::canTrickleIceCandidates() const { + if (closed_ || !peer_handler_->RemoteDescription()) { + return base::nullopt; + } + webrtc::PeerConnectionInterface* native_connection = + peer_handler_->NativePeerConnection(); + if (!native_connection) { + return base::nullopt; + } + absl::optional<bool> can_trickle = + native_connection->can_trickle_ice_candidates(); + if (!can_trickle) { + return base::nullopt; + } + return *can_trickle; +} + +bool RTCPeerConnection::canTrickleIceCandidates(bool& is_null) const { + base::Optional<bool> result = canTrickleIceCandidates(); + is_null = !result; + return result.value_or(false); +} + void RTCPeerConnection::restartIce() { if (closed_) return; @@ -1913,13 +1999,31 @@ void RTCPeerConnection::restartIce() { void RTCPeerConnection::addStream(ScriptState* script_state, MediaStream* stream, + const ScriptValue& media_constraints_value, + ExceptionState& exception_state) { + Dictionary media_constraints(script_state->GetIsolate(), + media_constraints_value.V8Value(), + exception_state); + if (exception_state.HadException()) + return; + AddStream(script_state, stream, media_constraints, exception_state); +} + +void RTCPeerConnection::addStream(ScriptState* script_state, + MediaStream* stream, + ExceptionState& exception_state) { + AddStream(script_state, stream, Dictionary(), exception_state); +} + +void RTCPeerConnection::AddStream(ScriptState* script_state, + MediaStream* stream, const Dictionary& media_constraints, ExceptionState& exception_state) { if (ThrowExceptionIfSignalingStateClosed(signaling_state_, &exception_state)) return; if (!media_constraints.IsUndefinedOrNull()) { MediaErrorState media_error_state; - WebMediaConstraints constraints = + MediaConstraints constraints = media_constraints_impl::Create(ExecutionContext::From(script_state), media_constraints, media_error_state); if (media_error_state.HadException()) { @@ -1999,10 +2103,10 @@ MediaStreamVector RTCPeerConnection::getRemoteStreams() const { return remote_streams; } -MediaStream* RTCPeerConnection::getRemoteStreamById(const WebString& id) const { +MediaStream* RTCPeerConnection::getRemoteStreamById(const String& id) const { for (const auto& rtp_receiver : rtp_receivers_) { for (const auto& stream : rtp_receiver->streams()) { - if (static_cast<WebString>(stream->id()) == id) { + if (stream->id() == id) { return stream; } } @@ -2060,12 +2164,12 @@ ScriptPromise RTCPeerConnection::getStats(ScriptState* script_state, // "getStats(optional MediaStreamTrack? selector)". null is a valid selector // value, but a value of the wrong type isn't. if (first_argument->IsNullOrUndefined()) - return PromiseBasedGetStats(script_state, nullptr); + return PromiseBasedGetStats(script_state, nullptr, exception_state); MediaStreamTrack* track = V8MediaStreamTrack::ToImplWithTypeCheck(isolate, first_argument); if (track) - return PromiseBasedGetStats(script_state, track); + return PromiseBasedGetStats(script_state, track, exception_state); exception_state.ThrowTypeError( "The argument provided as parameter 1 is neither a callback (function) " @@ -2094,17 +2198,17 @@ ScriptPromise RTCPeerConnection::LegacyCallbackBasedGetStats( ScriptPromise RTCPeerConnection::PromiseBasedGetStats( ScriptState* script_state, - MediaStreamTrack* selector) { + MediaStreamTrack* selector, + ExceptionState& exception_state) { if (!selector) { ExecutionContext* context = ExecutionContext::From(script_state); UseCounter::Count(context, WebFeature::kRTCPeerConnectionGetStats); if (!peer_handler_) { LOG(ERROR) << "Internal error: peer_handler_ has been discarded"; - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kOperationError, - "Internal error: release in progress")); + exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, + "Internal error: release in progress"); + return ScriptPromise(); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); @@ -2132,17 +2236,16 @@ ScriptPromise RTCPeerConnection::PromiseBasedGetStats( } } if (track_uses == 0u) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidAccessError, - "There is no sender or receiver for the track.")); + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidAccessError, + "There is no sender or receiver for the track."); + return ScriptPromise(); } if (track_uses > 1u) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidAccessError, - "There are more than one sender or receiver for the track.")); + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidAccessError, + "There are more than one sender or receiver for the track."); + return ScriptPromise(); } // There is just one use of the track, a sender or receiver. if (track_sender) { @@ -2179,6 +2282,20 @@ RTCRtpTransceiver* RTCPeerConnection::addTransceiver( if (ThrowExceptionIfSignalingStateClosed(signaling_state_, &exception_state)) return nullptr; auto webrtc_init = ToRtpTransceiverInit(init); + // Validate sendEncodings. + for (auto& encoding : webrtc_init.send_encodings) { + if (encoding.rid.length() > 16) { + exception_state.ThrowTypeError("Illegal length of rid"); + return nullptr; + } + // Allowed characters: a-z 0-9 _ and - + if (encoding.rid.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM" + "NOPQRSTUVWXYZ0123456789-_") != + std::string::npos) { + exception_state.ThrowTypeError("Illegal character in rid"); + return nullptr; + } + } webrtc::RTCErrorOr<std::unique_ptr<RTCRtpTransceiverPlatform>> result = webrtc::RTCError(webrtc::RTCErrorType::UNSUPPORTED_OPERATION); if (track_or_kind.IsMediaStreamTrack()) { @@ -2190,7 +2307,7 @@ RTCRtpTransceiver* RTCPeerConnection::addTransceiver( const String& kind_string = track_or_kind.GetAsString(); // TODO(hbos): Make cricket::MediaType an allowed identifier in // rtc_peer_connection.cc and use that instead of a boolean. - std::string kind; + String kind; if (kind_string == "audio") { kind = webrtc::MediaStreamTrackInterface::kAudioKind; } else if (kind_string == "video") { @@ -2235,7 +2352,7 @@ RTCRtpSender* RTCPeerConnection::addTrack(MediaStreamTrack* track, } } - WebVector<WebMediaStream> web_streams(streams.size()); + Vector<WebMediaStream> web_streams(streams.size()); for (wtf_size_t i = 0; i < streams.size(); ++i) { web_streams[i] = streams[i]->Descriptor(); } @@ -2474,7 +2591,9 @@ RTCRtpSender* RTCPeerConnection::CreateOrUpdateSender( if (sender_it == rtp_senders_.end()) { // Create new sender (with empty stream set). sender = MakeGarbageCollected<RTCRtpSender>( - this, std::move(web_sender), kind, track, MediaStreamVector()); + this, std::move(web_sender), kind, track, MediaStreamVector(), + force_encoded_audio_insertable_streams(), + force_encoded_video_insertable_streams()); rtp_senders_.push_back(sender); } else { // Update existing sender (not touching the stream set). @@ -2494,8 +2613,8 @@ RTCRtpReceiver* RTCPeerConnection::CreateOrUpdateReceiver( // Create track. MediaStreamTrack* track; if (receiver_it == rtp_receivers_.end()) { - track = MediaStreamTrack::Create(GetExecutionContext(), - platform_receiver->Track()); + track = MakeGarbageCollected<MediaStreamTrack>(GetExecutionContext(), + platform_receiver->Track()); RegisterTrack(track); } else { track = (*receiver_it)->track(); @@ -2507,7 +2626,9 @@ RTCRtpReceiver* RTCPeerConnection::CreateOrUpdateReceiver( if (receiver_it == rtp_receivers_.end()) { // Create new receiver. receiver = MakeGarbageCollected<RTCRtpReceiver>( - this, std::move(platform_receiver), track, MediaStreamVector()); + this, std::move(platform_receiver), track, MediaStreamVector(), + force_encoded_audio_insertable_streams(), + force_encoded_video_insertable_streams()); // Receiving tracks should be muted by default. SetReadyState() propagates // the related state changes to ensure it is muted on all layers. It also // fires events - which is not desired - but because they fire synchronously @@ -2698,22 +2819,24 @@ void RTCPeerConnection::MaybeFireNegotiationNeeded() { } void RTCPeerConnection::DidGenerateICECandidate( - scoped_refptr<RTCIceCandidatePlatform> platform_candidate) { + RTCIceCandidatePlatform* platform_candidate) { DCHECK(!closed_); DCHECK(GetExecutionContext()->IsContextThread()); DCHECK(platform_candidate); - RTCIceCandidate* ice_candidate = - RTCIceCandidate::Create(std::move(platform_candidate)); + RTCIceCandidate* ice_candidate = RTCIceCandidate::Create(platform_candidate); ScheduleDispatchEvent(RTCPeerConnectionIceEvent::Create(ice_candidate)); } -void RTCPeerConnection::DidFailICECandidate(const WebString& host_candidate, - const WebString& url, + +void RTCPeerConnection::DidFailICECandidate(const String& address, + base::Optional<uint16_t> port, + const String& host_candidate, + const String& url, int error_code, - const WebString& error_text) { + const String& error_text) { DCHECK(!closed_); DCHECK(GetExecutionContext()->IsContextThread()); ScheduleDispatchEvent(RTCPeerConnectionIceErrorEvent::Create( - host_candidate, url, error_code, error_text)); + address, port, host_candidate, url, error_code, error_text)); } void RTCPeerConnection::DidChangeSignalingState( @@ -2737,11 +2860,11 @@ void RTCPeerConnection::DidChangeIceConnectionState( if (sdp_semantics_ == webrtc::SdpSemantics::kUnifiedPlan) { // Unified plan relies on UpdateIceConnectionState() instead. peer_handler_->TrackIceConnectionStateChange( - WebRTCPeerConnectionHandler::IceConnectionStateVersion::kLegacy, + RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion::kLegacy, new_state); } else { peer_handler_->TrackIceConnectionStateChange( - WebRTCPeerConnectionHandler::IceConnectionStateVersion::kDefault, + RTCPeerConnectionHandlerPlatform::IceConnectionStateVersion::kDefault, new_state); ChangeIceConnectionState(new_state); } @@ -2763,7 +2886,7 @@ void RTCPeerConnection::DidAddReceiverPlanB( webrtc::PeerConnectionInterface::SignalingState::kClosed) return; // Create track. - MediaStreamTrack* track = MediaStreamTrack::Create( + auto* track = MakeGarbageCollected<MediaStreamTrack>( GetExecutionContext(), platform_receiver->Track()); tracks_.insert(track->Component(), track); // Create or update streams. @@ -2804,7 +2927,9 @@ void RTCPeerConnection::DidAddReceiverPlanB( } DCHECK(FindReceiver(*platform_receiver) == rtp_receivers_.end()); RTCRtpReceiver* rtp_receiver = MakeGarbageCollected<RTCRtpReceiver>( - this, std::move(platform_receiver), track, streams); + this, std::move(platform_receiver), track, streams, + force_encoded_audio_insertable_streams(), + force_encoded_video_insertable_streams()); rtp_receivers_.push_back(rtp_receiver); ScheduleDispatchEvent(MakeGarbageCollected<RTCTrackEvent>( rtp_receiver, rtp_receiver->track(), streams, nullptr)); @@ -2868,8 +2993,8 @@ void RTCPeerConnection::DidModifySctpTransport( } void RTCPeerConnection::DidModifyTransceivers( - WebVector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers, - WebVector<uintptr_t> removed_transceiver_ids, + Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers, + Vector<uintptr_t> removed_transceiver_ids, bool is_remote_description) { for (auto id : removed_transceiver_ids) { for (auto* it = transceivers_.begin(); it != transceivers_.end(); ++it) { @@ -3000,7 +3125,7 @@ void RTCPeerConnection::DidModifyTransceivers( void RTCPeerConnection::SetAssociatedMediaStreams( RTCRtpReceiver* receiver, - const WebVector<WebString>& stream_ids, + const Vector<String>& stream_ids, HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>* remove_list, HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>* @@ -3011,7 +3136,7 @@ void RTCPeerConnection::SetAssociatedMediaStreams( for (const auto& stream_id : stream_ids) { MediaStream* curr_stream = nullptr; for (const auto& known_stream : known_streams) { - if (static_cast<WebString>(known_stream->id()) == stream_id) { + if (known_stream->id() == stream_id) { curr_stream = known_stream; break; } @@ -3059,14 +3184,16 @@ void RTCPeerConnection::DidAddRemoteDataChannel( } void RTCPeerConnection::DidNoteInterestingUsage(int usage_pattern) { - Document* document = To<Document>(GetExecutionContext()); - ukm::SourceId source_id = document->UkmSourceID(); + if (!GetExecutionContext()) + return; + LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext()); + ukm::SourceId source_id = window->document()->UkmSourceID(); ukm::builders::WebRTC_AddressHarvesting(source_id) .SetUsagePattern(usage_pattern) - .Record(document->UkmRecorder()); + .Record(window->document()->UkmRecorder()); } -void RTCPeerConnection::ReleasePeerConnectionHandler() { +void RTCPeerConnection::UnregisterPeerConnectionHandler() { if (stopped_) return; @@ -3074,7 +3201,7 @@ void RTCPeerConnection::ReleasePeerConnectionHandler() { ice_connection_state_ = webrtc::PeerConnectionInterface::kIceConnectionClosed; signaling_state_ = webrtc::PeerConnectionInterface::SignalingState::kClosed; - peer_handler_.reset(); + peer_handler_->StopAndUnregister(); dispatch_scheduled_events_task_handle_.Cancel(); feature_handle_for_scheduler_.reset(); } @@ -3090,11 +3217,11 @@ const AtomicString& RTCPeerConnection::InterfaceName() const { } ExecutionContext* RTCPeerConnection::GetExecutionContext() const { - return ContextLifecycleObserver::GetExecutionContext(); + return ExecutionContextLifecycleObserver::GetExecutionContext(); } -void RTCPeerConnection::ContextDestroyed(ExecutionContext*) { - ReleasePeerConnectionHandler(); +void RTCPeerConnection::ContextDestroyed() { + UnregisterPeerConnectionHandler(); } void RTCPeerConnection::ChangeSignalingState( @@ -3151,10 +3278,6 @@ void RTCPeerConnection::ChangeIceConnectionState( } ice_connection_state_ = ice_connection_state; DispatchEvent(*Event::Create(event_type_names::kIceconnectionstatechange)); - if (ice_connection_state_ == - webrtc::PeerConnectionInterface::kIceConnectionConnected) { - RecordRapporMetrics(); - } } webrtc::PeerConnectionInterface::IceConnectionState @@ -3276,10 +3399,6 @@ void RTCPeerConnection::CloseInternal() { dtls_transport_iter.value->Close(); } - Document* document = To<Document>(GetExecutionContext()); - HostsUsingFeatures::CountAnyWorld( - *document, HostsUsingFeatures::Feature::kRTCPeerConnectionUsed); - feature_handle_for_scheduler_.reset(); } @@ -3322,29 +3441,7 @@ void RTCPeerConnection::DispatchScheduledEvents() { events.clear(); } -void RTCPeerConnection::RecordRapporMetrics() { - Document* document = To<Document>(GetExecutionContext()); - for (const auto& component : tracks_.Keys()) { - switch (component->Source()->GetType()) { - case MediaStreamSource::kTypeAudio: - HostsUsingFeatures::CountAnyWorld( - *document, HostsUsingFeatures::Feature::kRTCPeerConnectionAudio); - break; - case MediaStreamSource::kTypeVideo: - HostsUsingFeatures::CountAnyWorld( - *document, HostsUsingFeatures::Feature::kRTCPeerConnectionVideo); - break; - default: - NOTREACHED(); - } - } - - if (has_data_channels_) - HostsUsingFeatures::CountAnyWorld( - *document, HostsUsingFeatures::Feature::kRTCPeerConnectionDataChannel); -} - -void RTCPeerConnection::Trace(blink::Visitor* visitor) { +void RTCPeerConnection::Trace(Visitor* visitor) { visitor->Trace(tracks_); visitor->Trace(rtp_senders_); visitor->Trace(rtp_receivers_); @@ -3354,7 +3451,7 @@ void RTCPeerConnection::Trace(blink::Visitor* visitor) { visitor->Trace(ice_transports_by_native_transport_); visitor->Trace(sctp_transport_); EventTargetWithInlineData::Trace(visitor); - ContextLifecycleObserver::Trace(visitor); + ExecutionContextLifecycleObserver::Trace(visitor); MediaStreamObserver::Trace(visitor); } |