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

Commit 8f6faba3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Floss: Disconnect device after GATT client closes" into main

parents 2423b5b7 4a6b6241
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -383,6 +383,7 @@ struct BluetoothDeviceContext {
    /// If supported UUIDs weren't available in EIR, wait for services to be
    /// resolved to connect.
    pub wait_to_connect: bool,
    pub connected_hid_profile: Option<Profile>,
}

impl BluetoothDeviceContext {
@@ -404,6 +405,7 @@ impl BluetoothDeviceContext {
            properties: HashMap::new(),
            services_resolved: false,
            wait_to_connect: false,
            connected_hid_profile: None,
        };
        device.update_properties(&properties);
        device
@@ -1346,6 +1348,25 @@ impl Bluetooth {
            || self.active_pairing_address.is_some()
            || self.pending_create_bond.is_some()
    }

    /// Disconnect the device if no HID or media profiles are enabled.
    pub fn disconnect_if_no_media_or_hid_profiles_connected(&mut self, device_address: RawAddress) {
        let context = match self.remote_devices.get(&device_address) {
            Some(context) => context.clone(),
            None => return,
        };
        let device = context.info.clone();

        let mut connected_profiles =
            self.bluetooth_media.lock().unwrap().get_connected_profiles(&device);
        if let Some(profile) = context.connected_hid_profile {
            connected_profiles.insert(profile);
        }
        if !connected_profiles.is_empty() {
            return;
        }
        self.disconnect_all_enabled_profiles(device);
    }
}

#[btif_callbacks_dispatcher(dispatch_base_callbacks, BaseCallbacks)]
@@ -3073,7 +3094,7 @@ impl BtifHHCallbacks for Bluetooth {
            BtDeviceType::Bredr => Profile::Hid,
            _ => {
                if self
                    .get_remote_uuids(device)
                    .get_remote_uuids(device.clone())
                    .contains(UuidHelper::get_profile_uuid(&Profile::Hogp).unwrap())
                {
                    Profile::Hogp
@@ -3087,9 +3108,19 @@ impl BtifHHCallbacks for Bluetooth {
            address,
            profile as u32,
            BtStatus::Success,
            state as u32,
            state.clone() as u32,
        );

        match state {
            BthhConnectionState::Connected => {
                self.remote_devices.entry(device.address).and_modify(|context| {
                    context.connected_hid_profile = Some(profile);
                })
            }
            _ => self.remote_devices.entry(device.address).and_modify(|context| {
                context.connected_hid_profile = None;
            }),
        };
        if BtBondState::Bonded != self.get_bond_state_by_addr(&address) {
            warn!(
                "[{}]: Rejecting a unbonded device's attempt to connect to HID/HOG profiles",
+8 −0
Original line number Diff line number Diff line
@@ -1448,6 +1448,9 @@ pub struct BluetoothGatt {

    gatt_async: Arc<tokio::sync::Mutex<GattAsyncIntf>>,
    enabled: bool,

    // For sending messages to the main event loop.
    tx: Sender<Message>,
}

impl BluetoothGatt {
@@ -1480,6 +1483,7 @@ impl BluetoothGatt {
                async_helper_msft_adv_monitor_enable,
            })),
            enabled: false,
            tx: tx.clone(),
        }
    }

@@ -2457,6 +2461,10 @@ impl IBluetoothGatt for BluetoothGatt {
        };

        self.gatt.as_ref().unwrap().lock().unwrap().client.disconnect(client_id, &addr, conn_id);
        let tx = self.tx.clone();
        tokio::spawn(async move {
            let _ = tx.send(Message::GattClientDisconnected(addr)).await;
        });
    }

    fn refresh_device(&self, client_id: i32, addr: RawAddress) {
+4 −0
Original line number Diff line number Diff line
@@ -579,6 +579,10 @@ impl BluetoothMedia {
        false
    }

    pub fn get_connected_profiles(&self, device: &BluetoothDevice) -> HashSet<Profile> {
        self.connected_profiles.get(&device.address).unwrap_or(&HashSet::new()).clone()
    }

    fn add_connected_profile(&mut self, addr: RawAddress, profile: Profile) {
        if self.is_profile_connected(&addr, &profile) {
            warn!("[{}]: profile is already connected", DisplayAddress(&addr));
+10 −0
Original line number Diff line number Diff line
@@ -168,6 +168,9 @@ pub enum Message {
    // UHid callbacks
    UHidHfpOutputCallback(RawAddress, u8, u8),
    UHidTelephonyUseCallback(RawAddress, bool),

    // GATT Callbacks
    GattClientDisconnected(RawAddress),
}

pub enum BluetoothAPI {
@@ -544,6 +547,13 @@ impl Stack {
                        .unwrap()
                        .dispatch_uhid_telephony_use_callback(addr, state);
                }

                Message::GattClientDisconnected(address) => {
                    bluetooth
                        .lock()
                        .unwrap()
                        .disconnect_if_no_media_or_hid_profiles_connected(address);
                }
            }
        }
    }
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ use topshim_macros::{cb_variant, profile_enabled_or};

use log::warn;

#[derive(Debug, FromPrimitive, PartialEq, PartialOrd)]
#[derive(Clone, Debug, FromPrimitive, PartialEq, PartialOrd)]
#[repr(u32)]
pub enum BthhConnectionState {
    Connected = 0,