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

Commit c57931f5 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Gerrit Code Review
Browse files

Merge "Load bluetooth.audio HAL as either 2.0 or 2.1"

parents f8b89875 75ac2490
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ cc_library_shared {
    header_libs: ["libhardware_headers"],
    shared_libs: [
        "android.hardware.bluetooth.audio@2.0",
        "android.hardware.bluetooth.audio@2.1",
        "libaudioutils",
        "libbase",
        "libbluetooth_audio_session",
+21 −18
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@
#include <log/log.h>
#include <stdlib.h>

#include "BluetoothAudioSessionControl.h"
#include "BluetoothAudioSessionControl_2_1.h"
#include "device_port_proxy.h"
#include "stream_apis.h"
#include "utils.h"
@@ -33,7 +33,7 @@ namespace bluetooth {
namespace audio {

using ::android::base::StringPrintf;
using ::android::bluetooth::audio::BluetoothAudioSessionControl;
using ::android::bluetooth::audio::BluetoothAudioSessionControl_2_1;
using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
@@ -99,7 +99,7 @@ constexpr unsigned int kMaxWaitingTimeMs = 4500;

BluetoothAudioPortOut::BluetoothAudioPortOut()
    : state_(BluetoothStreamState::DISABLED),
      session_type_(SessionType::UNKNOWN),
      session_type_(SessionType_2_1::UNKNOWN),
      cookie_(android::bluetooth::audio::kObserversCookieUndefined) {}

bool BluetoothAudioPortOut::SetUp(audio_devices_t devices) {
@@ -135,7 +135,7 @@ bool BluetoothAudioPortOut::SetUp(audio_devices_t devices) {
  ::android::bluetooth::audio::PortStatusCallbacks cbacks = {
      .control_result_cb_ = control_result_cb,
      .session_changed_cb_ = session_changed_cb};
  cookie_ = BluetoothAudioSessionControl::RegisterControlResultCback(
  cookie_ = BluetoothAudioSessionControl_2_1::RegisterControlResultCback(
      session_type_, cbacks);
  LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);

@@ -149,19 +149,19 @@ bool BluetoothAudioPortOut::init_session_type(audio_devices_t device) {
    case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
      LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_BLUETOOTH_A2DP (HEADPHONES/SPEAKER) ("
                   << StringPrintf("%#x", device) << ")";
      session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
      session_type_ = SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH;
      break;
    case AUDIO_DEVICE_OUT_HEARING_AID:
      LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_HEARING_AID (MEDIA/VOICE) (" << StringPrintf("%#x", device)
                   << ")";
      session_type_ = SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
      session_type_ = SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
      break;
    default:
      LOG(ERROR) << __func__ << ": unknown device=" << StringPrintf("%#x", device);
      return false;
  }

  if (!BluetoothAudioSessionControl::IsSessionReady(session_type_)) {
  if (!BluetoothAudioSessionControl_2_1::IsSessionReady(session_type_)) {
    LOG(ERROR) << __func__ << ": device=" << StringPrintf("%#x", device) << ", session_type=" << toString(session_type_)
               << " is not ready";
    return false;
@@ -177,7 +177,7 @@ void BluetoothAudioPortOut::TearDown() {
  }

  LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
  BluetoothAudioSessionControl::UnregisterControlResultCback(session_type_,
  BluetoothAudioSessionControl_2_1::UnregisterControlResultCback(session_type_,
                                                                 cookie_);
  cookie_ = android::bluetooth::audio::kObserversCookieUndefined;
}
@@ -260,7 +260,7 @@ bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const {
  }

  const AudioConfiguration& hal_audio_cfg =
      BluetoothAudioSessionControl::GetAudioConfig(session_type_);
      BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_);
  if (hal_audio_cfg.getDiscriminator() !=
      AudioConfiguration::hidl_discriminator::pcmConfig) {
    audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
@@ -324,7 +324,7 @@ bool BluetoothAudioPortOut::Start() {
  bool retval = false;
  if (state_ == BluetoothStreamState::STANDBY) {
    state_ = BluetoothStreamState::STARTING;
    if (BluetoothAudioSessionControl::StartStream(session_type_)) {
    if (BluetoothAudioSessionControl_2_1::StartStream(session_type_)) {
      retval = CondwaitState(BluetoothStreamState::STARTING);
    } else {
      LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
@@ -355,7 +355,7 @@ bool BluetoothAudioPortOut::Suspend() {
  bool retval = false;
  if (state_ == BluetoothStreamState::STARTED) {
    state_ = BluetoothStreamState::SUSPENDING;
    if (BluetoothAudioSessionControl::SuspendStream(session_type_)) {
    if (BluetoothAudioSessionControl_2_1::SuspendStream(session_type_)) {
      retval = CondwaitState(BluetoothStreamState::SUSPENDING);
    } else {
      LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
@@ -382,7 +382,7 @@ void BluetoothAudioPortOut::Stop() {
  LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
            << ", state=" << state_ << " request";
  state_ = BluetoothStreamState::DISABLED;
  BluetoothAudioSessionControl::StopStream(session_type_);
  BluetoothAudioSessionControl_2_1::StopStream(session_type_);
  LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
            << ", state=" << state_ << " done";
}
@@ -390,7 +390,8 @@ void BluetoothAudioPortOut::Stop() {
size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const {
  if (!in_use()) return 0;
  if (!is_stereo_to_mono_) {
    return BluetoothAudioSessionControl::OutWritePcmData(session_type_, buffer, bytes);
    return BluetoothAudioSessionControl_2_1::OutWritePcmData(session_type_,
                                                             buffer, bytes);
  }

  // WAR to mix the stereo into Mono (16 bits per sample)
@@ -400,7 +401,9 @@ size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const
  std::unique_ptr<int16_t[]> dst{new int16_t[write_frames]};
  downmix_to_mono_i16_from_stereo_i16(dst.get(), src, write_frames);
  // a frame is 16 bits, and the size of a mono frame is equal to half a stereo.
  return BluetoothAudioSessionControl::OutWritePcmData(session_type_, dst.get(), write_frames * 2) * 2;
  return BluetoothAudioSessionControl_2_1::OutWritePcmData(
             session_type_, dst.get(), write_frames * 2) *
         2;
}

bool BluetoothAudioPortOut::GetPresentationPosition(uint64_t* delay_ns,
@@ -410,7 +413,7 @@ bool BluetoothAudioPortOut::GetPresentationPosition(uint64_t* delay_ns,
    LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
    return false;
  }
  bool retval = BluetoothAudioSessionControl::GetPresentationPosition(
  bool retval = BluetoothAudioSessionControl_2_1::GetPresentationPosition(
      session_type_, delay_ns, bytes, timestamp);
  LOG(VERBOSE) << __func__ << ": session_type=" << StringPrintf("%#hhx", session_type_)
               << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << ", delay=" << *delay_ns
@@ -429,7 +432,7 @@ void BluetoothAudioPortOut::UpdateMetadata(
  LOG(DEBUG) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
             << ", state=" << state_ << ", " << source_metadata->track_count << " track(s)";
  if (source_metadata->track_count == 0) return;
  BluetoothAudioSessionControl::UpdateTracksMetadata(session_type_,
  BluetoothAudioSessionControl_2_1::UpdateTracksMetadata(session_type_,
                                                         source_metadata);
}

+6 −5
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

#pragma once

#include <android/hardware/bluetooth/audio/2.0/types.h>
#include <android/hardware/bluetooth/audio/2.1/types.h>
#include <hardware/audio.h>
#include <condition_variable>
#include <mutex>
@@ -28,7 +28,8 @@ namespace android {
namespace bluetooth {
namespace audio {

using ::android::hardware::bluetooth::audio::V2_0::SessionType;
using SessionType_2_1 =
    ::android::hardware::bluetooth::audio::V2_1::SessionType;

// Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio
// Session Control. All methods are not thread safe, so users must acquire a
@@ -87,13 +88,13 @@ class BluetoothAudioPortOut {
  void SetState(BluetoothStreamState state);

  bool IsA2dp() const {
    return session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
           session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
    return session_type_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
           session_type_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH;
  }

 private:
  BluetoothStreamState state_;
  SessionType session_type_;
  SessionType_2_1 session_type_;
  uint16_t cookie_;
  mutable std::mutex cv_mutex_;
  std::condition_variable internal_cv_;
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ cc_library_static {
    ],
    shared_libs: [
        "android.hardware.bluetooth.audio@2.0",
        "android.hardware.bluetooth.audio@2.1",
        "libfmq",
        "libhidlbase",
    ],
@@ -45,6 +46,7 @@ cc_test {
    ],
    shared_libs: [
        "android.hardware.bluetooth.audio@2.0",
        "android.hardware.bluetooth.audio@2.1",
        "libcutils",
        "libfmq",
        "libhidlbase",
+15 −42
Original line number Diff line number Diff line
@@ -17,13 +17,11 @@
#define LOG_TAG "BTAudioClientIf"

#include "client_interface.h"
#include "hal_version_manager.h"

#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <base/logging.h>
#include <hidl/MQDescriptor.h>
#include <hidl/ServiceManagement.h>
#include <future>

#include "osi/include/log.h"
@@ -36,15 +34,15 @@ using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::audio::common::V5_0::SourceMetadata;
using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
using ::android::hardware::bluetooth::audio::V2_0::
    IBluetoothAudioProvidersFactory;

using DataMQ = ::android::hardware::MessageQueue<
    uint8_t, ::android::hardware::kSynchronizedReadWrite>;

static constexpr int kDefaultDataReadTimeoutMs = 10;      // 10 ms
static constexpr int kDefaultDataReadPollIntervalMs = 1;  // non-blocking poll
static constexpr char kFullyQualifiedInterfaceName[] =
    "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory";

std::unique_ptr<HalVersionManager> HalVersionManager::instance_ptr =
    std::unique_ptr<HalVersionManager>(new HalVersionManager());

std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
  switch (ack) {
@@ -191,7 +189,8 @@ BluetoothAudioClientInterface::BluetoothAudioClientInterface(IBluetoothTransport
                                                             bluetooth::common::MessageLoopThread* message_loop)
    : sink_(sink), provider_(nullptr), session_started_(false), mDataMQ(nullptr),
      death_recipient_(new BluetoothAudioDeathRecipient(this, message_loop)) {
  if (IsSupported()) {
  if (HalVersionManager::GetHalVersion() !=
      BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
    FetchAudioProvider();
  } else {
    LOG(WARNING) << "IBluetoothAudioProvidersFactory not declared";
@@ -212,39 +211,17 @@ BluetoothAudioClientInterface::GetAudioCapabilities() const {
  return capabilities_;
}

bool BluetoothAudioClientInterface::IsSupported() {
  auto service_manager = android::hardware::defaultServiceManager1_2();
  CHECK(service_manager != nullptr);
  size_t instance_count = 0;
  auto listManifestByInterface_cb =
      [&instance_count](
          const hidl_vec<android::hardware::hidl_string>& instanceNames) {
        instance_count = instanceNames.size();
        LOG(INFO) << "listManifestByInterface_cb returns " << instance_count
                  << " instance(s)";
      };
  auto hidl_retval = service_manager->listManifestByInterface(
      kFullyQualifiedInterfaceName, listManifestByInterface_cb);
  if (!hidl_retval.isOk()) {
    LOG(FATAL) << __func__ << ": IServiceManager::listByInterface failure: "
               << hidl_retval.description();
    return false;
  }
  return (instance_count > 0);
}

std::vector<AudioCapabilities>
BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) {
  std::vector<AudioCapabilities> capabilities(0);
  if (!IsSupported()) return capabilities;
  if (HalVersionManager::GetHalVersion() ==
      BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
    return capabilities;
  }

  android::sp<IBluetoothAudioProvidersFactory> providersFactory =
      IBluetoothAudioProvidersFactory::getService();
  CHECK(providersFactory != nullptr)
      << "IBluetoothAudioProvidersFactory::getService() failed";
  LOG(INFO) << "IBluetoothAudioProvidersFactory::getService() returned "
            << providersFactory.get()
            << (providersFactory->isRemote() ? " (remote)" : " (local)");
  android::sp<IBluetoothAudioProvidersFactory_2_0> providersFactory =
      HalVersionManager::GetProviderFactory_2_0();

  auto getProviderCapabilities_cb =
      [&capabilities](const hidl_vec<AudioCapabilities>& audioCapabilities) {
@@ -267,12 +244,8 @@ void BluetoothAudioClientInterface::FetchAudioProvider() {
    LOG(WARNING) << __func__ << ": reflash";
  }

  android::sp<IBluetoothAudioProvidersFactory> providersFactory =
      IBluetoothAudioProvidersFactory::getService();
  CHECK(providersFactory != nullptr) << "IBluetoothAudioProvidersFactory::getService() failed";
  LOG(INFO) << "IBluetoothAudioProvidersFactory::getService() returned "
            << providersFactory.get()
            << (providersFactory->isRemote() ? " (remote)" : " (local)");
  android::sp<IBluetoothAudioProvidersFactory_2_0> providersFactory =
      HalVersionManager::GetProviderFactory_2_0();

  auto getProviderCapabilities_cb =
      [& capabilities = this->capabilities_](
Loading