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

Commit 66c40119 authored by Hsin-yu Chao's avatar Hsin-yu Chao Committed by Jeremy Wu
Browse files

bta_ag_sco: Init and start HFP SW encode/decode

Add HFP encode/decode interface if property
bluetooth.hfp.software_datapath.enabled is set.

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

Change-Id: Idd0cd9aacc9fc121f21c2160f41c69c64298a530
parent 71558ba4
Loading
Loading
Loading
Loading
+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);
+115 −18
Original line number Diff line number Diff line
@@ -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},
@@ -282,10 +285,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 +1369,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
@@ -1388,11 +1432,25 @@ void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& /* data */) {
            .is_controller_codec = is_controller_codec,
            .is_nrec = p_scb->nrec_enabled,
    };
    if (hfp_software_datapath_enabled) {
      if (hfp_encode_interface) {
        hfp_encode_interface->UpdateAudioConfigToHal(config);
        hfp_decode_interface->UpdateAudioConfigToHal(config);
      }
    } else {
      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 +1607,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 +1648,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 +1693,6 @@ void bta_ag_api_set_active_device(const RawAddress& new_active_device) {
        }
      }
    }
  }
  active_device_addr = new_active_device;
}
+1 −0
Original line number Diff line number Diff line
@@ -203,6 +203,7 @@ cc_library_static {
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/bta/ag",
        "packages/modules/Bluetooth/system/bta/include",
        "packages/modules/Bluetooth/system/bta/sys",
        "packages/modules/Bluetooth/system/gd",
+3 −10
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <cfloat>
#include <memory>

#include "bta/ag/bta_ag_int.h"
#include "btif/include/core_callbacks.h"
#include "btif/include/stack_manager_t.h"
#include "os/log.h"
@@ -144,17 +145,9 @@ size_t write(const uint8_t* p_buf, uint32_t len) {
void open() {}
void cleanup() {}

size_t read(uint8_t* p_buf, uint32_t len) {
  (void)p_buf;
  (void)len;
  return 0;
}
size_t read(uint8_t* p_buf, uint32_t len) { return bta_ag_sco_read(p_buf, len); }

size_t write(const uint8_t* p_buf, uint32_t len) {
  (void)p_buf;
  (void)len;
  return 0;
}
size_t write(const uint8_t* p_buf, uint32_t len) { return bta_ag_sco_write(p_buf, len); }
#endif

enum decode_buf_state {