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

Commit 0ba29b29 authored by Shunkai Yao's avatar Shunkai Yao
Browse files

Change BluetoothAudioHalVersion from enum to class

Bug: 315983648
Bug: 307291692
Bug: 307595549
Test: m
Test: atest bluetooth_audio_hal_version_test (with flag on/off)
Test: Bluetooth audio functionality with flag on/off on Pixel
Test: lunch aosp_arm64-trunk_staging-eng; m
Change-Id: I18b639463e19e649f9d82b35e2a6003b9e7d35a2
parent c4cd266a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ cc_library_static {
        "libutils",
    ],
    static_libs: [
        "bluetooth_flags_c_lib",
        "libbt-common",
        "libbt_shim_bridge",
        "libosi",
@@ -71,6 +72,7 @@ cc_library_static {
    cflags: [
        "-DBUILDCFG",
        "-Wno-unused-parameter",
        "-Wthread-safety",
    ],
    apex_available: [
        "com.android.btservices",
+105 −37
Original line number Diff line number Diff line
@@ -36,52 +36,78 @@ using ::aidl::android::hardware::bluetooth::audio::
static const std::string kDefaultAudioProviderFactoryInterface =
    std::string() + IBluetoothAudioProviderFactory::descriptor + "/default";

// Ideally HalVersionManager can be a singleton class
std::unique_ptr<HalVersionManager> HalVersionManager::instance_ptr =
    std::make_unique<HalVersionManager>();

BluetoothAudioHalVersion HalVersionManager::GetHalVersion() {
  std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
  return instance_ptr->hal_version_;
}
#if COM_ANDROID_BLUETOOTH_FLAGS_AUDIO_HAL_VERSION_CLASS

BluetoothAudioHalTransport HalVersionManager::GetHalTransport() {
  return instance_ptr->hal_transport_;
std::string toString(BluetoothAudioHalTransport transport) {
  switch (transport) {
    case BluetoothAudioHalTransport::UNKNOWN:
      return "UNKNOWN";
    case BluetoothAudioHalTransport::HIDL:
      return "HIDL";
    case BluetoothAudioHalTransport::AIDL:
      return "AIDL";
    default:
      return std::to_string(static_cast<int32_t>(transport));
  }
}

const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_UNAVAILABLE =
    BluetoothAudioHalVersion();
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_0 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 0);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_1 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 1);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V1 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 1, 0);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V2 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 2, 0);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V3 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 3, 0);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V4 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 4, 0);

/**
 * A singleton implementation to get the AIDL interface version.
 */
BluetoothAudioHalVersion GetAidlInterfaceVersion() {
  static auto aidl_version = []() -> BluetoothAudioHalVersion {
    int version = 0;
    auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
        ::ndk::SpAIBinder(AServiceManager_waitForService(
            kDefaultAudioProviderFactoryInterface.c_str())));

    if (provider_factory == nullptr) {
      LOG_ERROR(
          "getInterfaceVersion: Can't get aidl version from unknown factory");
      return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
    }

android::sp<IBluetoothAudioProvidersFactory_2_1>
HalVersionManager::GetProvidersFactory_2_1() {
  std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
  if (instance_ptr->hal_version_ != BluetoothAudioHalVersion::VERSION_2_1) {
    return nullptr;
    auto aidl_retval = provider_factory->getInterfaceVersion(&version);
    if (!aidl_retval.isOk()) {
      LOG_ERROR("BluetoothAudioHal::getInterfaceVersion failure: %s",
                aidl_retval.getDescription().c_str());
      return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
    }
  android::sp<IBluetoothAudioProvidersFactory_2_1> providers_factory =
      IBluetoothAudioProvidersFactory_2_1::getService();
  CHECK(providers_factory)
      << "V2_1::IBluetoothAudioProvidersFactory::getService() failed";

  LOG(INFO) << "V2_1::IBluetoothAudioProvidersFactory::getService() returned "
            << providers_factory.get()
            << (providers_factory->isRemote() ? " (remote)" : " (local)");
  return providers_factory;
    return BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, version,
                                    0);
  }();

  return aidl_version;
}

