@@ -19,6 +19,7 @@ use tokio_util::sync::CancellationToken;
1919use crate :: application:: PacketApplication ;
2020use crate :: config:: { APP_ID , PROFILE } ;
2121use crate :: constants:: packet_log_path;
22+ use crate :: dbus;
2223use crate :: ext:: MessageExt ;
2324use crate :: objects:: { self , SendRequestState } ;
2425use crate :: objects:: { TransferState , UserAction } ;
@@ -171,6 +172,7 @@ mod imp {
171172 pub is_mdns_discovery_on : Rc < Cell < bool > > ,
172173
173174 pub looping_async_tasks : RefCell < Vec < LoopingTaskHandle > > ,
175+ pub dbus_async_tasks : RefCell < Vec < LoopingTaskHandle > > ,
174176
175177 pub is_background_allowed : Cell < bool > ,
176178 pub should_quit : Cell < bool > ,
@@ -216,6 +218,7 @@ mod imp {
216218 obj. setup_notification_actions_monitor ( ) ;
217219 obj. setup_rqs_service ( ) ;
218220 obj. request_background_at_start ( ) ;
221+ obj. setup_dbus_api ( ) ;
219222 }
220223 }
221224
@@ -265,9 +268,16 @@ mod imp {
265268
266269 // Abort all looping tasks before closing
267270 tracing:: info!(
268- count = self . looping_async_tasks. borrow( ) . len( ) ,
271+ rqs_tasks = self . looping_async_tasks. borrow( ) . len( ) ,
272+ dbus_tasks = self . dbus_async_tasks. borrow( ) . len( ) ,
269273 "Cancelling looping tasks"
270274 ) ;
275+ while let Some ( join_handle) = self . dbus_async_tasks . borrow_mut ( ) . pop ( ) {
276+ match join_handle {
277+ LoopingTaskHandle :: Tokio ( join_handle) => join_handle. abort ( ) ,
278+ LoopingTaskHandle :: Glib ( join_handle) => join_handle. abort ( ) ,
279+ }
280+ }
271281 while let Some ( join_handle) = self . looping_async_tasks . borrow_mut ( ) . pop ( ) {
272282 match join_handle {
273283 LoopingTaskHandle :: Tokio ( join_handle) => join_handle. abort ( ) ,
@@ -1849,6 +1859,70 @@ impl PacketApplicationWindow {
18491859 handle
18501860 }
18511861
1862+ async fn setup_dbus_api ( & self ) {
1863+ let obj = self . clone ( ) ;
1864+
1865+ let inner = async move || -> anyhow:: Result < ( ) > {
1866+ let imp = obj. imp ( ) ;
1867+
1868+ _ = dbus:: create_connection ( imp. settings . boolean ( "device-visibility" ) ) . await ?;
1869+
1870+ let handle = glib:: spawn_future_local ( clone ! (
1871+ #[ weak]
1872+ imp,
1873+ async move {
1874+ // IMPORTANT: Keep notice of get() and get_mut() so that it doesn't lead to deadlock
1875+ let mut visibility_rx = {
1876+ let iface_ref = dbus:: packet_iface( ) . await ;
1877+ iface_ref
1878+ . get( )
1879+ . await
1880+ . visibility_rx
1881+ . clone( )
1882+ . lock_owned( )
1883+ . await
1884+ } ;
1885+
1886+ while let Some ( extern_visibility) = visibility_rx. recv( ) . await {
1887+ _ = imp
1888+ . settings
1889+ . set_boolean( "device-visibility" , extern_visibility)
1890+ . inspect_err( |err| tracing:: warn!( %err) ) ;
1891+ }
1892+ }
1893+ ) ) ;
1894+ imp. dbus_async_tasks
1895+ . borrow_mut ( )
1896+ . push ( LoopingTaskHandle :: Glib ( handle) ) ;
1897+
1898+ imp. settings
1899+ . connect_changed ( Some ( "device-visibility" ) , move |settings, key| {
1900+ let key = key. to_string ( ) ;
1901+ glib:: spawn_future_local ( clone ! (
1902+ #[ weak]
1903+ settings,
1904+ async move {
1905+ let iface_ref = dbus:: packet_iface( ) . await ;
1906+ let mut iface = iface_ref. get_mut( ) . await ;
1907+ iface. visibility = settings. boolean( & key) ;
1908+ _ = iface
1909+ . device_visibility_changed( iface_ref. signal_emitter( ) )
1910+ . await
1911+ . inspect_err( |err| tracing:: warn!( %err) ) ;
1912+ }
1913+ ) ) ;
1914+ } ) ;
1915+
1916+ Ok ( ( ) )
1917+ } ;
1918+
1919+ glib:: spawn_future_local ( async move {
1920+ _ = inner ( )
1921+ . await
1922+ . inspect_err ( |err| tracing:: error!( %err, "Failed to setup DBus API" ) ) ;
1923+ } ) ;
1924+ }
1925+
18521926 fn setup_connection_monitors ( & self ) {
18531927 let imp = self . imp ( ) ;
18541928
0 commit comments