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