From 12f92ac59747e9221075dfe8241c56f25857a007 Mon Sep 17 00:00:00 2001 From: Fabio Lenherr / DashieTM Date: Sun, 12 Nov 2023 22:10:15 +0100 Subject: [PATCH] feat: Implement working signal receiver --- Cargo.toml | 2 +- src/components/wifi/wifiBox.rs | 219 ++++++++++++++++++++++------- src/components/wifi/wifiBoxImpl.rs | 5 +- 3 files changed, 177 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 453c19f..2db6d87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ description = "A wip universal Linux settings application." [dependencies] reset_daemon = "0.1.0" -ReSet-Lib = "0.2.3" +ReSet-Lib = "0.2.5" adw = { version = "0.5.3", package = "libadwaita", features = ["v1_4"] } dbus = "0.9.7" gtk = { version = "0.7.3", package = "gtk4", features = ["v4_12"] } diff --git a/src/components/wifi/wifiBox.rs b/src/components/wifi/wifiBox.rs index 0f27d52..c7c8438 100644 --- a/src/components/wifi/wifiBox.rs +++ b/src/components/wifi/wifiBox.rs @@ -1,6 +1,8 @@ use std::collections::HashMap; +use std::sync::atomic::Ordering; use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::{atomic::AtomicBool, Arc}; +use std::thread; use std::time::Duration; use crate::components::base::listEntry::ListEntry; @@ -8,15 +10,16 @@ use adw::glib; use adw::glib::Object; use adw::prelude::{BoxExt, ListBoxRowExt}; use adw::subclass::prelude::ObjectSubclassIsExt; -use dbus::arg::RefArg; +use dbus::arg::{AppendAll, ReadAll, RefArg}; use dbus::blocking::Connection; use dbus::Error; use dbus::Path; +use gtk::gio; use gtk::glib::Variant; use gtk::prelude::ActionableExt; use ReSet_Lib::network::network::AccessPoint; -use ReSet_Lib::signals::AccessPointAdded; use ReSet_Lib::signals::AccessPointRemoved; +use ReSet_Lib::signals::{AccessPointAdded, GetVal}; use ReSet_Lib::utils::Events; use crate::components::wifi::wifiBoxImpl; @@ -42,72 +45,105 @@ impl WifiBox { pub fn setupCallbacks(&self) { let selfImp = self.imp(); - selfImp.resetSavedNetworks.set_action_name(Some("navigation.push")); - selfImp.resetSavedNetworks.set_action_target_value(Some(&Variant::from("saved"))); + selfImp + .resetSavedNetworks + .set_action_name(Some("navigation.push")); + selfImp + .resetSavedNetworks + .set_action_target_value(Some(&Variant::from("saved"))); - selfImp.resetAvailableNetworks.set_action_name(Some("navigation.pop")); + selfImp + .resetAvailableNetworks + .set_action_name(Some("navigation.pop")); } - - // pub fn donotdisturb() { - // thread::spawn(|| { - // let conn = Connection::new_session().unwrap(); - // let proxy = conn.with_proxy( - // "org.freedesktop.Notifications", - // "/org/freedesktop/Notifications", - // Duration::from_millis(1000), - // ); - // let _: Result<(), Error> = - // proxy.method_call("org.freedesktop.Notifications", "DoNotDisturb", ()); - // }); - // } } pub fn scanForWifi(wifiBox: Arc) { let wifibox_ref = wifiBox.clone(); + let wifibox_ref_listener = wifiBox.clone(); let wifiEntries = wifiBox.imp().wifiEntries.clone(); - glib::spawn_future_local(async move { - let accessPoints = get_access_points().await; + gio::spawn_blocking(move || { + let accessPoints = get_access_points(); + let wifiEntriesListener = wifiEntries.clone(); let wifiEntries = wifiEntries.clone(); { let mut wifiEntries = wifiEntries.lock().unwrap(); for accessPoint in accessPoints { - wifiEntries.push(ListEntry::new(&*WifiEntry::new(accessPoint))); + wifiEntries.push(accessPoint); } } - glib::MainContext::default().spawn_local(async move { + glib::spawn_future(async move { glib::idle_add_once(move || { - let wifiEntries = wifiEntries.lock().unwrap(); + let mut wifiEntries = wifiEntries.lock().unwrap(); let selfImp = wifibox_ref.imp(); - for wifiEntry in wifiEntries.iter() { - selfImp.resetWifiList.append(wifiEntry); + for _ in 0..wifiEntries.len() { + selfImp + .resetWifiList + .append(&ListEntry::new(&*WifiEntry::new( + wifiEntries.pop().unwrap(), + ))); } }); }); + let wifiBoxImpl = wifibox_ref_listener.imp(); + wifiBoxImpl + .listener_active + .store(true, std::sync::atomic::Ordering::SeqCst); + dbus_start_network_events(); let (sender, receiver): ( Sender,)>>, Receiver,)>>, ) = channel(); let sender_ref = Arc::new(sender); - let listener_active = Arc::new(AtomicBool::new(false)); - ReSet_Lib::utils::start_event_listener::< + let res = start_event_listener::< (AccessPoint,), (Path<'static>,), AccessPointAdded, AccessPointRemoved, - >(listener_active, sender_ref); - // handle receiver... - let res = receiver.try_recv(); - if res.is_ok() { - let access_point = res.unwrap(); - match access_point { - Events::AddedEvent(access_point) => { - dbg!(access_point); - } - _ => (), - }; - } else { - println!("no message there :)"); + >( + wifibox_ref_listener.imp().listener_active.clone(), + sender_ref, + ); + if res.is_err() { + println!("Could not connect listener"); + } + loop { + if wifiBoxImpl + .listener_active + .load(std::sync::atomic::Ordering::SeqCst) + == false + { + break; + } + println!("receiving!"); + let res = receiver.recv(); + if res.is_ok() { + let access_point = res.unwrap(); + match access_point { + Events::AddedEvent(access_point) => { + { + let mut wifiEntries = wifiEntriesListener.lock().unwrap(); + println!("got this access point:"); + dbg!(access_point.0.clone()); + wifiEntries.push(access_point.0); + } + let wifiEntriesListener = wifiEntriesListener.clone(); + let wifiBoxImpl = wifibox_ref_listener.clone(); + glib::spawn_future(async move { + glib::idle_add_once(move || { + let mut wifiEntries = wifiEntriesListener.lock().unwrap(); + wifiBoxImpl.imp().resetWifiList.append(&ListEntry::new( + &*WifiEntry::new(wifiEntries.pop().unwrap()), + )); + }); + }); + } + _ => (), + }; + } else { + println!("no message there :)"); + } } }); } @@ -116,8 +152,8 @@ pub fn show_stored_connections(wifiBox: Arc) { let wifibox_ref = wifiBox.clone(); let wifiEntries = wifiBox.imp().savedWifiEntries.clone(); - glib::spawn_future_local(async move { - let connections = get_stored_connections().await; + gio::spawn_blocking(move || { + let connections = get_stored_connections(); let wifiEntries = wifiEntries.clone(); { let mut wifiEntries = wifiEntries.lock().unwrap(); @@ -129,7 +165,7 @@ pub fn show_stored_connections(wifiBox: Arc) { wifiEntries.push(entry); } } - glib::MainContext::default().spawn_local(async move { + glib::spawn_future(async move { glib::idle_add_once(move || { let wifiEntries = wifiEntries.lock().unwrap(); let selfImp = wifibox_ref.imp(); @@ -141,7 +177,17 @@ pub fn show_stored_connections(wifiBox: Arc) { }); } -pub async fn get_access_points() -> Vec { +pub fn dbus_start_network_events() { + let conn = Connection::new_session().unwrap(); + let proxy = conn.with_proxy( + "org.xetibo.ReSet", + "/org/xetibo/ReSet", + Duration::from_millis(1000), + ); + let _: Result<(), Error> = proxy.method_call("org.xetibo.ReSet", "StartNetworkListener", ()); +} + +pub fn get_access_points() -> Vec { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy( "org.xetibo.ReSet", @@ -157,7 +203,7 @@ pub async fn get_access_points() -> Vec { accessPoints } -pub async fn get_stored_connections() -> Vec<(Path<'static>, Vec)> { +pub fn get_stored_connections() -> Vec<(Path<'static>, Vec)> { let conn = Connection::new_session().unwrap(); let proxy = conn.with_proxy( "org.xetibo.ReSet", @@ -182,8 +228,10 @@ pub fn getConnectionSettings(path: Path<'static>) -> Option { "/org/xetibo/ReSet", Duration::from_millis(1000), ); - let res: Result<(HashMap>>,>,), Error> = - proxy.method_call("org.xetibo.ReSet", "GetConnectionSettings", (path,)); + let res: Result< + (HashMap>>>,), + Error, + > = proxy.method_call("org.xetibo.ReSet", "GetConnectionSettings", (path,)); if res.is_err() { println!("lol not work"); return None; @@ -196,3 +244,80 @@ pub fn getConnectionSettings(path: Path<'static>) -> Option { } Some(res.unwrap()) } + +// temporary, testing this with lib is pain +// + +pub fn start_event_listener< + AddedType: ReadAll + AppendAll + Send + Sync + 'static, + RemovedType: ReadAll + AppendAll + Send + Sync + 'static, + AddedEvent: ReadAll + AppendAll + dbus::message::SignalArgs + GetVal, + RemovedEvent: ReadAll + AppendAll + dbus::message::SignalArgs + GetVal, +>( + active_listener: Arc, + sender: Arc>>, +) -> Result<(), dbus::Error> { + thread::spawn(move || { + let added_sender = sender.clone(); + let removed_sender = sender.clone(); + let conn = Connection::new_session().unwrap(); + let mr = AddedEvent::match_rule( + Some(&"org.xetibo.ReSet".into()), + Some(&Path::from("/org/xetibo/ReSet")), + ) + .static_clone(); + let mrb = RemovedEvent::match_rule( + Some(&"org.xetibo.ReSet".into()), + Some(&Path::from("/org/xetibo/ReSet")), + ) + .static_clone(); + let res = conn.add_match(mr, move |ir: AddedEvent, _, _| { + println!("received added event"); + let res = added_sender.send(Events::AddedEvent(ir.get_value())); + if res.is_err() { + println!("fail on sending added"); + return false; + } + true + }); + if res.is_err() { + println!("fail on add"); + return Err(dbus::Error::new_custom( + "SignalMatchFailed", + "Failed to match signal on ReSet.", + )); + } + let res = conn.add_match(mrb, move |ir: RemovedEvent, _, _| { + println!("received removed event"); + let res = removed_sender.send(Events::RemovedEvent(ir.get_value())); + if res.is_err() { + println!("fail on sending removed"); + return false; + } + true + }); + if res.is_err() { + println!("fail on remove"); + return Err(dbus::Error::new_custom( + "SignalMatchFailed", + "Failed to match signal on ReSet.", + )); + } + active_listener.store(true, Ordering::SeqCst); + println!("starting thread listener"); + loop { + let _ = conn.process(Duration::from_millis(1000))?; + if !active_listener.load(Ordering::SeqCst) { + println!("stopping thread listener"); + break; + } + thread::sleep(Duration::from_millis(1000)); + } + Ok(()) + }); + Ok(()) +} + +pub fn stop_listener(active_listener: Arc) { + active_listener.store(false, Ordering::SeqCst); +} diff --git a/src/components/wifi/wifiBoxImpl.rs b/src/components/wifi/wifiBoxImpl.rs index c0e2dbf..501f41f 100644 --- a/src/components/wifi/wifiBoxImpl.rs +++ b/src/components/wifi/wifiBoxImpl.rs @@ -1,4 +1,6 @@ +use std::sync::atomic::AtomicBool; use std::sync::{Arc, Mutex}; +use ReSet_Lib::network::network::AccessPoint; use gtk::{CompositeTemplate, glib, ListBox, Switch}; use gtk::prelude::*; use gtk::subclass::prelude::*; @@ -23,8 +25,9 @@ pub struct WifiBox { pub resetStoredWifiList: TemplateChild, #[template_child] pub resetAvailableNetworks: TemplateChild, - pub wifiEntries: Arc>>, + pub wifiEntries: Arc>>, pub savedWifiEntries: Arc>>, + pub listener_active: Arc, } unsafe impl Send for WifiBox {}