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

Commit bac3500e authored by Henri Chataing's avatar Henri Chataing Committed by Automerger Merge Worker
Browse files

Merge changes Iaab0a019,Ifb94fae4,Id8df92b3,I29abee42,I5e195cbc, ... into main am: 1ae34a89

parents df5ad0f8 1ae34a89
Loading
Loading
Loading
Loading
+16 −18
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ static struct {
} android_bluetooth_BluetoothCodecConfig;

static const btav_source_interface_t* sBluetoothA2dpInterface = nullptr;
static std::vector<btav_a2dp_codec_info_t> supported_codecs;
static std::shared_timed_mutex interface_mutex;

static jobject mCallbacksObj = nullptr;
@@ -296,7 +297,7 @@ static void initNative(JNIEnv* env, jobject object,

  bt_status_t status = sBluetoothA2dpInterface->init(
      &sBluetoothA2dpCallbacks, maxConnectedAudioDevices, codec_priorities,
      codec_offloading);
      codec_offloading, &supported_codecs);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("%s: Failed to initialize Bluetooth A2DP, status: %d", __func__,
          status);
@@ -340,34 +341,31 @@ static jobjectArray getSupportedCodecTypesNative(JNIEnv* env) {
    return nullptr;
  }

  jmethodID createFromType = env->GetStaticMethodID(
      android_bluetooth_BluetoothCodecType_clazz, "createFromType",
      "(I)Landroid/bluetooth/BluetoothCodecType;");
  if (createFromType == nullptr) {
    ALOGE(
        "%s: Failed to find method createFromType of BluetoothCodecType class",
  jmethodID init = env->GetMethodID(android_bluetooth_BluetoothCodecType_clazz,
                                    "<init>", "(IJLjava/lang/String;)V");

  if (init == nullptr) {
    ALOGE("%s: Failed to find method <init> of BluetoothCodecType class",
          __func__);
    return nullptr;
  }

  std::array<btav_a2dp_codec_index_t, 6> default_supported_codecs = {
      BTAV_A2DP_CODEC_INDEX_SOURCE_SBC,  BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
      BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD,
      BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC, BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS,
  };
  jobjectArray result =
      env->NewObjectArray(default_supported_codecs.size(),
      env->NewObjectArray(supported_codecs.size(),
                          android_bluetooth_BluetoothCodecType_clazz, nullptr);

  if (result == nullptr) {
    ALOGE("%s: Failed to allocate result array of BluetoothCodecType",
          __func__);
    return nullptr;
  }

  for (size_t index = 0; index < default_supported_codecs.size(); index++) {
    jobject codec_type = env->CallStaticObjectMethod(
        android_bluetooth_BluetoothCodecType_clazz, createFromType,
        (jint)default_supported_codecs[index]);
  for (size_t index = 0; index < supported_codecs.size(); index++) {
    jobject codec_type = env->NewObject(
        android_bluetooth_BluetoothCodecType_clazz, init,
        (jint)supported_codecs[index].codec_type,
        (jlong)supported_codecs[index].codec_id,
        env->NewStringUTF(supported_codecs[index].codec_name.c_str()));
    env->SetObjectArrayElement(result, index, codec_type);
  }

+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ cc_library_static {
                "aidl/hearing_aid_software_encoding_aidl.cc",
                "aidl/hfp_client_interface_aidl.cc",
                "aidl/le_audio_software_aidl.cc",
                "aidl/provider_info.cc",
                "hal_version_manager.cc",
                "hearing_aid_software_encoding.cc",
                "hfp_client_interface.cc",
+87 −0
Original line number Diff line number Diff line
@@ -155,6 +155,93 @@ bool is_opus_supported() {
  return false;
}

namespace provider {

// Lookup the codec info in the list of supported offloaded sink codecs.
std::optional<btav_a2dp_codec_index_t> sink_codec_index(
    const uint8_t* p_codec_info) {
  return (HalVersionManager::GetHalTransport() ==
          BluetoothAudioHalTransport::AIDL)
             ? aidl::a2dp::provider::sink_codec_index(p_codec_info)
             : std::nullopt;
}

// Lookup the codec info in the list of supported offloaded source codecs.
std::optional<btav_a2dp_codec_index_t> source_codec_index(
    const uint8_t* p_codec_info) {
  return (HalVersionManager::GetHalTransport() ==
          BluetoothAudioHalTransport::AIDL)
             ? aidl::a2dp::provider::source_codec_index(p_codec_info)
             : std::nullopt;
}

// Return the name of the codec which is assigned to the input index.
// The codec index must be in the ranges
// BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or
// BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX.
// Returns nullopt if the codec_index is not assigned or codec extensibility
// is not supported or enabled.
std::optional<const char*> codec_index_str(
    btav_a2dp_codec_index_t codec_index) {
  return (HalVersionManager::GetHalTransport() ==
          BluetoothAudioHalTransport::AIDL)
             ? aidl::a2dp::provider::codec_index_str(codec_index)
             : std::nullopt;
}

// Return true if the codec is supported for the session type
// A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH.
bool supports_codec(btav_a2dp_codec_index_t codec_index) {
  return (HalVersionManager::GetHalTransport() ==
          BluetoothAudioHalTransport::AIDL)
             ? aidl::a2dp::provider::supports_codec(codec_index)
             : false;
}

// Return the A2DP capabilities for the selected codec.
bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id,
                uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) {
  return (HalVersionManager::GetHalTransport() ==
          BluetoothAudioHalTransport::AIDL)
             ? aidl::a2dp::provider::codec_info(codec_index, codec_id,
                                                codec_info, codec_config)
             : false;
}

// Query the codec selection fromt the audio HAL.
// The HAL is expected to pick the best audio configuration based on the
// discovered remote SEPs.
std::optional<a2dp_configuration> get_a2dp_configuration(
    RawAddress peer_address,
    std::vector<a2dp_remote_capabilities> const& remote_seps,
    btav_a2dp_codec_config_t const& user_preferences) {
  return (HalVersionManager::GetHalTransport() ==
          BluetoothAudioHalTransport::AIDL)
             ? aidl::a2dp::provider::get_a2dp_configuration(
                   peer_address, remote_seps, user_preferences)
             : std::nullopt;
}

// Query the codec parameters from the audio HAL.
// The HAL performs a two part validation:
//  - check if the configuration is valid
//  - check if the configuration is supported by the audio provider
// In case any of these checks fails, the corresponding A2DP
// status is returned. If the configuration is valid and supported,
// A2DP_OK is returned.
tA2DP_STATUS parse_a2dp_configuration(
    btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info,
    btav_a2dp_codec_config_t* codec_parameters,
    std::vector<uint8_t>* vendor_specific_parameters) {
  return (HalVersionManager::GetHalTransport() ==
          BluetoothAudioHalTransport::AIDL)
             ? aidl::a2dp::provider::parse_a2dp_configuration(
                   codec_index, codec_info, codec_parameters,
                   vendor_specific_parameters)
             : A2DP_FAIL;
}

}  // namespace provider
}  // namespace a2dp
}  // namespace audio
}  // namespace bluetooth
+96 −0
Original line number Diff line number Diff line
@@ -16,9 +16,13 @@

#pragma once

#include <iomanip>
#include <sstream>
#include <vector>

#include "a2dp_error_codes.h"
#include "audio_a2dp_hw/include/audio_a2dp_hw.h"
#include "avdt_api.h"
#include "common/message_loop_thread.h"

namespace bluetooth {
@@ -62,6 +66,98 @@ void set_remote_delay(uint16_t delay_report);
// Check whether OPUS is supported
bool is_opus_supported();

// Definitions for A2DP hardware offload codec extensibility.
namespace provider {

// Lookup the codec info in the list of supported offloaded sink codecs.
std::optional<btav_a2dp_codec_index_t> sink_codec_index(
    const uint8_t* p_codec_info);

// Lookup the codec info in the list of supported offloaded source codecs.
std::optional<btav_a2dp_codec_index_t> source_codec_index(
    const uint8_t* p_codec_info);

// Return the name of the codec which is assigned to the input index.
// The codec index must be in the ranges
// BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or
// BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX.
// Returns nullopt if the codec_index is not assigned or codec extensibility
// is not supported or enabled.
std::optional<const char*> codec_index_str(btav_a2dp_codec_index_t codec_index);

// Return true if the codec is supported for the session type
// A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH.
bool supports_codec(btav_a2dp_codec_index_t codec_index);

// Return the A2DP capabilities for the selected codec.
// `codec_info` returns the OTA codec capabilities, `codec_config`
// returns the supported capabilities in a generic format.
bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id,
                uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config);

struct a2dp_configuration {
  int remote_seid;
  uint8_t codec_config[AVDT_CODEC_SIZE];
  btav_a2dp_codec_config_t codec_parameters;
  std::vector<uint8_t> vendor_specific_parameters;

  inline std::string toString() const {
    std::ostringstream os;
    os << "A2dpConfiguration{";
    os << "remote_seid: " << remote_seid;
    os << ", codec_index: " << codec_parameters.codec_type;
    os << ", codec_config: {";
    for (int i = 0; i < AVDT_CODEC_SIZE; i++) {
      os << "0x" << std::hex << std::setw(2) << std::setfill('0')
         << static_cast<int>(codec_config[i]);
      if (i != AVDT_CODEC_SIZE - 1) os << ",";
    }
    os << "}";
    os << "}";
    return os.str();
  }
};

struct a2dp_remote_capabilities {
  int seid;
  uint8_t const* capabilities;

  inline std::string toString() const {
    std::ostringstream os;
    os << "A2dpRemoteCapabilities{";
    os << "seid: " << seid;
    os << ", capabilities: {";
    if (capabilities != nullptr) {
      for (int i = 0; i < AVDT_CODEC_SIZE; i++) {
        os << "0x" << std::hex << std::setw(2) << std::setfill('0')
           << static_cast<int>(capabilities[i]);
        if (i != AVDT_CODEC_SIZE - 1) os << ",";
      }
    }
    os << "}";
    os << "}";
    return os.str();
  }
};

// Query the codec selection fromt the audio HAL.
// The HAL is expected to pick the best audio configuration based on the
// discovered remote SEPs.
std::optional<a2dp_configuration> get_a2dp_configuration(
    RawAddress peer_address,
    std::vector<a2dp_remote_capabilities> const& remote_seps,
    btav_a2dp_codec_config_t const& user_preferences);

// Query the codec parameters from the audio HAL.
// The HAL is expected to parse the codec configuration
// received from the peer and decide whether accept
// the it or not.
tA2DP_STATUS parse_a2dp_configuration(
    btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info,
    btav_a2dp_codec_config_t* codec_parameters,
    std::vector<uint8_t>* vendor_specific_parameters);

}  // namespace provider
}  // namespace a2dp
}  // namespace audio
}  // namespace bluetooth
+61 −0
Original line number Diff line number Diff line
@@ -281,6 +281,67 @@ size_t read(uint8_t* p_buf, uint32_t len) {
// Check if OPUS codec is supported
bool is_opus_supported() { return true; }

namespace provider {

// Lookup the codec info in the list of supported offloaded sink codecs.
std::optional<btav_a2dp_codec_index_t> sink_codec_index(
    const uint8_t* p_codec_info) {
  return std::nullopt;
}

// Lookup the codec info in the list of supported offloaded source codecs.
std::optional<btav_a2dp_codec_index_t> source_codec_index(
    const uint8_t* p_codec_info) {
  return std::nullopt;
}

// Return the name of the codec which is assigned to the input index.
// The codec index must be in the ranges
// BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or
// BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX.
// Returns nullopt if the codec_index is not assigned or codec extensibility
// is not supported or enabled.
std::optional<const char*> codec_index_str(
    btav_a2dp_codec_index_t codec_index) {
  return std::nullopt;
}

// Return true if the codec is supported for the session type
// A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH.
bool supports_codec(btav_a2dp_codec_index_t codec_index) { return false; }

// Return the A2DP capabilities for the selected codec.
bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id,
                uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) {
  return false;
}

// Query the codec selection fromt the audio HAL.
// The HAL is expected to pick the best audio configuration based on the
// discovered remote SEPs.
std::optional<a2dp_configuration> get_a2dp_configuration(
    RawAddress peer_address,
    std::vector<a2dp_remote_capabilities> const& remote_seps,
    btav_a2dp_codec_config_t const& user_preferences) {
  return std::nullopt;
}

// Query the codec parameters from the audio HAL.
// The HAL performs a two part validation:
//  - check if the configuration is valid
//  - check if the configuration is supported by the audio provider
// In case any of these checks fails, the corresponding A2DP
// status is returned. If the configuration is valid and supported,
// A2DP_OK is returned.
tA2DP_STATUS parse_a2dp_configuration(
    btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info,
    btav_a2dp_codec_config_t* codec_parameters,
    std::vector<uint8_t>* vendor_specific_parameters) {
  return A2DP_FAIL;
}

}  // namespace provider

}  // namespace a2dp
}  // namespace audio
}  // namespace bluetooth
Loading