android::sp<IBluetoothAudioProvidersFactory_2_0>
HalVersionManager::GetProvidersFactory_2_0() {
  std::unique_lock<std::mutex> guard(instance_ptr->mutex_);
  if (instance_ptr->hal_version_ == BluetoothAudioHalVersion::VERSION_2_1) {
    guard.unlock();
    return instance_ptr->GetProvidersFactory_2_1();
BluetoothAudioHalTransport HalVersionManager::GetHalTransport() {
  return instance_ptr->hal_version_.getTransport();
}
  android::sp<IBluetoothAudioProvidersFactory_2_0> providers_factory =
      IBluetoothAudioProvidersFactory_2_0::getService();
  CHECK(providers_factory)
      << "V2_0::IBluetoothAudioProvidersFactory::getService() failed";

  LOG(INFO) << "V2_0::IBluetoothAudioProvidersFactory::getService() returned "
            << providers_factory.get()
            << (providers_factory->isRemote() ? " (remote)" : " (local)");
  guard.unlock();
  return providers_factory;
#else  // COM_ANDROID_BLUETOOTH_FLAGS_AUDIO_HAL_VERSION_CLASS

BluetoothAudioHalTransport HalVersionManager::GetHalTransport() {
  return instance_ptr->hal_transport_;
}

BluetoothAudioHalVersion GetAidlInterfaceVersion() {
@@ -116,10 +142,52 @@ BluetoothAudioHalVersion GetAidlInterfaceVersion() {
      LOG_ERROR("Unknown AIDL version %d", aidl_version);
      return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
  }

  return BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
}

#endif  // COM_ANDROID_BLUETOOTH_FLAGS_AUDIO_HAL_VERSION_CLASS

BluetoothAudioHalVersion HalVersionManager::GetHalVersion() {
  std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
  return instance_ptr->hal_version_;
}

android::sp<IBluetoothAudioProvidersFactory_2_1>
HalVersionManager::GetProvidersFactory_2_1() {
  std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
  if (instance_ptr->hal_version_ != BluetoothAudioHalVersion::VERSION_2_1) {
    return nullptr;
  }
  android::sp<IBluetoothAudioProvidersFactory_2_1> providers_factory =
      IBluetoothAudioProvidersFactory_2_1::getService();
  CHECK(providers_factory)
      << "V2_1::IBluetoothAudioProvidersFactory::getService() failed";

  LOG(INFO) << "V2_1::IBluetoothAudioProvidersFactory::getService() returned "
            << providers_factory.get()
            << (providers_factory->isRemote() ? " (remote)" : " (local)");
  return providers_factory;
}

android::sp<IBluetoothAudioProvidersFactory_2_0>
HalVersionManager::GetProvidersFactory_2_0() {
  std::unique_lock<std::mutex> guard(instance_ptr->mutex_);
  if (instance_ptr->hal_version_ == BluetoothAudioHalVersion::VERSION_2_1) {
    guard.unlock();
    return instance_ptr->GetProvidersFactory_2_1();
  }
  android::sp<IBluetoothAudioProvidersFactory_2_0> providers_factory =
      IBluetoothAudioProvidersFactory_2_0::getService();
  CHECK(providers_factory)
      << "V2_0::IBluetoothAudioProvidersFactory::getService() failed";

  LOG(INFO) << "V2_0::IBluetoothAudioProvidersFactory::getService() returned "
            << providers_factory.get()
            << (providers_factory->isRemote() ? " (remote)" : " (local)");
  guard.unlock();
  return providers_factory;
}

HalVersionManager::HalVersionManager() {
  hal_transport_ = BluetoothAudioHalTransport::UNKNOWN;
  if (AServiceManager_checkService(
+85 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvidersFactory.h>
#include <android/hardware/bluetooth/audio/2.1/types.h>
#include <com_android_bluetooth_flags.h>

namespace bluetooth {
namespace audio {
@@ -34,6 +35,88 @@ constexpr char kFullyQualifiedInterfaceName_2_0[] =
constexpr char kFullyQualifiedInterfaceName_2_1[] =
    "android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory";

#if COM_ANDROID_BLUETOOTH_FLAGS_AUDIO_HAL_VERSION_CLASS
/**
 * The type of HAL transport, it's important to have
 * BluetoothAudioHalTransport::HIDL value defined smaller than
 * BluetoothAudioHalTransport::AIDL.
 */
enum class BluetoothAudioHalTransport : uint8_t {
  // Uninit, default value
  UNKNOWN,
  HIDL,
  AIDL,
};

std::string toString(BluetoothAudioHalTransport transport);

/**
 * A hal version class with built-in comparison operators.
 */
class BluetoothAudioHalVersion {
 public:
  BluetoothAudioHalVersion(BluetoothAudioHalTransport transport =
                               BluetoothAudioHalTransport::UNKNOWN,
                           uint16_t major = 0, uint16_t minor = 0)
      : mTransport(transport), mMajor(major), mMinor(minor) {}

  bool isHIDL() const { return mTransport == BluetoothAudioHalTransport::HIDL; }
  bool isAIDL() const { return mTransport == BluetoothAudioHalTransport::AIDL; }

  BluetoothAudioHalTransport getTransport() const { return mTransport; }

  inline bool operator!=(const BluetoothAudioHalVersion& rhs) const {
    return std::tie(mTransport, mMajor, mMinor) !=
           std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor);
  }
  inline bool operator<(const BluetoothAudioHalVersion& rhs) const {
    return std::tie(mTransport, mMajor, mMinor) <
           std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor);
  }
  inline bool operator<=(const BluetoothAudioHalVersion& rhs) const {
    return std::tie(mTransport, mMajor, mMinor) <=
           std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor);
  }
  inline bool operator==(const BluetoothAudioHalVersion& rhs) const {
    return std::tie(mTransport, mMajor, mMinor) ==
           std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor);
  }
  inline bool operator>(const BluetoothAudioHalVersion& rhs) const {
    return std::tie(mTransport, mMajor, mMinor) >
           std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor);
  }
  inline bool operator>=(const BluetoothAudioHalVersion& rhs) const {
    return std::tie(mTransport, mMajor, mMinor) >=
           std::tie(rhs.mTransport, rhs.mMajor, rhs.mMinor);
  }

  inline std::string toString() const {
    std::ostringstream os;
    os << "BluetoothAudioHalVersion: {";
    os << "transport: " << bluetooth::audio::toString(mTransport);
    os << ", major: " << std::to_string(mMajor);
    os << ", minor: " << std::to_string(mMinor);
    os << "}";
    return os.str();
  }

  /* Known HalVersion definitions */
  static const BluetoothAudioHalVersion VERSION_UNAVAILABLE;
  static const BluetoothAudioHalVersion VERSION_2_0;
  static const BluetoothAudioHalVersion VERSION_2_1;
  static const BluetoothAudioHalVersion VERSION_AIDL_V1;
  static const BluetoothAudioHalVersion VERSION_AIDL_V2;
  static const BluetoothAudioHalVersion VERSION_AIDL_V3;
  static const BluetoothAudioHalVersion VERSION_AIDL_V4;

 private:
  BluetoothAudioHalTransport mTransport = BluetoothAudioHalTransport::UNKNOWN;
  uint16_t mMajor = 0;
  uint16_t mMinor = 0;
};

#else  // COM_ANDROID_BLUETOOTH_FLAGS_AUDIO_HAL_VERSION_CLASS

enum class BluetoothAudioHalVersion : uint8_t {
  VERSION_UNAVAILABLE = 0,
  VERSION_2_0,
@@ -51,6 +134,8 @@ enum class BluetoothAudioHalTransport : uint8_t {
  HIDL,
};

#endif  // COM_ANDROID_BLUETOOTH_FLAGS_AUDIO_HAL_VERSION_CLASS

class HalVersionManager {
 public:
  static BluetoothAudioHalVersion GetHalVersion();
+19 −0
Original line number Diff line number Diff line
@@ -19,6 +19,25 @@
namespace bluetooth {
namespace audio {

#if COM_ANDROID_BLUETOOTH_FLAGS_AUDIO_HAL_VERSION_CLASS

const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_UNAVAILABLE =
    BluetoothAudioHalVersion();
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_0 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 0);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_2_1 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::HIDL, 2, 1);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V1 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 1, 0);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V2 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 2, 0);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V3 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 3, 0);
const BluetoothAudioHalVersion BluetoothAudioHalVersion::VERSION_AIDL_V4 =
    BluetoothAudioHalVersion(BluetoothAudioHalTransport::AIDL, 4, 0);

#endif  // COM_ANDROID_BLUETOOTH_FLAGS_AUDIO_HAL_VERSION_CLASS

std::unique_ptr<HalVersionManager> HalVersionManager::instance_ptr = nullptr;

BluetoothAudioHalVersion HalVersionManager::GetHalVersion() {
+43 −0
Original line number Diff line number Diff line
@@ -573,3 +573,46 @@ cc_defaults {
        },
    },
}

