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

Commit 0aee9096 authored by Katherine Lai's avatar Katherine Lai Committed by Gerrit Code Review
Browse files

Merge "floss: Add IsDualModeAudioSinkDevice API" into main

parents ea4abe7e e9cac4b0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -880,6 +880,7 @@ impl CommandHandler {
                    connection_state,
                    uuids,
                    wake_allowed,
                    dual_mode_audio,
                ) = {
                    let ctx = self.lock_context();
                    let adapter = ctx.adapter_dbus.as_ref().unwrap();
@@ -898,6 +899,7 @@ impl CommandHandler {
                    };
                    let uuids = adapter.get_remote_uuids(device.clone());
                    let wake_allowed = adapter.get_remote_wake_allowed(device.clone());
                    let dual_mode_audio = adapter.is_dual_mode_audio_sink_device(device.clone());

                    (
                        name,
@@ -910,6 +912,7 @@ impl CommandHandler {
                        connection_state,
                        uuids,
                        wake_allowed,
                        dual_mode_audio,
                    )
                };

@@ -923,6 +926,7 @@ impl CommandHandler {
                print_info!("Wake Allowed: {}", wake_allowed);
                print_info!("Bond State: {:?}", bonded);
                print_info!("Connection State: {}", connection_state);
                print_info!("Dual Mode Audio Device: {}", dual_mode_audio);
                print_info!(
                    "Uuids: {}",
                    DisplayList(
+5 −0
Original line number Diff line number Diff line
@@ -1030,6 +1030,11 @@ impl IBluetooth for BluetoothDBus {
    fn is_le_audio_supported(&self) -> bool {
        dbus_generated!()
    }

    #[dbus_method("IsDualModeAudioSinkDevice")]
    fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool {
        dbus_generated!()
    }
}

pub(crate) struct BluetoothQALegacyDBus {
+5 −0
Original line number Diff line number Diff line
@@ -765,6 +765,11 @@ impl IBluetooth for IBluetoothDBus {
    fn is_le_audio_supported(&self) -> bool {
        dbus_generated!()
    }

    #[dbus_method("IsDualModeAudioSinkDevice", DBusLog::Disable)]
    fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool {
        dbus_generated!()
    }
}

impl_dbus_arg_enum!(SocketType);
+28 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin};
use crate::bluetooth_gatt::{
    BluetoothGatt, GattActions, IBluetoothGatt, IScannerCallback, ScanResult,
};
use crate::bluetooth_media::{BluetoothMedia, IBluetoothMedia, MediaActions};
use crate::bluetooth_media::{BluetoothMedia, IBluetoothMedia, MediaActions, LEA_UNKNOWN_GROUP_ID};
use crate::callbacks::Callbacks;
use crate::socket_manager::SocketActions;
use crate::uuid::{Profile, UuidHelper};
@@ -258,6 +258,10 @@ pub trait IBluetooth {

    /// Returns whether LE Audio is supported.
    fn is_le_audio_supported(&self) -> bool;

    /// Returns whether the remote device is a dual mode audio sink device (supports both classic and
    /// LE Audio sink roles).
    fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool;
}

/// Adapter API for Bluetooth qualification and verification.
@@ -2971,6 +2975,29 @@ impl IBluetooth for Bluetooth {
        // See Core 5.3, Vol 6, 4.6 FEATURE SUPPORT
        self.le_local_supported_features >> 28 & 1 == 1u64
    }

    fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool {
        fn is_dual_mode(uuids: Vec<Uuid>) -> bool {
            fn get_unwrapped_uuid(profile: Profile) -> Uuid {
                *UuidHelper::get_profile_uuid(&profile).unwrap_or(&Uuid::empty())
            }

            uuids.contains(&get_unwrapped_uuid(Profile::LeAudio))
                && (uuids.contains(&get_unwrapped_uuid(Profile::A2dpSink))
                    || uuids.contains(&get_unwrapped_uuid(Profile::Hfp)))
        }

        let media = self.bluetooth_media.lock().unwrap();
        let group_id = media.get_group_id(device.address);
        if group_id == LEA_UNKNOWN_GROUP_ID {
            return is_dual_mode(self.get_remote_uuids(device));
        }

        // Check if any device in the CSIP group is a dual mode audio sink device
        media.get_group_devices(group_id).iter().any(|addr| {
            is_dual_mode(self.get_remote_uuids(BluetoothDevice::new(*addr, "".to_string())))
        })
    }
}

impl BtifSdpCallbacks for Bluetooth {
+15 −9
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ const MEDIA_LE_AUDIO_PROFILES: &[Profile] =
    &[Profile::LeAudio, Profile::VolumeControl, Profile::CoordinatedSet];

/// Group ID used to identify unknown/non-existent groups.
const LEA_UNKNOWN_GROUP_ID: i32 = -1;
pub const LEA_UNKNOWN_GROUP_ID: i32 = -1;

/// Refer to |pairDeviceByCsip| in |CachedBluetoothDeviceManager.java|.
/// Number of attempts for CSIS to bond set members of a connected group.
@@ -852,11 +852,7 @@ impl BluetoothMedia {
                    BtVcConnectionState::Connected => {
                        self.vc_states.insert(addr, state);

                        let group_id = *self
                            .le_audio_node_to_group
                            .get(&addr)
                            .unwrap_or(&LEA_UNKNOWN_GROUP_ID);

                        let group_id = self.get_group_id(addr);
                        match self.le_audio_groups.get(&group_id) {
                            Some(group) if self.is_group_connected(group) => {
                                self.callbacks.lock().unwrap().for_all_callbacks(|callback| {
@@ -953,8 +949,7 @@ impl BluetoothMedia {
                    return;
                }

                let group_id =
                    *self.le_audio_node_to_group.get(&addr).unwrap_or(&LEA_UNKNOWN_GROUP_ID);
                let group_id = self.get_group_id(addr);
                if group_id == LEA_UNKNOWN_GROUP_ID {
                    warn!(
                        "LeAudioClientCallbacks::ConnectionState: [{}] Ignored dispatching of LeAudio callback on a device with no group",
@@ -3020,6 +3015,17 @@ impl BluetoothMedia {
        self.phone_state.num_active = 1;
        self.phone_state_change("".into());
    }

    pub fn get_group_devices(&self, group_id: i32) -> HashSet<RawAddress> {
        match self.le_audio_groups.get(&group_id) {
            Some(g) => g.devices.clone(),
            _ => HashSet::new(),
        }
    }

    pub fn get_group_id(&self, addr: RawAddress) -> i32 {
        *self.le_audio_node_to_group.get(&addr).unwrap_or(&LEA_UNKNOWN_GROUP_ID)
    }
}

fn get_a2dp_dispatcher(tx: Sender<Message>) -> A2dpCallbacksDispatcher {
@@ -3173,7 +3179,7 @@ impl IBluetoothMedia for BluetoothMedia {
    }

    fn disconnect_lea_group_by_member_address(&mut self, addr: RawAddress) {
        let group_id = *self.le_audio_node_to_group.get(&addr).unwrap_or(&LEA_UNKNOWN_GROUP_ID);
        let group_id = self.get_group_id(addr);
        if group_id == LEA_UNKNOWN_GROUP_ID {
            warn!(
                "disconnect_lea_group_by_member_address: [{}]: address belongs to no group",