aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/rtcdatachannel.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/rtcdatachannel.rs')
-rw-r--r--components/script/dom/rtcdatachannel.rs260
1 files changed, 260 insertions, 0 deletions
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<dyn WebRtcDataChannelBackend>,
+ label: USVString,
+ ordered: bool,
+ max_packet_life_time: Option<u16>,
+ max_retransmits: Option<u16>,
+ protocol: USVString,
+ negotiated: bool,
+ id: Option<u16>,
+}
+
+impl RTCDataChannel {
+ #[allow(unrooted_must_root)]
+ pub fn new_inherited(
+ webrtc_controller: &DomRefCell<Option<WebRtcController>>,
+ label: USVString,
+ options: &RTCDataChannelInit,
+ ) -> RTCDataChannel {
+ let webrtc = webrtc_controller.borrow();
+ let webrtc = webrtc.as_ref().unwrap();
+
+ let (sender, receiver) = mpsc::channel::<Box<dyn WebRtcDataChannelBackend>>();
+
+ 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<Option<WebRtcController>>,
+ label: USVString,
+ options: &RTCDataChannelInit,
+ ) -> DomRoot<RTCDataChannel> {
+ 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::<Event>().fire(self.upcast());
+ }
+
+ fn on_close(&self) {
+ let event = Event::new(
+ &self.global(),
+ atom!("close"),
+ EventBubbles::DoesNotBubble,
+ EventCancelable::NotCancelable,
+ );
+ event.upcast::<Event>().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<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
+ }
+
+ // 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<ArrayBuffer>) -> () {}
+
+ // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-send!overload-3
+ fn Send___(&self, data: CustomAutoRooterGuard<ArrayBufferView>) -> () {}
+}
+
+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(),
+ }
+ }
+}