mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Auto merge of #26752 - ferjm:datachannel, r=Manishearth
WebRTC data channels support - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #26212 This depends on https://github.com/servo/media/pull/350 and contains the basic pieces to make a simple test like https://ferjm.github.io/samples/src/content/datachannel/basic/ work
This commit is contained in:
commit
4b034ede46
22 changed files with 930 additions and 34 deletions
43
Cargo.lock
generated
43
Cargo.lock
generated
|
@ -2286,9 +2286,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gstreamer-webrtc"
|
name = "gstreamer-webrtc"
|
||||||
version = "0.15.0"
|
version = "0.15.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e64235af90676896b01f3cbe50808fefaf498057ca288ce4a31a89de81464e04"
|
checksum = "1f433d1294266fb1d65e1dc2d4de365f7f4caf23cb72db3a3bd6904eeec88cf1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib",
|
"glib",
|
||||||
"glib-sys",
|
"glib-sys",
|
||||||
|
@ -3659,6 +3659,16 @@ dependencies = [
|
||||||
"version_check",
|
"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]]
|
[[package]]
|
||||||
name = "num-derive"
|
name = "num-derive"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -4884,7 +4894,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media"
|
name = "servo-media"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"servo-media-audio",
|
"servo-media-audio",
|
||||||
"servo-media-player",
|
"servo-media-player",
|
||||||
|
@ -4896,16 +4906,19 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-audio"
|
name = "servo-media-audio"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boxfnonce",
|
"boxfnonce",
|
||||||
"byte-slice-cast",
|
"byte-slice-cast",
|
||||||
"euclid",
|
"euclid",
|
||||||
|
"log",
|
||||||
|
"num-complex",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"servo-media-player",
|
"servo-media-player",
|
||||||
|
"servo-media-streams",
|
||||||
"servo-media-traits",
|
"servo-media-traits",
|
||||||
"servo_media_derive",
|
"servo_media_derive",
|
||||||
"smallvec 0.6.13",
|
"smallvec 0.6.13",
|
||||||
|
@ -4915,7 +4928,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-dummy"
|
name = "servo-media-dummy"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boxfnonce",
|
"boxfnonce",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
|
@ -4930,7 +4943,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-gstreamer"
|
name = "servo-media-gstreamer"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boxfnonce",
|
"boxfnonce",
|
||||||
"byte-slice-cast",
|
"byte-slice-cast",
|
||||||
|
@ -4966,7 +4979,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-gstreamer-render"
|
name = "servo-media-gstreamer-render"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gstreamer",
|
"gstreamer",
|
||||||
"gstreamer-video",
|
"gstreamer-video",
|
||||||
|
@ -4976,7 +4989,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-gstreamer-render-android"
|
name = "servo-media-gstreamer-render-android"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib",
|
"glib",
|
||||||
"gstreamer",
|
"gstreamer",
|
||||||
|
@ -4989,7 +5002,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-gstreamer-render-unix"
|
name = "servo-media-gstreamer-render-unix"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glib",
|
"glib",
|
||||||
"gstreamer",
|
"gstreamer",
|
||||||
|
@ -5002,7 +5015,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-player"
|
name = "servo-media-player"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -5014,7 +5027,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-streams"
|
name = "servo-media-streams"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
@ -5023,16 +5036,18 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-traits"
|
name = "servo-media-traits"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo-media-webrtc"
|
name = "servo-media-webrtc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boxfnonce",
|
"boxfnonce",
|
||||||
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"servo-media-streams",
|
"servo-media-streams",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5104,7 +5119,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo_media_derive"
|
name = "servo_media_derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/media#62cd58a94c54e8d9ff3845f263356e242e951686"
|
source = "git+https://github.com/servo/media#18ece081a071b1b6b323f8d7b2684a76a7df203e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 1.0.17",
|
"proc-macro2 1.0.17",
|
||||||
"quote 1.0.2",
|
"quote 1.0.2",
|
||||||
|
|
|
@ -16,6 +16,7 @@ characteristicvaluechanged
|
||||||
checkbox
|
checkbox
|
||||||
click
|
click
|
||||||
close
|
close
|
||||||
|
closing
|
||||||
color
|
color
|
||||||
complete
|
complete
|
||||||
compositionend
|
compositionend
|
||||||
|
@ -23,6 +24,7 @@ compositionstart
|
||||||
compositionupdate
|
compositionupdate
|
||||||
controllerchange
|
controllerchange
|
||||||
cursive
|
cursive
|
||||||
|
datachannel
|
||||||
date
|
date
|
||||||
datetime-local
|
datetime-local
|
||||||
dir
|
dir
|
||||||
|
|
|
@ -487,6 +487,10 @@ pub mod raredata;
|
||||||
pub mod readablestream;
|
pub mod readablestream;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
|
pub mod rtcdatachannel;
|
||||||
|
pub mod rtcdatachannelevent;
|
||||||
|
pub mod rtcerror;
|
||||||
|
pub mod rtcerrorevent;
|
||||||
pub mod rtcicecandidate;
|
pub mod rtcicecandidate;
|
||||||
pub mod rtcpeerconnection;
|
pub mod rtcpeerconnection;
|
||||||
pub mod rtcpeerconnectioniceevent;
|
pub mod rtcpeerconnectioniceevent;
|
||||||
|
|
387
components/script/dom/rtcdatachannel.rs
Normal file
387
components/script/dom/rtcdatachannel.rs
Normal file
|
@ -0,0 +1,387 @@
|
||||||
|
/* 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::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;
|
||||||
|
use crate::dom::messageevent::MessageEvent;
|
||||||
|
use crate::dom::rtcerror::RTCError;
|
||||||
|
use crate::dom::rtcerrorevent::RTCErrorEvent;
|
||||||
|
use crate::dom::rtcpeerconnection::RTCPeerConnection;
|
||||||
|
use dom_struct::dom_struct;
|
||||||
|
use js::conversions::ToJSValConvertible;
|
||||||
|
use js::jsapi::{JSAutoRealm, JSObject};
|
||||||
|
use js::jsval::UndefinedValue;
|
||||||
|
use js::rust::CustomAutoRooterGuard;
|
||||||
|
use js::typedarray::{ArrayBuffer, ArrayBufferView, CreateWith};
|
||||||
|
use script_traits::serializable::BlobImpl;
|
||||||
|
use servo_media::webrtc::{
|
||||||
|
DataChannelId, DataChannelInit, DataChannelMessage, DataChannelState, WebRtcError,
|
||||||
|
};
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct RTCDataChannel {
|
||||||
|
eventtarget: EventTarget,
|
||||||
|
#[ignore_malloc_size_of = "defined in servo-media"]
|
||||||
|
servo_media_id: DataChannelId,
|
||||||
|
peer_connection: Dom<RTCPeerConnection>,
|
||||||
|
label: USVString,
|
||||||
|
ordered: bool,
|
||||||
|
max_packet_life_time: Option<u16>,
|
||||||
|
max_retransmits: Option<u16>,
|
||||||
|
protocol: USVString,
|
||||||
|
negotiated: bool,
|
||||||
|
id: Option<u16>,
|
||||||
|
ready_state: Cell<RTCDataChannelState>,
|
||||||
|
binary_type: DomRefCell<DOMString>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RTCDataChannel {
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
pub fn new_inherited(
|
||||||
|
peer_connection: &RTCPeerConnection,
|
||||||
|
label: USVString,
|
||||||
|
options: &RTCDataChannelInit,
|
||||||
|
servo_media_id: Option<DataChannelId>,
|
||||||
|
) -> RTCDataChannel {
|
||||||
|
let mut init: DataChannelInit = options.into();
|
||||||
|
init.label = label.to_string();
|
||||||
|
|
||||||
|
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"),
|
||||||
|
);
|
||||||
|
|
||||||
|
let channel = RTCDataChannel {
|
||||||
|
eventtarget: EventTarget::new_inherited(),
|
||||||
|
servo_media_id,
|
||||||
|
peer_connection: Dom::from_ref(&peer_connection),
|
||||||
|
label,
|
||||||
|
ordered: options.ordered,
|
||||||
|
max_packet_life_time: options.maxPacketLifeTime,
|
||||||
|
max_retransmits: options.maxRetransmits,
|
||||||
|
protocol: options.protocol.clone(),
|
||||||
|
negotiated: options.negotiated,
|
||||||
|
id: options.id,
|
||||||
|
ready_state: Cell::new(RTCDataChannelState::Connecting),
|
||||||
|
binary_type: DomRefCell::new(DOMString::from("blob")),
|
||||||
|
};
|
||||||
|
|
||||||
|
channel
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
global: &GlobalScope,
|
||||||
|
peer_connection: &RTCPeerConnection,
|
||||||
|
label: USVString,
|
||||||
|
options: &RTCDataChannelInit,
|
||||||
|
servo_media_id: Option<DataChannelId>,
|
||||||
|
) -> DomRoot<RTCDataChannel> {
|
||||||
|
let rtc_data_channel = reflect_dom_object(
|
||||||
|
Box::new(RTCDataChannel::new_inherited(
|
||||||
|
peer_connection,
|
||||||
|
label,
|
||||||
|
options,
|
||||||
|
servo_media_id,
|
||||||
|
)),
|
||||||
|
global,
|
||||||
|
);
|
||||||
|
|
||||||
|
peer_connection.register_data_channel(rtc_data_channel.servo_media_id, &*rtc_data_channel);
|
||||||
|
|
||||||
|
rtc_data_channel
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_open(&self) {
|
||||||
|
let event = Event::new(
|
||||||
|
&self.global(),
|
||||||
|
atom!("open"),
|
||||||
|
EventBubbles::DoesNotBubble,
|
||||||
|
EventCancelable::NotCancelable,
|
||||||
|
);
|
||||||
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn on_close(&self) {
|
||||||
|
let event = Event::new(
|
||||||
|
&self.global(),
|
||||||
|
atom!("close"),
|
||||||
|
EventBubbles::DoesNotBubble,
|
||||||
|
EventCancelable::NotCancelable,
|
||||||
|
);
|
||||||
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
|
|
||||||
|
self.peer_connection
|
||||||
|
.unregister_data_channel(&self.servo_media_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
receivedAlert: None,
|
||||||
|
sctpCauseCode: None,
|
||||||
|
sdpLineNumber: None,
|
||||||
|
sentAlert: None,
|
||||||
|
};
|
||||||
|
let message = match error {
|
||||||
|
WebRtcError::Backend(message) => DOMString::from(message),
|
||||||
|
};
|
||||||
|
let error = RTCError::new(&global, &init, message);
|
||||||
|
let event = RTCErrorEvent::new(&global, atom!("error"), false, false, &error);
|
||||||
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
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());
|
||||||
|
|
||||||
|
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::<JSObject>());
|
||||||
|
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![],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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::<Event>().fire(self.upcast());
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
|
self.ready_state.set(state.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send(&self, source: &SendSource) -> Fallible<()> {
|
||||||
|
if self.ready_state.get() != 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 {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.peer_connection
|
||||||
|
.unregister_data_channel(&self.servo_media_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
// 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<u16> {
|
||||||
|
self.max_packet_life_time
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-datachannel-maxretransmits
|
||||||
|
fn GetMaxRetransmits(&self) -> Option<u16> {
|
||||||
|
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<u16> {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-datachannel-readystate
|
||||||
|
fn ReadyState(&self) -> RTCDataChannelState {
|
||||||
|
self.ready_state.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) -> ();
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-close
|
||||||
|
fn Close(&self) {
|
||||||
|
let controller = self.peer_connection.get_webrtc_controller().borrow();
|
||||||
|
controller
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.close_data_channel(&self.servo_media_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<()> {
|
||||||
|
self.send(&SendSource::String(&data))
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-1
|
||||||
|
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<ArrayBuffer>) -> Fallible<()> {
|
||||||
|
self.send(&SendSource::ArrayBuffer(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-3
|
||||||
|
fn Send___(&self, data: CustomAutoRooterGuard<ArrayBufferView>) -> Fallible<()> {
|
||||||
|
self.send(&SendSource::ArrayBufferView(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&RTCDataChannelInit> for DataChannelInit {
|
||||||
|
fn from(init: &RTCDataChannelInit) -> DataChannelInit {
|
||||||
|
DataChannelInit {
|
||||||
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DataChannelState> 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
77
components/script/dom/rtcdatachannelevent.rs
Normal file
77
components/script/dom/rtcdatachannelevent.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/* 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<RTCDataChannel>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<RTCDataChannelEvent> {
|
||||||
|
let event = reflect_dom_object(
|
||||||
|
Box::new(RTCDataChannelEvent::new_inherited(&channel)),
|
||||||
|
global,
|
||||||
|
);
|
||||||
|
{
|
||||||
|
let event = event.upcast::<Event>();
|
||||||
|
event.init_event(type_, bubbles, cancelable);
|
||||||
|
}
|
||||||
|
event
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn Constructor(
|
||||||
|
window: &Window,
|
||||||
|
type_: DOMString,
|
||||||
|
init: &RTCDataChannelEventInit,
|
||||||
|
) -> DomRoot<RTCDataChannelEvent> {
|
||||||
|
RTCDataChannelEvent::new(
|
||||||
|
&window.global(),
|
||||||
|
Atom::from(type_),
|
||||||
|
init.parent.bubbles,
|
||||||
|
init.parent.cancelable,
|
||||||
|
&init.channel,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RTCDataChannelEventMethods for RTCDataChannelEvent {
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-datachannelevent-channel
|
||||||
|
fn Channel(&self) -> DomRoot<RTCDataChannel> {
|
||||||
|
DomRoot::from_ref(&*self.channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://dom.spec.whatwg.org/#dom-event-istrusted
|
||||||
|
fn IsTrusted(&self) -> bool {
|
||||||
|
self.event.IsTrusted()
|
||||||
|
}
|
||||||
|
}
|
90
components/script/dom/rtcerror.rs
Normal file
90
components/script/dom/rtcerror.rs
Normal file
|
@ -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<DOMException>,
|
||||||
|
error_detail: RTCErrorDetailType,
|
||||||
|
sdp_line_number: Option<i32>,
|
||||||
|
http_request_status_code: Option<i32>,
|
||||||
|
sctp_cause_code: Option<i32>,
|
||||||
|
received_alert: Option<u32>,
|
||||||
|
sent_alert: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(global: &GlobalScope, init: &RTCErrorInit, message: DOMString) -> DomRoot<RTCError> {
|
||||||
|
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> {
|
||||||
|
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<i32> {
|
||||||
|
self.sdp_line_number
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcerror
|
||||||
|
fn GetHttpRequestStatusCode(&self) -> Option<i32> {
|
||||||
|
self.http_request_status_code
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcerror-sctpcausecode
|
||||||
|
fn GetSctpCauseCode(&self) -> Option<i32> {
|
||||||
|
self.sctp_cause_code
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcerror-receivedalert
|
||||||
|
fn GetReceivedAlert(&self) -> Option<u32> {
|
||||||
|
self.received_alert
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcerror-sentalert
|
||||||
|
fn GetSentAlert(&self) -> Option<u32> {
|
||||||
|
self.sent_alert
|
||||||
|
}
|
||||||
|
}
|
74
components/script/dom/rtcerrorevent.rs
Normal file
74
components/script/dom/rtcerrorevent.rs
Normal file
|
@ -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::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<RTCError>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RTCErrorEvent {
|
||||||
|
fn new_inherited(error: &RTCError) -> RTCErrorEvent {
|
||||||
|
RTCErrorEvent {
|
||||||
|
event: Event::new_inherited(),
|
||||||
|
error: Dom::from_ref(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
global: &GlobalScope,
|
||||||
|
type_: Atom,
|
||||||
|
bubbles: bool,
|
||||||
|
cancelable: bool,
|
||||||
|
error: &RTCError,
|
||||||
|
) -> DomRoot<RTCErrorEvent> {
|
||||||
|
let event = reflect_dom_object(Box::new(RTCErrorEvent::new_inherited(&error)), global);
|
||||||
|
{
|
||||||
|
let event = event.upcast::<Event>();
|
||||||
|
event.init_event(type_, bubbles, cancelable);
|
||||||
|
}
|
||||||
|
event
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn Constructor(
|
||||||
|
window: &Window,
|
||||||
|
type_: DOMString,
|
||||||
|
init: &RTCErrorEventInit,
|
||||||
|
) -> DomRoot<RTCErrorEvent> {
|
||||||
|
RTCErrorEvent::new(
|
||||||
|
&window.global(),
|
||||||
|
Atom::from(type_),
|
||||||
|
init.parent.bubbles,
|
||||||
|
init.parent.cancelable,
|
||||||
|
&init.error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RTCErrorEventMethods for RTCErrorEvent {
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcerrorevent-error
|
||||||
|
fn Error(&self) -> DomRoot<RTCError> {
|
||||||
|
DomRoot::from_ref(&*self.error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://dom.spec.whatwg.org/#dom-event-istrusted
|
||||||
|
fn IsTrusted(&self) -> bool {
|
||||||
|
self.event.IsTrusted()
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
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::RTCIceCandidateBinding::RTCIceCandidateInit;
|
||||||
use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding::RTCPeerConnectionMethods;
|
use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding::RTCPeerConnectionMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding::{
|
use crate::dom::bindings::codegen::Bindings::RTCPeerConnectionBinding::{
|
||||||
|
@ -19,19 +20,22 @@ use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
|
||||||
use crate::dom::bindings::reflector::reflect_dom_object;
|
use crate::dom::bindings::reflector::reflect_dom_object;
|
||||||
use crate::dom::bindings::reflector::DomObject;
|
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::event::{Event, EventBubbles, EventCancelable};
|
||||||
use crate::dom::eventtarget::EventTarget;
|
use crate::dom::eventtarget::EventTarget;
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::mediastream::MediaStream;
|
use crate::dom::mediastream::MediaStream;
|
||||||
use crate::dom::mediastreamtrack::MediaStreamTrack;
|
use crate::dom::mediastreamtrack::MediaStreamTrack;
|
||||||
use crate::dom::promise::Promise;
|
use crate::dom::promise::Promise;
|
||||||
|
use crate::dom::rtcdatachannel::RTCDataChannel;
|
||||||
|
use crate::dom::rtcdatachannelevent::RTCDataChannelEvent;
|
||||||
use crate::dom::rtcicecandidate::RTCIceCandidate;
|
use crate::dom::rtcicecandidate::RTCIceCandidate;
|
||||||
use crate::dom::rtcpeerconnectioniceevent::RTCPeerConnectionIceEvent;
|
use crate::dom::rtcpeerconnectioniceevent::RTCPeerConnectionIceEvent;
|
||||||
use crate::dom::rtcsessiondescription::RTCSessionDescription;
|
use crate::dom::rtcsessiondescription::RTCSessionDescription;
|
||||||
use crate::dom::rtctrackevent::RTCTrackEvent;
|
use crate::dom::rtctrackevent::RTCTrackEvent;
|
||||||
use crate::dom::window::Window;
|
use crate::dom::window::Window;
|
||||||
use crate::realms::InRealm;
|
use crate::realms::{enter_realm, InRealm};
|
||||||
use crate::task::TaskCanceller;
|
use crate::task::TaskCanceller;
|
||||||
use crate::task_source::networking::NetworkingTaskSource;
|
use crate::task_source::networking::NetworkingTaskSource;
|
||||||
use crate::task_source::TaskSource;
|
use crate::task_source::TaskSource;
|
||||||
|
@ -40,12 +44,14 @@ use dom_struct::dom_struct;
|
||||||
use servo_media::streams::registry::MediaStreamId;
|
use servo_media::streams::registry::MediaStreamId;
|
||||||
use servo_media::streams::MediaStreamType;
|
use servo_media::streams::MediaStreamType;
|
||||||
use servo_media::webrtc::{
|
use servo_media::webrtc::{
|
||||||
BundlePolicy, GatheringState, IceCandidate, IceConnectionState, SdpType, SessionDescription,
|
BundlePolicy, DataChannelEvent, DataChannelId, DataChannelState, GatheringState, IceCandidate,
|
||||||
SignalingState, WebRtcController, WebRtcSignaller,
|
IceConnectionState, SdpType, SessionDescription, SignalingState, WebRtcController,
|
||||||
|
WebRtcSignaller,
|
||||||
};
|
};
|
||||||
use servo_media::ServoMedia;
|
use servo_media::ServoMedia;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -66,6 +72,8 @@ pub struct RTCPeerConnection {
|
||||||
gathering_state: Cell<RTCIceGatheringState>,
|
gathering_state: Cell<RTCIceGatheringState>,
|
||||||
ice_connection_state: Cell<RTCIceConnectionState>,
|
ice_connection_state: Cell<RTCIceConnectionState>,
|
||||||
signaling_state: Cell<RTCSignalingState>,
|
signaling_state: Cell<RTCSignalingState>,
|
||||||
|
#[ignore_malloc_size_of = "defined in servo-media"]
|
||||||
|
data_channels: DomRefCell<HashMap<DataChannelId, Dom<RTCDataChannel>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RTCSignaller {
|
struct RTCSignaller {
|
||||||
|
@ -142,6 +150,25 @@ impl WebRtcSignaller for RTCSignaller {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_event: move || {
|
||||||
|
let this = this.root();
|
||||||
|
let global = this.global();
|
||||||
|
let _ac = enter_realm(&*global);
|
||||||
|
this.on_data_channel_event(channel, event);
|
||||||
|
}),
|
||||||
|
&self.canceller,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn close(&self) {
|
fn close(&self) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -161,6 +188,7 @@ impl RTCPeerConnection {
|
||||||
gathering_state: Cell::new(RTCIceGatheringState::New),
|
gathering_state: Cell::new(RTCIceGatheringState::New),
|
||||||
ice_connection_state: Cell::new(RTCIceConnectionState::New),
|
ice_connection_state: Cell::new(RTCIceConnectionState::New),
|
||||||
signaling_state: Cell::new(RTCSignalingState::Stable),
|
signaling_state: Cell::new(RTCSignalingState::Stable),
|
||||||
|
data_channels: DomRefCell::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +227,10 @@ impl RTCPeerConnection {
|
||||||
Ok(RTCPeerConnection::new(&window.global(), config))
|
Ok(RTCPeerConnection::new(&window.global(), config))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_webrtc_controller(&self) -> &DomRefCell<Option<WebRtcController>> {
|
||||||
|
&self.controller
|
||||||
|
}
|
||||||
|
|
||||||
fn make_signaller(&self) -> Box<dyn WebRtcSignaller> {
|
fn make_signaller(&self) -> Box<dyn WebRtcSignaller> {
|
||||||
let trusted = Trusted::new(self);
|
let trusted = Trusted::new(self);
|
||||||
let (task_source, canceller) = self
|
let (task_source, canceller) = self
|
||||||
|
@ -256,6 +288,68 @@ impl RTCPeerConnection {
|
||||||
event.upcast::<Event>().fire(self.upcast());
|
event.upcast::<Event>().fire(self.upcast());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_data_channel_event(&self, channel_id: DataChannelId, event: DataChannelEvent) {
|
||||||
|
if self.closed.get() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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::<Event>().fire(self.upcast());
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
let channel = if let Some(channel) = self.data_channels.borrow().get(&channel_id) {
|
||||||
|
DomRoot::from_ref(&**channel)
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"Got an event for an unregistered data channel {:?}",
|
||||||
|
channel_id
|
||||||
|
);
|
||||||
|
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!(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register_data_channel(&self, id: DataChannelId, channel: &RTCDataChannel) {
|
||||||
|
if self
|
||||||
|
.data_channels
|
||||||
|
.borrow_mut()
|
||||||
|
.insert(id, Dom::from_ref(channel))
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
warn!("Data channel already registered {:?}", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
/// https://www.w3.org/TR/webrtc/#update-ice-gathering-state
|
||||||
fn update_gathering_state(&self, state: GatheringState) {
|
fn update_gathering_state(&self, state: GatheringState) {
|
||||||
// step 1
|
// step 1
|
||||||
|
@ -448,6 +542,9 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
|
||||||
SetOnsignalingstatechange
|
SetOnsignalingstatechange
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-ondatachannel
|
||||||
|
event_handler!(datachannel, GetOndatachannel, SetOndatachannel);
|
||||||
|
|
||||||
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate
|
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate
|
||||||
fn AddIceCandidate(&self, candidate: &RTCIceCandidateInit, comp: InRealm) -> Rc<Promise> {
|
fn AddIceCandidate(&self, candidate: &RTCIceCandidateInit, comp: InRealm) -> Rc<Promise> {
|
||||||
let p = Promise::new_in_current_realm(&self.global(), comp);
|
let p = Promise::new_in_current_realm(&self.global(), comp);
|
||||||
|
@ -624,8 +721,13 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
|
||||||
// Step 5 handled by backend
|
// Step 5 handled by backend
|
||||||
self.controller.borrow_mut().as_ref().unwrap().quit();
|
self.controller.borrow_mut().as_ref().unwrap().quit();
|
||||||
|
|
||||||
// Step 6-10
|
// Step 6
|
||||||
// (no current support for data channels, transports, etc)
|
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
|
// Step 11
|
||||||
self.ice_connection_state.set(RTCIceConnectionState::Closed);
|
self.ice_connection_state.set(RTCIceConnectionState::Closed);
|
||||||
|
@ -633,6 +735,15 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
|
||||||
// Step 11
|
// Step 11
|
||||||
// (no current support for connection state)
|
// (no current support for connection state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://www.w3.org/TR/webrtc/#dom-peerconnection-createdatachannel
|
||||||
|
fn CreateDataChannel(
|
||||||
|
&self,
|
||||||
|
label: USVString,
|
||||||
|
init: &RTCDataChannelInit,
|
||||||
|
) -> DomRoot<RTCDataChannel> {
|
||||||
|
RTCDataChannel::new(&self.global(), &self, label, init, None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SessionDescription> for RTCSessionDescriptionInit {
|
impl From<SessionDescription> for RTCSessionDescriptionInit {
|
||||||
|
|
49
components/script/dom/webidls/RTCDataChannel.webidl
Normal file
49
components/script/dom/webidls/RTCDataChannel.webidl
Normal file
|
@ -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://w3c.github.io/webrtc-pc/#dom-rtcdatachannel
|
||||||
|
|
||||||
|
[Exposed=Window, Pref="dom.webrtc.enabled"]
|
||||||
|
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;
|
||||||
|
[SetterThrows] attribute DOMString binaryType;
|
||||||
|
[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
|
||||||
|
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"
|
||||||
|
};
|
15
components/script/dom/webidls/RTCDataChannelEvent.webidl
Normal file
15
components/script/dom/webidls/RTCDataChannelEvent.webidl
Normal file
|
@ -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://w3c.github.io/webrtc-pc/#dom-rtcdatachannelevent
|
||||||
|
|
||||||
|
[Exposed=Window, Pref="dom.webrtc.enabled"]
|
||||||
|
interface RTCDataChannelEvent : Event {
|
||||||
|
constructor(DOMString type, RTCDataChannelEventInit eventInitDict);
|
||||||
|
readonly attribute RTCDataChannel channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary RTCDataChannelEventInit : EventInit {
|
||||||
|
required RTCDataChannel channel;
|
||||||
|
};
|
35
components/script/dom/webidls/RTCError.webidl
Normal file
35
components/script/dom/webidls/RTCError.webidl
Normal file
|
@ -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://w3c.github.io/webrtc-pc/#dom-rtcerror
|
||||||
|
|
||||||
|
[Exposed=Window, Pref="dom.webrtc.enabled"]
|
||||||
|
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"
|
||||||
|
};
|
15
components/script/dom/webidls/RTCErrorEvent.webidl
Normal file
15
components/script/dom/webidls/RTCErrorEvent.webidl
Normal file
|
@ -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://w3c.github.io/webrtc-pc/#dom-rtcerrorevent
|
||||||
|
|
||||||
|
[Exposed=Window, Pref="dom.webrtc.enabled"]
|
||||||
|
interface RTCErrorEvent : Event {
|
||||||
|
constructor(DOMString type, RTCErrorEventInit eventInitDict);
|
||||||
|
[SameObject] readonly attribute RTCError error;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary RTCErrorEventInit : EventInit {
|
||||||
|
required RTCError error;
|
||||||
|
};
|
|
@ -126,3 +126,11 @@ partial interface RTCPeerConnection {
|
||||||
// optional RTCRtpTransceiverInit init);
|
// optional RTCRtpTransceiverInit init);
|
||||||
attribute EventHandler ontrack;
|
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;
|
||||||
|
};
|
||||||
|
|
|
@ -55,7 +55,7 @@ euclid = "0.20"
|
||||||
gfx = { path = "../gfx" }
|
gfx = { path = "../gfx" }
|
||||||
gfx_traits = { path = "../gfx_traits" }
|
gfx_traits = { path = "../gfx_traits" }
|
||||||
gleam = "0.11"
|
gleam = "0.11"
|
||||||
gstreamer = { version = "0.15", optional = true }
|
gstreamer = { version = "0.15", features = ["v1_16"], optional = true }
|
||||||
ipc-channel = "0.14"
|
ipc-channel = "0.14"
|
||||||
keyboard-types = "0.5"
|
keyboard-types = "0.5"
|
||||||
layout_thread_2013 = { path = "../layout_thread", optional = true }
|
layout_thread_2013 = { path = "../layout_thread", optional = true }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM ubuntu:bionic-20200403
|
FROM ubuntu:eoan-20200608
|
||||||
|
|
||||||
ENV \
|
ENV \
|
||||||
#
|
#
|
||||||
|
|
|
@ -24,9 +24,8 @@ RUN \
|
||||||
clang \
|
clang \
|
||||||
llvm \
|
llvm \
|
||||||
llvm-dev \
|
llvm-dev \
|
||||||
#
|
|
||||||
# GStreamer
|
# GStreamer
|
||||||
libgstreamer-plugins-bad1.0-dev \
|
libpcre3-dev \
|
||||||
#
|
#
|
||||||
# OpenSSL
|
# OpenSSL
|
||||||
libssl-dev \
|
libssl-dev \
|
||||||
|
|
|
@ -272,7 +272,9 @@ class PostBuildCommands(CommandBase):
|
||||||
|
|
||||||
features += self.pick_media_stack(media_stack, target)
|
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:
|
if returncode:
|
||||||
return returncode
|
return returncode
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,6 @@
|
||||||
[video/mp4; codecs="avc1.4D401E" (optional)]
|
[video/mp4; codecs="avc1.4D401E" (optional)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[audio/wav; codecs="1" (optional)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[audio/wav (optional)]
|
[audio/wav (optional)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -76,3 +73,7 @@
|
||||||
|
|
||||||
[video/3gpp; codecs="mp4v.20.8" (optional)]
|
[video/3gpp; codecs="mp4v.20.8" (optional)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[audio/wav with and without codecs]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -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]
|
[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
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[setTargetAtTime-after-event-within-block.html]
|
|
||||||
[Test setTargetAtTime after an event in the same processing block]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[setValueAtTime-within-block.html]
|
|
||||||
[Test setValueAtTime with start time not on a block boundary]
|
|
||||||
expected: FAIL
|
|
|
@ -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.]
|
[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
|
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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue