#![allow(
clippy::as_conversions,
clippy::doc_markdown, // TODO: From generated code in #[frb].
clippy::missing_panics_doc,
clippy::needless_pass_by_value,
clippy::undocumented_unsafe_blocks,
clippy::unwrap_used,
non_snake_case,
)]
use std::{
panic::{RefUnwindSafe, UnwindSafe},
ptr,
};
use flutter_rust_bridge::{frb, DartOpaque, RustOpaque, SyncReturn};
use tracerr::Traced;
use crate::{
api::{utils::new_dart_opaque, Error, Error as DartError, ForeignClass},
connection,
media::{
self,
constraints::{ConstrainBoolean, ConstrainU32},
EnumerateDevicesError, EnumerateDisplaysError,
InvalidOutputAudioDeviceIdError, MediaDirection, MediaKind,
MediaSourceKind, MicVolumeError,
},
platform::{self, utils::dart_future::IntoDartFuture},
room::{self, ConstraintsUpdateError, RoomJoinError},
};
pub use dart_sys::Dart_Handle;
pub use crate::{
connection::ConnectionHandle,
jason::Jason,
media::{
track::{local::LocalMediaTrack, remote::Track as RemoteMediaTrack},
MediaManagerHandle,
},
room::{RoomCloseReason, RoomHandle},
rpc::ReconnectHandle,
};
#[derive(Debug)]
pub struct ApiMediaDeviceDetails {
pub kind: media::MediaDeviceKind,
pub device_id: String,
pub label: String,
pub group_id: Option<String>,
pub is_failed: bool,
}
#[derive(Debug)]
pub struct ApiMediaDisplayDetails {
pub device_id: String,
pub title: Option<String>,
}
#[derive(Debug)]
#[frb]
pub struct ApiAudioConstraints {
#[frb(non_final)]
pub device_id: Option<String>,
#[frb(non_final)]
pub auto_gain_control: Option<ConstrainBoolean>,
}
impl From<ApiAudioConstraints> for media::AudioTrackConstraints {
fn from(value: ApiAudioConstraints) -> Self {
let mut res = Self::new();
if let Some(id) = value.device_id {
res.device_id(id);
}
if let Some(auto_gain_control) = value.auto_gain_control {
match auto_gain_control {
ConstrainBoolean::Exact(e) => res.exact_auto_gain_control(e),
ConstrainBoolean::Ideal(i) => res.ideal_auto_gain_control(i),
}
}
res
}
}
#[derive(Copy, Clone, Debug)]
pub enum ApiConstrainFacingMode {
Exact(media::FacingMode),
Ideal(media::FacingMode),
}
#[derive(Debug)]
#[frb]
pub struct ApiDeviceVideoTrackConstraints {
#[frb(non_final)]
pub device_id: Option<String>,
#[frb(non_final)]
pub facing_mode: Option<ApiConstrainFacingMode>,
#[frb(non_final)]
pub height: Option<ConstrainU32>,
#[frb(non_final)]
pub width: Option<ConstrainU32>,
}
impl From<ApiDeviceVideoTrackConstraints>
for media::DeviceVideoTrackConstraints
{
fn from(value: ApiDeviceVideoTrackConstraints) -> Self {
let mut res = Self::new();
if let Some(id) = value.device_id {
res.device_id(id);
}
if let Some(mode) = value.facing_mode {
match mode {
ApiConstrainFacingMode::Exact(e) => res.exact_facing_mode(e),
ApiConstrainFacingMode::Ideal(i) => res.ideal_facing_mode(i),
}
}
if let Some(height) = value.height {
match height {
ConstrainU32::Exact(e) => res.exact_height(e),
ConstrainU32::Ideal(i) => res.ideal_height(i),
ConstrainU32::Range(min, max) => res.height_in_range(min, max),
}
}
if let Some(width) = value.width {
match width {
ConstrainU32::Exact(e) => res.exact_width(e),
ConstrainU32::Ideal(i) => res.ideal_width(i),
ConstrainU32::Range(min, max) => res.width_in_range(min, max),
}
}
res
}
}
#[derive(Debug)]
#[frb]
pub struct ApiDisplayVideoTrackConstraints {
#[frb(non_final)]
pub device_id: Option<String>,
#[frb(non_final)]
pub height: Option<ConstrainU32>,
#[frb(non_final)]
pub width: Option<ConstrainU32>,
#[frb(non_final)]
pub frame_rate: Option<ConstrainU32>,
}
impl From<ApiDisplayVideoTrackConstraints>
for media::DisplayVideoTrackConstraints
{
fn from(value: ApiDisplayVideoTrackConstraints) -> Self {
let mut res = Self::new();
if let Some(id) = value.device_id {
res.device_id(id);
}
if let Some(height) = value.height {
match height {
ConstrainU32::Exact(e) => res.exact_height(e),
ConstrainU32::Ideal(i) => res.ideal_height(i),
ConstrainU32::Range(..) => unreachable!(),
}
}
if let Some(width) = value.width {
match width {
ConstrainU32::Exact(e) => res.exact_width(e),
ConstrainU32::Ideal(i) => res.ideal_width(i),
ConstrainU32::Range(..) => unreachable!(),
}
}
if let Some(frame_rate) = value.frame_rate {
match frame_rate {
ConstrainU32::Exact(e) => res.exact_frame_rate(e),
ConstrainU32::Ideal(i) => res.ideal_frame_rate(i),
ConstrainU32::Range(..) => unreachable!(),
}
}
res
}
}
#[derive(Debug)]
#[frb]
pub struct ApiMediaStreamSettings {
#[frb(non_final)]
pub audio: Option<ApiAudioConstraints>,
#[frb(non_final)]
pub device_video: Option<ApiDeviceVideoTrackConstraints>,
#[frb(non_final)]
pub display_video: Option<ApiDisplayVideoTrackConstraints>,
}
impl From<ApiMediaStreamSettings> for media::MediaStreamSettings {
fn from(value: ApiMediaStreamSettings) -> Self {
let mut res = Self::new();
if let Some(audio) = value.audio {
res.audio(audio.into());
}
if let Some(device) = value.device_video {
res.device_video(device.into());
}
if let Some(display) = value.display_video {
res.display_video(display.into());
}
res
}
}
impl<T> ForeignClass for Vec<T> {}
impl ForeignClass for ConnectionHandle {}
impl RefUnwindSafe for ConnectionHandle {}
impl UnwindSafe for ConnectionHandle {}
#[must_use]
pub fn connection_handle_from_ptr(
ptr: usize,
) -> SyncReturn<RustOpaque<ConnectionHandle>> {
SyncReturn(unsafe {
RustOpaque::new(ConnectionHandle::from_ptr(
ptr::NonNull::new(ptr as _).unwrap(),
))
})
}
pub fn connection_handle_on_close(
connection: RustOpaque<ConnectionHandle>,
f: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
let f = unsafe {
platform::Function::new(f.try_unwrap().unwrap().into_raw().cast())
};
connection.on_close(f).map_err(DartError::from)?;
Ok(SyncReturn(()))
}
pub fn connection_handle_on_remote_track_added(
connection: RustOpaque<ConnectionHandle>,
f: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
let f = unsafe {
platform::Function::new(f.try_unwrap().unwrap().into_raw().cast())
};
connection
.on_remote_track_added(f)
.map_err(DartError::from)?;
Ok(SyncReturn(()))
}
pub fn connection_handle_on_quality_score_update(
connection: RustOpaque<ConnectionHandle>,
f: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
let f = unsafe {
platform::Function::new(f.try_unwrap().unwrap().into_raw().cast())
};
connection
.on_quality_score_update(f)
.map_err(DartError::from)?;
Ok(SyncReturn(()))
}
pub fn connection_handle_get_remote_member_id(
connection: RustOpaque<ConnectionHandle>,
) -> Result<SyncReturn<String>, DartOpaque> {
Ok(SyncReturn(
connection.get_remote_member_id().map_err(DartError::from)?,
))
}
#[must_use]
pub fn connection_handle_enable_remote_audio(
connection: RustOpaque<ConnectionHandle>,
) -> SyncReturn<DartOpaque> {
SyncReturn(
async move {
connection.enable_remote_audio().await?;
Ok::<(), Traced<connection::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn connection_handle_disable_remote_audio(
connection: RustOpaque<ConnectionHandle>,
) -> SyncReturn<DartOpaque> {
SyncReturn(
async move {
connection.disable_remote_audio().await?;
Ok::<(), Traced<connection::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn connection_handle_enable_remote_video(
connection: RustOpaque<ConnectionHandle>,
source_kind: Option<MediaSourceKind>,
) -> SyncReturn<DartOpaque> {
let result = async move {
connection.enable_remote_video(source_kind).await?;
Ok::<(), Traced<connection::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn connection_handle_disable_remote_video(
connection: RustOpaque<ConnectionHandle>,
source_kind: Option<MediaSourceKind>,
) -> SyncReturn<DartOpaque> {
let result = async move {
connection.disable_remote_video(source_kind).await?;
Ok::<(), Traced<connection::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
impl RefUnwindSafe for Jason {}
impl UnwindSafe for Jason {}
#[must_use]
pub fn on_panic(cb: DartOpaque) -> SyncReturn<()> {
platform::set_panic_callback(unsafe {
platform::Function::new(cb.try_unwrap().unwrap().into_raw().cast())
});
SyncReturn(())
}
#[must_use]
pub fn jason_new() -> SyncReturn<RustOpaque<Jason>> {
SyncReturn(RustOpaque::new(Jason::new(None)))
}
#[must_use]
pub fn jason_init_room(
jason: RustOpaque<Jason>,
) -> SyncReturn<RustOpaque<RoomHandle>> {
SyncReturn(RustOpaque::new(jason.init_room()))
}
#[must_use]
pub fn jason_media_manager(
jason: RustOpaque<Jason>,
) -> SyncReturn<RustOpaque<MediaManagerHandle>> {
SyncReturn(RustOpaque::new(jason.media_manager()))
}
#[must_use]
pub fn jason_close_room(
jason: RustOpaque<Jason>,
room_to_delete: RustOpaque<RoomHandle>,
) -> SyncReturn<()> {
let room_to_delete = room_to_delete.try_unwrap().unwrap();
jason.close_room(&room_to_delete);
SyncReturn(())
}
#[must_use]
pub fn jason_dispose(jason: RustOpaque<Jason>) -> SyncReturn<()> {
let jason = jason.try_unwrap().unwrap();
jason.dispose();
SyncReturn(())
}
impl ForeignClass for LocalMediaTrack {}
#[must_use]
pub fn local_media_track_from_ptr(
ptr: usize,
) -> SyncReturn<RustOpaque<LocalMediaTrack>> {
SyncReturn(unsafe {
RustOpaque::new(LocalMediaTrack::from_ptr(
ptr::NonNull::new(ptr as _).unwrap(),
))
})
}
#[must_use]
pub fn vec_local_tracks_from_ptr(
ptr: usize,
) -> SyncReturn<Vec<RustOpaque<LocalMediaTrack>>> {
SyncReturn(unsafe {
Vec::<LocalMediaTrack>::from_ptr(ptr::NonNull::new(ptr as _).unwrap())
.into_iter()
.map(RustOpaque::new)
.collect()
})
}
#[must_use]
pub fn local_media_track_get_track(
track: RustOpaque<LocalMediaTrack>,
) -> SyncReturn<DartOpaque> {
SyncReturn(unsafe { new_dart_opaque(track.get_track().handle()) })
}
#[must_use]
pub fn local_media_track_kind(
track: RustOpaque<LocalMediaTrack>,
) -> SyncReturn<MediaKind> {
SyncReturn(track.kind())
}
#[must_use]
pub fn local_media_track_on_ended(
track: RustOpaque<LocalMediaTrack>,
f: DartOpaque,
) -> SyncReturn<()> {
track.on_ended(unsafe {
platform::Function::new(f.try_unwrap().unwrap().into_raw().cast())
});
SyncReturn(())
}
#[must_use]
pub fn local_media_track_state(
track: RustOpaque<LocalMediaTrack>,
) -> SyncReturn<DartOpaque> {
SyncReturn(
async move { Ok::<_, Error>(track.state().await as i64) }
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn is_on_audio_level_available(
track: RustOpaque<LocalMediaTrack>,
) -> SyncReturn<bool> {
SyncReturn(track.is_on_audio_level_available())
}
#[must_use]
pub fn on_audio_level_changed(
track: RustOpaque<LocalMediaTrack>,
f: DartOpaque,
) -> SyncReturn<()> {
track.on_audio_level_changed(unsafe {
platform::Function::new(f.try_unwrap().unwrap().into_raw().cast())
});
SyncReturn(())
}
#[must_use]
pub fn local_media_track_media_source_kind(
track: RustOpaque<LocalMediaTrack>,
) -> SyncReturn<MediaSourceKind> {
SyncReturn(track.media_source_kind())
}
#[must_use]
pub fn local_media_track_free(
track: RustOpaque<LocalMediaTrack>,
) -> SyncReturn<DartOpaque> {
let track = track.try_unwrap().unwrap();
SyncReturn(
async move {
track.maybe_stop().await;
Ok::<_, Error>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn vec_media_device_details_from_ptr(
ptr: usize,
) -> SyncReturn<Vec<ApiMediaDeviceDetails>> {
SyncReturn(unsafe {
Vec::<ApiMediaDeviceDetails>::from_ptr(
ptr::NonNull::new(ptr as _).unwrap(),
)
})
}
#[must_use]
pub fn vec_media_display_details_from_ptr(
ptr: usize,
) -> SyncReturn<Vec<ApiMediaDisplayDetails>> {
SyncReturn(unsafe {
Vec::<ApiMediaDisplayDetails>::from_ptr(
ptr::NonNull::new(ptr as _).unwrap(),
)
})
}
impl RefUnwindSafe for MediaManagerHandle {}
impl UnwindSafe for MediaManagerHandle {}
#[must_use]
pub fn media_manager_handle_init_local_tracks(
manager: RustOpaque<MediaManagerHandle>,
caps: ApiMediaStreamSettings,
) -> SyncReturn<DartOpaque> {
let manager = MediaManagerHandle::clone(&manager);
SyncReturn(
async move { manager.init_local_tracks(caps.into()).await }
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn media_manager_handle_enumerate_devices(
manager: RustOpaque<MediaManagerHandle>,
) -> SyncReturn<DartOpaque> {
let manager = MediaManagerHandle::clone(&manager);
let result = async move {
Ok::<Vec<_>, Traced<EnumerateDevicesError>>(
manager
.enumerate_devices()
.await?
.into_iter()
.map(|v| ApiMediaDeviceDetails {
kind: v.kind(),
device_id: v.device_id(),
label: v.label(),
group_id: v.group_id(),
is_failed: v.is_failed(),
})
.collect(),
)
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn media_manager_handle_enumerate_displays(
manager: RustOpaque<MediaManagerHandle>,
) -> SyncReturn<DartOpaque> {
let manager = MediaManagerHandle::clone(&manager);
let result = async move {
Ok::<Vec<_>, Traced<EnumerateDisplaysError>>(
manager
.enumerate_displays()
.await?
.into_iter()
.map(|v| ApiMediaDisplayDetails {
device_id: v.device_id(),
title: v.title(),
})
.collect(),
)
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn media_manager_handle_set_output_audio_id(
manager: RustOpaque<MediaManagerHandle>,
device_id: String,
) -> SyncReturn<DartOpaque> {
let manager = MediaManagerHandle::clone(&manager);
let result = async move {
manager
.set_output_audio_id(device_id)
.await
.map_err(tracerr::map_from_and_wrap!())?;
Ok::<_, Traced<InvalidOutputAudioDeviceIdError>>(())
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn media_manager_handle_set_microphone_volume(
manager: RustOpaque<MediaManagerHandle>,
level: i64,
) -> SyncReturn<DartOpaque> {
let manager = MediaManagerHandle::clone(&manager);
let result = async move {
manager
.set_microphone_volume(level)
.await
.map_err(tracerr::map_from_and_wrap!())?;
Ok::<_, Traced<MicVolumeError>>(())
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn media_manager_handle_microphone_volume_is_available(
manager: RustOpaque<MediaManagerHandle>,
) -> SyncReturn<DartOpaque> {
let manager = MediaManagerHandle::clone(&manager);
let result = async move { manager.microphone_volume_is_available().await }
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn media_manager_handle_microphone_volume(
manager: RustOpaque<MediaManagerHandle>,
) -> SyncReturn<DartOpaque> {
let manager = MediaManagerHandle::clone(&manager);
SyncReturn(
async move { manager.microphone_volume().await }
.into_dart_future()
.into_dart_opaque(),
)
}
pub fn media_manager_handle_on_device_change(
manager: RustOpaque<MediaManagerHandle>,
cb: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
let manager = MediaManagerHandle::clone(&manager);
manager
.on_device_change(unsafe {
platform::Function::new(cb.try_unwrap().unwrap().into_raw().cast())
})
.map_err(DartError::from)?;
Ok(SyncReturn(()))
}
impl ForeignClass for ReconnectHandle {}
impl RefUnwindSafe for ReconnectHandle {}
impl UnwindSafe for ReconnectHandle {}
#[must_use]
pub fn reconnect_handle_from_ptr(
ptr: usize,
) -> SyncReturn<RustOpaque<ReconnectHandle>> {
SyncReturn(unsafe {
RustOpaque::new(ReconnectHandle::from_ptr(
ptr::NonNull::new(ptr as _).unwrap(),
))
})
}
#[must_use]
pub fn reconnect_handle_reconnect_with_delay(
reconnect_handle: RustOpaque<ReconnectHandle>,
delay_ms: u32,
) -> SyncReturn<DartOpaque> {
let reconnect_handle = ReconnectHandle::clone(&reconnect_handle);
let result = async move {
reconnect_handle.reconnect_with_delay(delay_ms).await?;
Ok::<_, Error>(())
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn reconnect_handle_reconnect_with_backoff(
reconnect_handle: RustOpaque<ReconnectHandle>,
starting_delay: u32,
multiplier: f64,
max_delay: u32,
max_elapsed_time_ms: Option<u32>,
) -> SyncReturn<DartOpaque> {
let reconnect_handle = ReconnectHandle::clone(&reconnect_handle);
let result = async move {
reconnect_handle
.reconnect_with_backoff(
starting_delay,
multiplier,
max_delay,
max_elapsed_time_ms,
)
.await?;
Ok::<_, DartError>(())
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
impl ForeignClass for RemoteMediaTrack {}
impl RefUnwindSafe for RemoteMediaTrack {}
impl UnwindSafe for RemoteMediaTrack {}
#[must_use]
pub fn remote_media_track_from_ptr(
ptr: usize,
) -> SyncReturn<RustOpaque<RemoteMediaTrack>> {
SyncReturn(unsafe {
RustOpaque::new(RemoteMediaTrack::from_ptr(
ptr::NonNull::new(ptr as _).unwrap(),
))
})
}
#[must_use]
pub fn remote_media_track_get_track(
track: RustOpaque<RemoteMediaTrack>,
) -> SyncReturn<DartOpaque> {
SyncReturn(unsafe { new_dart_opaque(track.get_track().handle()) })
}
#[must_use]
pub fn remote_media_track_on_muted(
track: RustOpaque<RemoteMediaTrack>,
f: DartOpaque,
) -> SyncReturn<()> {
track.on_muted(unsafe {
platform::Function::new(f.try_unwrap().unwrap().into_raw().cast())
});
SyncReturn(())
}
#[must_use]
pub fn remote_media_track_on_unmuted(
track: RustOpaque<RemoteMediaTrack>,
f: DartOpaque,
) -> SyncReturn<()> {
track.on_unmuted(unsafe {
platform::Function::new(f.try_unwrap().unwrap().into_raw().cast())
});
SyncReturn(())
}
#[must_use]
pub fn remote_media_track_on_stopped(
track: RustOpaque<RemoteMediaTrack>,
f: DartOpaque,
) -> SyncReturn<()> {
track.on_stopped(unsafe {
platform::Function::new(f.try_unwrap().unwrap().into_raw().cast())
});
SyncReturn(())
}
#[must_use]
pub fn remote_media_track_on_media_direction_changed(
track: RustOpaque<RemoteMediaTrack>,
f: DartOpaque,
) -> SyncReturn<()> {
track.on_media_direction_changed(unsafe {
platform::Function::<MediaDirection>::new(
f.try_unwrap().unwrap().into_raw().cast(),
)
});
SyncReturn(())
}
#[must_use]
pub fn remote_media_track_muted(
track: RustOpaque<RemoteMediaTrack>,
) -> SyncReturn<bool> {
SyncReturn(track.muted())
}
#[must_use]
pub fn remote_media_track_kind(
track: RustOpaque<RemoteMediaTrack>,
) -> SyncReturn<MediaKind> {
SyncReturn(track.kind())
}
#[must_use]
pub fn remote_media_track_media_source_kind(
track: RustOpaque<RemoteMediaTrack>,
) -> SyncReturn<MediaSourceKind> {
SyncReturn(track.media_source_kind())
}
#[must_use]
pub fn remote_media_track_media_direction(
track: RustOpaque<RemoteMediaTrack>,
) -> SyncReturn<MediaDirection> {
SyncReturn(track.media_direction())
}
impl ForeignClass for RoomCloseReason {}
#[must_use]
pub fn room_close_reason_from_ptr(ptr: usize) -> SyncReturn<RoomCloseReason> {
SyncReturn(unsafe {
RoomCloseReason::from_ptr(ptr::NonNull::new(ptr as _).unwrap())
})
}
impl RefUnwindSafe for RoomHandle {}
impl UnwindSafe for RoomHandle {}
#[must_use]
pub fn room_handle_join(
room_handle: RustOpaque<RoomHandle>,
token: String,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
let result = async move {
room_handle.join(token).await?;
Ok::<_, Traced<RoomJoinError>>(())
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn room_handle_set_local_media_settings(
room_handle: RustOpaque<RoomHandle>,
settings: ApiMediaStreamSettings,
stop_first: bool,
rollback_on_fail: bool,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
let result = async move {
room_handle
.set_local_media_settings(
settings.into(),
stop_first,
rollback_on_fail,
)
.await?;
Ok::<_, ConstraintsUpdateError>(())
}
.into_dart_future()
.into_dart_opaque();
SyncReturn(result)
}
#[must_use]
pub fn room_handle_mute_audio(
room_handle: RustOpaque<RoomHandle>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.mute_audio().await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_unmute_audio(
room_handle: RustOpaque<RoomHandle>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.unmute_audio().await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_enable_audio(
room_handle: RustOpaque<RoomHandle>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.enable_audio().await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_disable_audio(
room_handle: RustOpaque<RoomHandle>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.disable_audio().await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_mute_video(
room_handle: RustOpaque<RoomHandle>,
source_kind: Option<MediaSourceKind>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.mute_video(source_kind).await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_unmute_video(
room_handle: RustOpaque<RoomHandle>,
source_kind: Option<MediaSourceKind>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.unmute_video(source_kind).await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_enable_video(
room_handle: RustOpaque<RoomHandle>,
source_kind: Option<MediaSourceKind>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.enable_video(source_kind).await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_disable_video(
room_handle: RustOpaque<RoomHandle>,
source_kind: Option<MediaSourceKind>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.disable_video(source_kind).await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_enable_remote_audio(
room_handle: RustOpaque<RoomHandle>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.enable_remote_audio().await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_disable_remote_audio(
room_handle: RustOpaque<RoomHandle>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.disable_remote_audio().await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_enable_remote_video(
room_handle: RustOpaque<RoomHandle>,
source_kind: Option<MediaSourceKind>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.enable_remote_video(source_kind).await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
#[must_use]
pub fn room_handle_disable_remote_video(
room_handle: RustOpaque<RoomHandle>,
source_kind: Option<MediaSourceKind>,
) -> SyncReturn<DartOpaque> {
let room_handle = RoomHandle::clone(&room_handle);
SyncReturn(
async move {
room_handle.disable_remote_video(source_kind).await?;
Ok::<_, Traced<room::ChangeMediaStateError>>(())
}
.into_dart_future()
.into_dart_opaque(),
)
}
pub fn room_handle_on_new_connection(
room_handle: RustOpaque<RoomHandle>,
cb: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
Ok(SyncReturn(
room_handle
.on_new_connection(unsafe {
platform::Function::new(
cb.try_unwrap().unwrap().into_raw().cast(),
)
})
.map_err(DartError::from)?,
))
}
pub fn room_handle_on_close(
room_handle: RustOpaque<RoomHandle>,
cb: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
room_handle
.on_close(unsafe {
platform::Function::new(cb.try_unwrap().unwrap().into_raw().cast())
})
.map_err(DartError::from)?;
Ok(SyncReturn(()))
}
pub fn room_handle_on_local_track(
room_handle: RustOpaque<RoomHandle>,
cb: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
room_handle
.on_local_track(unsafe {
platform::Function::new(cb.try_unwrap().unwrap().into_raw().cast())
})
.map_err(DartError::from)?;
Ok(SyncReturn(()))
}
pub fn room_handle_on_connection_loss(
room_handle: RustOpaque<RoomHandle>,
cb: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
room_handle
.on_connection_loss(unsafe {
platform::Function::new(cb.try_unwrap().unwrap().into_raw().cast())
})
.map_err(DartError::from)?;
Ok(SyncReturn(()))
}
pub fn room_handle_on_failed_local_media(
room_handle: RustOpaque<RoomHandle>,
cb: DartOpaque,
) -> Result<SyncReturn<()>, DartOpaque> {
room_handle
.on_failed_local_media(unsafe {
platform::Function::new(cb.try_unwrap().unwrap().into_raw().cast())
})
.map_err(DartError::from)?;
Ok(SyncReturn(()))
}
#[must_use]
pub fn log_dart_exception(
message: String,
stack_trace: String,
) -> SyncReturn<()> {
log::error!("{message}\n{stack_trace}");
SyncReturn(())
}