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

Commit 031660da authored by Sarvesh Kalwit's avatar Sarvesh Kalwit
Browse files

Floss: Wait to request battery data until after bonding

Previously, we would send requests to read GATT-based battery data
immediately after forming an ACL connection. However, if the device was
not bonded by the time this request was sent, some peripherals would
reject the read request.

With this change, we wait until after bonding is complete to request
battery data.

Bug: 329796289
Test: m && manual verification with Logitech Casa Keys
Flag: Exempt, Floss-only

Change-Id: Iaf29059c1b3149cf54d9d6a22ed5988b3d339d87
parent b7d0abce
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ use crate::uuid::UuidHelper;
use crate::Message;
use crate::RPCProxy;
use crate::{uuid, APIMessage, BluetoothAPI};
use bt_topshim::btif::{BtTransport, DisplayAddress, RawAddress, Uuid};
use bt_topshim::btif::{BtAclState, BtBondState, BtTransport, DisplayAddress, RawAddress, Uuid};
use bt_topshim::profiles::gatt::{GattStatus, LePhy};
use log::debug;
use std::collections::HashMap;
@@ -57,7 +57,7 @@ pub enum BatteryServiceActions {
    /// Params: addr, handle, value
    OnNotify(RawAddress, i32, Vec<u8>),
    /// Params: remote_device, transport
    Connect(BluetoothDevice, BtTransport),
    Connect(BluetoothDevice, BtAclState, BtBondState, BtTransport),
    /// Params: remote_device
    Disconnect(BluetoothDevice),
}
@@ -223,10 +223,14 @@ impl BatteryService {
                });
            }

            BatteryServiceActions::Connect(device, transport) => {
                if transport != BtTransport::Le {
            BatteryServiceActions::Connect(device, acl_state, bond_state, transport) => {
                if transport != BtTransport::Le
                    || acl_state != BtAclState::Connected
                    || bond_state != BtBondState::Bonded
                {
                    return;
                }

                self.init_device(device.address, transport);
            }

+40 −6
Original line number Diff line number Diff line
@@ -1884,16 +1884,36 @@ impl BtifBluetoothCallbacks for Bluetooth {
                        Instant::now(),
                        vec![],
                    ));
                    let acl_reported_transport = device.acl_reported_transport.clone();
                    let acl_state = device.ble_acl_state.clone();
                    let device_info = device.info.clone();

                    // Since this is a newly bonded device, we also need to trigger SDP on it.
                    device.services_resolved = false;
                    self.fetch_remote_uuids(device_info);
                    self.fetch_remote_uuids(device_info.clone());
                    if self.get_wake_allowed_device_bonded() {
                        self.create_uhid_for_suspend_wakesource();
                    }
                    // Update the connectable mode since bonded list is changed.
                    self.trigger_update_connectable_mode();

                    let transport = match self.get_remote_type(device_info.clone()) {
                        BtDeviceType::Bredr => BtTransport::Bredr,
                        BtDeviceType::Ble => BtTransport::Le,
                        _ => acl_reported_transport,
                    };

                    let tx = self.tx.clone();
                    tokio::spawn(async move {
                        let _ = tx
                            .send(Message::OnDeviceConnectionStateChanged(
                                device_info.clone(),
                                acl_state,
                                BtBondState::Bonded,
                                transport,
                            ))
                            .await;
                    });
                }
                BtBondState::Bonding => {}
            }
