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

Commit 703c071d authored by Hsin-chen Chuang's avatar Hsin-chen Chuang Committed by Automerger Merge Worker
Browse files

Merge "floss: Refactor btstack initialization order (2/4 BluetoothAdmin)" into main am: a0c9568d

parents 573cc15c a0c9568d
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
@@ -190,12 +190,6 @@ impl InterfaceManager {
                            mixin.clone(),
                            mixin.clone(),
                        );
                        );


                        cr.lock().unwrap().insert(
                            Self::make_object_name(virt_index, "admin"),
                            &[admin_iface],
                            bluetooth_admin.clone(),
                        );

                        cr.lock().unwrap().insert(
                        cr.lock().unwrap().insert(
                            Self::make_object_name(virt_index, "logging"),
                            Self::make_object_name(virt_index, "logging"),
                            &[logging_iface],
                            &[logging_iface],
@@ -221,6 +215,13 @@ impl InterfaceManager {
                                .init_adv_manager(bt_clone, is_le_ext_adv_supported);
                                .init_adv_manager(bt_clone, is_le_ext_adv_supported);
                        });
                        });
                    }
                    }
                    BluetoothAPI::Admin => {
                        cr.lock().unwrap().insert(
                            Self::make_object_name(virt_index, "admin"),
                            &[admin_iface],
                            bluetooth_admin.clone(),
                        );
                    }
                    BluetoothAPI::Gatt => {
                    BluetoothAPI::Gatt => {
                        cr.lock().unwrap().insert(
                        cr.lock().unwrap().insert(
                            Self::make_object_name(virt_index, "gatt"),
                            Self::make_object_name(virt_index, "gatt"),
+9 −7
Original line number Original line Diff line number Diff line
@@ -186,10 +186,6 @@ fn main() -> Result<(), Box<dyn Error>> {
            intf.clone(),
            intf.clone(),
            battery_provider_manager.clone(),
            battery_provider_manager.clone(),
        ))));
        ))));
        let bluetooth_admin = Arc::new(Mutex::new(Box::new(BluetoothAdmin::new(
            String::from(ADMIN_SETTINGS_FILE_PATH),
            tx.clone(),
        ))));
        let bluetooth = Arc::new(Mutex::new(Box::new(Bluetooth::new(
        let bluetooth = Arc::new(Mutex::new(Box::new(Bluetooth::new(
            virt_index,
            virt_index,
            hci_index,
            hci_index,
@@ -197,7 +193,6 @@ fn main() -> Result<(), Box<dyn Error>> {
            api_tx.clone(),
            api_tx.clone(),
            sig_notifier.clone(),
            sig_notifier.clone(),
            intf.clone(),
            intf.clone(),
            bluetooth_admin.clone(),
            bluetooth_gatt.clone(),
            bluetooth_gatt.clone(),
            bluetooth_media.clone(),
            bluetooth_media.clone(),
        ))));
        ))));
@@ -215,7 +210,6 @@ fn main() -> Result<(), Box<dyn Error>> {
        ))));
        ))));


        bluetooth_media.lock().unwrap().set_adapter(bluetooth.clone());
        bluetooth_media.lock().unwrap().set_adapter(bluetooth.clone());
        bluetooth_admin.lock().unwrap().set_adapter(bluetooth.clone());


        bluetooth.lock().unwrap().init(init_flags, hci_index);
        bluetooth.lock().unwrap().init(init_flags, hci_index);
        bluetooth.lock().unwrap().enable();
        bluetooth.lock().unwrap().enable();
@@ -227,7 +221,15 @@ fn main() -> Result<(), Box<dyn Error>> {
            tx.clone(),
            tx.clone(),
            bt_sock_mgr_runtime,
            bt_sock_mgr_runtime,
            intf.clone(),
            intf.clone(),
            bluetooth_admin.clone(),
        ))));

        // This construction doesn't need |intf| to be init-ed, but just depends on those who need.
        let bluetooth_admin = Arc::new(Mutex::new(Box::new(BluetoothAdmin::new(
            String::from(ADMIN_SETTINGS_FILE_PATH),
            tx.clone(),
            bluetooth.clone(),
            bluetooth_media.clone(),
            bt_sock_mgr.clone(),
        ))));
        ))));


        // Run the stack main dispatch loop.
        // Run the stack main dispatch loop.
+36 −124
Original line number Original line Diff line number Diff line
@@ -44,7 +44,7 @@ use tokio::task::JoinHandle;
use tokio::time;
use tokio::time;


