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

Commit ac5bdedd authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

LeAudio: Split HAL clients into source and sink

This splits the client_audio.cc for sink and source files
and moves them into a new subdirectory for better separation
and mantainability. It was also put into the le_audio namespace.

It simplifies class naming - now named from the perspective of
the bluetooth profile role rather than mixing the bluetooth
domain with the framework point of view. This eliminates the
non-intuitive usages like registering LeAudioClientAudioSinkReceiver
in LeAudioClientAudioSource. It could be confusing who is Sink,
who is Source and what the Receiver is. After this change, the
AudioHalClient::LeAudioSourceCallbacks instance is registered
in AudioHalClient::LeAudioSource.

The interface was cleaned up, simplified and the confusing
const void* token has been removed. The object ownership was
redefined. Sink and Source endpoint classes have a static
Acquire() methods which gives the user an ownership of a HAL
session. Since HAL allows a single client for a single direction,
the acquired HAL client instance needs to be released to allow
subsequent Acquire() calls to proceed. The Hal client life cycle
is managed by a smart pointers. Releasing it, releases the HAL
audio session and deallocates the HAL client instance. Previously
the ownership was not clearly defined, which caused situations like
le audio service allocating and releasing it in the production run,
but only releasing it in the unit test runs. But in some test cases
this object was deallocated by the test case itself. This required
special handling to avoid double free or the usage of stack allocated
objects.

Lastly, it improves logs and switches to the new logging mechanism.

Test: atest --host bluetooth_le_audio_test bluetooth_le_audio_client_test bluetooth_test_broadcaster --no-bazel-mode
Bug: 249737696
Tag: #refactor
Change-Id: I41da290d7941b4a1a3001015cb9c15a89f9c3375
Merged-In: I41da290d7941b4a1a3001015cb9c15a89f9c3375
(cherry picked from commit d3b8e9f2)
parent f49459ee
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -99,7 +99,8 @@ cc_library_static {
        "le_audio/state_machine.cc",
        "le_audio/storage_helper.cc",
        "le_audio/client_parser.cc",
        "le_audio/client_audio.cc",
        "le_audio/audio_hal_client/audio_sink_hal_client.cc",
        "le_audio/audio_hal_client/audio_source_hal_client.cc",
        "le_audio/le_audio_utils.cc",
        "le_audio/le_audio_set_configuration_provider.cc",
        "le_audio/le_audio_set_configuration_provider_json.cc",
@@ -558,8 +559,9 @@ cc_test {
        "test/common/bta_gatt_api_mock.cc",
        "test/common/bta_gatt_queue_mock.cc",
        "test/common/btm_api_mock.cc",
        "le_audio/client_audio.cc",
        "le_audio/client_audio_test.cc",
        "le_audio/audio_hal_client/audio_sink_hal_client.cc",
        "le_audio/audio_hal_client/audio_source_hal_client.cc",
        "le_audio/audio_hal_client/audio_hal_client_test.cc",
        "le_audio/client_parser.cc",
        "le_audio/client_parser_test.cc",
        "le_audio/content_control_id_keeper.cc",
@@ -629,7 +631,6 @@ cc_test {
        "gatt/database.cc",
        "gatt/database_builder.cc",
        "le_audio/client.cc",
        "le_audio/client_audio.cc",
        "le_audio/client_parser.cc",
        "le_audio/content_control_id_keeper.cc",
        "le_audio/devices.cc",
@@ -777,7 +778,6 @@ cc_test {
        "le_audio/broadcaster/mock_ble_advertising_manager.cc",
        "le_audio/broadcaster/mock_state_machine.cc",
        "le_audio/content_control_id_keeper.cc",
        "le_audio/client_audio.cc",
        "le_audio/le_audio_utils.cc",
        "le_audio/le_audio_types.cc",
        "le_audio/mock_iso_manager.cc",
+0 −6
Original line number Diff line number Diff line
@@ -24,9 +24,6 @@

#include <vector>

class LeAudioUnicastClientAudioSource;
class LeAudioUnicastClientAudioSink;

class LeAudioHalVerifier {
 public:
  static bool SupportsLeAudio();
@@ -46,9 +43,6 @@ class LeAudioClient {
          offloading_preference);
  static void Cleanup(base::Callback<void()> cleanupCb);
  static LeAudioClient* Get(void);
  static void InitializeAudioClients(
      LeAudioUnicastClientAudioSource* clientAudioSource,
      LeAudioUnicastClientAudioSink* clientAudioSink);
  static void DebugDump(int fd);

  virtual void RemoveDevice(const RawAddress& address) = 0;
+0 −4
Original line number Diff line number Diff line
@@ -23,8 +23,6 @@

#include "bta/include/bta_le_audio_api.h"

class LeAudioBroadcastClientAudioSource;

/* Interface class */
class LeAudioBroadcaster {
 public:
@@ -39,8 +37,6 @@ class LeAudioBroadcaster {
  static void Cleanup(void);
  static LeAudioBroadcaster* Get(void);
  static bool IsLeAudioBroadcasterRunning(void);
  static void InitializeAudioClient(
      LeAudioBroadcastClientAudioSource* clientAudioSource);
  static void DebugDump(int fd);

  virtual void CreateAudioBroadcast(
+63 −89
Original line number Diff line number Diff line
/*
 * Copyright 2020 HIMSA II K/S - www.himsa.com.
 * Represented by EHIMA - www.ehima.com
 * Copyright (c) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -17,29 +18,12 @@
#pragma once

#include <future>
#include <memory>

#include "audio_hal_interface/le_audio_software.h"
#include "common/repeating_timer.h"

/* Implementations of Le Audio will also implement this interface */
class LeAudioClientAudioSinkReceiver {
 public:
  virtual ~LeAudioClientAudioSinkReceiver() = default;
  virtual void OnAudioDataReady(const std::vector<uint8_t>& data) = 0;
  virtual void OnAudioSuspend(std::promise<void> do_suspend_promise) = 0;
  virtual void OnAudioResume(void) = 0;
  virtual void OnAudioMetadataUpdate(
      std::vector<struct playback_track_metadata> source_metadata) = 0;
};
class LeAudioClientAudioSourceReceiver {
 public:
  virtual ~LeAudioClientAudioSourceReceiver() = default;
  virtual void OnAudioSuspend(std::promise<void> do_suspend_promise) = 0;
  virtual void OnAudioResume(void) = 0;
  virtual void OnAudioMetadataUpdate(
      std::vector<struct record_track_metadata> sink_metadata) = 0;
};

namespace le_audio {
/* Represents configuration of audio codec, as exchanged between le audio and
 * phone.
 * It can also be passed to the audio source to configure its parameters.
@@ -110,87 +94,77 @@ struct LeAudioCodecConfiguration {
  }
};

/* Represents source of audio for le audio client */
class LeAudioClientAudioSource {
/* Used by the local BLE Audio Sink device to pass the audio data
 * received from a remote BLE Audio Source to the Audio HAL.
 */
class LeAudioSinkAudioHalClient {
 public:
  virtual ~LeAudioClientAudioSource() = default;
  class Callbacks {
   public:
    virtual ~Callbacks() = default;
    virtual void OnAudioSuspend(std::promise<void> do_suspend_promise) = 0;
    virtual void OnAudioResume(void) = 0;
    virtual void OnAudioMetadataUpdate(
        std::vector<struct record_track_metadata> sink_metadata) = 0;
  };

  virtual ~LeAudioSinkAudioHalClient() = default;
  virtual bool Start(const LeAudioCodecConfiguration& codecConfiguration,
                     LeAudioClientAudioSinkReceiver* audioReceiver);
  virtual void Stop();
  virtual void Release(const void* instance);
  virtual void ConfirmStreamingRequest();
  virtual void CancelStreamingRequest();
  virtual void UpdateRemoteDelay(uint16_t remote_delay_ms);
  virtual void UpdateAudioConfigToHal(const ::le_audio::offload_config& config);
  virtual void UpdateBroadcastAudioConfigToHal(
      const ::le_audio::broadcast_offload_config& config);
  virtual void SuspendedForReconfiguration();
  virtual void ReconfigurationComplete();

  static void DebugDump(int fd);

 protected:
  const void* Acquire(bool is_broadcasting_session_type);
  bool InitAudioSinkThread(const std::string name);
                     Callbacks* audioReceiver) = 0;
  virtual void Stop() = 0;
  virtual size_t SendData(uint8_t* data, uint16_t size) = 0;

  bluetooth::common::MessageLoopThread* worker_thread_ = nullptr;
  virtual void ConfirmStreamingRequest() = 0;
  virtual void CancelStreamingRequest() = 0;

 private:
  bool SinkOnResumeReq(bool start_media_task);
  bool SinkOnSuspendReq();
  bool SinkOnMetadataUpdateReq(const source_metadata_t& source_metadata);
  virtual void UpdateRemoteDelay(uint16_t remote_delay_ms) = 0;
  virtual void UpdateAudioConfigToHal(
      const ::le_audio::offload_config& config) = 0;
  virtual void SuspendedForReconfiguration() = 0;
  virtual void ReconfigurationComplete() = 0;

  void StartAudioTicks();
  void StopAudioTicks();
  void SendAudioData();

  bluetooth::common::RepeatingTimer audio_timer_;
  LeAudioCodecConfiguration source_codec_config_;
  LeAudioClientAudioSinkReceiver* audioSinkReceiver_ = nullptr;
  bluetooth::audio::le_audio::LeAudioClientInterface::Sink*
      sinkClientInterface_ = nullptr;
  static std::unique_ptr<LeAudioSinkAudioHalClient> AcquireUnicast();
  static void DebugDump(int fd);

  /* Guard audio sink receiver mutual access from stack with internal mutex */
  std::mutex sinkInterfaceMutex_;
 protected:
  LeAudioSinkAudioHalClient() = default;
};

/* Represents audio sink for le audio client */
class LeAudioUnicastClientAudioSink {
/* Used by the local BLE Audio Source device to get data from the
 * Audio HAL, so we could send it over to a remote BLE Audio Sink device.
 */
class LeAudioSourceAudioHalClient {
 public:
  class Callbacks {
   public:
  virtual ~LeAudioUnicastClientAudioSink() = default;
    virtual ~Callbacks() = default;
    virtual void OnAudioDataReady(const std::vector<uint8_t>& data) = 0;
    virtual void OnAudioSuspend(std::promise<void> do_suspend_promise) = 0;
    virtual void OnAudioResume(void) = 0;
    virtual void OnAudioMetadataUpdate(
        std::vector<struct playback_track_metadata> source_metadata) = 0;
  };

  virtual ~LeAudioSourceAudioHalClient() = default;
  virtual bool Start(const LeAudioCodecConfiguration& codecConfiguration,
                     LeAudioClientAudioSourceReceiver* audioReceiver);
  virtual void Stop();
  virtual const void* Acquire();
  virtual void Release(const void* instance);
  virtual size_t SendData(uint8_t* data, uint16_t size);
  virtual void ConfirmStreamingRequest();
  virtual void CancelStreamingRequest();
  virtual void UpdateRemoteDelay(uint16_t remote_delay_ms);
  virtual void UpdateAudioConfigToHal(const ::le_audio::offload_config& config);
  virtual void SuspendedForReconfiguration();
  virtual void ReconfigurationComplete();
                     Callbacks* audioReceiver) = 0;
  virtual void Stop() = 0;
  virtual size_t SendData(uint8_t* data, uint16_t size) { return 0; }
  virtual void ConfirmStreamingRequest() = 0;
  virtual void CancelStreamingRequest() = 0;
  virtual void UpdateRemoteDelay(uint16_t remote_delay_ms) = 0;
  virtual void UpdateAudioConfigToHal(
      const ::le_audio::offload_config& config) = 0;
  virtual void UpdateBroadcastAudioConfigToHal(
      const ::le_audio::broadcast_offload_config& config) = 0;
  virtual void SuspendedForReconfiguration() = 0;
  virtual void ReconfigurationComplete() = 0;

  static std::unique_ptr<LeAudioSourceAudioHalClient> AcquireUnicast();
  static std::unique_ptr<LeAudioSourceAudioHalClient> AcquireBroadcast();
  static void DebugDump(int fd);

 private:
  bool SourceOnResumeReq(bool start_media_task);
  bool SourceOnSuspendReq();
  bool SourceOnMetadataUpdateReq(const sink_metadata_t& sink_metadata);

  LeAudioClientAudioSourceReceiver* audioSourceReceiver_ = nullptr;
  bluetooth::audio::le_audio::LeAudioClientInterface::Source*
      sourceClientInterface_ = nullptr;
};

class LeAudioUnicastClientAudioSource : public LeAudioClientAudioSource {
 public:
  virtual const void* Acquire();
};

class LeAudioBroadcastClientAudioSource : public LeAudioClientAudioSource {
 public:
  virtual const void* Acquire();
 protected:
  LeAudioSourceAudioHalClient() = default;
};
}  // namespace le_audio
Loading