Skip to content
Snippets Groups Projects
Commit f4672191 authored by Bao Do's avatar Bao Do
Browse files

HFP Audio client - header functions and client interface

Bug: 294134504
Bug: 315234036
Test: mmm packages/modules/Bluetooth/system/audio_hal_interface
Change-Id: I06b48e01750e5bdf016ad2e2f8f8ee9ee17f3388
parent ef20867d
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,7 @@
#include "client_interface_aidl.h"
#include <android/binder_manager.h>
#include <android_bluetooth_flags.h>
namespace bluetooth {
namespace audio {
......@@ -135,7 +136,7 @@ void BluetoothAudioClientInterface::FetchAudioProvider() {
CHECK(provider_ != nullptr);
binder_status_t binder_status = AIBinder_linkToDeath(
provider_factory->asBinder().get(), death_recipient_.get(), this);
provider_factory->asBinder().get(), death_recipient_.get(), this);
if (binder_status != STATUS_OK) {
LOG(ERROR) << "Failed to linkToDeath " << static_cast<int>(binder_status);
}
......@@ -155,8 +156,8 @@ BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() {
if (provider_factory_ != nullptr) {
AIBinder_unlinkToDeath(provider_factory_->asBinder().get(), death_recipient_.get(),
nullptr);
AIBinder_unlinkToDeath(provider_factory_->asBinder().get(),
death_recipient_.get(), nullptr);
}
}
......@@ -169,8 +170,8 @@ BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
BluetoothAudioSourceClientInterface::~BluetoothAudioSourceClientInterface() {
if (provider_factory_ != nullptr) {
AIBinder_unlinkToDeath(provider_factory_->asBinder().get(), death_recipient_.get(),
nullptr);
AIBinder_unlinkToDeath(provider_factory_->asBinder().get(),
death_recipient_.get(), nullptr);
}
}
......@@ -196,7 +197,12 @@ bool BluetoothAudioClientInterface::UpdateAudioConfig(
transport_->GetSessionType() ==
SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
transport_->GetSessionType() ==
SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
(IS_FLAG_ENABLED(is_sco_managed_by_audio) &&
(transport_->GetSessionType() ==
SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
transport_->GetSessionType() ==
SessionType::HFP_SOFTWARE_DECODING_DATAPATH)));
bool is_a2dp_offload_session =
(transport_->GetSessionType() ==
SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
......@@ -221,9 +227,15 @@ bool BluetoothAudioClientInterface::UpdateAudioConfig(
bool is_leaudio_broadcast_offload_audio_config =
(is_leaudio_broadcast_offload_session &&
audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
bool is_hfp_offload_audio_config =
(IS_FLAG_ENABLED(is_sco_managed_by_audio) &&
transport_->GetSessionType() ==
SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH &&
audio_config_tag == AudioConfiguration::hfpConfig);
if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
!is_leaudio_unicast_offload_audio_config &&
!is_leaudio_broadcast_offload_audio_config) {
!is_leaudio_broadcast_offload_audio_config &&
!is_hfp_offload_audio_config) {
return false;
}
transport_->UpdateAudioConfiguration(audio_config);
......@@ -315,7 +327,10 @@ int BluetoothAudioClientInterface::StartSession() {
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
transport_->GetSessionType() ==
SessionType::
LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
(IS_FLAG_ENABLED(is_sco_managed_by_audio) &&
transport_->GetSessionType() ==
SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH)) {
transport_->ResetPresentationPosition();
session_started_ = true;
return 0;
......@@ -406,7 +421,10 @@ void BluetoothAudioClientInterface::FlushAudioData() {
transport_->GetSessionType() ==
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
transport_->GetSessionType() ==
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
(IS_FLAG_ENABLED(is_sco_managed_by_audio) &&
transport_->GetSessionType() ==
SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH)) {
return;
}
......
/*
* Copyright 2023 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <cstdint>
#include "client_interface_aidl.h"
#include "common/message_loop_thread.h"
namespace bluetooth {
namespace audio {
namespace aidl {
namespace hfp {
using ::aidl::android::hardware::bluetooth::audio::LatencyMode;
typedef enum {
HFP_CTRL_CMD_NONE,
HFP_CTRL_CMD_CHECK_READY,
HFP_CTRL_CMD_START,
HFP_CTRL_CMD_STOP,
HFP_CTRL_CMD_SUSPEND,
HFP_CTRL_GET_INPUT_AUDIO_CONFIG,
HFP_CTRL_GET_OUTPUT_AUDIO_CONFIG,
HFP_CTRL_SET_OUTPUT_AUDIO_CONFIG,
HFP_CTRL_GET_PRESENTATION_POSITION,
} tHFP_CTRL_CMD;
// Provide call-in APIs for the Bluetooth Audio HAL
class HfpTransport {
public:
HfpTransport();
BluetoothAudioCtrlAck StartRequest();
BluetoothAudioCtrlAck SuspendRequest();
void StopRequest();
void SetLatencyMode(LatencyMode latency_mode);
bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
uint64_t* total_bytes_read,
timespec* data_position);
void SourceMetadataChanged(const source_metadata_v7_t& source_metadata);
void SinkMetadataChanged(const sink_metadata_v7_t&);
void ResetPresentationPosition();
uint8_t GetPendingCmd() const;
void ResetPendingCmd();
void LogBytesProcessed(size_t bytes_read);
private:
tHFP_CTRL_CMD hfp_pending_cmd_;
};
// Sink transport implementation
class HfpDecodingTransport
: public ::bluetooth::audio::aidl::IBluetoothSinkTransportInstance {
public:
HfpDecodingTransport(SessionType sessionType);
~HfpDecodingTransport();
BluetoothAudioCtrlAck StartRequest(bool is_low_latency);
BluetoothAudioCtrlAck SuspendRequest();
void StopRequest();
void SetLatencyMode(LatencyMode latency_mode);
bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
uint64_t* total_bytes_read,
timespec* data_position);
void SourceMetadataChanged(const source_metadata_v7_t& source_metadata);
void SinkMetadataChanged(const sink_metadata_v7_t& sink_metadata);
void ResetPresentationPosition();
void LogBytesRead(size_t bytes_read) override;
uint8_t GetPendingCmd() const;
void ResetPendingCmd();
static inline HfpDecodingTransport* instance_ = nullptr;
static inline BluetoothAudioSinkClientInterface* software_hal_interface =
nullptr;
static inline BluetoothAudioSinkClientInterface* offloading_hal_interface =
nullptr;
static inline BluetoothAudioSinkClientInterface* active_hal_interface =
nullptr;
private:
HfpTransport* transport_;
};
class HfpEncodingTransport
: public ::bluetooth::audio::aidl::IBluetoothSourceTransportInstance {
public:
HfpEncodingTransport(SessionType sessionType);
~HfpEncodingTransport();
BluetoothAudioCtrlAck StartRequest(bool is_low_latency);
BluetoothAudioCtrlAck SuspendRequest();
void StopRequest();
void SetLatencyMode(LatencyMode latency_mode);
bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
uint64_t* total_bytes_read,
timespec* data_position);
void SourceMetadataChanged(const source_metadata_v7_t& source_metadata);
void SinkMetadataChanged(const sink_metadata_v7_t& sink_metadata);
void ResetPresentationPosition();
void LogBytesWritten(size_t bytes_written) override;
uint8_t GetPendingCmd() const;
void ResetPendingCmd();
static inline HfpEncodingTransport* instance_ = nullptr;
static inline BluetoothAudioSourceClientInterface* software_hal_interface =
nullptr;
static inline BluetoothAudioSourceClientInterface* offloading_hal_interface =
nullptr;
static inline BluetoothAudioSourceClientInterface* active_hal_interface =
nullptr;
private:
HfpTransport* transport_;
};
} // namespace hfp
} // namespace aidl
} // namespace audio
} // namespace bluetooth
/*
* Copyright 2023 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "bta/ag/bta_ag_int.h"
#include "common/message_loop_thread.h"
namespace bluetooth {
namespace audio {
namespace hfp {
class HfpClientInterface {
private:
class IClientInterfaceEndpoint {
public:
virtual ~IClientInterfaceEndpoint() = default;
virtual void Cleanup() = 0;
virtual void StartSession() = 0;
virtual void StopSession() = 0;
virtual void UpdateAudioConfigToHal(
const ::hfp::offload_config& config) = 0;
};
public:
class Decode : public IClientInterfaceEndpoint {
public:
Decode(){};
virtual ~Decode() = default;
void Cleanup() override;
void StartSession() override;
void StopSession() override;
void UpdateAudioConfigToHal(const ::hfp::offload_config& config) override;
size_t Read(uint8_t* p_buf, uint32_t len);
};
class Encode : public IClientInterfaceEndpoint {
public:
virtual ~Encode() = default;
void Cleanup() override;
void StartSession() override;
void StopSession() override;
void UpdateAudioConfigToHal(const ::hfp::offload_config& config) override;
size_t Write(const uint8_t* p_buf, uint32_t len);
};
// Get HFP sink client interface if it's not previously acquired and not
// yet released.
Decode* GetDecode(bluetooth::common::MessageLoopThread* message_loop);
// Release sink interface if belongs to HFP client interface
bool ReleaseDecode(Decode* sink);
// Get HFP source client interface if it's not previously acquired and
// not yet released.
Encode* GetEncode(bluetooth::common::MessageLoopThread* message_loop);
// Release source interface if belongs to HFP client interface
bool ReleaseEncode(Encode* source);
// Get interface, if previously not initialized - it'll initialize singleton.
static HfpClientInterface* Get();
private:
static HfpClientInterface* interface;
Decode* decode_ = nullptr;
Encode* encode_ = nullptr;
};
} // namespace hfp
} // namespace audio
} // namespace bluetooth
......@@ -292,6 +292,17 @@ typedef uint16_t tBTA_AG_PEER_CODEC;
#define BTA_AG_AT_MAX_LEN 256
#endif
// Define hfp offload config structure
namespace hfp {
struct offload_config {
tBTA_AG_PEER_CODEC sco_codec;
int32_t connection_handle;
bool is_controller_codec;
bool is_nrec;
};
} // namespace hfp
/* data associated with BTA_AG_IND_RES */
typedef struct {
uint16_t id;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment