diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/Cargo.toml | 3 | ||||
-rw-r--r-- | components/script/dom/document.rs | 19 | ||||
-rw-r--r-- | components/script/dom/event.rs | 15 | ||||
-rw-r--r-- | components/script/dom/rtcpeerconnection.rs | 233 | ||||
-rw-r--r-- | components/script/dom/webidls/Event.webidl | 2 | ||||
-rw-r--r-- | components/script/dom/webidls/RTCPeerConnection.webidl | 39 |
6 files changed, 287 insertions, 24 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 6bb94a63abf..7764dde2bbf 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -14,6 +14,7 @@ path = "lib.rs" [features] debugmozjs = ['js/debugmozjs'] +profilemozjs = ['js/profilemozjs'] unstable = [] unrooted_must_root_lint = ["script_plugins/unrooted_must_root_lint"] default = ["unrooted_must_root_lint"] @@ -63,7 +64,7 @@ indexmap = "1.0.2" ipc-channel = "0.11" itertools = "0.8" jstraceable_derive = {path = "../jstraceable_derive"} -js = {package = "mozjs", version = "0.10.0"} +js = {package = "mozjs", version = "0.10.1"} keyboard-types = "0.4.4" lazy_static = "1" libc = "0.2" diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 012aaecbe4f..b59f9502d63 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -2184,18 +2184,19 @@ impl Document { // Step 4.1. let window = self.window(); + let document = Trusted::new(self); window .task_manager() .dom_manipulation_task_source() - .queue_event( - self.upcast(), - atom!("DOMContentLoaded"), - EventBubbles::Bubbles, - EventCancelable::NotCancelable, - window, - ); - - update_with_current_time_ms(&self.dom_content_loaded_event_end); + .queue( + task!(fire_dom_content_loaded_event: move || { + let document = document.root(); + document.upcast::<EventTarget>().fire_bubbling_event(atom!("DOMContentLoaded")); + update_with_current_time_ms(&document.dom_content_loaded_event_end); + }), + window.upcast(), + ) + .unwrap(); // html parsing has finished - set dom content loaded self.interactive_time diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index ad843d7a9b2..7c56e672e11 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -6,8 +6,11 @@ use crate::dom::bindings::callback::ExceptionHandling; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::EventBinding; use crate::dom::bindings::codegen::Bindings::EventBinding::{EventConstants, EventMethods}; +use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp; +use crate::dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceBinding::PerformanceMethods; use crate::dom::bindings::error::Fallible; use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::num::Finite; use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::{DomRoot, DomSlice, MutNullableDom}; @@ -21,6 +24,7 @@ use crate::dom::window::Window; use crate::task::TaskOnce; use devtools_traits::{TimelineMarker, TimelineMarkerType}; use dom_struct::dom_struct; +use metrics::ToMs; use servo_atoms::Atom; use std::cell::Cell; use std::default::Default; @@ -40,7 +44,7 @@ pub struct Event { trusted: Cell<bool>, dispatching: Cell<bool>, initialized: Cell<bool>, - timestamp: u64, + precise_time_ns: u64, } impl Event { @@ -59,7 +63,7 @@ impl Event { trusted: Cell::new(false), dispatching: Cell::new(false), initialized: Cell::new(false), - timestamp: time::get_time().sec as u64, + precise_time_ns: time::precise_time_ns(), } } @@ -322,8 +326,11 @@ impl EventMethods for Event { } // https://dom.spec.whatwg.org/#dom-event-timestamp - fn TimeStamp(&self) -> u64 { - self.timestamp + fn TimeStamp(&self) -> DOMHighResTimeStamp { + Finite::wrap( + (self.precise_time_ns - (*self.global().performance().TimeOrigin()).round() as u64) + .to_ms(), + ) } // https://dom.spec.whatwg.org/#dom-event-initevent diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 0a1c41cf3f9..e4948e08d8e 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, RTCOfferOptions, + RTCAnswerOptions, RTCBundlePolicy, RTCConfiguration, RTCIceConnectionState, + RTCIceGatheringState, RTCOfferOptions, RTCSignalingState, }; use crate::dom::bindings::codegen::Bindings::RTCSessionDescriptionBinding::{ RTCSdpType, RTCSessionDescriptionInit, @@ -36,7 +37,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, IceConnectionState, SdpType, SessionDescription, + SignalingState, WebRtcController, WebRtcSignaller, }; use servo_media::ServoMedia; use servo_media_auto::Backend; @@ -59,6 +61,9 @@ pub struct RTCPeerConnection { answer_promises: DomRefCell<Vec<Rc<Promise>>>, local_description: MutNullableDom<RTCSessionDescription>, remote_description: MutNullableDom<RTCSessionDescription>, + gathering_state: Cell<RTCIceGatheringState>, + ice_connection_state: Cell<RTCIceConnectionState>, + signaling_state: Cell<RTCSignalingState>, } struct RTCSignaller { @@ -90,6 +95,39 @@ 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 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 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<BackendMediaStream>) {} fn close(&self) { @@ -108,6 +146,9 @@ impl RTCPeerConnection { answer_promises: DomRefCell::new(vec![]), local_description: Default::default(), remote_description: Default::default(), + gathering_state: Cell::new(RTCIceGatheringState::New), + ice_connection_state: Cell::new(RTCIceConnectionState::New), + signaling_state: Cell::new(RTCSignalingState::Stable), } } @@ -198,6 +239,96 @@ impl RTCPeerConnection { event.upcast::<Event>().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::<Event>().fire(self.upcast()); + + // step 6 + if state == RTCIceGatheringState::Complete { + let event = RTCPeerConnectionIceEvent::new( + &self.global(), + atom!("icecandidate"), + None, + None, + true, + ); + event.upcast::<Event>().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!("iceconnectionstatechange"), + EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, + ); + event.upcast::<Event>().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::<Event>().fire(self.upcast()); + } + fn create_offer(&self) { let generation = self.offer_answer_generation.get(); let (task_source, canceller) = self @@ -269,6 +400,20 @@ 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, + GetOnicegatheringstatechange, + SetOnicegatheringstatechange + ); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-onnegotiationneeded event_handler!( negotiationneeded, @@ -276,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<Promise> { let p = Promise::new(&self.global()); @@ -419,6 +571,46 @@ 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() + } + + /// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-iceconnectionstate + 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() + } + + /// 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<SessionDescription> for RTCSessionDescriptionInit { @@ -450,3 +642,40 @@ impl<'a> From<&'a RTCSessionDescriptionInit> for SessionDescription { } } } + +impl From<GatheringState> for RTCIceGatheringState { + fn from(state: GatheringState) -> Self { + match state { + GatheringState::New => RTCIceGatheringState::New, + GatheringState::Gathering => RTCIceGatheringState::Gathering, + GatheringState::Complete => RTCIceGatheringState::Complete, + } + } +} + +impl From<IceConnectionState> 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, + } + } +} + +impl From<SignalingState> 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/Event.webidl b/components/script/dom/webidls/Event.webidl index f6074bd68f3..2bf103149d9 100644 --- a/components/script/dom/webidls/Event.webidl +++ b/components/script/dom/webidls/Event.webidl @@ -35,7 +35,7 @@ interface Event { [Unforgeable] readonly attribute boolean isTrusted; [Constant] - readonly attribute DOMTimeStamp timeStamp; + readonly attribute DOMHighResTimeStamp timeStamp; void initEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false); }; diff --git a/components/script/dom/webidls/RTCPeerConnection.webidl b/components/script/dom/webidls/RTCPeerConnection.webidl index c79dba097bf..0f00f3b5b95 100644 --- a/components/script/dom/webidls/RTCPeerConnection.webidl +++ b/components/script/dom/webidls/RTCPeerConnection.webidl @@ -18,21 +18,21 @@ interface RTCPeerConnection : EventTarget { // readonly attribute RTCSessionDescription? currentRemoteDescription; // readonly attribute RTCSessionDescription? pendingRemoteDescription; Promise<void> addIceCandidate(optional RTCIceCandidateInit candidate); - // readonly attribute RTCSignalingState signalingState; - // readonly attribute RTCIceGatheringState iceGatheringState; - // readonly attribute RTCIceConnectionState iceConnectionState; + readonly attribute RTCSignalingState signalingState; + readonly attribute RTCIceGatheringState iceGatheringState; + readonly attribute RTCIceConnectionState iceConnectionState; // readonly attribute RTCPeerConnectionState connectionState; // readonly attribute boolean? canTrickleIceCandidates; // static sequence<RTCIceServer> getDefaultIceServers(); // RTCConfiguration getConfiguration(); // void setConfiguration(RTCConfiguration configuration); - // void close(); + void close(); attribute EventHandler onnegotiationneeded; attribute EventHandler onicecandidate; // attribute EventHandler onicecandidateerror; - // attribute EventHandler onsignalingstatechange; - // attribute EventHandler oniceconnectionstatechange; - // attribute EventHandler onicegatheringstatechange; + attribute EventHandler onsignalingstatechange; + attribute EventHandler oniceconnectionstatechange; + attribute EventHandler onicegatheringstatechange; // attribute EventHandler onconnectionstatechange; // removed from spec, but still shipped by browsers @@ -89,3 +89,28 @@ dictionary RTCOfferOptions : RTCOfferAnswerOptions { dictionary RTCAnswerOptions : RTCOfferAnswerOptions { }; + +enum RTCIceGatheringState { + "new", + "gathering", + "complete" +}; + +enum RTCIceConnectionState { + "new", + "checking", + "connected", + "completed", + "disconnected", + "failed", + "closed" +}; + +enum RTCSignalingState { + "stable", + "have-local-offer", + "have-remote-offer", + "have-local-pranswer", + "have-remote-pranswer", + "closed" +}; |