From c1d351d7117e4566ec068fb216f78e1296f662b9 Mon Sep 17 00:00:00 2001 From: Fabio Lenherr / DashieTM Date: Mon, 13 Nov 2023 14:43:14 +0100 Subject: [PATCH 1/2] feat: Add wifi adapter calls --- src/lib.rs | 68 +++++++++++++++++++++++++++++++++++++++++- src/network/network.rs | 4 +-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 99de2a2..490bdc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ use ReSet_Lib::{ audio::audio::{InputStream, OutputStream, Sink, Source}, bluetooth::bluetooth::BluetoothDevice, network::network::{AccessPoint, Error}, - utils::call_system_dbus_method, + utils::{call_system_dbus_method, get_system_dbus_property}, }; // use crate::network::network::{ @@ -200,6 +200,72 @@ pub async fn run_daemon() { Ok((access_points,)) }, ); + c.method( + "GetCurrentNetworkDevice", + (), + ("path", "name"), + move |_, d: &mut DaemonData, ()| { + let name = get_system_dbus_property::<(), String>( + "org.freedesktop.NetworkManager", + d.current_n_device.dbus_path.clone(), + "org.freedesktop.NetworkManager.Device", + "Interface", + ); + Ok(( + d.current_n_device.dbus_path.clone(), + name.unwrap_or_else(|_| String::from("")), + )) + }, + ); + c.method( + "GetAllNetworkDevices", + (), + ("devices",), + move |_, d: &mut DaemonData, ()| { + let mut devices = Vec::new(); + let device_paths = get_wifi_devices(); + for device in device_paths { + let name = get_system_dbus_property::<(), String>( + "org.freedesktop.NetworkManager", + device.dbus_path.clone(), + "org.freedesktop.NetworkManager.Device", + "Interface", + ); + devices.push((device.dbus_path, name.unwrap_or_else(|_| String::from("")))); + } + let name = get_system_dbus_property::<(), String>( + "org.freedesktop.NetworkManager", + d.current_n_device.dbus_path.clone(), + "org.freedesktop.NetworkManager.Device", + "Interface", + ); + devices.push(( + d.current_n_device.dbus_path.clone(), + name.unwrap_or_else(|_| String::from("")), + )); + Ok((devices,)) + }, + ); + c.method( + "SetNetworkDevice", + ("path",), + ("result",), + move |_, d: &mut DaemonData, (path,): (Path<'static>,)| { + let mut res = false; + let mut iter = 0; + for device in d.n_devices.iter() { + if device.dbus_path == path { + res = true; + } + iter += 1; + } + if res { + d.n_devices.push(d.current_n_device.clone()); + d.current_n_device = d.n_devices.remove(iter); + } + Ok((res,)) + }, + ); c.method( "ConnectToKnownAccessPoint", ("access_point",), diff --git a/src/network/network.rs b/src/network/network.rs index ee5e622..dadf295 100644 --- a/src/network/network.rs +++ b/src/network/network.rs @@ -74,7 +74,7 @@ impl Clone for Device { } impl Device { - pub fn from_path(path: Path<'static>) -> Self { + pub fn new(path: Path<'static>) -> Self { Self { access_point: None, connection: None, @@ -224,7 +224,7 @@ pub fn get_wifi_devices() -> Vec { for path in result { let device_type = get_device_type(path.to_string()); if device_type == DeviceType::WIFI { - let mut device = Device::from_path(path); + let mut device = Device::new(path); device.initialize(); devices.push(device); } From 7f278e846c55af479e05a248569ff8680bff7818 Mon Sep 17 00:00:00 2001 From: Fabio Lenherr / DashieTM Date: Mon, 13 Nov 2023 18:13:08 +0100 Subject: [PATCH 2/2] feat: Add default Sink and Source functions --- src/audio/audio.rs | 81 +++++++++++++++++++++++++++++++++++++++++++--- src/lib.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 4 deletions(-) diff --git a/src/audio/audio.rs b/src/audio/audio.rs index 86a3007..b40bac2 100644 --- a/src/audio/audio.rs +++ b/src/audio/audio.rs @@ -174,10 +174,6 @@ impl PulseServer { } _ => (), } - dbg!(facility); - dbg!(operation); - dbg!(index); - // unsafe { (*ml_ref.as_ptr()).signal(false) } }, ))); @@ -205,7 +201,9 @@ impl PulseServer { pub fn handle_message(&self, message: AudioRequest) { match message { AudioRequest::ListSinks => self.get_sinks(), + AudioRequest::GetDefaultSink => self.get_default_sink(), AudioRequest::ListSources => self.get_sources(), + AudioRequest::GetDefaultSource => self.get_default_source(), AudioRequest::ListInputStreams => self.get_input_streams(), AudioRequest::ListOutputStreams => self.get_output_streams(), AudioRequest::SetInputStreamMute(input_stream) => { @@ -236,6 +234,81 @@ impl PulseServer { } } + pub fn get_default_sink(&self) { + self.mainloop.borrow_mut().lock(); + let introspector = self.context.borrow().introspect(); + let sink = Rc::new(RefCell::new(Vec::new())); + let sink_ref = sink.clone(); + let sink_name = Rc::new(RefCell::new(String::from(""))); + let sink_name_ref = sink_name.clone(); + let ml_ref = Rc::clone(&self.mainloop); + introspector.get_server_info(move |result| { + if result.default_sink_name.is_some() { + let mut borrow = sink_name_ref.borrow_mut(); + *borrow = String::from(result.default_sink_name.clone().unwrap()); + } + }); + let result = + introspector.get_sink_info_by_name( + sink_name.take().as_str(), + move |result| match result { + ListResult::Item(item) => { + sink_ref.borrow_mut().push(item.into()); + } + ListResult::Error => unsafe { + (*ml_ref.as_ptr()).signal(true); + }, + ListResult::End => unsafe { + (*ml_ref.as_ptr()).signal(false); + }, + }, + ); + while result.get_state() != pulse::operation::State::Done { + self.mainloop.borrow_mut().wait(); + } + let _ = self + .sender + .send(AudioResponse::DefaultSink(sink.take().pop().unwrap())); + self.mainloop.borrow_mut().unlock(); + } + + pub fn get_default_source(&self) { + self.mainloop.borrow_mut().lock(); + let introspector = self.context.borrow().introspect(); + let source = Rc::new(RefCell::new(Vec::new())); + let source_ref = source.clone(); + let source_name = Rc::new(RefCell::new(String::from(""))); + let source_name_ref = source_name.clone(); + let ml_ref = Rc::clone(&self.mainloop); + introspector.get_server_info(move |result| { + if result.default_source_name.is_some() { + let mut borrow = source_name_ref.borrow_mut(); + *borrow = String::from(result.default_sink_name.clone().unwrap()); + } + }); + let result = + introspector.get_source_info_by_name(source_name.take().as_str(), move |result| { + match result { + ListResult::Item(item) => { + source_ref.borrow_mut().push(item.into()); + } + ListResult::Error => unsafe { + (*ml_ref.as_ptr()).signal(true); + }, + ListResult::End => unsafe { + (*ml_ref.as_ptr()).signal(false); + }, + } + }); + while result.get_state() != pulse::operation::State::Done { + self.mainloop.borrow_mut().wait(); + } + let _ = self + .sender + .send(AudioResponse::DefaultSource(source.take().pop().unwrap())); + self.mainloop.borrow_mut().unlock(); + } + pub fn get_sinks(&self) { self.mainloop.borrow_mut().lock(); let introspector = self.context.borrow().introspect(); diff --git a/src/lib.rs b/src/lib.rs index 490bdc3..588346a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,8 @@ mod bluetooth; mod network; use std::{ + borrow::BorrowMut, + cell::RefCell, collections::HashMap, future::{self}, sync::{atomic::AtomicBool, Arc, Mutex}, @@ -39,10 +41,12 @@ use crate::{ pub enum AudioRequest { ListSources, + GetDefaultSource, SetSourceVolume(Source), SetSourceMute(Source), SetDefaultSource(Source), ListSinks, + GetDefaultSink, SetSinkVolume(Sink), SetSinkMute(Sink), SetDefaultSink(Sink), @@ -57,6 +61,8 @@ pub enum AudioRequest { } pub enum AudioResponse { + DefaultSink(Sink), + DefaultSource(Source), Sources(Vec), Sinks(Vec), InputStreams(Vec), @@ -430,6 +436,58 @@ pub async fn run_daemon() { Ok((true,)) }, ); + c.method_with_cr_async( + "GetDefaultSink", + (), + ("default_sink",), + move |mut ctx, cross, ()| { + let data: &mut DaemonData = cross.data_mut(ctx.path()).unwrap(); + let sink: Option; + let _ = data.audio_sender.send(AudioRequest::GetDefaultSink); + let response = data.audio_receiver.recv(); + if response.is_ok() { + sink = match response.unwrap() { + AudioResponse::DefaultSink(s) => Some(s), + _ => None, + } + } else { + sink = None; + } + let response: Result<(Sink,), dbus::MethodErr>; + if sink.is_none() { + response = Err(dbus::MethodErr::failed("Could not get default sink")); + } else { + response = Ok((sink.unwrap(),)); + } + async move { ctx.reply(response) } + }, + ); + c.method_with_cr_async( + "GetDefaultSource", + (), + ("default_source",), + move |mut ctx, cross, ()| { + let data: &mut DaemonData = cross.data_mut(ctx.path()).unwrap(); + let source: Option; + let _ = data.audio_sender.send(AudioRequest::GetDefaultSource); + let response = data.audio_receiver.recv(); + if response.is_ok() { + source = match response.unwrap() { + AudioResponse::DefaultSource(s) => Some(s), + _ => None, + } + } else { + source = None; + } + let response: Result<(Source,), dbus::MethodErr>; + if source.is_none() { + response = Err(dbus::MethodErr::failed("Could not get default sink")); + } else { + response = Ok((source.unwrap(),)); + } + async move { ctx.reply(response) } + }, + ); c.method_with_cr_async("ListSinks", (), ("sinks",), move |mut ctx, cross, ()| { let data: &mut DaemonData = cross.data_mut(ctx.path()).unwrap(); let sinks: Vec; @@ -562,6 +620,28 @@ pub async fn run_daemon() { async move { ctx.reply(Ok((result,))) } }, ); + c.method_with_cr_async( + "SetDefaultSource", + ("source",), + ("result",), + move |mut ctx, cross, (source,): (Source,)| { + let data: &mut DaemonData = cross.data_mut(ctx.path()).unwrap(); + let _ = data + .audio_sender + .send(AudioRequest::SetDefaultSource(source)); + let result: bool; + let res = data.audio_receiver.recv(); + if res.is_err() { + result = false; + } else { + result = match res.unwrap() { + AudioResponse::BoolResponse(b) => b, + _ => false, + }; + } + async move { ctx.reply(Ok((result,))) } + }, + ); c.method_with_cr_async( "ListInputStreams", (),