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

Commit dc8e5608 authored by Bao Do's avatar Bao Do Committed by Automerger Merge Worker
Browse files

Merge changes from topics "leaudio-multicodec", "leaudio-multicodec-base" into main am: 435d7f42

parents 0c88196a 435d7f42
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -154,6 +154,8 @@ ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo(
    SessionType session_type, std::optional<ProviderInfo>* _aidl_return) {
  *_aidl_return = std::nullopt;

  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type);

  if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
      session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
    auto& provider_info = _aidl_return->emplace();
@@ -161,13 +163,14 @@ ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo(
    provider_info.name = A2dpOffloadCodecFactory::GetInstance()->name;
    for (auto codec : A2dpOffloadCodecFactory::GetInstance()->codecs)
      provider_info.codecInfos.push_back(codec->info);
  } else if (session_type ==
  }

  if (session_type ==
          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
      session_type ==
          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
      session_type ==
                 SessionType::
                     LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
          SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
    std::vector<CodecInfo> db_codec_info =
        BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(session_type);
    if (!db_codec_info.empty()) {
@@ -175,9 +178,9 @@ ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo(
      provider_info.name = kLeAudioOffloadProviderName;
      provider_info.codecInfos = db_codec_info;
      *_aidl_return = provider_info;
    }
      return ndk::ScopedAStatus::ok();
    }
  }

  return ndk::ScopedAStatus::ok();
}
+168 −9
Original line number Diff line number Diff line
@@ -82,6 +82,19 @@ const std::map<CodecSpecificConfigurationLtv::FrameDuration, uint32_t>
         CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000},
};

std::map<int32_t, CodecSpecificConfigurationLtv::SamplingFrequency>
    sampling_freq_map = {
        {16000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000},
        {48000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000},
        {96000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ96000},
};

std::map<int32_t, CodecSpecificConfigurationLtv::FrameDuration>
    frame_duration_map = {
        {7500, CodecSpecificConfigurationLtv::FrameDuration::US7500},
        {10000, CodecSpecificConfigurationLtv::FrameDuration::US10000},
};

LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider()
    : LeAudioOffloadAudioProvider() {
  session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
@@ -307,6 +320,16 @@ bool LeAudioOffloadAudioProvider::isMatchedAseConfiguration(
  return true;
}

bool LeAudioOffloadAudioProvider::isMatchedBISConfiguration(
    LeAudioBisConfiguration bis_cfg,
    const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) {
  if (!isMatchedValidCodec(bis_cfg.codecId, capabilities.codecId)) return false;
  if (!isCapabilitiesMatchedCodecConfiguration(
          bis_cfg.codecConfiguration, capabilities.codecSpecificCapabilities))
    return false;
  return true;
}

void LeAudioOffloadAudioProvider::filterCapabilitiesAseDirectionConfiguration(
    std::vector<std::optional<AseDirectionConfiguration>>&
        direction_configurations,
@@ -597,7 +620,8 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration(
};

ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSinkAseMetadataChanged(
    IBluetoothAudioProvider::AseState in_state,
    IBluetoothAudioProvider::AseState in_state, int32_t /*in_cigId*/,
    int32_t /*in_cisId*/,
    const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata) {
  (void)in_state;
  (void)in_metadata;
@@ -605,13 +629,95 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSinkAseMetadataChanged(
};

ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSourceAseMetadataChanged(
    IBluetoothAudioProvider::AseState in_state,
    IBluetoothAudioProvider::AseState in_state, int32_t /*in_cigId*/,
    int32_t /*in_cisId*/,
    const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata) {
  (void)in_state;
  (void)in_metadata;
  return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
};

void LeAudioOffloadAudioProvider::getBroadcastSettings() {
  if (!broadcast_settings.empty()) return;

  LOG(INFO) << __func__ << ": Loading broadcast settings from provider info";

  std::vector<CodecInfo> db_codec_info =
      BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
          SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
  broadcast_settings.clear();
  CodecSpecificConfigurationLtv::AudioChannelAllocation default_allocation;
  default_allocation.bitmask =
      CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER;

  for (auto& codec_info : db_codec_info) {
    if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio)
      continue;
    auto& transport = codec_info.transport.get<CodecInfo::Transport::leAudio>();
    LeAudioBroadcastConfigurationSetting setting;
    // Default setting
    setting.numBis = 1;
    setting.phy = {Phy::TWO_M};
    // Populate BIS configuration info using codec_info
    LeAudioBisConfiguration bis_cfg;
    bis_cfg.codecId = codec_info.id;

    CodecSpecificConfigurationLtv::OctetsPerCodecFrame octets;
    octets.value = transport.bitdepth[0];

    bis_cfg.codecConfiguration = {
        sampling_freq_map[transport.samplingFrequencyHz[0]], octets,
        frame_duration_map[transport.frameDurationUs[0]], default_allocation};

    // Add information to structure
    IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration sub_bis_cfg;
    sub_bis_cfg.numBis = 1;
    sub_bis_cfg.bisConfiguration = bis_cfg;
    IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration sub_cfg;
    sub_cfg.bisConfigurations = {sub_bis_cfg};
    setting.subgroupsConfigurations = {sub_cfg};

    broadcast_settings.push_back(setting);
  }

  LOG(INFO) << __func__
            << ": Done loading broadcast settings from provider info";
}

/* Get a new LeAudioAseConfigurationSetting by matching a setting with a
 * capabilities. The new setting will have a filtered list of
 * AseDirectionConfiguration that matched the capabilities */
std::optional<LeAudioBroadcastConfigurationSetting>
LeAudioOffloadAudioProvider::
    getCapabilitiesMatchedBroadcastConfigurationSettings(
        LeAudioBroadcastConfigurationSetting& setting,
        const IBluetoothAudioProvider::LeAudioDeviceCapabilities&
            capabilities) {
  std::vector<IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration>
      filter_subgroup;
  for (auto& sub_cfg : setting.subgroupsConfigurations) {
    std::vector<IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration>
        filtered_bis_cfg;
    for (auto& bis_cfg : sub_cfg.bisConfigurations)
      if (isMatchedBISConfiguration(bis_cfg.bisConfiguration, capabilities)) {
        filtered_bis_cfg.push_back(bis_cfg);
      }
    if (!filtered_bis_cfg.empty()) {
      IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration
          subgroup_cfg;
      subgroup_cfg.bisConfigurations = filtered_bis_cfg;
      filter_subgroup.push_back(subgroup_cfg);
    }
  }
  if (filter_subgroup.empty()) return std::nullopt;

  // Create a new LeAudioAseConfigurationSetting and return
  LeAudioBroadcastConfigurationSetting filtered_setting(setting);
  filtered_setting.subgroupsConfigurations = filter_subgroup;

  return filtered_setting;
}

ndk::ScopedAStatus
LeAudioOffloadAudioProvider::getLeAudioBroadcastConfiguration(
    const std::optional<std::vector<
@@ -619,13 +725,66 @@ LeAudioOffloadAudioProvider::getLeAudioBroadcastConfiguration(
        in_remoteSinkAudioCapabilities,
    const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
        in_requirement,
    IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting*
        _aidl_return) {
  /* TODO: Implement */
  (void)in_remoteSinkAudioCapabilities;
  (void)in_requirement;
  (void)_aidl_return;
  return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
    LeAudioBroadcastConfigurationSetting* _aidl_return) {
  getBroadcastSettings();
  _aidl_return = nullptr;

  // Match and filter capability
  std::vector<LeAudioBroadcastConfigurationSetting> filtered_settings;
  if (!in_remoteSinkAudioCapabilities.has_value()) {
    LOG(WARNING) << __func__ << ": Empty capability";
    return ndk::ScopedAStatus::ok();
  }
  for (auto& setting : broadcast_settings) {
    for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
      if (!capability.has_value()) continue;
      auto filtered_setting =
          getCapabilitiesMatchedBroadcastConfigurationSettings(
              setting, capability.value());
      if (filtered_setting.has_value())
        filtered_settings.push_back(filtered_setting.value());
    }
  }

  if (filtered_settings.empty()) {
    LOG(WARNING) << __func__ << ": Cannot match any remote capability";
    return ndk::ScopedAStatus::ok();
  }

  // Match and return the first matched requirement
  if (in_requirement.subgroupConfigurationRequirements.empty()) {
    LOG(INFO) << __func__ << ": Empty requirement";
    *_aidl_return = filtered_settings[0];
    return ndk::ScopedAStatus::ok();
  }

  for (auto& setting : filtered_settings) {
    // Further filter out bis configuration
    LeAudioBroadcastConfigurationSetting filtered_setting(setting);
    filtered_setting.subgroupsConfigurations.clear();
    for (auto& sub_cfg : setting.subgroupsConfigurations) {
      bool isMatched = false;
      for (auto& sub_req : in_requirement.subgroupConfigurationRequirements) {
        // Matching number of BIS
        if (sub_req.bisNumPerSubgroup != sub_cfg.bisConfigurations.size())
          continue;
        // Currently will ignore quality and context hint.
        isMatched = true;
        break;
      }
      if (isMatched)
        filtered_setting.subgroupsConfigurations.push_back(sub_cfg);
    }
    // Return the first match
    if (!filtered_setting.subgroupsConfigurations.empty()) {
      LOG(INFO) << __func__ << ": Matched requirement";
      *_aidl_return = filtered_setting;
      return ndk::ScopedAStatus::ok();
    }
  }

  LOG(WARNING) << __func__ << ": Cannot match any requirement";
  return ndk::ScopedAStatus::ok();
};

}  // namespace audio
+19 −6
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "BluetoothAudioProvider.h"
#include "aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.h"
#include "aidl/android/hardware/bluetooth/audio/MetadataLtv.h"
#include "aidl/android/hardware/bluetooth/audio/SessionType.h"

namespace aidl {
namespace android {
@@ -38,6 +39,8 @@ using AseQosDirectionRequirement = IBluetoothAudioProvider::
    LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement;
using LeAudioAseQosConfiguration =
    IBluetoothAudioProvider::LeAudioAseQosConfiguration;
using LeAudioBroadcastConfigurationSetting =
    IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting;

class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
 public:
@@ -68,12 +71,14 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
          in_qosRequirement,
      IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return)
      override;
  ndk::ScopedAStatus onSinkAseMetadataChanged(
      IBluetoothAudioProvider::AseState in_state,
  ndk::ScopedAStatus onSourceAseMetadataChanged(
      IBluetoothAudioProvider::AseState in_state, int32_t in_cigId,
      int32_t in_cisId,
      const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata)
      override;
  ndk::ScopedAStatus onSourceAseMetadataChanged(
      IBluetoothAudioProvider::AseState in_state,
  ndk::ScopedAStatus onSinkAseMetadataChanged(
      IBluetoothAudioProvider::AseState in_state, int32_t in_cigId,
      int32_t in_cisId,
      const std::optional<std::vector<std::optional<MetadataLtv>>>& in_metadata)
      override;
  ndk::ScopedAStatus getLeAudioBroadcastConfiguration(
@@ -82,12 +87,12 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
          in_remoteSinkAudioCapabilities,
      const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
          in_requirement,
      IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting*
          _aidl_return) override;
      LeAudioBroadcastConfigurationSetting* _aidl_return) override;

 private:
  ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
  std::map<CodecId, uint32_t> codec_priority_map_;
  std::vector<LeAudioBroadcastConfigurationSetting> broadcast_settings;

  // Private matching function definitions
  bool isMatchedValidCodec(CodecId cfg_codec, CodecId req_codec);
@@ -119,6 +124,9 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
      std::vector<CodecSpecificCapabilitiesLtv> codec_capabilities);
  bool isMatchedAseConfiguration(LeAudioAseConfiguration setting_cfg,
                                 LeAudioAseConfiguration requirement_cfg);
  bool isMatchedBISConfiguration(
      LeAudioBisConfiguration bis_cfg,
      const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
  void filterCapabilitiesAseDirectionConfiguration(
      std::vector<std::optional<AseDirectionConfiguration>>&
          direction_configurations,
@@ -144,6 +152,11 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
          requirement);
  bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos,
                               AseQosDirectionRequirement requirement_qos);
  std::optional<LeAudioBroadcastConfigurationSetting>
  getCapabilitiesMatchedBroadcastConfigurationSettings(
      LeAudioBroadcastConfigurationSetting& setting,
      const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities);
  void getBroadcastSettings();
};

class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
+26 −10
Original line number Diff line number Diff line
@@ -1553,8 +1553,8 @@ TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
    for (auto bits_per_sample : hfp_bits_per_samples_) {
      for (auto channel_mode : hfp_channel_modes_) {
        for (auto data_interval_us : hfp_data_interval_us_) {
          EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
                      channel_mode, data_interval_us));
          EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
                                  data_interval_us));
          EXPECT_TRUE(audio_provider_->endSession().isOk());
        }
      }
