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

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

Merge "audio: Introduce client interface support for HAL 2.1"

parents 1fb60983 bbab3003
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ using ::bluetooth::audio::PcmParameters;
using ::bluetooth::audio::SampleRate;
using ::bluetooth::audio::SessionType;

using ::bluetooth::audio::BluetoothAudioClientInterface;
using ::bluetooth::audio::BluetoothAudioSinkClientInterface;
using ::bluetooth::audio::codec::A2dpAacToHalConfig;
using ::bluetooth::audio::codec::A2dpAptxToHalConfig;
using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample;
@@ -50,10 +50,11 @@ using ::bluetooth::audio::codec::CodecConfiguration;
BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack);

// Provide call-in APIs for the Bluetooth Audio HAL
class A2dpTransport : public ::bluetooth::audio::IBluetoothTransportInstance {
class A2dpTransport
    : public ::bluetooth::audio::IBluetoothSinkTransportInstance {
 public:
  A2dpTransport(SessionType sessionType)
      : IBluetoothTransportInstance(sessionType, {}),
      : IBluetoothSinkTransportInstance(sessionType, {}),
        total_bytes_read_(0),
        data_position_({}) {
    a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
@@ -192,9 +193,9 @@ tA2DP_CTRL_CMD A2dpTransport::a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
uint16_t A2dpTransport::remote_delay_report_ = 0;

// Common interface to call-out into Bluetooth Audio HAL
BluetoothAudioClientInterface* software_hal_interface = nullptr;
BluetoothAudioClientInterface* offloading_hal_interface = nullptr;
BluetoothAudioClientInterface* active_hal_interface = nullptr;
BluetoothAudioSinkClientInterface* software_hal_interface = nullptr;
BluetoothAudioSinkClientInterface* offloading_hal_interface = nullptr;
BluetoothAudioSinkClientInterface* active_hal_interface = nullptr;

// Save the value if the remote reports its delay before this interface is
// initialized
@@ -292,8 +293,7 @@ bool a2dp_get_selected_hal_pcm_config(PcmParameters* pcm_config) {
  A2dpCodecConfig* a2dp_codec_configs = bta_av_get_a2dp_current_codec();
  if (a2dp_codec_configs == nullptr) {
    LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
    *pcm_config = ::bluetooth::audio::BluetoothAudioClientInterface::
        kInvalidPcmConfiguration;
    *pcm_config = BluetoothAudioSinkClientInterface::kInvalidPcmConfiguration;
    return false;
  }

@@ -349,8 +349,8 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) {

  auto a2dp_sink =
      new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
  software_hal_interface = new bluetooth::audio::BluetoothAudioClientInterface(
      a2dp_sink, message_loop);
  software_hal_interface =
      new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop);
  if (!software_hal_interface->IsValid()) {
    LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP is invalid?!";
    delete software_hal_interface;
@@ -362,8 +362,7 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) {
  if (btif_av_is_a2dp_offload_enabled()) {
    a2dp_sink = new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
    offloading_hal_interface =
        new bluetooth::audio::BluetoothAudioClientInterface(a2dp_sink,
                                                            message_loop);
        new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop);
    if (!offloading_hal_interface->IsValid()) {
      LOG(FATAL) << __func__
                 << ": BluetoothAudio HAL for A2DP offloading is invalid?!";
+423 −71

File changed.

Preview size limit exceeded, changes collapsed.

+145 −41
Original line number Diff line number Diff line
@@ -32,14 +32,30 @@
namespace bluetooth {
namespace audio {

using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
using AudioCapabilities =
    ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
using AudioCapabilities_2_1 =
    ::android::hardware::bluetooth::audio::V2_1::AudioCapabilities;
using AudioConfiguration =
    ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
using AudioConfiguration_2_1 =
    ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
using ::android::hardware::bluetooth::audio::V2_0::SessionType;
using IBluetoothAudioProvider =
    ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
using IBluetoothAudioProvider_2_1 =
    ::android::hardware::bluetooth::audio::V2_1::IBluetoothAudioProvider;
using PcmParameters =
    ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
using PcmParameters_2_1 =
    ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
using SampleRate = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
using SessionType = ::android::hardware::bluetooth::audio::V2_0::SessionType;
using SessionType_2_1 =
    ::android::hardware::bluetooth::audio::V2_1::SessionType;
using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
using BluetoothAudioStatus =
    ::android::hardware::bluetooth::audio::V2_0::Status;
@@ -73,22 +89,40 @@ inline BluetoothAudioStatus BluetoothAudioCtrlAckToHalStatus(
  }
}

// An IBluetoothTransportInstance needs to be implemented by a Bluetooth audio
// transport, such as A2DP or Hearing Aid, to handle callbacks from Audio HAL.
// An IBluetoothTransportInstance needs to be implemented by a Bluetooth
// audio transport, such as A2DP or Hearing Aid, to handle callbacks from Audio
// HAL.
class IBluetoothTransportInstance {
 public:
  IBluetoothTransportInstance(SessionType sessionType,
                              AudioConfiguration audioConfig)
      : session_type_(sessionType), audio_config_(std::move(audioConfig)){};
      : session_type_(sessionType),
        session_type_2_1_(SessionType_2_1::UNKNOWN),
        audio_config_(std::move(audioConfig)),
        audio_config_2_1_({}){};
  IBluetoothTransportInstance(SessionType_2_1 sessionType_2_1,
                              AudioConfiguration_2_1 audioConfig_2_1)
      : session_type_(SessionType::UNKNOWN),
        session_type_2_1_(sessionType_2_1),
        audio_config_({}),
        audio_config_2_1_(std::move(audioConfig_2_1)){};
  virtual ~IBluetoothTransportInstance() = default;

  SessionType GetSessionType() const { return session_type_; }
  SessionType_2_1 GetSessionType_2_1() const { return session_type_2_1_; }

  AudioConfiguration GetAudioConfiguration() const { return audio_config_; }
  AudioConfiguration_2_1 GetAudioConfiguration_2_1() const {
    return audio_config_2_1_;
  }

  void UpdateAudioConfiguration(const AudioConfiguration& audio_config) {
    audio_config_ = audio_config;
  }
  void UpdateAudioConfiguration_2_1(
      const AudioConfiguration_2_1& audio_config_2_1) {
    audio_config_2_1_ = audio_config_2_1;
  }

  virtual BluetoothAudioCtrlAck StartRequest() = 0;

@@ -105,12 +139,42 @@ class IBluetoothTransportInstance {
  // Invoked when the transport is requested to reset presentation position
  virtual void ResetPresentationPosition() = 0;

  // Invoked when the transport is requested to log bytes read
  virtual void LogBytesRead(size_t bytes_readed) = 0;

 private:
  const SessionType session_type_;
  const SessionType_2_1 session_type_2_1_;
  AudioConfiguration audio_config_;
  AudioConfiguration_2_1 audio_config_2_1_;
};

// An IBluetoothSinkTransportInstance needs to be implemented by a Bluetooth
// audio transport, such as A2DP, Hearing Aid or LeAudio, to handle callbacks
// from Audio HAL.
class IBluetoothSinkTransportInstance : public IBluetoothTransportInstance {
 public:
  IBluetoothSinkTransportInstance(SessionType_2_1 sessionType_2_1,
                                  AudioConfiguration_2_1 audioConfig_2_1)
      : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
  IBluetoothSinkTransportInstance(SessionType sessionType,
                                  AudioConfiguration audioConfig)
      : IBluetoothTransportInstance{sessionType, audioConfig} {}
  virtual ~IBluetoothSinkTransportInstance() = default;

  // Invoked when the transport is requested to log bytes read
  virtual void LogBytesRead(size_t bytes_readed) = 0;
};

class IBluetoothSourceTransportInstance : public IBluetoothTransportInstance {
 public:
  IBluetoothSourceTransportInstance(SessionType sessionType,
                                    AudioConfiguration audioConfig)
      : IBluetoothTransportInstance{sessionType, audioConfig} {}
  IBluetoothSourceTransportInstance(SessionType_2_1 sessionType_2_1,
                                    AudioConfiguration_2_1 audioConfig_2_1)
      : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
  virtual ~IBluetoothSourceTransportInstance() = default;

  // Invoked when the transport is requested to log bytes written
  virtual void LogBytesWritten(size_t bytes_written) = 0;
};

// common object is shared between different kind of SessionType
@@ -121,65 +185,105 @@ class BluetoothAudioDeathRecipient;
// IBluetoothTransportInstance
class BluetoothAudioClientInterface {
 public:
  // Constructs an BluetoothAudioClientInterface to communicate to
  // BluetoothAudio HAL. |sink| is the implementation for the transport, and
  // |message_loop| is the thread where callbacks are invoked.
  BluetoothAudioClientInterface(
      IBluetoothTransportInstance* sink,
      bluetooth::common::MessageLoopThread* message_loop);

  ~BluetoothAudioClientInterface();
      android::sp<BluetoothAudioDeathRecipient> death_recipient,
      IBluetoothTransportInstance* instance);
  virtual ~BluetoothAudioClientInterface() = default;

  bool IsValid() const {
    return provider_ != nullptr;
    return provider_ != nullptr || provider_2_1_ != nullptr;
  }

  IBluetoothTransportInstance* GetTransportInstance() const { return sink_; }

  std::vector<AudioCapabilities> GetAudioCapabilities() const;
  std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1() const;
  static std::vector<AudioCapabilities> GetAudioCapabilities(
      SessionType session_type);

  bool UpdateAudioConfig(const AudioConfiguration& audioConfig);

  int StartSession();
  static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1(
      SessionType_2_1 session_type_2_1);

  void StreamStarted(const BluetoothAudioCtrlAck& ack);

  void StreamSuspended(const BluetoothAudioCtrlAck& ack);

  int EndSession();

  // Read data from audio  HAL through fmq
  size_t ReadAudioData(uint8_t* p_buf, uint32_t len);

  // Write data to audio HAL through fmq
  size_t WriteAudioData(uint8_t* p_buf, uint32_t len);
  int StartSession();
  int StartSession_2_1();

  // Renew the connection and usually is used when HIDL restarted
  void RenewAudioProviderAndSession();

  int EndSession();

  bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
  bool UpdateAudioConfig_2_1(const AudioConfiguration_2_1& audioConfig_2_1);

  void FlushAudioData();

  static constexpr PcmParameters kInvalidPcmConfiguration = {
      .sampleRate = SampleRate::RATE_UNKNOWN,
      .channelMode = ChannelMode::UNKNOWN,
      .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
  };

 private:
  static bool IsSupported();
      .bitsPerSample = BitsPerSample::BITS_UNKNOWN};

 protected:
  mutable std::mutex internal_mutex_;
  // Helper function to connect to an IBluetoothAudioProvider
  void FetchAudioProvider();
  // Helper function to connect to an IBluetoothAudioProvider 2.1
  void FetchAudioProvider_2_1();

  mutable std::mutex internal_mutex_;
  IBluetoothTransportInstance* sink_;
  android::sp<IBluetoothAudioProvider> provider_;
  std::vector<AudioCapabilities> capabilities_;
  android::sp<IBluetoothAudioProvider_2_1> provider_2_1_;
  bool session_started_;
  std::unique_ptr<::android::hardware::MessageQueue<
      uint8_t, ::android::hardware::kSynchronizedReadWrite>>
      mDataMQ;
  android::sp<BluetoothAudioDeathRecipient> death_recipient_;

 private:
  IBluetoothTransportInstance* transport_;
  std::vector<AudioCapabilities> capabilities_;
  std::vector<AudioCapabilities_2_1> capabilities_2_1_;
};

// The client interface connects an IBluetoothTransportInstance to
// IBluetoothAudioProvider and helps to route callbacks to
// IBluetoothTransportInstance
class BluetoothAudioSinkClientInterface : public BluetoothAudioClientInterface {
 public:
  // Constructs an BluetoothAudioSinkClientInterface to communicate to
  // BluetoothAudio HAL. |sink| is the implementation for the transport, and
  // |message_loop| is the thread where callbacks are invoked.
  BluetoothAudioSinkClientInterface(
      IBluetoothSinkTransportInstance* sink,
      bluetooth::common::MessageLoopThread* message_loop);
  virtual ~BluetoothAudioSinkClientInterface();

  IBluetoothSinkTransportInstance* GetTransportInstance() const {
    return sink_;
  }

  // Read data from audio  HAL through fmq
  size_t ReadAudioData(uint8_t* p_buf, uint32_t len);

 private:
  IBluetoothSinkTransportInstance* sink_;
};

class BluetoothAudioSourceClientInterface
    : public BluetoothAudioClientInterface {
 public:
  // Constructs an BluetoothAudioSourceClientInterface to communicate to
  // BluetoothAudio HAL. |source| is the implementation for the transport, and
  // |message_loop| is the thread where callbacks are invoked.
  BluetoothAudioSourceClientInterface(
      IBluetoothSourceTransportInstance* source,
      bluetooth::common::MessageLoopThread* message_loop);
  virtual ~BluetoothAudioSourceClientInterface();

  // Write data to audio HAL through fmq
  size_t WriteAudioData(const uint8_t* p_buf, uint32_t len);

 private:
  IBluetoothSourceTransportInstance* source_;
};

}  // namespace audio
+184 −86

File changed.

Preview size limit exceeded, changes collapsed.

+6 −5
Original line number Diff line number Diff line
@@ -33,14 +33,15 @@ using ::bluetooth::audio::ChannelMode;
using ::bluetooth::audio::PcmParameters;
using ::bluetooth::audio::SampleRate;
using ::bluetooth::audio::SessionType;
using ::bluetooth::audio::SessionType_2_1;
using ::bluetooth::audio::hearing_aid::StreamCallbacks;

// Transport implementation for Hearing Aids
class HearingAidTransport
    : public bluetooth::audio::IBluetoothTransportInstance {
    : public bluetooth::audio::IBluetoothSinkTransportInstance {
 public:
  HearingAidTransport(StreamCallbacks stream_cb)
      : IBluetoothTransportInstance(
      : IBluetoothSinkTransportInstance(
            SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, {}),
        stream_cb_(std::move(stream_cb)),
        remote_delay_report_ms_(0),
@@ -142,7 +143,7 @@ bool HearingAidGetSelectedHalPcmConfig(PcmParameters* hal_pcm_config) {
// Sink instance of Hearing Aids to provide call-in APIs for Bluetooth Audio Hal
HearingAidTransport* hearing_aid_sink = nullptr;
// Common interface to call-out into Bluetooth Audio Hal
bluetooth::audio::BluetoothAudioClientInterface*
bluetooth::audio::BluetoothAudioSinkClientInterface*
    hearing_aid_hal_clientinterface = nullptr;
bool btaudio_hearing_aid_disabled = false;
bool is_configured = false;
@@ -178,7 +179,7 @@ bool init(StreamCallbacks stream_cb,

  hearing_aid_sink = new HearingAidTransport(std::move(stream_cb));
  hearing_aid_hal_clientinterface =
      new bluetooth::audio::BluetoothAudioClientInterface(hearing_aid_sink,
      new bluetooth::audio::BluetoothAudioSinkClientInterface(hearing_aid_sink,
                                                              message_loop);
  if (!hearing_aid_hal_clientinterface->IsValid()) {
    LOG(WARNING) << __func__ << ": BluetoothAudio HAL for Hearing Aid is invalid?!";