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

Commit 9d4c7b1e authored by Grzegorz Kołodziejczyk's avatar Grzegorz Kołodziejczyk Committed by Grzegorz Kolodziejczyk
Browse files

le_audio: Differentiate Broadcast and Unicast for ClientInterface

While Broadcast and Unicast Sink Client Interface Endpoints can be
instantiated simultanousely a spearate Cleanup procedure should be
performed. Also Broadcast and Unicast transports should not share common
status.

Tag: #feature
Bug: 299238288
Test: atest BluetoothInstrumentationTests
Change-Id: I1f86e2b08a56a612e9c0f8a63f7c4c84916e59db
parent f19cefe6
Loading
Loading
Loading
Loading
+40 −24
Original line number Diff line number Diff line
@@ -97,8 +97,15 @@ LeAudioClientInterface* LeAudioClientInterface::Get() {
}

void LeAudioClientInterface::Sink::Cleanup() {
  LOG(INFO) << __func__ << " sink";
  LOG_INFO("HAL transport: 0x%02x, is broadcast: %d",
            static_cast<int>(HalVersionManager::GetHalTransport()),
            is_broadcaster_);

  StopSession();

  /* Cleanup transport interface and instance according to type and role */
  if (HalVersionManager::GetHalTransport() ==
      BluetoothAudioHalTransport::HIDL) {
    if (hidl::le_audio::LeAudioSinkTransport::interface) {
      delete hidl::le_audio::LeAudioSinkTransport::interface;
      hidl::le_audio::LeAudioSinkTransport::interface = nullptr;
@@ -107,21 +114,30 @@ void LeAudioClientInterface::Sink::Cleanup() {
      delete hidl::le_audio::LeAudioSinkTransport::instance;
      hidl::le_audio::LeAudioSinkTransport::instance = nullptr;
    }
  if (aidl::le_audio::LeAudioSinkTransport::interface_unicast_) {
    delete aidl::le_audio::LeAudioSinkTransport::interface_unicast_;
    aidl::le_audio::LeAudioSinkTransport::interface_unicast_ = nullptr;
  }
  } else if (HalVersionManager::GetHalTransport() ==
             BluetoothAudioHalTransport::AIDL) {
    if (IsBroadcaster()) {
      if (aidl::le_audio::LeAudioSinkTransport::interface_broadcast_) {
        delete aidl::le_audio::LeAudioSinkTransport::interface_broadcast_;
        aidl::le_audio::LeAudioSinkTransport::interface_broadcast_ = nullptr;
      }
      if (aidl::le_audio::LeAudioSinkTransport::instance_broadcast_) {
        delete aidl::le_audio::LeAudioSinkTransport::instance_broadcast_;
        aidl::le_audio::LeAudioSinkTransport::instance_broadcast_ = nullptr;
      }
    } else {
      if (aidl::le_audio::LeAudioSinkTransport::interface_unicast_) {
        delete aidl::le_audio::LeAudioSinkTransport::interface_unicast_;
        aidl::le_audio::LeAudioSinkTransport::interface_unicast_ = nullptr;
      }
      if (aidl::le_audio::LeAudioSinkTransport::instance_unicast_) {
        delete aidl::le_audio::LeAudioSinkTransport::instance_unicast_;
        aidl::le_audio::LeAudioSinkTransport::instance_unicast_ = nullptr;
      }
  if (aidl::le_audio::LeAudioSinkTransport::instance_broadcast_) {
    delete aidl::le_audio::LeAudioSinkTransport::instance_broadcast_;
    aidl::le_audio::LeAudioSinkTransport::instance_broadcast_ = nullptr;
    }
  } else {
    LOG_ERROR("Invalid HAL transport: 0x%02x",
              static_cast<int>(HalVersionManager::GetHalTransport()));
  }
}

+23 −22
Original line number Diff line number Diff line
@@ -32,13 +32,6 @@ using bluetooth::audio::le_audio::LeAudioClientInterface;

namespace le_audio {
namespace {
// TODO: HAL state should be in the HAL implementation
enum {
  HAL_UNINITIALIZED,
  HAL_STOPPED,
  HAL_STARTED,
} le_audio_sink_hal_state;

struct AudioHalStats {
  size_t media_read_total_underflow_bytes;
  size_t media_read_total_underflow_count;
@@ -54,6 +47,12 @@ struct AudioHalStats {
} sStats;

class SourceImpl : public LeAudioSourceAudioHalClient {
  enum LeAudioSinkHalState {
    HAL_UNINITIALIZED,
    HAL_STOPPED,
    HAL_STARTED,
  } le_audio_sink_hal_state_;

 public:
  // Interface implementation
  bool Start(const LeAudioCodecConfiguration& codec_configuration,
@@ -70,9 +69,11 @@ class SourceImpl : public LeAudioSourceAudioHalClient {
  void ReconfigurationComplete() override;

  // Internal functionality
  SourceImpl(bool is_broadcaster) : is_broadcaster_(is_broadcaster){};
  SourceImpl(bool is_broadcaster)
      : le_audio_sink_hal_state_(HAL_UNINITIALIZED),
        is_broadcaster_(is_broadcaster){};
  ~SourceImpl() override {
    if (le_audio_sink_hal_state != HAL_UNINITIALIZED) Release();
    if (le_audio_sink_hal_state_ != HAL_UNINITIALIZED) Release();
  }

  bool OnResumeReq(bool start_media_task);
@@ -127,12 +128,12 @@ bool SourceImpl::Acquire() {
  }

  LOG_INFO();
  le_audio_sink_hal_state = HAL_STOPPED;
  le_audio_sink_hal_state_ = HAL_STOPPED;
  return this->InitAudioSinkThread();
}

void SourceImpl::Release() {
  if (le_audio_sink_hal_state == HAL_UNINITIALIZED) {
  if (le_audio_sink_hal_state_ == HAL_UNINITIALIZED) {
    LOG_WARN("Audio HAL Audio sink is not running");
    return;
  }
@@ -150,7 +151,7 @@ void SourceImpl::Release() {
      LOG_ERROR("Can't get LE Audio HAL interface");
    }

    le_audio_sink_hal_state = HAL_UNINITIALIZED;
    le_audio_sink_hal_state_ = HAL_UNINITIALIZED;
    halSinkInterface_ = nullptr;
  }
}
@@ -294,7 +295,7 @@ bool SourceImpl::Start(const LeAudioCodecConfiguration& codec_configuration,
    return false;
  }

  if (le_audio_sink_hal_state == HAL_STARTED) {
  if (le_audio_sink_hal_state_ == HAL_STARTED) {
    LOG_ERROR("Audio HAL Audio sink is already in use");
    return false;
  }
@@ -319,7 +320,7 @@ bool SourceImpl::Start(const LeAudioCodecConfiguration& codec_configuration,

  std::lock_guard<std::mutex> guard(audioSourceCallbacksMutex_);
  audioSourceCallbacks_ = audioReceiver;
  le_audio_sink_hal_state = HAL_STARTED;
  le_audio_sink_hal_state_ = HAL_STARTED;
  return true;
}

@@ -329,7 +330,7 @@ void SourceImpl::Stop() {
    return;
  }

  if (le_audio_sink_hal_state != HAL_STARTED) {
  if (le_audio_sink_hal_state_ != HAL_STARTED) {
    LOG_ERROR("Audio HAL Audio sink was not started!");
    return;
  }
@@ -337,7 +338,7 @@ void SourceImpl::Stop() {
  LOG_INFO();

  halSinkInterface_->StopSession();
  le_audio_sink_hal_state = HAL_STOPPED;
  le_audio_sink_hal_state_ = HAL_STOPPED;

  if (CodecManager::GetInstance()->GetCodecLocation() ==
      types::CodecLocation::HOST) {
@@ -350,7 +351,7 @@ void SourceImpl::Stop() {

void SourceImpl::ConfirmStreamingRequest() {
  if ((halSinkInterface_ == nullptr) ||
      (le_audio_sink_hal_state != HAL_STARTED)) {
      (le_audio_sink_hal_state_ != HAL_STARTED)) {
    LOG_ERROR("Audio HAL Audio sink was not started!");
    return;
  }
@@ -366,7 +367,7 @@ void SourceImpl::ConfirmStreamingRequest() {

void SourceImpl::SuspendedForReconfiguration() {
  if ((halSinkInterface_ == nullptr) ||
      (le_audio_sink_hal_state != HAL_STARTED)) {
      (le_audio_sink_hal_state_ != HAL_STARTED)) {
    LOG_ERROR("Audio HAL Audio sink was not started!");
    return;
  }
@@ -377,7 +378,7 @@ void SourceImpl::SuspendedForReconfiguration() {

void SourceImpl::ReconfigurationComplete() {
  if ((halSinkInterface_ == nullptr) ||
      (le_audio_sink_hal_state != HAL_STARTED)) {
      (le_audio_sink_hal_state_ != HAL_STARTED)) {
    LOG_ERROR("Audio HAL Audio sink was not started!");
    return;
  }
@@ -388,7 +389,7 @@ void SourceImpl::ReconfigurationComplete() {

void SourceImpl::CancelStreamingRequest() {
  if ((halSinkInterface_ == nullptr) ||
      (le_audio_sink_hal_state != HAL_STARTED)) {
      (le_audio_sink_hal_state_ != HAL_STARTED)) {
    LOG_ERROR("Audio HAL Audio sink was not started!");
    return;
  }
@@ -399,7 +400,7 @@ void SourceImpl::CancelStreamingRequest() {

void SourceImpl::UpdateRemoteDelay(uint16_t remote_delay_ms) {
  if ((halSinkInterface_ == nullptr) ||
      (le_audio_sink_hal_state != HAL_STARTED)) {
      (le_audio_sink_hal_state_ != HAL_STARTED)) {
    LOG_ERROR("Audio HAL Audio sink was not started!");
    return;
  }
@@ -411,7 +412,7 @@ void SourceImpl::UpdateRemoteDelay(uint16_t remote_delay_ms) {
void SourceImpl::UpdateAudioConfigToHal(
    const ::le_audio::offload_config& config) {
  if ((halSinkInterface_ == nullptr) ||
      (le_audio_sink_hal_state != HAL_STARTED)) {
      (le_audio_sink_hal_state_ != HAL_STARTED)) {
    LOG_ERROR("Audio HAL Audio sink was not started!");
    return;
  }