1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
//! [MediaDeviceInfo][0] related representations.
//!
//! [0]: https://w3.org/TR/mediacapture-streams#device-info
use medea_macro::dart_bridge;
use crate::{
media::MediaDeviceKind,
platform::dart::utils::{
dart_string_into_rust, handle::DartHandle, NonNullDartValueArgExt,
},
};
#[dart_bridge("flutter/lib/src/native/platform/media_device_info.g.dart")]
mod media_device_info {
use std::{os::raw::c_char, ptr};
use dart_sys::Dart_Handle;
use crate::api::DartValueArg;
extern "C" {
/// Returns an unique identifier of the provided device.
pub fn device_id(info: Dart_Handle) -> ptr::NonNull<c_char>;
/// Returns a kind of the provided device.
pub fn kind(info: Dart_Handle) -> i64;
/// Returns a label describing the provided device (for example,
/// "External USB Webcam").
///
/// If the provided device has no associated label, then returns an
/// empty string.
pub fn label(info: Dart_Handle) -> ptr::NonNull<c_char>;
/// Returns a group identifier of the provided device.
pub fn group_id(
info: Dart_Handle,
) -> ptr::NonNull<DartValueArg<Option<String>>>;
/// Indicates whether the last attempt to use the provided device
/// failed.
pub fn is_failed(info: Dart_Handle) -> bool;
}
}
/// Representation of a [MediaDeviceInfo][0] ONLY for input devices.
///
/// [0]: https://w3.org/TR/mediacapture-streams#device-info
#[derive(Clone, Debug)]
pub struct MediaDeviceInfo {
/// Handle to the Dart side `MediaDeviceInfo`.
handle: DartHandle,
/// [`MediaDeviceKind`] of this [`MediaDeviceInfo`].
kind: MediaDeviceKind,
}
impl MediaDeviceInfo {
/// Returns a unique identifier of the device represented by this
/// [`MediaDeviceInfo`].
#[must_use]
pub fn device_id(&self) -> String {
let device_id =
unsafe { media_device_info::device_id(self.handle.get()) };
unsafe { dart_string_into_rust(device_id) }
}
/// Returns a kind of the device represented by this [`MediaDeviceInfo`].
#[must_use]
pub const fn kind(&self) -> MediaDeviceKind {
self.kind
}
/// Returns a label describing the device represented by this
/// [`MediaDeviceInfo`] (for example, "External USB Webcam").
///
/// If the device has no associated label, then returns an empty string.
#[must_use]
pub fn label(&self) -> String {
let label = unsafe { media_device_info::label(self.handle.get()) };
unsafe { dart_string_into_rust(label) }
}
/// Returns a group identifier of the device represented by this
/// [`MediaDeviceInfo`]
///
/// Two devices have the same group identifier if they belong to the same
/// physical device. For example, the audio input and output devices
/// representing the speaker and microphone of the same headset have the
/// same [groupId][1].
///
/// [1]: https://w3.org/TR/mediacapture-streams#dom-mediadeviceinfo-groupid
#[allow(clippy::unwrap_in_result)]
#[must_use]
pub fn group_id(&self) -> Option<String> {
let group_id =
unsafe { media_device_info::group_id(self.handle.get()) };
Option::try_from(unsafe { group_id.unbox() }).unwrap()
}
/// Indicates whether the last attempt to use this device failed.
#[must_use]
pub fn is_failed(&self) -> bool {
unsafe { media_device_info::is_failed(self.handle.get()) }
}
}
impl TryFrom<DartHandle> for MediaDeviceInfo {
type Error = NotInput;
fn try_from(value: DartHandle) -> Result<Self, Self::Error> {
#[allow(clippy::map_err_ignore)]
let kind = unsafe { media_device_info::kind(value.get()) }
.try_into()
.map_err(|_| NotInput)?;
Ok(Self {
handle: value,
kind,
})
}
}
/// Error of a [MediaDeviceInfo][0] representing not an input device.
///
/// [0]: https://w3.org/TR/mediacapture-streams#device-info
#[derive(Clone, Copy, Debug)]
pub struct NotInput;