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

Commit 6894b364 authored by Jeremy Wu's avatar Jeremy Wu Committed by Gerrit Code Review
Browse files

Merge changes I801f5baa,I5b19e763,Ib644c143,I96523646,Idd0cd9aa, ... into main

* changes:
  HfpClientInterface: implement UpdateAudioConfigToHal
  HfpClientInterface: always ack on |*StreamingRequest|
  HfpClientInterface: fix decoder client suspend
  StopWatchLegacy: fix OOB array access in |RecordLog|
  bta_ag_sco: Init and start HFP SW encode/decode
  bta_ag_sco: add mock files and funcs for tests
parents 9cccf3f8 a56cd183
Loading
Loading
Loading
Loading
+45 −13
Original line number Diff line number Diff line
@@ -97,6 +97,12 @@ AudioConfiguration offload_config_to_hal_audio_config(const ::hfp::offload_confi
  return AudioConfiguration(hfp_config);
}

AudioConfiguration pcm_config_to_hal_audio_config(const ::hfp::pcm_config& pcm_config) {
  PcmConfiguration config = get_default_pcm_configuration();
  config.sampleRateHz = pcm_config.sample_rate_hz;
  return AudioConfiguration(config);
}

bool is_aidl_support_hfp() {
  return HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL &&
         HalVersionManager::GetHalVersion() >= BluetoothAudioHalVersion::VERSION_AIDL_V4;
@@ -157,14 +163,24 @@ void HfpClientInterface::Decode::StopSession() {

void HfpClientInterface::Decode::UpdateAudioConfigToHal(
        const ::hfp::offload_config& offload_config) {
  log::warn(
          "'UpdateAudioConfigToHal(offload_config)' should not be called on "
          "HfpClientInterface::Decode");
}

void HfpClientInterface::Decode::UpdateAudioConfigToHal(const ::hfp::pcm_config& pcm_config) {
  if (!is_aidl_support_hfp()) {
    log::warn("Unsupported HIDL or AIDL version");
    return;
  }

  log::warn("decode - Unsupported update audio config for software session");
  log::info("decode");
  if (!get_decode_client_interface()->UpdateAudioConfig(
              pcm_config_to_hal_audio_config(pcm_config))) {
    log::error("cannot update audio config to HAL");
    return;
  }
}

size_t HfpClientInterface::Decode::Write(const uint8_t* p_buf, uint32_t len) {
  if (!is_aidl_support_hfp()) {
@@ -179,14 +195,14 @@ void HfpClientInterface::Decode::ConfirmStreamingRequest() {
  auto instance = aidl::hfp::HfpDecodingTransport::instance_;
  auto pending_cmd = instance->GetPendingCmd();
  switch (pending_cmd) {
    case aidl::hfp::HFP_CTRL_CMD_NONE:
      log::warn("no pending start stream request");
      FALLTHROUGH_INTENDED;
    case aidl::hfp::HFP_CTRL_CMD_START:
      aidl::hfp::HfpDecodingTransport::software_hal_interface->StreamStarted(
              aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
      instance->ResetPendingCmd();
      return;
    case aidl::hfp::HFP_CTRL_CMD_NONE:
      log::warn("no pending start stream request");
      return;
    default:
      log::warn("Invalid state, {}", pending_cmd);
  }
@@ -203,10 +219,10 @@ void HfpClientInterface::Decode::CancelStreamingRequest() {
      return;
    case aidl::hfp::HFP_CTRL_CMD_NONE:
      log::warn("no pending start stream request");
      return;
      FALLTHROUGH_INTENDED;
    case aidl::hfp::HFP_CTRL_CMD_SUSPEND:
      log::info("suspends");
      aidl::hfp::HfpEncodingTransport::software_hal_interface->StreamSuspended(
      aidl::hfp::HfpDecodingTransport::software_hal_interface->StreamSuspended(
              aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
      instance->ResetPendingCmd();
      return;
@@ -308,14 +324,24 @@ void HfpClientInterface::Encode::StopSession() {

void HfpClientInterface::Encode::UpdateAudioConfigToHal(
        const ::hfp::offload_config& offload_config) {
  log::warn(
          "'UpdateAudioConfigToHal(offload_config)' should not be called on "
          "HfpClientInterface::Encode");
}

void HfpClientInterface::Encode::UpdateAudioConfigToHal(const ::hfp::pcm_config& pcm_config) {
  if (!is_aidl_support_hfp()) {
    log::warn("Unsupported HIDL or AIDL version");
    return;
  }

  log::warn("encode - Unsupported update audio config for software session");
  log::info("encode");
  if (!get_encode_client_interface()->UpdateAudioConfig(
              pcm_config_to_hal_audio_config(pcm_config))) {
    log::error("cannot update audio config to HAL");
    return;
  }
}

size_t HfpClientInterface::Encode::Read(uint8_t* p_buf, uint32_t len) {
  if (!is_aidl_support_hfp()) {
@@ -330,14 +356,14 @@ void HfpClientInterface::Encode::ConfirmStreamingRequest() {
  auto instance = aidl::hfp::HfpEncodingTransport::instance_;
  auto pending_cmd = instance->GetPendingCmd();
  switch (pending_cmd) {
    case aidl::hfp::HFP_CTRL_CMD_NONE:
      log::warn("no pending start stream request");
      FALLTHROUGH_INTENDED;
    case aidl::hfp::HFP_CTRL_CMD_START:
      aidl::hfp::HfpEncodingTransport::software_hal_interface->StreamStarted(
              aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
      instance->ResetPendingCmd();
      return;
    case aidl::hfp::HFP_CTRL_CMD_NONE:
      log::warn("no pending start stream request");
      return;
    default:
      log::warn("Invalid state, {}", pending_cmd);
  }
@@ -354,7 +380,7 @@ void HfpClientInterface::Encode::CancelStreamingRequest() {
      return;
    case aidl::hfp::HFP_CTRL_CMD_NONE:
      log::warn("no pending start stream request");
      return;
      FALLTHROUGH_INTENDED;
    case aidl::hfp::HFP_CTRL_CMD_SUSPEND:
      log::info("suspends");
      aidl::hfp::HfpEncodingTransport::software_hal_interface->StreamSuspended(
@@ -469,6 +495,12 @@ void HfpClientInterface::Offload::UpdateAudioConfigToHal(
          offload_config_to_hal_audio_config(offload_config));
}

void HfpClientInterface::Offload::UpdateAudioConfigToHal(const ::hfp::pcm_config& pcm_config) {
  log::warn(
          "'UpdateAudioConfigToHal(pcm_config)' should not be called on "
          "HfpClientInterface::Offload");
}

void HfpClientInterface::Offload::ConfirmStreamingRequest() {
  auto instance = aidl::hfp::HfpEncodingTransport::instance_;
  auto pending_cmd = instance->GetPendingCmd();
+4 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ private:
    virtual void StartSession() = 0;
    virtual void StopSession() = 0;
    virtual void UpdateAudioConfigToHal(const ::hfp::offload_config& config) = 0;
    virtual void UpdateAudioConfigToHal(const ::hfp::pcm_config& config) = 0;
    virtual void ConfirmStreamingRequest() = 0;
    virtual void CancelStreamingRequest() = 0;
  };
@@ -50,6 +51,7 @@ public:
    void StartSession() override;
    void StopSession() override;
    void UpdateAudioConfigToHal(const ::hfp::offload_config& config) override;
    void UpdateAudioConfigToHal(const ::hfp::pcm_config& config) override;
    void ConfirmStreamingRequest() override;
    void CancelStreamingRequest() override;
    size_t Write(const uint8_t* p_buf, uint32_t len);
@@ -63,6 +65,7 @@ public:
    void StartSession() override;
    void StopSession() override;
    void UpdateAudioConfigToHal(const ::hfp::offload_config& config) override;
    void UpdateAudioConfigToHal(const ::hfp::pcm_config& config) override;
    void ConfirmStreamingRequest() override;
    void CancelStreamingRequest() override;
    size_t Read(uint8_t* p_buf, uint32_t len);
@@ -76,6 +79,7 @@ public:
    void StartSession() override;
    void StopSession() override;
    void UpdateAudioConfigToHal(const ::hfp::offload_config& config) override;
    void UpdateAudioConfigToHal(const ::hfp::pcm_config& config) override;
    void ConfirmStreamingRequest() override;
    void CancelStreamingRequest() override;
    std::unordered_map<tBTA_AG_UUID_CODEC, ::hfp::sco_config> GetHfpScoConfig();
+3 −0
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@ HfpClientInterface::Offload::GetHfpScoConfig() {
  return std::unordered_map<tBTA_AG_UUID_CODEC, ::hfp::sco_config>();
}

size_t HfpClientInterface::Encode::Read(uint8_t* p_buf, uint32_t len) { return 0; }

size_t HfpClientInterface::Decode::Write(const uint8_t* p_buf, uint32_t len) { return 0; }
}  // namespace hfp
}  // namespace audio
}  // namespace bluetooth
+2 −0
Original line number Diff line number Diff line
@@ -445,6 +445,8 @@ void bta_ag_result(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
void bta_ag_setcodec(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
void bta_ag_send_ring(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
void bta_ag_handle_collision(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data);
size_t bta_ag_sco_write(const uint8_t* p_buf, uint32_t len);
size_t bta_ag_sco_read(uint8_t* p_buf, uint32_t len);

/* Internal utility functions */
void bta_ag_sco_codec_nego(tBTA_AG_SCB* p_scb, bool result);
+141 −25
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@

#include "audio_hal_interface/hfp_client_interface.h"
#include "bta/ag/bta_ag_int.h"
#include "bta_ag_swb_aptx.h"
#include "bta/include/bta_ag_swb_aptx.h"
#include "btm_status.h"
#include "hci/controller_interface.h"
#include "internal_include/bt_target.h"
@@ -63,9 +63,12 @@ using namespace bluetooth;
              HCI_AIR_CODING_FORMAT_TRANSPNT))

static bool sco_allowed = true;
static bool hfp_software_datapath_enabled = false;
static RawAddress active_device_addr = {};
static std::unique_ptr<HfpInterface> hfp_client_interface;
static std::unique_ptr<HfpInterface::Offload> hfp_offload_interface;
static std::unique_ptr<HfpInterface::Encode> hfp_encode_interface;
static std::unique_ptr<HfpInterface::Decode> hfp_decode_interface;
static std::unordered_map<tBTA_AG_UUID_CODEC, ::hfp::sco_config> sco_config_map;
static std::unordered_map<tBTA_AG_UUID_CODEC, esco_coding_format_t> codec_coding_format_map{
        {tBTA_AG_UUID_CODEC::UUID_CODEC_LC3, ESCO_CODING_FORMAT_LC3},
@@ -124,6 +127,22 @@ static const char* bta_ag_sco_state_str(uint8_t state) {
  }
}

static int codec_uuid_to_sample_rate(tBTA_AG_UUID_CODEC codec) {
  int sample_rate;
  switch (codec) {
    case tBTA_AG_UUID_CODEC::UUID_CODEC_LC3:
      sample_rate = 32000;
      break;
    case tBTA_AG_UUID_CODEC::UUID_CODEC_MSBC:
      sample_rate = 16000;
      break;
    case tBTA_AG_UUID_CODEC::UUID_CODEC_CVSD:
    default:
      sample_rate = 8000;
  }
  return sample_rate;
}

/**
 * Check if bd_addr is the current active device.
 *
@@ -282,10 +301,17 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
      } else {
        log::error("eSCO/SCO failed to open, no more fall back");
        if (bta_ag_is_sco_managed_by_audio()) {
          if (hfp_software_datapath_enabled) {
            if (hfp_encode_interface) {
              hfp_encode_interface->CancelStreamingRequest();
              hfp_decode_interface->CancelStreamingRequest();
            }
          } else {
            hfp_offload_interface->CancelStreamingRequest();
          }
        }
      }
    }

    bta_ag_cb.sco.p_curr_scb->inuse_codec = tBTA_AG_UUID_CODEC::UUID_CODEC_NONE;

@@ -1359,6 +1385,40 @@ void bta_ag_sco_shutdown(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& /* data */) {
  bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E);
}

/*******************************************************************************
 *
 * Function         bta_ag_sco_write
 *
 * Description      Writes bytes to decoder interface
 *
 *
 * Returns          Number of bytes written
 *
 ******************************************************************************/
size_t bta_ag_sco_write(const uint8_t* p_buf, uint32_t len) {
  if (hfp_software_datapath_enabled && hfp_decode_interface) {
    return hfp_decode_interface->Write(p_buf, len);
  }
  return 0;
}

/*******************************************************************************
 *
 * Function         bta_ag_sco_read
 *
 * Description      Reads bytes from encoder interface
 *
 *
 * Returns          Number of bytes read
 *
 ******************************************************************************/
size_t bta_ag_sco_read(uint8_t* p_buf, uint32_t len) {
  if (hfp_software_datapath_enabled && hfp_encode_interface) {
    return hfp_encode_interface->Read(p_buf, len);
  }
  return 0;
}

/*******************************************************************************
 *
 * Function         bta_ag_sco_conn_open
@@ -1382,17 +1442,34 @@ void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& /* data */) {
      is_controller_codec = sco_config_map[p_scb->inuse_codec].useControllerCodec;
    }

    if (hfp_software_datapath_enabled) {
      if (hfp_encode_interface) {
        int sample_rate = codec_uuid_to_sample_rate(p_scb->inuse_codec);
        hfp::pcm_config config{.sample_rate_hz = sample_rate};
        hfp_encode_interface->UpdateAudioConfigToHal(config);
        hfp_decode_interface->UpdateAudioConfigToHal(config);
      }
    } else {
      hfp::offload_config config{
              .sco_codec = p_scb->inuse_codec,
              .connection_handle = p_scb->conn_handle,
              .is_controller_codec = is_controller_codec,
              .is_nrec = p_scb->nrec_enabled,
      };

      hfp_offload_interface->UpdateAudioConfigToHal(config);
    }

    // ConfirmStreamingRequest before sends callback to java layer
    if (hfp_software_datapath_enabled) {
      if (hfp_encode_interface) {
        hfp_encode_interface->ConfirmStreamingRequest();
        hfp_decode_interface->ConfirmStreamingRequest();
      }
    } else {
      hfp_offload_interface->ConfirmStreamingRequest();
    }
  }

  /* call app callback */
  bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
@@ -1549,20 +1626,36 @@ bool bta_ag_is_sco_managed_by_audio() {
}

void bta_ag_stream_suspended() {
  if (bta_ag_is_sco_managed_by_audio() && hfp_offload_interface) {
  if (bta_ag_is_sco_managed_by_audio()) {
    if (hfp_software_datapath_enabled) {
      if (hfp_encode_interface) {
        hfp_encode_interface->CancelStreamingRequest();
        hfp_decode_interface->CancelStreamingRequest();
      }
    } else {
      if (hfp_offload_interface) {
        hfp_offload_interface->CancelStreamingRequest();
      }
    }
  }
}

const RawAddress& bta_ag_get_active_device() { return active_device_addr; }

void bta_clear_active_device() {
  log::debug("Set bta active device to null, current active device:{}", active_device_addr);
  if (bta_ag_is_sco_managed_by_audio()) {
    if (hfp_software_datapath_enabled) {
      if (hfp_encode_interface && !active_device_addr.IsEmpty()) {
        hfp_encode_interface->StopSession();
        hfp_decode_interface->StopSession();
      }
    } else {
      if (hfp_offload_interface && !active_device_addr.IsEmpty()) {
        hfp_offload_interface->StopSession();
      }
    }
  }
  active_device_addr = RawAddress::kEmpty;
}

@@ -1574,13 +1667,35 @@ void bta_ag_api_set_active_device(const RawAddress& new_active_device) {
  }

  if (bta_ag_is_sco_managed_by_audio()) {
    // Initialize and start HFP software data path
    if (!hfp_client_interface) {
      hfp_client_interface = std::unique_ptr<HfpInterface>(HfpInterface::Get());
      if (!hfp_client_interface) {
        log::error("could not acquire audio source interface");
      }
    }
    hfp_software_datapath_enabled =
            osi_property_get_bool("bluetooth.hfp.software_datapath.enabled", false);

    // Initialize and start HFP software datapath if enabled
    if (hfp_software_datapath_enabled) {
      if (hfp_client_interface && !hfp_encode_interface && !hfp_decode_interface) {
        hfp_encode_interface = std::unique_ptr<HfpInterface::Encode>(
                hfp_client_interface->GetEncode(get_main_thread()));
        hfp_decode_interface = std::unique_ptr<HfpInterface::Decode>(
                hfp_client_interface->GetDecode(get_main_thread()));
        if (!hfp_encode_interface || !hfp_decode_interface) {
          log::warn("could not get HFP SW interface");
        }
      }

      if (hfp_encode_interface && hfp_decode_interface) {
        if (active_device_addr.IsEmpty()) {
          hfp_encode_interface->StartSession();
          hfp_decode_interface->StartSession();
        }
      }
    } else {  // Initialize and start HFP offloading
      if (hfp_client_interface && !hfp_offload_interface) {
        hfp_offload_interface = std::unique_ptr<HfpInterface::Offload>(
                hfp_client_interface->GetOffload(get_main_thread()));
@@ -1597,5 +1712,6 @@ void bta_ag_api_set_active_device(const RawAddress& new_active_device) {
        }
      }
    }
  }
  active_device_addr = new_active_device;
}
Loading