/* 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(), } } }