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

Commit a56cd183 authored by Jeremy Wu's avatar Jeremy Wu
Browse files

HfpClientInterface: implement UpdateAudioConfigToHal

This CL implements the function that allows updating audio config
(specifically, to account for codec change in HFP) for SW path.

Test: m com.google.android.btservices
Bug: 349290628
Bug: 315234036
Flag: com::android::bluetooth::flags::is_sco_managed_by_audio and HFP
and bluetooth.hfp.software_datapath.enabled

Change-Id: I801f5baabc5fef9081650336a52a194b3235de0e
parent f1a650c7
Loading
Loading
Loading
Loading
+36 −4
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()) {
@@ -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()) {
@@ -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();
+25 −6
Original line number Diff line number Diff line
@@ -127,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.
 *
@@ -1426,18 +1442,21 @@ 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;
    }

    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,
    };
    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);
    }

+10 −1
Original line number Diff line number Diff line
@@ -293,9 +293,9 @@ typedef uint16_t tBTA_AG_PEER_CODEC;
#define BTA_AG_AT_MAX_LEN 256
#endif

// Define hfp offload config structure
namespace hfp {

// Define hfp offload config structure
struct offload_config {
  tBTA_AG_UUID_CODEC sco_codec;
  int32_t connection_handle;
@@ -303,6 +303,15 @@ struct offload_config {
  bool is_nrec;
};

// Define hfp pcm config structure
struct pcm_config {
  int sample_rate_hz;
  // The below fields are always fixed
  // int channel_mode = ChannelMode::MONO;
  // uint8_t bits_per_sample = 16;
  // int data_interval_us = 7500;
};

struct sco_config {
  int inputDataPath;
  int outputDataPath;