@@ -1617,8 +1617,8 @@ TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
    for (auto bits_per_sample : hfp_bits_per_samples_) {
      for (auto channel_mode : hfp_channel_modes_) {
        for (auto data_interval_us : hfp_data_interval_us_) {
            EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
                        channel_mode, data_interval_us));
          EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode,
                                  data_interval_us));
          EXPECT_TRUE(audio_provider_->endSession().isOk());
        }
      }
@@ -3041,6 +3041,22 @@ TEST_P(
  }
}

TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
       GetEmptyBroadcastConfigurationEmptyCapability) {
  std::vector<std::optional<LeAudioDeviceCapabilities>> empty_capability;
  IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement
      empty_requirement;

  IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration =
      new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting();

  // Check empty capability for source direction
  auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration(
      empty_capability, empty_requirement, configuration);

  ASSERT_TRUE(aidl_retval.isOk());
}

/**
 * Test whether each provider of type
 * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
+32 −19
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@
    (p) += 4;                                                         \
  }

#define LOG_TAG "BTAudioCodecsAidl"
#define LOG_TAG "BTAudioAseConfigAidl"

#include "BluetoothLeAudioAseConfigurationSettingProvider.h"

@@ -58,9 +58,9 @@ namespace audio {

/* Internal structure definition */
std::map<std::string,
         std::tuple<std::vector<std::optional<AseDirectionConfiguration>>*,
                    std::vector<std::optional<AseDirectionConfiguration>>*,
                    ConfigurationFlags*>>
         std::tuple<std::vector<std::optional<AseDirectionConfiguration>>,
                    std::vector<std::optional<AseDirectionConfiguration>>,
                    ConfigurationFlags>>
    configurations_;

