diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index ebf3b512d6a..7a6022cb64c 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -97,6 +97,7 @@ seeked seeking select serif +signalingstatechange srclang statechange storage diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 8e12e2ab012..f9bb844d8fe 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -8,7 +8,7 @@ use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding; use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding::RTCPeerConnectionMethods; use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding::{ RTCAnswerOptions, RTCBundlePolicy, RTCConfiguration, RTCIceConnectionState, - RTCIceGatheringState, RTCOfferOptions, + RTCIceGatheringState, RTCOfferOptions, RTCSignalingState, }; use crate::dom::bindings::codegen::Bindings::RTCSessionDescriptionBinding::{ RTCSdpType, RTCSessionDescriptionInit, @@ -38,7 +38,7 @@ use dom_struct::dom_struct; use servo_media::streams::MediaStream as BackendMediaStream; use servo_media::webrtc::{ BundlePolicy, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription, - WebRtcController, WebRtcSignaller, + SignalingState, WebRtcController, WebRtcSignaller, }; use servo_media::ServoMedia; use servo_media_auto::Backend; @@ -63,6 +63,7 @@ pub struct RTCPeerConnection { remote_description: MutNullableDom, gathering_state: Cell, ice_connection_state: Cell, + signaling_state: Cell, } struct RTCSignaller { @@ -116,6 +117,17 @@ impl WebRtcSignaller for RTCSignaller { ); } + fn update_signaling_state(&self, state: SignalingState) { + let this = self.trusted.clone(); + let _ = self.task_source.queue_with_canceller( + task!(update_signaling_state: move || { + let this = this.root(); + this.update_signaling_state(state); + }), + &self.canceller, + ); + } + fn on_add_stream(&self, _: Box) {} fn close(&self) { @@ -136,6 +148,7 @@ impl RTCPeerConnection { remote_description: Default::default(), gathering_state: Cell::new(RTCIceGatheringState::New), ice_connection_state: Cell::new(RTCIceConnectionState::New), + signaling_state: Cell::new(RTCSignalingState::Stable), } } @@ -294,6 +307,28 @@ impl RTCPeerConnection { event.upcast::().fire(self.upcast()); } + fn update_signaling_state(&self, state: SignalingState) { + if self.closed.get() { + return; + } + + let state: RTCSignalingState = state.into(); + + if state == self.signaling_state.get() { + return; + } + + self.signaling_state.set(state); + + let event = Event::new( + &self.global(), + atom!("signalingstatechange"), + EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, + ); + event.upcast::().fire(self.upcast()); + } + fn create_offer(&self) { let generation = self.offer_answer_generation.get(); let (task_source, canceller) = self @@ -386,6 +421,13 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { SetOnnegotiationneeded ); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-signalingstatechange + event_handler!( + signalingstatechange, + GetOnsignalingstatechange, + SetOnsignalingstatechange + ); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate fn AddIceCandidate(&self, candidate: &RTCIceCandidateInit) -> Rc { let p = Promise::new(&self.global()); @@ -539,6 +581,11 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { fn IceConnectionState(&self) -> RTCIceConnectionState { self.ice_connection_state.get() } + + /// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-signalingstate + fn SignalingState(&self) -> RTCSignalingState { + self.signaling_state.get() + } } impl From for RTCSessionDescriptionInit { @@ -594,3 +641,16 @@ impl From for RTCIceConnectionState { } } } + +impl From for RTCSignalingState { + fn from(state: SignalingState) -> Self { + match state { + SignalingState::Stable => RTCSignalingState::Stable, + SignalingState::HaveLocalOffer => RTCSignalingState::Have_local_offer, + SignalingState::HaveRemoteOffer => RTCSignalingState::Have_remote_offer, + SignalingState::HaveLocalPranswer => RTCSignalingState::Have_local_pranswer, + SignalingState::HaveRemotePranswer => RTCSignalingState::Have_remote_pranswer, + SignalingState::Closed => RTCSignalingState::Closed, + } + } +} diff --git a/components/script/dom/webidls/RTCPeerConnection.webidl b/components/script/dom/webidls/RTCPeerConnection.webidl index ec74e551bc5..60447917b3e 100644 --- a/components/script/dom/webidls/RTCPeerConnection.webidl +++ b/components/script/dom/webidls/RTCPeerConnection.webidl @@ -18,7 +18,7 @@ interface RTCPeerConnection : EventTarget { // readonly attribute RTCSessionDescription? currentRemoteDescription; // readonly attribute RTCSessionDescription? pendingRemoteDescription; Promise addIceCandidate(optional RTCIceCandidateInit candidate); - // readonly attribute RTCSignalingState signalingState; + readonly attribute RTCSignalingState signalingState; readonly attribute RTCIceGatheringState iceGatheringState; readonly attribute RTCIceConnectionState iceConnectionState; // readonly attribute RTCPeerConnectionState connectionState; @@ -30,7 +30,7 @@ interface RTCPeerConnection : EventTarget { attribute EventHandler onnegotiationneeded; attribute EventHandler onicecandidate; // attribute EventHandler onicecandidateerror; - // attribute EventHandler onsignalingstatechange; + attribute EventHandler onsignalingstatechange; attribute EventHandler oniceconnectionstatechange; attribute EventHandler onicegatheringstatechange; // attribute EventHandler onconnectionstatechange; @@ -105,3 +105,12 @@ enum RTCIceConnectionState { "failed", "closed" }; + +enum RTCSignalingState { + "stable", + "have-local-offer", + "have-remote-offer", + "have-local-pranswer", + "have-remote-pranswer", + "closed" +};