Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e04eac40 authored by Sonny Sasaka's avatar Sonny Sasaka
Browse files

Floss: Refactor btif_callbacks_dispatcher

This refactors dispatcher functions like dispatch_base_callbacks to not
assume that the generated dispatcher belongs to a particular struct, but
rather they accept object reference as parameters. This is useful when
we want to apply the dispatcher functions to multiple objects, for
example dispatching LeRand message to Suspend object instead in addition
to Bluetooth object.

Bug: 232547719
Tag: #floss
Test: Build Floss on Linux

Change-Id: Ia68f6be3af33e04201745b4d7601d015dcebe29c
parent a6d175f2
Loading
Loading
Loading
Loading
+44 −15
Original line number Diff line number Diff line
@@ -42,23 +42,53 @@ pub fn btif_callback(_attr: TokenStream, item: TokenStream) -> TokenStream {
}

/// Generates a dispatcher from a message to a function.
///
/// Example usage: This will generate a function called `dispatch_base_callbacks` to dispatch
/// `bt_topshim::btif::BaseCallbacks` to the functions in the defined trait.
///
/// ```ignore
/// #[btif_callbacks_dispatcher(dispatch_base_callbacks, BaseCallbacks)]
/// trait BtifBluetoothCallbacks {
///     #[btif_callback(Foo)]
///     fn foo(&mut self, param1: u32, param2: bool);
///     #[btif_callback(Bar)]
///     fn bar(&mut self);
/// }
/// ```
///
/// Structs can implement the callback trait like:
/// ```ignore
/// struct Struct1 {}
/// impl BtifBluetoothCallbacks for Struct1 {
///     fn foo(&mut self, param1: u32, param2: bool) {...}
///     fn bar(&mut self) {...}
/// }
///
/// struct Struct2 {}
/// impl BtifBluetoothCallbacks for Struct2 {
///     fn foo(&mut self, param1: u32, param2: bool) {...}
///     fn bar(&mut self) {...}
/// }
/// ```
///
/// The generated function can be called against any struct that implements the defined trait:
/// ```ignore
/// let struct1 = Struct1 {};
/// let struct2 = Struct2 {};
/// dispatch_base_callbacks(&mut struct1, BaseCallbacks::Foo(1, true));
/// dispatch_base_callbacks(&mut struct2, BaseCallbacks::Foo(2, false));
/// ```
#[proc_macro_attribute]
pub fn btif_callbacks_dispatcher(attr: TokenStream, item: TokenStream) -> TokenStream {
    let args = Punctuated::<Expr, Comma>::parse_separated_nonempty.parse(attr.clone()).unwrap();

    let struct_ident = if let Expr::Path(p) = &args[0] {
        p.path.get_ident().unwrap()
    } else {
        panic!("struct name must be specified");
    };

    let fn_ident = if let Expr::Path(p) = &args[1] {
    let fn_ident = if let Expr::Path(p) = &args[0] {
        p.path.get_ident().unwrap()
    } else {
        panic!("function name must be specified");
    };

    let callbacks_struct_ident = if let Expr::Path(p) = &args[2] {
    let callbacks_struct_ident = if let Expr::Path(p) = &args[1] {
        p.path.get_ident().unwrap()
    } else {
        panic!("callbacks struct ident must be specified");
@@ -67,6 +97,7 @@ pub fn btif_callbacks_dispatcher(attr: TokenStream, item: TokenStream) -> TokenS
    let mut dispatch_arms = quote! {};

    let ast: ItemTrait = syn::parse(item.clone()).unwrap();
    let trait_ident = ast.ident;

    let mut fn_names = quote! {};
    for attr in ast.items {
@@ -110,7 +141,7 @@ pub fn btif_callbacks_dispatcher(attr: TokenStream, item: TokenStream) -> TokenS
            dispatch_arms = quote! {
                #dispatch_arms
                #callbacks_struct_ident::#btif_callback(#arg_names) => {
                    self.#method_ident(#arg_names);
                    obj.#method_ident(#arg_names);
                }
            };
        }
@@ -120,15 +151,13 @@ pub fn btif_callbacks_dispatcher(attr: TokenStream, item: TokenStream) -> TokenS

    let gen = quote! {
        #ori_item
        impl #struct_ident {
            pub(crate) fn #fn_ident(&mut self, cb: #callbacks_struct_ident) {
        pub(crate) fn #fn_ident<T: #trait_ident>(obj: &mut T, cb: #callbacks_struct_ident) {
            match cb {
                #dispatch_arms

                _ => println!("Unhandled callback arm {:?}", cb),
            }
        }
        }
    };

    // TODO: Have a simple framework to turn on/off macro-generated code debug.
+3 −3
Original line number Diff line number Diff line
@@ -581,7 +581,7 @@ impl Bluetooth {
    }
}