use crate::battery_service::BatteryServiceActions;
use crate::battery_service::BatteryServiceActions;
use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin};
use crate::bluetooth_admin::BluetoothAdminPolicyHelper;
use crate::bluetooth_gatt::{
use crate::bluetooth_gatt::{
    BluetoothGatt, GattActions, IBluetoothGatt, IScannerCallback, ScanResult,
    BluetoothGatt, GattActions, IBluetoothGatt, IScannerCallback, ScanResult,
};
};
@@ -575,22 +575,6 @@ pub trait IBluetoothCallback: RPCProxy {
    fn on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32);
    fn on_sdp_record_created(&mut self, record: BtSdpRecord, handle: i32);
}
}


/// An interface for other modules to track found remote devices.
pub trait IBluetoothDeviceCallback {
    /// When a device is found via discovery.
    fn on_device_found(&mut self, remote_device: BluetoothDevice);

    /// When a device is cleared from discovered devices cache.
    fn on_device_cleared(&mut self, remote_device: BluetoothDevice);

    /// When a device property is changed.
    fn on_remote_device_properties_changed(
        &mut self,
        remote_device: BluetoothDevice,
        properties: Vec<BluetoothProperty>,
    );
}

pub trait IBluetoothConnectionCallback: RPCProxy {
pub trait IBluetoothConnectionCallback: RPCProxy {
    /// Notification sent when a remote device completes HCI connection.
    /// Notification sent when a remote device completes HCI connection.
    fn on_device_connected(&mut self, remote_device: BluetoothDevice);
    fn on_device_connected(&mut self, remote_device: BluetoothDevice);
@@ -608,7 +592,6 @@ pub struct Bluetooth {
    remote_devices: HashMap<RawAddress, BluetoothDeviceContext>,
    remote_devices: HashMap<RawAddress, BluetoothDeviceContext>,
    ble_scanner_id: Option<u8>,
    ble_scanner_id: Option<u8>,
    ble_scanner_uuid: Option<Uuid>,
    ble_scanner_uuid: Option<Uuid>,
    bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
    bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
    bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
    bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
    bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
    callbacks: Callbacks<dyn IBluetoothCallback + Send>,
    callbacks: Callbacks<dyn IBluetoothCallback + Send>,
@@ -657,7 +640,6 @@ impl Bluetooth {
        api_tx: Sender<APIMessage>,
        api_tx: Sender<APIMessage>,
        sig_notifier: Arc<SigData>,
        sig_notifier: Arc<SigData>,
        intf: Arc<Mutex<BluetoothInterface>>,
        intf: Arc<Mutex<BluetoothInterface>>,
        bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
        bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
        bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>,
        bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
        bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
    ) -> Bluetooth {
    ) -> Bluetooth {
@@ -673,7 +655,6 @@ impl Bluetooth {
            hh: None,
            hh: None,
            ble_scanner_id: None,
            ble_scanner_id: None,
            ble_scanner_uuid: None,
            ble_scanner_uuid: None,
            bluetooth_admin,
            bluetooth_gatt,
            bluetooth_gatt,
            bluetooth_media,
            bluetooth_media,
            discovering_started: Instant::now(),
            discovering_started: Instant::now(),
@@ -739,114 +720,42 @@ impl Bluetooth {
        });
        });
    }
    }


    fn disable_profile(&mut self, profile: &Profile) {
        if !UuidHelper::is_profile_supported(profile) {
            return;
        }

        match profile {
            Profile::Hid => {
                self.hh.as_mut().unwrap().activate_hidp(false);
            }

            Profile::Hogp => {
                self.hh.as_mut().unwrap().activate_hogp(false);
            }

            Profile::A2dpSource
            | Profile::Hfp
            | Profile::AvrcpTarget
            | Profile::LeAudio
            | Profile::VolumeControl
            | Profile::CoordinatedSet => {
                self.bluetooth_media.lock().unwrap().disable_profile(profile);
            }
            // Ignore profiles that we don't connect.
            _ => (),
        }
    }

    fn enable_profile(&mut self, profile: &Profile) {
        if !UuidHelper::is_profile_supported(profile) {
            return;
        }

        match profile {
            Profile::Hid => {
                self.hh.as_mut().unwrap().activate_hidp(true);
            }

            Profile::Hogp => {
                self.hh.as_mut().unwrap().activate_hogp(true);
            }

            Profile::A2dpSource
            | Profile::Hfp
            | Profile::AvrcpTarget
            | Profile::LeAudio
            | Profile::VolumeControl
            | Profile::CoordinatedSet => {
                self.bluetooth_media.lock().unwrap().enable_profile(profile);
            }
            // Ignore profiles that we don't connect.
            _ => (),
        }
    }

    fn is_profile_enabled(&self, profile: &Profile) -> Option<bool> {
        if !UuidHelper::is_profile_supported(profile) {
            return None;
        }

        match profile {
            Profile::Hid => Some(self.hh.as_ref().unwrap().is_hidp_activated),

            Profile::Hogp => Some(self.hh.as_ref().unwrap().is_hogp_activated),

            Profile::A2dpSource
            | Profile::Hfp
            | Profile::AvrcpTarget
            | Profile::LeAudio
            | Profile::VolumeControl
            | Profile::CoordinatedSet => {
                self.bluetooth_media.lock().unwrap().is_profile_enabled(profile)
            }
            // Ignore profiles that we don't connect.
            _ => None,
        }
    }

    pub(crate) fn get_hci_index(&self) -> u16 {
    pub(crate) fn get_hci_index(&self) -> u16 {
        self.hci_index as u16
        self.hci_index as u16
    }
    }


    pub fn toggle_enabled_profiles(&mut self, allowed_services: &Vec<Uuid>) {
    pub(crate) fn handle_admin_policy_changed(
        for profile in UuidHelper::get_ordered_supported_profiles() {
        &mut self,
            // Only toggle initializable profiles.
        admin_policy_helper: BluetoothAdminPolicyHelper,
            if let Some(enabled) = self.is_profile_enabled(&profile) {
    ) {
                let allowed = allowed_services.is_empty()
        match (
                    || allowed_services.contains(UuidHelper::get_profile_uuid(&profile).unwrap());
            admin_policy_helper.is_profile_allowed(&Profile::Hid),

            self.hh.as_ref().unwrap().is_hidp_activated,
                if allowed && !enabled {
        ) {
                    debug!("Enabling profile {}", &profile);
            (true, false) => self.hh.as_mut().unwrap().activate_hidp(true),
                    self.enable_profile(&profile);
            (false, true) => self.hh.as_mut().unwrap().activate_hidp(false),
                } else if !allowed && enabled {
            _ => {}
                    debug!("Disabling profile {}", &profile);
                    self.disable_profile(&profile);
                }
        }
        }

        match (
            admin_policy_helper.is_profile_allowed(&Profile::Hogp),
            self.hh.as_ref().unwrap().is_hogp_activated,
        ) {
            (true, false) => self.hh.as_mut().unwrap().activate_hogp(true),
            (false, true) => self.hh.as_mut().unwrap().activate_hogp(false),
            _ => {}
        }
        }


        if self.hh.as_mut().unwrap().configure_enabled_profiles() {
        if self.hh.as_mut().unwrap().configure_enabled_profiles() {
            self.hh.as_mut().unwrap().disable();
            self.hh.as_mut().unwrap().disable();
            let txl = self.tx.clone();
            let tx = self.tx.clone();


            tokio::spawn(async move {
            tokio::spawn(async move {
                // Wait 100 milliseconds to prevent race condition caused by quick disable then
                // Wait 100 milliseconds to prevent race condition caused by quick disable then
                // enable.
                // enable.
                // TODO: (b/272191117): don't enable until we're sure disable is done.
                // TODO: (b/272191117): don't enable until we're sure disable is done.
                tokio::time::sleep(Duration::from_millis(100)).await;
                tokio::time::sleep(Duration::from_millis(100)).await;
                let _ = txl.send(Message::HidHostEnable).await;
                let _ = tx.send(Message::HidHostEnable).await;
            });
            });
        }
        }
    }
    }
