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

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

Merge changes Iaab0a019,Ifb94fae4,Id8df92b3,I29abee42,I5e195cbc, ... into main...

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

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/2855937



Change-Id: I62f414067e647f1e3a1547594a0760ca2671b4db
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents c8fcb49c bac3500e
Loading
Loading
Loading
Loading
+16 −18
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ static struct {
} android_bluetooth_BluetoothCodecConfig;
} android_bluetooth_BluetoothCodecConfig;


static const btav_source_interface_t* sBluetoothA2dpInterface = nullptr;
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 std::shared_timed_mutex interface_mutex;


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


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


  jmethodID createFromType = env->GetStaticMethodID(
  jmethodID init = env->GetMethodID(android_bluetooth_BluetoothCodecType_clazz,
      android_bluetooth_BluetoothCodecType_clazz, "createFromType",
                                    "<init>", "(IJLjava/lang/String;)V");
      "(I)Landroid/bluetooth/BluetoothCodecType;");

  if (createFromType == nullptr) {
  if (init == nullptr) {
    ALOGE(
    ALOGE("%s: Failed to find method <init> of BluetoothCodecType class",
        "%s: Failed to find method createFromType of BluetoothCodecType class",
          __func__);
          __func__);
    return nullptr;
    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 =
  jobjectArray result =
      env->NewObjectArray(default_supported_codecs.size(),
      env->NewObjectArray(supported_codecs.size(),
                          android_bluetooth_BluetoothCodecType_clazz, nullptr);
                          android_bluetooth_BluetoothCodecType_clazz, nullptr);

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


  for (size_t index = 0; index < default_supported_codecs.size(); index++) {
  for (size_t index = 0; index < supported_codecs.size(); index++) {
    jobject codec_type = env->CallStaticObjectMethod(
    jobject codec_type = env->NewObject(
        android_bluetooth_BluetoothCodecType_clazz, createFromType,
        android_bluetooth_BluetoothCodecType_clazz, init,
        (jint)default_supported_codecs[index]);
        (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);
    env->SetObjectArrayElement(result, index, codec_type);
  }
  }


+1 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ cc_library_static {
                "aidl/hearing_aid_software_encoding_aidl.cc",
                "aidl/hearing_aid_software_encoding_aidl.cc",
                "aidl/hfp_client_interface_aidl.cc",
                "aidl/hfp_client_interface_aidl.cc",
                "aidl/le_audio_software_aidl.cc",
                "aidl/le_audio_software_aidl.cc",
                "aidl/provider_info.cc",
                "hal_version_manager.cc",
                "hal_version_manager.cc",
                "hearing_aid_software_encoding.cc",
                "hearing_aid_software_encoding.cc",
                "hfp_client_interface.cc",
                "hfp_client_interface.cc",
+87 −0
Original line number Original line Diff line number Diff line
@@ -155,6 +155,93 @@ bool is_opus_supported() {
  return false;
  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 a2dp
}  // namespace audio
}  // namespace audio
}  // namespace bluetooth
}  // namespace bluetooth
+96 −0
Original line number Original line Diff line number Diff line
@@ -16,9 +16,13 @@


#pragma once
#pragma once


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


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


namespace bluetooth {
namespace bluetooth {
@@ -62,6 +66,98 @@ void set_remote_delay(uint16_t delay_report);
// Check whether OPUS is supported
// Check whether OPUS is supported
bool is_opus_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 a2dp
}  // namespace audio
}  // namespace audio
}  // namespace bluetooth
}  // namespace bluetooth
+61 −0
Original line number Original line 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
// Check if OPUS codec is supported
bool is_opus_supported() { return true; }
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 a2dp
}  // namespace audio
}  // namespace audio
}  // namespace bluetooth
}  // namespace bluetooth
Loading