cc_test {
    name: "bluetooth_audio_hal_version_test",
    local_include_dirs: ["common"],
    defaults: [
        "latest_android_hardware_audio_common_ndk_static",
        "latest_android_hardware_bluetooth_audio_ndk_static",
        "latest_android_media_audio_common_types_ndk_static",
        "mts_defaults",
    ],
    shared_libs: [
        "android.hardware.bluetooth.audio@2.0",
        "android.hardware.bluetooth.audio@2.1",
        "libbase",
        "libbinder",
        "libbinder_ndk",
        "libchrome",
        "libhidlbase",
        "liblog",
        "libutils",
    ],
    include_dirs: ["packages/modules/Bluetooth/system"],
    srcs: ["common/hal_version_manager_test.cc"],
    static_libs: [
        "android.hardware.bluetooth@1.0",
        "android.hardware.bluetooth@1.1",
        "android.hardware.common-V2-ndk",
        "android.hardware.common.fmq-V1-ndk",
        "bluetooth_flags_c_lib",
        "libbt-audio-hal-interface",
        "libflagtest",
    ],
    header_libs: ["libbluetooth_headers"],
    test_suites: ["general-tests"],
    cflags: [
        "-Wall",
        "-Werror",
        "-Wextra",
    ],
    sanitize: {
        address: true,
    },
}
Loading