@@ -868,8 +777,6 @@ impl Bluetooth {
            dispatch: make_message_dispatcher(self.tx.clone(), Message::HidHost),
            dispatch: make_message_dispatcher(self.tx.clone(), Message::HidHost),
        });
        });


        let allowed_profiles = self.bluetooth_admin.lock().unwrap().get_allowed_services();
        self.toggle_enabled_profiles(&allowed_profiles);
        // Mark profiles as ready
        // Mark profiles as ready
        self.profiles_ready = true;
        self.profiles_ready = true;
    }
    }
@@ -1075,6 +982,20 @@ impl Bluetooth {
            .collect()
            .collect()
    }
    }


    /// Returns all devices with UUIDs, while None means there's not yet an UUID property change.
    pub(crate) fn get_all_devices_and_uuids(&self) -> Vec<(BluetoothDevice, Option<Vec<Uuid>>)> {
        self.remote_devices
            .values()
            .map(|d| {
                let uuids = d.properties.get(&BtPropertyType::Uuids).and_then(|prop| match prop {
                    BluetoothProperty::Uuids(uuids) => Some(uuids.clone()),
                    _ => None,
                });
                (d.info.clone(), uuids)
            })
            .collect()
    }

    /// Gets the bond state of a single device with its address.
    /// Gets the bond state of a single device with its address.
    pub fn get_bond_state_by_addr(&self, addr: &RawAddress) -> BtBondState {
    pub fn get_bond_state_by_addr(&self, addr: &RawAddress) -> BtBondState {
        self.remote_devices.get(addr).map_or(BtBondState::NotBonded, |d| d.bond_state.clone())
        self.remote_devices.get(addr).map_or(BtBondState::NotBonded, |d| d.bond_state.clone())
@@ -1112,8 +1033,6 @@ impl Bluetooth {
            self.callbacks.for_all_callbacks(|callback| {
            self.callbacks.for_all_callbacks(|callback| {
                callback.on_device_cleared(d.clone());
                callback.on_device_cleared(d.clone());
            });
            });

            self.bluetooth_admin.lock().unwrap().on_device_cleared(&d);
        }
        }
    }
    }


