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

Commit 0088bc86 authored by Jeremy Wu's avatar Jeremy Wu Committed by Gerrit Code Review
Browse files

Merge "Floss: add codec type parameter to |set_audio_config|" into main

parents e1e13c2f 02cdb18d
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -4,7 +4,10 @@ use bt_topshim::btif::{
    BtBondState, BtConnectionState, BtDeviceType, BtDiscMode, BtPropertyType, BtSspVariant,
    BtStatus, BtTransport, BtVendorProductInfo, Uuid, Uuid128Bit,
};
use bt_topshim::profiles::a2dp::{A2dpCodecConfig, PresentationPosition};
use bt_topshim::profiles::a2dp::{
    A2dpCodecBitsPerSample, A2dpCodecChannelMode, A2dpCodecConfig, A2dpCodecIndex,
    A2dpCodecSampleRate, PresentationPosition,
};
use bt_topshim::profiles::avrcp::PlayerMetadata;
use bt_topshim::profiles::gatt::{AdvertisingStatus, GattStatus, LePhy};
use bt_topshim::profiles::hfp::HfpCodecCapability;
@@ -415,6 +418,11 @@ pub struct A2dpCodecConfigDBus {
    codec_specific_4: i64,
}

impl_dbus_arg_enum!(A2dpCodecIndex);
impl_dbus_arg_from_into!(A2dpCodecSampleRate, i32);
impl_dbus_arg_from_into!(A2dpCodecBitsPerSample, i32);
impl_dbus_arg_from_into!(A2dpCodecChannelMode, i32);

