Loading system/gd/rust/linux/client/src/callbacks.rs +91 −8 Original line number Original line Diff line number Diff line use crate::dbus_iface::{ export_bluetooth_callback_dbus_obj, export_bluetooth_connection_callback_dbus_obj, export_bluetooth_gatt_callback_dbus_obj, export_bluetooth_manager_callback_dbus_obj, }; use crate::ClientContext; use crate::ClientContext; use crate::{console_yellow, print_info}; use crate::{console_yellow, print_info}; use bt_topshim::btif::{BtBondState, BtSspVariant}; use bt_topshim::btif::{BtBondState, BtSspVariant}; Loading @@ -7,6 +11,9 @@ use btstack::bluetooth::{ }; }; use btstack::bluetooth_gatt::{BluetoothGattService, IBluetoothGattCallback, LePhy}; use btstack::bluetooth_gatt::{BluetoothGattService, IBluetoothGattCallback, LePhy}; use btstack::RPCProxy; use btstack::RPCProxy; use dbus::nonblock::SyncConnection; use dbus_crossroads::Crossroads; use dbus_projection::DisconnectWatcher; use manager_service::iface_bluetooth_manager::IBluetoothManagerCallback; use manager_service::iface_bluetooth_manager::IBluetoothManagerCallback; use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex}; Loading @@ -14,11 +21,19 @@ use std::sync::{Arc, Mutex}; pub(crate) struct BtManagerCallback { pub(crate) struct BtManagerCallback { objpath: String, objpath: String, context: Arc<Mutex<ClientContext>>, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } } impl BtManagerCallback { impl BtManagerCallback { pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self { pub(crate) fn new( Self { objpath, context } objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, context, dbus_connection, dbus_crossroads } } } } } Loading Loading @@ -50,17 +65,36 @@ impl manager_service::RPCProxy for BtManagerCallback { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); export_bluetooth_manager_callback_dbus_obj( self.get_object_id(), self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(self)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); } } } /// Callback container for adapter interface callbacks. /// Callback container for adapter interface callbacks. pub(crate) struct BtCallback { pub(crate) struct BtCallback { objpath: String, objpath: String, context: Arc<Mutex<ClientContext>>, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } } impl BtCallback { impl BtCallback { pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self { pub(crate) fn new( Self { objpath, context } objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, context, dbus_connection, dbus_crossroads } } } } } Loading Loading @@ -179,16 +213,35 @@ impl RPCProxy for BtCallback { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); export_bluetooth_callback_dbus_obj( self.get_object_id(), self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(self)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); } } } pub(crate) struct BtConnectionCallback { pub(crate) struct BtConnectionCallback { objpath: String, objpath: String, _context: Arc<Mutex<ClientContext>>, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } } impl BtConnectionCallback { impl BtConnectionCallback { pub(crate) fn new(objpath: String, _context: Arc<Mutex<ClientContext>>) -> Self { pub(crate) fn new( Self { objpath, _context } objpath: String, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, _context, dbus_connection, dbus_crossroads } } } } } Loading @@ -214,16 +267,35 @@ impl RPCProxy for BtConnectionCallback { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); export_bluetooth_connection_callback_dbus_obj( self.get_object_id(), self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(self)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); } } } pub(crate) struct BtGattCallback { pub(crate) struct BtGattCallback { objpath: String, objpath: String, context: Arc<Mutex<ClientContext>>, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } } impl BtGattCallback { impl BtGattCallback { pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self { pub(crate) fn new( Self { objpath, context } objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, context, dbus_connection, dbus_crossroads } } } } } Loading Loading @@ -367,4 +439,15 @@ impl RPCProxy for BtGattCallback { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); export_bluetooth_gatt_callback_dbus_obj( self.get_object_id(), self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(self)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); } } } system/gd/rust/linux/client/src/command_handler.rs +5 −0 Original line number Original line Diff line number Diff line Loading @@ -538,11 +538,16 @@ impl CommandHandler { enforce_arg_len(args, 1, "gatt <commands>", || match &args[0][0..] { enforce_arg_len(args, 1, "gatt <commands>", || match &args[0][0..] { "register-client" => { "register-client" => { let dbus_connection = self.context.lock().unwrap().dbus_connection.clone(); let dbus_crossroads = self.context.lock().unwrap().dbus_crossroads.clone(); self.context.lock().unwrap().gatt_dbus.as_mut().unwrap().register_client( self.context.lock().unwrap().gatt_dbus.as_mut().unwrap().register_client( String::from(GATT_CLIENT_APP_UUID), String::from(GATT_CLIENT_APP_UUID), Box::new(BtGattCallback::new( Box::new(BtGattCallback::new( String::from("/org/chromium/bluetooth/client/bluetooth_gatt_callback"), String::from("/org/chromium/bluetooth/client/bluetooth_gatt_callback"), self.context.clone(), self.context.clone(), dbus_connection, dbus_crossroads, )), )), false, false, ); ); Loading system/gd/rust/linux/client/src/dbus_iface.rs +34 −61 Original line number Original line Diff line number Diff line Loading @@ -15,8 +15,6 @@ use btstack::bluetooth_gatt::{ use dbus::arg::{AppendAll, RefArg}; use dbus::arg::{AppendAll, RefArg}; use dbus::nonblock::SyncConnection; use dbus::nonblock::SyncConnection; use dbus_crossroads::Crossroads; use dbus_projection::{impl_dbus_arg_enum, DisconnectWatcher}; use dbus_projection::{impl_dbus_arg_enum, DisconnectWatcher}; use dbus_macros::{ use dbus_macros::{ Loading @@ -30,7 +28,7 @@ use manager_service::iface_bluetooth_manager::{ use num_traits::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive}; use std::convert::TryInto; use std::convert::TryInto; use std::sync::{Arc, Mutex}; use std::sync::Arc; use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust}; use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust}; Loading Loading @@ -98,7 +96,6 @@ pub struct BluetoothDeviceDBus { struct ClientDBusProxy { struct ClientDBusProxy { conn: Arc<SyncConnection>, conn: Arc<SyncConnection>, cr: Arc<Mutex<Crossroads>>, bus_name: String, bus_name: String, objpath: dbus::Path<'static>, objpath: dbus::Path<'static>, interface: String, interface: String, Loading Loading @@ -160,6 +157,7 @@ impl btstack::RPCProxy for IBluetoothCallbackDBus { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) {} } } #[generate_dbus_exporter( #[generate_dbus_exporter( Loading Loading @@ -204,6 +202,7 @@ impl btstack::RPCProxy for IBluetoothConnectionCallbackDBus { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) {} } } #[generate_dbus_exporter( #[generate_dbus_exporter( Loading @@ -223,15 +222,10 @@ pub(crate) struct BluetoothDBus { } } impl BluetoothDBus { impl BluetoothDBus { pub(crate) fn new( pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothDBus { conn: Arc<SyncConnection>, cr: Arc<Mutex<Crossroads>>, index: i32, ) -> BluetoothDBus { BluetoothDBus { BluetoothDBus { client_proxy: ClientDBusProxy { client_proxy: ClientDBusProxy { conn: conn.clone(), conn: conn.clone(), cr: cr, bus_name: String::from("org.chromium.bluetooth"), bus_name: String::from("org.chromium.bluetooth"), objpath: make_object_path(index, "adapter"), objpath: make_object_path(index, "adapter"), interface: String::from("org.chromium.bluetooth.Bluetooth"), interface: String::from("org.chromium.bluetooth.Bluetooth"), Loading @@ -240,37 +234,31 @@ impl BluetoothDBus { } } } } trait DBusExportable {} #[generate_dbus_interface_client] #[generate_dbus_interface_client] impl IBluetooth for BluetoothDBus { impl IBluetooth for BluetoothDBus { fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) { fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) { let path_string = callback.get_object_id(); let callback = { let path = dbus::Path::new(path_string.clone()).unwrap(); let path = dbus::Path::new(callback.get_object_id()).unwrap(); export_bluetooth_callback_dbus_obj( callback.export_for_rpc(); path_string, path self.client_proxy.conn.clone(), }; &mut self.client_proxy.cr.lock().unwrap(), Arc::new(Mutex::new(callback)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); self.client_proxy.method_noreturn("RegisterCallback", (path,)) self.client_proxy.method_noreturn("RegisterCallback", (callback,)) } } fn register_connection_callback( fn register_connection_callback( &mut self, &mut self, callback: Box<dyn IBluetoothConnectionCallback + Send>, callback: Box<dyn IBluetoothConnectionCallback + Send>, ) -> u32 { ) -> u32 { let path_string = callback.get_object_id(); let callback = { let path = dbus::Path::new(path_string.clone()).unwrap(); let path = dbus::Path::new(callback.get_object_id()).unwrap(); export_bluetooth_connection_callback_dbus_obj( callback.export_for_rpc(); path_string, path self.client_proxy.conn.clone(), }; &mut self.client_proxy.cr.lock().unwrap(), Arc::new(Mutex::new(callback)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); self.client_proxy.method("RegisterConnectionCallback", (path,)) self.client_proxy.method("RegisterConnectionCallback", (callback,)) } } #[dbus_method("UnregisterConnectionCallback")] #[dbus_method("UnregisterConnectionCallback")] Loading Loading @@ -445,14 +433,10 @@ pub(crate) struct BluetoothManagerDBus { } } impl BluetoothManagerDBus { impl BluetoothManagerDBus { pub(crate) fn new( pub(crate) fn new(conn: Arc<SyncConnection>) -> BluetoothManagerDBus { conn: Arc<SyncConnection>, cr: Arc<Mutex<Crossroads>>, ) -> BluetoothManagerDBus { BluetoothManagerDBus { BluetoothManagerDBus { client_proxy: ClientDBusProxy { client_proxy: ClientDBusProxy { conn: conn.clone(), conn: conn.clone(), cr: cr, bus_name: String::from("org.chromium.bluetooth.Manager"), bus_name: String::from("org.chromium.bluetooth.Manager"), objpath: dbus::Path::new("/org/chromium/bluetooth/Manager").unwrap(), objpath: dbus::Path::new("/org/chromium/bluetooth/Manager").unwrap(), interface: String::from("org.chromium.bluetooth.Manager"), interface: String::from("org.chromium.bluetooth.Manager"), Loading Loading @@ -486,17 +470,13 @@ impl IBluetoothManager for BluetoothManagerDBus { // `generate_dbus_interface_client` doesn't support callback types yet. // `generate_dbus_interface_client` doesn't support callback types yet. // TODO(b/200732080): Support autogenerate code for callback types. // TODO(b/200732080): Support autogenerate code for callback types. fn register_callback(&mut self, callback: Box<dyn IBluetoothManagerCallback + Send>) { fn register_callback(&mut self, callback: Box<dyn IBluetoothManagerCallback + Send>) { let path_string = callback.get_object_id(); let callback = { let path = dbus::Path::new(path_string.clone()).unwrap(); let path = dbus::Path::new(callback.get_object_id()).unwrap(); export_bluetooth_manager_callback_dbus_obj( callback.export_for_rpc(); path_string, path self.client_proxy.conn.clone(), }; &mut self.client_proxy.cr.lock().unwrap(), Arc::new(Mutex::new(callback)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); self.client_proxy.method_noreturn("RegisterCallback", (path,)) self.client_proxy.method_noreturn("RegisterCallback", (callback,)) } } #[dbus_method("GetFlossEnabled")] #[dbus_method("GetFlossEnabled")] Loading Loading @@ -529,6 +509,7 @@ impl manager_service::RPCProxy for IBluetoothManagerCallbackDBus { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) {} } } #[generate_dbus_exporter( #[generate_dbus_exporter( Loading @@ -548,15 +529,10 @@ pub(crate) struct BluetoothGattDBus { } } impl BluetoothGattDBus { impl BluetoothGattDBus { pub(crate) fn new( pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus { conn: Arc<SyncConnection>, cr: Arc<Mutex<Crossroads>>, index: i32, ) -> BluetoothGattDBus { BluetoothGattDBus { BluetoothGattDBus { client_proxy: ClientDBusProxy { client_proxy: ClientDBusProxy { conn: conn.clone(), conn: conn.clone(), cr: cr, bus_name: String::from("org.chromium.bluetooth"), bus_name: String::from("org.chromium.bluetooth"), objpath: make_object_path(index, "gatt"), objpath: make_object_path(index, "gatt"), interface: String::from("org.chromium.bluetooth.BluetoothGatt"), interface: String::from("org.chromium.bluetooth.BluetoothGatt"), Loading Loading @@ -589,17 +565,13 @@ impl IBluetoothGatt for BluetoothGattDBus { callback: Box<dyn IBluetoothGattCallback + Send>, callback: Box<dyn IBluetoothGattCallback + Send>, eatt_support: bool, eatt_support: bool, ) { ) { let path_string = callback.get_object_id(); let callback = { let path = dbus::Path::new(path_string.clone()).unwrap(); let path = dbus::Path::new(callback.get_object_id()).unwrap(); export_bluetooth_gatt_callback_dbus_obj( callback.export_for_rpc(); path_string, path self.client_proxy.conn.clone(), }; &mut self.client_proxy.cr.lock().unwrap(), Arc::new(Mutex::new(callback)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); self.client_proxy.method_noreturn("RegisterClient", (app_uuid, path, eatt_support)) self.client_proxy.method_noreturn("RegisterClient", (app_uuid, callback, eatt_support)) } } #[dbus_method("UnregisterClient")] #[dbus_method("UnregisterClient")] Loading Loading @@ -760,6 +732,7 @@ impl btstack::RPCProxy for IBluetoothGattCallbackDBus { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) {} } } #[generate_dbus_exporter( #[generate_dbus_exporter( Loading system/gd/rust/linux/client/src/main.rs +20 −13 Original line number Original line Diff line number Diff line Loading @@ -82,8 +82,7 @@ impl ClientContext { ) -> ClientContext { ) -> ClientContext { // Manager interface is almost always available but adapter interface // Manager interface is almost always available but adapter interface // requires that the specific adapter is enabled. // requires that the specific adapter is enabled. let manager_dbus = let manager_dbus = BluetoothManagerDBus::new(dbus_connection.clone()); BluetoothManagerDBus::new(dbus_connection.clone(), dbus_crossroads.clone()); ClientContext { ClientContext { adapters: HashMap::new(), adapters: HashMap::new(), Loading Loading @@ -128,12 +127,11 @@ impl ClientContext { // Creates adapter proxy, registers callbacks and initializes address. // Creates adapter proxy, registers callbacks and initializes address. fn create_adapter_proxy(&mut self, idx: i32) { fn create_adapter_proxy(&mut self, idx: i32) { let conn = self.dbus_connection.clone(); let conn = self.dbus_connection.clone(); let cr = self.dbus_crossroads.clone(); let dbus = BluetoothDBus::new(conn.clone(), cr.clone(), idx); let dbus = BluetoothDBus::new(conn.clone(), idx); self.adapter_dbus = Some(dbus); self.adapter_dbus = Some(dbus); let gatt_dbus = BluetoothGattDBus::new(conn.clone(), cr.clone(), idx); let gatt_dbus = BluetoothGattDBus::new(conn.clone(), idx); self.gatt_dbus = Some(gatt_dbus); self.gatt_dbus = Some(gatt_dbus); // Trigger callback registration in the foreground // Trigger callback registration in the foreground Loading Loading @@ -212,7 +210,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { let (tx, rx) = mpsc::channel::<ForegroundActions>(10); let (tx, rx) = mpsc::channel::<ForegroundActions>(10); // Create the context needed for handling commands // Create the context needed for handling commands let context = Arc::new(Mutex::new(ClientContext::new(conn, cr, tx.clone()))); let context = Arc::new(Mutex::new(ClientContext::new(conn.clone(), cr.clone(), tx.clone()))); // Check if manager interface is valid. We only print some help text before failing on the // Check if manager interface is valid. We only print some help text before failing on the // first actual access to the interface (so we can also capture the actual reason the // first actual access to the interface (so we can also capture the actual reason the Loading @@ -228,6 +227,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { context.lock().unwrap().manager_dbus.register_callback(Box::new(BtManagerCallback::new( context.lock().unwrap().manager_dbus.register_callback(Box::new(BtManagerCallback::new( String::from("/org/chromium/bluetooth/client/bluetooth_manager_callback"), String::from("/org/chromium/bluetooth/client/bluetooth_manager_callback"), context.clone(), context.clone(), conn.clone(), cr.clone(), ))); ))); // Check if the default adapter is enabled. If yes, we should create the adapter proxy // Check if the default adapter is enabled. If yes, we should create the adapter proxy Loading Loading @@ -312,13 +313,17 @@ async fn start_interactive_shell( let conn_cb_objpath: String = let conn_cb_objpath: String = format!("/org/chromium/bluetooth/client/{}/bluetooth_conn_callback", adapter); format!("/org/chromium/bluetooth/client/{}/bluetooth_conn_callback", adapter); context let dbus_connection = context.lock().unwrap().dbus_connection.clone(); .lock() let dbus_crossroads = context.lock().unwrap().dbus_crossroads.clone(); .unwrap() .adapter_dbus context.lock().unwrap().adapter_dbus.as_mut().unwrap().register_callback(Box::new( .as_mut() BtCallback::new( .unwrap() cb_objpath, .register_callback(Box::new(BtCallback::new(cb_objpath, context.clone()))); context.clone(), dbus_connection.clone(), dbus_crossroads.clone(), ), )); context context .lock() .lock() .unwrap() .unwrap() Loading @@ -328,6 +333,8 @@ async fn start_interactive_shell( .register_connection_callback(Box::new(BtConnectionCallback::new( .register_connection_callback(Box::new(BtConnectionCallback::new( conn_cb_objpath, conn_cb_objpath, context.clone(), context.clone(), dbus_connection.clone(), dbus_crossroads.clone(), ))); ))); context.lock().unwrap().adapter_ready = true; context.lock().unwrap().adapter_ready = true; let adapter_address = context.lock().unwrap().update_adapter_address(); let adapter_address = context.lock().unwrap().update_adapter_address(); Loading system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs +2 −0 Original line number Original line Diff line number Diff line Loading @@ -571,6 +571,7 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream { String::from("") String::from("") } } fn unregister(&mut self, _id: u32) -> bool { false } fn unregister(&mut self, _id: u32) -> bool { false } fn export_for_rpc(self: Box<Self>) {} } } struct #struct_ident { struct #struct_ident { Loading @@ -596,6 +597,7 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream { fn unregister(&mut self, id: u32) -> bool { fn unregister(&mut self, id: u32) -> bool { self.disconnect_watcher.lock().unwrap().remove(self.remote.clone(), id) self.disconnect_watcher.lock().unwrap().remove(self.remote.clone(), id) } } fn export_for_rpc(self: Box<Self>) {} } } impl DBusArg for Box<dyn #trait_ + Send> { impl DBusArg for Box<dyn #trait_ + Send> { Loading Loading
system/gd/rust/linux/client/src/callbacks.rs +91 −8 Original line number Original line Diff line number Diff line use crate::dbus_iface::{ export_bluetooth_callback_dbus_obj, export_bluetooth_connection_callback_dbus_obj, export_bluetooth_gatt_callback_dbus_obj, export_bluetooth_manager_callback_dbus_obj, }; use crate::ClientContext; use crate::ClientContext; use crate::{console_yellow, print_info}; use crate::{console_yellow, print_info}; use bt_topshim::btif::{BtBondState, BtSspVariant}; use bt_topshim::btif::{BtBondState, BtSspVariant}; Loading @@ -7,6 +11,9 @@ use btstack::bluetooth::{ }; }; use btstack::bluetooth_gatt::{BluetoothGattService, IBluetoothGattCallback, LePhy}; use btstack::bluetooth_gatt::{BluetoothGattService, IBluetoothGattCallback, LePhy}; use btstack::RPCProxy; use btstack::RPCProxy; use dbus::nonblock::SyncConnection; use dbus_crossroads::Crossroads; use dbus_projection::DisconnectWatcher; use manager_service::iface_bluetooth_manager::IBluetoothManagerCallback; use manager_service::iface_bluetooth_manager::IBluetoothManagerCallback; use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex}; Loading @@ -14,11 +21,19 @@ use std::sync::{Arc, Mutex}; pub(crate) struct BtManagerCallback { pub(crate) struct BtManagerCallback { objpath: String, objpath: String, context: Arc<Mutex<ClientContext>>, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } } impl BtManagerCallback { impl BtManagerCallback { pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self { pub(crate) fn new( Self { objpath, context } objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, context, dbus_connection, dbus_crossroads } } } } } Loading Loading @@ -50,17 +65,36 @@ impl manager_service::RPCProxy for BtManagerCallback { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); export_bluetooth_manager_callback_dbus_obj( self.get_object_id(), self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(self)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); } } } /// Callback container for adapter interface callbacks. /// Callback container for adapter interface callbacks. pub(crate) struct BtCallback { pub(crate) struct BtCallback { objpath: String, objpath: String, context: Arc<Mutex<ClientContext>>, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } } impl BtCallback { impl BtCallback { pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self { pub(crate) fn new( Self { objpath, context } objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, context, dbus_connection, dbus_crossroads } } } } } Loading Loading @@ -179,16 +213,35 @@ impl RPCProxy for BtCallback { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); export_bluetooth_callback_dbus_obj( self.get_object_id(), self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(self)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); } } } pub(crate) struct BtConnectionCallback { pub(crate) struct BtConnectionCallback { objpath: String, objpath: String, _context: Arc<Mutex<ClientContext>>, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } } impl BtConnectionCallback { impl BtConnectionCallback { pub(crate) fn new(objpath: String, _context: Arc<Mutex<ClientContext>>) -> Self { pub(crate) fn new( Self { objpath, _context } objpath: String, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, _context, dbus_connection, dbus_crossroads } } } } } Loading @@ -214,16 +267,35 @@ impl RPCProxy for BtConnectionCallback { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); export_bluetooth_connection_callback_dbus_obj( self.get_object_id(), self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(self)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); } } } pub(crate) struct BtGattCallback { pub(crate) struct BtGattCallback { objpath: String, objpath: String, context: Arc<Mutex<ClientContext>>, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } } impl BtGattCallback { impl BtGattCallback { pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self { pub(crate) fn new( Self { objpath, context } objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, context, dbus_connection, dbus_crossroads } } } } } Loading Loading @@ -367,4 +439,15 @@ impl RPCProxy for BtGattCallback { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); export_bluetooth_gatt_callback_dbus_obj( self.get_object_id(), self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(self)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); } } }
system/gd/rust/linux/client/src/command_handler.rs +5 −0 Original line number Original line Diff line number Diff line Loading @@ -538,11 +538,16 @@ impl CommandHandler { enforce_arg_len(args, 1, "gatt <commands>", || match &args[0][0..] { enforce_arg_len(args, 1, "gatt <commands>", || match &args[0][0..] { "register-client" => { "register-client" => { let dbus_connection = self.context.lock().unwrap().dbus_connection.clone(); let dbus_crossroads = self.context.lock().unwrap().dbus_crossroads.clone(); self.context.lock().unwrap().gatt_dbus.as_mut().unwrap().register_client( self.context.lock().unwrap().gatt_dbus.as_mut().unwrap().register_client( String::from(GATT_CLIENT_APP_UUID), String::from(GATT_CLIENT_APP_UUID), Box::new(BtGattCallback::new( Box::new(BtGattCallback::new( String::from("/org/chromium/bluetooth/client/bluetooth_gatt_callback"), String::from("/org/chromium/bluetooth/client/bluetooth_gatt_callback"), self.context.clone(), self.context.clone(), dbus_connection, dbus_crossroads, )), )), false, false, ); ); Loading
system/gd/rust/linux/client/src/dbus_iface.rs +34 −61 Original line number Original line Diff line number Diff line Loading @@ -15,8 +15,6 @@ use btstack::bluetooth_gatt::{ use dbus::arg::{AppendAll, RefArg}; use dbus::arg::{AppendAll, RefArg}; use dbus::nonblock::SyncConnection; use dbus::nonblock::SyncConnection; use dbus_crossroads::Crossroads; use dbus_projection::{impl_dbus_arg_enum, DisconnectWatcher}; use dbus_projection::{impl_dbus_arg_enum, DisconnectWatcher}; use dbus_macros::{ use dbus_macros::{ Loading @@ -30,7 +28,7 @@ use manager_service::iface_bluetooth_manager::{ use num_traits::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive}; use std::convert::TryInto; use std::convert::TryInto; use std::sync::{Arc, Mutex}; use std::sync::Arc; use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust}; use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust}; Loading Loading @@ -98,7 +96,6 @@ pub struct BluetoothDeviceDBus { struct ClientDBusProxy { struct ClientDBusProxy { conn: Arc<SyncConnection>, conn: Arc<SyncConnection>, cr: Arc<Mutex<Crossroads>>, bus_name: String, bus_name: String, objpath: dbus::Path<'static>, objpath: dbus::Path<'static>, interface: String, interface: String, Loading Loading @@ -160,6 +157,7 @@ impl btstack::RPCProxy for IBluetoothCallbackDBus { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) {} } } #[generate_dbus_exporter( #[generate_dbus_exporter( Loading Loading @@ -204,6 +202,7 @@ impl btstack::RPCProxy for IBluetoothConnectionCallbackDBus { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) {} } } #[generate_dbus_exporter( #[generate_dbus_exporter( Loading @@ -223,15 +222,10 @@ pub(crate) struct BluetoothDBus { } } impl BluetoothDBus { impl BluetoothDBus { pub(crate) fn new( pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothDBus { conn: Arc<SyncConnection>, cr: Arc<Mutex<Crossroads>>, index: i32, ) -> BluetoothDBus { BluetoothDBus { BluetoothDBus { client_proxy: ClientDBusProxy { client_proxy: ClientDBusProxy { conn: conn.clone(), conn: conn.clone(), cr: cr, bus_name: String::from("org.chromium.bluetooth"), bus_name: String::from("org.chromium.bluetooth"), objpath: make_object_path(index, "adapter"), objpath: make_object_path(index, "adapter"), interface: String::from("org.chromium.bluetooth.Bluetooth"), interface: String::from("org.chromium.bluetooth.Bluetooth"), Loading @@ -240,37 +234,31 @@ impl BluetoothDBus { } } } } trait DBusExportable {} #[generate_dbus_interface_client] #[generate_dbus_interface_client] impl IBluetooth for BluetoothDBus { impl IBluetooth for BluetoothDBus { fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) { fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) { let path_string = callback.get_object_id(); let callback = { let path = dbus::Path::new(path_string.clone()).unwrap(); let path = dbus::Path::new(callback.get_object_id()).unwrap(); export_bluetooth_callback_dbus_obj( callback.export_for_rpc(); path_string, path self.client_proxy.conn.clone(), }; &mut self.client_proxy.cr.lock().unwrap(), Arc::new(Mutex::new(callback)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); self.client_proxy.method_noreturn("RegisterCallback", (path,)) self.client_proxy.method_noreturn("RegisterCallback", (callback,)) } } fn register_connection_callback( fn register_connection_callback( &mut self, &mut self, callback: Box<dyn IBluetoothConnectionCallback + Send>, callback: Box<dyn IBluetoothConnectionCallback + Send>, ) -> u32 { ) -> u32 { let path_string = callback.get_object_id(); let callback = { let path = dbus::Path::new(path_string.clone()).unwrap(); let path = dbus::Path::new(callback.get_object_id()).unwrap(); export_bluetooth_connection_callback_dbus_obj( callback.export_for_rpc(); path_string, path self.client_proxy.conn.clone(), }; &mut self.client_proxy.cr.lock().unwrap(), Arc::new(Mutex::new(callback)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); self.client_proxy.method("RegisterConnectionCallback", (path,)) self.client_proxy.method("RegisterConnectionCallback", (callback,)) } } #[dbus_method("UnregisterConnectionCallback")] #[dbus_method("UnregisterConnectionCallback")] Loading Loading @@ -445,14 +433,10 @@ pub(crate) struct BluetoothManagerDBus { } } impl BluetoothManagerDBus { impl BluetoothManagerDBus { pub(crate) fn new( pub(crate) fn new(conn: Arc<SyncConnection>) -> BluetoothManagerDBus { conn: Arc<SyncConnection>, cr: Arc<Mutex<Crossroads>>, ) -> BluetoothManagerDBus { BluetoothManagerDBus { BluetoothManagerDBus { client_proxy: ClientDBusProxy { client_proxy: ClientDBusProxy { conn: conn.clone(), conn: conn.clone(), cr: cr, bus_name: String::from("org.chromium.bluetooth.Manager"), bus_name: String::from("org.chromium.bluetooth.Manager"), objpath: dbus::Path::new("/org/chromium/bluetooth/Manager").unwrap(), objpath: dbus::Path::new("/org/chromium/bluetooth/Manager").unwrap(), interface: String::from("org.chromium.bluetooth.Manager"), interface: String::from("org.chromium.bluetooth.Manager"), Loading Loading @@ -486,17 +470,13 @@ impl IBluetoothManager for BluetoothManagerDBus { // `generate_dbus_interface_client` doesn't support callback types yet. // `generate_dbus_interface_client` doesn't support callback types yet. // TODO(b/200732080): Support autogenerate code for callback types. // TODO(b/200732080): Support autogenerate code for callback types. fn register_callback(&mut self, callback: Box<dyn IBluetoothManagerCallback + Send>) { fn register_callback(&mut self, callback: Box<dyn IBluetoothManagerCallback + Send>) { let path_string = callback.get_object_id(); let callback = { let path = dbus::Path::new(path_string.clone()).unwrap(); let path = dbus::Path::new(callback.get_object_id()).unwrap(); export_bluetooth_manager_callback_dbus_obj( callback.export_for_rpc(); path_string, path self.client_proxy.conn.clone(), }; &mut self.client_proxy.cr.lock().unwrap(), Arc::new(Mutex::new(callback)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); self.client_proxy.method_noreturn("RegisterCallback", (path,)) self.client_proxy.method_noreturn("RegisterCallback", (callback,)) } } #[dbus_method("GetFlossEnabled")] #[dbus_method("GetFlossEnabled")] Loading Loading @@ -529,6 +509,7 @@ impl manager_service::RPCProxy for IBluetoothManagerCallbackDBus { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) {} } } #[generate_dbus_exporter( #[generate_dbus_exporter( Loading @@ -548,15 +529,10 @@ pub(crate) struct BluetoothGattDBus { } } impl BluetoothGattDBus { impl BluetoothGattDBus { pub(crate) fn new( pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus { conn: Arc<SyncConnection>, cr: Arc<Mutex<Crossroads>>, index: i32, ) -> BluetoothGattDBus { BluetoothGattDBus { BluetoothGattDBus { client_proxy: ClientDBusProxy { client_proxy: ClientDBusProxy { conn: conn.clone(), conn: conn.clone(), cr: cr, bus_name: String::from("org.chromium.bluetooth"), bus_name: String::from("org.chromium.bluetooth"), objpath: make_object_path(index, "gatt"), objpath: make_object_path(index, "gatt"), interface: String::from("org.chromium.bluetooth.BluetoothGatt"), interface: String::from("org.chromium.bluetooth.BluetoothGatt"), Loading Loading @@ -589,17 +565,13 @@ impl IBluetoothGatt for BluetoothGattDBus { callback: Box<dyn IBluetoothGattCallback + Send>, callback: Box<dyn IBluetoothGattCallback + Send>, eatt_support: bool, eatt_support: bool, ) { ) { let path_string = callback.get_object_id(); let callback = { let path = dbus::Path::new(path_string.clone()).unwrap(); let path = dbus::Path::new(callback.get_object_id()).unwrap(); export_bluetooth_gatt_callback_dbus_obj( callback.export_for_rpc(); path_string, path self.client_proxy.conn.clone(), }; &mut self.client_proxy.cr.lock().unwrap(), Arc::new(Mutex::new(callback)), Arc::new(Mutex::new(DisconnectWatcher::new())), ); self.client_proxy.method_noreturn("RegisterClient", (app_uuid, path, eatt_support)) self.client_proxy.method_noreturn("RegisterClient", (app_uuid, callback, eatt_support)) } } #[dbus_method("UnregisterClient")] #[dbus_method("UnregisterClient")] Loading Loading @@ -760,6 +732,7 @@ impl btstack::RPCProxy for IBluetoothGattCallbackDBus { fn unregister(&mut self, _id: u32) -> bool { fn unregister(&mut self, _id: u32) -> bool { false false } } fn export_for_rpc(self: Box<Self>) {} } } #[generate_dbus_exporter( #[generate_dbus_exporter( Loading
system/gd/rust/linux/client/src/main.rs +20 −13 Original line number Original line Diff line number Diff line Loading @@ -82,8 +82,7 @@ impl ClientContext { ) -> ClientContext { ) -> ClientContext { // Manager interface is almost always available but adapter interface // Manager interface is almost always available but adapter interface // requires that the specific adapter is enabled. // requires that the specific adapter is enabled. let manager_dbus = let manager_dbus = BluetoothManagerDBus::new(dbus_connection.clone()); BluetoothManagerDBus::new(dbus_connection.clone(), dbus_crossroads.clone()); ClientContext { ClientContext { adapters: HashMap::new(), adapters: HashMap::new(), Loading Loading @@ -128,12 +127,11 @@ impl ClientContext { // Creates adapter proxy, registers callbacks and initializes address. // Creates adapter proxy, registers callbacks and initializes address. fn create_adapter_proxy(&mut self, idx: i32) { fn create_adapter_proxy(&mut self, idx: i32) { let conn = self.dbus_connection.clone(); let conn = self.dbus_connection.clone(); let cr = self.dbus_crossroads.clone(); let dbus = BluetoothDBus::new(conn.clone(), cr.clone(), idx); let dbus = BluetoothDBus::new(conn.clone(), idx); self.adapter_dbus = Some(dbus); self.adapter_dbus = Some(dbus); let gatt_dbus = BluetoothGattDBus::new(conn.clone(), cr.clone(), idx); let gatt_dbus = BluetoothGattDBus::new(conn.clone(), idx); self.gatt_dbus = Some(gatt_dbus); self.gatt_dbus = Some(gatt_dbus); // Trigger callback registration in the foreground // Trigger callback registration in the foreground Loading Loading @@ -212,7 +210,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { let (tx, rx) = mpsc::channel::<ForegroundActions>(10); let (tx, rx) = mpsc::channel::<ForegroundActions>(10); // Create the context needed for handling commands // Create the context needed for handling commands let context = Arc::new(Mutex::new(ClientContext::new(conn, cr, tx.clone()))); let context = Arc::new(Mutex::new(ClientContext::new(conn.clone(), cr.clone(), tx.clone()))); // Check if manager interface is valid. We only print some help text before failing on the // Check if manager interface is valid. We only print some help text before failing on the // first actual access to the interface (so we can also capture the actual reason the // first actual access to the interface (so we can also capture the actual reason the Loading @@ -228,6 +227,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { context.lock().unwrap().manager_dbus.register_callback(Box::new(BtManagerCallback::new( context.lock().unwrap().manager_dbus.register_callback(Box::new(BtManagerCallback::new( String::from("/org/chromium/bluetooth/client/bluetooth_manager_callback"), String::from("/org/chromium/bluetooth/client/bluetooth_manager_callback"), context.clone(), context.clone(), conn.clone(), cr.clone(), ))); ))); // Check if the default adapter is enabled. If yes, we should create the adapter proxy // Check if the default adapter is enabled. If yes, we should create the adapter proxy Loading Loading @@ -312,13 +313,17 @@ async fn start_interactive_shell( let conn_cb_objpath: String = let conn_cb_objpath: String = format!("/org/chromium/bluetooth/client/{}/bluetooth_conn_callback", adapter); format!("/org/chromium/bluetooth/client/{}/bluetooth_conn_callback", adapter); context let dbus_connection = context.lock().unwrap().dbus_connection.clone(); .lock() let dbus_crossroads = context.lock().unwrap().dbus_crossroads.clone(); .unwrap() .adapter_dbus context.lock().unwrap().adapter_dbus.as_mut().unwrap().register_callback(Box::new( .as_mut() BtCallback::new( .unwrap() cb_objpath, .register_callback(Box::new(BtCallback::new(cb_objpath, context.clone()))); context.clone(), dbus_connection.clone(), dbus_crossroads.clone(), ), )); context context .lock() .lock() .unwrap() .unwrap() Loading @@ -328,6 +333,8 @@ async fn start_interactive_shell( .register_connection_callback(Box::new(BtConnectionCallback::new( .register_connection_callback(Box::new(BtConnectionCallback::new( conn_cb_objpath, conn_cb_objpath, context.clone(), context.clone(), dbus_connection.clone(), dbus_crossroads.clone(), ))); ))); context.lock().unwrap().adapter_ready = true; context.lock().unwrap().adapter_ready = true; let adapter_address = context.lock().unwrap().update_adapter_address(); let adapter_address = context.lock().unwrap().update_adapter_address(); Loading
system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs +2 −0 Original line number Original line Diff line number Diff line Loading @@ -571,6 +571,7 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream { String::from("") String::from("") } } fn unregister(&mut self, _id: u32) -> bool { false } fn unregister(&mut self, _id: u32) -> bool { false } fn export_for_rpc(self: Box<Self>) {} } } struct #struct_ident { struct #struct_ident { Loading @@ -596,6 +597,7 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream { fn unregister(&mut self, id: u32) -> bool { fn unregister(&mut self, id: u32) -> bool { self.disconnect_watcher.lock().unwrap().remove(self.remote.clone(), id) self.disconnect_watcher.lock().unwrap().remove(self.remote.clone(), id) } } fn export_for_rpc(self: Box<Self>) {} } } impl DBusArg for Box<dyn #trait_ + Send> { impl DBusArg for Box<dyn #trait_ + Send> { Loading