From 209caa418ba3891e8fd5a9cc911a163380894bd5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 6 Mar 2019 11:58:32 +0530 Subject: [PATCH 1/4] Add ICEGatheringState to RTCPeerConnection --- components/atoms/static_atoms.txt | 1 + components/script/dom/rtcpeerconnection.rs | 90 ++++++++++++++++++- .../dom/webidls/RTCPeerConnection.webidl | 10 ++- 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index 74f24a23e30..e720f8435b3 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -37,6 +37,7 @@ gattserverdisconnected hashchange hidden icecandidate +icegatheringstatechange image input invalid diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 0a1c41cf3f9..13e58b14038 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::RTCIceCandidateBinding::RTCIceCandi 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, RTCOfferOptions, + RTCAnswerOptions, RTCBundlePolicy, RTCConfiguration, RTCIceGatheringState, RTCOfferOptions, }; use crate::dom::bindings::codegen::Bindings::RTCSessionDescriptionBinding::{ RTCSdpType, RTCSessionDescriptionInit, @@ -36,7 +36,8 @@ use dom_struct::dom_struct; use servo_media::streams::MediaStream as BackendMediaStream; use servo_media::webrtc::{ - BundlePolicy, IceCandidate, SdpType, SessionDescription, WebRtcController, WebRtcSignaller, + BundlePolicy, GatheringState, IceCandidate, SdpType, SessionDescription, WebRtcController, + WebRtcSignaller, }; use servo_media::ServoMedia; use servo_media_auto::Backend; @@ -59,6 +60,7 @@ pub struct RTCPeerConnection { answer_promises: DomRefCell>>, local_description: MutNullableDom, remote_description: MutNullableDom, + gathering_state: Cell, } struct RTCSignaller { @@ -90,6 +92,17 @@ impl WebRtcSignaller for RTCSignaller { ); } + fn update_gathering_state(&self, state: GatheringState) { + let this = self.trusted.clone(); + let _ = self.task_source.queue_with_canceller( + task!(update_gathering_state: move || { + let this = this.root(); + this.update_gathering_state(state); + }), + &self.canceller, + ); + } + fn on_add_stream(&self, _: Box) {} fn close(&self) { @@ -108,6 +121,7 @@ impl RTCPeerConnection { answer_promises: DomRefCell::new(vec![]), local_description: Default::default(), remote_description: Default::default(), + gathering_state: Cell::new(RTCIceGatheringState::New), } } @@ -198,6 +212,55 @@ impl RTCPeerConnection { event.upcast::().fire(self.upcast()); } + /// https://www.w3.org/TR/webrtc/#update-ice-gathering-state + fn update_gathering_state(&self, state: GatheringState) { + // step 1 + if self.closed.get() { + return; + } + + // step 2 (state derivation already done by gstreamer) + let state: RTCIceGatheringState = state.into(); + + // step 3 + if state == self.gathering_state.get() { + return; + } + + // step 4 + self.gathering_state.set(state); + + // step 5 + let event = Event::new( + &self.global(), + atom!("icegatheringstatechange"), + EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, + ); + event.upcast::().fire(self.upcast()); + + // step 6 + if state == RTCIceGatheringState::Complete { + let event = RTCPeerConnectionIceEvent::new( + &self.global(), + atom!("icecandidate"), + None, + None, + true, + ); + event.upcast::().fire(self.upcast()); + } + + // step 5 + let event = Event::new( + &self.global(), + atom!("icegatheringstatechange"), + 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 @@ -269,6 +332,13 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-icecandidate event_handler!(icecandidate, GetOnicecandidate, SetOnicecandidate); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-icegatheringstatechange + event_handler!( + icegatheringstatechange, + GetOnicegatheringstatechange, + SetOnicegatheringstatechange + ); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-onnegotiationneeded event_handler!( negotiationneeded, @@ -419,6 +489,11 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { self.controller.borrow().as_ref().unwrap().add_stream(track); } } + + /// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-icegatheringstate + fn IceGatheringState(&self) -> RTCIceGatheringState { + self.gathering_state.get() + } } impl From for RTCSessionDescriptionInit { @@ -450,3 +525,14 @@ impl<'a> From<&'a RTCSessionDescriptionInit> for SessionDescription { } } } + + +impl From for RTCIceGatheringState { + fn from(state: GatheringState) -> Self { + match state { + GatheringState::New => RTCIceGatheringState::New, + GatheringState::Gathering => RTCIceGatheringState::Gathering, + GatheringState::Complete => RTCIceGatheringState::Complete, + } + } +} diff --git a/components/script/dom/webidls/RTCPeerConnection.webidl b/components/script/dom/webidls/RTCPeerConnection.webidl index c79dba097bf..ea1930a0561 100644 --- a/components/script/dom/webidls/RTCPeerConnection.webidl +++ b/components/script/dom/webidls/RTCPeerConnection.webidl @@ -19,7 +19,7 @@ interface RTCPeerConnection : EventTarget { // readonly attribute RTCSessionDescription? pendingRemoteDescription; Promise addIceCandidate(optional RTCIceCandidateInit candidate); // readonly attribute RTCSignalingState signalingState; - // readonly attribute RTCIceGatheringState iceGatheringState; + readonly attribute RTCIceGatheringState iceGatheringState; // readonly attribute RTCIceConnectionState iceConnectionState; // readonly attribute RTCPeerConnectionState connectionState; // readonly attribute boolean? canTrickleIceCandidates; @@ -32,7 +32,7 @@ interface RTCPeerConnection : EventTarget { // attribute EventHandler onicecandidateerror; // attribute EventHandler onsignalingstatechange; // attribute EventHandler oniceconnectionstatechange; - // attribute EventHandler onicegatheringstatechange; + attribute EventHandler onicegatheringstatechange; // attribute EventHandler onconnectionstatechange; // removed from spec, but still shipped by browsers @@ -89,3 +89,9 @@ dictionary RTCOfferOptions : RTCOfferAnswerOptions { dictionary RTCAnswerOptions : RTCOfferAnswerOptions { }; + +enum RTCIceGatheringState { + "new", + "gathering", + "complete" +}; From fc25a80892e701742f5167a0c4ea6a92e5730c7b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 6 Mar 2019 12:31:17 +0530 Subject: [PATCH 2/4] Add ICEConnectionState to RTCPeerConnection --- components/atoms/static_atoms.txt | 1 + components/script/dom/rtcpeerconnection.rs | 68 +++++++++++++++++-- .../dom/webidls/RTCPeerConnection.webidl | 14 +++- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index e720f8435b3..ebf3b512d6a 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -37,6 +37,7 @@ gattserverdisconnected hashchange hidden icecandidate +iceconnectionstatechange icegatheringstatechange image input diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 13e58b14038..8e12e2ab012 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -7,7 +7,8 @@ use crate::dom::bindings::codegen::Bindings::RTCIceCandidateBinding::RTCIceCandi 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, RTCIceGatheringState, RTCOfferOptions, + RTCAnswerOptions, RTCBundlePolicy, RTCConfiguration, RTCIceConnectionState, + RTCIceGatheringState, RTCOfferOptions, }; use crate::dom::bindings::codegen::Bindings::RTCSessionDescriptionBinding::{ RTCSdpType, RTCSessionDescriptionInit, @@ -36,8 +37,8 @@ use dom_struct::dom_struct; use servo_media::streams::MediaStream as BackendMediaStream; use servo_media::webrtc::{ - BundlePolicy, GatheringState, IceCandidate, SdpType, SessionDescription, WebRtcController, - WebRtcSignaller, + BundlePolicy, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription, + WebRtcController, WebRtcSignaller, }; use servo_media::ServoMedia; use servo_media_auto::Backend; @@ -61,6 +62,7 @@ pub struct RTCPeerConnection { local_description: MutNullableDom, remote_description: MutNullableDom, gathering_state: Cell, + ice_connection_state: Cell, } struct RTCSignaller { @@ -103,6 +105,17 @@ impl WebRtcSignaller for RTCSignaller { ); } + fn update_ice_connection_state(&self, state: IceConnectionState) { + let this = self.trusted.clone(); + let _ = self.task_source.queue_with_canceller( + task!(update_ice_connection_state: move || { + let this = this.root(); + this.update_ice_connection_state(state); + }), + &self.canceller, + ); + } + fn on_add_stream(&self, _: Box) {} fn close(&self) { @@ -122,6 +135,7 @@ impl RTCPeerConnection { local_description: Default::default(), remote_description: Default::default(), gathering_state: Cell::new(RTCIceGatheringState::New), + ice_connection_state: Cell::new(RTCIceConnectionState::New), } } @@ -250,11 +264,30 @@ impl RTCPeerConnection { ); event.upcast::().fire(self.upcast()); } + } + + /// https://www.w3.org/TR/webrtc/#update-ice-connection-state + fn update_ice_connection_state(&self, state: IceConnectionState) { + // step 1 + if self.closed.get() { + return; + } + + // step 2 (state derivation already done by gstreamer) + let state: RTCIceConnectionState = state.into(); + + // step 3 + if state == self.ice_connection_state.get() { + return; + } + + // step 4 + self.ice_connection_state.set(state); // step 5 let event = Event::new( &self.global(), - atom!("icegatheringstatechange"), + atom!("iceconnectionstatechange"), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, ); @@ -332,6 +365,13 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-icecandidate event_handler!(icecandidate, GetOnicecandidate, SetOnicecandidate); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-iceconnectionstatechange + event_handler!( + iceconnectionstatechange, + GetOniceconnectionstatechange, + SetOniceconnectionstatechange + ); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-icegatheringstatechange event_handler!( icegatheringstatechange, @@ -494,6 +534,11 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { fn IceGatheringState(&self) -> RTCIceGatheringState { self.gathering_state.get() } + + /// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-iceconnectionstate + fn IceConnectionState(&self) -> RTCIceConnectionState { + self.ice_connection_state.get() + } } impl From for RTCSessionDescriptionInit { @@ -526,7 +571,6 @@ impl<'a> From<&'a RTCSessionDescriptionInit> for SessionDescription { } } - impl From for RTCIceGatheringState { fn from(state: GatheringState) -> Self { match state { @@ -536,3 +580,17 @@ impl From for RTCIceGatheringState { } } } + +impl From for RTCIceConnectionState { + fn from(state: IceConnectionState) -> Self { + match state { + IceConnectionState::New => RTCIceConnectionState::New, + IceConnectionState::Checking => RTCIceConnectionState::Checking, + IceConnectionState::Connected => RTCIceConnectionState::Connected, + IceConnectionState::Completed => RTCIceConnectionState::Completed, + IceConnectionState::Disconnected => RTCIceConnectionState::Disconnected, + IceConnectionState::Failed => RTCIceConnectionState::Failed, + IceConnectionState::Closed => RTCIceConnectionState::Closed, + } + } +} diff --git a/components/script/dom/webidls/RTCPeerConnection.webidl b/components/script/dom/webidls/RTCPeerConnection.webidl index ea1930a0561..ec74e551bc5 100644 --- a/components/script/dom/webidls/RTCPeerConnection.webidl +++ b/components/script/dom/webidls/RTCPeerConnection.webidl @@ -20,7 +20,7 @@ interface RTCPeerConnection : EventTarget { Promise addIceCandidate(optional RTCIceCandidateInit candidate); // readonly attribute RTCSignalingState signalingState; readonly attribute RTCIceGatheringState iceGatheringState; - // readonly attribute RTCIceConnectionState iceConnectionState; + readonly attribute RTCIceConnectionState iceConnectionState; // readonly attribute RTCPeerConnectionState connectionState; // readonly attribute boolean? canTrickleIceCandidates; // static sequence getDefaultIceServers(); @@ -31,7 +31,7 @@ interface RTCPeerConnection : EventTarget { attribute EventHandler onicecandidate; // attribute EventHandler onicecandidateerror; // attribute EventHandler onsignalingstatechange; - // attribute EventHandler oniceconnectionstatechange; + attribute EventHandler oniceconnectionstatechange; attribute EventHandler onicegatheringstatechange; // attribute EventHandler onconnectionstatechange; @@ -95,3 +95,13 @@ enum RTCIceGatheringState { "gathering", "complete" }; + +enum RTCIceConnectionState { + "new", + "checking", + "connected", + "completed", + "disconnected", + "failed", + "closed" +}; From 5cb5503a755efd7e3b7927f590f26feb03e97e0d Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 6 Mar 2019 12:44:14 +0530 Subject: [PATCH 3/4] Add SignalingState to RTCPeerConnection --- components/atoms/static_atoms.txt | 1 + components/script/dom/rtcpeerconnection.rs | 64 ++++++++++++++++++- .../dom/webidls/RTCPeerConnection.webidl | 13 +++- 3 files changed, 74 insertions(+), 4 deletions(-) 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" +}; From 7343241c3d703b18c16ca758f12ae082c0ff2bd2 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 6 Mar 2019 13:11:50 +0530 Subject: [PATCH 4/4] Add RTCPeerConnection::Close --- components/script/dom/rtcpeerconnection.rs | 25 +++++++++++++++++++ .../dom/webidls/RTCPeerConnection.webidl | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index f9bb844d8fe..e4948e08d8e 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -586,6 +586,31 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { fn SignalingState(&self) -> RTCSignalingState { self.signaling_state.get() } + + /// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close + fn Close(&self) { + // Step 1 + if self.closed.get() { + return; + } + // Step 2 + self.closed.set(true); + + // Step 4 + self.signaling_state.set(RTCSignalingState::Closed); + + // Step 5 handled by backend + self.controller.borrow_mut().as_ref().unwrap().quit(); + + // Step 6-10 + // (no current support for data channels, transports, etc) + + // Step 11 + self.ice_connection_state.set(RTCIceConnectionState::Closed); + + // Step 11 + // (no current support for connection state) + } } impl From for RTCSessionDescriptionInit { diff --git a/components/script/dom/webidls/RTCPeerConnection.webidl b/components/script/dom/webidls/RTCPeerConnection.webidl index 60447917b3e..0f00f3b5b95 100644 --- a/components/script/dom/webidls/RTCPeerConnection.webidl +++ b/components/script/dom/webidls/RTCPeerConnection.webidl @@ -26,7 +26,7 @@ interface RTCPeerConnection : EventTarget { // static sequence getDefaultIceServers(); // RTCConfiguration getConfiguration(); // void setConfiguration(RTCConfiguration configuration); - // void close(); + void close(); attribute EventHandler onnegotiationneeded; attribute EventHandler onicecandidate; // attribute EventHandler onicecandidateerror;