impl_dbus_arg_from_into!(HfpCodecCapability, i32);
#[dbus_propmap(BluetoothAudioDevice)]
pub struct BluetoothAudioDeviceDBus {
@@ -2524,9 +2532,11 @@ impl IBluetoothMedia for BluetoothMediaDBus {
    #[dbus_method("SetAudioConfig")]
    fn set_audio_config(
        &mut self,
        sample_rate: i32,
        bits_per_sample: i32,
        channel_mode: i32,
        address: String,
        codec_type: A2dpCodecIndex,
        sample_rate: A2dpCodecSampleRate,
        bits_per_sample: A2dpCodecBitsPerSample,
        channel_mode: A2dpCodecChannelMode,
    ) -> bool {
        dbus_generated!()
    }
+16 −5
Original line number Diff line number Diff line
use bt_topshim::profiles::a2dp::{A2dpCodecConfig, PresentationPosition};
use bt_topshim::profiles::a2dp::{
    A2dpCodecBitsPerSample, A2dpCodecChannelMode, A2dpCodecConfig, A2dpCodecIndex,
    A2dpCodecSampleRate, PresentationPosition,
};
use bt_topshim::profiles::avrcp::PlayerMetadata;
use bt_topshim::profiles::hfp::HfpCodecCapability;
use btstack::bluetooth_media::{BluetoothAudioDevice, IBluetoothMedia, IBluetoothMediaCallback};
@@ -11,10 +14,12 @@ use dbus::strings::Path;
use dbus_macros::{dbus_method, dbus_propmap, dbus_proxy_obj, generate_dbus_exporter};

use dbus_projection::DisconnectWatcher;
use dbus_projection::{dbus_generated, impl_dbus_arg_from_into};
use dbus_projection::{dbus_generated, impl_dbus_arg_enum, impl_dbus_arg_from_into};

use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust};

use num_traits::{FromPrimitive, ToPrimitive};

use std::convert::{TryFrom, TryInto};
use std::sync::Arc;

@@ -44,6 +49,10 @@ pub struct BluetoothAudioDeviceDBus {
}

impl_dbus_arg_from_into!(HfpCodecCapability, i32);
impl_dbus_arg_enum!(A2dpCodecIndex);
impl_dbus_arg_from_into!(A2dpCodecSampleRate, i32);
impl_dbus_arg_from_into!(A2dpCodecBitsPerSample, i32);
impl_dbus_arg_from_into!(A2dpCodecChannelMode, i32);

#[dbus_proxy_obj(BluetoothMediaCallback, "org.chromium.bluetooth.BluetoothMediaCallback")]
impl IBluetoothMediaCallback for BluetoothMediaCallbackDBus {
@@ -203,9 +212,11 @@ impl IBluetoothMedia for IBluetoothMediaDBus {
    #[dbus_method("SetAudioConfig")]
    fn set_audio_config(
        &mut self,
        sample_rate: i32,
        bits_per_sample: i32,
        channel_mode: i32,
        address: String,
        codec_type: A2dpCodecIndex,
        sample_rate: A2dpCodecSampleRate,
        bits_per_sample: A2dpCodecBitsPerSample,
        channel_mode: A2dpCodecChannelMode,
    ) -> bool {
        dbus_generated!()
    }
+66 −14
Original line number Diff line number Diff line
@@ -6,8 +6,8 @@ use bt_topshim::btif::{
};
use bt_topshim::profiles::a2dp::{
    A2dp, A2dpCallbacks, A2dpCallbacksDispatcher, A2dpCodecBitsPerSample, A2dpCodecChannelMode,
    A2dpCodecConfig, A2dpCodecSampleRate, BtavAudioState, BtavConnectionState,
    PresentationPosition,
    A2dpCodecConfig, A2dpCodecIndex, A2dpCodecPriority, A2dpCodecSampleRate, BtavAudioState,
    BtavConnectionState, PresentationPosition,
};
use bt_topshim::profiles::avrcp::{
    Avrcp, AvrcpCallbacks, AvrcpCallbacksDispatcher, PlayerMetadata,
@@ -90,9 +90,11 @@ pub trait IBluetoothMedia {

    fn set_audio_config(
        &mut self,
        sample_rate: i32,
        bits_per_sample: i32,
        channel_mode: i32,
        address: String,
        codec_type: A2dpCodecIndex,
        sample_rate: A2dpCodecSampleRate,
        bits_per_sample: A2dpCodecBitsPerSample,
        channel_mode: A2dpCodecChannelMode,
    ) -> bool;

    // Set the A2DP/AVRCP volume. Valid volume specified by the spec should be
@@ -2164,21 +2166,71 @@ impl IBluetoothMedia for BluetoothMedia {

    fn set_audio_config(
        &mut self,
        sample_rate: i32,
        bits_per_sample: i32,
        channel_mode: i32,
        address: String,
        codec_type: A2dpCodecIndex,
        sample_rate: A2dpCodecSampleRate,
        bits_per_sample: A2dpCodecBitsPerSample,
        channel_mode: A2dpCodecChannelMode,
    ) -> bool {
        if !A2dpCodecSampleRate::validate_bits(sample_rate)
            || !A2dpCodecBitsPerSample::validate_bits(bits_per_sample)
            || !A2dpCodecChannelMode::validate_bits(channel_mode)
        {
        let addr = match RawAddress::from_string(address.clone()) {
            None => {
                warn!("Invalid device address {}", address);
                return false;
            }
            Some(addr) => addr,
        };

        if self.a2dp_states.get(&addr).is_none() {
            warn!(
                "[{}]: Ignore set config event for unconnected or disconnected A2DP device",
                DisplayAddress(&addr)
            );
            return false;
        }

        match self.a2dp.as_mut() {
            Some(a2dp) => {
                a2dp.set_audio_config(sample_rate, bits_per_sample, channel_mode);
                true
                let caps = self.a2dp_caps.get(&addr).unwrap_or(&Vec::new()).to_vec();

                for cap in &caps {
                    if A2dpCodecIndex::from(cap.codec_type) == codec_type {
                        if (A2dpCodecSampleRate::from_bits(cap.sample_rate).unwrap() & sample_rate)
                            != sample_rate
                        {
                            warn!("Unsupported sample rate {:?}", sample_rate);
                            return false;
                        }
                        if (A2dpCodecBitsPerSample::from_bits(cap.bits_per_sample).unwrap()
                            & bits_per_sample)
                            != bits_per_sample
                        {
                            warn!("Unsupported bit depth {:?}", bits_per_sample);
                            return false;
                        }
                        if (A2dpCodecChannelMode::from_bits(cap.channel_mode).unwrap()
                            & channel_mode)
                            != channel_mode
                        {
                            warn!("Unsupported channel mode {:?}", channel_mode);
                            return false;
                        }

                        let config = vec![A2dpCodecConfig {
                            codec_type: codec_type as i32,
                            codec_priority: A2dpCodecPriority::Highest as i32,
                            sample_rate: sample_rate.bits() as i32,
                            bits_per_sample: bits_per_sample.bits() as i32,
                            channel_mode: channel_mode.bits() as i32,
                            ..Default::default()
                        }];

                        a2dp.config_codec(addr, config);
                        return true;
                    }
                }

                warn!("Unsupported codec type {:?}", codec_type);
                false
            }
            None => {
                warn!("Uninitialized A2DP to set audio config");
+1 −1
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ static void audio_config_cb(
}
static bool mandatory_codec_preferred_cb(const RawAddress& addr) {
  rusty::mandatory_codec_preferred_callback(addr);
  return true;
  return false;
}

btav_source_callbacks_t g_callbacks = {
+48 −7
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ use crate::topstack::get_dispatchers;
use bitflags::bitflags;
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::cast::FromPrimitive;
use std::convert::{TryFrom, TryInto};
use std::sync::{Arc, Mutex};
use topshim_macros::{cb_variant, profile_enabled_or, profile_enabled_or_default};

@@ -38,8 +39,8 @@ impl From<u32> for BtavAudioState {
    }
}

#[derive(Debug, FromPrimitive, PartialEq, PartialOrd)]
#[repr(u32)]
#[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
#[repr(i32)]
pub enum A2dpCodecIndex {
    SrcSbc = 0,
    SrcAac,
@@ -67,7 +68,7 @@ impl From<i32> for A2dpCodecIndex {
    }
}

#[derive(Debug, FromPrimitive, PartialEq, PartialOrd)]
#[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
#[repr(i32)]
pub enum A2dpCodecPriority {
    Disabled = -1,
@@ -113,6 +114,20 @@ impl A2dpCodecSampleRate {
    }
}

impl TryInto<i32> for A2dpCodecSampleRate {
    type Error = ();
    fn try_into(self) -> Result<i32, Self::Error> {
        Ok(self.bits())
    }
}

impl TryFrom<i32> for A2dpCodecSampleRate {
    type Error = ();
    fn try_from(val: i32) -> Result<Self, Self::Error> {
        Self::from_bits(val).ok_or(())
    }
}

bitflags! {
    pub struct A2dpCodecBitsPerSample: i32 {
        const SAMPLE_NONE = 0x0;
@@ -128,6 +143,20 @@ impl A2dpCodecBitsPerSample {
    }
}

impl TryInto<i32> for A2dpCodecBitsPerSample {
    type Error = ();
    fn try_into(self) -> Result<i32, Self::Error> {
        Ok(self.bits())
    }
}

impl TryFrom<i32> for A2dpCodecBitsPerSample {
    type Error = ();
    fn try_from(val: i32) -> Result<Self, Self::Error> {
        Self::from_bits(val).ok_or(())
    }
}

bitflags! {
    pub struct A2dpCodecChannelMode: i32 {
        const MODE_NONE = 0x0;
@@ -142,6 +171,20 @@ impl A2dpCodecChannelMode {
    }
}

impl TryInto<i32> for A2dpCodecChannelMode {
    type Error = ();
    fn try_into(self) -> Result<i32, Self::Error> {
        Ok(self.bits())
    }
}

impl TryFrom<i32> for A2dpCodecChannelMode {
    type Error = ();
    fn try_from(val: i32) -> Result<Self, Self::Error> {
        Self::from_bits(val).ok_or(())
    }
}

#[cxx::bridge(namespace = bluetooth::topshim::rust)]
pub mod ffi {
    unsafe extern "C++" {
@@ -364,10 +407,8 @@ impl A2dp {
    }

    #[profile_enabled_or]
    pub fn set_audio_config(&self, sample_rate: i32, bits_per_sample: i32, channel_mode: i32) {
        let config =
            A2dpCodecConfig { sample_rate, bits_per_sample, channel_mode, ..Default::default() };
        self.internal.set_audio_config(config);
    pub fn config_codec(&self, addr: RawAddress, config: Vec<A2dpCodecConfig>) {
        self.internal.config_codec(addr, config);
    }

    #[profile_enabled_or(false)]