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

Commit 9f5e7e8a authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes from topic "offload_capability_selected" am: a6820255 am: d6d63d25 am: eaa9a725

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/1940865

Change-Id: I410c4687d58e1e1296ab3a07e219edfc80290201
parents 6fea1047 eaa9a725
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -385,6 +385,7 @@ bool hal_ucast_capability_to_stack_format(
  auto sample_rate_hz = hal_lc3_capability.samplingFrequencyHz[0];
  auto frame_duration_us = hal_lc3_capability.frameDurationUs[0];
  auto octets_per_frame = hal_lc3_capability.octetsPerFrame[0];
  auto channel_count = hal_capability.channelCountPerDevice;

  if (sampling_freq_map.find(sample_rate_hz) == sampling_freq_map.end() ||
      frame_duration_map.find(frame_duration_us) == frame_duration_map.end() ||
@@ -406,8 +407,8 @@ bool hal_ucast_capability_to_stack_format(
          {.sampling_frequency = sampling_freq_map[sample_rate_hz],
           .frame_duration = frame_duration_map[frame_duration_us],
           .octets_per_codec_frame = octets_per_frame_map[octets_per_frame],
           .audio_channel_allocation = audio_location_map[supportedChannel]})};

           .audio_channel_allocation = audio_location_map[supportedChannel],
           .channel_count = static_cast<uint8_t>(channel_count)})};
  return true;
}

