Keep ownership of observers on the Rust side

This commit is contained in:
Théo Monnom
2022-09-18 15:22:57 +02:00
parent 81b45d9c48
commit dca8cf7796
11 changed files with 88 additions and 70 deletions
@@ -18,7 +18,7 @@ namespace livekit {
public: public:
explicit DataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel); explicit DataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel);
void register_observer(std::unique_ptr<NativeDataChannelObserver> observer); void register_observer(NativeDataChannelObserver &observer);
void unregister_observer(); void unregister_observer();
void close(); void close();
private: private:
@@ -42,7 +42,7 @@ namespace livekit {
rust::Box<DataChannelObserverWrapper> observer_; rust::Box<DataChannelObserverWrapper> observer_;
}; };
std::unique_ptr<NativeDataChannelObserver> create_native_peer_connection_observer(rust::Box<DataChannelObserverWrapper> observer); std::unique_ptr<NativeDataChannelObserver> create_native_data_channel_observer(rust::Box<DataChannelObserverWrapper> observer);
} // livekit } // livekit
#endif //CLIENT_SDK_NATIVE_DATA_CHANNEL_H #endif //CLIENT_SDK_NATIVE_DATA_CHANNEL_H
@@ -17,18 +17,17 @@ namespace livekit {
class PeerConnection { class PeerConnection {
public: public:
explicit PeerConnection(rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection, std::unique_ptr<NativePeerConnectionObserver> observer); explicit PeerConnection(rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection);
void create_offer(std::unique_ptr<NativeCreateSdpObserverHandle> observer, RTCOfferAnswerOptions options); void create_offer(NativeCreateSdpObserverHandle &observer, RTCOfferAnswerOptions options);
void create_answer(std::unique_ptr<NativeCreateSdpObserverHandle> observer, RTCOfferAnswerOptions options); void create_answer(NativeCreateSdpObserverHandle &observer, RTCOfferAnswerOptions options);
void set_local_description(std::unique_ptr<SessionDescription> desc, std::unique_ptr<NativeSetLocalSdpObserverHandle> observer); void set_local_description(std::unique_ptr<SessionDescription> desc, NativeSetLocalSdpObserverHandle &observer);
void set_remote_description(std::unique_ptr<SessionDescription> desc, std::unique_ptr<NativeSetRemoteSdpObserverHandle> observer); void set_remote_description(std::unique_ptr<SessionDescription> desc, NativeSetRemoteSdpObserverHandle &observer);
std::unique_ptr<DataChannel> create_data_channel(rust::String label, std::unique_ptr<NativeDataChannelInit> init); std::unique_ptr<DataChannel> create_data_channel(rust::String label, std::unique_ptr<NativeDataChannelInit> init);
void close(); void close();
private: private:
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
std::unique_ptr<NativePeerConnectionObserver> observer_;
}; };
static std::unique_ptr<PeerConnection> _unique_peer_connection() { static std::unique_ptr<PeerConnection> _unique_peer_connection() {
@@ -17,7 +17,7 @@ namespace livekit {
public: public:
PeerConnectionFactory(); PeerConnectionFactory();
std::unique_ptr<PeerConnection> create_peer_connection(std::unique_ptr<NativeRTCConfiguration> config, std::unique_ptr<NativePeerConnectionObserver> observer) const; std::unique_ptr<PeerConnection> create_peer_connection(std::unique_ptr<NativeRTCConfiguration> config, NativePeerConnectionObserver &observer) const;
private: private:
std::unique_ptr<rtc::Thread> network_thread_; std::unique_ptr<rtc::Thread> network_thread_;
@@ -13,8 +13,8 @@ namespace livekit {
} }
void DataChannel::register_observer(std::unique_ptr<NativeDataChannelObserver> observer) { void DataChannel::register_observer(NativeDataChannelObserver &observer) {
data_channel_->RegisterObserver(observer.get()); data_channel_->RegisterObserver(&observer);
} }
void DataChannel::unregister_observer() { void DataChannel::unregister_observer() {
@@ -65,7 +65,7 @@ namespace livekit {
observer_->on_buffered_amount_change(sent_data_size); observer_->on_buffered_amount_change(sent_data_size);
} }
std::unique_ptr<NativeDataChannelObserver> create_native_peer_connection_observer(rust::Box<DataChannelObserverWrapper> observer){ std::unique_ptr<NativeDataChannelObserver> create_native_data_channel_observer(rust::Box<DataChannelObserverWrapper> observer){
return std::make_unique<NativeDataChannelObserver>(std::move(observer)); return std::make_unique<NativeDataChannelObserver>(std::move(observer));
} }
} // livekit } // livekit
@@ -60,7 +60,6 @@ pub mod ffi {
type NativeDataChannelInit; type NativeDataChannelInit;
type NativeDataChannelObserver; type NativeDataChannelObserver;
fn close(self: Pin<&mut DataChannel>); fn close(self: Pin<&mut DataChannel>);
fn create_data_channel_init(init: DataChannelInit) -> UniquePtr<NativeDataChannelInit>; fn create_data_channel_init(init: DataChannelInit) -> UniquePtr<NativeDataChannelInit>;
@@ -21,26 +21,24 @@ namespace livekit {
return rtc_options; return rtc_options;
} }
PeerConnection::PeerConnection(rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection, PeerConnection::PeerConnection(rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection) : peer_connection_(std::move(peer_connection)) {
std::unique_ptr<NativePeerConnectionObserver> observer) : peer_connection_(
std::move(peer_connection)), observer_(std::move(observer)) {
} }
void PeerConnection::create_offer(std::unique_ptr<NativeCreateSdpObserverHandle> observer_handle, RTCOfferAnswerOptions options) { void PeerConnection::create_offer(NativeCreateSdpObserverHandle &observer_handle, RTCOfferAnswerOptions options) {
peer_connection_->CreateOffer(observer_handle->observer.get(), toNativeOfferAnswerOptions(options)); peer_connection_->CreateOffer(observer_handle.observer.get(), toNativeOfferAnswerOptions(options));
} }
void PeerConnection::create_answer(std::unique_ptr<NativeCreateSdpObserverHandle> observer_handle, RTCOfferAnswerOptions options) { void PeerConnection::create_answer(NativeCreateSdpObserverHandle &observer_handle, RTCOfferAnswerOptions options) {
peer_connection_->CreateAnswer(observer_handle->observer.get(), toNativeOfferAnswerOptions(options)); peer_connection_->CreateAnswer(observer_handle.observer.get(), toNativeOfferAnswerOptions(options));
} }
void PeerConnection::set_local_description(std::unique_ptr<SessionDescription> desc, std::unique_ptr<NativeSetLocalSdpObserverHandle> observer) { void PeerConnection::set_local_description(std::unique_ptr<SessionDescription> desc, NativeSetLocalSdpObserverHandle &observer) {
peer_connection_->SetLocalDescription(desc->clone()->release(), observer->observer); peer_connection_->SetLocalDescription(desc->clone()->release(), observer.observer);
} }
void PeerConnection::set_remote_description(std::unique_ptr<SessionDescription> desc, std::unique_ptr<NativeSetRemoteSdpObserverHandle> observer) { void PeerConnection::set_remote_description(std::unique_ptr<SessionDescription> desc, NativeSetRemoteSdpObserverHandle &observer) {
peer_connection_->SetRemoteDescription(desc->clone()->release(), observer->observer); peer_connection_->SetRemoteDescription(desc->clone()->release(), observer.observer);
} }
std::unique_ptr<DataChannel> PeerConnection::create_data_channel(rust::String label, std::unique_ptr<NativeDataChannelInit> init) { std::unique_ptr<DataChannel> PeerConnection::create_data_channel(rust::String label, std::unique_ptr<NativeDataChannelInit> init) {
@@ -109,26 +109,38 @@ pub mod ffi {
type NativePeerConnectionObserver; type NativePeerConnectionObserver;
type PeerConnection; type PeerConnection;
fn create_offer( /// SAFETY
/// The observer must live as long as the operation ends
unsafe fn create_offer(
self: Pin<&mut PeerConnection>, self: Pin<&mut PeerConnection>,
observer: UniquePtr<NativeCreateSdpObserverHandle>, observer: Pin<&mut NativeCreateSdpObserverHandle>,
options: RTCOfferAnswerOptions, options: RTCOfferAnswerOptions,
); );
fn create_answer(
/// SAFETY
/// The observer must live as long as the operation ends
unsafe fn create_answer(
self: Pin<&mut PeerConnection>, self: Pin<&mut PeerConnection>,
observer: UniquePtr<NativeCreateSdpObserverHandle>, observer: Pin<&mut NativeCreateSdpObserverHandle>,
options: RTCOfferAnswerOptions, options: RTCOfferAnswerOptions,
); );
fn set_local_description(
/// SAFETY
/// The observer must live as long as the operation ends
unsafe fn set_local_description(
self: Pin<&mut PeerConnection>, self: Pin<&mut PeerConnection>,
desc: UniquePtr<SessionDescription>, desc: UniquePtr<SessionDescription>,
observer: UniquePtr<NativeSetLocalSdpObserverHandle>, observer: Pin<&mut NativeSetLocalSdpObserverHandle>,
); );
fn set_remote_description(
/// SAFETY
/// The observer must live as long as the operation ends
unsafe fn set_remote_description(
self: Pin<&mut PeerConnection>, self: Pin<&mut PeerConnection>,
desc: UniquePtr<SessionDescription>, desc: UniquePtr<SessionDescription>,
observer: UniquePtr<NativeSetRemoteSdpObserverHandle>, observer: Pin<&mut NativeSetRemoteSdpObserverHandle>,
); );
fn close(self: Pin<&mut PeerConnection>); fn close(self: Pin<&mut PeerConnection>);
fn create_native_peer_connection_observer( fn create_native_peer_connection_observer(
@@ -212,10 +224,7 @@ pub mod ffi {
self: &PeerConnectionObserverWrapper, self: &PeerConnectionObserverWrapper,
receiver: UniquePtr<RtpReceiver>, receiver: UniquePtr<RtpReceiver>,
); );
unsafe fn on_interesting_usage( unsafe fn on_interesting_usage(self: &PeerConnectionObserverWrapper, usage_pattern: i32);
self: &PeerConnectionObserverWrapper,
usage_pattern: i32,
);
} }
} }
@@ -358,10 +367,7 @@ impl PeerConnectionObserverWrapper {
(*self.observer).on_ice_connection_receiving_change(receiving); (*self.observer).on_ice_connection_receiving_change(receiving);
} }
unsafe fn on_ice_selected_candidate_pair_changed( unsafe fn on_ice_selected_candidate_pair_changed(&self, event: ffi::CandidatePairChangeEvent) {
&self,
event: ffi::CandidatePairChangeEvent,
) {
(*self.observer).on_ice_selected_candidate_pair_changed(event); (*self.observer).on_ice_selected_candidate_pair_changed(event);
} }
@@ -53,15 +53,15 @@ namespace livekit{
} }
} }
std::unique_ptr<PeerConnection> PeerConnectionFactory::create_peer_connection(std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config, std::unique_ptr<NativePeerConnectionObserver> observer) const { std::unique_ptr<PeerConnection> PeerConnectionFactory::create_peer_connection(std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config, NativePeerConnectionObserver &observer) const {
webrtc::PeerConnectionDependencies deps{observer.get()}; webrtc::PeerConnectionDependencies deps{&observer};
auto result = peer_factory_->CreatePeerConnectionOrError(*config, std::move(deps)); auto result = peer_factory_->CreatePeerConnectionOrError(*config, std::move(deps));
if(!result.ok()) { if(!result.ok()) {
throw std::runtime_error(serialize_error(to_error(result.error()))); throw std::runtime_error(serialize_error(to_error(result.error())));
} }
return std::make_unique<PeerConnection>(result.value(), std::move(observer)); return std::make_unique<PeerConnection>(result.value());
} }
std::unique_ptr<PeerConnectionFactory> create_peer_connection_factory() { std::unique_ptr<PeerConnectionFactory> create_peer_connection_factory() {
@@ -44,10 +44,12 @@ pub mod ffi {
fn create_peer_connection_factory() -> UniquePtr<PeerConnectionFactory>; fn create_peer_connection_factory() -> UniquePtr<PeerConnectionFactory>;
fn create_rtc_configuration(conf: RTCConfiguration) -> UniquePtr<NativeRTCConfiguration>; fn create_rtc_configuration(conf: RTCConfiguration) -> UniquePtr<NativeRTCConfiguration>;
fn create_peer_connection( /// SAFETY
/// The observer must live as long as the PeerConnection
unsafe fn create_peer_connection(
self: &PeerConnectionFactory, self: &PeerConnectionFactory,
config: UniquePtr<NativeRTCConfiguration>, config: UniquePtr<NativeRTCConfiguration>,
observer: UniquePtr<NativePeerConnectionObserver>, observer: Pin<&mut NativePeerConnectionObserver>,
) -> Result<UniquePtr<PeerConnection>>; ) -> Result<UniquePtr<PeerConnection>>;
} }
} }
+33 -20
View File
@@ -30,16 +30,21 @@ pub enum SdpError {
pub struct PeerConnection { pub struct PeerConnection {
cxx_handle: UniquePtr<sys_pc::ffi::PeerConnection>, cxx_handle: UniquePtr<sys_pc::ffi::PeerConnection>,
observer: Box<InternalObserver>, observer: Box<InternalObserver>,
// Keep alive for C++
native_observer: UniquePtr<sys_pc::ffi::NativePeerConnectionObserver>
} }
impl PeerConnection { impl PeerConnection {
pub(crate) fn new( pub(crate) fn new(
cxx_handle: UniquePtr<sys_pc::ffi::PeerConnection>, cxx_handle: UniquePtr<sys_pc::ffi::PeerConnection>,
observer: Box<InternalObserver>, observer: Box<InternalObserver>,
native_observer: UniquePtr<sys_pc::ffi::NativePeerConnectionObserver>
) -> Self { ) -> Self {
Self { Self {
cxx_handle, cxx_handle,
observer, observer,
native_observer
} }
} }
@@ -48,11 +53,14 @@ impl PeerConnection {
let wrapper = let wrapper =
sys_jsep::CreateSdpObserverWrapper::new(Box::new(InternalCreateSdpObserver { tx })); sys_jsep::CreateSdpObserverWrapper::new(Box::new(InternalCreateSdpObserver { tx }));
let native_wrapper = sys_jsep::ffi::create_native_create_sdp_observer(Box::new(wrapper)); let mut native_wrapper =
sys_jsep::ffi::create_native_create_sdp_observer(Box::new(wrapper));
self.cxx_handle unsafe {
.pin_mut() self.cxx_handle
.create_offer(native_wrapper, RTCOfferAnswerOptions::default()); .pin_mut()
.create_offer(native_wrapper.pin_mut(), RTCOfferAnswerOptions::default());
}
match rx.recv().await { match rx.recv().await {
Some(value) => value.map_err(Into::into), Some(value) => value.map_err(Into::into),
@@ -65,11 +73,14 @@ impl PeerConnection {
let wrapper = let wrapper =
sys_jsep::CreateSdpObserverWrapper::new(Box::new(InternalCreateSdpObserver { tx })); sys_jsep::CreateSdpObserverWrapper::new(Box::new(InternalCreateSdpObserver { tx }));
let native_wrapper = sys_jsep::ffi::create_native_create_sdp_observer(Box::new(wrapper)); let mut native_wrapper =
sys_jsep::ffi::create_native_create_sdp_observer(Box::new(wrapper));
self.cxx_handle unsafe {
.pin_mut() self.cxx_handle
.create_answer(native_wrapper, RTCOfferAnswerOptions::default()); .pin_mut()
.create_answer(native_wrapper.pin_mut(), RTCOfferAnswerOptions::default());
}
match rx.recv().await { match rx.recv().await {
Some(value) => value.map_err(Into::into), Some(value) => value.map_err(Into::into),
@@ -84,11 +95,14 @@ impl PeerConnection {
let (tx, mut rx) = mpsc::channel(1); let (tx, mut rx) = mpsc::channel(1);
let wrapper = let wrapper =
sys_jsep::SetLocalSdpObserverWrapper::new(Box::new(InternalSetLocalSdpObserver { tx })); sys_jsep::SetLocalSdpObserverWrapper::new(Box::new(InternalSetLocalSdpObserver { tx }));
let native_wrapper = sys_jsep::ffi::create_native_set_local_sdp_observer(Box::new(wrapper)); let mut native_wrapper =
sys_jsep::ffi::create_native_set_local_sdp_observer(Box::new(wrapper));
self.cxx_handle unsafe {
.pin_mut() self.cxx_handle
.set_local_description(desc.release(), native_wrapper); .pin_mut()
.set_local_description(desc.release(), native_wrapper.pin_mut());
}
match rx.recv().await { match rx.recv().await {
Some(value) => value.map_err(Into::into), Some(value) => value.map_err(Into::into),
@@ -105,12 +119,14 @@ impl PeerConnection {
sys_jsep::SetRemoteSdpObserverWrapper::new(Box::new(InternalSetRemoteSdpObserver { sys_jsep::SetRemoteSdpObserverWrapper::new(Box::new(InternalSetRemoteSdpObserver {
tx, tx,
})); }));
let native_wrapper = let mut native_wrapper =
sys_jsep::ffi::create_native_set_remote_sdp_observer(Box::new(wrapper)); sys_jsep::ffi::create_native_set_remote_sdp_observer(Box::new(wrapper));
self.cxx_handle unsafe {
.pin_mut() self.cxx_handle
.set_remote_description(desc.release(), native_wrapper); .pin_mut()
.set_remote_description(desc.release(), native_wrapper.pin_mut());
}
match rx.recv().await { match rx.recv().await {
Some(value) => value.map_err(Into::into), Some(value) => value.map_err(Into::into),
@@ -532,10 +548,7 @@ impl sys_pc::PeerConnectionObserver for InternalObserver {
} }
} }
fn on_remove_track( fn on_remove_track(&self, receiver: UniquePtr<libwebrtc_sys::rtp_receiver::ffi::RtpReceiver>) {
&self,
receiver: UniquePtr<libwebrtc_sys::rtp_receiver::ffi::RtpReceiver>,
) {
trace!("on_remove_track"); trace!("on_remove_track");
let mut handler = self.on_remove_track_handler.lock().unwrap(); let mut handler = self.on_remove_track_handler.lock().unwrap();
if let Some(f) = handler.as_mut() { if let Some(f) = handler.as_mut() {
@@ -26,15 +26,16 @@ impl PeerConnectionFactory {
unsafe { unsafe {
let mut observer = Box::new(InternalObserver::default()); let mut observer = Box::new(InternalObserver::default());
let observer_wrapper = sys_pc::PeerConnectionObserverWrapper::new(&mut *observer); let mut native_observer = sys_pc::ffi::create_native_peer_connection_observer(
let native_observer = Box::new(sys_pc::PeerConnectionObserverWrapper::new(&mut *observer)),
sys_pc::ffi::create_native_peer_connection_observer(Box::new(observer_wrapper)); );
let res = self let res = self
.cxx_handle .cxx_handle
.create_peer_connection(native_config, native_observer); .create_peer_connection(native_config, native_observer.pin_mut());
match res { match res {
Ok(cxx_handle) => Ok(PeerConnection::new(cxx_handle, observer)), Ok(cxx_handle) => Ok(PeerConnection::new(cxx_handle, observer, native_observer)),
Err(e) => { Err(e) => {
Err(RTCError::from(e.what())) // TODO Err(RTCError::from(e.what())) // TODO
} }