Loading system/gd/rust/linux/client/src/dbus_iface.rs +119 −94 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ use dbus_crossroads::Crossroads; use dbus_projection::{impl_dbus_arg_enum, DisconnectWatcher}; use dbus_macros::{dbus_method, dbus_propmap, generate_dbus_exporter}; use dbus_macros::{ dbus_method, dbus_propmap, generate_dbus_exporter, generate_dbus_interface_client, }; use manager_service::iface_bluetooth_manager::{ AdapterWithEnabled, IBluetoothManager, IBluetoothManagerCallback, Loading @@ -41,6 +43,7 @@ impl_dbus_arg_enum!(BtSspVariant); impl_dbus_arg_enum!(GattStatus); impl_dbus_arg_enum!(GattWriteType); impl_dbus_arg_enum!(LePhy); impl_dbus_arg_enum!(GattWriteRequestStatus); // Represents Uuid128Bit as an array in D-Bus. impl DBusArg for Uuid128Bit { Loading Loading @@ -237,7 +240,7 @@ impl BluetoothDBus { } } // TODO(b/200732080): These are boilerplate codes, consider creating a macro to generate. #[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(); Loading Loading @@ -270,8 +273,9 @@ impl IBluetooth for BluetoothDBus { self.client_proxy.method("RegisterConnectionCallback", (path,)) } #[dbus_method("UnregisterConnectionCallback")] fn unregister_connection_callback(&mut self, id: u32) -> bool { self.client_proxy.method("UnregisterConnectionCallback", (id,)) dbus_generated!() } fn enable(&mut self) -> bool { Loading @@ -284,136 +288,149 @@ impl IBluetooth for BluetoothDBus { true } #[dbus_method("GetAddress")] fn get_address(&self) -> String { self.client_proxy.method("GetAddress", ()) dbus_generated!() } #[dbus_method("GetUuids")] fn get_uuids(&self) -> Vec<Uuid128Bit> { let result: Vec<Vec<u8>> = self.client_proxy.method("GetUuids", ()); <Vec<Uuid128Bit> as DBusArg>::from_dbus(result, None, None, None).unwrap() dbus_generated!() } #[dbus_method("GetName")] fn get_name(&self) -> String { self.client_proxy.method("GetName", ()) dbus_generated!() } #[dbus_method("SetName")] fn set_name(&self, name: String) -> bool { self.client_proxy.method("SetName", (name,)) dbus_generated!() } #[dbus_method("GetBluetoothClass")] fn get_bluetooth_class(&self) -> u32 { self.client_proxy.method("GetBluetoothClass", ()) dbus_generated!() } #[dbus_method("SetBluetoothClass")] fn set_bluetooth_class(&self, cod: u32) -> bool { self.client_proxy.method("SetBluetoothClass", (cod,)) dbus_generated!() } #[dbus_method("GetDiscoverable")] fn get_discoverable(&self) -> bool { self.client_proxy.method("GetDiscoverable", ()) dbus_generated!() } #[dbus_method("GetDiscoverableTimeout")] fn get_discoverable_timeout(&self) -> u32 { self.client_proxy.method("GetDiscoverableTimeout", ()) dbus_generated!() } #[dbus_method("SetDiscoverable")] fn set_discoverable(&self, mode: bool, duration: u32) -> bool { self.client_proxy.method("SetDiscoverable", (mode, duration)) dbus_generated!() } #[dbus_method("IsMultiAdvertisementSupported")] fn is_multi_advertisement_supported(&self) -> bool { self.client_proxy.method("IsMultiAdvertisementSupported", ()) dbus_generated!() } #[dbus_method("IsLeExtendedAdvertisingSupported")] fn is_le_extended_advertising_supported(&self) -> bool { self.client_proxy.method("IsLeExtendedAdvertisingSupported", ()) dbus_generated!() } #[dbus_method("StartDiscovery")] fn start_discovery(&self) -> bool { self.client_proxy.method("StartDiscovery", ()) dbus_generated!() } #[dbus_method("CancelDiscovery")] fn cancel_discovery(&self) -> bool { self.client_proxy.method("CancelDiscovery", ()) dbus_generated!() } #[dbus_method("IsDiscovering")] fn is_discovering(&self) -> bool { self.client_proxy.method("IsDiscovering", ()) dbus_generated!() } #[dbus_method("GetDiscoveryEndMillis")] fn get_discovery_end_millis(&self) -> u64 { self.client_proxy.method("GetDiscoveryEndMillis", ()) dbus_generated!() } #[dbus_method("CreateBond")] fn create_bond(&self, device: BluetoothDevice, transport: BtTransport) -> bool { self.client_proxy.method( "CreateBond", (BluetoothDevice::to_dbus(device).unwrap(), BtTransport::to_dbus(transport).unwrap()), ) dbus_generated!() } #[dbus_method("CancelBondProcess")] fn cancel_bond_process(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("CancelBondProcess", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("RemoveBond")] fn remove_bond(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("RemoveBond", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("GetBondedDevices")] fn get_bonded_devices(&self) -> Vec<BluetoothDevice> { let props: Vec<dbus::arg::PropMap> = self.client_proxy.method("GetBondedDevices", ()); <Vec<BluetoothDevice> as DBusArg>::from_dbus(props, None, None, None).unwrap() dbus_generated!() } #[dbus_method("GetBondState")] fn get_bond_state(&self, device: BluetoothDevice) -> u32 { self.client_proxy.method("GetBondState", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("SetPin")] fn set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool { self.client_proxy .method("SetPin", (BluetoothDevice::to_dbus(device).unwrap(), accept, pin_code)) dbus_generated!() } #[dbus_method("SetPasskey")] fn set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool { self.client_proxy .method("SetPasskey", (BluetoothDevice::to_dbus(device).unwrap(), accept, passkey)) dbus_generated!() } #[dbus_method("SetPairingConfirmation")] fn set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool { self.client_proxy .method("SetPairingConfirmation", (BluetoothDevice::to_dbus(device).unwrap(), accept)) dbus_generated!() } #[dbus_method("GetConnectionState")] fn get_connection_state(&self, device: BluetoothDevice) -> u32 { self.client_proxy.method("GetConnectionState", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("GetRemoteUuids")] fn get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid128Bit> { let result: Vec<Vec<u8>> = self .client_proxy .method("GetRemoteUuids", (BluetoothDevice::to_dbus(device).unwrap(),)); <Vec<Uuid128Bit> as DBusArg>::from_dbus(result, None, None, None).unwrap() dbus_generated!() } #[dbus_method("FetchRemoteUuids")] fn fetch_remote_uuids(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("FetchRemoteUuids", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("SdpSearch")] fn sdp_search(&self, device: BluetoothDevice, uuid: Uuid128Bit) -> bool { self.client_proxy.method( "SdpSearch", (BluetoothDevice::to_dbus(device).unwrap(), Uuid128Bit::to_dbus(uuid).unwrap()), ) dbus_generated!() } #[dbus_method("ConnectAllEnabledProfiles")] fn connect_all_enabled_profiles(&self, device: BluetoothDevice) -> bool { self.client_proxy .method("ConnectAllEnabledProfiles", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("DisconnectAllEnabledProfiles")] fn disconnect_all_enabled_profiles(&self, device: BluetoothDevice) -> bool { self.client_proxy .method("DisconnectAllEnabledProfiles", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } } Loading Loading @@ -449,20 +466,25 @@ impl BluetoothManagerDBus { } } // TODO: These are boilerplate codes, consider creating a macro to generate. #[generate_dbus_interface_client] impl IBluetoothManager for BluetoothManagerDBus { #[dbus_method("Start")] fn start(&mut self, hci_interface: i32) { self.client_proxy.method_noreturn("Start", (hci_interface,)) dbus_generated!() } #[dbus_method("Stop")] fn stop(&mut self, hci_interface: i32) { self.client_proxy.method_noreturn("Stop", (hci_interface,)) dbus_generated!() } #[dbus_method("GetAdapterEnabled")] fn get_adapter_enabled(&mut self, hci_interface: i32) -> bool { self.client_proxy.method("GetAdapterEnabled", (hci_interface,)) dbus_generated!() } // `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(); Loading @@ -477,17 +499,19 @@ impl IBluetoothManager for BluetoothManagerDBus { self.client_proxy.method_noreturn("RegisterCallback", (path,)) } #[dbus_method("GetFlossEnabled")] fn get_floss_enabled(&mut self) -> bool { self.client_proxy.method("GetFlossEnabled", ()) dbus_generated!() } #[dbus_method("SetFlossEnabled")] fn set_floss_enabled(&mut self, enabled: bool) { self.client_proxy.method_noreturn("SetFlossEnabled", (enabled,)) dbus_generated!() } #[dbus_method("GetAvailableAdapters")] fn get_available_adapters(&mut self) -> Vec<AdapterWithEnabled> { let props: Vec<dbus::arg::PropMap> = self.client_proxy.method("GetAvailableAdapters", ()); <Vec<AdapterWithEnabled> as DBusArg>::from_dbus(props, None, None, None).unwrap() dbus_generated!() } } Loading Loading @@ -541,7 +565,7 @@ impl BluetoothGattDBus { } } // TODO: These are boilerplate codes, consider creating a macro to generate. #[generate_dbus_interface_client] impl IBluetoothGatt for BluetoothGattDBus { fn register_scanner(&self, _callback: Box<dyn IScannerCallback + Send>) { // TODO(b/200066804): implement Loading Loading @@ -578,10 +602,12 @@ impl IBluetoothGatt for BluetoothGattDBus { self.client_proxy.method_noreturn("RegisterClient", (app_uuid, path, eatt_support)) } #[dbus_method("UnregisterClient")] fn unregister_client(&mut self, client_id: i32) { self.client_proxy.method_noreturn("UnregisterClient", (client_id,)) dbus_generated!() } #[dbus_method("ClientConnect")] fn client_connect( &self, client_id: i32, Loading @@ -591,16 +617,15 @@ impl IBluetoothGatt for BluetoothGattDBus { opportunistic: bool, phy: i32, ) { self.client_proxy.method_noreturn( "ClientConnect", (client_id, addr, is_direct, transport, opportunistic, phy), ) dbus_generated!() } #[dbus_method("ClientDisconnect")] fn client_disconnect(&self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("ClientDisconnect", (client_id, addr)) dbus_generated!() } #[dbus_method("ClientSetPreferredPhy")] fn client_set_preferred_phy( &self, client_id: i32, Loading @@ -609,32 +634,35 @@ impl IBluetoothGatt for BluetoothGattDBus { rx_phy: LePhy, phy_options: i32, ) { self.client_proxy.method_noreturn( "ClientSetPreferredPhy", (client_id, addr, tx_phy.to_i32().unwrap(), rx_phy.to_i32().unwrap(), phy_options), ) dbus_generated!() } #[dbus_method("ClientReadPhy")] fn client_read_phy(&mut self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("ClientReadPhy", (client_id, addr)) dbus_generated!() } #[dbus_method("RefreshDevice")] fn refresh_device(&self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("RefreshDevice", (client_id, addr)) dbus_generated!() } #[dbus_method("DiscoverServices")] fn discover_services(&self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("DiscoverServices", (client_id, addr)) dbus_generated!() } #[dbus_method("DiscoverServiceByUuid")] fn discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String) { self.client_proxy.method_noreturn("DiscoverServiceByUuid", (client_id, addr, uuid)) dbus_generated!() } #[dbus_method("ReadCharacteristic")] fn read_characteristic(&self, client_id: i32, addr: String, handle: i32, auth_req: i32) { self.client_proxy.method_noreturn("ReadCharacteristic", (client_id, addr, handle, auth_req)) dbus_generated!() } #[dbus_method("ReadUsingCharacteristicUuid")] fn read_using_characteristic_uuid( &self, client_id: i32, Loading @@ -644,12 +672,10 @@ impl IBluetoothGatt for BluetoothGattDBus { end_handle: i32, auth_req: i32, ) { self.client_proxy.method_noreturn( "ReadUsingCharacteristicUuid", (client_id, addr, uuid, start_handle, end_handle, auth_req), ) dbus_generated!() } #[dbus_method("WriteCharacteristic")] fn write_characteristic( &self, client_id: i32, Loading @@ -659,17 +685,15 @@ impl IBluetoothGatt for BluetoothGattDBus { auth_req: i32, value: Vec<u8>, ) -> GattWriteRequestStatus { GattWriteRequestStatus::from_i32(self.client_proxy.method( "WriteCharacteristic", (client_id, addr, handle, write_type.to_i32().unwrap(), auth_req, value), )) .unwrap() dbus_generated!() } #[dbus_method("ReadDescriptor")] fn read_descriptor(&self, client_id: i32, addr: String, handle: i32, auth_req: i32) { self.client_proxy.method_noreturn("ReadDescriptor", (client_id, addr, handle, auth_req)) dbus_generated!() } #[dbus_method("WriteDescriptor")] fn write_descriptor( &self, client_id: i32, Loading @@ -678,31 +702,35 @@ impl IBluetoothGatt for BluetoothGattDBus { auth_req: i32, value: Vec<u8>, ) { self.client_proxy .method_noreturn("WriteDescriptor", (client_id, addr, handle, auth_req, value)) dbus_generated!() } #[dbus_method("RegisterForNotification")] fn register_for_notification(&self, client_id: i32, addr: String, handle: i32, enable: bool) { self.client_proxy .method_noreturn("RegisterForNotification", (client_id, addr, handle, enable)) dbus_generated!() } #[dbus_method("BeginReliableWrite")] fn begin_reliable_write(&mut self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("BeginReliableWrite", (client_id, addr)) dbus_generated!() } #[dbus_method("EndReliableWrite")] fn end_reliable_write(&mut self, client_id: i32, addr: String, execute: bool) { self.client_proxy.method_noreturn("EndReliableWrite", (client_id, addr, execute)) dbus_generated!() } #[dbus_method("ReadRemoteRssi")] fn read_remote_rssi(&self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("ReadRemoteRssi", (client_id, addr)) dbus_generated!() } #[dbus_method("ConfigureMtu")] fn configure_mtu(&self, client_id: i32, addr: String, mtu: i32) { self.client_proxy.method_noreturn("ConfigureMtu", (client_id, addr, mtu)) dbus_generated!() } #[dbus_method("ConnectionParameterUpdate")] fn connection_parameter_update( &self, client_id: i32, Loading @@ -714,10 +742,7 @@ impl IBluetoothGatt for BluetoothGattDBus { min_ce_len: u16, max_ce_len: u16, ) { self.client_proxy.method_noreturn( "ConnectionParameterUpdate", (client_id, addr, min_interval, max_interval, latency, timeout, min_ce_len, max_ce_len), ) dbus_generated!() } } Loading system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs +135 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,135 @@ pub fn generate_dbus_exporter(attr: TokenStream, item: TokenStream) -> TokenStre gen.into() } /// Generates a client implementation of a D-Bus interface. /// /// Example: /// #[generate_dbus_interface_client()] /// /// The impl containing #[dbus_method()] will contain a generated code to call the method via D-Bus. #[proc_macro_attribute] pub fn generate_dbus_interface_client(_attr: TokenStream, item: TokenStream) -> TokenStream { let ast: ItemImpl = syn::parse(item.clone()).unwrap(); let trait_path = ast.trait_.unwrap().1; let struct_path = match *ast.self_ty { Type::Path(path) => path, _ => panic!("Struct path not available"), }; let mut methods = quote! {}; // Iterate on every methods of a trait impl for item in ast.items { if let ImplItem::Method(method) = item { // If the method is not marked with #[dbus_method], just copy the // original method body. if method.attrs.len() != 1 { methods = quote! { #methods #method }; continue; } let attr = &method.attrs[0]; if !attr.path.get_ident().unwrap().to_string().eq("dbus_method") { continue; } let sig = &method.sig; let dbus_method_name = if let Meta::List(meta_list) = attr.parse_meta().unwrap() { Some(meta_list.nested[0].clone()) } else { None }; if dbus_method_name.is_none() { continue; } let mut input_list = quote! {}; // Iterate on every parameter of a method to build a tuple, e.g. // `(param1, param2, param3)` for input in &method.sig.inputs { if let FnArg::Typed(ref typed) = input { let arg_type = &typed.ty; if let Pat::Ident(pat_ident) = &*typed.pat { let ident = pat_ident.ident.clone(); input_list = quote! { #input_list <#arg_type as DBusArg>::to_dbus(#ident).unwrap(), }; } } } let mut output_as_dbus_arg = quote! {}; if let ReturnType::Type(_, t) = &method.sig.output { output_as_dbus_arg = quote! {<#t as DBusArg>}; } let input_tuple = quote! { (#input_list) }; let body = match &method.sig.output { // Build the method call to `self.client_proxy`. `method` or `method_noreturn` // depends on whether there is a return from the function. ReturnType::Default => { quote! { self.client_proxy.method_noreturn(#dbus_method_name, #input_tuple) } } _ => { quote! { let ret: #output_as_dbus_arg::DBusType = self.client_proxy.method( #dbus_method_name, #input_tuple, ); #output_as_dbus_arg::from_dbus(ret, None, None, None).unwrap() } } }; // The method definition is its signature and the body. let generated_method = quote! { #sig { #body } }; // Assemble all the method definitions. methods = quote! { #methods #generated_method }; } } let gen = quote! { impl #trait_path for #struct_path { #methods } }; // TODO: Have a switch to turn on/off this debug. debug_output_to_file( &gen, std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()) .join(format!("out-{}.rs", struct_path.path.get_ident().unwrap())) .to_str() .unwrap() .to_string(), ); gen.into() } fn copy_without_attributes(item: &TokenStream) -> TokenStream { let mut ast: ItemStruct = syn::parse(item.clone()).unwrap(); for field in &mut ast.fields { Loading Loading @@ -365,7 +494,13 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream { for item in ast.items { if let ImplItem::Method(method) = item { // If the method is not marked with #[dbus_method], just copy the // original method body. if method.attrs.len() != 1 { method_impls = quote! { #method_impls #method }; continue; } Loading Loading
system/gd/rust/linux/client/src/dbus_iface.rs +119 −94 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ use dbus_crossroads::Crossroads; use dbus_projection::{impl_dbus_arg_enum, DisconnectWatcher}; use dbus_macros::{dbus_method, dbus_propmap, generate_dbus_exporter}; use dbus_macros::{ dbus_method, dbus_propmap, generate_dbus_exporter, generate_dbus_interface_client, }; use manager_service::iface_bluetooth_manager::{ AdapterWithEnabled, IBluetoothManager, IBluetoothManagerCallback, Loading @@ -41,6 +43,7 @@ impl_dbus_arg_enum!(BtSspVariant); impl_dbus_arg_enum!(GattStatus); impl_dbus_arg_enum!(GattWriteType); impl_dbus_arg_enum!(LePhy); impl_dbus_arg_enum!(GattWriteRequestStatus); // Represents Uuid128Bit as an array in D-Bus. impl DBusArg for Uuid128Bit { Loading Loading @@ -237,7 +240,7 @@ impl BluetoothDBus { } } // TODO(b/200732080): These are boilerplate codes, consider creating a macro to generate. #[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(); Loading Loading @@ -270,8 +273,9 @@ impl IBluetooth for BluetoothDBus { self.client_proxy.method("RegisterConnectionCallback", (path,)) } #[dbus_method("UnregisterConnectionCallback")] fn unregister_connection_callback(&mut self, id: u32) -> bool { self.client_proxy.method("UnregisterConnectionCallback", (id,)) dbus_generated!() } fn enable(&mut self) -> bool { Loading @@ -284,136 +288,149 @@ impl IBluetooth for BluetoothDBus { true } #[dbus_method("GetAddress")] fn get_address(&self) -> String { self.client_proxy.method("GetAddress", ()) dbus_generated!() } #[dbus_method("GetUuids")] fn get_uuids(&self) -> Vec<Uuid128Bit> { let result: Vec<Vec<u8>> = self.client_proxy.method("GetUuids", ()); <Vec<Uuid128Bit> as DBusArg>::from_dbus(result, None, None, None).unwrap() dbus_generated!() } #[dbus_method("GetName")] fn get_name(&self) -> String { self.client_proxy.method("GetName", ()) dbus_generated!() } #[dbus_method("SetName")] fn set_name(&self, name: String) -> bool { self.client_proxy.method("SetName", (name,)) dbus_generated!() } #[dbus_method("GetBluetoothClass")] fn get_bluetooth_class(&self) -> u32 { self.client_proxy.method("GetBluetoothClass", ()) dbus_generated!() } #[dbus_method("SetBluetoothClass")] fn set_bluetooth_class(&self, cod: u32) -> bool { self.client_proxy.method("SetBluetoothClass", (cod,)) dbus_generated!() } #[dbus_method("GetDiscoverable")] fn get_discoverable(&self) -> bool { self.client_proxy.method("GetDiscoverable", ()) dbus_generated!() } #[dbus_method("GetDiscoverableTimeout")] fn get_discoverable_timeout(&self) -> u32 { self.client_proxy.method("GetDiscoverableTimeout", ()) dbus_generated!() } #[dbus_method("SetDiscoverable")] fn set_discoverable(&self, mode: bool, duration: u32) -> bool { self.client_proxy.method("SetDiscoverable", (mode, duration)) dbus_generated!() } #[dbus_method("IsMultiAdvertisementSupported")] fn is_multi_advertisement_supported(&self) -> bool { self.client_proxy.method("IsMultiAdvertisementSupported", ()) dbus_generated!() } #[dbus_method("IsLeExtendedAdvertisingSupported")] fn is_le_extended_advertising_supported(&self) -> bool { self.client_proxy.method("IsLeExtendedAdvertisingSupported", ()) dbus_generated!() } #[dbus_method("StartDiscovery")] fn start_discovery(&self) -> bool { self.client_proxy.method("StartDiscovery", ()) dbus_generated!() } #[dbus_method("CancelDiscovery")] fn cancel_discovery(&self) -> bool { self.client_proxy.method("CancelDiscovery", ()) dbus_generated!() } #[dbus_method("IsDiscovering")] fn is_discovering(&self) -> bool { self.client_proxy.method("IsDiscovering", ()) dbus_generated!() } #[dbus_method("GetDiscoveryEndMillis")] fn get_discovery_end_millis(&self) -> u64 { self.client_proxy.method("GetDiscoveryEndMillis", ()) dbus_generated!() } #[dbus_method("CreateBond")] fn create_bond(&self, device: BluetoothDevice, transport: BtTransport) -> bool { self.client_proxy.method( "CreateBond", (BluetoothDevice::to_dbus(device).unwrap(), BtTransport::to_dbus(transport).unwrap()), ) dbus_generated!() } #[dbus_method("CancelBondProcess")] fn cancel_bond_process(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("CancelBondProcess", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("RemoveBond")] fn remove_bond(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("RemoveBond", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("GetBondedDevices")] fn get_bonded_devices(&self) -> Vec<BluetoothDevice> { let props: Vec<dbus::arg::PropMap> = self.client_proxy.method("GetBondedDevices", ()); <Vec<BluetoothDevice> as DBusArg>::from_dbus(props, None, None, None).unwrap() dbus_generated!() } #[dbus_method("GetBondState")] fn get_bond_state(&self, device: BluetoothDevice) -> u32 { self.client_proxy.method("GetBondState", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("SetPin")] fn set_pin(&self, device: BluetoothDevice, accept: bool, pin_code: Vec<u8>) -> bool { self.client_proxy .method("SetPin", (BluetoothDevice::to_dbus(device).unwrap(), accept, pin_code)) dbus_generated!() } #[dbus_method("SetPasskey")] fn set_passkey(&self, device: BluetoothDevice, accept: bool, passkey: Vec<u8>) -> bool { self.client_proxy .method("SetPasskey", (BluetoothDevice::to_dbus(device).unwrap(), accept, passkey)) dbus_generated!() } #[dbus_method("SetPairingConfirmation")] fn set_pairing_confirmation(&self, device: BluetoothDevice, accept: bool) -> bool { self.client_proxy .method("SetPairingConfirmation", (BluetoothDevice::to_dbus(device).unwrap(), accept)) dbus_generated!() } #[dbus_method("GetConnectionState")] fn get_connection_state(&self, device: BluetoothDevice) -> u32 { self.client_proxy.method("GetConnectionState", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("GetRemoteUuids")] fn get_remote_uuids(&self, device: BluetoothDevice) -> Vec<Uuid128Bit> { let result: Vec<Vec<u8>> = self .client_proxy .method("GetRemoteUuids", (BluetoothDevice::to_dbus(device).unwrap(),)); <Vec<Uuid128Bit> as DBusArg>::from_dbus(result, None, None, None).unwrap() dbus_generated!() } #[dbus_method("FetchRemoteUuids")] fn fetch_remote_uuids(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("FetchRemoteUuids", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("SdpSearch")] fn sdp_search(&self, device: BluetoothDevice, uuid: Uuid128Bit) -> bool { self.client_proxy.method( "SdpSearch", (BluetoothDevice::to_dbus(device).unwrap(), Uuid128Bit::to_dbus(uuid).unwrap()), ) dbus_generated!() } #[dbus_method("ConnectAllEnabledProfiles")] fn connect_all_enabled_profiles(&self, device: BluetoothDevice) -> bool { self.client_proxy .method("ConnectAllEnabledProfiles", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } #[dbus_method("DisconnectAllEnabledProfiles")] fn disconnect_all_enabled_profiles(&self, device: BluetoothDevice) -> bool { self.client_proxy .method("DisconnectAllEnabledProfiles", (BluetoothDevice::to_dbus(device).unwrap(),)) dbus_generated!() } } Loading Loading @@ -449,20 +466,25 @@ impl BluetoothManagerDBus { } } // TODO: These are boilerplate codes, consider creating a macro to generate. #[generate_dbus_interface_client] impl IBluetoothManager for BluetoothManagerDBus { #[dbus_method("Start")] fn start(&mut self, hci_interface: i32) { self.client_proxy.method_noreturn("Start", (hci_interface,)) dbus_generated!() } #[dbus_method("Stop")] fn stop(&mut self, hci_interface: i32) { self.client_proxy.method_noreturn("Stop", (hci_interface,)) dbus_generated!() } #[dbus_method("GetAdapterEnabled")] fn get_adapter_enabled(&mut self, hci_interface: i32) -> bool { self.client_proxy.method("GetAdapterEnabled", (hci_interface,)) dbus_generated!() } // `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(); Loading @@ -477,17 +499,19 @@ impl IBluetoothManager for BluetoothManagerDBus { self.client_proxy.method_noreturn("RegisterCallback", (path,)) } #[dbus_method("GetFlossEnabled")] fn get_floss_enabled(&mut self) -> bool { self.client_proxy.method("GetFlossEnabled", ()) dbus_generated!() } #[dbus_method("SetFlossEnabled")] fn set_floss_enabled(&mut self, enabled: bool) { self.client_proxy.method_noreturn("SetFlossEnabled", (enabled,)) dbus_generated!() } #[dbus_method("GetAvailableAdapters")] fn get_available_adapters(&mut self) -> Vec<AdapterWithEnabled> { let props: Vec<dbus::arg::PropMap> = self.client_proxy.method("GetAvailableAdapters", ()); <Vec<AdapterWithEnabled> as DBusArg>::from_dbus(props, None, None, None).unwrap() dbus_generated!() } } Loading Loading @@ -541,7 +565,7 @@ impl BluetoothGattDBus { } } // TODO: These are boilerplate codes, consider creating a macro to generate. #[generate_dbus_interface_client] impl IBluetoothGatt for BluetoothGattDBus { fn register_scanner(&self, _callback: Box<dyn IScannerCallback + Send>) { // TODO(b/200066804): implement Loading Loading @@ -578,10 +602,12 @@ impl IBluetoothGatt for BluetoothGattDBus { self.client_proxy.method_noreturn("RegisterClient", (app_uuid, path, eatt_support)) } #[dbus_method("UnregisterClient")] fn unregister_client(&mut self, client_id: i32) { self.client_proxy.method_noreturn("UnregisterClient", (client_id,)) dbus_generated!() } #[dbus_method("ClientConnect")] fn client_connect( &self, client_id: i32, Loading @@ -591,16 +617,15 @@ impl IBluetoothGatt for BluetoothGattDBus { opportunistic: bool, phy: i32, ) { self.client_proxy.method_noreturn( "ClientConnect", (client_id, addr, is_direct, transport, opportunistic, phy), ) dbus_generated!() } #[dbus_method("ClientDisconnect")] fn client_disconnect(&self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("ClientDisconnect", (client_id, addr)) dbus_generated!() } #[dbus_method("ClientSetPreferredPhy")] fn client_set_preferred_phy( &self, client_id: i32, Loading @@ -609,32 +634,35 @@ impl IBluetoothGatt for BluetoothGattDBus { rx_phy: LePhy, phy_options: i32, ) { self.client_proxy.method_noreturn( "ClientSetPreferredPhy", (client_id, addr, tx_phy.to_i32().unwrap(), rx_phy.to_i32().unwrap(), phy_options), ) dbus_generated!() } #[dbus_method("ClientReadPhy")] fn client_read_phy(&mut self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("ClientReadPhy", (client_id, addr)) dbus_generated!() } #[dbus_method("RefreshDevice")] fn refresh_device(&self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("RefreshDevice", (client_id, addr)) dbus_generated!() } #[dbus_method("DiscoverServices")] fn discover_services(&self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("DiscoverServices", (client_id, addr)) dbus_generated!() } #[dbus_method("DiscoverServiceByUuid")] fn discover_service_by_uuid(&self, client_id: i32, addr: String, uuid: String) { self.client_proxy.method_noreturn("DiscoverServiceByUuid", (client_id, addr, uuid)) dbus_generated!() } #[dbus_method("ReadCharacteristic")] fn read_characteristic(&self, client_id: i32, addr: String, handle: i32, auth_req: i32) { self.client_proxy.method_noreturn("ReadCharacteristic", (client_id, addr, handle, auth_req)) dbus_generated!() } #[dbus_method("ReadUsingCharacteristicUuid")] fn read_using_characteristic_uuid( &self, client_id: i32, Loading @@ -644,12 +672,10 @@ impl IBluetoothGatt for BluetoothGattDBus { end_handle: i32, auth_req: i32, ) { self.client_proxy.method_noreturn( "ReadUsingCharacteristicUuid", (client_id, addr, uuid, start_handle, end_handle, auth_req), ) dbus_generated!() } #[dbus_method("WriteCharacteristic")] fn write_characteristic( &self, client_id: i32, Loading @@ -659,17 +685,15 @@ impl IBluetoothGatt for BluetoothGattDBus { auth_req: i32, value: Vec<u8>, ) -> GattWriteRequestStatus { GattWriteRequestStatus::from_i32(self.client_proxy.method( "WriteCharacteristic", (client_id, addr, handle, write_type.to_i32().unwrap(), auth_req, value), )) .unwrap() dbus_generated!() } #[dbus_method("ReadDescriptor")] fn read_descriptor(&self, client_id: i32, addr: String, handle: i32, auth_req: i32) { self.client_proxy.method_noreturn("ReadDescriptor", (client_id, addr, handle, auth_req)) dbus_generated!() } #[dbus_method("WriteDescriptor")] fn write_descriptor( &self, client_id: i32, Loading @@ -678,31 +702,35 @@ impl IBluetoothGatt for BluetoothGattDBus { auth_req: i32, value: Vec<u8>, ) { self.client_proxy .method_noreturn("WriteDescriptor", (client_id, addr, handle, auth_req, value)) dbus_generated!() } #[dbus_method("RegisterForNotification")] fn register_for_notification(&self, client_id: i32, addr: String, handle: i32, enable: bool) { self.client_proxy .method_noreturn("RegisterForNotification", (client_id, addr, handle, enable)) dbus_generated!() } #[dbus_method("BeginReliableWrite")] fn begin_reliable_write(&mut self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("BeginReliableWrite", (client_id, addr)) dbus_generated!() } #[dbus_method("EndReliableWrite")] fn end_reliable_write(&mut self, client_id: i32, addr: String, execute: bool) { self.client_proxy.method_noreturn("EndReliableWrite", (client_id, addr, execute)) dbus_generated!() } #[dbus_method("ReadRemoteRssi")] fn read_remote_rssi(&self, client_id: i32, addr: String) { self.client_proxy.method_noreturn("ReadRemoteRssi", (client_id, addr)) dbus_generated!() } #[dbus_method("ConfigureMtu")] fn configure_mtu(&self, client_id: i32, addr: String, mtu: i32) { self.client_proxy.method_noreturn("ConfigureMtu", (client_id, addr, mtu)) dbus_generated!() } #[dbus_method("ConnectionParameterUpdate")] fn connection_parameter_update( &self, client_id: i32, Loading @@ -714,10 +742,7 @@ impl IBluetoothGatt for BluetoothGattDBus { min_ce_len: u16, max_ce_len: u16, ) { self.client_proxy.method_noreturn( "ConnectionParameterUpdate", (client_id, addr, min_interval, max_interval, latency, timeout, min_ce_len, max_ce_len), ) dbus_generated!() } } Loading
system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs +135 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,135 @@ pub fn generate_dbus_exporter(attr: TokenStream, item: TokenStream) -> TokenStre gen.into() } /// Generates a client implementation of a D-Bus interface. /// /// Example: /// #[generate_dbus_interface_client()] /// /// The impl containing #[dbus_method()] will contain a generated code to call the method via D-Bus. #[proc_macro_attribute] pub fn generate_dbus_interface_client(_attr: TokenStream, item: TokenStream) -> TokenStream { let ast: ItemImpl = syn::parse(item.clone()).unwrap(); let trait_path = ast.trait_.unwrap().1; let struct_path = match *ast.self_ty { Type::Path(path) => path, _ => panic!("Struct path not available"), }; let mut methods = quote! {}; // Iterate on every methods of a trait impl for item in ast.items { if let ImplItem::Method(method) = item { // If the method is not marked with #[dbus_method], just copy the // original method body. if method.attrs.len() != 1 { methods = quote! { #methods #method }; continue; } let attr = &method.attrs[0]; if !attr.path.get_ident().unwrap().to_string().eq("dbus_method") { continue; } let sig = &method.sig; let dbus_method_name = if let Meta::List(meta_list) = attr.parse_meta().unwrap() { Some(meta_list.nested[0].clone()) } else { None }; if dbus_method_name.is_none() { continue; } let mut input_list = quote! {}; // Iterate on every parameter of a method to build a tuple, e.g. // `(param1, param2, param3)` for input in &method.sig.inputs { if let FnArg::Typed(ref typed) = input { let arg_type = &typed.ty; if let Pat::Ident(pat_ident) = &*typed.pat { let ident = pat_ident.ident.clone(); input_list = quote! { #input_list <#arg_type as DBusArg>::to_dbus(#ident).unwrap(), }; } } } let mut output_as_dbus_arg = quote! {}; if let ReturnType::Type(_, t) = &method.sig.output { output_as_dbus_arg = quote! {<#t as DBusArg>}; } let input_tuple = quote! { (#input_list) }; let body = match &method.sig.output { // Build the method call to `self.client_proxy`. `method` or `method_noreturn` // depends on whether there is a return from the function. ReturnType::Default => { quote! { self.client_proxy.method_noreturn(#dbus_method_name, #input_tuple) } } _ => { quote! { let ret: #output_as_dbus_arg::DBusType = self.client_proxy.method( #dbus_method_name, #input_tuple, ); #output_as_dbus_arg::from_dbus(ret, None, None, None).unwrap() } } }; // The method definition is its signature and the body. let generated_method = quote! { #sig { #body } }; // Assemble all the method definitions. methods = quote! { #methods #generated_method }; } } let gen = quote! { impl #trait_path for #struct_path { #methods } }; // TODO: Have a switch to turn on/off this debug. debug_output_to_file( &gen, std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()) .join(format!("out-{}.rs", struct_path.path.get_ident().unwrap())) .to_str() .unwrap() .to_string(), ); gen.into() } fn copy_without_attributes(item: &TokenStream) -> TokenStream { let mut ast: ItemStruct = syn::parse(item.clone()).unwrap(); for field in &mut ast.fields { Loading Loading @@ -365,7 +494,13 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream { for item in ast.items { if let ImplItem::Method(method) = item { // If the method is not marked with #[dbus_method], just copy the // original method body. if method.attrs.len() != 1 { method_impls = quote! { #method_impls #method }; continue; } Loading