From 5788882b16a30fee81c75ab26b7f6c8555b43693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Fri, 12 Jun 2020 16:21:16 +0200 Subject: [PATCH 01/27] Update servo-media and gstreamer --- Cargo.lock | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8849f2165f7..554369dd6b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2036,9 +2036,9 @@ dependencies = [ [[package]] name = "gstreamer" -version = "0.15.6" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeec6021aec963d6c547cf3e4e6d4f24a8e128b1a54dc509a700c821f835c73a" +checksum = "ce8664a114cd6ec16bece783d5eee59496919915b1f6884400ba4a953274a163" dependencies = [ "bitflags", "cfg-if", @@ -3667,6 +3667,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-derive" version = "0.3.0" @@ -4913,7 +4923,7 @@ dependencies = [ [[package]] name = "servo-media" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "servo-media-audio", "servo-media-player", @@ -4925,16 +4935,19 @@ dependencies = [ [[package]] name = "servo-media-audio" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "boxfnonce", "byte-slice-cast", "euclid", + "log", + "num-complex", "num-traits", "petgraph", "serde", "serde_derive", "servo-media-player", + "servo-media-streams", "servo-media-traits", "servo_media_derive", "smallvec 0.6.13", @@ -4944,7 +4957,7 @@ dependencies = [ [[package]] name = "servo-media-dummy" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "boxfnonce", "ipc-channel", @@ -4959,7 +4972,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "boxfnonce", "byte-slice-cast", @@ -4995,7 +5008,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer-render" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "gstreamer", "gstreamer-video", @@ -5005,7 +5018,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer-render-android" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "glib", "gstreamer", @@ -5018,7 +5031,7 @@ dependencies = [ [[package]] name = "servo-media-gstreamer-render-unix" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "glib", "gstreamer", @@ -5031,7 +5044,7 @@ dependencies = [ [[package]] name = "servo-media-player" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "ipc-channel", "serde", @@ -5043,7 +5056,7 @@ dependencies = [ [[package]] name = "servo-media-streams" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "lazy_static", "uuid", @@ -5052,16 +5065,18 @@ dependencies = [ [[package]] name = "servo-media-traits" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" [[package]] name = "servo-media-webrtc" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "boxfnonce", + "lazy_static", "log", "servo-media-streams", + "uuid", ] [[package]] @@ -5133,7 +5148,7 @@ dependencies = [ [[package]] name = "servo_media_derive" version = "0.1.0" -source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686" +source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e" dependencies = [ "proc-macro2 1.0.17", "quote 1.0.2", From 4e6d3e7cec0fa2467bdb7e6dd926facc4c37a28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Sat, 30 May 2020 21:51:17 +0200 Subject: [PATCH 02/27] WebRTCDataChannel initial support --- components/script/dom/bindings/trace.rs | 3 +- components/script/dom/mod.rs | 1 + components/script/dom/rtcdatachannel.rs | 260 ++++++++++++++++++ components/script/dom/rtcpeerconnection.rs | 15 + .../script/dom/webidls/RTCDataChannel.webidl | 49 ++++ .../dom/webidls/RTCPeerConnection.webidl | 8 + 6 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 components/script/dom/rtcdatachannel.rs create mode 100644 components/script/dom/webidls/RTCDataChannel.webidl diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 6208a7bc1ba..40ec44a62d5 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -128,7 +128,7 @@ use servo_media::player::video::VideoFrame; use servo_media::player::Player; use servo_media::streams::registry::MediaStreamId; use servo_media::streams::MediaStreamType; -use servo_media::webrtc::WebRtcController; +use servo_media::webrtc::{WebRtcController, WebRtcDataChannelBackend}; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use smallvec::SmallVec; use std::borrow::Cow; @@ -607,6 +607,7 @@ unsafe_no_jsmanaged_fields!(NodeId); unsafe_no_jsmanaged_fields!(AnalysisEngine, DistanceModel, PanningModel, ParamType); unsafe_no_jsmanaged_fields!(Arc>); unsafe_no_jsmanaged_fields!(WebRtcController); +unsafe_no_jsmanaged_fields!(Box); unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType); unsafe_no_jsmanaged_fields!(Mutex); unsafe_no_jsmanaged_fields!(ResourceFetchTiming); diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 2ee17f3e74b..1024a37c3f4 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -486,6 +486,7 @@ pub mod raredata; pub mod readablestream; pub mod request; pub mod response; +pub mod rtcdatachannel; pub mod rtcicecandidate; pub mod rtcpeerconnection; pub mod rtcpeerconnectioniceevent; diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs new file mode 100644 index 00000000000..d7388729dbd --- /dev/null +++ b/components/script/dom/rtcdatachannel.rs @@ -0,0 +1,260 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelInit; +use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelMethods; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::refcounted::Trusted; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::str::USVString; +use crate::dom::blob::Blob; +use crate::dom::event::{Event, EventBubbles, EventCancelable}; +use crate::dom::eventtarget::EventTarget; +use crate::dom::globalscope::GlobalScope; +use crate::task_source::TaskSource; +use dom_struct::dom_struct; +use js::rust::CustomAutoRooterGuard; +use js::typedarray::{ArrayBuffer, ArrayBufferView}; +use servo_media::webrtc::{ + WebRtcController, WebRtcDataChannelBackend, WebRtcDataChannelInit, WebRtcError, +}; +use std::sync::mpsc; + +#[dom_struct] +pub struct RTCDataChannel { + eventtarget: EventTarget, + #[ignore_malloc_size_of = "defined in servo-media"] + channel: Box, + label: USVString, + ordered: bool, + max_packet_life_time: Option, + max_retransmits: Option, + protocol: USVString, + negotiated: bool, + id: Option, +} + +impl RTCDataChannel { + #[allow(unrooted_must_root)] + pub fn new_inherited( + webrtc_controller: &DomRefCell>, + label: USVString, + options: &RTCDataChannelInit, + ) -> RTCDataChannel { + let webrtc = webrtc_controller.borrow(); + let webrtc = webrtc.as_ref().unwrap(); + + let (sender, receiver) = mpsc::channel::>(); + + let mut init: WebRtcDataChannelInit = options.into(); + init.label = label.to_string(); + + webrtc.create_data_channel(init, sender); + let channel = receiver.recv().unwrap(); + + let rtc_data_channel = RTCDataChannel { + eventtarget: EventTarget::new_inherited(), + channel, + label, + ordered: options.ordered, + max_packet_life_time: options.maxPacketLifeTime, + max_retransmits: options.maxRetransmits, + protocol: options.protocol.clone(), + negotiated: options.negotiated, + id: options.id, + }; + + let trusted = Trusted::new(&rtc_data_channel); + + let this = trusted.clone(); + rtc_data_channel.channel.set_on_open(Box::new(move || { + let this_ = this.clone(); + let global = this.root().global(); + let task_source = global.networking_task_source(); + let _ = task_source.queue( + task!(on_open: move || { + this_.root().on_open(); + }), + global.upcast(), + ); + })); + + let this = trusted.clone(); + rtc_data_channel.channel.set_on_close(Box::new(move || { + let this_ = this.clone(); + let global = this.root().global(); + let task_source = global.networking_task_source(); + let _ = task_source.queue( + task!(on_close: move || { + this_.root().on_close(); + }), + global.upcast(), + ); + })); + + let this = trusted.clone(); + rtc_data_channel + .channel + .set_on_error(Box::new(move |error| { + let this_ = this.clone(); + let global = this.root().global(); + let task_source = global.networking_task_source(); + let _ = task_source.queue( + task!(on_error: move || { + this_.root().on_error(error); + }), + global.upcast(), + ); + })); + + let this = trusted.clone(); + rtc_data_channel + .channel + .set_on_message(Box::new(move |message| { + let this_ = this.clone(); + let global = this.root().global(); + let task_source = global.networking_task_source(); + let _ = task_source.queue( + task!(on_message: move || { + this_.root().on_message(message); + }), + global.upcast(), + ); + })); + + rtc_data_channel + } + + pub fn new( + global: &GlobalScope, + webrtc_controller: &DomRefCell>, + label: USVString, + options: &RTCDataChannelInit, + ) -> DomRoot { + reflect_dom_object( + Box::new(RTCDataChannel::new_inherited( + webrtc_controller, + label, + options, + )), + global, + ) + } + + fn on_open(&self) { + let event = Event::new( + &self.global(), + atom!("open"), + EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, + ); + event.upcast::().fire(self.upcast()); + } + + fn on_close(&self) { + let event = Event::new( + &self.global(), + atom!("close"), + EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, + ); + event.upcast::().fire(self.upcast()); + } + + fn on_error(&self, error: WebRtcError) {} + + fn on_message(&self, message: String) {} +} + +impl RTCDataChannelMethods for RTCDataChannel { + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onopen + event_handler!(open, GetOnopen, SetOnopen); + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onbufferedamountlow + event_handler!( + bufferedamountlow, + GetOnbufferedamountlow, + SetOnbufferedamountlow + ); + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onerror + event_handler!(error, GetOnerror, SetOnerror); + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onclosing + event_handler!(closing, GetOnclosing, SetOnclosing); + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onclose + event_handler!(close, GetOnclose, SetOnclose); + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onmessage + event_handler!(message, GetOnmessage, SetOnmessage); + + // https://www.w3.org/TR/webrtc/#dom-datachannel-label + fn Label(&self) -> USVString { + self.label.clone() + } + // https://www.w3.org/TR/webrtc/#dom-datachannel-ordered + fn Ordered(&self) -> bool { + self.ordered + } + + // https://www.w3.org/TR/webrtc/#dom-datachannel-maxpacketlifetime + fn GetMaxPacketLifeTime(&self) -> Option { + self.max_packet_life_time + } + + // https://www.w3.org/TR/webrtc/#dom-datachannel-maxretransmits + fn GetMaxRetransmits(&self) -> Option { + self.max_retransmits + } + + // https://www.w3.org/TR/webrtc/#dom-datachannel-protocol + fn Protocol(&self) -> USVString { + self.protocol.clone() + } + + // https://www.w3.org/TR/webrtc/#dom-datachannel-negotiated + fn Negotiated(&self) -> bool { + self.negotiated + } + + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-id + fn GetId(&self) -> Option { + self.id + } + + // fn ReadyState(&self) -> RTCDataChannelState; + // fn BufferedAmount(&self) -> u32; + // fn BufferedAmountLowThreshold(&self) -> u32; + // fn SetBufferedAmountLowThreshold(&self, value: u32) -> (); + + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-close + fn Close(&self) -> () {} + + // fn BinaryType(&self) -> DOMString; + // fn SetBinaryType(&self, value: DOMString) -> (); + + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send + fn Send(&self, data: USVString) -> () {} + + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-1 + fn Send_(&self, data: &Blob) -> () {} + + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-2 + fn Send__(&self, data: CustomAutoRooterGuard) -> () {} + + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-3 + fn Send___(&self, data: CustomAutoRooterGuard) -> () {} +} + +impl From<&RTCDataChannelInit> for WebRtcDataChannelInit { + fn from(init: &RTCDataChannelInit) -> WebRtcDataChannelInit { + WebRtcDataChannelInit { + label: String::new(), + id: init.id, + max_packet_life_time: init.maxPacketLifeTime, + max_retransmits: init.maxRetransmits, + negotiated: init.negotiated, + ordered: init.ordered, + protocol: init.protocol.to_string(), + } + } +} diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index fa8c5dda800..5ce0b109bbd 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelInit; use crate::dom::bindings::codegen::Bindings::RTCIceCandidateBinding::RTCIceCandidateInit; use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding::RTCPeerConnectionMethods; use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding::{ @@ -20,12 +21,14 @@ use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; +use crate::dom::bindings::str::USVString; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::mediastream::MediaStream; use crate::dom::mediastreamtrack::MediaStreamTrack; use crate::dom::promise::Promise; +use crate::dom::rtcdatachannel::RTCDataChannel; use crate::dom::rtcicecandidate::RTCIceCandidate; use crate::dom::rtcpeerconnectioniceevent::RTCPeerConnectionIceEvent; use crate::dom::rtcsessiondescription::RTCSessionDescription; @@ -448,6 +451,9 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { SetOnsignalingstatechange ); + // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-ondatachannel + event_handler!(datachannel, GetOndatachannel, SetOndatachannel); + /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate fn AddIceCandidate(&self, candidate: &RTCIceCandidateInit, comp: InRealm) -> Rc { let p = Promise::new_in_current_realm(&self.global(), comp); @@ -633,6 +639,15 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { // Step 11 // (no current support for connection state) } + + /// https://www.w3.org/TR/webrtc/#dom-peerconnection-createdatachannel + fn CreateDataChannel( + &self, + label: USVString, + dataChannelDict: &RTCDataChannelInit, + ) -> DomRoot { + RTCDataChannel::new(&self.global(), &self.controller, label, dataChannelDict) + } } impl From for RTCSessionDescriptionInit { diff --git a/components/script/dom/webidls/RTCDataChannel.webidl b/components/script/dom/webidls/RTCDataChannel.webidl new file mode 100644 index 00000000000..e8a08969e55 --- /dev/null +++ b/components/script/dom/webidls/RTCDataChannel.webidl @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + + // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel + + [Exposed=Window] +interface RTCDataChannel : EventTarget { + readonly attribute USVString label; + readonly attribute boolean ordered; + readonly attribute unsigned short? maxPacketLifeTime; + readonly attribute unsigned short? maxRetransmits; + readonly attribute USVString protocol; + readonly attribute boolean negotiated; + readonly attribute unsigned short? id; + //readonly attribute RTCDataChannelState readyState; + //readonly attribute unsigned long bufferedAmount; + //attribute unsigned long bufferedAmountLowThreshold; + attribute EventHandler onopen; + attribute EventHandler onbufferedamountlow; + attribute EventHandler onerror; + attribute EventHandler onclosing; + attribute EventHandler onclose; + void close(); + attribute EventHandler onmessage; + //attribute DOMString binaryType; + void send(USVString data); + void send(Blob data); + void send(ArrayBuffer data); + void send(ArrayBufferView data); +}; + +// https://www.w3.org/TR/webrtc/#dom-rtcdatachannelinit +dictionary RTCDataChannelInit { + boolean ordered = true; + unsigned short maxPacketLifeTime; + unsigned short maxRetransmits; + USVString protocol = ""; + boolean negotiated = false; + unsigned short id; +}; + +// https://www.w3.org/TR/webrtc/#dom-rtcdatachannelstate +enum RTCDataChannelState { + "connecting", + "open", + "closing", + "closed" +}; \ No newline at end of file diff --git a/components/script/dom/webidls/RTCPeerConnection.webidl b/components/script/dom/webidls/RTCPeerConnection.webidl index d2054343150..f53691a9a70 100644 --- a/components/script/dom/webidls/RTCPeerConnection.webidl +++ b/components/script/dom/webidls/RTCPeerConnection.webidl @@ -126,3 +126,11 @@ partial interface RTCPeerConnection { // optional RTCRtpTransceiverInit init); attribute EventHandler ontrack; }; + +// https://www.w3.org/TR/webrtc/#rtcpeerconnection-interface-extensions-0 +partial interface RTCPeerConnection { + // readonly attribute RTCSctpTransport? sctp; + RTCDataChannel createDataChannel(USVString label, + optional RTCDataChannelInit dataChannelDict = {}); + attribute EventHandler ondatachannel; +}; From 84598a517323f47284e34aa328a195ae96c5f8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Mon, 1 Jun 2020 11:42:39 +0200 Subject: [PATCH 03/27] Introduce RTCError and RTCErrorEvent --- components/script/dom/mod.rs | 2 + components/script/dom/rtcerror.rs | 90 +++++++++++++++++++ components/script/dom/rtcerrorevent.rs | 72 +++++++++++++++ components/script/dom/webidls/RTCError.webidl | 35 ++++++++ .../script/dom/webidls/RTCErrorEvent.webidl | 15 ++++ 5 files changed, 214 insertions(+) create mode 100644 components/script/dom/rtcerror.rs create mode 100644 components/script/dom/rtcerrorevent.rs create mode 100644 components/script/dom/webidls/RTCError.webidl create mode 100644 components/script/dom/webidls/RTCErrorEvent.webidl diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 1024a37c3f4..e4464d570df 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -487,6 +487,8 @@ pub mod readablestream; pub mod request; pub mod response; pub mod rtcdatachannel; +pub mod rtcerror; +pub mod rtcerrorevent; pub mod rtcicecandidate; pub mod rtcpeerconnection; pub mod rtcpeerconnectioniceevent; diff --git a/components/script/dom/rtcerror.rs b/components/script/dom/rtcerror.rs new file mode 100644 index 00000000000..db23cd7c096 --- /dev/null +++ b/components/script/dom/rtcerror.rs @@ -0,0 +1,90 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::RTCErrorDetailType; +use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::RTCErrorInit; +use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::RTCErrorMethods; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; +use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::str::DOMString; +use crate::dom::domexception::{DOMErrorName, DOMException}; +use crate::dom::globalscope::GlobalScope; +use crate::dom::window::Window; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct RTCError { + exception: Dom, + error_detail: RTCErrorDetailType, + sdp_line_number: Option, + http_request_status_code: Option, + sctp_cause_code: Option, + received_alert: Option, + sent_alert: Option, +} + +impl RTCError { + fn new_inherited(global: &GlobalScope, init: &RTCErrorInit, message: DOMString) -> RTCError { + RTCError { + exception: Dom::from_ref(&*DOMException::new( + global, + DOMErrorName::from(&message).unwrap(), + )), + error_detail: init.errorDetail, + sdp_line_number: init.sdpLineNumber, + http_request_status_code: init.httpRequestStatusCode, + sctp_cause_code: init.sctpCauseCode, + received_alert: init.receivedAlert, + sent_alert: init.sentAlert, + } + } + + fn new(global: &GlobalScope, init: &RTCErrorInit, message: DOMString) -> DomRoot { + reflect_dom_object( + Box::new(RTCError::new_inherited(global, init, message)), + global, + ) + } + + #[allow(non_snake_case)] + pub fn Constructor( + window: &Window, + init: &RTCErrorInit, + message: DOMString, + ) -> DomRoot { + RTCError::new(&window.global(), init, message) + } +} + +impl RTCErrorMethods for RTCError { + // https://www.w3.org/TR/webrtc/#dom-rtcerror-errordetail + fn ErrorDetail(&self) -> RTCErrorDetailType { + self.error_detail + } + + // https://www.w3.org/TR/webrtc/#dom-rtcerror-sdplinenumber + fn GetSdpLineNumber(&self) -> Option { + self.sdp_line_number + } + + // https://www.w3.org/TR/webrtc/#dom-rtcerror + fn GetHttpRequestStatusCode(&self) -> Option { + self.http_request_status_code + } + + // https://www.w3.org/TR/webrtc/#dom-rtcerror-sctpcausecode + fn GetSctpCauseCode(&self) -> Option { + self.sctp_cause_code + } + + // https://www.w3.org/TR/webrtc/#dom-rtcerror-receivedalert + fn GetReceivedAlert(&self) -> Option { + self.received_alert + } + + // https://www.w3.org/TR/webrtc/#dom-rtcerror-sentalert + fn GetSentAlert(&self) -> Option { + self.sent_alert + } +} diff --git a/components/script/dom/rtcerrorevent.rs b/components/script/dom/rtcerrorevent.rs new file mode 100644 index 00000000000..aeaf361aa58 --- /dev/null +++ b/components/script/dom/rtcerrorevent.rs @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods; +use crate::dom::bindings::codegen::Bindings::RTCErrorEventBinding::RTCErrorEventInit; +use crate::dom::bindings::codegen::Bindings::RTCErrorEventBinding::RTCErrorEventMethods; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; +use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::str::DOMString; +use crate::dom::event::Event; +use crate::dom::globalscope::GlobalScope; +use crate::dom::rtcerror::RTCError; +use crate::dom::window::Window; +use dom_struct::dom_struct; +use servo_atoms::Atom; + +#[dom_struct] +pub struct RTCErrorEvent { + event: Event, + error: Dom, +} + +impl RTCErrorEvent { + fn new_inherited(error: &RTCError) -> RTCErrorEvent { + RTCErrorEvent { + event: Event::new_inherited(), + error: Dom::from_ref(error), + } + } + + fn new( + global: &GlobalScope, + type_: Atom, + bubbles: bool, + cancelable: bool, + error: &RTCError, + ) -> DomRoot { + let event = reflect_dom_object(Box::new(RTCErrorEvent::new_inherited(&error)), global); + { + let event = event.upcast::(); + event.init_event(type_, bubbles, cancelable); + } + event + } + + #[allow(non_snake_case)] + pub fn Constructor( + window: &Window, + type_: DOMString, + init: &RTCErrorEventInit, + ) -> DomRoot { + RTCErrorEvent::new( + &window.global(), + Atom::from(type_), + init.parent.bubbles, + init.parent.cancelable, + &init.error, + ) + } +} + +impl RTCErrorEventMethods for RTCErrorEvent { + fn Error(&self) -> DomRoot { + DomRoot::from_ref(&*self.error) + } + + fn IsTrusted(&self) -> bool { + self.event.IsTrusted() + } +} diff --git a/components/script/dom/webidls/RTCError.webidl b/components/script/dom/webidls/RTCError.webidl new file mode 100644 index 00000000000..01929f0af5a --- /dev/null +++ b/components/script/dom/webidls/RTCError.webidl @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// https://www.w3.org/TR/webrtc/#dom-rtcerror + +[Exposed=Window] +interface RTCError : DOMException { + constructor(RTCErrorInit init, optional DOMString message = ""); + readonly attribute RTCErrorDetailType errorDetail; + readonly attribute long? sdpLineNumber; + readonly attribute long? httpRequestStatusCode; + readonly attribute long? sctpCauseCode; + readonly attribute unsigned long? receivedAlert; + readonly attribute unsigned long? sentAlert; +}; + +dictionary RTCErrorInit { + required RTCErrorDetailType errorDetail; + long sdpLineNumber; + long httpRequestStatusCode; + long sctpCauseCode; + unsigned long receivedAlert; + unsigned long sentAlert; +}; + +enum RTCErrorDetailType { + "data-channel-failure", + "dtls-failure", + "fingerprint-failure", + "sctp-failure", + "sdp-syntax-error", + "hardware-encoder-not-available", + "hardware-encoder-error" +}; \ No newline at end of file diff --git a/components/script/dom/webidls/RTCErrorEvent.webidl b/components/script/dom/webidls/RTCErrorEvent.webidl new file mode 100644 index 00000000000..1f215d39374 --- /dev/null +++ b/components/script/dom/webidls/RTCErrorEvent.webidl @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + + // https://www.w3.org/TR/webrtc/#rtcerrorevent-interface + +[Exposed=Window] +interface RTCErrorEvent : Event { + constructor(DOMString type, RTCErrorEventInit eventInitDict); + [SameObject] readonly attribute RTCError error; +}; + +dictionary RTCErrorEventInit : EventInit { + required RTCError error; +}; \ No newline at end of file From 5c6dcbf54e77b94e3d7d2cf11a53144ec783a52a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Mon, 1 Jun 2020 12:19:47 +0200 Subject: [PATCH 04/27] Trigger RTCErrorEvent on data channel error --- components/script/dom/rtcdatachannel.rs | 22 ++++++++++++++++++++-- components/script/dom/rtcerror.rs | 2 +- components/script/dom/rtcerrorevent.rs | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index d7388729dbd..a1a0e2075f0 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -5,15 +5,18 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelInit; use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelMethods; +use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::{RTCErrorDetailType, RTCErrorInit}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::str::USVString; +use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::blob::Blob; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::dom::rtcerror::RTCError; +use crate::dom::rtcerrorevent::RTCErrorEvent; use crate::task_source::TaskSource; use dom_struct::dom_struct; use js::rust::CustomAutoRooterGuard; @@ -164,7 +167,22 @@ impl RTCDataChannel { event.upcast::().fire(self.upcast()); } - fn on_error(&self, error: WebRtcError) {} + fn on_error(&self, error: WebRtcError) { + let init = RTCErrorInit { + errorDetail: RTCErrorDetailType::Data_channel_failure, + httpRequestStatusCode: None, + receivedAlert: None, + sctpCauseCode: None, + sdpLineNumber: None, + sentAlert: None, + }; + let message = match error { + WebRtcError::Backend(message) => DOMString::from(message), + }; + let error = RTCError::new(&self.global(), &init, message); + let event = RTCErrorEvent::new(&self.global(), atom!("error"), false, false, &error); + event.upcast::().fire(self.upcast()); + } fn on_message(&self, message: String) {} } diff --git a/components/script/dom/rtcerror.rs b/components/script/dom/rtcerror.rs index db23cd7c096..615cd267c9f 100644 --- a/components/script/dom/rtcerror.rs +++ b/components/script/dom/rtcerror.rs @@ -40,7 +40,7 @@ impl RTCError { } } - fn new(global: &GlobalScope, init: &RTCErrorInit, message: DOMString) -> DomRoot { + pub fn new(global: &GlobalScope, init: &RTCErrorInit, message: DOMString) -> DomRoot { reflect_dom_object( Box::new(RTCError::new_inherited(global, init, message)), global, diff --git a/components/script/dom/rtcerrorevent.rs b/components/script/dom/rtcerrorevent.rs index aeaf361aa58..a647fe8bcbd 100644 --- a/components/script/dom/rtcerrorevent.rs +++ b/components/script/dom/rtcerrorevent.rs @@ -30,7 +30,7 @@ impl RTCErrorEvent { } } - fn new( + pub fn new( global: &GlobalScope, type_: Atom, bubbles: bool, From 82260a9d2b0db1e84bc73664d2dfa6bf5314f562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Mon, 1 Jun 2020 16:28:57 +0200 Subject: [PATCH 05/27] On data channel message handler --- components/script/dom/rtcdatachannel.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index a1a0e2075f0..3b29c0f0a4b 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -15,10 +15,14 @@ use crate::dom::blob::Blob; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::dom::messageevent::MessageEvent; use crate::dom::rtcerror::RTCError; use crate::dom::rtcerrorevent::RTCErrorEvent; use crate::task_source::TaskSource; use dom_struct::dom_struct; +use js::conversions::ToJSValConvertible; +use js::jsapi::JSAutoRealm; +use js::jsval::UndefinedValue; use js::rust::CustomAutoRooterGuard; use js::typedarray::{ArrayBuffer, ArrayBufferView}; use servo_media::webrtc::{ @@ -184,7 +188,26 @@ impl RTCDataChannel { event.upcast::().fire(self.upcast()); } - fn on_message(&self, message: String) {} + #[allow(unsafe_code)] + fn on_message(&self, text: String) { + // XXX(ferjm) Support binary messages + unsafe { + let global = self.global(); + let cx = global.get_cx(); + let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); + rooted!(in(*cx) let mut message = UndefinedValue()); + text.to_jsval(*cx, message.handle_mut()); + + MessageEvent::dispatch_jsval( + self.upcast(), + &global, + message.handle(), + Some(&global.origin().immutable().ascii_serialization()), + None, + vec![], + ); + } + } } impl RTCDataChannelMethods for RTCDataChannel { From 2c5fc3b3c81d862d9f9eab7de11ae4a7b658e2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Mon, 1 Jun 2020 17:08:43 +0200 Subject: [PATCH 06/27] Allow sending strings through data channels --- components/script/dom/rtcdatachannel.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 3b29c0f0a4b..9d51cef77fd 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -274,7 +274,11 @@ impl RTCDataChannelMethods for RTCDataChannel { // fn SetBinaryType(&self, value: DOMString) -> (); // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send - fn Send(&self, data: USVString) -> () {} + fn Send(&self, data: USVString) -> () { + if let Err(error) = self.channel.send(&data.0) { + warn!("Could not send data channel message. Error: {:?}", error); + } + } // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-1 fn Send_(&self, data: &Blob) -> () {} From f5c930087e51df882a65d47950d79954bdf24e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Mon, 1 Jun 2020 19:31:15 +0200 Subject: [PATCH 07/27] Implement ondatachannel event --- components/atoms/static_atoms.txt | 1 + components/script/dom/mod.rs | 1 + components/script/dom/rtcdatachannel.rs | 11 ++- components/script/dom/rtcdatachannelevent.rs | 74 +++++++++++++++++++ components/script/dom/rtcpeerconnection.rs | 41 +++++++++- .../dom/webidls/RTCDataChannelEvent.webidl | 15 ++++ 6 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 components/script/dom/rtcdatachannelevent.rs create mode 100644 components/script/dom/webidls/RTCDataChannelEvent.webidl diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index d4f2f38da7e..b546092a4ac 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -23,6 +23,7 @@ compositionstart compositionupdate controllerchange cursive +datachannel date datetime-local dir diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index e4464d570df..24de0ab650a 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -487,6 +487,7 @@ pub mod readablestream; pub mod request; pub mod response; pub mod rtcdatachannel; +pub mod rtcdatachannelevent; pub mod rtcerror; pub mod rtcerrorevent; pub mod rtcicecandidate; diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 9d51cef77fd..3daa4b0fd85 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -50,6 +50,7 @@ impl RTCDataChannel { webrtc_controller: &DomRefCell>, label: USVString, options: &RTCDataChannelInit, + channel: Option>, ) -> RTCDataChannel { let webrtc = webrtc_controller.borrow(); let webrtc = webrtc.as_ref().unwrap(); @@ -59,8 +60,12 @@ impl RTCDataChannel { let mut init: WebRtcDataChannelInit = options.into(); init.label = label.to_string(); - webrtc.create_data_channel(init, sender); - let channel = receiver.recv().unwrap(); + let channel = if channel.is_none() { + webrtc.create_data_channel(init, sender); + receiver.recv().unwrap() + } else { + channel.unwrap() + }; let rtc_data_channel = RTCDataChannel { eventtarget: EventTarget::new_inherited(), @@ -140,12 +145,14 @@ impl RTCDataChannel { webrtc_controller: &DomRefCell>, label: USVString, options: &RTCDataChannelInit, + channel: Option>, ) -> DomRoot { reflect_dom_object( Box::new(RTCDataChannel::new_inherited( webrtc_controller, label, options, + channel, )), global, ) diff --git a/components/script/dom/rtcdatachannelevent.rs b/components/script/dom/rtcdatachannelevent.rs new file mode 100644 index 00000000000..cd5239eff79 --- /dev/null +++ b/components/script/dom/rtcdatachannelevent.rs @@ -0,0 +1,74 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods; +use crate::dom::bindings::codegen::Bindings::RTCDataChannelEventBinding::RTCDataChannelEventInit; +use crate::dom::bindings::codegen::Bindings::RTCDataChannelEventBinding::RTCDataChannelEventMethods; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; +use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::str::DOMString; +use crate::dom::event::Event; +use crate::dom::globalscope::GlobalScope; +use crate::dom::rtcdatachannel::RTCDataChannel; +use crate::dom::window::Window; +use dom_struct::dom_struct; +use servo_atoms::Atom; + +#[dom_struct] +pub struct RTCDataChannelEvent { + event: Event, + channel: Dom, +} + +impl RTCDataChannelEvent { + fn new_inherited(channel: &RTCDataChannel) -> RTCDataChannelEvent { + RTCDataChannelEvent { + event: Event::new_inherited(), + channel: Dom::from_ref(channel), + } + } + + pub fn new( + global: &GlobalScope, + type_: Atom, + bubbles: bool, + cancelable: bool, + channel: &RTCDataChannel, + ) -> DomRoot { + let event = reflect_dom_object( + Box::new(RTCDataChannelEvent::new_inherited(&channel)), + global, + ); + { + let event = event.upcast::(); + event.init_event(type_, bubbles, cancelable); + } + event + } + + pub fn Constructor( + window: &Window, + type_: DOMString, + init: &RTCDataChannelEventInit, + ) -> DomRoot { + RTCDataChannelEvent::new( + &window.global(), + Atom::from(type_), + init.parent.bubbles, + init.parent.cancelable, + &init.channel, + ) + } +} + +impl RTCDataChannelEventMethods for RTCDataChannelEvent { + fn Channel(&self) -> DomRoot { + DomRoot::from_ref(&*self.channel) + } + + fn IsTrusted(&self) -> bool { + self.event.IsTrusted() + } +} diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 5ce0b109bbd..2e7f05f4873 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -29,6 +29,7 @@ use crate::dom::mediastream::MediaStream; use crate::dom::mediastreamtrack::MediaStreamTrack; use crate::dom::promise::Promise; use crate::dom::rtcdatachannel::RTCDataChannel; +use crate::dom::rtcdatachannelevent::RTCDataChannelEvent; use crate::dom::rtcicecandidate::RTCIceCandidate; use crate::dom::rtcpeerconnectioniceevent::RTCPeerConnectionIceEvent; use crate::dom::rtcsessiondescription::RTCSessionDescription; @@ -44,7 +45,7 @@ use servo_media::streams::registry::MediaStreamId; use servo_media::streams::MediaStreamType; use servo_media::webrtc::{ BundlePolicy, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription, - SignalingState, WebRtcController, WebRtcSignaller, + SignalingState, WebRtcController, WebRtcDataChannelBackend, WebRtcSignaller, }; use servo_media::ServoMedia; @@ -145,6 +146,18 @@ impl WebRtcSignaller for RTCSignaller { ); } + fn on_data_channel(&self, channel: Box) { + // XXX(ferjm) get label and options from channel properties. + let this = self.trusted.clone(); + let _ = self.task_source.queue_with_canceller( + task!(on_data_channel: move || { + let this = this.root(); + this.on_data_channel(channel); + }), + &self.canceller, + ); + } + fn close(&self) { // do nothing } @@ -259,6 +272,24 @@ impl RTCPeerConnection { event.upcast::().fire(self.upcast()); } + fn on_data_channel(&self, channel: Box) { + if self.closed.get() { + return; + } + + let channel = RTCDataChannel::new( + &self.global(), + &self.controller, + USVString::from("".to_owned()), + &RTCDataChannelInit::empty(), + Some(channel), + ); + + let event = + RTCDataChannelEvent::new(&self.global(), atom!("datachannel"), false, false, &channel); + event.upcast::().fire(self.upcast()); + } + /// https://www.w3.org/TR/webrtc/#update-ice-gathering-state fn update_gathering_state(&self, state: GatheringState) { // step 1 @@ -646,7 +677,13 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { label: USVString, dataChannelDict: &RTCDataChannelInit, ) -> DomRoot { - RTCDataChannel::new(&self.global(), &self.controller, label, dataChannelDict) + RTCDataChannel::new( + &self.global(), + &self.controller, + label, + dataChannelDict, + None, + ) } } diff --git a/components/script/dom/webidls/RTCDataChannelEvent.webidl b/components/script/dom/webidls/RTCDataChannelEvent.webidl new file mode 100644 index 00000000000..5b1cde9e723 --- /dev/null +++ b/components/script/dom/webidls/RTCDataChannelEvent.webidl @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + + // https://www.w3.org/TR/webrtc/#rtcdatachannelevent + + [Exposed=Window] +interface RTCDataChannelEvent : Event { + constructor(DOMString type, RTCDataChannelEventInit eventInitDict); + readonly attribute RTCDataChannel channel; +}; + +dictionary RTCDataChannelEventInit : EventInit { + required RTCDataChannel channel; +}; \ No newline at end of file From ace0d7795ec3e9ad1bdadfd1894aacbd0d3676d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 2 Jun 2020 10:28:33 +0200 Subject: [PATCH 08/27] Fix rooting issues with data channels callbacks --- components/script/dom/rtcdatachannel.rs | 137 +++++++++++++----------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 3daa4b0fd85..2b26bf4f8b9 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -45,7 +45,6 @@ pub struct RTCDataChannel { } impl RTCDataChannel { - #[allow(unrooted_must_root)] pub fn new_inherited( webrtc_controller: &DomRefCell>, label: USVString, @@ -67,7 +66,7 @@ impl RTCDataChannel { channel.unwrap() }; - let rtc_data_channel = RTCDataChannel { + RTCDataChannel { eventtarget: EventTarget::new_inherited(), channel, label, @@ -77,67 +76,7 @@ impl RTCDataChannel { protocol: options.protocol.clone(), negotiated: options.negotiated, id: options.id, - }; - - let trusted = Trusted::new(&rtc_data_channel); - - let this = trusted.clone(); - rtc_data_channel.channel.set_on_open(Box::new(move || { - let this_ = this.clone(); - let global = this.root().global(); - let task_source = global.networking_task_source(); - let _ = task_source.queue( - task!(on_open: move || { - this_.root().on_open(); - }), - global.upcast(), - ); - })); - - let this = trusted.clone(); - rtc_data_channel.channel.set_on_close(Box::new(move || { - let this_ = this.clone(); - let global = this.root().global(); - let task_source = global.networking_task_source(); - let _ = task_source.queue( - task!(on_close: move || { - this_.root().on_close(); - }), - global.upcast(), - ); - })); - - let this = trusted.clone(); - rtc_data_channel - .channel - .set_on_error(Box::new(move |error| { - let this_ = this.clone(); - let global = this.root().global(); - let task_source = global.networking_task_source(); - let _ = task_source.queue( - task!(on_error: move || { - this_.root().on_error(error); - }), - global.upcast(), - ); - })); - - let this = trusted.clone(); - rtc_data_channel - .channel - .set_on_message(Box::new(move |message| { - let this_ = this.clone(); - let global = this.root().global(); - let task_source = global.networking_task_source(); - let _ = task_source.queue( - task!(on_message: move || { - this_.root().on_message(message); - }), - global.upcast(), - ); - })); - - rtc_data_channel + } } pub fn new( @@ -147,7 +86,7 @@ impl RTCDataChannel { options: &RTCDataChannelInit, channel: Option>, ) -> DomRoot { - reflect_dom_object( + let rtc_data_channel = reflect_dom_object( Box::new(RTCDataChannel::new_inherited( webrtc_controller, label, @@ -155,7 +94,75 @@ impl RTCDataChannel { channel, )), global, - ) + ); + + let trusted = Trusted::new(&*rtc_data_channel); + let (task_source, canceller) = global + .as_window() + .task_manager() + .networking_task_source_with_canceller(); + + let this = trusted.clone(); + rtc_data_channel.channel.set_on_open(Box::new(move || { + let this = this.clone(); + let _ = task_source.queue_with_canceller( + task!(on_open: move || { + this.root().on_open(); + }), + &canceller, + ); + })); + + let this = trusted.clone(); + let (task_source, canceller) = global + .as_window() + .task_manager() + .networking_task_source_with_canceller(); + rtc_data_channel.channel.set_on_close(Box::new(move || { + let this = this.clone(); + let _ = task_source.queue_with_canceller( + task!(on_close: move || { + this.root().on_close(); + }), + &canceller, + ); + })); + + let this = trusted.clone(); + let (task_source, canceller) = global + .as_window() + .task_manager() + .networking_task_source_with_canceller(); + rtc_data_channel + .channel + .set_on_error(Box::new(move |error| { + let this = this.clone(); + let _ = task_source.queue_with_canceller( + task!(on_error: move || { + this.root().on_error(error); + }), + &canceller, + ); + })); + + let this = trusted.clone(); + let (task_source, canceller) = global + .as_window() + .task_manager() + .networking_task_source_with_canceller(); + rtc_data_channel + .channel + .set_on_message(Box::new(move |message| { + let this = this.clone(); + let _ = task_source.queue_with_canceller( + task!(on_message: move || { + this.root().on_message(message); + }), + &canceller, + ); + })); + + rtc_data_channel } fn on_open(&self) { From 960b010d300503befa9c4469d0ee055908dba923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 2 Jun 2020 10:52:34 +0200 Subject: [PATCH 09/27] Cleanups and tidy fixes --- components/script/dom/rtcdatachannel.rs | 10 +++++----- components/script/dom/rtcdatachannelevent.rs | 3 +++ components/script/dom/rtcerrorevent.rs | 2 ++ components/script/dom/rtcpeerconnection.rs | 10 ++-------- components/script/dom/webidls/RTCDataChannel.webidl | 10 +++++----- .../script/dom/webidls/RTCDataChannelEvent.webidl | 4 ++-- components/script/dom/webidls/RTCError.webidl | 4 ++-- components/script/dom/webidls/RTCErrorEvent.webidl | 4 ++-- 8 files changed, 23 insertions(+), 24 deletions(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 2b26bf4f8b9..24475c22323 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -282,26 +282,26 @@ impl RTCDataChannelMethods for RTCDataChannel { // fn SetBufferedAmountLowThreshold(&self, value: u32) -> (); // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-close - fn Close(&self) -> () {} + fn Close(&self) {} // fn BinaryType(&self) -> DOMString; // fn SetBinaryType(&self, value: DOMString) -> (); // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send - fn Send(&self, data: USVString) -> () { + fn Send(&self, data: USVString) { if let Err(error) = self.channel.send(&data.0) { warn!("Could not send data channel message. Error: {:?}", error); } } // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-1 - fn Send_(&self, data: &Blob) -> () {} + // fn Send_(&self, data: &Blob) -> () {} // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-2 - fn Send__(&self, data: CustomAutoRooterGuard) -> () {} + // fn Send__(&self, data: CustomAutoRooterGuard) -> () {} // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-3 - fn Send___(&self, data: CustomAutoRooterGuard) -> () {} + // fn Send___(&self, data: CustomAutoRooterGuard) -> () {} } impl From<&RTCDataChannelInit> for WebRtcDataChannelInit { diff --git a/components/script/dom/rtcdatachannelevent.rs b/components/script/dom/rtcdatachannelevent.rs index cd5239eff79..95935f68107 100644 --- a/components/script/dom/rtcdatachannelevent.rs +++ b/components/script/dom/rtcdatachannelevent.rs @@ -48,6 +48,7 @@ impl RTCDataChannelEvent { event } + #[allow(non_snake_case)] pub fn Constructor( window: &Window, type_: DOMString, @@ -64,10 +65,12 @@ impl RTCDataChannelEvent { } impl RTCDataChannelEventMethods for RTCDataChannelEvent { + // https://www.w3.org/TR/webrtc/#dom-datachannelevent-channel fn Channel(&self) -> DomRoot { DomRoot::from_ref(&*self.channel) } + // https://dom.spec.whatwg.org/#dom-event-istrusted fn IsTrusted(&self) -> bool { self.event.IsTrusted() } diff --git a/components/script/dom/rtcerrorevent.rs b/components/script/dom/rtcerrorevent.rs index a647fe8bcbd..2d40844423a 100644 --- a/components/script/dom/rtcerrorevent.rs +++ b/components/script/dom/rtcerrorevent.rs @@ -62,10 +62,12 @@ impl RTCErrorEvent { } impl RTCErrorEventMethods for RTCErrorEvent { + // https://www.w3.org/TR/webrtc/#dom-rtcerrorevent-error fn Error(&self) -> DomRoot { DomRoot::from_ref(&*self.error) } + // https://dom.spec.whatwg.org/#dom-event-istrusted fn IsTrusted(&self) -> bool { self.event.IsTrusted() } diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 2e7f05f4873..2e568c7a971 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -675,15 +675,9 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { fn CreateDataChannel( &self, label: USVString, - dataChannelDict: &RTCDataChannelInit, + init: &RTCDataChannelInit, ) -> DomRoot { - RTCDataChannel::new( - &self.global(), - &self.controller, - label, - dataChannelDict, - None, - ) + RTCDataChannel::new(&self.global(), &self.controller, label, init, None) } } diff --git a/components/script/dom/webidls/RTCDataChannel.webidl b/components/script/dom/webidls/RTCDataChannel.webidl index e8a08969e55..910353dbbd3 100644 --- a/components/script/dom/webidls/RTCDataChannel.webidl +++ b/components/script/dom/webidls/RTCDataChannel.webidl @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel +// https://w3c.github.io/webrtc-pc/#dom-rtcdatachannel [Exposed=Window] interface RTCDataChannel : EventTarget { @@ -25,9 +25,9 @@ interface RTCDataChannel : EventTarget { attribute EventHandler onmessage; //attribute DOMString binaryType; void send(USVString data); - void send(Blob data); - void send(ArrayBuffer data); - void send(ArrayBufferView data); + //void send(Blob data); + //void send(ArrayBuffer data); + //void send(ArrayBufferView data); }; // https://www.w3.org/TR/webrtc/#dom-rtcdatachannelinit @@ -46,4 +46,4 @@ enum RTCDataChannelState { "open", "closing", "closed" -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/RTCDataChannelEvent.webidl b/components/script/dom/webidls/RTCDataChannelEvent.webidl index 5b1cde9e723..081ab15db25 100644 --- a/components/script/dom/webidls/RTCDataChannelEvent.webidl +++ b/components/script/dom/webidls/RTCDataChannelEvent.webidl @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - // https://www.w3.org/TR/webrtc/#rtcdatachannelevent +// https://w3c.github.io/webrtc-pc/#dom-rtcdatachannelevent [Exposed=Window] interface RTCDataChannelEvent : Event { @@ -12,4 +12,4 @@ interface RTCDataChannelEvent : Event { dictionary RTCDataChannelEventInit : EventInit { required RTCDataChannel channel; -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/RTCError.webidl b/components/script/dom/webidls/RTCError.webidl index 01929f0af5a..f398c450905 100644 --- a/components/script/dom/webidls/RTCError.webidl +++ b/components/script/dom/webidls/RTCError.webidl @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -// https://www.w3.org/TR/webrtc/#dom-rtcerror +// https://w3c.github.io/webrtc-pc/#dom-rtcerror [Exposed=Window] interface RTCError : DOMException { @@ -32,4 +32,4 @@ enum RTCErrorDetailType { "sdp-syntax-error", "hardware-encoder-not-available", "hardware-encoder-error" -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/RTCErrorEvent.webidl b/components/script/dom/webidls/RTCErrorEvent.webidl index 1f215d39374..9433fc6f579 100644 --- a/components/script/dom/webidls/RTCErrorEvent.webidl +++ b/components/script/dom/webidls/RTCErrorEvent.webidl @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - // https://www.w3.org/TR/webrtc/#rtcerrorevent-interface +// https://w3c.github.io/webrtc-pc/#dom-rtcerrorevent [Exposed=Window] interface RTCErrorEvent : Event { @@ -12,4 +12,4 @@ interface RTCErrorEvent : Event { dictionary RTCErrorEventInit : EventInit { required RTCError error; -}; \ No newline at end of file +}; From 9d456d5d17aebe0c3aae988f6450f9af51573c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Thu, 11 Jun 2020 11:27:58 +0200 Subject: [PATCH 10/27] Use data channel ids --- components/script/dom/bindings/trace.rs | 3 +- components/script/dom/rtcdatachannel.rs | 199 ++++++++------------- components/script/dom/rtcpeerconnection.rs | 90 ++++++++-- 3 files changed, 148 insertions(+), 144 deletions(-) diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 40ec44a62d5..6208a7bc1ba 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -128,7 +128,7 @@ use servo_media::player::video::VideoFrame; use servo_media::player::Player; use servo_media::streams::registry::MediaStreamId; use servo_media::streams::MediaStreamType; -use servo_media::webrtc::{WebRtcController, WebRtcDataChannelBackend}; +use servo_media::webrtc::WebRtcController; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use smallvec::SmallVec; use std::borrow::Cow; @@ -607,7 +607,6 @@ unsafe_no_jsmanaged_fields!(NodeId); unsafe_no_jsmanaged_fields!(AnalysisEngine, DistanceModel, PanningModel, ParamType); unsafe_no_jsmanaged_fields!(Arc>); unsafe_no_jsmanaged_fields!(WebRtcController); -unsafe_no_jsmanaged_fields!(Box); unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType); unsafe_no_jsmanaged_fields!(Mutex); unsafe_no_jsmanaged_fields!(ResourceFetchTiming); diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 24475c22323..4b5aa8eeed2 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -2,39 +2,32 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelInit; use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelMethods; use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::{RTCErrorDetailType, RTCErrorInit}; use crate::dom::bindings::inheritance::Castable; -use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::{DOMString, USVString}; -use crate::dom::blob::Blob; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::messageevent::MessageEvent; use crate::dom::rtcerror::RTCError; use crate::dom::rtcerrorevent::RTCErrorEvent; -use crate::task_source::TaskSource; +use crate::dom::rtcpeerconnection::RTCPeerConnection; use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; use js::jsapi::JSAutoRealm; use js::jsval::UndefinedValue; -use js::rust::CustomAutoRooterGuard; -use js::typedarray::{ArrayBuffer, ArrayBufferView}; -use servo_media::webrtc::{ - WebRtcController, WebRtcDataChannelBackend, WebRtcDataChannelInit, WebRtcError, -}; -use std::sync::mpsc; +use servo_media::webrtc::{DataChannelId, DataChannelInit, DataChannelMessage, WebRtcError}; #[dom_struct] pub struct RTCDataChannel { eventtarget: EventTarget, #[ignore_malloc_size_of = "defined in servo-media"] - channel: Box, + servo_media_id: DataChannelId, + peer_connection: Dom, label: USVString, ordered: bool, max_packet_life_time: Option, @@ -45,30 +38,29 @@ pub struct RTCDataChannel { } impl RTCDataChannel { + #[allow(unrooted_must_root)] pub fn new_inherited( - webrtc_controller: &DomRefCell>, + peer_connection: &RTCPeerConnection, label: USVString, options: &RTCDataChannelInit, - channel: Option>, + servo_media_id: Option, ) -> RTCDataChannel { - let webrtc = webrtc_controller.borrow(); - let webrtc = webrtc.as_ref().unwrap(); - - let (sender, receiver) = mpsc::channel::>(); - - let mut init: WebRtcDataChannelInit = options.into(); + let mut init: DataChannelInit = options.into(); init.label = label.to_string(); - let channel = if channel.is_none() { - webrtc.create_data_channel(init, sender); - receiver.recv().unwrap() - } else { - channel.unwrap() - }; + let controller = peer_connection.get_webrtc_controller().borrow(); + let servo_media_id = servo_media_id.unwrap_or( + controller + .as_ref() + .unwrap() + .create_data_channel(init) + .expect("Expected data channel id"), + ); - RTCDataChannel { + let channel = RTCDataChannel { eventtarget: EventTarget::new_inherited(), - channel, + servo_media_id, + peer_connection: Dom::from_ref(&peer_connection), label, ordered: options.ordered, max_packet_life_time: options.maxPacketLifeTime, @@ -76,96 +68,34 @@ impl RTCDataChannel { protocol: options.protocol.clone(), negotiated: options.negotiated, id: options.id, - } + }; + + peer_connection.register_data_channel(servo_media_id, &channel); + + channel } pub fn new( global: &GlobalScope, - webrtc_controller: &DomRefCell>, + peer_connection: &RTCPeerConnection, label: USVString, options: &RTCDataChannelInit, - channel: Option>, + servo_media_id: Option, ) -> DomRoot { let rtc_data_channel = reflect_dom_object( Box::new(RTCDataChannel::new_inherited( - webrtc_controller, + peer_connection, label, options, - channel, + servo_media_id, )), global, ); - let trusted = Trusted::new(&*rtc_data_channel); - let (task_source, canceller) = global - .as_window() - .task_manager() - .networking_task_source_with_canceller(); - - let this = trusted.clone(); - rtc_data_channel.channel.set_on_open(Box::new(move || { - let this = this.clone(); - let _ = task_source.queue_with_canceller( - task!(on_open: move || { - this.root().on_open(); - }), - &canceller, - ); - })); - - let this = trusted.clone(); - let (task_source, canceller) = global - .as_window() - .task_manager() - .networking_task_source_with_canceller(); - rtc_data_channel.channel.set_on_close(Box::new(move || { - let this = this.clone(); - let _ = task_source.queue_with_canceller( - task!(on_close: move || { - this.root().on_close(); - }), - &canceller, - ); - })); - - let this = trusted.clone(); - let (task_source, canceller) = global - .as_window() - .task_manager() - .networking_task_source_with_canceller(); - rtc_data_channel - .channel - .set_on_error(Box::new(move |error| { - let this = this.clone(); - let _ = task_source.queue_with_canceller( - task!(on_error: move || { - this.root().on_error(error); - }), - &canceller, - ); - })); - - let this = trusted.clone(); - let (task_source, canceller) = global - .as_window() - .task_manager() - .networking_task_source_with_canceller(); - rtc_data_channel - .channel - .set_on_message(Box::new(move |message| { - let this = this.clone(); - let _ = task_source.queue_with_canceller( - task!(on_message: move || { - this.root().on_message(message); - }), - &canceller, - ); - })); - rtc_data_channel } - fn on_open(&self) { + pub fn on_open(&self) { let event = Event::new( &self.global(), atom!("open"), @@ -175,7 +105,7 @@ impl RTCDataChannel { event.upcast::().fire(self.upcast()); } - fn on_close(&self) { + pub fn on_close(&self) { let event = Event::new( &self.global(), atom!("close"), @@ -183,9 +113,12 @@ impl RTCDataChannel { EventCancelable::NotCancelable, ); event.upcast::().fire(self.upcast()); + + self.peer_connection + .unregister_data_channel(&self.servo_media_id); } - fn on_error(&self, error: WebRtcError) { + pub fn on_error(&self, error: WebRtcError) { let init = RTCErrorInit { errorDetail: RTCErrorDetailType::Data_channel_failure, httpRequestStatusCode: None, @@ -203,27 +136,37 @@ impl RTCDataChannel { } #[allow(unsafe_code)] - fn on_message(&self, text: String) { + pub fn on_message(&self, message: DataChannelMessage) { // XXX(ferjm) Support binary messages - unsafe { - let global = self.global(); - let cx = global.get_cx(); - let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); - rooted!(in(*cx) let mut message = UndefinedValue()); - text.to_jsval(*cx, message.handle_mut()); + match message { + DataChannelMessage::Text(text) => unsafe { + let global = self.global(); + let cx = global.get_cx(); + let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); + rooted!(in(*cx) let mut message = UndefinedValue()); + text.to_jsval(*cx, message.handle_mut()); - MessageEvent::dispatch_jsval( - self.upcast(), - &global, - message.handle(), - Some(&global.origin().immutable().ascii_serialization()), - None, - vec![], - ); + MessageEvent::dispatch_jsval( + self.upcast(), + &global, + message.handle(), + Some(&global.origin().immutable().ascii_serialization()), + None, + vec![], + ); + }, + DataChannelMessage::Binary(_) => {}, } } } +impl Drop for RTCDataChannel { + fn drop(&mut self) { + self.peer_connection + .unregister_data_channel(&self.servo_media_id); + } +} + impl RTCDataChannelMethods for RTCDataChannel { // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onopen event_handler!(open, GetOnopen, SetOnopen); @@ -282,16 +225,24 @@ impl RTCDataChannelMethods for RTCDataChannel { // fn SetBufferedAmountLowThreshold(&self, value: u32) -> (); // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-close - fn Close(&self) {} + fn Close(&self) { + let controller = self.peer_connection.get_webrtc_controller().borrow(); + controller + .as_ref() + .unwrap() + .close_data_channel(&self.servo_media_id); + } // fn BinaryType(&self) -> DOMString; // fn SetBinaryType(&self, value: DOMString) -> (); // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send fn Send(&self, data: USVString) { - if let Err(error) = self.channel.send(&data.0) { - warn!("Could not send data channel message. Error: {:?}", error); - } + let controller = self.peer_connection.get_webrtc_controller().borrow(); + controller + .as_ref() + .unwrap() + .send_data_channel_message(&self.servo_media_id, DataChannelMessage::Text(data.0)); } // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-1 @@ -304,9 +255,9 @@ impl RTCDataChannelMethods for RTCDataChannel { // fn Send___(&self, data: CustomAutoRooterGuard) -> () {} } -impl From<&RTCDataChannelInit> for WebRtcDataChannelInit { - fn from(init: &RTCDataChannelInit) -> WebRtcDataChannelInit { - WebRtcDataChannelInit { +impl From<&RTCDataChannelInit> for DataChannelInit { + fn from(init: &RTCDataChannelInit) -> DataChannelInit { + DataChannelInit { label: String::new(), id: init.id, max_packet_life_time: init.maxPacketLifeTime, diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 2e568c7a971..1ec1cc4e337 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -20,7 +20,7 @@ use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::reflector::DomObject; -use crate::dom::bindings::root::{DomRoot, MutNullableDom}; +use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::bindings::str::USVString; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; @@ -44,12 +44,14 @@ use dom_struct::dom_struct; use servo_media::streams::registry::MediaStreamId; use servo_media::streams::MediaStreamType; use servo_media::webrtc::{ - BundlePolicy, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription, - SignalingState, WebRtcController, WebRtcDataChannelBackend, WebRtcSignaller, + BundlePolicy, DataChannelEvent, DataChannelId, GatheringState, IceCandidate, + IceConnectionState, SdpType, SessionDescription, SignalingState, WebRtcController, + WebRtcSignaller, }; use servo_media::ServoMedia; use std::cell::Cell; +use std::collections::HashMap; use std::rc::Rc; #[dom_struct] @@ -70,6 +72,8 @@ pub struct RTCPeerConnection { gathering_state: Cell, ice_connection_state: Cell, signaling_state: Cell, + #[ignore_malloc_size_of = "defined in servo-media"] + data_channels: DomRefCell>>, } struct RTCSignaller { @@ -146,13 +150,18 @@ impl WebRtcSignaller for RTCSignaller { ); } - fn on_data_channel(&self, channel: Box) { + fn on_data_channel_event( + &self, + channel: DataChannelId, + event: DataChannelEvent, + _: &WebRtcController, + ) { // XXX(ferjm) get label and options from channel properties. let this = self.trusted.clone(); let _ = self.task_source.queue_with_canceller( - task!(on_data_channel: move || { + task!(on_data_channel_event: move || { let this = this.root(); - this.on_data_channel(channel); + this.on_data_channel_event(channel, event); }), &self.canceller, ); @@ -160,6 +169,7 @@ impl WebRtcSignaller for RTCSignaller { fn close(&self) { // do nothing + // XXX(ferjm) close all data channels. } } @@ -177,6 +187,7 @@ impl RTCPeerConnection { gathering_state: Cell::new(RTCIceGatheringState::New), ice_connection_state: Cell::new(RTCIceConnectionState::New), signaling_state: Cell::new(RTCSignalingState::Stable), + data_channels: DomRefCell::new(HashMap::new()), } } @@ -215,6 +226,10 @@ impl RTCPeerConnection { Ok(RTCPeerConnection::new(&window.global(), config)) } + pub fn get_webrtc_controller(&self) -> &DomRefCell> { + &self.controller + } + fn make_signaller(&self) -> Box { let trusted = Trusted::new(self); let (task_source, canceller) = self @@ -272,22 +287,61 @@ impl RTCPeerConnection { event.upcast::().fire(self.upcast()); } - fn on_data_channel(&self, channel: Box) { + fn on_data_channel_event(&self, channel_id: DataChannelId, event: DataChannelEvent) { if self.closed.get() { return; } - let channel = RTCDataChannel::new( - &self.global(), - &self.controller, - USVString::from("".to_owned()), - &RTCDataChannelInit::empty(), - Some(channel), - ); + match event { + DataChannelEvent::NewChannel => { + let channel = RTCDataChannel::new( + &self.global(), + &self, + USVString::from("".to_owned()), + &RTCDataChannelInit::empty(), + Some(channel_id), + ); - let event = - RTCDataChannelEvent::new(&self.global(), atom!("datachannel"), false, false, &channel); - event.upcast::().fire(self.upcast()); + self.register_data_channel(channel_id, &channel); + + let event = RTCDataChannelEvent::new( + &self.global(), + atom!("datachannel"), + false, + false, + &channel, + ); + event.upcast::().fire(self.upcast()); + }, + _ => { + if let Some(ref channel) = self.data_channels.borrow().get(&channel_id) { + match event { + DataChannelEvent::Open => channel.on_open(), + DataChannelEvent::Close => channel.on_close(), + DataChannelEvent::Error(error) => channel.on_error(error), + DataChannelEvent::OnMessage(message) => channel.on_message(message), + _ => unreachable!(), + } + } else { + debug_assert!(false, "Got an event for an unregistered data channel"); + } + }, + }; + } + + pub fn register_data_channel(&self, id: DataChannelId, channel: &RTCDataChannel) { + if self + .data_channels + .borrow_mut() + .insert(id, Dom::from_ref(channel)) + .is_none() + { + debug_assert!(false, "Could not register data channel"); + } + } + + pub fn unregister_data_channel(&self, id: &DataChannelId) { + self.data_channels.borrow_mut().remove(&id); } /// https://www.w3.org/TR/webrtc/#update-ice-gathering-state @@ -677,7 +731,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { label: USVString, init: &RTCDataChannelInit, ) -> DomRoot { - RTCDataChannel::new(&self.global(), &self.controller, label, init, None) + RTCDataChannel::new(&self.global(), &self, label, init, None) } } From 7db485aeb22ea9dffa122c5ab3ff1ccc4659ece5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Thu, 11 Jun 2020 12:07:55 +0200 Subject: [PATCH 11/27] RTCDataChannel.readyState getter --- components/atoms/static_atoms.txt | 1 + components/script/dom/rtcdatachannel.rs | 45 ++++++++++++++++++- components/script/dom/rtcpeerconnection.rs | 3 +- .../script/dom/webidls/RTCDataChannel.webidl | 2 +- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index b546092a4ac..a21efef4ff4 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -16,6 +16,7 @@ characteristicvaluechanged checkbox click close +closing color complete compositionend diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 4b5aa8eeed2..75d8d48ccd8 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -2,8 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelInit; use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelMethods; +use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelState; use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::{RTCErrorDetailType, RTCErrorInit}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; @@ -20,7 +22,9 @@ use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; use js::jsapi::JSAutoRealm; use js::jsval::UndefinedValue; -use servo_media::webrtc::{DataChannelId, DataChannelInit, DataChannelMessage, WebRtcError}; +use servo_media::webrtc::{ + DataChannelId, DataChannelInit, DataChannelMessage, DataChannelState, WebRtcError, +}; #[dom_struct] pub struct RTCDataChannel { @@ -35,6 +39,7 @@ pub struct RTCDataChannel { protocol: USVString, negotiated: bool, id: Option, + ready_state: DomRefCell, } impl RTCDataChannel { @@ -68,6 +73,7 @@ impl RTCDataChannel { protocol: options.protocol.clone(), negotiated: options.negotiated, id: options.id, + ready_state: DomRefCell::new(RTCDataChannelState::Connecting), }; peer_connection.register_data_channel(servo_media_id, &channel); @@ -158,6 +164,22 @@ impl RTCDataChannel { DataChannelMessage::Binary(_) => {}, } } + + pub fn on_state_change(&self, state: DataChannelState) { + match state { + DataChannelState::Closing => { + let event = Event::new( + &self.global(), + atom!("closing"), + EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, + ); + event.upcast::().fire(self.upcast()); + }, + _ => {}, + }; + *self.ready_state.borrow_mut() = state.into(); + } } impl Drop for RTCDataChannel { @@ -219,7 +241,13 @@ impl RTCDataChannelMethods for RTCDataChannel { self.id } - // fn ReadyState(&self) -> RTCDataChannelState; + fn ReadyState(&self) -> RTCDataChannelState { + *self.ready_state.borrow() + } + + // XXX We need a way to know when the underlying data transport + // actually sends data from its queue to decrease buffered amount. + // fn BufferedAmount(&self) -> u32; // fn BufferedAmountLowThreshold(&self) -> u32; // fn SetBufferedAmountLowThreshold(&self, value: u32) -> (); @@ -268,3 +296,16 @@ impl From<&RTCDataChannelInit> for DataChannelInit { } } } + +impl From for RTCDataChannelState { + fn from(state: DataChannelState) -> RTCDataChannelState { + match state { + DataChannelState::New | + DataChannelState::Connecting | + DataChannelState::__Unknown(_) => RTCDataChannelState::Connecting, + DataChannelState::Open => RTCDataChannelState::Open, + DataChannelState::Closing => RTCDataChannelState::Closing, + DataChannelState::Closed => RTCDataChannelState::Closed, + } + } +} diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 1ec1cc4e337..7ffbe5c72a7 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -320,7 +320,8 @@ impl RTCPeerConnection { DataChannelEvent::Close => channel.on_close(), DataChannelEvent::Error(error) => channel.on_error(error), DataChannelEvent::OnMessage(message) => channel.on_message(message), - _ => unreachable!(), + DataChannelEvent::StateChange(state) => channel.on_state_change(state), + DataChannelEvent::NewChannel => unreachable!(), } } else { debug_assert!(false, "Got an event for an unregistered data channel"); diff --git a/components/script/dom/webidls/RTCDataChannel.webidl b/components/script/dom/webidls/RTCDataChannel.webidl index 910353dbbd3..8de4986750f 100644 --- a/components/script/dom/webidls/RTCDataChannel.webidl +++ b/components/script/dom/webidls/RTCDataChannel.webidl @@ -13,7 +13,7 @@ interface RTCDataChannel : EventTarget { readonly attribute USVString protocol; readonly attribute boolean negotiated; readonly attribute unsigned short? id; - //readonly attribute RTCDataChannelState readyState; + readonly attribute RTCDataChannelState readyState; //readonly attribute unsigned long bufferedAmount; //attribute unsigned long bufferedAmountLowThreshold; attribute EventHandler onopen; From f855fbb60411ff598b54d292ba34435b4903eacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Thu, 11 Jun 2020 16:58:02 +0200 Subject: [PATCH 12/27] Allow sending binary messages --- components/script/dom/rtcdatachannel.rs | 54 +++++++++++++++---- .../script/dom/webidls/RTCDataChannel.webidl | 8 +-- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 75d8d48ccd8..ea2452dbc5e 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -7,10 +7,12 @@ use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChann use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelMethods; use crate::dom::bindings::codegen::Bindings::RTCDataChannelBinding::RTCDataChannelState; use crate::dom::bindings::codegen::Bindings::RTCErrorBinding::{RTCErrorDetailType, RTCErrorInit}; +use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::{DOMString, USVString}; +use crate::dom::blob::Blob; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; @@ -22,6 +24,8 @@ use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; use js::jsapi::JSAutoRealm; use js::jsval::UndefinedValue; +use js::rust::CustomAutoRooterGuard; +use js::typedarray::{ArrayBuffer, ArrayBufferView}; use servo_media::webrtc::{ DataChannelId, DataChannelInit, DataChannelMessage, DataChannelState, WebRtcError, }; @@ -180,6 +184,29 @@ impl RTCDataChannel { }; *self.ready_state.borrow_mut() = state.into(); } + + fn send(&self, source: &SendSource) -> Fallible<()> { + if *self.ready_state.borrow() != RTCDataChannelState::Open { + return Err(Error::InvalidState); + } + + let message = match source { + SendSource::String(string) => DataChannelMessage::Text(string.0.clone()), + SendSource::Blob(blob) => { + DataChannelMessage::Binary(blob.get_bytes().unwrap_or(vec![])) + }, + SendSource::ArrayBuffer(array) => DataChannelMessage::Binary(array.to_vec()), + SendSource::ArrayBufferView(array) => DataChannelMessage::Binary(array.to_vec()), + }; + + let controller = self.peer_connection.get_webrtc_controller().borrow(); + controller + .as_ref() + .unwrap() + .send_data_channel_message(&self.servo_media_id, message); + + Ok(()) + } } impl Drop for RTCDataChannel { @@ -189,6 +216,13 @@ impl Drop for RTCDataChannel { } } +enum SendSource<'a, 'b> { + String(&'a USVString), + Blob(&'a Blob), + ArrayBuffer(CustomAutoRooterGuard<'b, ArrayBuffer>), + ArrayBufferView(CustomAutoRooterGuard<'b, ArrayBufferView>), +} + impl RTCDataChannelMethods for RTCDataChannel { // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onopen event_handler!(open, GetOnopen, SetOnopen); @@ -265,22 +299,24 @@ impl RTCDataChannelMethods for RTCDataChannel { // fn SetBinaryType(&self, value: DOMString) -> (); // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send - fn Send(&self, data: USVString) { - let controller = self.peer_connection.get_webrtc_controller().borrow(); - controller - .as_ref() - .unwrap() - .send_data_channel_message(&self.servo_media_id, DataChannelMessage::Text(data.0)); + fn Send(&self, data: USVString) -> Fallible<()> { + self.send(&SendSource::String(&data)) } // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-1 - // fn Send_(&self, data: &Blob) -> () {} + fn Send_(&self, data: &Blob) -> Fallible<()> { + self.send(&SendSource::Blob(data)) + } // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-2 - // fn Send__(&self, data: CustomAutoRooterGuard) -> () {} + fn Send__(&self, data: CustomAutoRooterGuard) -> Fallible<()> { + self.send(&SendSource::ArrayBuffer(data)) + } // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-3 - // fn Send___(&self, data: CustomAutoRooterGuard) -> () {} + fn Send___(&self, data: CustomAutoRooterGuard) -> Fallible<()> { + self.send(&SendSource::ArrayBufferView(data)) + } } impl From<&RTCDataChannelInit> for DataChannelInit { diff --git a/components/script/dom/webidls/RTCDataChannel.webidl b/components/script/dom/webidls/RTCDataChannel.webidl index 8de4986750f..df1053b13c1 100644 --- a/components/script/dom/webidls/RTCDataChannel.webidl +++ b/components/script/dom/webidls/RTCDataChannel.webidl @@ -24,10 +24,10 @@ interface RTCDataChannel : EventTarget { void close(); attribute EventHandler onmessage; //attribute DOMString binaryType; - void send(USVString data); - //void send(Blob data); - //void send(ArrayBuffer data); - //void send(ArrayBufferView data); + [Throws] void send(USVString data); + [Throws] void send(Blob data); + [Throws] void send(ArrayBuffer data); + [Throws] void send(ArrayBufferView data); }; // https://www.w3.org/TR/webrtc/#dom-rtcdatachannelinit From 2dedcaeaaf050b347cc64fdd6681db879926b78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Thu, 11 Jun 2020 18:59:34 +0200 Subject: [PATCH 13/27] Allow receiving binary data channel messages --- components/script/dom/rtcdatachannel.rs | 81 +++++++++++++------ .../script/dom/webidls/RTCDataChannel.webidl | 2 +- 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index ea2452dbc5e..80d543f0441 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -22,13 +22,15 @@ use crate::dom::rtcerrorevent::RTCErrorEvent; use crate::dom::rtcpeerconnection::RTCPeerConnection; use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; -use js::jsapi::JSAutoRealm; +use js::jsapi::{JSAutoRealm, JSObject}; use js::jsval::UndefinedValue; use js::rust::CustomAutoRooterGuard; -use js::typedarray::{ArrayBuffer, ArrayBufferView}; +use js::typedarray::{ArrayBuffer, ArrayBufferView, CreateWith}; +use script_traits::serializable::BlobImpl; use servo_media::webrtc::{ DataChannelId, DataChannelInit, DataChannelMessage, DataChannelState, WebRtcError, }; +use std::ptr; #[dom_struct] pub struct RTCDataChannel { @@ -44,6 +46,7 @@ pub struct RTCDataChannel { negotiated: bool, id: Option, ready_state: DomRefCell, + binary_type: DomRefCell, } impl RTCDataChannel { @@ -78,6 +81,7 @@ impl RTCDataChannel { negotiated: options.negotiated, id: options.id, ready_state: DomRefCell::new(RTCDataChannelState::Connecting), + binary_type: DomRefCell::new(DOMString::from("blob")), }; peer_connection.register_data_channel(servo_media_id, &channel); @@ -146,26 +150,46 @@ impl RTCDataChannel { } #[allow(unsafe_code)] - pub fn on_message(&self, message: DataChannelMessage) { - // XXX(ferjm) Support binary messages - match message { - DataChannelMessage::Text(text) => unsafe { - let global = self.global(); - let cx = global.get_cx(); - let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); - rooted!(in(*cx) let mut message = UndefinedValue()); - text.to_jsval(*cx, message.handle_mut()); + pub fn on_message(&self, channel_message: DataChannelMessage) { + unsafe { + let global = self.global(); + let cx = global.get_cx(); + let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); + rooted!(in(*cx) let mut message = UndefinedValue()); - MessageEvent::dispatch_jsval( - self.upcast(), - &global, - message.handle(), - Some(&global.origin().immutable().ascii_serialization()), - None, - vec![], - ); - }, - DataChannelMessage::Binary(_) => {}, + match channel_message { + DataChannelMessage::Text(text) => { + text.to_jsval(*cx, message.handle_mut()); + }, + DataChannelMessage::Binary(data) => match &**self.binary_type.borrow() { + "blob" => { + let blob = + Blob::new(&global, BlobImpl::new_from_bytes(data, "".to_owned())); + blob.to_jsval(*cx, message.handle_mut()); + }, + "arraybuffer" => { + rooted!(in(*cx) let mut array_buffer = ptr::null_mut::()); + assert!(ArrayBuffer::create( + *cx, + CreateWith::Slice(&data), + array_buffer.handle_mut() + ) + .is_ok()); + + (*array_buffer).to_jsval(*cx, message.handle_mut()); + }, + _ => unreachable!(), + }, + } + + MessageEvent::dispatch_jsval( + self.upcast(), + &global, + message.handle(), + Some(&global.origin().immutable().ascii_serialization()), + None, + vec![], + ); } } @@ -295,8 +319,19 @@ impl RTCDataChannelMethods for RTCDataChannel { .close_data_channel(&self.servo_media_id); } - // fn BinaryType(&self) -> DOMString; - // fn SetBinaryType(&self, value: DOMString) -> (); + // https://www.w3.org/TR/webrtc/#dom-datachannel-binarytype + fn BinaryType(&self) -> DOMString { + self.binary_type.borrow().clone() + } + + // https://www.w3.org/TR/webrtc/#dom-datachannel-binarytype + fn SetBinaryType(&self, value: DOMString) -> Fallible<()> { + if value != "blob" || value != "arraybuffer" { + return Err(Error::Syntax); + } + *self.binary_type.borrow_mut() = value; + Ok(()) + } // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send fn Send(&self, data: USVString) -> Fallible<()> { diff --git a/components/script/dom/webidls/RTCDataChannel.webidl b/components/script/dom/webidls/RTCDataChannel.webidl index df1053b13c1..7dd195c7cdd 100644 --- a/components/script/dom/webidls/RTCDataChannel.webidl +++ b/components/script/dom/webidls/RTCDataChannel.webidl @@ -23,7 +23,7 @@ interface RTCDataChannel : EventTarget { attribute EventHandler onclose; void close(); attribute EventHandler onmessage; - //attribute DOMString binaryType; + [SetterThrows] attribute DOMString binaryType; [Throws] void send(USVString data); [Throws] void send(Blob data); [Throws] void send(ArrayBuffer data); From 820ea452e78cda3e0a7c866d21bf675e34852367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Fri, 12 Jun 2020 15:58:23 +0200 Subject: [PATCH 14/27] Set data channels as closed on peer connection close --- components/script/dom/rtcdatachannel.rs | 8 ++++++-- components/script/dom/rtcpeerconnection.rs | 12 ++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 80d543f0441..c0a3db51cc4 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -133,6 +133,9 @@ impl RTCDataChannel { } pub fn on_error(&self, error: WebRtcError) { + let global = self.global(); + let cx = global.get_cx(); + let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); let init = RTCErrorInit { errorDetail: RTCErrorDetailType::Data_channel_failure, httpRequestStatusCode: None, @@ -144,8 +147,8 @@ impl RTCDataChannel { let message = match error { WebRtcError::Backend(message) => DOMString::from(message), }; - let error = RTCError::new(&self.global(), &init, message); - let event = RTCErrorEvent::new(&self.global(), atom!("error"), false, false, &error); + let error = RTCError::new(&global, &init, message); + let event = RTCErrorEvent::new(&global, atom!("error"), false, false, &error); event.upcast::().fire(self.upcast()); } @@ -299,6 +302,7 @@ impl RTCDataChannelMethods for RTCDataChannel { self.id } + // https://www.w3.org/TR/webrtc/#dom-datachannel-readystate fn ReadyState(&self) -> RTCDataChannelState { *self.ready_state.borrow() } diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 7ffbe5c72a7..348fef25256 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -44,7 +44,7 @@ use dom_struct::dom_struct; use servo_media::streams::registry::MediaStreamId; use servo_media::streams::MediaStreamType; use servo_media::webrtc::{ - BundlePolicy, DataChannelEvent, DataChannelId, GatheringState, IceCandidate, + BundlePolicy, DataChannelEvent, DataChannelId, DataChannelState, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription, SignalingState, WebRtcController, WebRtcSignaller, }; @@ -169,7 +169,6 @@ impl WebRtcSignaller for RTCSignaller { fn close(&self) { // do nothing - // XXX(ferjm) close all data channels. } } @@ -716,8 +715,13 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { // 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 6 + for (_, val) in self.data_channels.borrow().iter() { + val.on_state_change(DataChannelState::Closed); + } + + // Step 7-10 + // (no current support for transports, etc) // Step 11 self.ice_connection_state.set(RTCIceConnectionState::Closed); From db0b9eee983a1d972f9777fafdee8abb5674fb8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 16 Jun 2020 11:04:53 +0200 Subject: [PATCH 15/27] Update gstreamer-webrtc --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 554369dd6b9..1c685ed3f5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2294,9 +2294,9 @@ dependencies = [ [[package]] name = "gstreamer-webrtc" -version = "0.15.0" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64235af90676896b01f3cbe50808fefaf498057ca288ce4a31a89de81464e04" +checksum = "1f433d1294266fb1d65e1dc2d4de365f7f4caf23cb72db3a3bd6904eeec88cf1" dependencies = [ "glib", "glib-sys", From 51a9438b62af2931d0585e11ade2533b5e63870d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 16 Jun 2020 12:03:28 +0200 Subject: [PATCH 16/27] Add 1.16 feature to gstreamer --- components/servo/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index 2b52339e628..1d13db8c4e1 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -55,7 +55,7 @@ euclid = "0.20" gfx = { path = "../gfx" } gfx_traits = { path = "../gfx_traits" } gleam = "0.11" -gstreamer = { version = "0.15", optional = true } +gstreamer = { version = "0.15", features = ["v1_16"], optional = true } ipc-channel = "0.14" keyboard-types = "0.4" layout_thread_2013 = { path = "../layout_thread", optional = true } From 9ee349dee9230502fd92d96763e01894549b2316 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 16 Jun 2020 15:04:53 -0400 Subject: [PATCH 17/27] Remove gstreamer installation from docker. --- etc/taskcluster/docker/build.dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/etc/taskcluster/docker/build.dockerfile b/etc/taskcluster/docker/build.dockerfile index c9cdc0b9503..14f24ae4d8c 100644 --- a/etc/taskcluster/docker/build.dockerfile +++ b/etc/taskcluster/docker/build.dockerfile @@ -25,9 +25,6 @@ RUN \ llvm \ llvm-dev \ # - # GStreamer - libgstreamer-plugins-bad1.0-dev \ - # # OpenSSL libssl-dev \ # From 57699d87df6d11b3fd891acf49d8f971ae6dac31 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 16 Jun 2020 16:29:05 -0400 Subject: [PATCH 18/27] Install libpcre on CI. --- etc/taskcluster/docker/build.dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/taskcluster/docker/build.dockerfile b/etc/taskcluster/docker/build.dockerfile index 14f24ae4d8c..5e6966e0885 100644 --- a/etc/taskcluster/docker/build.dockerfile +++ b/etc/taskcluster/docker/build.dockerfile @@ -24,6 +24,8 @@ RUN \ clang \ llvm \ llvm-dev \ + # GStreamer + libpcre \ # # OpenSSL libssl-dev \ From cbdf95eb34efa7cdedb7a374b772eecec12e0232 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 16 Jun 2020 16:41:41 -0400 Subject: [PATCH 19/27] Use correct package name. --- etc/taskcluster/docker/build.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/taskcluster/docker/build.dockerfile b/etc/taskcluster/docker/build.dockerfile index 5e6966e0885..4d2187c5fa7 100644 --- a/etc/taskcluster/docker/build.dockerfile +++ b/etc/taskcluster/docker/build.dockerfile @@ -25,7 +25,7 @@ RUN \ llvm \ llvm-dev \ # GStreamer - libpcre \ + libpcre3 \ # # OpenSSL libssl-dev \ From 9506fb63f59483b503ef01c93805ff8f946321e7 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 16 Jun 2020 17:31:20 -0400 Subject: [PATCH 20/27] Use a more correct package name. --- etc/taskcluster/docker/build.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/taskcluster/docker/build.dockerfile b/etc/taskcluster/docker/build.dockerfile index 4d2187c5fa7..e05240d4f12 100644 --- a/etc/taskcluster/docker/build.dockerfile +++ b/etc/taskcluster/docker/build.dockerfile @@ -25,7 +25,7 @@ RUN \ llvm \ llvm-dev \ # GStreamer - libpcre3 \ + libpcre3-dev \ # # OpenSSL libssl-dev \ From a6a00d5e65ca5f10a6ae159de8e1b40a52d9ba4b Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 17 Jun 2020 10:38:15 -0400 Subject: [PATCH 21/27] Use newer Ubuntu docker image. --- etc/taskcluster/docker/base.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/taskcluster/docker/base.dockerfile b/etc/taskcluster/docker/base.dockerfile index 2598bb65d24..90459eaa664 100644 --- a/etc/taskcluster/docker/base.dockerfile +++ b/etc/taskcluster/docker/base.dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:bionic-20200403 +FROM ubuntu:eoan-20200608 ENV \ # From b968852456abba89cc1ec55fc467858f91c9b319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Thu, 18 Jun 2020 10:38:45 +0200 Subject: [PATCH 22/27] Do not register data channel twice --- components/script/dom/rtcpeerconnection.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 348fef25256..c92233b59bf 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -301,8 +301,6 @@ impl RTCPeerConnection { Some(channel_id), ); - self.register_data_channel(channel_id, &channel); - let event = RTCDataChannelEvent::new( &self.global(), atom!("datachannel"), @@ -334,9 +332,9 @@ impl RTCPeerConnection { .data_channels .borrow_mut() .insert(id, Dom::from_ref(channel)) - .is_none() + .is_some() { - debug_assert!(false, "Could not register data channel"); + debug_assert!(false, "Data channel already registered"); } } From 7eb44f81f21551ee4c81d1cf62976fed2979c9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Mon, 22 Jun 2020 16:25:39 +0200 Subject: [PATCH 23/27] Fix data channels borrowing errors --- components/script/dom/rtcdatachannel.rs | 11 ++++++----- components/script/dom/rtcpeerconnection.rs | 21 ++++++++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index c0a3db51cc4..7cf42b0f5fc 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -30,6 +30,7 @@ use script_traits::serializable::BlobImpl; use servo_media::webrtc::{ DataChannelId, DataChannelInit, DataChannelMessage, DataChannelState, WebRtcError, }; +use std::cell::Cell; use std::ptr; #[dom_struct] @@ -45,7 +46,7 @@ pub struct RTCDataChannel { protocol: USVString, negotiated: bool, id: Option, - ready_state: DomRefCell, + ready_state: Cell, binary_type: DomRefCell, } @@ -80,7 +81,7 @@ impl RTCDataChannel { protocol: options.protocol.clone(), negotiated: options.negotiated, id: options.id, - ready_state: DomRefCell::new(RTCDataChannelState::Connecting), + ready_state: Cell::new(RTCDataChannelState::Connecting), binary_type: DomRefCell::new(DOMString::from("blob")), }; @@ -209,11 +210,11 @@ impl RTCDataChannel { }, _ => {}, }; - *self.ready_state.borrow_mut() = state.into(); + self.ready_state.set(state.into()); } fn send(&self, source: &SendSource) -> Fallible<()> { - if *self.ready_state.borrow() != RTCDataChannelState::Open { + if self.ready_state.get() != RTCDataChannelState::Open { return Err(Error::InvalidState); } @@ -304,7 +305,7 @@ impl RTCDataChannelMethods for RTCDataChannel { // https://www.w3.org/TR/webrtc/#dom-datachannel-readystate fn ReadyState(&self) -> RTCDataChannelState { - *self.ready_state.borrow() + self.ready_state.get() } // XXX We need a way to know when the underlying data transport diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index c92233b59bf..5d84b155216 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -311,17 +311,20 @@ impl RTCPeerConnection { event.upcast::().fire(self.upcast()); }, _ => { - if let Some(ref channel) = self.data_channels.borrow().get(&channel_id) { - match event { - DataChannelEvent::Open => channel.on_open(), - DataChannelEvent::Close => channel.on_close(), - DataChannelEvent::Error(error) => channel.on_error(error), - DataChannelEvent::OnMessage(message) => channel.on_message(message), - DataChannelEvent::StateChange(state) => channel.on_state_change(state), - DataChannelEvent::NewChannel => unreachable!(), - } + let channel = if let Some(channel) = self.data_channels.borrow().get(&channel_id) { + DomRoot::from_ref(&**channel) } else { debug_assert!(false, "Got an event for an unregistered data channel"); + return; + }; + + match event { + DataChannelEvent::Open => channel.on_open(), + DataChannelEvent::Close => channel.on_close(), + DataChannelEvent::Error(error) => channel.on_error(error), + DataChannelEvent::OnMessage(message) => channel.on_message(message), + DataChannelEvent::StateChange(state) => channel.on_state_change(state), + DataChannelEvent::NewChannel => unreachable!(), } }, }; From 6ebb73d9a42cc8c703b79a8fcbf76f4c56e1b5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Mon, 22 Jun 2020 17:10:22 +0200 Subject: [PATCH 24/27] Fix rooting issue --- components/script/dom/rtcdatachannel.rs | 4 ++-- components/script/dom/rtcpeerconnection.rs | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 7cf42b0f5fc..052f3f13131 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -85,8 +85,6 @@ impl RTCDataChannel { binary_type: DomRefCell::new(DOMString::from("blob")), }; - peer_connection.register_data_channel(servo_media_id, &channel); - channel } @@ -107,6 +105,8 @@ impl RTCDataChannel { global, ); + peer_connection.register_data_channel(rtc_data_channel.servo_media_id, &*rtc_data_channel); + rtc_data_channel } diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 5d84b155216..bd4ac712c96 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -35,7 +35,7 @@ use crate::dom::rtcpeerconnectioniceevent::RTCPeerConnectionIceEvent; use crate::dom::rtcsessiondescription::RTCSessionDescription; use crate::dom::rtctrackevent::RTCTrackEvent; use crate::dom::window::Window; -use crate::realms::InRealm; +use crate::realms::{enter_realm, InRealm}; use crate::task::TaskCanceller; use crate::task_source::networking::NetworkingTaskSource; use crate::task_source::TaskSource; @@ -161,6 +161,8 @@ impl WebRtcSignaller for RTCSignaller { let _ = self.task_source.queue_with_canceller( task!(on_data_channel_event: move || { let this = this.root(); + let global = this.global(); + let _ac = enter_realm(&*global); this.on_data_channel_event(channel, event); }), &self.canceller, @@ -314,7 +316,10 @@ impl RTCPeerConnection { let channel = if let Some(channel) = self.data_channels.borrow().get(&channel_id) { DomRoot::from_ref(&**channel) } else { - debug_assert!(false, "Got an event for an unregistered data channel"); + warn!( + "Got an event for an unregistered data channel {:?}", + channel_id + ); return; }; @@ -337,7 +342,7 @@ impl RTCPeerConnection { .insert(id, Dom::from_ref(channel)) .is_some() { - debug_assert!(false, "Data channel already registered"); + warn!("Data channel already registered {:?}", id); } } From a4f1bc2efc36aa90cfc82a7a02b7b22a12bab667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 30 Jun 2020 11:05:25 +0200 Subject: [PATCH 25/27] Update test expectations --- .../mime-types/canPlayType.html.ini | 7 ++++--- .../k-rate-biquad-connection.html.ini | 15 +++++++++++++++ ...TargetAtTime-after-event-within-block.html.ini | 3 --- .../setValueAtTime-within-block.html.ini | 3 --- .../detune-limiting.html.ini | 3 +++ tests/wpt/mozilla/meta/MANIFEST.json | 2 +- 6 files changed, 23 insertions(+), 10 deletions(-) delete mode 100644 tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html.ini delete mode 100644 tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/setValueAtTime-within-block.html.ini diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini index acc60d48f6a..792579fabfa 100644 --- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini +++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html.ini @@ -41,9 +41,6 @@ [video/mp4; codecs="avc1.4D401E" (optional)] expected: FAIL - [audio/wav; codecs="1" (optional)] - expected: FAIL - [audio/wav (optional)] expected: FAIL @@ -76,3 +73,7 @@ [video/3gpp; codecs="mp4v.20.8" (optional)] expected: FAIL + + [audio/wav with and without codecs] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad-connection.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad-connection.html.ini index b145905f63e..1a72a00be27 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad-connection.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/k-rate-biquad-connection.html.ini @@ -38,3 +38,18 @@ [X k-rate detune with input: output[0,2048\] does not equal [0,0.12810896337032318,0.47732436656951904,0.8133140802383423,0.9599840044975281,0.9983929991722107,0.9618627429008484,0.8107287883758545,0.5545527338981628,0.24036024510860443,-0.09643325209617615,-0.424831748008728,-0.7066475749015808,-0.9075677990913391,-1.0057729482650757,-0.9910215139389038...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[128\]\t-9.0901952981948853e-1\t-8.0834698677062988e-1\t1.0067254304885864e-1\t1.2454124861781007e-1\t0.0000000000000000e+0\n\t[129\]\t-8.0550211668014526e-1\t-5.6012439727783203e-1\t2.4537771940231323e-1\t4.3807718534460011e-1\t0.0000000000000000e+0\n\t[130\]\t-6.2269222736358643e-1\t-2.4871249496936798e-1\t3.7397973239421844e-1\t1.5036628233747511e+0\t0.0000000000000000e+0\n\t[131\]\t-3.5228535532951355e-1\t9.0757519006729126e-2\t4.4304287433624268e-1\t4.8816106828944248e+0\t0.0000000000000000e+0\n\t[132\]\t-1.3693822547793388e-2\t4.1998896002769470e-1\t4.3368278257548809e-1\t1.0326051964482361e+0\t0.0000000000000000e+0\n\t...and 1915 more errors.\n\tMax AbsError of 2.1426951885223389e+0 at index of 391.\n\t[391\]\t6.9794428348541260e-1\t-1.4447509050369263e+0\t2.1426951885223389e+0\t1.4830897015202589e+0\t0.0000000000000000e+0\n\tMax RelError of 2.4604596714524988e+2 at index of 272.\n\t[272\]\t9.5641678571701050e-1\t-3.9030096959322691e-3\t9.6031979541294277e-1\t2.4604596714524988e+2\t0.0000000000000000e+0\n] expected: FAIL + [X k-rate detune with input: output[2048:\] does not equal [-0.5481402277946472,-0.548226535320282,-0.548312246799469,-0.5483972430229187,-0.5484814047813416,-0.5485645532608032,-0.5486468076705933,-0.5487281680107117,-0.5488086938858032,-0.5488886833190918,-0.5489681363105774,-0.5490474104881287,-0.5491266250610352,-0.5492058992385864,-0.5492852926254272,-0.5493649244308472...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[0\]\t3.0815025093033910e-4\t-5.4814022779464722e-1\t5.4844837804557756e-1\t1.0005621741213377e+0\t0.0000000000000000e+0\n\t[1\]\t2.8959600604139268e-4\t-5.4822653532028198e-1\t5.4851613132632338e-1\t1.0005282414975996e+0\t0.0000000000000000e+0\n\t[2\]\t2.7124350890517235e-4\t-5.4831224679946899e-1\t5.4858349030837417e-1\t1.0004946880367682e+0\t0.0000000000000000e+0\n\t[3\]\t2.5326051400043070e-4\t-5.4839724302291870e-1\t5.4865050353691913e-1\t1.0004618194515429e+0\t0.0000000000000000e+0\n\t[4\]\t2.3577432148158550e-4\t-5.4848140478134155e-1\t5.4871717910282314e-1\t1.0004298674839771e+0\t0.0000000000000000e+0\n\t...and 2043 more errors.\n\tMax AbsError of 5.5494356551207602e-1 at index of 195.\n\t[195\]\t-2.7666052337735891e-3\t-5.5771017074584961e-1\t5.5494356551207602e-1\t9.9503934950644046e-1\t0.0000000000000000e+0\n\tMax RelError of 1.0005621741213377e+0 at index of 0.\n] + expected: FAIL + + [X All k-rate AudioParams does not equal [0,0.3311063051223755,0.6248595118522644,0.8481203317642212,0.9757021069526672,0.9932119250297546,0.8986744284629822,0.7027547359466553,0.42755505442619324,0.1041216030716896,-0.23105813562870026,-0.5401715040206909,-0.7883464694023132,-0.9475855827331543,-0.9999247193336487,-0.9394592046737671...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[640\]\t8.2034111022949219e-1\t7.7920007705688477e-1\t4.1141033172607422e-2\t5.2799061991884222e-2\t0.0000000000000000e+0\n\t[641\]\t5.5707097053527832e-1\t4.6239438652992249e-1\t9.4676584005355835e-2\t2.0475288360627431e-1\t0.0000000000000000e+0\n\t[642\]\t2.5545451045036316e-1\t1.8853309750556946e-1\t6.6921412944793701e-2\t3.5495843345392858e-1\t0.0000000000000000e+0\n\t[643\]\t-6.9336682558059692e-2\t-1.7021611332893372e-1\t1.0087943077087402e-1\t5.9265500073973498e-1\t0.0000000000000000e+0\n\t[644\]\t-3.9448010921478271e-1\t-4.7897621989250183e-1\t8.4496110677719116e-2\t1.7640982405490371e-1\t0.0000000000000000e+0\n\t...and 992 more errors.\n\tMax AbsError of 1.6447335481643677e-1 at index of 785.\n\t[785\]\t3.4482055902481079e-1\t5.0929391384124756e-1\t1.6447335481643677e-1\t3.2294388435928745e-1\t0.0000000000000000e+0\n\tMax RelError of 2.2756960801624473e+1 at index of 867.\n\t[867\]\t1.4153416454792023e-1\t5.9575871564447880e-3\t1.3557657739147544e-1\t2.2756960801624473e+1\t0.0000000000000000e+0\n] + expected: FAIL + + [X k-rate detune with input: output[0,2048\] does not equal [0,0.12810896337032318,0.47732436656951904,0.8133140802383423,0.9599840044975281,0.9983929991722107,0.9618627429008484,0.8107287883758545,0.5545527338981628,0.24036024510860443,-0.09643325209617615,-0.424831748008728,-0.7066475749015808,-0.9075677990913391,-1.0057729482650757,-0.9910215139389038...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[128\]\t-9.0901952981948853e-1\t-8.0834698677062988e-1\t1.0067254304885864e-1\t1.2454124861781007e-1\t0.0000000000000000e+0\n\t[129\]\t-8.0550211668014526e-1\t-5.6012439727783203e-1\t2.4537771940231323e-1\t4.3807718534460011e-1\t0.0000000000000000e+0\n\t[130\]\t-6.2269222736358643e-1\t-2.4871249496936798e-1\t3.7397973239421844e-1\t1.5036628233747511e+0\t0.0000000000000000e+0\n\t[131\]\t-3.5228535532951355e-1\t9.0757519006729126e-2\t4.4304287433624268e-1\t4.8816106828944248e+0\t0.0000000000000000e+0\n\t[132\]\t-1.3693827204406261e-2\t4.1998893022537231e-1\t4.3368275742977858e-1\t1.0326052098493594e+0\t0.0000000000000000e+0\n\t...and 1915 more errors.\n\tMax AbsError of 2.1426951885223389e+0 at index of 391.\n\t[391\]\t6.9794428348541260e-1\t-1.4447509050369263e+0\t2.1426951885223389e+0\t1.4830897015202589e+0\t0.0000000000000000e+0\n\tMax RelError of 2.4604596714524988e+2 at index of 272.\n\t[272\]\t9.5641678571701050e-1\t-3.9030096959322691e-3\t9.6031979541294277e-1\t2.4604596714524988e+2\t0.0000000000000000e+0\n] + expected: FAIL + + [X k-rate Q with input: output[2048:\] does not equal [-0.007429864257574081,-0.0032945373095571995,0.0019048331305384636,0.003956870641559362,0.0035721869207918644,0.004832542035728693,0.008425349369645119,0.010273684747517109,0.007734519429504871,0.003703415160998702,0.0022171076852828264,0.0024073002859950066,0.0002190779778175056,-0.004831020720303059,-0.00846010260283947,-0.007902969606220722...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[0\]\t1.3721438590437174e-3\t-7.4298642575740814e-3\t8.8020081166177988e-3\t1.1846795326906463e+0\t0.0000000000000000e+0\n\t[1\]\t2.7593520935624838e-3\t-3.2945373095571995e-3\t6.0538894031196833e-3\t1.8375537546828853e+0\t0.0000000000000000e+0\n\t[2\]\t4.5378590002655983e-3\t1.9048331305384636e-3\t2.6330258697271347e-3\t1.3822868930166201e+0\t0.0000000000000000e+0\n\t[3\]\t2.8837921563535929e-3\t3.9568706415593624e-3\t1.0730784852057695e-3\t2.7119372413521214e-1\t0.0000000000000000e+0\n\t[4\]\t-1.0738878045231104e-3\t3.5721869207918644e-3\t4.6460747253149748e-3\t1.3006247512616322e+0\t0.0000000000000000e+0\n\t...and 2043 more errors.\n\tMax AbsError of 1.0892769030760974e-2 at index of 7.\n\t[7\]\t-6.1908428324386477e-4\t1.0273684747517109e-2\t1.0892769030760974e-2\t1.0602592252398519e+0\t0.0000000000000000e+0\n\tMax RelError of 2.0718886992081339e+3 at index of 217.\n\t[217\]\t4.6172842849045992e-4\t-2.2296148927125614e-7\t4.6195138997973118e-4\t2.0718886992081339e+3\t0.0000000000000000e+0\n] + expected: FAIL + + [X k-rate frequency with input: output[0,2048\] does not equal [0,0.02839340642094612,0.1450495570898056,0.36942505836486816,0.6520541310310364,0.9131435751914978,1.0783559083938599,1.1012734174728394,0.9707123637199402,0.7065789699554443,0.3498469293117523,-0.048511650413274765,-0.4367612302303314,-0.7688571810722351,-1.0084279775619507,-1.131049394607544...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[128\]\t-1.1191306114196777e+0\t-1.0972596406936646e+0\t2.1870970726013184e-2\t1.9932356859664331e-2\t0.0000000000000000e+0\n\t[129\]\t-9.9151837825775146e-1\t-9.3471795320510864e-1\t5.6800425052642822e-2\t6.0767448467076671e-2\t0.0000000000000000e+0\n\t[130\]\t-7.5953400135040283e-1\t-6.6672790050506592e-1\t9.2806100845336914e-2\t1.3919636597633545e-1\t0.0000000000000000e+0\n\t[131\]\t-4.4247153401374817e-1\t-3.2352218031883240e-1\t1.1894935369491577e-1\t3.6766985675507846e-1\t0.0000000000000000e+0\n\t[132\]\t-7.1794100105762482e-2\t5.6181099265813828e-2\t1.2797519937157631e-1\t2.2779048655861591e+0\t0.0000000000000000e+0\n\t...and 891 more errors.\n\tMax AbsError of 4.1948493570089340e-1 at index of 649.\n\t[649\]\t-3.7298277020454407e-3\t-4.2321476340293884e-1\t4.1948493570089340e-1\t9.9118691495529354e-1\t0.0000000000000000e+0\n\tMax RelError of 1.1267462635054815e+2 at index of 553.\n\t[553\]\t3.3036437630653381e-1\t2.9062279500067234e-3\t3.2745814835652709e-1\t1.1267462635054815e+2\t0.0000000000000000e+0\n] + expected: FAIL + diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html.ini deleted file mode 100644 index 857f336ece3..00000000000 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/setTargetAtTime-after-event-within-block.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[setTargetAtTime-after-event-within-block.html] - [Test setTargetAtTime after an event in the same processing block] - expected: FAIL diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/setValueAtTime-within-block.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/setValueAtTime-within-block.html.ini deleted file mode 100644 index da05fe2e316..00000000000 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-audioparam-interface/setValueAtTime-within-block.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[setValueAtTime-within-block.html] - [Test setValueAtTime with start time not on a block boundary] - expected: FAIL diff --git a/tests/wpt/metadata/webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html.ini b/tests/wpt/metadata/webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html.ini index 2fc8e9e122c..3847065f310 100644 --- a/tests/wpt/metadata/webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html.ini +++ b/tests/wpt/metadata/webaudio/the-audio-api/the-oscillatornode-interface/detune-limiting.html.ini @@ -17,3 +17,6 @@ [X Osc(freq: 44100.00390625) output: Expected 0 for all values but found 5511 unexpected values: \n\tIndex\tActual\n\t[1\]\t5.565462970480439e-7\n\t[2\]\t0.0000011130925940960879\n\t[3\]\t0.0000016696390048309695\n\t[4\]\t0.0000022261851881921757\n\t...and 5507 more errors.] expected: FAIL + [X Osc(freq: 1, detune: 18514.189453125) output does not equal [0,5.565462970480439e-7,0.0000011130925940960879,0.0000016696390048309695,0.0000022261851881921757,0.0000027827315989270573,0.000003339278009661939,0.000003895824193023145,0.000004452370376384351,0.0000050089170144929085,0.000005565463197854115,0.000006122009381215321,0.000006678556019323878,0.000007235102202685084,0.00000779164838604629,0.000008348194569407497...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[1\]\t1.4247585204429924e-4\t5.5654629704804393e-7\t1.4191930574725120e-4\t2.5500000000000000e+2\t0.0000000000000000e+0\n\t[2\]\t2.8495170408859849e-4\t1.1130925940960879e-6\t2.8383861149450240e-4\t2.5500000000000000e+2\t0.0000000000000000e+0\n\t[3\]\t4.2742758523672819e-4\t1.6696390048309695e-6\t4.2575794623189722e-4\t2.5500000000000000e+2\t0.0000000000000000e+0\n\t[4\]\t5.6990334996953607e-4\t2.2261851881921757e-6\t5.6767716478134389e-4\t2.5499997385318113e+2\t0.0000000000000000e+0\n\t[5\]\t7.1237923111766577e-4\t2.7827315989270573e-6\t7.0959649951873871e-4\t2.5499997908254574e+2\t0.0000000000000000e+0\n\t...and 5506 more errors.\n\tMax AbsError of 7.0388848986476660e-1 at index of 5511.\n\t[5511\]\t7.0695561170578003e-1\t3.0671218410134315e-3\t7.0388848986476660e-1\t2.2949479230084623e+2\t0.0000000000000000e+0\n\tMax RelError of 2.5500000000000000e+2 at index of 1.\n] + expected: FAIL + diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 0af4c016a89..9a3b898019f 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -13952,7 +13952,7 @@ ] ], "interfaces.html": [ - "145c902ff033ba1de46b41dec07992fae4fd2f13", + "0776b2873c16cd34bdc85c23f44030729eaae524", [ null, {} From 27f439a71c426330e61ef41ea4d72cd720a68069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 30 Jun 2020 15:27:56 +0200 Subject: [PATCH 26/27] Hide interfaces behind webrtc pref --- components/script/dom/webidls/RTCDataChannel.webidl | 2 +- components/script/dom/webidls/RTCDataChannelEvent.webidl | 2 +- components/script/dom/webidls/RTCError.webidl | 2 +- components/script/dom/webidls/RTCErrorEvent.webidl | 2 +- tests/wpt/mozilla/meta/MANIFEST.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/script/dom/webidls/RTCDataChannel.webidl b/components/script/dom/webidls/RTCDataChannel.webidl index 7dd195c7cdd..cdc3b9fdd48 100644 --- a/components/script/dom/webidls/RTCDataChannel.webidl +++ b/components/script/dom/webidls/RTCDataChannel.webidl @@ -4,7 +4,7 @@ // https://w3c.github.io/webrtc-pc/#dom-rtcdatachannel - [Exposed=Window] +[Exposed=Window, Pref="dom.webrtc.enabled"] interface RTCDataChannel : EventTarget { readonly attribute USVString label; readonly attribute boolean ordered; diff --git a/components/script/dom/webidls/RTCDataChannelEvent.webidl b/components/script/dom/webidls/RTCDataChannelEvent.webidl index 081ab15db25..bc564a12138 100644 --- a/components/script/dom/webidls/RTCDataChannelEvent.webidl +++ b/components/script/dom/webidls/RTCDataChannelEvent.webidl @@ -4,7 +4,7 @@ // https://w3c.github.io/webrtc-pc/#dom-rtcdatachannelevent - [Exposed=Window] +[Exposed=Window, Pref="dom.webrtc.enabled"] interface RTCDataChannelEvent : Event { constructor(DOMString type, RTCDataChannelEventInit eventInitDict); readonly attribute RTCDataChannel channel; diff --git a/components/script/dom/webidls/RTCError.webidl b/components/script/dom/webidls/RTCError.webidl index f398c450905..f7ffa3d2d57 100644 --- a/components/script/dom/webidls/RTCError.webidl +++ b/components/script/dom/webidls/RTCError.webidl @@ -4,7 +4,7 @@ // https://w3c.github.io/webrtc-pc/#dom-rtcerror -[Exposed=Window] +[Exposed=Window, Pref="dom.webrtc.enabled"] interface RTCError : DOMException { constructor(RTCErrorInit init, optional DOMString message = ""); readonly attribute RTCErrorDetailType errorDetail; diff --git a/components/script/dom/webidls/RTCErrorEvent.webidl b/components/script/dom/webidls/RTCErrorEvent.webidl index 9433fc6f579..d3ac256744c 100644 --- a/components/script/dom/webidls/RTCErrorEvent.webidl +++ b/components/script/dom/webidls/RTCErrorEvent.webidl @@ -4,7 +4,7 @@ // https://w3c.github.io/webrtc-pc/#dom-rtcerrorevent -[Exposed=Window] +[Exposed=Window, Pref="dom.webrtc.enabled"] interface RTCErrorEvent : Event { constructor(DOMString type, RTCErrorEventInit eventInitDict); [SameObject] readonly attribute RTCError error; diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 9a3b898019f..0af4c016a89 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -13952,7 +13952,7 @@ ] ], "interfaces.html": [ - "0776b2873c16cd34bdc85c23f44030729eaae524", + "145c902ff033ba1de46b41dec07992fae4fd2f13", [ null, {} From c2968fa2e56ecfb0b39192b0779d8fb6f0e31da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 30 Jun 2020 17:38:18 +0200 Subject: [PATCH 27/27] Fix doc build --- python/servo/post_build_commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/servo/post_build_commands.py b/python/servo/post_build_commands.py index 9b38c584fd0..98fadae15c7 100644 --- a/python/servo/post_build_commands.py +++ b/python/servo/post_build_commands.py @@ -272,7 +272,9 @@ class PostBuildCommands(CommandBase): features += self.pick_media_stack(media_stack, target) - returncode = self.run_cargo_build_like_command("doc", params, features=features, **kwargs) + env = self.build_env(target=target, is_build=True, features=features) + + returncode = self.run_cargo_build_like_command("doc", params, features=features, env=env, **kwargs) if returncode: return returncode