std::vector<LeAudioAseConfigurationSetting> ase_configuration_settings_;
@@ -251,7 +251,7 @@ static const std::vector<
    kLeAudioSetScenarios = {{"/vendor/etc/aidl/le_audio/"
                             "aidl_audio_set_scenarios.bfbs",
                             "/vendor/etc/aidl/le_audio/"
                             "aidl_audio_set_configurations.json"}};
                             "aidl_audio_set_scenarios.json"}};

/* Implementation */

@@ -263,7 +263,9 @@ AudioSetConfigurationProviderJson::GetLeAudioAseConfigurationSettings() {

void AudioSetConfigurationProviderJson::
    LoadAudioSetConfigurationProviderJson() {
  if (configurations_.empty() && ase_configuration_settings_.empty()) {
  if (configurations_.empty() || ase_configuration_settings_.empty()) {
    ase_configuration_settings_.clear();
    configurations_.clear();
    auto loaded = LoadContent(kLeAudioSetConfigs, kLeAudioSetScenarios,
                              CodecLocation::HOST);
    if (!loaded)
@@ -565,7 +567,7 @@ bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles(
  std::string configurations_schema_binary_content;
  bool ok = flatbuffers::LoadFile(schema_file, true,
                                  &configurations_schema_binary_content);
  LOG(INFO) << __func__ << "Loading file " << schema_file;
  LOG(INFO) << __func__ << ": Loading file " << schema_file;
  if (!ok) return ok;

  /* Load the binary schema */
@@ -576,17 +578,17 @@ bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles(

  /* Load the content from JSON */
  std::string configurations_json_content;
  LOG(INFO) << __func__ << "Loading file " << schema_file;
  LOG(INFO) << __func__ << ": Loading file " << content_file;
  ok = flatbuffers::LoadFile(content_file, false, &configurations_json_content);
  if (!ok) return ok;

  /* Parse */
  LOG(INFO) << __func__ << "Parse JSON content" << schema_file;
  LOG(INFO) << __func__ << ": Parse JSON content";
  ok = configurations_parser_.Parse(configurations_json_content.c_str());
  if (!ok) return ok;

  /* Import from flatbuffers */
  LOG(INFO) << __func__ << "Build flat buffer structure" << schema_file;
  LOG(INFO) << __func__ << ": Build flat buffer structure";
  auto configurations_root = le_audio::GetAudioSetConfigurations(
      configurations_parser_.builder_.GetBufferPointer());
  if (!configurations_root) return false;
@@ -629,7 +631,7 @@ bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles(
    if (sourceAseConfiguration.empty() && sinkAseConfiguration.empty())
      continue;
    configurations_[flat_cfg->name()->str()] = std::make_tuple(
        &sourceAseConfiguration, &sinkAseConfiguration, &configurationFlags);
        sourceAseConfiguration, sinkAseConfiguration, configurationFlags);
  }

  return true;
@@ -641,6 +643,7 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles(
  std::string scenarios_schema_binary_content;
  bool ok = flatbuffers::LoadFile(schema_file, true,
                                  &scenarios_schema_binary_content);
  LOG(INFO) << __func__ << ": Loading file " << schema_file;
  if (!ok) return ok;

  /* Load the binary schema */
@@ -650,15 +653,18 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles(
  if (!ok) return ok;

  /* Load the content from JSON */
  LOG(INFO) << __func__ << ": Loading file " << content_file;
  std::string scenarios_json_content;
  ok = flatbuffers::LoadFile(content_file, false, &scenarios_json_content);
  if (!ok) return ok;

  /* Parse */
  LOG(INFO) << __func__ << ": Parse json content";
  ok = scenarios_parser_.Parse(scenarios_json_content.c_str());
  if (!ok) return ok;

  /* Import from flatbuffers */
  LOG(INFO) << __func__ << ": Build flat buffer structure";
  auto scenarios_root = le_audio::GetAudioSetScenarios(
      scenarios_parser_.builder_.GetBufferPointer());
  if (!scenarios_root) return false;
@@ -667,6 +673,7 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles(
  if ((flat_scenarios == nullptr) || (flat_scenarios->size() == 0))
    return false;

  LOG(INFO) << __func__ << ": Turn flat buffer into structure";
  AudioContext media_context = AudioContext();
  media_context.bitmask =
      (AudioContext::ALERTS | AudioContext::INSTRUCTIONAL |
@@ -686,9 +693,10 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles(
  AudioContext voice_assistants_context = AudioContext();
  voice_assistants_context.bitmask = AudioContext::VOICE_ASSISTANTS;

  LOG(DEBUG) << ": Updating " << flat_scenarios->size() << " scenarios.";
  LOG(DEBUG) << "Updating " << flat_scenarios->size() << " scenarios.";
  for (auto const& scenario : *flat_scenarios) {
    LOG(DEBUG) << "Scenario " << scenario->name()->c_str() << " configs:";
    LOG(DEBUG) << "Scenario " << scenario->name()->c_str()
               << " configs: " << scenario->configurations()->size();

    if (!scenario->configurations()) continue;
    std::string scenario_name = scenario->name()->c_str();
@@ -704,19 +712,24 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles(
    else if (scenario_name == "VoiceAssistants")
      context = AudioContext(voice_assistants_context);

    for (auto config_name : *scenario->configurations()) {
      if (configurations_.count(config_name->str()) == 0) continue;
      auto [source, sink, flags] = configurations_.at(config_name->str());
    for (auto it = scenario->configurations()->begin();
         it != scenario->configurations()->end(); ++it) {
      auto config_name = it->str();
      auto configuration = configurations_.find(config_name);
      if (configuration == configurations_.end()) continue;
      LOG(DEBUG) << "Getting configuration with name: " << config_name;
      auto [source, sink, flags] = configuration->second;
      // Each configuration will create a LeAudioAseConfigurationSetting
      // with the same {context, packing}
      // and different data
      LeAudioAseConfigurationSetting setting;
      setting.audioContext = context;
      // TODO: Packing
      setting.sourceAseConfiguration = *source;
      setting.sinkAseConfiguration = *sink;
      setting.flags = *flags;
      setting.sourceAseConfiguration = source;
      setting.sinkAseConfiguration = sink;
      setting.flags = flags;
      // Add to list of setting
      LOG(DEBUG) << "Pushing configuration to list: " << config_name;
      ase_configuration_settings_.push_back(setting);
    }
  }
Loading