+2 −0
Original line number Diff line number Diff line
@@ -580,6 +580,7 @@ cc_test {
        "le_audio/broadcaster/state_machine_test.cc",
        "le_audio/le_audio_types.cc",
        "le_audio/mock_iso_manager.cc",
        "le_audio/mock_codec_manager.cc",
    ],
    shared_libs: [
        "libprotobuf-cpp-lite",
@@ -631,6 +632,7 @@ cc_test {
        "le_audio/mock_iso_manager.cc",
        "le_audio/mock_le_audio_client_audio.cc",
        "test/common/mock_controller.cc",
        "le_audio/mock_codec_manager.cc",
    ],
    shared_libs: [
        "libprotobuf-cpp-lite",
+5 −3
Original line number Diff line number Diff line
@@ -35,9 +35,11 @@ class LeAudioClient {
 public:
  virtual ~LeAudioClient(void) = default;

  static void Initialize(bluetooth::le_audio::LeAudioClientCallbacks* callbacks,
                         base::Closure initCb,
                         base::Callback<bool()> hal_2_1_verifier);
  static void Initialize(
      bluetooth::le_audio::LeAudioClientCallbacks* callbacks,
      base::Closure initCb, base::Callback<bool()> hal_2_1_verifier,
      const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
          offloading_preference);
  static void Cleanup(void);
  static LeAudioClient* Get(void);
  static void DebugDump(int fd);
+4 −2
Original line number Diff line number Diff line
@@ -3308,7 +3308,9 @@ LeAudioClient* LeAudioClient::Get() {
/* Initializer of main le audio implementation class and its instance */
void LeAudioClient::Initialize(
    bluetooth::le_audio::LeAudioClientCallbacks* callbacks_,
    base::Closure initCb, base::Callback<bool()> hal_2_1_verifier) {
    base::Closure initCb, base::Callback<bool()> hal_2_1_verifier,
    const std::vector<bluetooth::le_audio::btle_audio_codec_config_t>&
        offloading_preference) {
  if (instance) {
    LOG(ERROR) << "Already initialized";
    return;
@@ -3342,7 +3344,7 @@ void LeAudioClient::Initialize(
  instance = new LeAudioClientImpl(callbacks_, stateMachineCallbacks, initCb);

  IsoManager::GetInstance()->RegisterCigCallbacks(stateMachineHciCallbacks);
  CodecManager::GetInstance()->Start();
  CodecManager::GetInstance()->Start(offloading_preference, capabilities);
}

void LeAudioClient::DebugDump(int fd) {
+163 −5
Original line number Diff line number Diff line
@@ -29,13 +29,22 @@ using bluetooth::hci::iso_manager::kIsoDataPathHci;
using bluetooth::hci::iso_manager::kIsoDataPathPlatformDefault;
using le_audio::CodecManager;
using le_audio::types::CodecLocation;

using bluetooth::le_audio::btle_audio_codec_config_t;
using bluetooth::le_audio::btle_audio_codec_index_t;
using le_audio::set_configurations::AudioSetConfiguration;
using le_audio::set_configurations::AudioSetConfigurations;
using le_audio::set_configurations::SetConfiguration;

}  // namespace

namespace le_audio {

struct codec_manager_impl {
 public:
  codec_manager_impl() {
  codec_manager_impl(
      const std::vector<btle_audio_codec_config_t>& offloading_preference,
      const std::vector<AudioSetConfiguration>& adsp_capabilities) {
    offload_enable_ = osi_property_get_bool(
                          "ro.bluetooth.leaudio_offload.supported", false) &&
                      osi_property_get_bool(
@@ -60,6 +69,7 @@ struct codec_manager_impl {
                            kIsoDataPathPlatformDefault, {});
    btm_configure_data_path(btm_data_direction::CONTROLLER_TO_HOST,
                            kIsoDataPathPlatformDefault, {});
    UpdateOffloadCapability(offloading_preference, adsp_capabilities);
    SetCodecLocation(CodecLocation::ADSP);
  }
  ~codec_manager_impl() {
@@ -108,23 +118,158 @@ struct codec_manager_impl {
    LeAudioClientAudioSink::UpdateAudioConfigToHal(source_config);
  }

  const AudioSetConfigurations* GetOffloadCodecConfig(
      types::LeAudioContextType ctx_type) {
    return &context_type_offload_config_map_[ctx_type];
  }

 private:
  void SetCodecLocation(CodecLocation location) {
    if (offload_enable_ == false) return;
    codec_location_ = location;
  }

  bool IsLc3ConfigMatched(
      const set_configurations::CodecCapabilitySetting& adsp_config,
      const set_configurations::CodecCapabilitySetting& target_config) {
    if (adsp_config.id.coding_format != types::kLeAudioCodingFormatLC3 ||
        target_config.id.coding_format != types::kLeAudioCodingFormatLC3) {
      return false;
    }

    const types::LeAudioLc3Config adsp_lc3_config =
        std::get<types::LeAudioLc3Config>(adsp_config.config);
    const types::LeAudioLc3Config target_lc3_config =
        std::get<types::LeAudioLc3Config>(target_config.config);

    if (adsp_lc3_config.sampling_frequency !=
            target_lc3_config.sampling_frequency ||
        adsp_lc3_config.frame_duration != target_lc3_config.frame_duration ||
        adsp_lc3_config.channel_count != target_lc3_config.channel_count ||
        adsp_lc3_config.octets_per_codec_frame !=
            target_lc3_config.octets_per_codec_frame) {
      return false;
    }

    return true;
  }

  bool IsSetConfigurationMatched(const SetConfiguration& software_set_config,
                                 const SetConfiguration& adsp_set_config) {
    // Skip the check of stategry and ase_cnt due to ADSP doesn't have the info
    return (
        software_set_config.direction == adsp_set_config.direction &&
        software_set_config.device_cnt == adsp_set_config.device_cnt &&
        IsLc3ConfigMatched(software_set_config.codec, adsp_set_config.codec));
  }

  bool IsAudioSetConfigurationMatched(
      const AudioSetConfiguration* software_audio_set_conf,
      std::unordered_set<uint8_t>& offload_preference_set,
      const std::vector<AudioSetConfiguration>& adsp_capabilities) {
    if (software_audio_set_conf->confs.empty()) {
      return false;
    }

    std::unordered_map<uint8_t, const SetConfiguration&>
        software_set_conf_direction_map;

    for (auto& software_set_conf : software_audio_set_conf->confs) {
      // Checks offload preference supports the codec
      if (offload_preference_set.find(
              software_set_conf.codec.id.coding_format) ==
          offload_preference_set.end()) {
        return false;
      }
      software_set_conf_direction_map.emplace(software_set_conf.direction,
                                              software_set_conf);
    }

    // Checks any of offload config matches the input audio set config
    for (const auto& adsp_audio_set_conf : adsp_capabilities) {
      if (adsp_audio_set_conf.confs.size() !=
          software_audio_set_conf->confs.size()) {
        continue;
      }

      size_t match_cnt = 0;

      for (auto& adsp_set_conf : adsp_audio_set_conf.confs) {
        auto it = software_set_conf_direction_map.find(adsp_set_conf.direction);

        if (it == software_set_conf_direction_map.end()) {
          continue;
        }

        if (IsSetConfigurationMatched(it->second, adsp_set_conf)) {
          match_cnt++;
        }
      }

      if (match_cnt == software_set_conf_direction_map.size()) {
        return true;
      }
    }

    return false;
  }

  void UpdateOffloadCapability(
      const std::vector<btle_audio_codec_config_t>& offloading_preference,
      const std::vector<AudioSetConfiguration>& adsp_capabilities) {
    LOG(INFO) << __func__;
    std::unordered_set<uint8_t> offload_preference_set;

    for (auto codec : offloading_preference) {
      auto it = btle_audio_codec_type_map_.find(codec.codec_type);

      if (it != btle_audio_codec_type_map_.end()) {
        offload_preference_set.insert(it->second);
      }
    }

    for (types::LeAudioContextType ctx_type :
         types::kLeAudioContextAllTypesArray) {
      // Gets the software supported context type and the corresponding config
      // priority
      const AudioSetConfigurations* software_audio_set_confs =
          set_configurations::get_confs_by_type(ctx_type);

      for (const auto& software_audio_set_conf : *software_audio_set_confs) {
        if (IsAudioSetConfigurationMatched(software_audio_set_conf,
                                           offload_preference_set,
                                           adsp_capabilities)) {
          LOG(INFO) << "Offload supported conf, context type: " << (int)ctx_type
                    << ", settings -> " << software_audio_set_conf->name;
          context_type_offload_config_map_[ctx_type].push_back(
              software_audio_set_conf);
        }
      }
    }
  }

  CodecLocation codec_location_ = CodecLocation::HOST;
  bool offload_enable_ = false;
  le_audio::offload_config sink_config;
  le_audio::offload_config source_config;
  std::unordered_map<types::LeAudioContextType, AudioSetConfigurations>
      context_type_offload_config_map_;
  std::unordered_map<btle_audio_codec_index_t, uint8_t>
      btle_audio_codec_type_map_ = {
          {::bluetooth::le_audio::LE_AUDIO_CODEC_INDEX_SOURCE_LC3,
           types::kLeAudioCodingFormatLC3}};
};

struct CodecManager::impl {
  impl(const CodecManager& codec_manager) : codec_manager_(codec_manager) {}

  void Start() {
  void Start(
      const std::vector<btle_audio_codec_config_t>& offloading_preference,
      const std::vector<set_configurations::AudioSetConfiguration>&
          adsp_capabilities) {
    LOG_ASSERT(!codec_manager_impl_);
    codec_manager_impl_ = std::make_unique<codec_manager_impl>();
    codec_manager_impl_ = std::make_unique<codec_manager_impl>(
        offloading_preference, adsp_capabilities);
  }

  void Stop() {
@@ -140,8 +285,12 @@ struct CodecManager::impl {

CodecManager::CodecManager() : pimpl_(std::make_unique<impl>(*this)) {}

void CodecManager::Start() {
  if (!pimpl_->IsRunning()) pimpl_->Start();
void CodecManager::Start(
    const std::vector<btle_audio_codec_config_t>& offloading_preference,
    const std::vector<set_configurations::AudioSetConfiguration>&
        adsp_capabilities) {
  if (!pimpl_->IsRunning())
    pimpl_->Start(offloading_preference, adsp_capabilities);
}

void CodecManager::Stop() {
@@ -170,4 +319,13 @@ void CodecManager::UpdateActiveSinkAudioConfig(
                                                             delay);
}

const AudioSetConfigurations* CodecManager::GetOffloadCodecConfig(
    types::LeAudioContextType ctx_type) {
  if (pimpl_->IsRunning()) {
    return pimpl_->codec_manager_impl_->GetOffloadCodecConfig(ctx_type);
  }

  return nullptr;
}

}  // namespace le_audio
Loading