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

Commit b5859f2c authored by Patty's avatar Patty
Browse files

Get default LE audio offload codec capability from HAL

Tag: #feature
Bug: 203535499
Bug: 150670922
Test: atest BluetoothInstrumentationTests

Change-Id: I4381e2d11619d17b4b921e5c40b8938d25d6c872
parent fd0d1bd9
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -302,35 +302,35 @@ BluetoothAudioClientInterface::GetAudioCapabilities_2_1(
  return capabilities_2_1;
}

std::vector<AudioCapabilities_2_1>
std::vector<AudioCapabilities_2_2>
BluetoothAudioClientInterface::GetAudioCapabilities_2_2(
    SessionType_2_1 session_type_2_1) {
  if (HalVersionManager::GetHalVersion() ==
      BluetoothAudioHalVersion::VERSION_2_1) {
    return GetAudioCapabilities_2_1(session_type_2_1);
  std::vector<AudioCapabilities_2_2> capabilities_2_2(0);
  if (HalVersionManager::GetHalVersion() !=
      BluetoothAudioHalVersion::VERSION_2_2) {
    LOG(ERROR) << __func__ << ", can't get capability for HAL 2.2";
    return capabilities_2_2;
  }

  std::vector<AudioCapabilities_2_1> capabilities_2_1(0);
  android::sp<IBluetoothAudioProvidersFactory_2_2> providersFactory =
      HalVersionManager::GetProvidersFactory_2_2();
  CHECK(providersFactory != nullptr)
      << "IBluetoothAudioProvidersFactory::getService() failed";

  auto getProviderCapabilities_cb =
      [&capabilities_2_1](
          const hidl_vec<AudioCapabilities_2_1>& audioCapabilities_2_1) {
        for (auto capability_2_1 : audioCapabilities_2_1) {
          capabilities_2_1.push_back(capability_2_1);
      [&capabilities_2_2](
          const hidl_vec<AudioCapabilities_2_2>& audioCapabilities_2_2) {
        for (auto capability_2_2 : audioCapabilities_2_2) {
          capabilities_2_2.push_back(capability_2_2);
        }
      };
  auto hidl_retval = providersFactory->getProviderCapabilities_2_1(
  auto hidl_retval = providersFactory->getProviderCapabilities_2_2(
      session_type_2_1, getProviderCapabilities_cb);
  if (!hidl_retval.isOk()) {
    LOG(FATAL) << __func__
               << ": BluetoothAudioHal::getProviderCapabilities failure: "
               << hidl_retval.description();
  }
  return capabilities_2_1;
  return capabilities_2_2;
}

void BluetoothAudioClientInterface::FetchAudioProvider() {
+4 −1
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ using AudioCapabilities =
    ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
using AudioCapabilities_2_1 =
    ::android::hardware::bluetooth::audio::V2_1::AudioCapabilities;
using AudioCapabilities_2_2 =
    ::android::hardware::bluetooth::audio::V2_2::AudioCapabilities;
using AudioConfiguration =
    ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
using AudioConfiguration_2_1 =
@@ -229,7 +231,7 @@ class BluetoothAudioClientInterface {
      SessionType session_type);
  static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1(
      SessionType_2_1 session_type_2_1);
  static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_2(
  static std::vector<AudioCapabilities_2_2> GetAudioCapabilities_2_2(
      SessionType_2_1 session_type_2_1);

  void StreamStarted(const BluetoothAudioCtrlAck& ack);
@@ -278,6 +280,7 @@ class BluetoothAudioClientInterface {
  IBluetoothTransportInstance* transport_;
  std::vector<AudioCapabilities> capabilities_;
  std::vector<AudioCapabilities_2_1> capabilities_2_1_;
  std::vector<AudioCapabilities_2_2> capabilities_2_2_;
};

// The client interface connects an IBluetoothTransportInstance to
+149 −1
Original line number Diff line number Diff line
@@ -19,7 +19,11 @@

#include "le_audio_software.h"

#include <unordered_map>
#include <vector>

#include "client_interface.h"
#include "codec_status.h"
#include "hal_version_manager.h"
#include "osi/include/log.h"
#include "osi/include/properties.h"
@@ -28,8 +32,11 @@ namespace {

using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
using ::android::hardware::bluetooth::audio::V2_0::CodecType;
using ::android::hardware::bluetooth::audio::V2_1::CodecType;
using ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
using ::bluetooth::audio::AudioConfiguration_2_2;
using ::bluetooth::audio::BluetoothAudioCtrlAck;
using ::bluetooth::audio::SampleRate_2_1;
@@ -37,6 +44,14 @@ using ::bluetooth::audio::SessionType;
using ::bluetooth::audio::SessionType_2_1;
using ::bluetooth::audio::le_audio::LeAudioClientInterface;
using ::bluetooth::audio::le_audio::StreamCallbacks;
using AudioCapabilities_2_2 =
    ::android::hardware::bluetooth::audio::V2_2::AudioCapabilities;
using android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapability;

using ::le_audio::set_configurations::AudioSetConfiguration;
using ::le_audio::set_configurations::CodecCapabilitySetting;
using ::le_audio::set_configurations::SetConfiguration;
using ::le_audio::types::LeAudioLc3Config;

bluetooth::audio::BluetoothAudioSinkClientInterface*
    le_audio_sink_hal_clientinterface = nullptr;
@@ -339,6 +354,139 @@ namespace bluetooth {
namespace audio {
namespace le_audio {

std::unordered_map<SampleRate_2_1, uint8_t> sampling_freq_map{
    {SampleRate_2_1::RATE_8000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq8000Hz},
    {SampleRate_2_1::RATE_16000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq16000Hz},
    {SampleRate_2_1::RATE_24000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq24000Hz},
    {SampleRate_2_1::RATE_32000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq32000Hz},
    {SampleRate_2_1::RATE_44100,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq44100Hz},
    {SampleRate_2_1::RATE_48000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq48000Hz},
    {SampleRate_2_1::RATE_88200,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq88200Hz},
    {SampleRate_2_1::RATE_96000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq96000Hz},
    {SampleRate_2_1::RATE_176400,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq176400Hz},
    {SampleRate_2_1::RATE_192000,
     ::le_audio::codec_spec_conf::kLeAudioSamplingFreq192000Hz}};

std::unordered_map<Lc3FrameDuration, uint8_t> frame_duration_map{
    {Lc3FrameDuration::DURATION_7500US,
     ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameDur7500us},
    {Lc3FrameDuration::DURATION_10000US,
     ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameDur10000us}};

std::unordered_map<uint32_t, uint16_t> octets_per_frame_map{
    {30, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen30},
    {40, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen40},
    {120, ::le_audio::codec_spec_conf::kLeAudioCodecLC3FrameLen120}};

std::unordered_map<AudioLocation, uint32_t> audio_location_map{
    {AudioLocation::UNKNOWN,
     ::le_audio::codec_spec_conf::kLeAudioLocationMonoUnspecified},
    {AudioLocation::FRONT_LEFT,
     ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft},
    {AudioLocation::FRONT_RIGHT,
     ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight},
    {static_cast<AudioLocation>(AudioLocation::FRONT_LEFT |
                                AudioLocation::FRONT_RIGHT),
     ::le_audio::codec_spec_conf::kLeAudioLocationFrontLeft |
         ::le_audio::codec_spec_conf::kLeAudioLocationFrontRight}};

bool halConfigToCodecCapabilitySetting(
    LeAudioCodecCapability halConfig, CodecCapabilitySetting& codecCapability) {
  if (halConfig.codecType != CodecType::LC3) {
    LOG(WARNING) << "Unsupported codecType: " << toString(halConfig.codecType);
    return false;
  }

  Lc3Parameters halLc3Config = halConfig.capabilities;
  AudioLocation supportedChannel = halConfig.supportedChannel;

  if (sampling_freq_map.find(halLc3Config.samplingFrequency) ==
          sampling_freq_map.end() ||
      frame_duration_map.find(halLc3Config.frameDuration) ==
          frame_duration_map.end() ||
      octets_per_frame_map.find(halLc3Config.octetsPerFrame) ==
          octets_per_frame_map.end() ||
      audio_location_map.find(supportedChannel) == audio_location_map.end()) {
    LOG(ERROR) << __func__ << ": Failed to convert HAL format to stack format"
               << "\nsample rate = " << (uint8_t)halLc3Config.samplingFrequency
               << "\nframe duration = " << (uint8_t)halLc3Config.frameDuration
               << "\noctets per frame= " << halLc3Config.octetsPerFrame
               << "\naudio location = " << (uint8_t)supportedChannel;

    return false;
  }

  codecCapability = {
      .id = ::le_audio::set_configurations::LeAudioCodecIdLc3,
      .config = LeAudioLc3Config(
          {.sampling_frequency =
               sampling_freq_map[halLc3Config.samplingFrequency],
           .frame_duration = frame_duration_map[halLc3Config.frameDuration],
           .octets_per_codec_frame =
               octets_per_frame_map[halLc3Config.octetsPerFrame],
           .audio_channel_allocation = audio_location_map[supportedChannel]})};

  return true;
}

std::vector<AudioSetConfiguration> get_offload_capabilities() {
  LOG(INFO) << __func__;
  std::vector<AudioSetConfiguration> offload_capabilities;
  std::vector<AudioCapabilities_2_2> le_audio_hal_capabilities =
      audio::BluetoothAudioSinkClientInterface::GetAudioCapabilities_2_2(
          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
  std::string strCapabilityLog;

  for (auto halCapability : le_audio_hal_capabilities) {
    CodecCapabilitySetting encodeCapability;
    CodecCapabilitySetting decodeCapability;
    LeAudioCodecCapability halEncodeConfig =
        halCapability.leAudioCapabilities().encodeCapability;
    LeAudioCodecCapability halDecodeConfig =
        halCapability.leAudioCapabilities().decodeCapability;
    AudioSetConfiguration audioSetConfig = {.name = "offload capability"};
    strCapabilityLog.clear();

    if (halConfigToCodecCapabilitySetting(halEncodeConfig, encodeCapability)) {
      audioSetConfig.confs.push_back(SetConfiguration(
          ::le_audio::types::kLeAudioDirectionSink, halEncodeConfig.deviceCount,
          halEncodeConfig.deviceCount * halEncodeConfig.channelCountPerDevice,
          encodeCapability));
      strCapabilityLog = " Encode Capability: " + toString(halEncodeConfig);
    }

    if (halConfigToCodecCapabilitySetting(halDecodeConfig, decodeCapability)) {
      audioSetConfig.confs.push_back(SetConfiguration(
          ::le_audio::types::kLeAudioDirectionSource,
          halDecodeConfig.deviceCount,
          halDecodeConfig.deviceCount * halDecodeConfig.channelCountPerDevice,
          decodeCapability));
      strCapabilityLog += " Decode Capability: " + toString(halDecodeConfig);
    }

    if (!audioSetConfig.confs.empty()) {
      offload_capabilities.push_back(audioSetConfig);
      LOG(INFO) << __func__
                << ": Supported codec capability =" << strCapabilityLog;

    } else {
      LOG(INFO) << __func__
                << ": Unknown codec capability =" << toString(halCapability);
    }
  }

  return offload_capabilities;
}

LeAudioClientInterface* LeAudioClientInterface::interface = nullptr;
LeAudioClientInterface* LeAudioClientInterface::Get() {
  if (osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false)) {
+4 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <functional>

#include "bta/le_audio/le_audio_types.h"
#include "common/message_loop_thread.h"

namespace bluetooth {
@@ -47,6 +48,9 @@ struct StreamCallbacks {
  std::function<bool(const sink_metadata_t&)> on_sink_metadata_update_;
};

std::vector<::le_audio::set_configurations::AudioSetConfiguration>
get_offload_capabilities();

class LeAudioClientInterface {
 public:
  struct PcmParameters {
+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@ namespace audio {

namespace le_audio {

std::vector<::le_audio::set_configurations::AudioSetConfiguration>
get_offload_capabilities() {
  return std::vector<::le_audio::set_configurations::AudioSetConfiguration>(0);
}

LeAudioClientInterface* LeAudioClientInterface::Get() { return nullptr; }

bool LeAudioClientInterface::IsSinkAcquired() { return false; }
Loading