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
130
131
132
133
134
//! [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, platform::Error};
extern "C" {
/// Returns an unique identifier of the provided device.
pub fn device_id(
info: Dart_Handle,
) -> Result<ptr::NonNull<c_char>, Error>;
/// Returns a kind of the provided device.
pub fn kind(info: Dart_Handle) -> Result<i64, Error>;
/// 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) -> Result<ptr::NonNull<c_char>, Error>;
/// Returns a group identifier of the provided device.
pub fn group_id(
info: Dart_Handle,
) -> Result<ptr::NonNull<DartValueArg<Option<String>>>, Error>;
/// Indicates whether the last attempt to use the provided device
/// failed.
pub fn is_failed(info: Dart_Handle) -> Result<bool, Error>;
}
}
/// 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()) }.unwrap();
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()) }.unwrap();
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()) }.unwrap();
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()) }.unwrap()
}
}
impl TryFrom<DartHandle> for MediaDeviceInfo {
type Error = NotInput;
#[allow(clippy::unwrap_in_result)] // intentional
fn try_from(value: DartHandle) -> Result<Self, Self::Error> {
#[allow(clippy::map_err_ignore)] // intentional
let kind = unsafe { media_device_info::kind(value.get()) }
.unwrap()
.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;