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

Commit 54233ccc authored by Henri Chataing's avatar Henri Chataing Committed by Gerrit Code Review
Browse files

Merge changes I835baafd,Ie240f60d into main

* changes:
  audio_hal_interface: Pass a2dp_offload_enabled flag to bluetooth::audio::a2dp::init
  audio_hal_interface: Inject a2dp dependencies through BluetoothAudioPort
parents 0fc5ac7c b21d8830
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -53,11 +53,12 @@ bool is_hal_offloading() {
}

// Initialize BluetoothAudio HAL: openProvider
bool init(bluetooth::common::MessageLoopThread* message_loop) {
bool init(bluetooth::common::MessageLoopThread* message_loop,
          bluetooth::audio::a2dp::BluetoothAudioPort const* audio_port, bool offload_enabled) {
  if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
    return hidl::a2dp::init(message_loop);
    return hidl::a2dp::init(message_loop, audio_port, offload_enabled);
  }
  return aidl::a2dp::init(message_loop);
  return aidl::a2dp::init(message_loop, audio_port, offload_enabled);
}

// Clean up BluetoothAudio HAL
+21 −2
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ namespace audio {
namespace a2dp {

/// Loosely copied after the definition from the Bluetooth Audio interface:
/// hardware/interfaces/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
/// audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
enum class BluetoothAudioStatus {
  SUCCESS = 0,
  UNKNOWN,
@@ -40,6 +40,24 @@ enum class BluetoothAudioStatus {
  PENDING,
};

/// Loosely copied after the definition from the Bluetooth Audio interface:
/// audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
///
/// Implements callbacks for the BT Audio HAL to start, suspend and configure
/// the audio stream. Completion of the requested operation is indicated
/// by the methods ack_stream_started, ack_stream_suspended.
class BluetoothAudioPort {
public:
  virtual ~BluetoothAudioPort() {}
  virtual BluetoothAudioStatus StartStream(bool /*low_latency*/) const {
    return BluetoothAudioStatus::FAILURE;
  }
  virtual BluetoothAudioStatus SuspendStream() const { return BluetoothAudioStatus::FAILURE; }
  virtual BluetoothAudioStatus SetLatencyMode(bool /*low_latency*/) const {
    return BluetoothAudioStatus::FAILURE;
  }
};

bool update_codec_offloading_capabilities(
        const std::vector<btav_a2dp_codec_config_t>& framework_preference,
        bool supports_a2dp_hw_offload_v2);
@@ -51,7 +69,8 @@ bool is_hal_enabled();
bool is_hal_offloading();

// Initialize BluetoothAudio HAL: openProvider
bool init(bluetooth::common::MessageLoopThread* message_loop);
bool init(bluetooth::common::MessageLoopThread* message_loop, BluetoothAudioPort const* audio_port,
          bool offload_enabled);

// Clean up BluetoothAudio HAL
void cleanup();
+7 −1
Original line number Diff line number Diff line
@@ -227,12 +227,17 @@ bool is_hal_enabled() { return true; }
// Check if new bluetooth_audio is running with offloading encoders
bool is_hal_offloading() { return false; }

static BluetoothAudioPort null_audio_port;
static BluetoothAudioPort const* bluetooth_audio_port = &null_audio_port;

// Initialize BluetoothAudio HAL: openProvider
bool init(bluetooth::common::MessageLoopThread* message_loop) {
bool init(bluetooth::common::MessageLoopThread* message_loop, BluetoothAudioPort const* audio_port,
          bool /*offload_enabled*/) {
  a2dp_uipc = UIPC_Init();
  total_bytes_read_ = 0;
  data_position_ = {};
  remote_delay_report_ = 0;
  bluetooth_audio_port = audio_port;

  return true;
}
@@ -240,6 +245,7 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) {
// Clean up BluetoothAudio HAL
void cleanup() {
  end_session();
  bluetooth_audio_port = &null_audio_port;

  if (a2dp_uipc != nullptr) {
    UIPC_Close(*a2dp_uipc, UIPC_CH_ID_ALL);
+59 −86
Original line number Diff line number Diff line
@@ -25,9 +25,6 @@
#include "a2dp_provider_info.h"
#include "a2dp_transport.h"
#include "audio_aidl_interfaces.h"
#include "bta/av/bta_av_int.h"
#include "btif/include/btif_common.h"
#include "btm_iso_api.h"
#include "codec_status_aidl.h"
#include "transport_instance.h"

@@ -45,8 +42,12 @@ namespace audio {
namespace aidl {
namespace a2dp {

using ::bluetooth::audio::a2dp::BluetoothAudioPort;
using ::bluetooth::audio::a2dp::BluetoothAudioStatus;

static BluetoothAudioPort null_audio_port;
static BluetoothAudioPort const* bluetooth_audio_port_ = &null_audio_port;

namespace {

using ::aidl::android::hardware::bluetooth::audio::A2dpStreamConfiguration;
@@ -67,6 +68,21 @@ using ::bluetooth::audio::aidl::codec::A2dpLdacToHalConfig;
using ::bluetooth::audio::aidl::codec::A2dpOpusToHalConfig;
using ::bluetooth::audio::aidl::codec::A2dpSbcToHalConfig;

static BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(BluetoothAudioStatus ack) {
  switch (ack) {
    case BluetoothAudioStatus::SUCCESS:
      return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
    case BluetoothAudioStatus::PENDING:
      return BluetoothAudioCtrlAck::PENDING;
    case BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION:
      return BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED;
    case BluetoothAudioStatus::UNKNOWN:
    case BluetoothAudioStatus::FAILURE:
    default:
      return BluetoothAudioCtrlAck::FAILURE;
  }
}

/***
 *
 * A2dpTransport functions and variables
@@ -74,6 +90,7 @@ using ::bluetooth::audio::aidl::codec::A2dpSbcToHalConfig;
 ***/

tA2DP_CTRL_CMD A2dpTransport::a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;

uint16_t A2dpTransport::remote_delay_report_ = 0;

A2dpTransport::A2dpTransport(SessionType sessionType)
@@ -85,92 +102,59 @@ A2dpTransport::A2dpTransport(SessionType sessionType)
}

BluetoothAudioCtrlAck A2dpTransport::StartRequest(bool is_low_latency) {
  // Check if a previous request is not finished
  // Check if a previous Start request is ongoing.
  if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
    log::info("A2DP_CTRL_CMD_START in progress");
    log::warn("unable to start stream: already pending");
    return BluetoothAudioCtrlAck::PENDING;
  } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
    log::warn("busy in pending_cmd={}", a2dp_pending_cmd_);
    return BluetoothAudioCtrlAck::FAILURE;
  }

  // Don't send START request to stack while we are in a call
  if (!bluetooth::headset::IsCallIdle()) {
    log::error("call state is busy");
    return BluetoothAudioCtrlAck::FAILURE_BUSY;
  }

  if (com::android::bluetooth::flags::a2dp_check_lea_iso_channel()) {
    // Don't send START request to stack while LEA sessions are in use
    if (hci::IsoManager::GetInstance()->GetNumberOfActiveIso() > 0) {
      log::error("LEA currently has active ISO channels");
  // Check if a different request is ongoing.
  if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
    log::warn("unable to start stream: busy with pending command {}", a2dp_pending_cmd_);
    return BluetoothAudioCtrlAck::FAILURE;
  }
  }

  if (btif_av_stream_started_ready(A2dpType::kSource)) {
    // Already started, ACK back immediately.
    return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
  }
  if (btif_av_stream_ready(A2dpType::kSource)) {
    // check if codec needs to be switched prior to stream start
    invoke_switch_codec_cb(is_low_latency);
    /*
     * Post start event and wait for audio path to open.
     * If we are the source, the ACK will be sent after the start
     * procedure is completed, othewise send it now.
     */
    a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
    btif_av_stream_start_with_latency(is_low_latency);
    if (btif_av_get_peer_sep(A2dpType::kSource) != AVDT_TSEP_SRC) {
      log::info("accepted");
      return BluetoothAudioCtrlAck::PENDING;
    }
    a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
    return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
  }
  log::error("AV stream is not ready to start");
  return BluetoothAudioCtrlAck::FAILURE;
  log::info("");

  auto status = bluetooth_audio_port_->StartStream(is_low_latency);
  a2dp_pending_cmd_ =
          status == BluetoothAudioStatus::PENDING ? A2DP_CTRL_CMD_START : A2DP_CTRL_CMD_NONE;

  return a2dp_ack_to_bt_audio_ctrl_ack(status);
}

BluetoothAudioCtrlAck A2dpTransport::SuspendRequest() {
  // Previous request is not finished
  // Check if a previous Suspend request is ongoing.
  if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_SUSPEND) {
    log::info("A2DP_CTRL_CMD_SUSPEND in progress");
    log::warn("unable to suspend stream: already pending");
    return BluetoothAudioCtrlAck::PENDING;
  } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
    log::warn("busy in pending_cmd={}", a2dp_pending_cmd_);
    return BluetoothAudioCtrlAck::FAILURE;
  }
  // Local suspend
  if (btif_av_stream_started_ready(A2dpType::kSource)) {
    log::info("accepted");
    a2dp_pending_cmd_ = A2DP_CTRL_CMD_SUSPEND;
    btif_av_stream_suspend();
    return BluetoothAudioCtrlAck::PENDING;

  // Check if a different request is ongoing.
  if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
    log::warn("unable to suspend stream: busy with pending command {}", a2dp_pending_cmd_);
    return BluetoothAudioCtrlAck::FAILURE;
  }
  /* If we are not in started state, just ack back ok and let
   * audioflinger close the channel. This can happen if we are
   * remotely suspended, clear REMOTE SUSPEND flag.
   */
  btif_av_clear_remote_suspend_flag(A2dpType::kSource);
  return BluetoothAudioCtrlAck::SUCCESS_FINISHED;

  log::info("");

  auto status = bluetooth_audio_port_->SuspendStream();
  a2dp_pending_cmd_ =
          status == BluetoothAudioStatus::PENDING ? A2DP_CTRL_CMD_SUSPEND : A2DP_CTRL_CMD_NONE;

  return a2dp_ack_to_bt_audio_ctrl_ack(status);
}

void A2dpTransport::StopRequest() {
  if (btif_av_get_peer_sep(A2dpType::kSource) == AVDT_TSEP_SNK &&
      !btif_av_stream_started_ready(A2dpType::kSource)) {
    btif_av_clear_remote_suspend_flag(A2dpType::kSource);
    return;
  }
  log::info("handling");
  a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
  btif_av_stream_stop(RawAddress::kEmpty);
  log::info("");

  auto status = bluetooth_audio_port_->SuspendStream();
  a2dp_pending_cmd_ =
          status == BluetoothAudioStatus::PENDING ? A2DP_CTRL_CMD_STOP : A2DP_CTRL_CMD_NONE;
}

void A2dpTransport::SetLatencyMode(LatencyMode latency_mode) {
  bool is_low_latency = latency_mode == LatencyMode::LOW_LATENCY ? true : false;
  btif_av_set_low_latency(is_low_latency);
  bluetooth_audio_port_->SetLatencyMode(latency_mode == LatencyMode::LOW_LATENCY);
}

bool A2dpTransport::GetPresentationPosition(uint64_t* remote_delay_report_ns,
@@ -239,21 +223,6 @@ uint16_t remote_delay = 0;

bool is_low_latency_mode_allowed = false;

static BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(BluetoothAudioStatus ack) {
  switch (ack) {
    case BluetoothAudioStatus::SUCCESS:
      return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
    case BluetoothAudioStatus::PENDING:
      return BluetoothAudioCtrlAck::PENDING;
    case BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION:
      return BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED;
    case BluetoothAudioStatus::UNKNOWN:
    case BluetoothAudioStatus::FAILURE:
    default:
      return BluetoothAudioCtrlAck::FAILURE;
  }
}

bool a2dp_get_selected_hal_codec_config(A2dpCodecConfig* a2dp_config, uint16_t peer_mtu,
                                        CodecConfiguration* codec_config) {
  btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
@@ -376,8 +345,10 @@ static void delete_hal_interface(BluetoothAudioSinkClientInterface* hal_interfac
}

// Initialize BluetoothAudio HAL: openProvider
bool init(bluetooth::common::MessageLoopThread* /*message_loop*/) {
bool init(bluetooth::common::MessageLoopThread* /*message_loop*/,
          BluetoothAudioPort const* audio_port, bool offload_enabled) {
  log::info("");
  log::assert_that(audio_port != nullptr, "audio_port != nullptr");

  if (software_hal_interface != nullptr) {
    return true;
@@ -393,7 +364,7 @@ bool init(bluetooth::common::MessageLoopThread* /*message_loop*/) {
    return false;
  }

  if (btif_av_is_a2dp_offload_enabled() && offloading_hal_interface == nullptr) {
  if (offload_enabled && offloading_hal_interface == nullptr) {
    offloading_hal_interface =
            new_hal_interface(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
    if (offloading_hal_interface == nullptr) {
@@ -403,6 +374,7 @@ bool init(bluetooth::common::MessageLoopThread* /*message_loop*/) {
    }
  }

  bluetooth_audio_port_ = audio_port;
  active_hal_interface =
          (offloading_hal_interface != nullptr ? offloading_hal_interface : software_hal_interface);

@@ -438,6 +410,7 @@ void cleanup() {
    delete a2dp_sink;
  }

  bluetooth_audio_port_ = &null_audio_port;
  remote_delay = 0;
}

+2 −5
Original line number Diff line number Diff line
@@ -20,10 +20,6 @@

#include "a2dp_encoding.h"
#include "a2dp_sbc_constants.h"
#include "btif/include/btif_a2dp_source.h"
#include "btif/include/btif_av.h"
#include "btif/include/btif_av_co.h"
#include "btif/include/btif_hf.h"
#include "common/message_loop_thread.h"
#include "hardware/bt_av.h"
#include "os/log.h"
@@ -52,7 +48,8 @@ bool is_hal_offloading();
/***
 * Initialize BluetoothAudio HAL: openProvider
 ***/
bool init(bluetooth::common::MessageLoopThread* message_loop);
bool init(bluetooth::common::MessageLoopThread* message_loop,
          bluetooth::audio::a2dp::BluetoothAudioPort const* audio_port, bool offload_enabled);

/***
 * Clean up BluetoothAudio HAL
Loading