@@ -2046,6 +2066,7 @@ impl BtifBluetoothCallbacks for Bluetooth {

        let info = device.info.clone();
        device.acl_reported_transport = link_type;
        let bond_state = device.bond_state.clone();

        metrics::acl_connection_state_changed(
            addr,
@@ -2069,7 +2090,14 @@ impl BtifBluetoothCallbacks for Bluetooth {
                    _ => acl_reported_transport,
                };
                tokio::spawn(async move {
                    let _ = txl.send(Message::OnAclConnected(info, transport)).await;
                    let _ = txl
                        .send(Message::OnDeviceConnectionStateChanged(
                            info,
                            BtAclState::Connected,
                            bond_state,
                            transport,
                        ))
                        .await;
                });
            }
            BtAclState::Disconnected => {
@@ -2079,7 +2107,7 @@ impl BtifBluetoothCallbacks for Bluetooth {
                    });
                }
                tokio::spawn(async move {
                    let _ = txl.send(Message::OnAclDisconnected(info)).await;
                    let _ = txl.send(Message::OnDeviceDisconnected(info)).await;
                });
            }
        };
@@ -2791,21 +2819,27 @@ impl IBluetooth for Bluetooth {
                            Profile::Bas => {
                                has_supported_profile = true;
                                let tx = self.tx.clone();
                                let transport = match self.remote_devices.get(&addr) {
                                    Some(context) => context.acl_reported_transport,
                                let device_context = match self.remote_devices.get(&addr) {
                                    Some(context) => context,
                                    None => return BtStatus::RemoteDeviceDown,
                                };

                                let acl_state = device_context.ble_acl_state.clone();
                                let bond_state = device_context.bond_state.clone();
                                let device_to_send = device.clone();

                                let transport = match self.get_remote_type(device.clone()) {
                                    BtDeviceType::Bredr => BtTransport::Bredr,
                                    BtDeviceType::Ble => BtTransport::Le,
                                    _ => transport,
                                    _ => device_context.acl_reported_transport.clone(),
                                };
                                topstack::get_runtime().spawn(async move {
                                    let _ = tx
                                        .send(Message::BatteryService(
                                            BatteryServiceActions::Connect(
                                                device_to_send,
                                                acl_state,
                                                bond_state,
                                                transport,
                                            ),
                                        ))
+15 −11
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ use crate::dis::{DeviceInformation, ServiceCallbacks};
use crate::socket_manager::{BluetoothSocketManager, SocketActions};
use crate::suspend::Suspend;
use bt_topshim::{
    btif::{BaseCallbacks, BtTransport, RawAddress},
    btif::{BaseCallbacks, BtAclState, BtBondState, BtTransport, RawAddress},
    profiles::{
        a2dp::A2dpCallbacks,
        avrcp::AvrcpCallbacks,
@@ -108,10 +108,10 @@ pub enum Message {
    TriggerUpdateConnectableMode,
    DelayedAdapterActions(DelayedActions),

    // Follows IBluetooth's on_device_(dis)connected callback but doesn't require depending on
    // Bluetooth.
    OnAclConnected(BluetoothDevice, BtTransport),
    OnAclDisconnected(BluetoothDevice),
    // Follows IBluetooth's on_device_(dis)connected and bond_state callbacks
    // but doesn't require depending on Bluetooth.
    OnDeviceConnectionStateChanged(BluetoothDevice, BtAclState, BtBondState, BtTransport),
    OnDeviceDisconnected(BluetoothDevice),

    // Suspend related
    SuspendCallbackRegistered(u32),
@@ -380,16 +380,20 @@ impl Stack {
                // Any service needing an updated list of devices can have an
                // update method triggered from here rather than needing a
                // reference to Bluetooth.
                Message::OnAclConnected(device, transport) => {
                    battery_service
                        .lock()
                        .unwrap()
                        .handle_action(BatteryServiceActions::Connect(device, transport));
                Message::OnDeviceConnectionStateChanged(
                    device,
                    acl_state,
                    bond_state,
                    transport,
                ) => {
                    battery_service.lock().unwrap().handle_action(BatteryServiceActions::Connect(
                        device, acl_state, bond_state, transport,
                    ));
                }

                // For battery service, use this to clean up internal handles. GATT connection is
                // already dropped if ACL disconnect has occurred.
                Message::OnAclDisconnected(device) => {
                Message::OnDeviceDisconnected(device) => {
                    battery_service
                        .lock()
                        .unwrap()