@@ -1706,8 +1625,6 @@ impl BtifBluetoothCallbacks for Bluetooth {
                );
                );
            });
            });
        }
        }

        self.bluetooth_admin.lock().unwrap().on_device_found(&device_info);
    }
    }


    fn discovery_state(&mut self, state: BtDiscoveryState) {
    fn discovery_state(&mut self, state: BtDiscoveryState) {
@@ -1979,11 +1896,6 @@ impl BtifBluetoothCallbacks for Bluetooth {
            );
            );
        });
        });


        self.bluetooth_admin
            .lock()
            .unwrap()
            .on_remote_device_properties_changed(&info, &properties);

        // Only care about device type property changed on bonded device.
        // Only care about device type property changed on bonded device.
        // If the property change happens during bonding, it will be updated after bonding complete anyway.
        // If the property change happens during bonding, it will be updated after bonding complete anyway.
        if self.get_bond_state_by_addr(&addr) == BtBondState::Bonded
        if self.get_bond_state_by_addr(&addr) == BtBondState::Bonded
+274 −122

File changed.

Preview size limit exceeded, changes collapsed.

+24 −0
Original line number Original line Diff line number Diff line
@@ -60,6 +60,7 @@ use crate::battery_provider_manager::{
    BatteryProviderManager, IBatteryProviderCallback, IBatteryProviderManager,
    BatteryProviderManager, IBatteryProviderCallback, IBatteryProviderManager,
};
};
use crate::bluetooth::{Bluetooth, BluetoothDevice, IBluetooth};
use crate::bluetooth::{Bluetooth, BluetoothDevice, IBluetooth};
use crate::bluetooth_admin::BluetoothAdminPolicyHelper;
use crate::callbacks::Callbacks;
use crate::callbacks::Callbacks;
use crate::uuid;
use crate::uuid;
use crate::uuid::{Profile, UuidHelper};
use crate::uuid::{Profile, UuidHelper};
@@ -811,6 +812,29 @@ impl BluetoothMedia {
        }
        }
    }
    }


    pub(crate) fn handle_admin_policy_changed(&mut self, admin_helper: BluetoothAdminPolicyHelper) {
        for profile in UuidHelper::get_ordered_supported_profiles() {
            match profile {
                Profile::A2dpSource
                | Profile::AvrcpTarget
                | Profile::Hfp
                | Profile::LeAudio
                | Profile::VolumeControl
                | Profile::CoordinatedSet => {}
                _ => continue,
            }
            let profile = &profile;
            match (
                admin_helper.is_profile_allowed(profile),
                self.is_profile_enabled(profile).unwrap(),
            ) {
                (true, false) => self.enable_profile(profile),
                (false, true) => self.disable_profile(profile),
                _ => {}
            }
        }
    }

    pub fn dispatch_csis_callbacks(&mut self, cb: CsisClientCallbacks) {
    pub fn dispatch_csis_callbacks(&mut self, cb: CsisClientCallbacks) {
        match cb {
        match cb {
            CsisClientCallbacks::ConnectionState(addr, state) => {
            CsisClientCallbacks::ConnectionState(addr, state) => {
Loading