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

Commit cca2f4b1 authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Decouple BAP logic from Audio HAL client type

Currently, instead of comparing audio set configurations directly, we
compare the audio HAL client configurations derived from the currently
supported remote device configurations. For the audio HAL client it is
mandatory to have the certain paramters which are not necessarily mandatory
for the hardware offloader case or for the vendor codecs or those received
over the config provider AIDL interface.

Currently, configurations without these parameters will not be considered
valid remote device configurations, even though some of these missing parameters
(like bits per sample) are irrelevant to the remote device configuration and are
only local audio HAL client specific.

This patch uses the remote device configuration data type comparison directly to
verify the remote device configurations, and improves naming to functions and
variables used by this logic to avoid similar unintended abuse in future.

Bug: 308428860
Test: atest bluetooth_le_audio_test bluetooth_le_audio_client_test  bluetooth_test_broadcaster bluetooth_test_broadcaster_state_machine bluetooth_le_audio_codec_manager_test
Flag: EXEMPT; Non-flaggable simplifying refactor - confirmed with unit tests
Change-Id: I2f9ec46e2b5761ede77774a4eb258606c6c277cf
parent fc7824bd
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -23,9 +23,8 @@
#include "audio_hal_interface/le_audio_software.h"

namespace bluetooth::le_audio {
/* Represents configuration of audio codec, as exchanged between le audio and
 * phone.
 * It can also be passed to the audio source to configure its parameters.
/* Represents configuration used to configure the local audio sessions and
 * the software codecs in case of a software coding sessions.
 */
struct LeAudioCodecConfiguration {
  static constexpr uint8_t kChannelNumberMono =
@@ -57,13 +56,13 @@ struct LeAudioCodecConfiguration {
  static constexpr uint32_t kInterval10000Us = 10000;

  /** number of channels */
  uint8_t num_channels;
  uint8_t num_channels = 0;

  /** sampling rate that the codec expects to receive from audio framework */
  uint32_t sample_rate;
  uint32_t sample_rate = 0;

  /** bits per sample that codec expects to receive from audio framework */
  uint8_t bits_per_sample;
  uint8_t bits_per_sample = 0;

  /** Data interval determines how often we send samples to the remote. This
   * should match how often we grab data from audio source, optionally we can
@@ -71,7 +70,7 @@ struct LeAudioCodecConfiguration {
   *
   * Value is provided in us.
   */
  uint32_t data_interval_us;
  uint32_t data_interval_us = 0;

  bool operator!=(const LeAudioCodecConfiguration& other) {
    return !((num_channels == other.num_channels) &&
+65 −136
Original line number Diff line number Diff line
@@ -249,8 +249,6 @@ class LeAudioClientImpl : public LeAudioClient {
        sink_monitor_mode_(false),
        sink_monitor_notified_status_(std::nullopt),
        source_monitor_mode_(false),
        current_source_codec_config({0, 0, 0, 0}),
        current_sink_codec_config({0, 0, 0, 0}),
        le_audio_source_hal_client_(nullptr),
        le_audio_sink_hal_client_(nullptr),
        close_vbc_timeout_(alarm_new("LeAudioCloseVbcTimeout")),
@@ -1111,9 +1109,7 @@ class LeAudioClientImpl : public LeAudioClient {
    group->is_duplex_preference_le_audio = is_duplex_preference_le_audio;
  }

  void StartAudioSession(LeAudioDeviceGroup* group,
                         const LeAudioCodecConfiguration* source_config,
                         const LeAudioCodecConfiguration* sink_config) {
  void StartAudioSession(LeAudioDeviceGroup* group) {
    /* This function is called when group is not yet set to active.
     * This is why we don't have to check if session is started already.
     * Just check if it is acquired.
@@ -1132,10 +1128,10 @@ class LeAudioClientImpl : public LeAudioClient {

    /* We assume that peer device always use same frame duration */
    uint32_t frame_duration_us = 0;
    if (!source_config->IsInvalid()) {
      frame_duration_us = source_config->data_interval_us;
    } else if (!sink_config->IsInvalid()) {
      frame_duration_us = sink_config->data_interval_us;
    if (!current_encoder_config_.IsInvalid()) {
      frame_duration_us = current_encoder_config_.data_interval_us;
    } else if (!current_decoder_config_.IsInvalid()) {
      frame_duration_us = current_decoder_config_.data_interval_us;
    } else {
      log::assert_that(true, "Both configs are invalid");
    }
@@ -1150,14 +1146,13 @@ class LeAudioClientImpl : public LeAudioClient {
    /* If group supports more than 16kHz for the microphone in converstional
     * case let's use that also for Audio Framework.
     */
    std::optional<LeAudioCodecConfiguration> sink_configuration =
        group->GetCodecConfigurationByDirection(
    auto sink_configuration = group->GetAudioSessionCodecConfigForDirection(
        LeAudioContextType::CONVERSATIONAL,
        bluetooth::le_audio::types::kLeAudioDirectionSource);
    if (sink_configuration &&
        sink_configuration->sample_rate >
    if (!sink_configuration.IsInvalid() &&
        sink_configuration.sample_rate >
            bluetooth::audio::le_audio::kSampleRate16000) {
      audio_framework_sink_config.sample_rate = sink_configuration->sample_rate;
      audio_framework_sink_config.sample_rate = sink_configuration.sample_rate;
    }

    le_audio_sink_hal_client_->Start(audio_framework_sink_config,
@@ -1289,14 +1284,12 @@ class LeAudioClientImpl : public LeAudioClient {
        }
      }
    }
    UpdateConfigAndCheckIfReconfigurationIsNeeded(group_id,
                                                  default_context_type);
    if (current_source_codec_config.IsInvalid() &&
        current_sink_codec_config.IsInvalid()) {
      log::error("Unsupported device configurations");

    /* Only update the configuration audio context and audio coding session
     * parameters if needed.
     */
    UpdateConfigAndCheckIfReconfigurationIsNeeded(group, default_context_type);
    callbacks_->OnGroupStatus(group_id, GroupStatus::INACTIVE);
      return;
    }

    auto previous_active_group = active_group_id_;
    log::info("Active group_id changed {} -> {}", previous_active_group,
@@ -1304,8 +1297,7 @@ class LeAudioClientImpl : public LeAudioClient {

    if (previous_active_group == bluetooth::groups::kGroupUnknown) {
      /* Expose audio sessions if there was no previous active group */
      StartAudioSession(group, &current_source_codec_config,
                        &current_sink_codec_config);
      StartAudioSession(group);
      active_group_id_ = group_id;
    } else {
      /* In case there was an active group. Stop the stream, but before that, set
@@ -3678,7 +3670,7 @@ class LeAudioClientImpl : public LeAudioClient {
      sw_enc_left = bluetooth::le_audio::CodecInterface::CreateInstance(
          stream_conf->codec_id);
      auto codec_status = sw_enc_left->InitEncoder(
          audio_framework_source_config, current_source_codec_config);
          audio_framework_source_config, current_encoder_config_);
      if (codec_status !=
          bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
        log::error("Left channel codec setup failed with err: {}",
@@ -3690,7 +3682,7 @@ class LeAudioClientImpl : public LeAudioClient {
      sw_enc_right = bluetooth::le_audio::CodecInterface::CreateInstance(
          stream_conf->codec_id);
      codec_status = sw_enc_right->InitEncoder(audio_framework_source_config,
                                               current_source_codec_config);
                                               current_encoder_config_);
      if (codec_status !=
          bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
        log::error("Right channel codec setup failed with err: {}",
@@ -3757,7 +3749,7 @@ class LeAudioClientImpl : public LeAudioClient {
      }
      sw_dec_left = bluetooth::le_audio::CodecInterface::CreateInstance(
          stream_conf->codec_id);
      auto codec_status = sw_dec_left->InitDecoder(current_sink_codec_config,
      auto codec_status = sw_dec_left->InitDecoder(current_decoder_config_,
                                                   audio_framework_sink_config);
      if (codec_status !=
          bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
@@ -3769,7 +3761,7 @@ class LeAudioClientImpl : public LeAudioClient {

      sw_dec_right = bluetooth::le_audio::CodecInterface::CreateInstance(
          stream_conf->codec_id);
      codec_status = sw_dec_right->InitDecoder(current_sink_codec_config,
      codec_status = sw_dec_right->InitDecoder(current_decoder_config_,
                                               audio_framework_sink_config);
      if (codec_status !=
          bluetooth::le_audio::CodecInterface::Status::STATUS_OK) {
@@ -3810,49 +3802,30 @@ class LeAudioClientImpl : public LeAudioClient {

  void StopAudio(void) { SuspendAudio(); }

  void printSingleConfiguration(int fd, LeAudioCodecConfiguration* conf,
                                bool print_audio_state, bool sender = false) {
  void printCurrentStreamConfiguration(int fd) {
    std::stringstream stream;
    if (print_audio_state) {
      if (sender) {
        stream << "\taudio sender state: " << audio_sender_state_ << "\n";
      } else {
        stream << "\taudio receiver state: " << audio_receiver_state_ << "\n";
      }
    }

    stream << "\tsample rate: " << +conf->sample_rate
           << ",\tchan: " << +conf->num_channels
           << ",\tbits: " << +conf->bits_per_sample
           << ",\tdata_interval_us: " << +conf->data_interval_us << "\n";
    auto config_printer = [&stream](LeAudioCodecConfiguration& conf) {
      stream << "\tsample rate: " << +conf.sample_rate
             << ",\tchan: " << +conf.num_channels
             << ",\tbits: " << +conf.bits_per_sample
             << ",\tdata_interval_us: " << +conf.data_interval_us << "\n";
    };

    dprintf(fd, "%s", stream.str().c_str());
  }
    stream << " Speaker codec config (audio framework) \n";
    stream << "\taudio sender state: " << audio_sender_state_ << "\n";
    config_printer(audio_framework_source_config);

  void printCurrentStreamConfiguration(int fd) {
    auto conf = &audio_framework_source_config;
    dprintf(fd, " Speaker codec config (audio framework) \n");
    if (conf) {
      printSingleConfiguration(fd, conf, false);
    }
    stream << " Microphone codec config (audio framework) \n";
    stream << "\taudio receiver state: " << audio_receiver_state_ << "\n";
    config_printer(audio_framework_sink_config);

    dprintf(fd, " Microphone codec config (audio framework) \n");
    conf = &audio_framework_sink_config;
    if (conf) {
      printSingleConfiguration(fd, conf, false);
    }
    stream << " Speaker codec config (SW encoder)\n";
    config_printer(current_encoder_config_);

    conf = &current_source_codec_config;
    dprintf(fd, " Speaker codec config (Bluetooth)\n");
    if (conf) {
      printSingleConfiguration(fd, conf, true, true);
    }
    stream << " Microphone codec config (SW decoder)\n";
    config_printer(current_decoder_config_);

    conf = &current_sink_codec_config;
    dprintf(fd, " Microphone codec config (Bluetooth)\n");
    if (conf) {
      printSingleConfiguration(fd, conf, true, false);
    }
    dprintf(fd, "%s", stream.str().c_str());
  }

  void Dump(int fd) {
@@ -3924,65 +3897,17 @@ class LeAudioClientImpl : public LeAudioClient {
  }

  AudioReconfigurationResult UpdateConfigAndCheckIfReconfigurationIsNeeded(
      int group_id, LeAudioContextType context_type) {
    bool reconfiguration_needed = false;
    bool sink_cfg_available = true;
    bool source_cfg_available = true;

      LeAudioDeviceGroup* group, LeAudioContextType context_type) {
    log::debug("Checking whether to reconfigure from {} to {}",
               ToString(configuration_context_type_), ToString(context_type));

    auto group = aseGroups_.FindById(group_id);
    if (!group) {
      log::error("Invalid group: {}", static_cast<int>(group_id));
      return AudioReconfigurationResult::RECONFIGURATION_NOT_NEEDED;
    }

    std::optional<LeAudioCodecConfiguration> source_configuration =
        group->GetCodecConfigurationByDirection(
            context_type, bluetooth::le_audio::types::kLeAudioDirectionSink);
    std::optional<LeAudioCodecConfiguration> sink_configuration =
        group->GetCodecConfigurationByDirection(
            context_type, bluetooth::le_audio::types::kLeAudioDirectionSource);

    if (source_configuration) {
      if (*source_configuration != current_source_codec_config) {
        current_source_codec_config = *source_configuration;
        reconfiguration_needed = true;
      }
    } else {
      if (!current_source_codec_config.IsInvalid()) {
        current_source_codec_config = {0, 0, 0, 0};
        reconfiguration_needed = true;
      }
      source_cfg_available = false;
    }

    if (sink_configuration) {
      if (*sink_configuration != current_sink_codec_config) {
        current_sink_codec_config = *sink_configuration;
        reconfiguration_needed = true;
      }
    } else {
      if (!current_sink_codec_config.IsInvalid()) {
        current_sink_codec_config = {0, 0, 0, 0};
        reconfiguration_needed = true;
      }

      sink_cfg_available = false;
    }

    if (DsaReconfigureNeeded(group, context_type)) {
      reconfiguration_needed = true;
    auto audio_set_conf = group->GetConfiguration(context_type);
    if (!audio_set_conf) {
      return AudioReconfigurationResult::RECONFIGURATION_NOT_POSSIBLE;
    }

    log::debug(
        "Context: {} Reconfiguration_needed = {}, sink_cfg_available = {}, "
        "source_cfg_available = {}",
        ToString(context_type), reconfiguration_needed, sink_cfg_available,
        source_cfg_available);

    if (!reconfiguration_needed) {
    if (group->IsGroupConfiguredTo(*audio_set_conf) &&
        !DsaReconfigureNeeded(group, context_type)) {
      // Assign the new configuration context as it reprents the current
      // use case even when it eventually ends up being the exact same
      // codec and qos configuration.
@@ -3993,14 +3918,17 @@ class LeAudioClientImpl : public LeAudioClient {
      return AudioReconfigurationResult::RECONFIGURATION_NOT_NEEDED;
    }

    if (!sink_cfg_available && !source_cfg_available) {
      return AudioReconfigurationResult::RECONFIGURATION_NOT_POSSIBLE;
    }

    log::info("Session reconfiguration needed group: {} for context type: {}",
              group->group_id_, ToHexString(context_type));

    configuration_context_type_ = context_type;

    // Note: The local sink config is based on remote device's source config
    //       and vice versa.
    current_decoder_config_ = group->GetAudioSessionCodecConfigForDirection(
        context_type, bluetooth::le_audio::types::kLeAudioDirectionSource);
    current_encoder_config_ = group->GetAudioSessionCodecConfigForDirection(
        context_type, bluetooth::le_audio::types::kLeAudioDirectionSink);
    return AudioReconfigurationResult::RECONFIGURATION_NEEDED;
  }

@@ -4143,7 +4071,7 @@ class LeAudioClientImpl : public LeAudioClient {
    }

    /* Check if the device resume is allowed */
    if (!group->GetCodecConfigurationByDirection(
    if (!group->HasCodecConfigurationForDirection(
            configuration_context_type_,
            bluetooth::le_audio::types::kLeAudioDirectionSink)) {
      log::error("invalid resume request for context type: {}",
@@ -4358,10 +4286,11 @@ class LeAudioClientImpl : public LeAudioClient {

  inline bool IsDirectionAvailableForCurrentConfiguration(
      const LeAudioDeviceGroup* group, uint8_t direction) const {
    return group
        ->GetCachedCodecConfigurationByDirection(configuration_context_type_,
                                                 direction)
        .has_value();
    auto current_config =
        group->GetCachedConfiguration(configuration_context_type_);
    if (current_config)
      return (current_config->confs.get(direction).size() != 0);
    return false;
  }

  void notifyAudioLocalSink(UnicastMonitorModeStatus status) {
@@ -4418,7 +4347,7 @@ class LeAudioClientImpl : public LeAudioClient {
    }

    /* Check if the device resume is allowed */
    if (!group->GetCodecConfigurationByDirection(
    if (!group->HasCodecConfigurationForDirection(
            configuration_context_type_,
            bluetooth::le_audio::types::kLeAudioDirectionSource)) {
      log::error("invalid resume request for context type: {}",
@@ -4639,8 +4568,8 @@ class LeAudioClientImpl : public LeAudioClient {

  bool SetConfigurationAndStopStreamWhenNeeded(
      LeAudioDeviceGroup* group, LeAudioContextType new_context_type) {
    auto reconfig_result = UpdateConfigAndCheckIfReconfigurationIsNeeded(
        group->group_id_, new_context_type);
    auto reconfig_result =
        UpdateConfigAndCheckIfReconfigurationIsNeeded(group, new_context_type);
    /* Even though the reconfiguration may not be needed, this has
     * to be set here as it might be the initial configuration.
     */
@@ -5821,9 +5750,9 @@ class LeAudioClientImpl : public LeAudioClient {

  static constexpr uint16_t kBapMinimumAttMtu = 64;

  /* Current stream configuration */
  LeAudioCodecConfiguration current_source_codec_config;
  LeAudioCodecConfiguration current_sink_codec_config;
  /* Current stream configuration - used to set up the software codecs */
  LeAudioCodecConfiguration current_encoder_config_;
  LeAudioCodecConfiguration current_decoder_config_;

  /* Static Audio Framework session configuration.
   *  Resampling will be done inside the bt stack
+22 −57
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@

#include <bluetooth/log.h>

#include <optional>

#include "bta/include/bta_gatt_api.h"
#include "bta_csis_api.h"
#include "btif/include/btif_profile_storage.h"
@@ -28,6 +30,7 @@
#include "internal_include/bt_trace.h"
#include "le_audio/le_audio_types.h"
#include "le_audio_set_configuration_provider.h"
#include "le_audio_utils.h"
#include "main/shim/entry.h"
#include "metrics_collector.h"
#include "os/log.h"
@@ -760,7 +763,7 @@ bool LeAudioDeviceGroup::UpdateAudioContextAvailability(void) {
}

bool LeAudioDeviceGroup::UpdateAudioSetConfigurationCache(
    LeAudioContextType ctx_type) {
    LeAudioContextType ctx_type) const {
  CodecManager::UnicastConfigurationRequirements requirements = {
      .audio_context_type = ctx_type};
  auto new_conf = CodecManager::GetInstance()->GetCodecConfig(
@@ -1550,7 +1553,7 @@ LeAudioDeviceGroup::GetActiveConfiguration(void) const {
}

std::shared_ptr<const set_configurations::AudioSetConfiguration>
LeAudioDeviceGroup::GetConfiguration(LeAudioContextType context_type) {
LeAudioDeviceGroup::GetConfiguration(LeAudioContextType context_type) const {
  if (context_type == LeAudioContextType::UNINITIALIZED) {
    return nullptr;
  }
@@ -1572,60 +1575,9 @@ LeAudioDeviceGroup::GetConfiguration(LeAudioContextType context_type) {
  return GetCachedConfiguration(context_type);
}

std::optional<LeAudioCodecConfiguration>
LeAudioDeviceGroup::GetCachedCodecConfigurationByDirection(
LeAudioCodecConfiguration
LeAudioDeviceGroup::GetAudioSessionCodecConfigForDirection(
    LeAudioContextType context_type, uint8_t direction) const {
  auto audio_set_conf = GetCachedConfiguration(context_type);
  if (!audio_set_conf) return std::nullopt;

  LeAudioCodecConfiguration group_config = {0, 0, 0, 0};
  for (const auto& conf : audio_set_conf->confs.get(direction)) {
    if (group_config.sample_rate != 0 &&
        conf.codec.GetSamplingFrequencyHz() != group_config.sample_rate) {
      log::warn(
          "stream configuration could not be determined (sampling frequency "
          "differs) for direction: {}",
          loghex(direction));
      return std::nullopt;
    }
    group_config.sample_rate = conf.codec.GetSamplingFrequencyHz();

    if (group_config.data_interval_us != 0 &&
        conf.codec.GetDataIntervalUs() != group_config.data_interval_us) {
      log::warn(
          "stream configuration could not be determined (data interval "
          "differs) for direction: {}",
          loghex(direction));
      return std::nullopt;
    }
    group_config.data_interval_us = conf.codec.GetDataIntervalUs();

    if (group_config.bits_per_sample != 0 &&
        conf.codec.GetBitsPerSample() != group_config.bits_per_sample) {
      log::warn(
          "stream configuration could not be determined (bits per sample "
          "differs) for direction: {}",
          loghex(direction));
      return std::nullopt;
    }
    group_config.bits_per_sample = conf.codec.GetBitsPerSample();

    log::assert_that(
        audio_set_conf->topology_info.has_value(),
        "No topology info, which is required to properly configure the ASEs");
    group_config.num_channels +=
        conf.codec.GetChannelCountPerIsoStream() *
        audio_set_conf->topology_info->device_count.get(direction);
  }

  if (group_config.IsInvalid()) return std::nullopt;

  return group_config;
}

std::optional<LeAudioCodecConfiguration>
LeAudioDeviceGroup::GetCodecConfigurationByDirection(
    LeAudioContextType context_type, uint8_t direction) {
  const set_configurations::AudioSetConfiguration* conf = nullptr;
  bool is_valid = false;

@@ -1640,8 +1592,19 @@ LeAudioDeviceGroup::GetCodecConfigurationByDirection(
    UpdateAudioSetConfigurationCache(context_type);
  }

  /* Return the cached value */
  return GetCachedCodecConfigurationByDirection(context_type, direction);
  auto audio_set_conf = GetCachedConfiguration(context_type);
  if (!audio_set_conf) return {0, 0, 0, 0};

  auto group_config =
      utils::GetAudioSessionCodecConfigFromAudioSetConfiguration(
          *audio_set_conf.get(), direction);
  return group_config;
}

bool LeAudioDeviceGroup::HasCodecConfigurationForDirection(
    types::LeAudioContextType context_type, uint8_t direction) const {
  auto audio_set_conf = GetConfiguration(context_type);
  return audio_set_conf ? !audio_set_conf->confs.get(direction).empty() : false;
}

bool LeAudioDeviceGroup::IsAudioSetConfigurationAvailable(
@@ -1864,6 +1827,8 @@ bool LeAudioDeviceGroup::IsConfiguredForContext(
    return false;
  }

  if (!stream_conf.conf) return false;

  /* Check if used configuration is same as the active one.*/
  return (stream_conf.conf.get() == GetActiveConfiguration().get());
}
+16 −9
Original line number Diff line number Diff line
@@ -76,6 +76,12 @@ class LeAudioDeviceGroup {
    types::CigState state_;
  } cig;

  bool IsGroupConfiguredTo(
      const set_configurations::AudioSetConfiguration& cfg) {
    if (!stream_conf.conf) return false;
    return cfg == *stream_conf.conf;
  }

  /* Current configuration strategy - recalculated on demand */
  mutable std::optional<types::LeAudioConfigurationStrategy> strategy_ =
      std::nullopt;
@@ -204,14 +210,15 @@ class LeAudioDeviceGroup {
  bool GetPresentationDelay(uint32_t* delay, uint8_t direction) const;
  uint16_t GetRemoteDelay(uint8_t direction) const;
  bool UpdateAudioContextAvailability(void);
  bool UpdateAudioSetConfigurationCache(types::LeAudioContextType ctx_type);
  bool UpdateAudioSetConfigurationCache(
      types::LeAudioContextType ctx_type) const;
  bool ReloadAudioLocations(void);
  bool ReloadAudioDirections(void);
  std::shared_ptr<const set_configurations::AudioSetConfiguration>
  GetActiveConfiguration(void) const;
  bool IsPendingConfiguration(void) const;
  std::shared_ptr<const set_configurations::AudioSetConfiguration>
  GetConfiguration(types::LeAudioContextType ctx_type);
  GetConfiguration(types::LeAudioContextType ctx_type) const;
  std::shared_ptr<const set_configurations::AudioSetConfiguration>
  GetCachedConfiguration(types::LeAudioContextType ctx_type) const;
  void InvalidateCachedConfigurations(void);
@@ -225,10 +232,9 @@ class LeAudioDeviceGroup {
  bool IsAudioSetConfigurationSupported(
      LeAudioDevice* leAudioDevice,
      const set_configurations::AudioSetConfiguration* audio_set_conf) const;
  std::optional<LeAudioCodecConfiguration> GetCodecConfigurationByDirection(
      types::LeAudioContextType group_context_type, uint8_t direction);
  std::optional<LeAudioCodecConfiguration>
  GetCachedCodecConfigurationByDirection(
  LeAudioCodecConfiguration GetAudioSessionCodecConfigForDirection(
      types::LeAudioContextType group_context_type, uint8_t direction) const;
  bool HasCodecConfigurationForDirection(
      types::LeAudioContextType group_context_type, uint8_t direction) const;
  bool IsAudioSetConfigurationAvailable(
      types::LeAudioContextType group_context_type);
@@ -432,7 +438,8 @@ class LeAudioDeviceGroup {
   * change. Stored as a pair of (is_valid_cache, configuration*). `pair.first`
   * being `false` means that the cached value should be refreshed.
   */
  std::map<types::LeAudioContextType,
  mutable std::map<
      types::LeAudioContextType,
      std::pair<bool, const std::shared_ptr<
                          set_configurations::AudioSetConfiguration>>>
      context_to_configuration_cache_map;
+50 −70

File changed.

Preview size limit exceeded, changes collapsed.

Loading