nandi/jolt-nativepublic Fork 0
2ab40bf193b6a39bc8d1397cc36d17572bbf59cd
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

devices_info.rs · 88 lines · 3.3 KBRust Blame HistoryRaw
Lift freeq's AV media plane out of sleek 90f8b89 nandi 20d ago1use num_traits::FromPrimitive;
2
3use crate::{DeviceDirection, SampleFormat};
4
5use super::{
6 android_device_flags,
7 utils::{
8 call_method_no_args_ret_bool, call_method_no_args_ret_char_sequence,
9 call_method_no_args_ret_int, call_method_no_args_ret_int_array,
10 call_method_no_args_ret_string, get_context, get_devices, get_system_service,
11 with_attached, JNIEnv, JObject, JResult,
12 },
13 AudioDeviceInfo, AudioDeviceType, Context,
14};
15
16impl AudioDeviceInfo {
17 /**
18 * Request audio devices using Android Java API
19 */
20 pub fn request(direction: DeviceDirection) -> Result<Vec<AudioDeviceInfo>, String> {
21 let context = get_context();
22
23 with_attached(context, |env, context| {
24 let sdk_version = env
25 .get_static_field("android/os/Build$VERSION", "SDK_INT", "I")?
26 .i()?;
27
28 if sdk_version >= 23 {
29 try_request_devices_info(env, &context, direction)
30 } else {
31 Err(jni::errors::Error::MethodNotFound {
32 name: "".into(),
33 sig: "".into(),
34 })
35 }
36 })
37 .map_err(|error| error.to_string())
38 }
39}
40
41fn try_request_devices_info<'j>(
42 env: &mut JNIEnv<'j>,
43 context: &JObject<'j>,
44 direction: DeviceDirection,
45) -> JResult<Vec<AudioDeviceInfo>> {
46 let audio_manager = get_system_service(env, context, Context::AUDIO_SERVICE)?;
47
48 let devices = get_devices(env, &audio_manager, android_device_flags(direction))?;
49
50 let length = env.get_array_length(&devices)?;
51
52 (0..length)
53 .map(|index| {
54 let device = env.get_object_array_element(&devices, index)?;
55 let id = call_method_no_args_ret_int(env, &device, "getId")?;
56 let address = call_method_no_args_ret_string(env, &device, "getAddress")?;
57 let address = String::from(env.get_string(&address)?);
58 let product_name =
59 call_method_no_args_ret_char_sequence(env, &device, "getProductName")?;
60 let product_name = String::from(env.get_string(&product_name)?);
61 let device_type =
62 FromPrimitive::from_i32(call_method_no_args_ret_int(env, &device, "getType")?)
63 .unwrap_or(AudioDeviceType::Unsupported);
64
65 let is_source = call_method_no_args_ret_bool(env, &device, "isSource")?;
66 let is_sink = call_method_no_args_ret_bool(env, &device, "isSink")?;
67 let direction = crate::device_description::direction_from_caps(is_source, is_sink);
68 let channel_counts =
69 call_method_no_args_ret_int_array(env, &device, "getChannelCounts")?;
70 let sample_rates = call_method_no_args_ret_int_array(env, &device, "getSampleRates")?;
71 let formats = call_method_no_args_ret_int_array(env, &device, "getEncodings")?
72 .into_iter()
73 .filter_map(SampleFormat::from_encoding)
74 .collect::<Vec<_>>();
75
76 Ok(AudioDeviceInfo {
77 id,
78 address,
79 product_name,
80 device_type,
81 direction,
82 channel_counts,
83 sample_rates,
84 formats,
85 })
86 })
87 .collect::<Result<Vec<_>, _>>()
88}