#[btif_callbacks_dispatcher(Bluetooth, dispatch_base_callbacks, BaseCallbacks)]
#[btif_callbacks_dispatcher(dispatch_base_callbacks, BaseCallbacks)]
pub(crate) trait BtifBluetoothCallbacks {
    #[btif_callback(AdapterState)]
    fn adapter_state_changed(&mut self, state: BtState);
@@ -642,7 +642,7 @@ pub(crate) trait BtifBluetoothCallbacks {
    fn le_rand_cb(&mut self, random: u64);
}

#[btif_callbacks_dispatcher(Bluetooth, dispatch_hid_host_callbacks, HHCallbacks)]
#[btif_callbacks_dispatcher(dispatch_hid_host_callbacks, HHCallbacks)]
pub(crate) trait BtifHHCallbacks {
    #[btif_callback(ConnectionState)]
    fn connection_state(&mut self, address: RawAddress, state: BthhConnectionState);
@@ -663,7 +663,7 @@ pub(crate) trait BtifHHCallbacks {
    fn handshake(&mut self, address: RawAddress, status: BthhStatus);
}

#[btif_callbacks_dispatcher(Bluetooth, dispatch_sdp_callbacks, SdpCallbacks)]
#[btif_callbacks_dispatcher(dispatch_sdp_callbacks, SdpCallbacks)]
pub(crate) trait BtifSdpCallbacks {
    #[btif_callback(SdpSearch)]
    fn sdp_search(
+4 −8
Original line number Diff line number Diff line
@@ -1493,7 +1493,7 @@ impl IBluetoothGatt for BluetoothGatt {
    }
}

#[btif_callbacks_dispatcher(BluetoothGatt, dispatch_gatt_client_callbacks, GattClientCallbacks)]
#[btif_callbacks_dispatcher(dispatch_gatt_client_callbacks, GattClientCallbacks)]
pub(crate) trait BtifGattClientCallbacks {
    #[btif_callback(RegisterClient)]
    fn register_client_cb(&mut self, status: GattStatus, client_id: i32, app_uuid: Uuid);
@@ -2097,7 +2097,7 @@ impl BtifGattClientCallbacks for BluetoothGatt {
    }
}

#[btif_callbacks_dispatcher(BluetoothGatt, dispatch_le_scanner_callbacks, GattScannerCallbacks)]
#[btif_callbacks_dispatcher(dispatch_le_scanner_callbacks, GattScannerCallbacks)]
pub(crate) trait BtifGattScannerCallbacks {
    #[btif_callback(OnScannerRegistered)]
    fn on_scanner_registered(&mut self, uuid: Uuid, scanner_id: u8, status: GattStatus);
@@ -2118,11 +2118,7 @@ pub(crate) trait BtifGattScannerCallbacks {
    );
}

#[btif_callbacks_dispatcher(
    BluetoothGatt,
    dispatch_le_scanner_inband_callbacks,
    GattScannerInbandCallbacks
)]
#[btif_callbacks_dispatcher(dispatch_le_scanner_inband_callbacks, GattScannerInbandCallbacks)]
pub(crate) trait BtifGattScannerInbandCallbacks {
    #[btif_callback(RegisterCallback)]
    fn inband_register_callback(&mut self, app_uuid: Uuid, scanner_id: u8, btm_status: u8);
@@ -2368,7 +2364,7 @@ impl BtifGattScannerCallbacks for BluetoothGatt {
    }
}

#[btif_callbacks_dispatcher(BluetoothGatt, dispatch_le_adv_callbacks, GattAdvCallbacks)]
#[btif_callbacks_dispatcher(dispatch_le_adv_callbacks, GattAdvCallbacks)]
pub(crate) trait BtifGattAdvCallbacks {
    #[btif_callback(OnAdvertisingSetStarted)]
    fn on_advertising_set_started(
+18 −9
Original line number Diff line number Diff line
@@ -25,8 +25,14 @@ use tokio::sync::mpsc::{Receiver, Sender};

use crate::battery_manager::BatteryManager;
use crate::battery_service::{BatteryService, GattBatteryCallbacks};
use crate::bluetooth::{Bluetooth, IBluetooth};
use crate::bluetooth_gatt::BluetoothGatt;
use crate::bluetooth::{
    dispatch_base_callbacks, dispatch_hid_host_callbacks, dispatch_sdp_callbacks, Bluetooth,
    IBluetooth,
};
use crate::bluetooth_gatt::{
    dispatch_gatt_client_callbacks, dispatch_le_adv_callbacks, dispatch_le_scanner_callbacks,
    dispatch_le_scanner_inband_callbacks, BluetoothGatt,
};
use crate::bluetooth_media::{BluetoothMedia, MediaActions};
use crate::socket_manager::{BluetoothSocketManager, SocketActions};
use crate::suspend::Suspend;
@@ -145,11 +151,11 @@ impl Stack {
                }

                Message::Base(b) => {
                    bluetooth.lock().unwrap().dispatch_base_callbacks(b);
                    dispatch_base_callbacks(bluetooth.lock().unwrap().as_mut(), b);
                }

                Message::GattClient(m) => {
                    bluetooth_gatt.lock().unwrap().dispatch_gatt_client_callbacks(m);
                    dispatch_gatt_client_callbacks(bluetooth_gatt.lock().unwrap().as_mut(), m);
                }

                Message::GattServer(m) => {
@@ -158,11 +164,14 @@ impl Stack {
                }

                Message::LeScanner(m) => {
                    bluetooth_gatt.lock().unwrap().dispatch_le_scanner_callbacks(m);
                    dispatch_le_scanner_callbacks(bluetooth_gatt.lock().unwrap().as_mut(), m);
                }

                Message::LeScannerInband(m) => {
                    bluetooth_gatt.lock().unwrap().dispatch_le_scanner_inband_callbacks(m);
                    dispatch_le_scanner_inband_callbacks(
                        bluetooth_gatt.lock().unwrap().as_mut(),
                        m,
                    );
                }

                Message::LeAdvInband(m) => {
@@ -170,7 +179,7 @@ impl Stack {
                }

                Message::LeAdv(m) => {
                    bluetooth_gatt.lock().unwrap().dispatch_le_adv_callbacks(m);
                    dispatch_le_adv_callbacks(bluetooth_gatt.lock().unwrap().as_mut(), m);
                }

                Message::Hfp(hf) => {
@@ -178,11 +187,11 @@ impl Stack {
                }

                Message::HidHost(h) => {
                    bluetooth.lock().unwrap().dispatch_hid_host_callbacks(h);
                    dispatch_hid_host_callbacks(bluetooth.lock().unwrap().as_mut(), h);
                }

                Message::Sdp(s) => {
                    bluetooth.lock().unwrap().dispatch_sdp_callbacks(s);
                    dispatch_sdp_callbacks(bluetooth.lock().unwrap().as_mut(), s);
                }

                Message::Media(action) => {