diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk index 627b54d..57e2f44 100644 --- a/BoardConfigCommon.mk +++ b/BoardConfigCommon.mk @@ -1,7 +1,7 @@ DEVICE_PATH := device/peter/gsi # Bluetooth -BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := $(DEVICE_PATH)/bluetooth/include +BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := $(DEVICE_PATH)/bluetooth # Props TARGET_SYSTEM_PROP := $(DEVICE_PATH)/system.prop diff --git a/bluetooth/audio/config/sysbta_audio_policy_configuration.xml b/bluetooth/audio/config/sysbta_audio_policy_configuration.xml deleted file mode 100644 index 79d1643..0000000 --- a/bluetooth/audio/config/sysbta_audio_policy_configuration.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bluetooth/audio/config/sysbta_audio_policy_configuration_7_0.xml b/bluetooth/audio/config/sysbta_audio_policy_configuration_7_0.xml deleted file mode 100644 index 47228b2..0000000 --- a/bluetooth/audio/config/sysbta_audio_policy_configuration_7_0.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bluetooth/audio/hal/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/hal/A2dpOffloadAudioProvider.cpp deleted file mode 100644 index 2d0d8c9..0000000 --- a/bluetooth/audio/hal/A2dpOffloadAudioProvider.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BTAudioProviderA2dpHW" - -#include "A2dpOffloadAudioProvider.h" - -#include -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -A2dpOffloadEncodingAudioProvider::A2dpOffloadEncodingAudioProvider() - : A2dpOffloadAudioProvider() { - session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH; -} - -A2dpOffloadDecodingAudioProvider::A2dpOffloadDecodingAudioProvider() - : A2dpOffloadAudioProvider() { - session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH; -} - -A2dpOffloadAudioProvider::A2dpOffloadAudioProvider() {} - -bool A2dpOffloadAudioProvider::isValid(const SessionType& session_type) { - return (session_type == session_type_); -} - -ndk::ScopedAStatus A2dpOffloadAudioProvider::startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, DataMQDesc* _aidl_return) { - if (audio_config.getTag() != AudioConfiguration::a2dpConfig) { - LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" - << audio_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid( - session_type_, audio_config.get())) { - LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" - << audio_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - return BluetoothAudioProvider::startSession( - host_if, audio_config, latency_modes, _aidl_return); -} - -ndk::ScopedAStatus A2dpOffloadAudioProvider::onSessionReady( - DataMQDesc* _aidl_return) { - *_aidl_return = DataMQDesc(); - BluetoothAudioSessionReport::OnSessionStarted( - session_type_, stack_iface_, nullptr, *audio_config_, latency_modes_); - return ndk::ScopedAStatus::ok(); -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/A2dpOffloadAudioProvider.h b/bluetooth/audio/hal/A2dpOffloadAudioProvider.h deleted file mode 100644 index e6f188b..0000000 --- a/bluetooth/audio/hal/A2dpOffloadAudioProvider.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - * 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 "BluetoothAudioProvider.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class A2dpOffloadAudioProvider : public BluetoothAudioProvider { - public: - A2dpOffloadAudioProvider(); - - bool isValid(const SessionType& session_type) override; - - ndk::ScopedAStatus startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); - - private: - ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; -}; - -class A2dpOffloadEncodingAudioProvider : public A2dpOffloadAudioProvider { - public: - A2dpOffloadEncodingAudioProvider(); -}; - -class A2dpOffloadDecodingAudioProvider : public A2dpOffloadAudioProvider { - public: - A2dpOffloadDecodingAudioProvider(); -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/hal/A2dpSoftwareAudioProvider.cpp deleted file mode 100644 index bd2da95..0000000 --- a/bluetooth/audio/hal/A2dpSoftwareAudioProvider.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BTAudioProviderA2dpSW" - -#include "A2dpSoftwareAudioProvider.h" - -#include -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -// Here the buffer size is based on SBC -static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo -// SBC is 128, and here we choose the LCM of 16, 24, and 32 -static constexpr uint32_t kPcmFrameCount = 96; -static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount; -// The max counts by 1 tick (20ms) for SBC is about 7. Since using 96 for the -// PCM counts, here we just choose a greater number -static constexpr uint32_t kRtpFrameCount = 10; -static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount; -static constexpr uint32_t kBufferCount = 2; // double buffer -static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount; - -A2dpSoftwareEncodingAudioProvider::A2dpSoftwareEncodingAudioProvider() - : A2dpSoftwareAudioProvider() { - session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH; -} - -A2dpSoftwareDecodingAudioProvider::A2dpSoftwareDecodingAudioProvider() - : A2dpSoftwareAudioProvider() { - session_type_ = SessionType::A2DP_SOFTWARE_DECODING_DATAPATH; -} - -A2dpSoftwareAudioProvider::A2dpSoftwareAudioProvider() - : BluetoothAudioProvider(), data_mq_(nullptr) { - LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize - << " byte(s)"; - std::unique_ptr data_mq( - new DataMQ(kDataMqSize, /* EventFlag */ true)); - if (data_mq && data_mq->isValid()) { - data_mq_ = std::move(data_mq); - } else { - ALOGE_IF(!data_mq, "failed to allocate data MQ"); - ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid"); - } -} - -bool A2dpSoftwareAudioProvider::isValid(const SessionType& sessionType) { - return (sessionType == session_type_ && data_mq_ && data_mq_->isValid()); -} - -ndk::ScopedAStatus A2dpSoftwareAudioProvider::startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, DataMQDesc* _aidl_return) { - if (audio_config.getTag() != AudioConfiguration::pcmConfig) { - LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" - << audio_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - const PcmConfiguration& pcm_config = - audio_config.get(); - if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { - LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" - << pcm_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - - return BluetoothAudioProvider::startSession( - host_if, audio_config, latency_modes, _aidl_return); -} - -ndk::ScopedAStatus A2dpSoftwareAudioProvider::onSessionReady( - DataMQDesc* _aidl_return) { - if (data_mq_ == nullptr || !data_mq_->isValid()) { - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - *_aidl_return = data_mq_->dupeDesc(); - auto desc = data_mq_->dupeDesc(); - BluetoothAudioSessionReport::OnSessionStarted( - session_type_, stack_iface_, &desc, *audio_config_, latency_modes_); - return ndk::ScopedAStatus::ok(); -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/A2dpSoftwareAudioProvider.h b/bluetooth/audio/hal/A2dpSoftwareAudioProvider.h deleted file mode 100644 index 3ebecf2..0000000 --- a/bluetooth/audio/hal/A2dpSoftwareAudioProvider.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - * 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 "BluetoothAudioProvider.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class A2dpSoftwareAudioProvider : public BluetoothAudioProvider { - public: - A2dpSoftwareAudioProvider(); - - bool isValid(const SessionType& sessionType) override; - - ndk::ScopedAStatus startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); - - private: - // audio data queue for software encoding - std::unique_ptr data_mq_; - - ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; -}; - -class A2dpSoftwareEncodingAudioProvider : public A2dpSoftwareAudioProvider { - public: - A2dpSoftwareEncodingAudioProvider(); -}; - -class A2dpSoftwareDecodingAudioProvider : public A2dpSoftwareAudioProvider { - public: - A2dpSoftwareDecodingAudioProvider(); -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/Android.bp b/bluetooth/audio/hal/Android.bp deleted file mode 100644 index e52a6b7..0000000 --- a/bluetooth/audio/hal/Android.bp +++ /dev/null @@ -1,92 +0,0 @@ -cc_library_shared { - name: "android.hardware.bluetooth.audio-system-impl", - vintf_fragments: ["bluetooth_audio.xml"], - srcs: [ - "BluetoothAudioProvider.cpp", - "BluetoothAudioProviderFactory.cpp", - "A2dpOffloadAudioProvider.cpp", - "A2dpSoftwareAudioProvider.cpp", - "HearingAidAudioProvider.cpp", - "LeAudioOffloadAudioProvider.cpp", - "LeAudioSoftwareAudioProvider.cpp", - "service.cpp", - ], - export_include_dirs: ["."], - header_libs: ["libhardware_headers"], - shared_libs: [ - "libbase", - "libbinder_ndk", - "libcutils", - "libfmq", - "liblog", - "android.hardware.bluetooth.audio-V2-ndk", - "libbluetooth_audio_session_aidl_system", - ], -} - -cc_binary { - name: "android.hardware.bluetooth.audio-service-system", - vintf_fragments: ["bluetooth_audio_system.xml"], - init_rc: ["android.hardware.bluetooth.audio-service-system.rc"], - relative_install_path: "hw", - srcs: [ - "BluetoothAudioProvider.cpp", - "BluetoothAudioProviderFactory.cpp", - "A2dpOffloadAudioProvider.cpp", - "A2dpSoftwareAudioProvider.cpp", - "HearingAidAudioProvider.cpp", - "LeAudioOffloadAudioProvider.cpp", - "LeAudioSoftwareAudioProvider.cpp", - "Device.cpp", - "DevicesFactory.cpp", - "ParametersUtil.cpp", - "PrimaryDevice.cpp", - "Stream.cpp", - "StreamIn.cpp", - "StreamOut.cpp", - "service_system.cpp", - ], - header_libs: [ - "libhardware_headers", - "android.hardware.audio.common.util@all-versions", - "libaudioutils_headers", - "libaudio_system_headers", - "libmedia_headers", - "libmediautils_headers", - ], - shared_libs: [ - "libbase", - "libbinder", - "libbinder_ndk", - "libcutils", - "libfmq", - "liblog", - "android.hardware.bluetooth.audio-V2-ndk", - "libbluetooth_audio_session_aidl_system", - "libfmq", - "libhardware", - "libhidlbase", - "liblog", - "libmedia_helper", - "libmediautils_vendor", - "libmemunreachable", - "libutils", - "android.hardware.audio.common-util", - "android.hardware.audio@6.0", -// "android.hardware.audio@7.1", - "android.hardware.audio@6.0-util", - "android.hardware.audio.common@6.0", -// "android.hardware.audio.common@6.0-enums", - "android.hardware.audio.common@6.0-util", - ], - static_libs: [ - "libaudiofoundation", - ], - cflags: [ - "-DMAJOR_VERSION=6", - "-DMINOR_VERSION=0", - "-DCOMMON_TYPES_MINOR_VERSION=0", - "-DCORE_TYPES_MINOR_VERSION=0", - "-include common/all-versions/VersionMacro.h", - ], -} diff --git a/bluetooth/audio/hal/BluetoothAudioProvider.cpp b/bluetooth/audio/hal/BluetoothAudioProvider.cpp deleted file mode 100644 index 2a88959..0000000 --- a/bluetooth/audio/hal/BluetoothAudioProvider.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BTAudioProviderStub" - -#include "BluetoothAudioProvider.h" - -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -BluetoothAudioProvider::BluetoothAudioProvider() { - death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient( - AIBinder_DeathRecipient_new(binderDiedCallbackAidl)); -} - -ndk::ScopedAStatus BluetoothAudioProvider::startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latencyModes, - DataMQDesc* _aidl_return) { - if (host_if == nullptr) { - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - - latency_modes_ = latencyModes; - audio_config_ = std::make_unique(audio_config); - stack_iface_ = host_if; - is_binder_died = false; - - AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(), - this); - - onSessionReady(_aidl_return); - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus BluetoothAudioProvider::endSession() { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); - - if (stack_iface_ != nullptr) { - BluetoothAudioSessionReport::OnSessionEnded(session_type_); - - if (!is_binder_died) { - AIBinder_unlinkToDeath(stack_iface_->asBinder().get(), - death_recipient_.get(), this); - } - } else { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - } - - stack_iface_ = nullptr; - audio_config_ = nullptr; - - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus BluetoothAudioProvider::streamStarted( - BluetoothAudioStatus status) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << ", status=" << toString(status); - - if (stack_iface_ != nullptr) { - BluetoothAudioSessionReport::ReportControlStatus(session_type_, true, - status); - } else { - LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) - << ", status=" << toString(status) << " has NO session"; - } - - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus BluetoothAudioProvider::streamSuspended( - BluetoothAudioStatus status) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << ", status=" << toString(status); - - if (stack_iface_ != nullptr) { - BluetoothAudioSessionReport::ReportControlStatus(session_type_, false, - status); - } else { - LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) - << ", status=" << toString(status) << " has NO session"; - } - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus BluetoothAudioProvider::updateAudioConfiguration( - const AudioConfiguration& audio_config) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); - - if (stack_iface_ == nullptr || audio_config_ == nullptr) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - - if (audio_config.getTag() != audio_config_->getTag()) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << " audio config type is not match"; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - - audio_config_ = std::make_unique(audio_config); - BluetoothAudioSessionReport::ReportAudioConfigChanged(session_type_, - *audio_config_); - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus BluetoothAudioProvider::setLowLatencyModeAllowed( - bool allowed) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); - - if (stack_iface_ == nullptr) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - LOG(INFO) << __func__ << " - allowed " << allowed; - BluetoothAudioSessionReport::ReportLowLatencyModeAllowedChanged( - session_type_, allowed); - return ndk::ScopedAStatus::ok(); -} - -void BluetoothAudioProvider::binderDiedCallbackAidl(void* ptr) { - LOG(ERROR) << __func__ << " - BluetoothAudio Service died"; - auto provider = static_cast(ptr); - if (provider == nullptr) { - LOG(ERROR) << __func__ << ": Null AudioProvider HAL died"; - return; - } - provider->is_binder_died = true; - provider->endSession(); -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/hal/BluetoothAudioProvider.h b/bluetooth/audio/hal/BluetoothAudioProvider.h deleted file mode 100644 index dbfff7d..0000000 --- a/bluetooth/audio/hal/BluetoothAudioProvider.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - * 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 -#include -#include -#include - -using ::aidl::android::hardware::common::fmq::MQDescriptor; -using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; -using ::android::AidlMessageQueue; - -using MqDataType = int8_t; -using MqDataMode = SynchronizedReadWrite; -using DataMQ = AidlMessageQueue; -using DataMQDesc = MQDescriptor; - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class BluetoothAudioProvider : public BnBluetoothAudioProvider { - public: - BluetoothAudioProvider(); - ndk::ScopedAStatus startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); - ndk::ScopedAStatus endSession(); - ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status); - ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status); - ndk::ScopedAStatus updateAudioConfiguration( - const AudioConfiguration& audio_config); - ndk::ScopedAStatus setLowLatencyModeAllowed(bool allowed); - - virtual bool isValid(const SessionType& sessionType) = 0; - - protected: - virtual ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) = 0; - static void binderDiedCallbackAidl(void* cookie_ptr); - - ::ndk::ScopedAIBinder_DeathRecipient death_recipient_; - - std::shared_ptr stack_iface_; - std::unique_ptr audio_config_ = nullptr; - SessionType session_type_; - std::vector latency_modes_; - bool is_binder_died = false; -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/hal/BluetoothAudioProviderFactory.cpp deleted file mode 100644 index 91731d4..0000000 --- a/bluetooth/audio/hal/BluetoothAudioProviderFactory.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BTAudioProviderFactoryAIDL" - -#include "BluetoothAudioProviderFactory.h" - -#include -#include - -#include "A2dpOffloadAudioProvider.h" -#include "A2dpSoftwareAudioProvider.h" -#include "BluetoothAudioProvider.h" -#include "HearingAidAudioProvider.h" -#include "LeAudioOffloadAudioProvider.h" -#include "LeAudioSoftwareAudioProvider.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {} - -ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider( - const SessionType session_type, - std::shared_ptr* _aidl_return) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type); - std::shared_ptr provider = nullptr; - - switch (session_type) { - case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: - provider = - ndk::SharedRefBase::make(); - break; - case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - provider = - ndk::SharedRefBase::make(); - break; - case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: - provider = ndk::SharedRefBase::make(); - break; - default: - provider = nullptr; - break; - } - - if (provider == nullptr || !provider->isValid(session_type)) { - provider = nullptr; - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - *_aidl_return = provider; - - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderCapabilities( - const SessionType session_type, - std::vector* _aidl_return) { - if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - auto codec_capabilities = - BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(session_type); - _aidl_return->resize(codec_capabilities.size()); - for (int i = 0; i < codec_capabilities.size(); i++) { - _aidl_return->at(i).set( - codec_capabilities[i]); - } - } else if (session_type == - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type == - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || - session_type == - SessionType:: - LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { - std::vector db_codec_capabilities = - BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(session_type); - if (db_codec_capabilities.size()) { - _aidl_return->resize(db_codec_capabilities.size()); - for (int i = 0; i < db_codec_capabilities.size(); ++i) { - _aidl_return->at(i).set( - db_codec_capabilities[i]); - } - } - } else if (session_type != SessionType::UNKNOWN) { - auto pcm_capabilities = BluetoothAudioCodecs::GetSoftwarePcmCapabilities(); - _aidl_return->resize(pcm_capabilities.size()); - for (int i = 0; i < pcm_capabilities.size(); i++) { - _aidl_return->at(i).set( - pcm_capabilities[i]); - } - } - - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type) - << " supports " << _aidl_return->size() << " codecs"; - return ndk::ScopedAStatus::ok(); -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/hal/BluetoothAudioProviderFactory.h b/bluetooth/audio/hal/BluetoothAudioProviderFactory.h deleted file mode 100644 index b38cfd2..0000000 --- a/bluetooth/audio/hal/BluetoothAudioProviderFactory.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - * 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 - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class BluetoothAudioProviderFactory : public BnBluetoothAudioProviderFactory { - public: - BluetoothAudioProviderFactory(); - - ndk::ScopedAStatus openProvider( - const SessionType session_type, - std::shared_ptr* _aidl_return) override; - - ndk::ScopedAStatus getProviderCapabilities( - const SessionType session_type, - std::vector* _aidl_return) override; -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/Device.cpp b/bluetooth/audio/hal/Device.cpp deleted file mode 100644 index 85b2768..0000000 --- a/bluetooth/audio/hal/Device.cpp +++ /dev/null @@ -1,628 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#define LOG_TAG "DeviceHAL" - -#include "Device.h" -#include "common/all-versions/default/EffectMap.h" -#include "StreamIn.h" -#include "StreamOut.h" -#include "Util.h" - -//#define LOG_NDEBUG 0 - -#include -#include -#include -#include - -#include -#include -#include - -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils; -namespace util { -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; -} - -Device::Device(audio_hw_device_t* device) : mIsClosed(false), mDevice(device) {} - -Device::~Device() { - (void)doClose(); - mDevice = nullptr; -} - -Result Device::analyzeStatus(const char* funcName, int status, - const std::vector& ignoreErrors) { - return util::analyzeStatus("Device", funcName, status, ignoreErrors); -} - -void Device::closeInputStream(audio_stream_in_t* stream) { - mDevice->close_input_stream(mDevice, stream); - LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0"); - --mOpenedStreamsCount; -} - -void Device::closeOutputStream(audio_stream_out_t* stream) { - mDevice->close_output_stream(mDevice, stream); - LOG_ALWAYS_FATAL_IF(mOpenedStreamsCount == 0, "mOpenedStreamsCount is already 0"); - --mOpenedStreamsCount; -} - -char* Device::halGetParameters(const char* keys) { - return mDevice->get_parameters(mDevice, keys); -} - -int Device::halSetParameters(const char* keysAndValues) { - return mDevice->set_parameters(mDevice, keysAndValues); -} - -// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow. -Return Device::initCheck() { - return analyzeStatus("init_check", mDevice->init_check(mDevice)); -} - -Return Device::setMasterVolume(float volume) { - if (mDevice->set_master_volume == NULL) { - return Result::NOT_SUPPORTED; - } - if (!util::isGainNormalized(volume)) { - ALOGW("Can not set a master volume (%f) outside [0,1]", volume); - return Result::INVALID_ARGUMENTS; - } - return analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume), - {ENOSYS} /*ignore*/); -} - -Return Device::getMasterVolume(getMasterVolume_cb _hidl_cb) { - Result retval(Result::NOT_SUPPORTED); - float volume = 0; - if (mDevice->get_master_volume != NULL) { - retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume), - {ENOSYS} /*ignore*/); - } - _hidl_cb(retval, volume); - return Void(); -} - -Return Device::setMicMute(bool mute) { - return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute), {ENOSYS} /*ignore*/); -} - -Return Device::getMicMute(getMicMute_cb _hidl_cb) { - bool mute = false; - Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute), - {ENOSYS} /*ignore*/); - _hidl_cb(retval, mute); - return Void(); -} - -Return Device::setMasterMute(bool mute) { - Result retval(Result::NOT_SUPPORTED); - if (mDevice->set_master_mute != NULL) { - retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute), - {ENOSYS} /*ignore*/); - } - return retval; -} - -Return Device::getMasterMute(getMasterMute_cb _hidl_cb) { - Result retval(Result::NOT_SUPPORTED); - bool mute = false; - if (mDevice->get_master_mute != NULL) { - retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute), - {ENOSYS} /*ignore*/); - } - _hidl_cb(retval, mute); - return Void(); -} - -Return Device::getInputBufferSize(const AudioConfig& config, getInputBufferSize_cb _hidl_cb) { - audio_config_t halConfig; - Result retval(Result::INVALID_ARGUMENTS); - uint64_t bufferSize = 0; - if (HidlUtils::audioConfigToHal(config, &halConfig) == NO_ERROR) { - size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig); - if (halBufferSize != 0) { - retval = Result::OK; - bufferSize = halBufferSize; - } - } - _hidl_cb(retval, bufferSize); - return Void(); -} - -std::tuple> Device::openOutputStreamCore(int32_t ioHandle, - const DeviceAddress& device, - const AudioConfig& config, - const AudioOutputFlags& flags, - AudioConfig* suggestedConfig) { - audio_config_t halConfig; - if (HidlUtils::audioConfigToHal(config, &halConfig) != NO_ERROR) { - return {Result::INVALID_ARGUMENTS, nullptr}; - } - audio_stream_out_t* halStream; - audio_devices_t halDevice; - char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { - return {Result::INVALID_ARGUMENTS, nullptr}; - } - audio_output_flags_t halFlags; - if (CoreUtils::audioOutputFlagsToHal(flags, &halFlags) != NO_ERROR) { - return {Result::INVALID_ARGUMENTS, nullptr}; - } - ALOGV("open_output_stream handle: %d devices: %x flags: %#x " - "srate: %d format %#x channels %x address %s", - ioHandle, halDevice, halFlags, halConfig.sample_rate, halConfig.format, - halConfig.channel_mask, halDeviceAddress); - int status = mDevice->open_output_stream(mDevice, ioHandle, halDevice, halFlags, &halConfig, - &halStream, halDeviceAddress); - ALOGV("open_output_stream status %d stream %p", status, halStream); - sp streamOut; - if (status == OK) { - streamOut = new StreamOut(this, halStream); - ++mOpenedStreamsCount; - } - status_t convertStatus = - HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, suggestedConfig); - ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__); - return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut}; -} - -std::tuple> Device::openInputStreamCore( - int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig) { - audio_config_t halConfig; - if (HidlUtils::audioConfigToHal(config, &halConfig) != NO_ERROR) { - return {Result::INVALID_ARGUMENTS, nullptr}; - } - audio_stream_in_t* halStream; - audio_devices_t halDevice; - char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { - return {Result::INVALID_ARGUMENTS, nullptr}; - } - audio_input_flags_t halFlags; - audio_source_t halSource; - if (CoreUtils::audioInputFlagsToHal(flags, &halFlags) != NO_ERROR || - HidlUtils::audioSourceToHal(source, &halSource) != NO_ERROR) { - return {Result::INVALID_ARGUMENTS, nullptr}; - } - ALOGV("open_input_stream handle: %d devices: %x flags: %#x " - "srate: %d format %#x channels %x address %s source %d", - ioHandle, halDevice, halFlags, halConfig.sample_rate, halConfig.format, - halConfig.channel_mask, halDeviceAddress, halSource); - int status = mDevice->open_input_stream(mDevice, ioHandle, halDevice, &halConfig, &halStream, - halFlags, halDeviceAddress, halSource); - ALOGV("open_input_stream status %d stream %p", status, halStream); - sp streamIn; - if (status == OK) { - streamIn = new StreamIn(this, halStream); - ++mOpenedStreamsCount; - } - status_t convertStatus = - HidlUtils::audioConfigFromHal(halConfig, true /*isInput*/, suggestedConfig); - ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__); - return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn}; -} - -#if MAJOR_VERSION == 2 -Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioOutputFlags flags, - openOutputStream_cb _hidl_cb) { - AudioConfig suggestedConfig; - auto [result, streamOut] = - openOutputStreamCore(ioHandle, device, config, flags, &suggestedConfig); - _hidl_cb(result, streamOut, suggestedConfig); - return Void(); -} - -Return Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlags flags, - AudioSource source, openInputStream_cb _hidl_cb) { - AudioConfig suggestedConfig; - auto [result, streamIn] = - openInputStreamCore(ioHandle, device, config, flags, source, &suggestedConfig); - _hidl_cb(result, streamIn, suggestedConfig); - return Void(); -} - -#elif MAJOR_VERSION >= 4 -std::tuple, AudioConfig> Device::openOutputStreamImpl( - int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - const SourceMetadata& sourceMetadata, -#if MAJOR_VERSION <= 6 - AudioOutputFlags flags) { - if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr); - status != NO_ERROR) { -#else - const AudioOutputFlags& flags) { - if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata, - false /*ignoreNonVendorTags*/, nullptr); - status != NO_ERROR) { -#endif - return {analyzeStatus("sourceMetadataToHal", status), nullptr, {}}; - } - AudioConfig suggestedConfig; - auto [result, streamOut] = - openOutputStreamCore(ioHandle, device, config, flags, &suggestedConfig); - if (streamOut) { - streamOut->updateSourceMetadata(sourceMetadata); - } - return {result, streamOut, suggestedConfig}; -} - -Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioOutputFlags flags, -#else - const AudioOutputFlags& flags, -#endif - const SourceMetadata& sourceMetadata, - openOutputStream_cb _hidl_cb) { - auto [result, streamOut, suggestedConfig] = - openOutputStreamImpl(ioHandle, device, config, sourceMetadata, flags); - _hidl_cb(result, streamOut, suggestedConfig); - return Void(); -} - -std::tuple, AudioConfig> Device::openInputStreamImpl( - int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioInputFlags flags, -#else - const AudioInputFlags& flags, -#endif - const SinkMetadata& sinkMetadata) { - if (sinkMetadata.tracks.size() == 0) { - // This should never happen, the framework must not create as stream - // if there is no client - ALOGE("openInputStream called without tracks connected"); - return {Result::INVALID_ARGUMENTS, nullptr, AudioConfig{}}; - } -#if MAJOR_VERSION <= 6 - if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) { -#else - if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata, - false /*ignoreNonVendorTags*/, nullptr); - status != NO_ERROR) { -#endif - return {analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{}}; - } - // Pick the first one as the main. - AudioSource source = sinkMetadata.tracks[0].source; - AudioConfig suggestedConfig; - auto [result, streamIn] = - openInputStreamCore(ioHandle, device, config, flags, source, &suggestedConfig); - if (streamIn) { - streamIn->updateSinkMetadata(sinkMetadata); - } - return {result, streamIn, suggestedConfig}; -} - -Return Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioInputFlags flags, -#else - const AudioInputFlags& flags, -#endif - const SinkMetadata& sinkMetadata, - openInputStream_cb _hidl_cb) { - auto [result, streamIn, suggestedConfig] = - openInputStreamImpl(ioHandle, device, config, flags, sinkMetadata); - _hidl_cb(result, streamIn, suggestedConfig); - return Void(); -} -#endif /* MAJOR_VERSION */ - -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 -Return Device::openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, const AudioOutputFlags& flags, - const SourceMetadata& sourceMetadata, - openOutputStream_7_1_cb _hidl_cb) { - auto [result, streamOut, suggestedConfig] = - openOutputStreamImpl(ioHandle, device, config, sourceMetadata, flags); - _hidl_cb(result, streamOut, suggestedConfig); - return Void(); -} -#endif // V7.1 - -Return Device::supportsAudioPatches() { - return version() >= AUDIO_DEVICE_API_VERSION_3_0; -} - -Return Device::createAudioPatch(const hidl_vec& sources, - const hidl_vec& sinks, - createAudioPatch_cb _hidl_cb) { - auto [retval, patch] = createOrUpdateAudioPatch(AudioPatchHandle{}, sources, sinks); - _hidl_cb(retval, patch); - return Void(); -} - -std::tuple Device::createOrUpdateAudioPatch( - AudioPatchHandle patch, const hidl_vec& sources, - const hidl_vec& sinks) { - Result retval(Result::NOT_SUPPORTED); - if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { - audio_patch_handle_t halPatch = static_cast(patch); - std::unique_ptr halSources; - if (status_t status = HidlUtils::audioPortConfigsToHal(sources, &halSources); - status != NO_ERROR) { - return {analyzeStatus("audioPortConfigsToHal;sources", status), patch}; - } - std::unique_ptr halSinks; - if (status_t status = HidlUtils::audioPortConfigsToHal(sinks, &halSinks); - status != NO_ERROR) { - return {analyzeStatus("audioPortConfigsToHal;sinks", status), patch}; - } - retval = analyzeStatus("create_audio_patch", - mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0], - sinks.size(), &halSinks[0], &halPatch)); - if (retval == Result::OK) { - patch = static_cast(halPatch); - } - } - return {retval, patch}; -} - -Return Device::releaseAudioPatch(int32_t patch) { - if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { - return analyzeStatus( - "release_audio_patch", - mDevice->release_audio_patch(mDevice, static_cast(patch))); - } - return Result::NOT_SUPPORTED; -} - -template -Return Device::getAudioPortImpl(const AudioPort& port, getAudioPort_cb _hidl_cb, - int (*halGetter)(audio_hw_device_t*, HalPort*), - const char* halGetterName) { - HalPort halPort; - if (status_t status = HidlUtils::audioPortToHal(port, &halPort); status != NO_ERROR) { - _hidl_cb(analyzeStatus("audioPortToHal", status), port); - return Void(); - } - Result retval = analyzeStatus(halGetterName, halGetter(mDevice, &halPort)); - AudioPort resultPort = port; - if (retval == Result::OK) { - if (status_t status = HidlUtils::audioPortFromHal(halPort, &resultPort); - status != NO_ERROR) { - _hidl_cb(analyzeStatus("audioPortFromHal", status), port); - return Void(); - } - } - _hidl_cb(retval, resultPort); - return Void(); -} - -#if MAJOR_VERSION <= 6 -Return Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { - return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port, "get_audio_port"); -} -#else -Return Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { - if (version() >= AUDIO_DEVICE_API_VERSION_3_2) { - // get_audio_port_v7 is mandatory if legacy HAL support this API version. - return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port_v7, "get_audio_port_v7"); - } else { - return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port, "get_audio_port"); - } -} -#endif - -Return Device::setAudioPortConfig(const AudioPortConfig& config) { - if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { - struct audio_port_config halPortConfig; - if (status_t status = HidlUtils::audioPortConfigToHal(config, &halPortConfig); - status != NO_ERROR) { - return analyzeStatus("audioPortConfigToHal", status); - } - return analyzeStatus("set_audio_port_config", - mDevice->set_audio_port_config(mDevice, &halPortConfig)); - } - return Result::NOT_SUPPORTED; -} - -#if MAJOR_VERSION == 2 -Return Device::getHwAvSync() { - int halHwAvSync; - Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); - return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID; -} -#elif MAJOR_VERSION >= 4 -Return Device::getHwAvSync(getHwAvSync_cb _hidl_cb) { - int halHwAvSync; - Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); - _hidl_cb(retval, halHwAvSync); - return Void(); -} -#endif - -Return Device::setScreenState(bool turnedOn) { - return setParam(AudioParameter::keyScreenState, turnedOn); -} - -#if MAJOR_VERSION == 2 -Return Device::getParameters(const hidl_vec& keys, getParameters_cb _hidl_cb) { - getParametersImpl({}, keys, _hidl_cb); - return Void(); -} - -Return Device::setParameters(const hidl_vec& parameters) { - return setParametersImpl({} /* context */, parameters); -} -#elif MAJOR_VERSION >= 4 -Return Device::getParameters(const hidl_vec& context, - const hidl_vec& keys, getParameters_cb _hidl_cb) { - getParametersImpl(context, keys, _hidl_cb); - return Void(); -} -Return Device::setParameters(const hidl_vec& context, - const hidl_vec& parameters) { - return setParametersImpl(context, parameters); -} -#endif - -#if MAJOR_VERSION == 2 -Return Device::debugDump(const hidl_handle& fd) { - return debug(fd, {}); -} -#endif - -Return Device::debug(const hidl_handle& fd, const hidl_vec& options) { - if (fd.getNativeHandle() != nullptr && fd->numFds == 1) { - const int fd0 = fd->data[0]; - bool dumpMem = false; - bool unreachableMemory = false; - for (const auto& option : options) { - if (option == "-m") { - dumpMem = true; - } else if (option == "--unreachable") { - unreachableMemory = true; - } - } - - if (dumpMem) { - dprintf(fd0, "\nDumping memory:\n"); - std::string s = dumpMemoryAddresses(100 /* limit */); - write(fd0, s.c_str(), s.size()); - } - if (unreachableMemory) { - dprintf(fd0, "\nDumping unreachable memory:\n"); - // TODO - should limit be an argument parameter? - std::string s = GetUnreachableMemoryString(true /* contents */, 100 /* limit */); - write(fd0, s.c_str(), s.size()); - } - - analyzeStatus("dump", mDevice->dump(mDevice, fd0)); - } - return Void(); -} - -#if MAJOR_VERSION >= 4 -Return Device::getMicrophones(getMicrophones_cb _hidl_cb) { - Result retval = Result::NOT_SUPPORTED; - size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT; - audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT]; - - hidl_vec microphones; - if (mDevice->get_microphones != NULL && - mDevice->get_microphones(mDevice, &mic_array[0], &actual_mics) == 0) { - microphones.resize(actual_mics); - for (size_t i = 0; i < actual_mics; ++i) { - (void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]); - } - retval = Result::OK; - } - _hidl_cb(retval, microphones); - return Void(); -} - -Return Device::setConnectedState(const DeviceAddress& address, bool connected) { - auto key = connected ? AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect; - return setParam(key, address); -} -#endif - -Result Device::doClose() { - if (mIsClosed || mOpenedStreamsCount != 0) return Result::INVALID_STATE; - mIsClosed = true; - return analyzeStatus("close", audio_hw_device_close(mDevice)); -} - -#if MAJOR_VERSION >= 6 -Return Device::close() { - return doClose(); -} - -Return Device::addDeviceEffect(AudioPortHandle device, uint64_t effectId) { - if (version() < AUDIO_DEVICE_API_VERSION_3_1 || mDevice->add_device_effect == nullptr) { - return Result::NOT_SUPPORTED; - } - - effect_handle_t halEffect = EffectMap::getInstance().get(effectId); - if (halEffect != NULL) { - return analyzeStatus("add_device_effect", - mDevice->add_device_effect( - mDevice, static_cast(device), halEffect)); - } else { - ALOGW("%s Invalid effect ID passed from client: %" PRIu64 "", __func__, effectId); - return Result::INVALID_ARGUMENTS; - } -} - -Return Device::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) { - if (version() < AUDIO_DEVICE_API_VERSION_3_1 || mDevice->remove_device_effect == nullptr) { - return Result::NOT_SUPPORTED; - } - - effect_handle_t halEffect = EffectMap::getInstance().get(effectId); - if (halEffect != NULL) { - return analyzeStatus("remove_device_effect", - mDevice->remove_device_effect( - mDevice, static_cast(device), halEffect)); - } else { - ALOGW("%s Invalid effect ID passed from client: %" PRIu64 "", __func__, effectId); - return Result::INVALID_ARGUMENTS; - } -} - -Return Device::updateAudioPatch(int32_t previousPatch, - const hidl_vec& sources, - const hidl_vec& sinks, - createAudioPatch_cb _hidl_cb) { - if (previousPatch != static_cast(AudioPatchHandle{})) { - auto [retval, patch] = createOrUpdateAudioPatch(previousPatch, sources, sinks); - _hidl_cb(retval, patch); - } else { - _hidl_cb(Result::INVALID_ARGUMENTS, previousPatch); - } - return Void(); -} - -#endif - -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 -Return Device::setConnectedState_7_1(const AudioPort& devicePort, bool connected) { - if (version() >= AUDIO_DEVICE_API_VERSION_3_2 && - mDevice->set_device_connected_state_v7 != nullptr) { - audio_port_v7 halPort; - if (status_t status = HidlUtils::audioPortToHal(devicePort, &halPort); status != NO_ERROR) { - return analyzeStatus("audioPortToHal", status); - } - return analyzeStatus("set_device_connected_state_v7", - mDevice->set_device_connected_state_v7(mDevice, &halPort, connected)); - } - return Result::NOT_SUPPORTED; -} -#endif - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/bluetooth/audio/hal/Device.h b/bluetooth/audio/hal/Device.h deleted file mode 100644 index 0696f97..0000000 --- a/bluetooth/audio/hal/Device.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_DEVICE_H -#define ANDROID_HARDWARE_AUDIO_DEVICE_H - -#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h) - -#include "ParametersUtil.h" - -#include - -#include -#include - -#include - -#include - -#include -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils; -using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::ParametersUtil; -using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CPP_VERSION; -using AudioInputFlags = CoreUtils::AudioInputFlags; -using AudioOutputFlags = CoreUtils::AudioOutputFlags; - -struct Device : public IDevice, public ParametersUtil { - explicit Device(audio_hw_device_t* device); - - // Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow. - Return initCheck() override; - Return setMasterVolume(float volume) override; - Return getMasterVolume(getMasterVolume_cb _hidl_cb) override; - Return setMicMute(bool mute) override; - Return getMicMute(getMicMute_cb _hidl_cb) override; - Return setMasterMute(bool mute) override; - Return getMasterMute(getMasterMute_cb _hidl_cb) override; - Return getInputBufferSize(const AudioConfig& config, - getInputBufferSize_cb _hidl_cb) override; - - std::tuple> openOutputStreamCore(int32_t ioHandle, - const DeviceAddress& device, - const AudioConfig& config, - const AudioOutputFlags& flags, - AudioConfig* suggestedConfig); - std::tuple> openInputStreamCore( - int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig); -#if MAJOR_VERSION >= 4 - std::tuple, AudioConfig> openOutputStreamImpl( - int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - const SourceMetadata& sourceMetadata, -#if MAJOR_VERSION <= 6 - AudioOutputFlags flags); -#else - const AudioOutputFlags& flags); -#endif - std::tuple, AudioConfig> openInputStreamImpl( - int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioInputFlags flags, -#else - const AudioInputFlags& flags, -#endif - const SinkMetadata& sinkMetadata); -#endif // MAJOR_VERSION >= 4 - - Return openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioOutputFlags flags, -#else - const AudioOutputFlags& flags, -#endif -#if MAJOR_VERSION >= 4 - const SourceMetadata& sourceMetadata, -#endif - openOutputStream_cb _hidl_cb) override; - Return openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioInputFlags flags, -#else - const AudioInputFlags& flags, -#endif -#if MAJOR_VERSION == 2 - AudioSource source, -#elif MAJOR_VERSION >= 4 - const SinkMetadata& sinkMetadata, -#endif - openInputStream_cb _hidl_cb) override; - -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 - Return openOutputStream_7_1(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, const AudioOutputFlags& flags, - const SourceMetadata& sourceMetadata, - openOutputStream_7_1_cb _hidl_cb) override; -#endif - - Return supportsAudioPatches() override; - Return createAudioPatch(const hidl_vec& sources, - const hidl_vec& sinks, - createAudioPatch_cb _hidl_cb) override; - Return releaseAudioPatch(int32_t patch) override; - Return getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override; - Return setAudioPortConfig(const AudioPortConfig& config) override; - - Return setScreenState(bool turnedOn) override; - -#if MAJOR_VERSION == 2 - Return getHwAvSync() override; - Return getParameters(const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& parameters) override; - Return debugDump(const hidl_handle& fd) override; -#elif MAJOR_VERSION >= 4 - Return getHwAvSync(getHwAvSync_cb _hidl_cb) override; - Return getParameters(const hidl_vec& context, - const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& context, - const hidl_vec& parameters) override; - Return getMicrophones(getMicrophones_cb _hidl_cb) override; - Return setConnectedState(const DeviceAddress& address, bool connected) override; -#endif -#if MAJOR_VERSION >= 6 - Return close() override; - Return addDeviceEffect(AudioPortHandle device, uint64_t effectId) override; - Return removeDeviceEffect(AudioPortHandle device, uint64_t effectId) override; - Return updateAudioPatch(int32_t previousPatch, const hidl_vec& sources, - const hidl_vec& sinks, - createAudioPatch_cb _hidl_cb) override; -#endif -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 - Return setConnectedState_7_1(const AudioPort& devicePort, bool connected) override; -#endif - Return debug(const hidl_handle& fd, const hidl_vec& options) override; - - // Utility methods for extending interfaces. - Result analyzeStatus(const char* funcName, int status, - const std::vector& ignoreErrors = {}); - void closeInputStream(audio_stream_in_t* stream); - void closeOutputStream(audio_stream_out_t* stream); - audio_hw_device_t* device() const { return mDevice; } - - uint32_t version() const { return mDevice->common.version; } - - private: - bool mIsClosed; - audio_hw_device_t* mDevice; - int mOpenedStreamsCount = 0; - - virtual ~Device(); - - Result doClose(); - std::tuple createOrUpdateAudioPatch( - AudioPatchHandle patch, const hidl_vec& sources, - const hidl_vec& sinks); - template - Return getAudioPortImpl(const AudioPort& port, getAudioPort_cb _hidl_cb, - int (*halGetter)(audio_hw_device_t*, HalPort*), - const char* halGetterName); - - // Methods from ParametersUtil. - char* halGetParameters(const char* keys) override; - int halSetParameters(const char* keysAndValues) override; -}; - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_DEVICE_H diff --git a/bluetooth/audio/hal/DevicesFactory.cpp b/bluetooth/audio/hal/DevicesFactory.cpp deleted file mode 100644 index cc42293..0000000 --- a/bluetooth/audio/hal/DevicesFactory.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#define LOG_TAG "DevicesFactoryHAL" - -#include "DevicesFactory.h" -#include "Device.h" -#include "PrimaryDevice.h" - -#include - -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -#if MAJOR_VERSION == 2 -Return DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) { - switch (device) { - case IDevicesFactory::Device::PRIMARY: - return openDevice(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb); - case IDevicesFactory::Device::A2DP: - return openDevice(AUDIO_HARDWARE_MODULE_ID_A2DP, _hidl_cb); - case IDevicesFactory::Device::USB: - return openDevice(AUDIO_HARDWARE_MODULE_ID_USB, _hidl_cb); - case IDevicesFactory::Device::R_SUBMIX: - return openDevice(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, _hidl_cb); - case IDevicesFactory::Device::STUB: - return openDevice(AUDIO_HARDWARE_MODULE_ID_STUB, _hidl_cb); - } - _hidl_cb(Result::INVALID_ARGUMENTS, nullptr); - return Void(); -} - -Return DevicesFactory::openDevice(const char* moduleName, openDevice_cb _hidl_cb) { - return openDevice(moduleName, _hidl_cb); -} -#elif MAJOR_VERSION >= 4 -Return DevicesFactory::openDevice(const hidl_string& moduleName, openDevice_cb _hidl_cb) { - if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) { - return openDevice(moduleName.c_str(), _hidl_cb); - } - return openDevice(moduleName.c_str(), _hidl_cb); -} -Return DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) { - return openDevice(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb); -} -#endif - -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 -Return DevicesFactory::openDevice_7_1(const hidl_string& moduleName, - openDevice_7_1_cb _hidl_cb) { - if (moduleName == AUDIO_HARDWARE_MODULE_ID_PRIMARY) { - Result result; - sp primary; - auto ret = openDevice( - AUDIO_HARDWARE_MODULE_ID_PRIMARY, - [&result, &primary](Result r, const sp& p) { - result = r; - primary = p; - }); - if (ret.isOk() && result == Result::OK && primary != nullptr) { - auto getDeviceRet = primary->getDevice(); - if (getDeviceRet.isOk()) { - _hidl_cb(result, getDeviceRet); - } else { - _hidl_cb(Result::NOT_INITIALIZED, nullptr); - } - } else { - _hidl_cb(result, nullptr); - } - return Void(); - } - return openDevice(moduleName.c_str(), _hidl_cb); -} - -Return DevicesFactory::openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) { - return openDevice(AUDIO_HARDWARE_MODULE_ID_PRIMARY, _hidl_cb); -} -#endif // V7.1 - -template -Return DevicesFactory::openDevice(const char* moduleName, Callback _hidl_cb) { - audio_hw_device_t* halDevice; - Result retval(Result::INVALID_ARGUMENTS); - sp result; - int halStatus = loadAudioInterface(moduleName, &halDevice); - if (halStatus == OK) { - result = new DeviceShim(halDevice); - retval = Result::OK; - } else if (halStatus == -EINVAL) { - retval = Result::NOT_INITIALIZED; - } - _hidl_cb(retval, result); - return Void(); -} - -// static -int DevicesFactory::loadAudioInterface(const char* if_name, audio_hw_device_t** dev) { - const hw_module_t* mod; - int rc; - - rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod); - if (rc) { - ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID, - if_name, strerror(-rc)); - goto out; - } - rc = audio_hw_device_open(mod, dev); - if (rc) { - ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__, AUDIO_HARDWARE_MODULE_ID, - if_name, strerror(-rc)); - goto out; - } - if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) { - ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version); - rc = -EINVAL; - audio_hw_device_close(*dev); - goto out; - } - return OK; - -out: - *dev = NULL; - return rc; -} - -IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name) { - return strcmp(name, "default") == 0 ? new DevicesFactory() : nullptr; -} - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/bluetooth/audio/hal/DevicesFactory.h b/bluetooth/audio/hal/DevicesFactory.h deleted file mode 100644 index 566bc8a..0000000 --- a/bluetooth/audio/hal/DevicesFactory.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_DEVICESFACTORY_H -#define ANDROID_HARDWARE_AUDIO_DEVICESFACTORY_H - -#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h) - -#include - -#include - -#include -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using namespace ::android::hardware::audio::CPP_VERSION; - -struct DevicesFactory : public IDevicesFactory { -#if MAJOR_VERSION == 2 - Return openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) override; -#elif MAJOR_VERSION >= 4 - Return openDevice(const hidl_string& device, openDevice_cb _hidl_cb) override; - Return openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override; -#endif -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 - Return openDevice_7_1(const hidl_string& device, openDevice_7_1_cb _hidl_cb) override; - Return openPrimaryDevice_7_1(openPrimaryDevice_7_1_cb _hidl_cb) override; -#endif - - private: - template - Return openDevice(const char* moduleName, Callback _hidl_cb); -#if MAJOR_VERSION == 2 - Return openDevice(const char* moduleName, openDevice_cb _hidl_cb); -#endif - - static int loadAudioInterface(const char* if_name, audio_hw_device_t** dev); -}; - -extern "C" IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name); - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_DEVICESFACTORY_H diff --git a/bluetooth/audio/hal/HearingAidAudioProvider.cpp b/bluetooth/audio/hal/HearingAidAudioProvider.cpp deleted file mode 100644 index e8b01ac..0000000 --- a/bluetooth/audio/hal/HearingAidAudioProvider.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BTAudioProviderHearingAid" - -#include "HearingAidAudioProvider.h" - -#include -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo -static constexpr uint32_t kPcmFrameCount = 128; -static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount; -static constexpr uint32_t kRtpFrameCount = 7; // max counts by 1 tick (20ms) -static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount; -static constexpr uint32_t kBufferCount = 1; // single buffer -static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount; - -HearingAidAudioProvider::HearingAidAudioProvider() - : BluetoothAudioProvider(), data_mq_(nullptr) { - LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize - << " byte(s)"; - std::unique_ptr data_mq( - new DataMQ(kDataMqSize, /* EventFlag */ true)); - if (data_mq && data_mq->isValid()) { - data_mq_ = std::move(data_mq); - session_type_ = SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH; - } else { - ALOGE_IF(!data_mq, "failed to allocate data MQ"); - ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid"); - } -} -bool HearingAidAudioProvider::isValid(const SessionType& sessionType) { - return (sessionType == session_type_ && data_mq_ && data_mq_->isValid()); -} - -ndk::ScopedAStatus HearingAidAudioProvider::startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, DataMQDesc* _aidl_return) { - if (audio_config.getTag() != AudioConfiguration::pcmConfig) { - LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" - << audio_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - const auto& pcm_config = audio_config.get(); - if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { - LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" - << pcm_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - - return BluetoothAudioProvider::startSession( - host_if, audio_config, latency_modes, _aidl_return); -} - -ndk::ScopedAStatus HearingAidAudioProvider::onSessionReady( - DataMQDesc* _aidl_return) { - if (data_mq_ == nullptr || !data_mq_->isValid()) { - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - *_aidl_return = data_mq_->dupeDesc(); - auto desc = data_mq_->dupeDesc(); - BluetoothAudioSessionReport::OnSessionStarted( - session_type_, stack_iface_, &desc, *audio_config_, latency_modes_); - return ndk::ScopedAStatus::ok(); -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/HearingAidAudioProvider.h b/bluetooth/audio/hal/HearingAidAudioProvider.h deleted file mode 100644 index a158c86..0000000 --- a/bluetooth/audio/hal/HearingAidAudioProvider.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - * 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 "BluetoothAudioProvider.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class HearingAidAudioProvider : public BluetoothAudioProvider { - public: - HearingAidAudioProvider(); - - bool isValid(const SessionType& sessionType) override; - - ndk::ScopedAStatus startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); - - private: - // audio data queue for software encoding - std::unique_ptr data_mq_; - - ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/hal/LeAudioOffloadAudioProvider.cpp deleted file mode 100644 index 0e22e44..0000000 --- a/bluetooth/audio/hal/LeAudioOffloadAudioProvider.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BTAudioProviderLeAudioHW" - -#include "LeAudioOffloadAudioProvider.h" - -#include -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider() - : LeAudioOffloadAudioProvider() { - session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH; -} - -LeAudioOffloadInputAudioProvider::LeAudioOffloadInputAudioProvider() - : LeAudioOffloadAudioProvider() { - session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH; -} - -LeAudioOffloadBroadcastAudioProvider::LeAudioOffloadBroadcastAudioProvider() - : LeAudioOffloadAudioProvider() { - session_type_ = - SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH; -} - -LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider() - : BluetoothAudioProvider() {} - -bool LeAudioOffloadAudioProvider::isValid(const SessionType& sessionType) { - return (sessionType == session_type_); -} - -ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, DataMQDesc* _aidl_return) { - if (audio_config.getTag() != AudioConfiguration::leAudioConfig) { - LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" - << audio_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - const auto& le_audio_config = - audio_config.get(); - if (!BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid( - session_type_, le_audio_config)) { - LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration=" - << le_audio_config.toString(); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - - return BluetoothAudioProvider::startSession( - host_if, audio_config, latency_modes, _aidl_return); -} - -ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady( - DataMQDesc* _aidl_return) { - BluetoothAudioSessionReport::OnSessionStarted( - session_type_, stack_iface_, nullptr, *audio_config_, latency_modes_); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::ok(); -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/LeAudioOffloadAudioProvider.h b/bluetooth/audio/hal/LeAudioOffloadAudioProvider.h deleted file mode 100644 index 614c794..0000000 --- a/bluetooth/audio/hal/LeAudioOffloadAudioProvider.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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. - * 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 "BluetoothAudioProvider.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { - public: - LeAudioOffloadAudioProvider(); - - bool isValid(const SessionType& sessionType) override; - - ndk::ScopedAStatus startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); - - private: - ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; -}; - -class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { - public: - LeAudioOffloadOutputAudioProvider(); -}; - -class LeAudioOffloadInputAudioProvider : public LeAudioOffloadAudioProvider { - public: - LeAudioOffloadInputAudioProvider(); -}; - -class LeAudioOffloadBroadcastAudioProvider - : public LeAudioOffloadAudioProvider { - public: - LeAudioOffloadBroadcastAudioProvider(); -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/LeAudioSoftwareAudioProvider.cpp b/bluetooth/audio/hal/LeAudioSoftwareAudioProvider.cpp deleted file mode 100644 index c16ff54..0000000 --- a/bluetooth/audio/hal/LeAudioSoftwareAudioProvider.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BTAudioProviderLeAudioSW" - -#include "LeAudioSoftwareAudioProvider.h" - -#include -#include -#include - -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -static constexpr uint32_t kBufferOutCount = 2; // two frame buffer -static constexpr uint32_t kBufferInCount = 2; // two frame buffer - -inline uint32_t channel_mode_to_channel_count(ChannelMode channel_mode) { - switch (channel_mode) { - case ChannelMode::MONO: - return 1; - case ChannelMode::STEREO: - return 2; - default: - return 0; - } - return 0; -} - -LeAudioSoftwareOutputAudioProvider::LeAudioSoftwareOutputAudioProvider() - : LeAudioSoftwareAudioProvider() { - session_type_ = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH; -} - -LeAudioSoftwareInputAudioProvider::LeAudioSoftwareInputAudioProvider() - : LeAudioSoftwareAudioProvider() { - session_type_ = SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH; -} - -LeAudioSoftwareBroadcastAudioProvider::LeAudioSoftwareBroadcastAudioProvider() - : LeAudioSoftwareAudioProvider() { - session_type_ = SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH; -} - -LeAudioSoftwareAudioProvider::LeAudioSoftwareAudioProvider() - : BluetoothAudioProvider(), data_mq_(nullptr) {} - -bool LeAudioSoftwareAudioProvider::isValid(const SessionType& sessionType) { - return (sessionType == session_type_); -} - -ndk::ScopedAStatus LeAudioSoftwareAudioProvider::startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, DataMQDesc* _aidl_return) { - if (audio_config.getTag() != AudioConfiguration::pcmConfig) { - LOG(WARNING) << __func__ << " - Invalid Audio Configuration=" - << audio_config.toString(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - const auto& pcm_config = audio_config.get(); - if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) { - LOG(WARNING) << __func__ << " - Unsupported PCM Configuration=" - << pcm_config.toString(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - - uint32_t buffer_modifier = 0; - if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH || - session_type_ == - SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH) - buffer_modifier = kBufferOutCount; - else if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH) - buffer_modifier = kBufferInCount; - - // 24 bit audio stream is sent as unpacked - int bytes_per_sample = - (pcm_config.bitsPerSample == 24) ? 4 : (pcm_config.bitsPerSample / 8); - - uint32_t data_mq_size = - (ceil(pcm_config.sampleRateHz) / 1000) * - channel_mode_to_channel_count(pcm_config.channelMode) * bytes_per_sample * - (pcm_config.dataIntervalUs / 1000) * buffer_modifier; - if (data_mq_size <= 0) { - LOG(ERROR) << __func__ << "Unexpected audio buffer size: " << data_mq_size - << ", SampleRateHz: " << pcm_config.sampleRateHz - << ", ChannelMode: " << toString(pcm_config.channelMode) - << ", BitsPerSample: " - << static_cast(pcm_config.bitsPerSample) - << ", BytesPerSample: " << bytes_per_sample - << ", DataIntervalUs: " << pcm_config.dataIntervalUs - << ", SessionType: " << toString(session_type_); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - - LOG(INFO) << __func__ << " - size of audio buffer " << data_mq_size - << " byte(s)"; - - std::unique_ptr temp_data_mq( - new DataMQ(data_mq_size, /* EventFlag */ true)); - if (temp_data_mq == nullptr || !temp_data_mq->isValid()) { - ALOGE_IF(!temp_data_mq, "failed to allocate data MQ"); - ALOGE_IF(temp_data_mq && !temp_data_mq->isValid(), "data MQ is invalid"); - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - data_mq_ = std::move(temp_data_mq); - - return BluetoothAudioProvider::startSession( - host_if, audio_config, latency_modes, _aidl_return); -} - -ndk::ScopedAStatus LeAudioSoftwareAudioProvider::onSessionReady( - DataMQDesc* _aidl_return) { - if (data_mq_ == nullptr || !data_mq_->isValid()) { - *_aidl_return = DataMQDesc(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - *_aidl_return = data_mq_->dupeDesc(); - auto desc = data_mq_->dupeDesc(); - BluetoothAudioSessionReport::OnSessionStarted( - session_type_, stack_iface_, &desc, *audio_config_, latency_modes_); - return ndk::ScopedAStatus::ok(); -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/hal/LeAudioSoftwareAudioProvider.h b/bluetooth/audio/hal/LeAudioSoftwareAudioProvider.h deleted file mode 100644 index 21243ff..0000000 --- a/bluetooth/audio/hal/LeAudioSoftwareAudioProvider.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - * 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 "BluetoothAudioProvider.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class LeAudioSoftwareAudioProvider : public BluetoothAudioProvider { - public: - LeAudioSoftwareAudioProvider(); - - bool isValid(const SessionType& sessionType) override; - - ndk::ScopedAStatus startSession( - const std::shared_ptr& host_if, - const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); - - private: - // audio data queue for software encoding - std::unique_ptr data_mq_; - - ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; -}; - -class LeAudioSoftwareOutputAudioProvider : public LeAudioSoftwareAudioProvider { - public: - LeAudioSoftwareOutputAudioProvider(); -}; - -class LeAudioSoftwareInputAudioProvider : public LeAudioSoftwareAudioProvider { - public: - LeAudioSoftwareInputAudioProvider(); -}; - -class LeAudioSoftwareBroadcastAudioProvider - : public LeAudioSoftwareAudioProvider { - public: - LeAudioSoftwareBroadcastAudioProvider(); -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl \ No newline at end of file diff --git a/bluetooth/audio/hal/ParametersUtil.cpp b/bluetooth/audio/hal/ParametersUtil.cpp deleted file mode 100644 index a632070..0000000 --- a/bluetooth/audio/hal/ParametersUtil.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#include "ParametersUtil.h" -#include "Util.h" - -#include - -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CORE_TYPES_CPP_VERSION { -namespace implementation { - -/** Converts a status_t in Result according to the rules of AudioParameter::get* - * Note: Static method and not private method to avoid leaking status_t dependency - */ -static Result getHalStatusToResult(status_t status) { - switch (status) { - case OK: - return Result::OK; - case BAD_VALUE: // Nothing was returned, probably because the HAL does - // not handle it - return Result::NOT_SUPPORTED; - case INVALID_OPERATION: // Conversion from string to the requested type - // failed - return Result::INVALID_ARGUMENTS; - default: // Should not happen - ALOGW("Unexpected status returned by getParam: %u", status); - return Result::INVALID_ARGUMENTS; - } -} - -Result ParametersUtil::getParam(const char* name, bool* value) { - String8 halValue; - Result retval = getParam(name, &halValue); - *value = false; - if (retval == Result::OK) { - if (halValue.empty()) { - return Result::NOT_SUPPORTED; - } - *value = !(halValue == AudioParameter::valueOff); - } - return retval; -} - -Result ParametersUtil::getParam(const char* name, int* value) { - const String8 halName(name); - AudioParameter keys; - keys.addKey(halName); - std::unique_ptr params = getParams(keys); - return getHalStatusToResult(params->getInt(halName, *value)); -} - -Result ParametersUtil::getParam(const char* name, String8* value, AudioParameter context) { - const String8 halName(name); - context.addKey(halName); - std::unique_ptr params = getParams(context); - return getHalStatusToResult(params->get(halName, *value)); -} - -void ParametersUtil::getParametersImpl( - const hidl_vec& context, const hidl_vec& keys, - std::function& parameters)> cb) { - AudioParameter halKeys; - for (auto& pair : context) { - halKeys.add(String8(pair.key.c_str()), String8(pair.value.c_str())); - } - for (size_t i = 0; i < keys.size(); ++i) { - halKeys.addKey(String8(keys[i].c_str())); - } - std::unique_ptr halValues = getParams(halKeys); - Result retval = - (keys.size() == 0 || halValues->size() != 0) ? Result::OK : Result::NOT_SUPPORTED; - hidl_vec result; - result.resize(halValues->size()); - String8 halKey, halValue; - for (size_t i = 0; i < halValues->size(); ++i) { - status_t status = halValues->getAt(i, halKey, halValue); - if (status != OK) { - result.resize(0); - retval = getHalStatusToResult(status); - break; - } - result[i].key = halKey.string(); - result[i].value = halValue.string(); - } - cb(retval, result); -} - -std::unique_ptr ParametersUtil::getParams(const AudioParameter& keys) { - String8 paramsAndValues; - char* halValues = halGetParameters(keys.keysToString().string()); - if (halValues != NULL) { - paramsAndValues.setTo(halValues); - free(halValues); - } else { - paramsAndValues.clear(); - } - return std::unique_ptr(new AudioParameter(paramsAndValues)); -} - -Result ParametersUtil::setParam(const char* name, const char* value) { - AudioParameter param; - param.add(String8(name), String8(value)); - return setParams(param); -} - -Result ParametersUtil::setParam(const char* name, bool value) { - AudioParameter param; - param.add(String8(name), String8(value ? AudioParameter::valueOn : AudioParameter::valueOff)); - return setParams(param); -} - -Result ParametersUtil::setParam(const char* name, int value) { - AudioParameter param; - param.addInt(String8(name), value); - return setParams(param); -} - -Result ParametersUtil::setParam(const char* name, float value) { - AudioParameter param; - param.addFloat(String8(name), value); - return setParams(param); -} - -Result ParametersUtil::setParametersImpl(const hidl_vec& context, - const hidl_vec& parameters) { - AudioParameter params; - for (auto& pair : context) { - params.add(String8(pair.key.c_str()), String8(pair.value.c_str())); - } - for (size_t i = 0; i < parameters.size(); ++i) { - params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str())); - } - return setParams(params); -} - -Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) { - audio_devices_t halDeviceType; - char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (CoreUtils::deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) { - return Result::INVALID_ARGUMENTS; - } - AudioParameter params{String8(halDeviceAddress)}; - params.addInt(String8(name), halDeviceType); - return setParams(params); -} - -Result ParametersUtil::setParams(const AudioParameter& param) { - int halStatus = halSetParameters(param.toString().string()); - return util::analyzeStatus(halStatus); -} - -} // namespace implementation -} // namespace CORE_TYPES_CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/bluetooth/audio/hal/ParametersUtil.h b/bluetooth/audio/hal/ParametersUtil.h deleted file mode 100644 index 25c193a..0000000 --- a/bluetooth/audio/hal/ParametersUtil.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_ -#define ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_ - -// clang-format off -#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h) -#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h) -// clang-format on - -#include -#include - -#include -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CORE_TYPES_CPP_VERSION { -namespace implementation { - -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; - -class ParametersUtil { - public: - Result setParam(const char* name, const char* value); - Result getParam(const char* name, bool* value); - Result getParam(const char* name, int* value); - Result getParam(const char* name, String8* value, AudioParameter context = {}); - void getParametersImpl( - const hidl_vec& context, const hidl_vec& keys, - std::function& parameters)> cb); - std::unique_ptr getParams(const AudioParameter& keys); - Result setParam(const char* name, bool value); - Result setParam(const char* name, int value); - Result setParam(const char* name, float value); - Result setParametersImpl(const hidl_vec& context, - const hidl_vec& parameters); - Result setParams(const AudioParameter& param); - Result setParam(const char* name, const DeviceAddress& address); - - protected: - virtual ~ParametersUtil() {} - - virtual char* halGetParameters(const char* keys) = 0; - virtual int halSetParameters(const char* keysAndValues) = 0; -}; - -} // namespace implementation -} // namespace CORE_TYPES_CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_PARAMETERS_UTIL_H_ diff --git a/bluetooth/audio/hal/PrimaryDevice.cpp b/bluetooth/audio/hal/PrimaryDevice.cpp deleted file mode 100644 index 1bba007..0000000 --- a/bluetooth/audio/hal/PrimaryDevice.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#define LOG_TAG "PrimaryDeviceHAL" - -#include "PrimaryDevice.h" -#include "Util.h" - -#if MAJOR_VERSION >= 4 -#include -#endif - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -namespace util { -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; -} - -PrimaryDevice::PrimaryDevice(audio_hw_device_t* device) : mDevice(new Device(device)) {} - -PrimaryDevice::~PrimaryDevice() { - // Do not call mDevice->close here. If there are any unclosed streams, - // they only hold IDevice instance, not IPrimaryDevice, thus IPrimaryDevice - // "part" of a device can be destroyed before the streams. -} - -// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow. -Return PrimaryDevice::initCheck() { - return mDevice->initCheck(); -} - -Return PrimaryDevice::setMasterVolume(float volume) { - return mDevice->setMasterVolume(volume); -} - -Return PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) { - return mDevice->getMasterVolume(_hidl_cb); -} - -Return PrimaryDevice::setMicMute(bool mute) { - return mDevice->setMicMute(mute); -} - -Return PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) { - return mDevice->getMicMute(_hidl_cb); -} - -Return PrimaryDevice::setMasterMute(bool mute) { - return mDevice->setMasterMute(mute); -} - -Return PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) { - return mDevice->getMasterMute(_hidl_cb); -} - -Return PrimaryDevice::getInputBufferSize(const AudioConfig& config, - getInputBufferSize_cb _hidl_cb) { - return mDevice->getInputBufferSize(config, _hidl_cb); -} - -#if MAJOR_VERSION == 2 -Return PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioOutputFlags flags, - openOutputStream_cb _hidl_cb) { - return mDevice->openOutputStream(ioHandle, device, config, flags, _hidl_cb); -} - -Return PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlags flags, - AudioSource source, openInputStream_cb _hidl_cb) { - return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb); -} -#elif MAJOR_VERSION >= 4 -Return PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioOutputFlags flags, -#else - const AudioOutputFlags& flags, -#endif - const SourceMetadata& sourceMetadata, - openOutputStream_cb _hidl_cb) { - return mDevice->openOutputStream(ioHandle, device, config, flags, sourceMetadata, _hidl_cb); -} - -Return PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioInputFlags flags, -#else - const AudioInputFlags& flags, -#endif - const SinkMetadata& sinkMetadata, - openInputStream_cb _hidl_cb) { - return mDevice->openInputStream(ioHandle, device, config, flags, sinkMetadata, _hidl_cb); -} -#endif - -Return PrimaryDevice::supportsAudioPatches() { - return mDevice->supportsAudioPatches(); -} - -Return PrimaryDevice::createAudioPatch(const hidl_vec& sources, - const hidl_vec& sinks, - createAudioPatch_cb _hidl_cb) { - return mDevice->createAudioPatch(sources, sinks, _hidl_cb); -} - -Return PrimaryDevice::releaseAudioPatch(int32_t patch) { - return mDevice->releaseAudioPatch(patch); -} - -Return PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { - return mDevice->getAudioPort(port, _hidl_cb); -} - -Return PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) { - return mDevice->setAudioPortConfig(config); -} - -Return PrimaryDevice::setScreenState(bool turnedOn) { - return mDevice->setScreenState(turnedOn); -} - -#if MAJOR_VERSION == 2 -Return PrimaryDevice::getHwAvSync() { - return mDevice->getHwAvSync(); -} - -Return PrimaryDevice::getParameters(const hidl_vec& keys, - getParameters_cb _hidl_cb) { - return mDevice->getParameters(keys, _hidl_cb); -} - -Return PrimaryDevice::setParameters(const hidl_vec& parameters) { - return mDevice->setParameters(parameters); -} - -Return PrimaryDevice::debugDump(const hidl_handle& fd) { - return mDevice->debugDump(fd); -} -#elif MAJOR_VERSION >= 4 -Return PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) { - return mDevice->getHwAvSync(_hidl_cb); -} -Return PrimaryDevice::getParameters(const hidl_vec& context, - const hidl_vec& keys, - getParameters_cb _hidl_cb) { - return mDevice->getParameters(context, keys, _hidl_cb); -} -Return PrimaryDevice::setParameters(const hidl_vec& context, - const hidl_vec& parameters) { - return mDevice->setParameters(context, parameters); -} -Return PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) { - return mDevice->getMicrophones(_hidl_cb); -} -Return PrimaryDevice::setConnectedState(const DeviceAddress& address, bool connected) { - return mDevice->setConnectedState(address, connected); -} -#endif -#if MAJOR_VERSION >= 6 -Return PrimaryDevice::close() { - return mDevice->close(); -} - -Return PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) { - return mDevice->addDeviceEffect(device, effectId); -} - -Return PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) { - return mDevice->removeDeviceEffect(device, effectId); -} - -Return PrimaryDevice::updateAudioPatch(int32_t previousPatch, - const hidl_vec& sources, - const hidl_vec& sinks, - updateAudioPatch_cb _hidl_cb) { - return mDevice->updateAudioPatch(previousPatch, sources, sinks, _hidl_cb); -} -#endif - -// Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow. -Return PrimaryDevice::setVoiceVolume(float volume) { - if (!util::isGainNormalized(volume)) { - ALOGW("Can not set a voice volume (%f) outside [0,1]", volume); - return Result::INVALID_ARGUMENTS; - } - return mDevice->analyzeStatus("set_voice_volume", - mDevice->device()->set_voice_volume(mDevice->device(), volume)); -} - -Return PrimaryDevice::setMode(AudioMode mode) { - // INVALID, CURRENT, CNT, MAX are reserved for internal use. - // TODO: remove the values from the HIDL interface - switch (mode) { - case AudioMode::NORMAL: - case AudioMode::RINGTONE: - case AudioMode::IN_CALL: - case AudioMode::IN_COMMUNICATION: -#if MAJOR_VERSION >= 6 - case AudioMode::CALL_SCREEN: -#endif - break; // Valid values - default: - return Result::INVALID_ARGUMENTS; - }; - - return mDevice->analyzeStatus( - "set_mode", - mDevice->device()->set_mode(mDevice->device(), static_cast(mode))); -} - -Return PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) { - bool enabled; - Result retval = mDevice->getParam(AudioParameter::keyBtNrec, &enabled); - _hidl_cb(retval, enabled); - return Void(); -} - -Return PrimaryDevice::setBtScoNrecEnabled(bool enabled) { - return mDevice->setParam(AudioParameter::keyBtNrec, enabled); -} - -Return PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) { - bool enabled; - Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, &enabled); - _hidl_cb(retval, enabled); - return Void(); -} - -Return PrimaryDevice::setBtScoWidebandEnabled(bool enabled) { - return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, enabled); -} - -static const char* convertTtyModeFromHIDL(IPrimaryDevice::TtyMode mode) { - switch (mode) { - case IPrimaryDevice::TtyMode::OFF: - return AUDIO_PARAMETER_VALUE_TTY_OFF; - case IPrimaryDevice::TtyMode::VCO: - return AUDIO_PARAMETER_VALUE_TTY_VCO; - case IPrimaryDevice::TtyMode::HCO: - return AUDIO_PARAMETER_VALUE_TTY_HCO; - case IPrimaryDevice::TtyMode::FULL: - return AUDIO_PARAMETER_VALUE_TTY_FULL; - default: - return nullptr; - } -} -static IPrimaryDevice::TtyMode convertTtyModeToHIDL(const char* halMode) { - if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0) - return IPrimaryDevice::TtyMode::OFF; - else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0) - return IPrimaryDevice::TtyMode::VCO; - else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0) - return IPrimaryDevice::TtyMode::HCO; - else if (strcmp(halMode, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0) - return IPrimaryDevice::TtyMode::FULL; - return IPrimaryDevice::TtyMode(-1); -} - -Return PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) { - String8 halMode; - Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_TTY_MODE, &halMode); - if (retval != Result::OK) { - _hidl_cb(retval, TtyMode::OFF); - return Void(); - } - TtyMode mode = convertTtyModeToHIDL(halMode); - if (mode == TtyMode(-1)) { - ALOGE("HAL returned invalid TTY value: %s", halMode.c_str()); - _hidl_cb(Result::INVALID_STATE, TtyMode::OFF); - return Void(); - } - _hidl_cb(Result::OK, mode); - return Void(); -} - -Return PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) { - const char* modeStr = convertTtyModeFromHIDL(mode); - if (modeStr == nullptr) { - ALOGW("Can not set an invalid TTY value: %d", mode); - return Result::INVALID_ARGUMENTS; - } - return mDevice->setParam(AUDIO_PARAMETER_KEY_TTY_MODE, modeStr); -} - -Return PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) { - bool enabled; - Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HAC, &enabled); - _hidl_cb(retval, enabled); - return Void(); -} - -Return PrimaryDevice::setHacEnabled(bool enabled) { - return mDevice->setParam(AUDIO_PARAMETER_KEY_HAC, enabled); -} - -#if MAJOR_VERSION >= 4 -Return PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) { - return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_HEADSET_NAME, name.c_str()); -} -Return PrimaryDevice::getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) { - bool enabled; - Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, &enabled); - _hidl_cb(retval, enabled); - return Void(); -} -Return PrimaryDevice::setBtHfpEnabled(bool enabled) { - return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_ENABLE, enabled); -} -Return PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) { - return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE, int(sampleRateHz)); -} -Return PrimaryDevice::setBtHfpVolume(float volume) { - if (!util::isGainNormalized(volume)) { - ALOGW("Can not set BT HFP volume (%f) outside [0,1]", volume); - return Result::INVALID_ARGUMENTS; - } - // Map the normalized volume onto the range of [0, 15] - return mDevice->setParam(AUDIO_PARAMETER_KEY_HFP_VOLUME, - static_cast(std::round(volume * 15))); -} -Return PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) { - // legacy API expects the rotation in degree - return mDevice->setParam(AUDIO_PARAMETER_KEY_ROTATION, int(rotation) * 90); -} -#endif - -Return PrimaryDevice::debug(const hidl_handle& fd, const hidl_vec& options) { - return mDevice->debug(fd, options); -} - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/bluetooth/audio/hal/PrimaryDevice.h b/bluetooth/audio/hal/PrimaryDevice.h deleted file mode 100644 index 8b37e01..0000000 --- a/bluetooth/audio/hal/PrimaryDevice.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_PRIMARYDEVICE_H -#define ANDROID_HARDWARE_AUDIO_PRIMARYDEVICE_H - -#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h) - -#include "Device.h" - -#include - -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CPP_VERSION; - -struct PrimaryDevice : public IPrimaryDevice { - explicit PrimaryDevice(audio_hw_device_t* device); - - // Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow. - Return initCheck() override; - Return setMasterVolume(float volume) override; - Return getMasterVolume(getMasterVolume_cb _hidl_cb) override; - Return setMicMute(bool mute) override; - Return getMicMute(getMicMute_cb _hidl_cb) override; - Return setMasterMute(bool mute) override; - Return getMasterMute(getMasterMute_cb _hidl_cb) override; - Return getInputBufferSize(const AudioConfig& config, - getInputBufferSize_cb _hidl_cb) override; - - Return openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioOutputFlags flags, -#else - const AudioOutputFlags& flags, -#endif -#if MAJOR_VERSION >= 4 - const SourceMetadata& sourceMetadata, -#endif - openOutputStream_cb _hidl_cb) override; - Return openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, -#if MAJOR_VERSION <= 6 - AudioInputFlags flags, -#else - const AudioInputFlags& flags, -#endif -#if MAJOR_VERSION == 2 - AudioSource source, -#elif MAJOR_VERSION >= 4 - const SinkMetadata& sinkMetadata, -#endif - openInputStream_cb _hidl_cb) override; - - Return supportsAudioPatches() override; - Return createAudioPatch(const hidl_vec& sources, - const hidl_vec& sinks, - createAudioPatch_cb _hidl_cb) override; - Return releaseAudioPatch(int32_t patch) override; - Return getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override; - Return setAudioPortConfig(const AudioPortConfig& config) override; - - Return setScreenState(bool turnedOn) override; - -#if MAJOR_VERSION == 2 - Return getHwAvSync() override; - Return getParameters(const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& parameters) override; - Return debugDump(const hidl_handle& fd) override; -#elif MAJOR_VERSION >= 4 - Return getHwAvSync(getHwAvSync_cb _hidl_cb) override; - Return getParameters(const hidl_vec& context, - const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& context, - const hidl_vec& parameters) override; - Return getMicrophones(getMicrophones_cb _hidl_cb) override; - Return setConnectedState(const DeviceAddress& address, bool connected) override; -#endif -#if MAJOR_VERSION >= 6 - Return close() override; - Return addDeviceEffect(AudioPortHandle device, uint64_t effectId) override; - Return removeDeviceEffect(AudioPortHandle device, uint64_t effectId) override; - Return updateAudioPatch(int32_t previousPatch, const hidl_vec& sources, - const hidl_vec& sinks, - updateAudioPatch_cb _hidl_cb) override; -#endif - - Return debug(const hidl_handle& fd, const hidl_vec& options) override; - - // Methods from ::android::hardware::audio::CPP_VERSION::IPrimaryDevice follow. - Return setVoiceVolume(float volume) override; - Return setMode(AudioMode mode) override; - Return getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) override; - Return setBtScoNrecEnabled(bool enabled) override; - Return getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) override; - Return setBtScoWidebandEnabled(bool enabled) override; - Return getTtyMode(getTtyMode_cb _hidl_cb) override; - Return setTtyMode(IPrimaryDevice::TtyMode mode) override; - Return getHacEnabled(getHacEnabled_cb _hidl_cb) override; - Return setHacEnabled(bool enabled) override; - -#if MAJOR_VERSION >= 4 - Return setBtScoHeadsetDebugName(const hidl_string& name) override; - Return getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) override; - Return setBtHfpEnabled(bool enabled) override; - Return setBtHfpSampleRate(uint32_t sampleRateHz) override; - Return setBtHfpVolume(float volume) override; - Return updateRotation(IPrimaryDevice::Rotation rotation) override; -#endif -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 - Return> getDevice() override { return mDevice; } -#endif - private: - sp mDevice; - - virtual ~PrimaryDevice(); -}; - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_PRIMARYDEVICE_H diff --git a/bluetooth/audio/hal/Stream.cpp b/bluetooth/audio/hal/Stream.cpp deleted file mode 100644 index 1d3b89c..0000000 --- a/bluetooth/audio/hal/Stream.cpp +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#define LOG_TAG "StreamHAL" - -#include "Stream.h" -#include "common/all-versions/HidlSupport.h" -#include "common/all-versions/default/EffectMap.h" -#include "Util.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils; -using ::android::hardware::audio::common::utils::splitString; -using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils; -namespace util { -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; -} - -Stream::Stream(bool isInput, audio_stream_t* stream) : mIsInput(isInput), mStream(stream) { - (void)mIsInput; // prevent 'unused field' warnings in pre-V7 versions. -} - -Stream::~Stream() { - mStream = nullptr; -} - -// static -Result Stream::analyzeStatus(const char* funcName, int status) { - return util::analyzeStatus("stream", funcName, status); -} - -// static -Result Stream::analyzeStatus(const char* funcName, int status, - const std::vector& ignoreErrors) { - return util::analyzeStatus("stream", funcName, status, ignoreErrors); -} - -char* Stream::halGetParameters(const char* keys) { - return mStream->get_parameters(mStream, keys); -} - -int Stream::halSetParameters(const char* keysAndValues) { - return mStream->set_parameters(mStream, keysAndValues); -} - -// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow. -Return Stream::getFrameSize() { - // Needs to be implemented by interface subclasses. But can't be declared as pure virtual, - // since interface subclasses implementation do not inherit from this class. - LOG_ALWAYS_FATAL("Stream::getFrameSize is pure abstract"); - return uint64_t{}; -} - -Return Stream::getFrameCount() { - int halFrameCount; - Result retval = getParam(AudioParameter::keyFrameCount, &halFrameCount); - return retval == Result::OK ? halFrameCount : 0; -} - -Return Stream::getBufferSize() { - return mStream->get_buffer_size(mStream); -} - -#if MAJOR_VERSION <= 6 -Return Stream::getSampleRate() { - return mStream->get_sample_rate(mStream); -} - -#if MAJOR_VERSION == 2 -Return Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) { - return getSupportedSampleRates(getFormat(), _hidl_cb); -} -Return Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) { - return getSupportedChannelMasks(getFormat(), _hidl_cb); -} -#endif - -Return Stream::getSupportedSampleRates(AudioFormat format, - getSupportedSampleRates_cb _hidl_cb) { - AudioParameter context; - context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(format)); - String8 halListValue; - Result result = - getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue, context); - hidl_vec sampleRates; - SampleRateSet halSampleRates; - if (result == Result::OK) { - halSampleRates = - samplingRatesFromString(halListValue.string(), AudioParameter::valueListSeparator); - sampleRates = hidl_vec(halSampleRates.begin(), halSampleRates.end()); - // Legacy get_parameter does not return a status_t, thus can not advertise of failure. - // Note that this method must succeed (non empty list) if the format is supported. - if (sampleRates.size() == 0) { - result = Result::NOT_SUPPORTED; - } - } -#if MAJOR_VERSION == 2 - _hidl_cb(sampleRates); -#elif MAJOR_VERSION >= 4 - _hidl_cb(result, sampleRates); -#endif - return Void(); -} - -Return Stream::getSupportedChannelMasks(AudioFormat format, - getSupportedChannelMasks_cb _hidl_cb) { - AudioParameter context; - context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(format)); - String8 halListValue; - Result result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue, context); - hidl_vec channelMasks; - ChannelMaskSet halChannelMasks; - if (result == Result::OK) { - halChannelMasks = - channelMasksFromString(halListValue.string(), AudioParameter::valueListSeparator); - channelMasks.resize(halChannelMasks.size()); - size_t i = 0; - for (auto channelMask : halChannelMasks) { - channelMasks[i++] = AudioChannelBitfield(channelMask); - } - // Legacy get_parameter does not return a status_t, thus can not advertise of failure. - // Note that this method must succeed (non empty list) if the format is supported. - if (channelMasks.size() == 0) { - result = Result::NOT_SUPPORTED; - } - } -#if MAJOR_VERSION == 2 - _hidl_cb(channelMasks); -#elif MAJOR_VERSION >= 4 - _hidl_cb(result, channelMasks); -#endif - return Void(); -} - -Return Stream::setSampleRate(uint32_t sampleRateHz) { - return setParam(AudioParameter::keySamplingRate, static_cast(sampleRateHz)); -} - -Return Stream::getChannelMask() { - return AudioChannelBitfield(mStream->get_channels(mStream)); -} - -Return Stream::setChannelMask(AudioChannelBitfield mask) { - return setParam(AudioParameter::keyChannels, static_cast(mask)); -} - -Return Stream::getFormat() { - return AudioFormat(mStream->get_format(mStream)); -} - -Return Stream::getSupportedFormats(getSupportedFormats_cb _hidl_cb) { - String8 halListValue; - Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue); - hidl_vec formats; - FormatVector halFormats; - if (result == Result::OK) { - halFormats = formatsFromString(halListValue.string(), AudioParameter::valueListSeparator); - formats.resize(halFormats.size()); - for (size_t i = 0; i < halFormats.size(); ++i) { - formats[i] = AudioFormat(halFormats[i]); - } - // Legacy get_parameter does not return a status_t, thus can not advertise of failure. - // Note that the method must not return an empty list if this capability is supported. - if (formats.size() == 0) { - result = Result::NOT_SUPPORTED; - } - } -#if MAJOR_VERSION <= 5 - _hidl_cb(formats); -#elif MAJOR_VERSION >= 6 - _hidl_cb(result, formats); -#endif - return Void(); -} - -Return Stream::setFormat(AudioFormat format) { - return setParam(AudioParameter::keyFormat, static_cast(format)); -} - -Return Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { - uint32_t halSampleRate = mStream->get_sample_rate(mStream); - audio_channel_mask_t halMask = mStream->get_channels(mStream); - audio_format_t halFormat = mStream->get_format(mStream); - _hidl_cb(halSampleRate, AudioChannelBitfield(halMask), AudioFormat(halFormat)); - return Void(); -} - -#else // MAJOR_VERSION <= 6 - -Return Stream::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { - String8 halListValue; - Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue); - hidl_vec profiles; - if (result != Result::OK) { - _hidl_cb(result, profiles); - return Void(); - } - // Ensure that the separator is one character, despite that it's defined as a C string. - static_assert(sizeof(AUDIO_PARAMETER_VALUE_LIST_SEPARATOR) == 2); - std::vector halFormats = - splitString(halListValue.string(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); - hidl_vec formats; - (void)HidlUtils::audioFormatsFromHal(halFormats, &formats); - std::vector tempProfiles; - for (const auto& format : formats) { - audio_format_t halFormat; - if (status_t status = HidlUtils::audioFormatToHal(format, &halFormat); status != NO_ERROR) { - continue; - } - AudioParameter context; - context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(halFormat)); - // Query supported sample rates for the format. - result = getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue, context); - if (result != Result::OK) break; - std::vector halSampleRates = - splitString(halListValue.string(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); - hidl_vec sampleRates; - sampleRates.resize(halSampleRates.size()); - for (size_t i = 0; i < sampleRates.size(); ++i) { - sampleRates[i] = std::stoi(halSampleRates[i]); - } - // Query supported channel masks for the format. - result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue, context); - if (result != Result::OK) break; - std::vector halChannelMasks = - splitString(halListValue.string(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); - hidl_vec channelMasks; - (void)HidlUtils::audioChannelMasksFromHal(halChannelMasks, &channelMasks); - // Create a profile. - if (channelMasks.size() != 0 && sampleRates.size() != 0) { - tempProfiles.push_back({.format = format, - .sampleRates = std::move(sampleRates), - .channelMasks = std::move(channelMasks)}); - } - } - // Legacy get_parameter does not return a status_t, thus can not advertise of failure. - // Note that the method must not return an empty list if this capability is supported. - if (!tempProfiles.empty()) { - profiles = tempProfiles; - } else { - result = Result::NOT_SUPPORTED; - } - _hidl_cb(result, profiles); - return Void(); -} - -Return Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { - audio_config_base_t halConfigBase = {mStream->get_sample_rate(mStream), - mStream->get_channels(mStream), - mStream->get_format(mStream)}; - AudioConfigBase configBase = {}; - status_t status = HidlUtils::audioConfigBaseFromHal(halConfigBase, mIsInput, &configBase); - _hidl_cb(Stream::analyzeStatus("get_audio_properties", status), configBase); - return Void(); -} - -Return Stream::setAudioProperties(const AudioConfigBaseOptional& config) { - audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; - bool formatSpecified, sRateSpecified, channelMaskSpecified; - status_t status = HidlUtils::audioConfigBaseOptionalToHal( - config, &halConfigBase, &formatSpecified, &sRateSpecified, &channelMaskSpecified); - if (status != NO_ERROR) { - return Stream::analyzeStatus("set_audio_properties", status); - } - if (sRateSpecified) { - if (Result result = setParam(AudioParameter::keySamplingRate, - static_cast(halConfigBase.sample_rate)); - result != Result::OK) { - return result; - } - } - if (channelMaskSpecified) { - if (Result result = setParam(AudioParameter::keyChannels, - static_cast(halConfigBase.channel_mask)); - result != Result::OK) { - return result; - } - } - if (formatSpecified) { - if (Result result = - setParam(AudioParameter::keyFormat, static_cast(halConfigBase.format)); - result != Result::OK) { - return result; - } - } - return Result::OK; -} - -#endif // MAJOR_VERSION <= 6 - -Return Stream::addEffect(uint64_t effectId) { - effect_handle_t halEffect = EffectMap::getInstance().get(effectId); - if (halEffect != NULL) { - return analyzeStatus("add_audio_effect", mStream->add_audio_effect(mStream, halEffect)); - } else { - ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId); - return Result::INVALID_ARGUMENTS; - } -} - -Return Stream::removeEffect(uint64_t effectId) { - effect_handle_t halEffect = EffectMap::getInstance().get(effectId); - if (halEffect != NULL) { - return analyzeStatus("remove_audio_effect", - mStream->remove_audio_effect(mStream, halEffect)); - } else { - ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId); - return Result::INVALID_ARGUMENTS; - } -} - -Return Stream::standby() { - return analyzeStatus("standby", mStream->standby(mStream)); -} - -Return Stream::setHwAvSync(uint32_t hwAvSync) { - return setParam(AudioParameter::keyStreamHwAvSync, static_cast(hwAvSync)); -} - -#if MAJOR_VERSION == 2 -Return Stream::getDevice() { - int device = 0; - Result retval = getParam(AudioParameter::keyRouting, &device); - return retval == Result::OK ? static_cast(device) : AudioDevice::NONE; -} - -Return Stream::setDevice(const DeviceAddress& address) { - return setParam(AudioParameter::keyRouting, address); -} - -Return Stream::getParameters(const hidl_vec& keys, getParameters_cb _hidl_cb) { - getParametersImpl({} /* context */, keys, _hidl_cb); - return Void(); -} - -Return Stream::setParameters(const hidl_vec& parameters) { - return setParametersImpl({} /* context */, parameters); -} - -Return Stream::setConnectedState(const DeviceAddress& address, bool connected) { - return setParam( - connected ? AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect, - address); -} -#elif MAJOR_VERSION >= 4 -Return Stream::getDevices(getDevices_cb _hidl_cb) { - int halDevice = 0; - Result retval = getParam(AudioParameter::keyRouting, &halDevice); - hidl_vec devices; - if (retval == Result::OK) { - devices.resize(1); - retval = Stream::analyzeStatus( - "get_devices", - CoreUtils::deviceAddressFromHal(static_cast(halDevice), nullptr, - &devices[0])); - } - _hidl_cb(retval, devices); - return Void(); -} - -Return Stream::setDevices(const hidl_vec& devices) { - // FIXME: can the legacy API set multiple device with address ? - if (devices.size() > 1) { - return Result::NOT_SUPPORTED; - } - DeviceAddress address{}; - if (devices.size() == 1) { - address = devices[0]; - } - return setParam(AudioParameter::keyRouting, address); -} - -Return Stream::getParameters(const hidl_vec& context, - const hidl_vec& keys, getParameters_cb _hidl_cb) { - getParametersImpl(context, keys, _hidl_cb); - return Void(); -} - -Return Stream::setParameters(const hidl_vec& context, - const hidl_vec& parameters) { - return setParametersImpl(context, parameters); -} -#endif - -Return Stream::start() { - return Result::NOT_SUPPORTED; -} - -Return Stream::stop() { - return Result::NOT_SUPPORTED; -} - -Return Stream::createMmapBuffer(int32_t minSizeFrames __unused, - createMmapBuffer_cb _hidl_cb) { - Result retval(Result::NOT_SUPPORTED); - MmapBufferInfo info; - _hidl_cb(retval, info); - return Void(); -} - -Return Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) { - Result retval(Result::NOT_SUPPORTED); - MmapPosition position; - _hidl_cb(retval, position); - return Void(); -} - -Return Stream::close() { - return Result::NOT_SUPPORTED; -} - -Return Stream::debug(const hidl_handle& fd, const hidl_vec& /* options */) { - if (fd.getNativeHandle() != nullptr && fd->numFds == 1) { - analyzeStatus("dump", mStream->dump(mStream, fd->data[0])); - } - return Void(); -} - -#if MAJOR_VERSION == 2 -Return Stream::debugDump(const hidl_handle& fd) { - return debug(fd, {} /* options */); -} -#endif - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/bluetooth/audio/hal/Stream.h b/bluetooth/audio/hal/Stream.h deleted file mode 100644 index 4e79884..0000000 --- a/bluetooth/audio/hal/Stream.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_STREAM_H -#define ANDROID_HARDWARE_AUDIO_STREAM_H - -// clang-format off -#include PATH(android/hardware/audio/COMMON_TYPES_FILE_VERSION/IStream.h) -// clang-format on - -#include "ParametersUtil.h" - -#include - -#include -#include - -#include - -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::ParametersUtil; -#if MAJOR_VERSION <= 6 -using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation:: - AudioChannelBitfield; -#endif -using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CPP_VERSION; - -struct Stream : public IStream, public ParametersUtil { - Stream(bool isInput, audio_stream_t* stream); - - /** 1GiB is the maximum buffer size the HAL client is allowed to request. - * This value has been chosen to be under SIZE_MAX and still big enough - * for all audio use case. - * Keep private for 2.0, put in .hal in 2.1 - */ - static constexpr uint32_t MAX_BUFFER_SIZE = 2 << 30 /* == 1GiB */; - - // Methods from ::android::hardware::audio::CPP_VERSION::IStream follow. - Return getFrameSize() override; - Return getFrameCount() override; - Return getBufferSize() override; -#if MAJOR_VERSION <= 6 - Return getSampleRate() override; -#if MAJOR_VERSION == 2 - Return getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; - Return getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override; -#endif - Return getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb); - Return getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb); - Return setSampleRate(uint32_t sampleRateHz) override; - Return getChannelMask() override; - Return setChannelMask(AudioChannelBitfield mask) override; - Return getFormat() override; - Return getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; - Return setFormat(AudioFormat format) override; -#else - Return getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; - Return setAudioProperties(const AudioConfigBaseOptional& config) override; -#endif // MAJOR_VERSION <= 6 - Return getAudioProperties(getAudioProperties_cb _hidl_cb) override; - Return addEffect(uint64_t effectId) override; - Return removeEffect(uint64_t effectId) override; - Return standby() override; -#if MAJOR_VERSION == 2 - Return getDevice() override; - Return setDevice(const DeviceAddress& address) override; - Return getParameters(const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& parameters) override; - Return setConnectedState(const DeviceAddress& address, bool connected) override; -#elif MAJOR_VERSION >= 4 - Return getDevices(getDevices_cb _hidl_cb) override; - Return setDevices(const hidl_vec& devices) override; - Return getParameters(const hidl_vec& context, - const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& context, - const hidl_vec& parameters) override; -#endif - Return setHwAvSync(uint32_t hwAvSync) override; - Return start() override; - Return stop() override; - Return createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; - Return getMmapPosition(getMmapPosition_cb _hidl_cb) override; - Return close() override; - - Return debug(const hidl_handle& fd, const hidl_vec& options) override; -#if MAJOR_VERSION == 2 - Return debugDump(const hidl_handle& fd) override; -#endif - - // Utility methods for extending interfaces. - static Result analyzeStatus(const char* funcName, int status); - static Result analyzeStatus(const char* funcName, int status, - const std::vector& ignoreErrors); - - private: - const bool mIsInput; - audio_stream_t* mStream; - - virtual ~Stream(); - - // Methods from ParametersUtil. - char* halGetParameters(const char* keys) override; - int halSetParameters(const char* keysAndValues) override; -}; - -template -struct StreamMmap : public RefBase { - explicit StreamMmap(T* stream) : mStream(stream) {} - - Return start(); - Return stop(); - Return createMmapBuffer(int32_t minSizeFrames, size_t frameSize, - IStream::createMmapBuffer_cb _hidl_cb); - Return getMmapPosition(IStream::getMmapPosition_cb _hidl_cb); - - private: - StreamMmap() {} - - T* mStream; -}; - -template -Return StreamMmap::start() { - if (mStream->start == NULL) return Result::NOT_SUPPORTED; - int result = mStream->start(mStream); - return Stream::analyzeStatus("start", result); -} - -template -Return StreamMmap::stop() { - if (mStream->stop == NULL) return Result::NOT_SUPPORTED; - int result = mStream->stop(mStream); - return Stream::analyzeStatus("stop", result); -} - -template -Return StreamMmap::createMmapBuffer(int32_t minSizeFrames, size_t frameSize, - IStream::createMmapBuffer_cb _hidl_cb) { - Result retval(Result::NOT_SUPPORTED); - MmapBufferInfo info; - native_handle_t* hidlHandle = nullptr; - - if (mStream->create_mmap_buffer != NULL) { - if (minSizeFrames <= 0) { - retval = Result::INVALID_ARGUMENTS; - goto exit; - } - struct audio_mmap_buffer_info halInfo; - retval = Stream::analyzeStatus( - "create_mmap_buffer", mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo)); - if (retval == Result::OK) { - hidlHandle = native_handle_create(1, 0); - hidlHandle->data[0] = halInfo.shared_memory_fd; - - // Negative buffer size frame is a legacy hack to indicate that the buffer - // is shareable to applications before the relevant flag was introduced - bool applicationShareable = - halInfo.flags & AUDIO_MMAP_APPLICATION_SHAREABLE || halInfo.buffer_size_frames < 0; - halInfo.buffer_size_frames = abs(halInfo.buffer_size_frames); - info.sharedMemory = // hidl_memory size must always be positive - hidl_memory("audio_buffer", hidlHandle, frameSize * halInfo.buffer_size_frames); -#if MAJOR_VERSION == 2 - if (applicationShareable) { - halInfo.buffer_size_frames *= -1; - } -#else - info.flags = - halInfo.flags | (applicationShareable ? MmapBufferFlag::APPLICATION_SHAREABLE - : MmapBufferFlag::NONE); -#endif - info.bufferSizeFrames = halInfo.buffer_size_frames; - info.burstSizeFrames = halInfo.burst_size_frames; - } - } -exit: - _hidl_cb(retval, info); - if (hidlHandle != nullptr) { - native_handle_delete(hidlHandle); - } - return Void(); -} - -template -Return StreamMmap::getMmapPosition(IStream::getMmapPosition_cb _hidl_cb) { - Result retval(Result::NOT_SUPPORTED); - MmapPosition position; - - if (mStream->get_mmap_position != NULL) { - struct audio_mmap_position halPosition; - retval = Stream::analyzeStatus("get_mmap_position", - mStream->get_mmap_position(mStream, &halPosition)); - if (retval == Result::OK) { - position.timeNanoseconds = halPosition.time_nanoseconds; - position.positionFrames = halPosition.position_frames; - } - } - _hidl_cb(retval, position); - return Void(); -} - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_STREAM_H diff --git a/bluetooth/audio/hal/StreamIn.cpp b/bluetooth/audio/hal/StreamIn.cpp deleted file mode 100644 index c45fb0c..0000000 --- a/bluetooth/audio/hal/StreamIn.cpp +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#define LOG_TAG "StreamInHAL" - -#include "StreamIn.h" -#include "Util.h" -#include "common/all-versions/HidlSupport.h" - -//#define LOG_NDEBUG 0 -#define ATRACE_TAG ATRACE_TAG_AUDIO - -#include -#include -#include -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils; -using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils; -namespace util { -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; -} - -namespace { - -class ReadThread : public Thread { - public: - // ReadThread's lifespan never exceeds StreamIn's lifespan. - ReadThread(std::atomic* stop, audio_stream_in_t* stream, StreamIn::CommandMQ* commandMQ, - StreamIn::DataMQ* dataMQ, StreamIn::StatusMQ* statusMQ, EventFlag* efGroup) - : Thread(false /*canCallJava*/), - mStop(stop), - mStream(stream), - mCommandMQ(commandMQ), - mDataMQ(dataMQ), - mStatusMQ(statusMQ), - mEfGroup(efGroup), - mBuffer(nullptr) {} - bool init() { - mBuffer.reset(new (std::nothrow) uint8_t[mDataMQ->getQuantumCount()]); - return mBuffer != nullptr; - } - virtual ~ReadThread() {} - - private: - std::atomic* mStop; - audio_stream_in_t* mStream; - StreamIn::CommandMQ* mCommandMQ; - StreamIn::DataMQ* mDataMQ; - StreamIn::StatusMQ* mStatusMQ; - EventFlag* mEfGroup; - std::unique_ptr mBuffer; - IStreamIn::ReadParameters mParameters; - IStreamIn::ReadStatus mStatus; - - bool threadLoop() override; - - void doGetCapturePosition(); - void doRead(); -}; - -void ReadThread::doRead() { - size_t availableToWrite = mDataMQ->availableToWrite(); - size_t requestedToRead = mParameters.params.read; - if (requestedToRead > availableToWrite) { - ALOGW( - "truncating read data from %d to %d due to insufficient data queue " - "space", - (int32_t)requestedToRead, (int32_t)availableToWrite); - requestedToRead = availableToWrite; - } - ssize_t readResult = mStream->read(mStream, &mBuffer[0], requestedToRead); - mStatus.retval = Result::OK; - if (readResult >= 0) { - mStatus.reply.read = readResult; - if (!mDataMQ->write(&mBuffer[0], readResult)) { - ALOGW("data message queue write failed"); - } - } else { - mStatus.retval = Stream::analyzeStatus("read", readResult); - } -} - -void ReadThread::doGetCapturePosition() { - mStatus.retval = StreamIn::getCapturePositionImpl( - mStream, &mStatus.reply.capturePosition.frames, &mStatus.reply.capturePosition.time); -} - -bool ReadThread::threadLoop() { - // This implementation doesn't return control back to the Thread until it - // decides to stop, - // as the Thread uses mutexes, and this can lead to priority inversion. - while (!std::atomic_load_explicit(mStop, std::memory_order_acquire)) { - uint32_t efState = 0; - mEfGroup->wait(static_cast(MessageQueueFlagBits::NOT_FULL), &efState); - if (!(efState & static_cast(MessageQueueFlagBits::NOT_FULL))) { - continue; // Nothing to do. - } - if (!mCommandMQ->read(&mParameters)) { - continue; // Nothing to do. - } - mStatus.replyTo = mParameters.command; - switch (mParameters.command) { - case IStreamIn::ReadCommand::READ: - doRead(); - break; - case IStreamIn::ReadCommand::GET_CAPTURE_POSITION: - doGetCapturePosition(); - break; - default: - ALOGE("Unknown read thread command code %d", mParameters.command); - mStatus.retval = Result::NOT_SUPPORTED; - break; - } - if (!mStatusMQ->write(&mStatus)) { - ALOGW("status message queue write failed"); - } - mEfGroup->wake(static_cast(MessageQueueFlagBits::NOT_EMPTY)); - } - - return false; -} - -} // namespace - -StreamIn::StreamIn(const sp& device, audio_stream_in_t* stream) - : mDevice(device), - mStream(stream), - mStreamCommon(new Stream(true /*isInput*/, &stream->common)), - mStreamMmap(new StreamMmap(stream)), - mEfGroup(nullptr), - mStopReadThread(false) {} - -StreamIn::~StreamIn() { - ATRACE_CALL(); - close(); - if (mReadThread.get()) { - ATRACE_NAME("mReadThread->join"); - status_t status = mReadThread->join(); - ALOGE_IF(status, "read thread exit error: %s", strerror(-status)); - } - if (mEfGroup) { - status_t status = EventFlag::deleteEventFlag(&mEfGroup); - ALOGE_IF(status, "read MQ event flag deletion error: %s", strerror(-status)); - } -#if MAJOR_VERSION <= 5 - mDevice->closeInputStream(mStream); -#endif - mStream = nullptr; -} - -// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow. -Return StreamIn::getFrameSize() { - return audio_stream_in_frame_size(mStream); -} - -Return StreamIn::getFrameCount() { - return mStreamCommon->getFrameCount(); -} - -Return StreamIn::getBufferSize() { - return mStreamCommon->getBufferSize(); -} - -#if MAJOR_VERSION <= 6 -Return StreamIn::getSampleRate() { - return mStreamCommon->getSampleRate(); -} - -#if MAJOR_VERSION == 2 -Return StreamIn::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) { - return mStreamCommon->getSupportedChannelMasks(_hidl_cb); -} -Return StreamIn::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) { - return mStreamCommon->getSupportedSampleRates(_hidl_cb); -} -#endif - -Return StreamIn::getSupportedChannelMasks(AudioFormat format, - getSupportedChannelMasks_cb _hidl_cb) { - return mStreamCommon->getSupportedChannelMasks(format, _hidl_cb); -} -Return StreamIn::getSupportedSampleRates(AudioFormat format, - getSupportedSampleRates_cb _hidl_cb) { - return mStreamCommon->getSupportedSampleRates(format, _hidl_cb); -} - -Return StreamIn::setSampleRate(uint32_t sampleRateHz) { - return mStreamCommon->setSampleRate(sampleRateHz); -} - -Return StreamIn::getChannelMask() { - return mStreamCommon->getChannelMask(); -} - -Return StreamIn::setChannelMask(AudioChannelBitfield mask) { - return mStreamCommon->setChannelMask(mask); -} - -Return StreamIn::getFormat() { - return mStreamCommon->getFormat(); -} - -Return StreamIn::getSupportedFormats(getSupportedFormats_cb _hidl_cb) { - return mStreamCommon->getSupportedFormats(_hidl_cb); -} - -Return StreamIn::setFormat(AudioFormat format) { - return mStreamCommon->setFormat(format); -} - -#else - -Return StreamIn::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { - return mStreamCommon->getSupportedProfiles(_hidl_cb); -} - -Return StreamIn::setAudioProperties(const AudioConfigBaseOptional& config) { - return mStreamCommon->setAudioProperties(config); -} - -#endif // MAJOR_VERSION <= 6 - -Return StreamIn::getAudioProperties(getAudioProperties_cb _hidl_cb) { - return mStreamCommon->getAudioProperties(_hidl_cb); -} - -Return StreamIn::addEffect(uint64_t effectId) { - return mStreamCommon->addEffect(effectId); -} - -Return StreamIn::removeEffect(uint64_t effectId) { - return mStreamCommon->removeEffect(effectId); -} - -Return StreamIn::standby() { - return mStreamCommon->standby(); -} - -Return StreamIn::setHwAvSync(uint32_t hwAvSync) { - return mStreamCommon->setHwAvSync(hwAvSync); -} - -#if MAJOR_VERSION == 2 -Return StreamIn::setConnectedState(const DeviceAddress& address, bool connected) { - return mStreamCommon->setConnectedState(address, connected); -} - -Return StreamIn::getDevice() { - return mStreamCommon->getDevice(); -} - -Return StreamIn::setDevice(const DeviceAddress& address) { - return mStreamCommon->setDevice(address); -} - -Return StreamIn::getParameters(const hidl_vec& keys, getParameters_cb _hidl_cb) { - return mStreamCommon->getParameters(keys, _hidl_cb); -} - -Return StreamIn::setParameters(const hidl_vec& parameters) { - return mStreamCommon->setParameters(parameters); -} - -Return StreamIn::debugDump(const hidl_handle& fd) { - return mStreamCommon->debugDump(fd); -} -#elif MAJOR_VERSION >= 4 -Return StreamIn::getDevices(getDevices_cb _hidl_cb) { - return mStreamCommon->getDevices(_hidl_cb); -} - -Return StreamIn::setDevices(const hidl_vec& devices) { - return mStreamCommon->setDevices(devices); -} -Return StreamIn::getParameters(const hidl_vec& context, - const hidl_vec& keys, getParameters_cb _hidl_cb) { - return mStreamCommon->getParameters(context, keys, _hidl_cb); -} - -Return StreamIn::setParameters(const hidl_vec& context, - const hidl_vec& parameters) { - return mStreamCommon->setParameters(context, parameters); -} -#endif - -Return StreamIn::start() { - return mStreamMmap->start(); -} - -Return StreamIn::stop() { - return mStreamMmap->stop(); -} - -Return StreamIn::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) { - return mStreamMmap->createMmapBuffer(minSizeFrames, audio_stream_in_frame_size(mStream), - _hidl_cb); -} - -Return StreamIn::getMmapPosition(getMmapPosition_cb _hidl_cb) { - return mStreamMmap->getMmapPosition(_hidl_cb); -} - -Return StreamIn::close() { - if (mStopReadThread.load(std::memory_order_relaxed)) { // only this thread writes - return Result::INVALID_STATE; - } - mStopReadThread.store(true, std::memory_order_release); - if (mEfGroup) { - mEfGroup->wake(static_cast(MessageQueueFlagBits::NOT_FULL)); - } -#if MAJOR_VERSION >= 6 - mDevice->closeInputStream(mStream); -#endif - return Result::OK; -} - -// Methods from ::android::hardware::audio::CPP_VERSION::IStreamIn follow. -Return StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) { - int halSource; - Result retval = mStreamCommon->getParam(AudioParameter::keyInputSource, &halSource); - AudioSource source = {}; - if (retval == Result::OK) { - retval = Stream::analyzeStatus( - "get_audio_source", - HidlUtils::audioSourceFromHal(static_cast(halSource), &source)); - } - _hidl_cb(retval, source); - return Void(); -} - -Return StreamIn::setGain(float gain) { - if (!util::isGainNormalized(gain)) { - ALOGW("Can not set a stream input gain (%f) outside [0,1]", gain); - return Result::INVALID_ARGUMENTS; - } - return Stream::analyzeStatus("set_gain", mStream->set_gain(mStream, gain)); -} - -Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCount, - prepareForReading_cb _hidl_cb) { - status_t status; -#if MAJOR_VERSION <= 6 - ThreadInfo threadInfo = {0, 0}; -#else - int32_t threadInfo = 0; -#endif - - // Wrap the _hidl_cb to return an error - auto sendError = [&threadInfo, &_hidl_cb](Result result) { - _hidl_cb(result, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), - threadInfo); - }; - - // Create message queues. - if (mDataMQ) { - ALOGE("the client attempts to call prepareForReading twice"); - sendError(Result::INVALID_STATE); - return Void(); - } - std::unique_ptr tempCommandMQ(new CommandMQ(1)); - - // Check frameSize and framesCount - if (frameSize == 0 || framesCount == 0) { - ALOGE("Null frameSize (%u) or framesCount (%u)", frameSize, framesCount); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - - if (frameSize > Stream::MAX_BUFFER_SIZE / framesCount) { - ALOGE("Buffer too big: %u*%u bytes > MAX_BUFFER_SIZE (%u)", frameSize, framesCount, - Stream::MAX_BUFFER_SIZE); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - std::unique_ptr tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */)); - - std::unique_ptr tempStatusMQ(new StatusMQ(1)); - if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) { - ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid"); - ALOGE_IF(!tempDataMQ->isValid(), "data MQ is invalid"); - ALOGE_IF(!tempStatusMQ->isValid(), "status MQ is invalid"); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - EventFlag* tempRawEfGroup{}; - status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup); - std::unique_ptr tempElfGroup( - tempRawEfGroup, [](auto* ef) { EventFlag::deleteEventFlag(&ef); }); - if (status != OK || !tempElfGroup) { - ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - - // Create and launch the thread. - auto tempReadThread = - sp::make(&mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), - tempStatusMQ.get(), tempElfGroup.get()); - if (!tempReadThread->init()) { - ALOGW("failed to start reader thread: %s", strerror(-status)); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - status = tempReadThread->run("reader", PRIORITY_URGENT_AUDIO); - if (status != OK) { - ALOGW("failed to start reader thread: %s", strerror(-status)); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - - mCommandMQ = std::move(tempCommandMQ); - mDataMQ = std::move(tempDataMQ); - mStatusMQ = std::move(tempStatusMQ); - mReadThread = tempReadThread; - mEfGroup = tempElfGroup.release(); -#if MAJOR_VERSION <= 6 - threadInfo.pid = getpid(); - threadInfo.tid = mReadThread->getTid(); -#else - threadInfo = mReadThread->getTid(); -#endif - _hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(), - threadInfo); - return Void(); -} - -Return StreamIn::getInputFramesLost() { - return mStream->get_input_frames_lost(mStream); -} - -// static -Result StreamIn::getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames, - uint64_t* time) { - // HAL may have a stub function, always returning ENOSYS, don't - // spam the log in this case. - static const std::vector ignoredErrors{ENOSYS}; - Result retval(Result::NOT_SUPPORTED); - if (stream->get_capture_position == NULL) return retval; - int64_t halFrames, halTime; - retval = Stream::analyzeStatus("get_capture_position", - stream->get_capture_position(stream, &halFrames, &halTime), - ignoredErrors); - if (retval == Result::OK) { - *frames = halFrames; - *time = halTime; - } - return retval; -}; - -Return StreamIn::getCapturePosition(getCapturePosition_cb _hidl_cb) { - uint64_t frames = 0, time = 0; - Result retval = getCapturePositionImpl(mStream, &frames, &time); - _hidl_cb(retval, frames, time); - return Void(); -} - -Return StreamIn::debug(const hidl_handle& fd, const hidl_vec& options) { - return mStreamCommon->debug(fd, options); -} - -#if MAJOR_VERSION >= 4 -Result StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) { - std::vector halTracks; -#if MAJOR_VERSION <= 6 - (void)CoreUtils::sinkMetadataToHal(sinkMetadata, &halTracks); -#else - // Validate whether a conversion to V7 is possible. This is needed - // to have a consistent behavior of the HAL regardless of the API - // version of the legacy HAL (and also to be consistent with openInputStream). - std::vector halTracksV7; - if (status_t status = CoreUtils::sinkMetadataToHalV7( - sinkMetadata, false /*ignoreNonVendorTags*/, &halTracksV7); - status == NO_ERROR) { - halTracks.reserve(halTracksV7.size()); - for (auto metadata_v7 : halTracksV7) { - halTracks.push_back(std::move(metadata_v7.base)); - } - } else { - return Stream::analyzeStatus("sinkMetadataToHal", status); - } -#endif // MAJOR_VERSION <= 6 - const sink_metadata_t halMetadata = { - .track_count = halTracks.size(), - .tracks = halTracks.data(), - }; - mStream->update_sink_metadata(mStream, &halMetadata); - return Result::OK; -} - -#if MAJOR_VERSION >= 7 -Result StreamIn::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) { - std::vector halTracks; - if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata, - false /*ignoreNonVendorTags*/, &halTracks); - status != NO_ERROR) { - return Stream::analyzeStatus("sinkMetadataToHal", status); - } - const sink_metadata_v7_t halMetadata = { - .track_count = halTracks.size(), - .tracks = halTracks.data(), - }; - mStream->update_sink_metadata_v7(mStream, &halMetadata); - return Result::OK; -} -#endif // MAJOR_VERSION >= 7 - -#if MAJOR_VERSION <= 6 -Return StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { - if (mStream->update_sink_metadata == nullptr) { - return Void(); // not supported by the HAL - } - (void)doUpdateSinkMetadata(sinkMetadata); - return Void(); -} -#elif MAJOR_VERSION >= 7 -Return StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { - if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) { - if (mStream->update_sink_metadata == nullptr) { - return Result::NOT_SUPPORTED; - } - return doUpdateSinkMetadata(sinkMetadata); - } else { - if (mStream->update_sink_metadata_v7 == nullptr) { - return Result::NOT_SUPPORTED; - } - return doUpdateSinkMetadataV7(sinkMetadata); - } -} -#endif - -Return StreamIn::getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) { - Result retval = Result::NOT_SUPPORTED; - size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT; - audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT]; - - hidl_vec microphones; - if (mStream->get_active_microphones != NULL && - mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics) == 0) { - microphones.resize(actual_mics); - for (size_t i = 0; i < actual_mics; ++i) { - (void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]); - } - retval = Result::OK; - } - - _hidl_cb(retval, microphones); - return Void(); -} -#endif - -#if MAJOR_VERSION >= 5 -Return StreamIn::setMicrophoneDirection(MicrophoneDirection direction) { - if (mStream->set_microphone_direction == nullptr) { - return Result::NOT_SUPPORTED; - } - if (!common::utils::isValidHidlEnum(direction)) { - ALOGE("%s: Invalid direction %d", __func__, direction); - return Result::INVALID_ARGUMENTS; - } - return Stream::analyzeStatus( - "set_microphone_direction", - mStream->set_microphone_direction( - mStream, static_cast(direction))); -} - -Return StreamIn::setMicrophoneFieldDimension(float zoom) { - if (mStream->set_microphone_field_dimension == nullptr) { - return Result::NOT_SUPPORTED; - } - if (std::isnan(zoom) || zoom < -1 || zoom > 1) { - ALOGE("%s: Invalid zoom %f", __func__, zoom); - return Result::INVALID_ARGUMENTS; - } - return Stream::analyzeStatus("set_microphone_field_dimension", - mStream->set_microphone_field_dimension(mStream, zoom)); -} - -#endif - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/bluetooth/audio/hal/StreamIn.h b/bluetooth/audio/hal/StreamIn.h deleted file mode 100644 index 4627eec..0000000 --- a/bluetooth/audio/hal/StreamIn.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_STREAMIN_H -#define ANDROID_HARDWARE_AUDIO_STREAMIN_H - -// clang-format off -#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStreamIn.h) -// clang-format on - -#include "Device.h" -#include "Stream.h" - -#include -#include - -#include -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CPP_VERSION; - -struct StreamIn : public IStreamIn { - typedef MessageQueue CommandMQ; - typedef MessageQueue DataMQ; - typedef MessageQueue StatusMQ; - - StreamIn(const sp& device, audio_stream_in_t* stream); - - // Methods from ::android::hardware::audio::CPP_VERSION::IStream follow. - Return getFrameSize() override; - Return getFrameCount() override; - Return getBufferSize() override; -#if MAJOR_VERSION <= 6 - Return getSampleRate() override; -#if MAJOR_VERSION == 2 - Return getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; - Return getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override; -#endif - Return getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb); - Return getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb); - Return setSampleRate(uint32_t sampleRateHz) override; - Return getChannelMask() override; - Return setChannelMask(AudioChannelBitfield mask) override; - Return getFormat() override; - Return getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; - Return setFormat(AudioFormat format) override; -#else - Return getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; - Return setAudioProperties(const AudioConfigBaseOptional& config) override; -#endif // MAJOR_VERSION <= 6 - Return getAudioProperties(getAudioProperties_cb _hidl_cb) override; - Return addEffect(uint64_t effectId) override; - Return removeEffect(uint64_t effectId) override; - Return standby() override; -#if MAJOR_VERSION == 2 - Return getDevice() override; - Return setDevice(const DeviceAddress& address) override; - Return getParameters(const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& parameters) override; - Return setConnectedState(const DeviceAddress& address, bool connected) override; -#elif MAJOR_VERSION >= 4 - Return getDevices(getDevices_cb _hidl_cb) override; - Return setDevices(const hidl_vec& devices) override; - Return getParameters(const hidl_vec& context, - const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& context, - const hidl_vec& parameters) override; -#endif - Return setHwAvSync(uint32_t hwAvSync) override; - Return close() override; - - Return debug(const hidl_handle& fd, const hidl_vec& options) override; -#if MAJOR_VERSION == 2 - Return debugDump(const hidl_handle& fd) override; -#endif - - // Methods from ::android::hardware::audio::CPP_VERSION::IStreamIn follow. - Return getAudioSource(getAudioSource_cb _hidl_cb) override; - Return setGain(float gain) override; - Return prepareForReading(uint32_t frameSize, uint32_t framesCount, - prepareForReading_cb _hidl_cb) override; - Return getInputFramesLost() override; - Return getCapturePosition(getCapturePosition_cb _hidl_cb) override; - Return start() override; - Return stop() override; - Return createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; - Return getMmapPosition(getMmapPosition_cb _hidl_cb) override; -#if MAJOR_VERSION >= 4 -#if MAJOR_VERSION <= 6 - Return updateSinkMetadata(const SinkMetadata& sinkMetadata) override; -#else - Return updateSinkMetadata(const SinkMetadata& sinkMetadata) override; -#endif - Return getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) override; -#endif // MAJOR_VERSION >= 4 -#if MAJOR_VERSION >= 5 - Return setMicrophoneDirection(MicrophoneDirection direction) override; - Return setMicrophoneFieldDimension(float zoom) override; -#endif - static Result getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames, - uint64_t* time); - - private: -#if MAJOR_VERSION >= 4 - Result doUpdateSinkMetadata(const SinkMetadata& sinkMetadata); -#if MAJOR_VERSION >= 7 - Result doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata); -#endif -#endif // MAJOR_VERSION >= 4 - - const sp mDevice; - audio_stream_in_t* mStream; - const sp mStreamCommon; - const sp> mStreamMmap; - std::unique_ptr mCommandMQ; - std::unique_ptr mDataMQ; - std::unique_ptr mStatusMQ; - EventFlag* mEfGroup; - std::atomic mStopReadThread; - sp mReadThread; - - virtual ~StreamIn(); -}; - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_STREAMIN_H diff --git a/bluetooth/audio/hal/StreamOut.cpp b/bluetooth/audio/hal/StreamOut.cpp deleted file mode 100644 index be85a9f..0000000 --- a/bluetooth/audio/hal/StreamOut.cpp +++ /dev/null @@ -1,837 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#define LOG_TAG "StreamOutHAL" - -#include "StreamOut.h" -#include "Util.h" - -//#define LOG_NDEBUG 0 -#define ATRACE_TAG ATRACE_TAG_AUDIO - -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils; -using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils; -namespace util { -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::util; -} - -namespace { - -class WriteThread : public Thread { - public: - // WriteThread's lifespan never exceeds StreamOut's lifespan. - WriteThread(std::atomic* stop, audio_stream_out_t* stream, - StreamOut::CommandMQ* commandMQ, StreamOut::DataMQ* dataMQ, - StreamOut::StatusMQ* statusMQ, EventFlag* efGroup) - : Thread(false /*canCallJava*/), - mStop(stop), - mStream(stream), - mCommandMQ(commandMQ), - mDataMQ(dataMQ), - mStatusMQ(statusMQ), - mEfGroup(efGroup), - mBuffer(nullptr) {} - bool init() { - mBuffer.reset(new (std::nothrow) uint8_t[mDataMQ->getQuantumCount()]); - return mBuffer != nullptr; - } - virtual ~WriteThread() {} - - private: - std::atomic* mStop; - audio_stream_out_t* mStream; - StreamOut::CommandMQ* mCommandMQ; - StreamOut::DataMQ* mDataMQ; - StreamOut::StatusMQ* mStatusMQ; - EventFlag* mEfGroup; - std::unique_ptr mBuffer; - IStreamOut::WriteStatus mStatus; - - bool threadLoop() override; - - void doGetLatency(); - void doGetPresentationPosition(); - void doWrite(); -}; - -void WriteThread::doWrite() { - const size_t availToRead = mDataMQ->availableToRead(); - mStatus.retval = Result::OK; - mStatus.reply.written = 0; - if (mDataMQ->read(&mBuffer[0], availToRead)) { - ssize_t writeResult = mStream->write(mStream, &mBuffer[0], availToRead); - if (writeResult >= 0) { - mStatus.reply.written = writeResult; - } else { - mStatus.retval = Stream::analyzeStatus("write", writeResult); - } - } -} - -void WriteThread::doGetPresentationPosition() { - mStatus.retval = - StreamOut::getPresentationPositionImpl(mStream, &mStatus.reply.presentationPosition.frames, - &mStatus.reply.presentationPosition.timeStamp); -} - -void WriteThread::doGetLatency() { - mStatus.retval = Result::OK; - mStatus.reply.latencyMs = mStream->get_latency(mStream); -} - -bool WriteThread::threadLoop() { - // This implementation doesn't return control back to the Thread until it - // decides to stop, - // as the Thread uses mutexes, and this can lead to priority inversion. - while (!std::atomic_load_explicit(mStop, std::memory_order_acquire)) { - uint32_t efState = 0; - mEfGroup->wait(static_cast(MessageQueueFlagBits::NOT_EMPTY), &efState); - if (!(efState & static_cast(MessageQueueFlagBits::NOT_EMPTY))) { - continue; // Nothing to do. - } - if (!mCommandMQ->read(&mStatus.replyTo)) { - continue; // Nothing to do. - } - switch (mStatus.replyTo) { - case IStreamOut::WriteCommand::WRITE: - doWrite(); - break; - case IStreamOut::WriteCommand::GET_PRESENTATION_POSITION: - doGetPresentationPosition(); - break; - case IStreamOut::WriteCommand::GET_LATENCY: - doGetLatency(); - break; - default: - ALOGE("Unknown write thread command code %d", mStatus.replyTo); - mStatus.retval = Result::NOT_SUPPORTED; - break; - } - if (!mStatusMQ->write(&mStatus)) { - ALOGE("status message queue write failed"); - } - mEfGroup->wake(static_cast(MessageQueueFlagBits::NOT_FULL)); - } - - return false; -} - -} // namespace - -StreamOut::StreamOut(const sp& device, audio_stream_out_t* stream) - : mDevice(device), - mStream(stream), - mStreamCommon(new Stream(false /*isInput*/, &stream->common)), - mStreamMmap(new StreamMmap(stream)), - mEfGroup(nullptr), - mStopWriteThread(false) {} - -StreamOut::~StreamOut() { - ATRACE_CALL(); - (void)close(); - if (mWriteThread.get()) { - ATRACE_NAME("mWriteThread->join"); - status_t status = mWriteThread->join(); - ALOGE_IF(status, "write thread exit error: %s", strerror(-status)); - } - if (mEfGroup) { - status_t status = EventFlag::deleteEventFlag(&mEfGroup); - ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status)); - } - mCallback = nullptr; -#if MAJOR_VERSION <= 5 - mDevice->closeOutputStream(mStream); - // Closing the output stream in the HAL waits for the callback to finish, - // and joins the callback thread. Thus is it guaranteed that the callback - // thread will not be accessing our object anymore. -#endif - mStream = nullptr; -} - -// Methods from ::android::hardware::audio::CPP_VERSION::IStream follow. -Return StreamOut::getFrameSize() { - return audio_stream_out_frame_size(mStream); -} - -Return StreamOut::getFrameCount() { - return mStreamCommon->getFrameCount(); -} - -Return StreamOut::getBufferSize() { - return mStreamCommon->getBufferSize(); -} - -#if MAJOR_VERSION <= 6 -Return StreamOut::getSampleRate() { - return mStreamCommon->getSampleRate(); -} - -#if MAJOR_VERSION == 2 -Return StreamOut::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) { - return mStreamCommon->getSupportedChannelMasks(_hidl_cb); -} -Return StreamOut::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) { - return mStreamCommon->getSupportedSampleRates(_hidl_cb); -} -#endif - -Return StreamOut::getSupportedChannelMasks(AudioFormat format, - getSupportedChannelMasks_cb _hidl_cb) { - return mStreamCommon->getSupportedChannelMasks(format, _hidl_cb); -} -Return StreamOut::getSupportedSampleRates(AudioFormat format, - getSupportedSampleRates_cb _hidl_cb) { - return mStreamCommon->getSupportedSampleRates(format, _hidl_cb); -} - -Return StreamOut::setSampleRate(uint32_t sampleRateHz) { - return mStreamCommon->setSampleRate(sampleRateHz); -} - -Return StreamOut::getChannelMask() { - return mStreamCommon->getChannelMask(); -} - -Return StreamOut::setChannelMask(AudioChannelBitfield mask) { - return mStreamCommon->setChannelMask(mask); -} - -Return StreamOut::getFormat() { - return mStreamCommon->getFormat(); -} - -Return StreamOut::getSupportedFormats(getSupportedFormats_cb _hidl_cb) { - return mStreamCommon->getSupportedFormats(_hidl_cb); -} - -Return StreamOut::setFormat(AudioFormat format) { - return mStreamCommon->setFormat(format); -} - -#else - -Return StreamOut::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { - return mStreamCommon->getSupportedProfiles(_hidl_cb); -} - -Return StreamOut::setAudioProperties(const AudioConfigBaseOptional& config) { - return mStreamCommon->setAudioProperties(config); -} - -#endif // MAJOR_VERSION <= 6 - -Return StreamOut::getAudioProperties(getAudioProperties_cb _hidl_cb) { - return mStreamCommon->getAudioProperties(_hidl_cb); -} - -Return StreamOut::addEffect(uint64_t effectId) { - return mStreamCommon->addEffect(effectId); -} - -Return StreamOut::removeEffect(uint64_t effectId) { - return mStreamCommon->removeEffect(effectId); -} - -Return StreamOut::standby() { - return mStreamCommon->standby(); -} - -Return StreamOut::setHwAvSync(uint32_t hwAvSync) { - return mStreamCommon->setHwAvSync(hwAvSync); -} - -#if MAJOR_VERSION == 2 -Return StreamOut::setConnectedState(const DeviceAddress& address, bool connected) { - return mStreamCommon->setConnectedState(address, connected); -} - -Return StreamOut::getDevice() { - return mStreamCommon->getDevice(); -} - -Return StreamOut::setDevice(const DeviceAddress& address) { - return mStreamCommon->setDevice(address); -} - -Return StreamOut::getParameters(const hidl_vec& keys, - getParameters_cb _hidl_cb) { - return mStreamCommon->getParameters(keys, _hidl_cb); -} - -Return StreamOut::setParameters(const hidl_vec& parameters) { - return mStreamCommon->setParameters(parameters); -} - -Return StreamOut::debugDump(const hidl_handle& fd) { - return mStreamCommon->debugDump(fd); -} -#elif MAJOR_VERSION >= 4 -Return StreamOut::getDevices(getDevices_cb _hidl_cb) { - return mStreamCommon->getDevices(_hidl_cb); -} - -Return StreamOut::setDevices(const hidl_vec& devices) { - return mStreamCommon->setDevices(devices); -} -Return StreamOut::getParameters(const hidl_vec& context, - const hidl_vec& keys, - getParameters_cb _hidl_cb) { - return mStreamCommon->getParameters(context, keys, _hidl_cb); -} - -Return StreamOut::setParameters(const hidl_vec& context, - const hidl_vec& parameters) { - return mStreamCommon->setParameters(context, parameters); -} -#endif - -Return StreamOut::close() { - if (mStopWriteThread.load(std::memory_order_relaxed)) { // only this thread writes - return Result::INVALID_STATE; - } - mStopWriteThread.store(true, std::memory_order_release); - if (mEfGroup) { - mEfGroup->wake(static_cast(MessageQueueFlagBits::NOT_EMPTY)); - } -#if MAJOR_VERSION >= 6 - mDevice->closeOutputStream(mStream); -#endif - return Result::OK; -} - -// Methods from ::android::hardware::audio::CPP_VERSION::IStreamOut follow. -Return StreamOut::getLatency() { - return mStream->get_latency(mStream); -} - -Return StreamOut::setVolume(float left, float right) { - if (mStream->set_volume == NULL) { - return Result::NOT_SUPPORTED; - } - if (!util::isGainNormalized(left)) { - ALOGW("Can not set a stream output volume {%f, %f} outside [0,1]", left, right); - return Result::INVALID_ARGUMENTS; - } - return Stream::analyzeStatus("set_volume", mStream->set_volume(mStream, left, right), - {ENOSYS} /*ignore*/); -} - -Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCount, - prepareForWriting_cb _hidl_cb) { - status_t status; -#if MAJOR_VERSION <= 6 - ThreadInfo threadInfo = {0, 0}; -#else - int32_t threadInfo = 0; -#endif - - // Wrap the _hidl_cb to return an error - auto sendError = [&threadInfo, &_hidl_cb](Result result) { - _hidl_cb(result, CommandMQ::Descriptor(), DataMQ::Descriptor(), StatusMQ::Descriptor(), - threadInfo); - }; - - // Create message queues. - if (mDataMQ) { - ALOGE("the client attempts to call prepareForWriting twice"); - sendError(Result::INVALID_STATE); - return Void(); - } - std::unique_ptr tempCommandMQ(new CommandMQ(1)); - - // Check frameSize and framesCount - if (frameSize == 0 || framesCount == 0) { - ALOGE("Null frameSize (%u) or framesCount (%u)", frameSize, framesCount); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - if (frameSize > Stream::MAX_BUFFER_SIZE / framesCount) { - ALOGE("Buffer too big: %u*%u bytes > MAX_BUFFER_SIZE (%u)", frameSize, framesCount, - Stream::MAX_BUFFER_SIZE); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - std::unique_ptr tempDataMQ(new DataMQ(frameSize * framesCount, true /* EventFlag */)); - - std::unique_ptr tempStatusMQ(new StatusMQ(1)); - if (!tempCommandMQ->isValid() || !tempDataMQ->isValid() || !tempStatusMQ->isValid()) { - ALOGE_IF(!tempCommandMQ->isValid(), "command MQ is invalid"); - ALOGE_IF(!tempDataMQ->isValid(), "data MQ is invalid"); - ALOGE_IF(!tempStatusMQ->isValid(), "status MQ is invalid"); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - EventFlag* tempRawEfGroup{}; - status = EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &tempRawEfGroup); - std::unique_ptr tempElfGroup( - tempRawEfGroup, [](auto* ef) { EventFlag::deleteEventFlag(&ef); }); - if (status != OK || !tempElfGroup) { - ALOGE("failed creating event flag for data MQ: %s", strerror(-status)); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - - // Create and launch the thread. - auto tempWriteThread = - sp::make(&mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), - tempStatusMQ.get(), tempElfGroup.get()); - if (!tempWriteThread->init()) { - ALOGW("failed to start writer thread: %s", strerror(-status)); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - status = tempWriteThread->run("writer", PRIORITY_URGENT_AUDIO); - if (status != OK) { - ALOGW("failed to start writer thread: %s", strerror(-status)); - sendError(Result::INVALID_ARGUMENTS); - return Void(); - } - - mCommandMQ = std::move(tempCommandMQ); - mDataMQ = std::move(tempDataMQ); - mStatusMQ = std::move(tempStatusMQ); - mWriteThread = tempWriteThread; - mEfGroup = tempElfGroup.release(); -#if MAJOR_VERSION <= 6 - threadInfo.pid = getpid(); - threadInfo.tid = mWriteThread->getTid(); -#else - threadInfo = mWriteThread->getTid(); -#endif - _hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(), - threadInfo); - return Void(); -} - -Return StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb) { - uint32_t halDspFrames; - Result retval = Stream::analyzeStatus("get_render_position", - mStream->get_render_position(mStream, &halDspFrames), - {ENOSYS} /*ignore*/); - _hidl_cb(retval, halDspFrames); - return Void(); -} - -Return StreamOut::getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb) { - Result retval(Result::NOT_SUPPORTED); - int64_t timestampUs = 0; - if (mStream->get_next_write_timestamp != NULL) { - retval = Stream::analyzeStatus("get_next_write_timestamp", - mStream->get_next_write_timestamp(mStream, ×tampUs), - {ENOSYS} /*ignore*/); - } - _hidl_cb(retval, timestampUs); - return Void(); -} - -Return StreamOut::setCallback(const sp& callback) { - if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED; - // Safe to pass 'this' because it is guaranteed that the callback thread - // is joined prior to exit from StreamOut's destructor. - int result = mStream->set_callback(mStream, StreamOut::asyncCallback, this); - if (result == 0) { - mCallback = callback; - } - return Stream::analyzeStatus("set_callback", result, {ENOSYS} /*ignore*/); -} - -Return StreamOut::clearCallback() { - if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED; - mCallback = nullptr; - return Result::OK; -} - -// static -int StreamOut::asyncCallback(stream_callback_event_t event, void*, void* cookie) { - // It is guaranteed that the callback thread is joined prior - // to exiting from StreamOut's destructor. Must *not* use sp - // here because it can make this code the last owner of StreamOut, - // and an attempt to run the destructor on the callback thread - // will cause a deadlock in the legacy HAL code. - StreamOut* self = reinterpret_cast(cookie); - // It's correct to hold an sp<> to callback because the reference - // in the StreamOut instance can be cleared in the meantime. There is - // no difference on which thread to run IStreamOutCallback's destructor. - sp callback = self->mCallback.load(); - if (callback.get() == nullptr) return 0; - ALOGV("asyncCallback() event %d", event); - Return result; - switch (event) { - case STREAM_CBK_EVENT_WRITE_READY: - result = callback->onWriteReady(); - break; - case STREAM_CBK_EVENT_DRAIN_READY: - result = callback->onDrainReady(); - break; - case STREAM_CBK_EVENT_ERROR: - result = callback->onError(); - break; - default: - ALOGW("asyncCallback() unknown event %d", event); - break; - } - ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str()); - return 0; -} - -Return StreamOut::supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb) { - _hidl_cb(mStream->pause != NULL, mStream->resume != NULL); - return Void(); -} - -Return StreamOut::pause() { - return mStream->pause != NULL - ? Stream::analyzeStatus("pause", mStream->pause(mStream), {ENOSYS} /*ignore*/) - : Result::NOT_SUPPORTED; -} - -Return StreamOut::resume() { - return mStream->resume != NULL - ? Stream::analyzeStatus("resume", mStream->resume(mStream), {ENOSYS} /*ignore*/) - : Result::NOT_SUPPORTED; -} - -Return StreamOut::supportsDrain() { - return mStream->drain != NULL; -} - -Return StreamOut::drain(AudioDrain type) { - audio_drain_type_t halDrainType = - type == AudioDrain::EARLY_NOTIFY ? AUDIO_DRAIN_EARLY_NOTIFY : AUDIO_DRAIN_ALL; - return mStream->drain != NULL - ? Stream::analyzeStatus("drain", mStream->drain(mStream, halDrainType), - {ENOSYS} /*ignore*/) - : Result::NOT_SUPPORTED; -} - -Return StreamOut::flush() { - return mStream->flush != NULL - ? Stream::analyzeStatus("flush", mStream->flush(mStream), {ENOSYS} /*ignore*/) - : Result::NOT_SUPPORTED; -} - -// static -Result StreamOut::getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames, - TimeSpec* timeStamp) { - // Don't logspam on EINVAL--it's normal for get_presentation_position - // to return it sometimes. EAGAIN may be returned by A2DP audio HAL - // implementation. ENODATA can also be reported while the writer is - // continuously querying it, but the stream has been stopped. - static const std::vector ignoredErrors{EINVAL, EAGAIN, ENODATA, ENOSYS}; - Result retval(Result::NOT_SUPPORTED); - if (stream->get_presentation_position == NULL) return retval; - struct timespec halTimeStamp; - retval = Stream::analyzeStatus("get_presentation_position", - stream->get_presentation_position(stream, frames, &halTimeStamp), - ignoredErrors); - if (retval == Result::OK) { - timeStamp->tvSec = halTimeStamp.tv_sec; - timeStamp->tvNSec = halTimeStamp.tv_nsec; - } - return retval; -} - -Return StreamOut::getPresentationPosition(getPresentationPosition_cb _hidl_cb) { - uint64_t frames = 0; - TimeSpec timeStamp = {0, 0}; - Result retval = getPresentationPositionImpl(mStream, &frames, &timeStamp); - _hidl_cb(retval, frames, timeStamp); - return Void(); -} - -Return StreamOut::start() { - return mStreamMmap->start(); -} - -Return StreamOut::stop() { - return mStreamMmap->stop(); -} - -Return StreamOut::createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) { - return mStreamMmap->createMmapBuffer(minSizeFrames, audio_stream_out_frame_size(mStream), - _hidl_cb); -} - -Return StreamOut::getMmapPosition(getMmapPosition_cb _hidl_cb) { - return mStreamMmap->getMmapPosition(_hidl_cb); -} - -Return StreamOut::debug(const hidl_handle& fd, const hidl_vec& options) { - return mStreamCommon->debug(fd, options); -} - -#if MAJOR_VERSION >= 4 -Result StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) { - std::vector halTracks; -#if MAJOR_VERSION <= 6 - (void)CoreUtils::sourceMetadataToHal(sourceMetadata, &halTracks); -#else - // Validate whether a conversion to V7 is possible. This is needed - // to have a consistent behavior of the HAL regardless of the API - // version of the legacy HAL (and also to be consistent with openOutputStream). - std::vector halTracksV7; - if (status_t status = CoreUtils::sourceMetadataToHalV7( - sourceMetadata, false /*ignoreNonVendorTags*/, &halTracksV7); - status == NO_ERROR) { - halTracks.reserve(halTracksV7.size()); - for (auto metadata_v7 : halTracksV7) { - halTracks.push_back(std::move(metadata_v7.base)); - } - } else { - return Stream::analyzeStatus("sourceMetadataToHal", status); - } -#endif // MAJOR_VERSION <= 6 - const source_metadata_t halMetadata = { - .track_count = halTracks.size(), - .tracks = halTracks.data(), - }; - mStream->update_source_metadata(mStream, &halMetadata); - return Result::OK; -} - -#if MAJOR_VERSION >= 7 -Result StreamOut::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) { - std::vector halTracks; - if (status_t status = CoreUtils::sourceMetadataToHalV7( - sourceMetadata, false /*ignoreNonVendorTags*/, &halTracks); - status != NO_ERROR) { - return Stream::analyzeStatus("sourceMetadataToHal", status); - } - const source_metadata_v7_t halMetadata = { - .track_count = halTracks.size(), - .tracks = halTracks.data(), - }; - mStream->update_source_metadata_v7(mStream, &halMetadata); - return Result::OK; -} -#endif // MAJOR_VERSION >= 7 - -#if MAJOR_VERSION <= 6 -Return StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) { - if (mStream->update_source_metadata == nullptr) { - return Void(); // not supported by the HAL - } - (void)doUpdateSourceMetadata(sourceMetadata); - return Void(); -} -#elif MAJOR_VERSION >= 7 -Return StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) { - if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) { - if (mStream->update_source_metadata == nullptr) { - return Result::NOT_SUPPORTED; - } - return doUpdateSourceMetadata(sourceMetadata); - } else { - if (mStream->update_source_metadata_v7 == nullptr) { - return Result::NOT_SUPPORTED; - } - return doUpdateSourceMetadataV7(sourceMetadata); - } -} -#endif - -Return StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) { - return Result::NOT_SUPPORTED; // TODO: propagate to legacy -} -#endif - -#if MAJOR_VERSION >= 6 -Return StreamOut::getDualMonoMode(getDualMonoMode_cb _hidl_cb) { - audio_dual_mono_mode_t mode = AUDIO_DUAL_MONO_MODE_OFF; - Result retval = mStream->get_dual_mono_mode != nullptr - ? Stream::analyzeStatus("get_dual_mono_mode", - mStream->get_dual_mono_mode(mStream, &mode)) - : Result::NOT_SUPPORTED; - _hidl_cb(retval, DualMonoMode(mode)); - return Void(); -} - -Return StreamOut::setDualMonoMode(DualMonoMode mode) { - return mStream->set_dual_mono_mode != nullptr - ? Stream::analyzeStatus( - "set_dual_mono_mode", - mStream->set_dual_mono_mode(mStream, - static_cast(mode))) - : Result::NOT_SUPPORTED; -} - -Return StreamOut::getAudioDescriptionMixLevel(getAudioDescriptionMixLevel_cb _hidl_cb) { - float leveldB = -std::numeric_limits::infinity(); - Result retval = mStream->get_audio_description_mix_level != nullptr - ? Stream::analyzeStatus( - "get_audio_description_mix_level", - mStream->get_audio_description_mix_level(mStream, &leveldB)) - : Result::NOT_SUPPORTED; - _hidl_cb(retval, leveldB); - return Void(); -} - -Return StreamOut::setAudioDescriptionMixLevel(float leveldB) { - return mStream->set_audio_description_mix_level != nullptr - ? Stream::analyzeStatus( - "set_audio_description_mix_level", - mStream->set_audio_description_mix_level(mStream, leveldB)) - : Result::NOT_SUPPORTED; -} - -Return StreamOut::getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) { - audio_playback_rate_t rate = AUDIO_PLAYBACK_RATE_INITIALIZER; - Result retval = - mStream->get_playback_rate_parameters != nullptr - ? Stream::analyzeStatus("get_playback_rate_parameters", - mStream->get_playback_rate_parameters(mStream, &rate)) - : Result::NOT_SUPPORTED; - _hidl_cb(retval, - PlaybackRate{rate.mSpeed, rate.mPitch, static_cast(rate.mStretchMode), - static_cast(rate.mFallbackMode)}); - return Void(); -} - -Return StreamOut::setPlaybackRateParameters(const PlaybackRate& playbackRate) { - audio_playback_rate_t rate = { - playbackRate.speed, playbackRate.pitch, - static_cast(playbackRate.timestretchMode), - static_cast(playbackRate.fallbackMode)}; - return mStream->set_playback_rate_parameters != nullptr - ? Stream::analyzeStatus("set_playback_rate_parameters", - mStream->set_playback_rate_parameters(mStream, &rate)) - : Result::NOT_SUPPORTED; -} - -Return StreamOut::setEventCallback(const sp& callback) { - if (mStream->set_event_callback == nullptr) return Result::NOT_SUPPORTED; - int result = mStream->set_event_callback(mStream, StreamOut::asyncEventCallback, this); - if (result == 0) { - mEventCallback = callback; - } - return Stream::analyzeStatus("set_stream_out_callback", result, {ENOSYS} /*ignore*/); -} - -// static -int StreamOut::asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie) { - StreamOut* self = reinterpret_cast(cookie); - sp eventCallback = self->mEventCallback.load(); - if (eventCallback.get() == nullptr) return 0; - ALOGV("%s event %d", __func__, event); - Return result; - switch (event) { - case STREAM_EVENT_CBK_TYPE_CODEC_FORMAT_CHANGED: { - hidl_vec audioMetadata; - // void* param is the byte string buffer from byte_string_from_audio_metadata(). - // As the byte string buffer may have embedded zeroes, we cannot use strlen() - // but instead use audio_utils::metadata::dataByteStringLen(). - audioMetadata.setToExternal((uint8_t*)param, audio_utils::metadata::dataByteStringLen( - (const uint8_t*)param)); - result = eventCallback->onCodecFormatChanged(audioMetadata); - } break; - default: - ALOGW("%s unknown event %d", __func__, event); - break; - } - ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str()); - return 0; -} - -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 -Return StreamOut::setLatencyMode(LatencyMode mode) { - return mStream->set_latency_mode != nullptr - ? Stream::analyzeStatus( - "set_latency_mode", - mStream->set_latency_mode(mStream, - static_cast(mode))) - : Result::NOT_SUPPORTED; -}; - -Return StreamOut::getRecommendedLatencyModes(getRecommendedLatencyModes_cb _hidl_cb) { - Result retval = Result::NOT_SUPPORTED; - hidl_vec hidlModes; - size_t num_modes = AUDIO_LATENCY_MODE_CNT; - audio_latency_mode_t modes[AUDIO_LATENCY_MODE_CNT]; - - if (mStream->get_recommended_latency_modes != nullptr && - mStream->get_recommended_latency_modes(mStream, &modes[0], &num_modes) == 0) { - if (num_modes == 0 || num_modes > AUDIO_LATENCY_MODE_CNT) { - ALOGW("%s invalid number of modes returned: %zu", __func__, num_modes); - retval = Result::INVALID_STATE; - } else { - hidlModes.resize(num_modes); - for (size_t i = 0; i < num_modes; ++i) { - hidlModes[i] = static_cast(modes[i]); - } - retval = Result::OK; - } - } - _hidl_cb(retval, hidlModes); - return Void(); -}; - -// static -void StreamOut::latencyModeCallback(audio_latency_mode_t* modes, size_t num_modes, void* cookie) { - StreamOut* self = reinterpret_cast(cookie); - sp callback = self->mLatencyModeCallback.load(); - if (callback.get() == nullptr) return; - - ALOGV("%s", __func__); - - if (num_modes == 0 || num_modes > AUDIO_LATENCY_MODE_CNT) { - ALOGW("%s invalid number of modes returned: %zu", __func__, num_modes); - return; - } - - hidl_vec hidlModes(num_modes); - for (size_t i = 0; i < num_modes; ++i) { - hidlModes[i] = static_cast(modes[i]); - } - Return result = callback->onRecommendedLatencyModeChanged(hidlModes); - ALOGW_IF(!result.isOk(), "Client callback failed: %s", result.description().c_str()); -} - -Return StreamOut::setLatencyModeCallback( - const sp& callback) { - if (mStream->set_latency_mode_callback == nullptr) return Result::NOT_SUPPORTED; - int result = mStream->set_latency_mode_callback(mStream, StreamOut::latencyModeCallback, this); - if (result == 0) { - mLatencyModeCallback = callback; - } - return Stream::analyzeStatus("set_latency_mode_callback", result, {ENOSYS} /*ignore*/); -}; - -#endif - -#endif - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/bluetooth/audio/hal/StreamOut.h b/bluetooth/audio/hal/StreamOut.h deleted file mode 100644 index ce5253f..0000000 --- a/bluetooth/audio/hal/StreamOut.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_STREAMOUT_H -#define ANDROID_HARDWARE_AUDIO_STREAMOUT_H - -#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h) - -#include "Device.h" -#include "Stream.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CPP_VERSION; - -struct StreamOut : public IStreamOut { - typedef MessageQueue CommandMQ; - typedef MessageQueue DataMQ; - typedef MessageQueue StatusMQ; - - StreamOut(const sp& device, audio_stream_out_t* stream); - - // Methods from ::android::hardware::audio::CPP_VERSION::IStream follow. - Return getFrameSize() override; - Return getFrameCount() override; - Return getBufferSize() override; -#if MAJOR_VERSION <= 6 - Return getSampleRate() override; -#if MAJOR_VERSION == 2 - Return getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; - Return getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override; -#endif - Return getSupportedSampleRates(AudioFormat format, getSupportedSampleRates_cb _hidl_cb); - Return getSupportedChannelMasks(AudioFormat format, getSupportedChannelMasks_cb _hidl_cb); - Return setSampleRate(uint32_t sampleRateHz) override; - Return getChannelMask() override; - Return setChannelMask(AudioChannelBitfield mask) override; - Return getFormat() override; - Return getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; - Return setFormat(AudioFormat format) override; -#else - Return getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; - Return setAudioProperties(const AudioConfigBaseOptional& config) override; -#endif // MAJOR_VERSION <= 6 - Return getAudioProperties(getAudioProperties_cb _hidl_cb) override; - Return addEffect(uint64_t effectId) override; - Return removeEffect(uint64_t effectId) override; - Return standby() override; -#if MAJOR_VERSION == 2 - Return getDevice() override; - Return setDevice(const DeviceAddress& address) override; - Return getParameters(const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& parameters) override; - Return setConnectedState(const DeviceAddress& address, bool connected) override; -#elif MAJOR_VERSION >= 4 - Return getDevices(getDevices_cb _hidl_cb) override; - Return setDevices(const hidl_vec& devices) override; - Return getParameters(const hidl_vec& context, - const hidl_vec& keys, - getParameters_cb _hidl_cb) override; - Return setParameters(const hidl_vec& context, - const hidl_vec& parameters) override; -#endif - Return setHwAvSync(uint32_t hwAvSync) override; - Return close() override; - - Return debug(const hidl_handle& fd, const hidl_vec& options) override; -#if MAJOR_VERSION == 2 - Return debugDump(const hidl_handle& fd) override; -#endif - - // Methods from ::android::hardware::audio::CPP_VERSION::IStreamOut follow. - Return getLatency() override; - Return setVolume(float left, float right) override; - Return prepareForWriting(uint32_t frameSize, uint32_t framesCount, - prepareForWriting_cb _hidl_cb) override; - Return getRenderPosition(getRenderPosition_cb _hidl_cb) override; - Return getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb) override; - Return setCallback(const sp& callback) override; - Return clearCallback() override; - Return supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb) override; - Return pause() override; - Return resume() override; - Return supportsDrain() override; - Return drain(AudioDrain type) override; - Return flush() override; - Return getPresentationPosition(getPresentationPosition_cb _hidl_cb) override; - Return start() override; - Return stop() override; - Return createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; - Return getMmapPosition(getMmapPosition_cb _hidl_cb) override; -#if MAJOR_VERSION >= 4 - Return selectPresentation(int32_t presentationId, int32_t programId) override; -#if MAJOR_VERSION <= 6 - Return updateSourceMetadata(const SourceMetadata& sourceMetadata) override; -#else - Return updateSourceMetadata(const SourceMetadata& sourceMetadata) override; -#endif -#endif // MAJOR_VERSION >= 4 -#if MAJOR_VERSION >= 6 - Return getDualMonoMode(getDualMonoMode_cb _hidl_cb) override; - Return setDualMonoMode(DualMonoMode mode) override; - Return getAudioDescriptionMixLevel(getAudioDescriptionMixLevel_cb _hidl_cb) override; - Return setAudioDescriptionMixLevel(float leveldB) override; - Return getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) override; - Return setPlaybackRateParameters(const PlaybackRate& playbackRate) override; -#endif - - static Result getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames, - TimeSpec* timeStamp); - -#if MAJOR_VERSION >= 6 - Return setEventCallback(const sp& callback) override; -#endif - - private: -#if MAJOR_VERSION >= 4 - Result doUpdateSourceMetadata(const SourceMetadata& sourceMetadata); -#if MAJOR_VERSION >= 7 - Result doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata); -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 - Return setLatencyMode(LatencyMode mode) override; - Return getRecommendedLatencyModes(getRecommendedLatencyModes_cb _hidl_cb) override; - Return setLatencyModeCallback( - const sp& callback) override; -#endif -#endif -#endif // MAJOR_VERSION >= 4 - - const sp mDevice; - audio_stream_out_t* mStream; - const sp mStreamCommon; - const sp> mStreamMmap; - mediautils::atomic_sp mCallback; // for non-blocking write and drain -#if MAJOR_VERSION >= 6 - mediautils::atomic_sp mEventCallback; -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 - mediautils::atomic_sp mLatencyModeCallback; -#endif -#endif - std::unique_ptr mCommandMQ; - std::unique_ptr mDataMQ; - std::unique_ptr mStatusMQ; - EventFlag* mEfGroup; - std::atomic mStopWriteThread; - sp mWriteThread; - - virtual ~StreamOut(); - - static int asyncCallback(stream_callback_event_t event, void* param, void* cookie); - -#if MAJOR_VERSION >= 6 - static int asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie); -#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 - static void latencyModeCallback(audio_latency_mode_t* modes, size_t num_modes, void* cookie); -#endif -#endif -}; - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_STREAMOUT_H diff --git a/bluetooth/audio/hal/Util.h b/bluetooth/audio/hal/Util.h deleted file mode 100644 index abf5317..0000000 --- a/bluetooth/audio/hal/Util.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_UTIL_H -#define ANDROID_HARDWARE_AUDIO_UTIL_H - -// clang-format off -#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h) -// clang-format on - -#include -#include - -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CORE_TYPES_CPP_VERSION { -namespace implementation { - -using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION; -using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION; - -namespace util { - -/** @return true if gain is between 0 and 1 included. */ -constexpr bool isGainNormalized(float gain) { - return gain >= 0.0 && gain <= 1.0; -} - -template -inline bool element_in(T e, const std::vector& v) { - return std::find(v.begin(), v.end(), e) != v.end(); -} - -static inline Result analyzeStatus(status_t status) { - switch (status) { - case 0: - return Result::OK; - case -EINVAL: - return Result::INVALID_ARGUMENTS; - case -ENODATA: - return Result::INVALID_STATE; - case -ENODEV: - return Result::NOT_INITIALIZED; - case -ENOSYS: - return Result::NOT_SUPPORTED; - default: - return Result::INVALID_STATE; - } -} - -static inline Result analyzeStatus(const char* className, const char* funcName, status_t status, - const std::vector& ignoreErrors = {}) { - if (status != 0 && !element_in(-status, ignoreErrors)) { - ALOGW("Error from HAL %s in function %s: %s", className, funcName, strerror(-status)); - } - return analyzeStatus(status); -} - -} // namespace util -} // namespace implementation -} // namespace CORE_TYPES_CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_UTIL_H diff --git a/bluetooth/audio/hal/android.hardware.bluetooth.audio-service-system.rc b/bluetooth/audio/hal/android.hardware.bluetooth.audio-service-system.rc deleted file mode 100644 index 34be159..0000000 --- a/bluetooth/audio/hal/android.hardware.bluetooth.audio-service-system.rc +++ /dev/null @@ -1,9 +0,0 @@ -service system.bt-audio-hal /system/bin/hw/android.hardware.bluetooth.audio-service-system - class hal - user audioserver - # media gid needed for /dev/fm (radio) and for /data/misc/media (tee) - group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub - capabilities BLOCK_SUSPEND - ioprio rt 4 - task_profiles ProcessCapacityHigh HighPerformance - onrestart restart audioserver diff --git a/bluetooth/audio/hal/bluetooth_audio.xml b/bluetooth/audio/hal/bluetooth_audio.xml deleted file mode 100644 index c4b1872..0000000 --- a/bluetooth/audio/hal/bluetooth_audio.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - android.hardware.bluetooth.audio - 2 - IBluetoothAudioProviderFactory/default - - diff --git a/bluetooth/audio/hal/bluetooth_audio_system.xml b/bluetooth/audio/hal/bluetooth_audio_system.xml deleted file mode 100644 index 450127d..0000000 --- a/bluetooth/audio/hal/bluetooth_audio_system.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - android.hardware.bluetooth.audio - 2 - IBluetoothAudioProviderFactory/sysbta - - - android.hardware.audio - hwbinder - @6.0::IDevicesFactory/sysbta - - diff --git a/bluetooth/audio/hal/service.cpp b/bluetooth/audio/hal/service.cpp deleted file mode 100644 index f8f9cde..0000000 --- a/bluetooth/audio/hal/service.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BtAudioAIDLService" - -#include -#include -#include - -#include "BluetoothAudioProviderFactory.h" - -using ::aidl::android::hardware::bluetooth::audio:: - BluetoothAudioProviderFactory; - -extern "C" __attribute__((visibility("default"))) binder_status_t -createIBluetoothAudioProviderFactory() { - auto factory = ::ndk::SharedRefBase::make(); - const std::string instance_name = - std::string() + BluetoothAudioProviderFactory::descriptor + "/default"; - binder_status_t aidl_status = AServiceManager_addService( - factory->asBinder().get(), instance_name.c_str()); - ALOGW_IF(aidl_status != STATUS_OK, "Could not register %s, status=%d", - instance_name.c_str(), aidl_status); - return aidl_status; -} \ No newline at end of file diff --git a/bluetooth/audio/hal/service_system.cpp b/bluetooth/audio/hal/service_system.cpp deleted file mode 100644 index 5b5ce11..0000000 --- a/bluetooth/audio/hal/service_system.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BtAudioAIDLServiceSystem" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h) - -#include - -#include "BluetoothAudioProviderFactory.h" -#include "DevicesFactory.h" - -//using namespace android::hardware; -using ::aidl::android::hardware::bluetooth::audio:: - BluetoothAudioProviderFactory; - -using ::android::hardware::audio::CPP_VERSION::implementation::DevicesFactory; -using namespace ::android::hardware::audio::CPP_VERSION; - -int main() { - signal(SIGPIPE, SIG_IGN); - - ::android::hardware::configureRpcThreadpool(16, true); - ::android::ProcessState::initWithDriver("/dev/binder"); - // start a threadpool for binder / hwbinder interactions - ::android::ProcessState::self()->startThreadPool(); - ::android::hardware::ProcessState::self()->startThreadPool(); - - auto factory = ::ndk::SharedRefBase::make(); - const std::string instance_name = - std::string() + BluetoothAudioProviderFactory::descriptor + "/sysbta"; - binder_status_t aidl_status = AServiceManager_addService( - factory->asBinder().get(), instance_name.c_str()); - ALOGW_IF(aidl_status != STATUS_OK, "Could not register %s, status=%d", - instance_name.c_str(), aidl_status); - - ::android::sp audio_factory = new DevicesFactory(); - ::android::status_t hidl_status = audio_factory->registerAsService("sysbta"); - ALOGW_IF(hidl_status != STATUS_OK, "Could not register sysbta, status=%d", hidl_status); - - ::android::hardware::joinRpcThreadpool(); -} diff --git a/bluetooth/audio/hw/Android.bp b/bluetooth/audio/hw/Android.bp deleted file mode 100644 index b7f016d..0000000 --- a/bluetooth/audio/hw/Android.bp +++ /dev/null @@ -1,33 +0,0 @@ -cc_library_shared { - name: "audio.sysbta.default", - relative_install_path: "hw", - srcs: [ - "audio_bluetooth_hw.cc", - "stream_apis.cc", - "device_port_proxy.cc", - "device_port_proxy_hidl.cc", - "utils.cc", - ], - header_libs: ["libhardware_headers"], - shared_libs: [ - "android.hardware.bluetooth.audio-V2-ndk", - "libbluetooth_audio_session_aidl_system", - "libaudioutils", - "libbase", - "libbinder_ndk", - "libcutils", - "libfmq", - "liblog", - "libutils", - // HIDL dependencies - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", - "libbluetooth_audio_session_system", - "libhidlbase", - ], - cflags: [ - "-Wall", - "-Werror", - "-Wno-unused-parameter", - ], -} diff --git a/bluetooth/audio/hw/audio_bluetooth_hw.cc b/bluetooth/audio/hw/audio_bluetooth_hw.cc deleted file mode 100644 index 887c4e3..0000000 --- a/bluetooth/audio/hw/audio_bluetooth_hw.cc +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2019 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. - */ - -#define LOG_TAG "BTAudioHw" - -#include -#include -#include -#include -#include -#include -#include - -#include "stream_apis.h" -#include "utils.h" - -using ::android::bluetooth::audio::utils::GetAudioParamString; -using ::android::bluetooth::audio::utils::ParseAudioParams; - -static int adev_set_parameters(struct audio_hw_device* dev, - const char* kvpairs) { - LOG(VERBOSE) << __func__ << ": kevpairs=[" << kvpairs << "]"; - std::unordered_map params = - ParseAudioParams(kvpairs); - if (params.empty()) return 0; - - LOG(VERBOSE) << __func__ << ": ParamsMap=[" << GetAudioParamString(params) - << "]"; - if (params.find("A2dpSuspended") == params.end()) { - return -ENOSYS; - } - - auto* bluetooth_device = reinterpret_cast(dev); - std::lock_guard guard(bluetooth_device->mutex_); - for (auto sout : bluetooth_device->opened_stream_outs_) { - if (sout->stream_out_.common.set_parameters != nullptr) { - sout->stream_out_.common.set_parameters(&sout->stream_out_.common, - kvpairs); - } - } - return 0; -} - -static char* adev_get_parameters(const struct audio_hw_device* dev, - const char* keys) { - LOG(VERBOSE) << __func__ << ": keys=[" << keys << "]"; - return strdup(""); -} - -static int adev_init_check(const struct audio_hw_device* dev) { return 0; } - -static int adev_set_voice_volume(struct audio_hw_device* dev, float volume) { - LOG(VERBOSE) << __func__ << ": volume=" << volume; - return -ENOSYS; -} - -static int adev_set_master_volume(struct audio_hw_device* dev, float volume) { - LOG(VERBOSE) << __func__ << ": volume=" << volume; - return -ENOSYS; -} - -static int adev_get_master_volume(struct audio_hw_device* dev, float* volume) { - return -ENOSYS; -} - -static int adev_set_master_mute(struct audio_hw_device* dev, bool muted) { - LOG(VERBOSE) << __func__ << ": mute=" << muted; - return -ENOSYS; -} - -static int adev_get_master_mute(struct audio_hw_device* dev, bool* muted) { - return -ENOSYS; -} - -static int adev_set_mode(struct audio_hw_device* dev, audio_mode_t mode) { - LOG(VERBOSE) << __func__ << ": mode=" << mode; - return 0; -} - -static int adev_set_mic_mute(struct audio_hw_device* dev, bool state) { - LOG(VERBOSE) << __func__ << ": state=" << state; - return -ENOSYS; -} - -static int adev_get_mic_mute(const struct audio_hw_device* dev, bool* state) { - return -ENOSYS; -} - -static int adev_dump(const audio_hw_device_t* device, int fd) { return 0; } - -static int adev_close(hw_device_t* device) { - auto* bluetooth_device = reinterpret_cast(device); - delete bluetooth_device; - return 0; -} - -static int adev_open(const hw_module_t* module, const char* name, - hw_device_t** device) { - LOG(VERBOSE) << __func__ << ": name=[" << name << "]"; - if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL; - - auto bluetooth_audio_device = new BluetoothAudioDevice{}; - struct audio_hw_device* adev = &bluetooth_audio_device->audio_device_; - if (!adev) return -ENOMEM; - - adev->common.tag = HARDWARE_DEVICE_TAG; - adev->common.version = AUDIO_DEVICE_API_VERSION_2_0; - adev->common.module = (struct hw_module_t*)module; - adev->common.close = adev_close; - - adev->init_check = adev_init_check; - adev->set_voice_volume = adev_set_voice_volume; - adev->set_master_volume = adev_set_master_volume; - adev->get_master_volume = adev_get_master_volume; - adev->set_mode = adev_set_mode; - adev->set_mic_mute = adev_set_mic_mute; - adev->get_mic_mute = adev_get_mic_mute; - adev->set_parameters = adev_set_parameters; - adev->get_parameters = adev_get_parameters; - adev->get_input_buffer_size = adev_get_input_buffer_size; - adev->open_output_stream = adev_open_output_stream; - adev->close_output_stream = adev_close_output_stream; - adev->open_input_stream = adev_open_input_stream; - adev->close_input_stream = adev_close_input_stream; - adev->dump = adev_dump; - adev->set_master_mute = adev_set_master_mute; - adev->get_master_mute = adev_get_master_mute; - - *device = &adev->common; - return 0; -} - -static struct hw_module_methods_t hal_module_methods = { - .open = adev_open, -}; - -struct audio_module HAL_MODULE_INFO_SYM = { - .common = - { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = AUDIO_MODULE_API_VERSION_0_1, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = AUDIO_HARDWARE_MODULE_ID, - .name = "Bluetooth Audio HW HAL", - .author = "The Android Open Source Project", - .methods = &hal_module_methods, - }, -}; diff --git a/bluetooth/audio/hw/device_port_proxy.cc b/bluetooth/audio/hw/device_port_proxy.cc deleted file mode 100644 index 8b49c4d..0000000 --- a/bluetooth/audio/hw/device_port_proxy.cc +++ /dev/null @@ -1,618 +0,0 @@ -/* - * Copyright 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. - * 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. - */ - -#define LOG_TAG "BTAudioHalDeviceProxyAIDL" - -#include "device_port_proxy.h" - -#include -#include -#include -#include -#include -#include - -#include "BluetoothAudioSessionControl.h" -#include "stream_apis.h" -#include "utils.h" - -namespace android { -namespace bluetooth { -namespace audio { -namespace aidl { - -using ::aidl::android::hardware::bluetooth::audio::AudioConfiguration; -using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioSessionControl; -using ::aidl::android::hardware::bluetooth::audio::ChannelMode; -using ::aidl::android::hardware::bluetooth::audio::PcmConfiguration; -using ::aidl::android::hardware::bluetooth::audio::PortStatusCallbacks; -using ::aidl::android::hardware::bluetooth::audio::PresentationPosition; - -using ::android::base::StringPrintf; -using ControlResultCallback = std::function; -using SessionChangedCallback = std::function; - -namespace { - -audio_channel_mask_t OutputChannelModeToAudioFormat(ChannelMode channel_mode) { - switch (channel_mode) { - case ChannelMode::MONO: - return AUDIO_CHANNEL_OUT_MONO; - case ChannelMode::STEREO: - return AUDIO_CHANNEL_OUT_STEREO; - default: - return kBluetoothDefaultOutputChannelModeMask; - } -} - -audio_channel_mask_t InputChannelModeToAudioFormat(ChannelMode channel_mode) { - switch (channel_mode) { - case ChannelMode::MONO: - return AUDIO_CHANNEL_IN_MONO; - case ChannelMode::STEREO: - return AUDIO_CHANNEL_IN_STEREO; - default: - return kBluetoothDefaultInputChannelModeMask; - } -} - -audio_format_t BitsPerSampleToAudioFormat(uint8_t bits_per_sample, - const SessionType& session_type) { - switch (bits_per_sample) { - case 16: - return AUDIO_FORMAT_PCM_16_BIT; - case 24: - /* Now we use knowledge that Classic sessions used packed, and LE Audio - * LC3 encoder uses unpacked as input. This should be passed as parameter - * from BT stack through AIDL, but it would require new interface version, - * so sticking with this workaround for now. */ - if (session_type == - SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH) { - return AUDIO_FORMAT_PCM_24_BIT_PACKED; - } else { - return AUDIO_FORMAT_PCM_8_24_BIT; - } - case 32: - return AUDIO_FORMAT_PCM_32_BIT; - default: - return kBluetoothDefaultAudioFormatBitsPerSample; - } -} - -// The maximum time to wait in std::condition_variable::wait_for() -constexpr unsigned int kMaxWaitingTimeMs = 4500; - -} // namespace - -BluetoothAudioPortAidl::BluetoothAudioPortAidl() - : cookie_(::aidl::android::hardware::bluetooth::audio:: - kObserversCookieUndefined), - state_(BluetoothStreamState::DISABLED), - session_type_(SessionType::UNKNOWN) {} - -BluetoothAudioPortAidlOut::~BluetoothAudioPortAidlOut() { - if (in_use()) TearDown(); -} - -BluetoothAudioPortAidlIn::~BluetoothAudioPortAidlIn() { - if (in_use()) TearDown(); -} - -bool BluetoothAudioPortAidl::SetUp(audio_devices_t devices) { - if (!init_session_type(devices)) return false; - - state_ = BluetoothStreamState::STANDBY; - - auto control_result_cb = [port = this](uint16_t cookie, bool start_resp, - const BluetoothAudioStatus& status) { - if (!port->in_use()) { - LOG(ERROR) << "control_result_cb: BluetoothAudioPortAidl is not in use"; - return; - } - if (port->cookie_ != cookie) { - LOG(ERROR) << "control_result_cb: proxy of device port (cookie=" - << StringPrintf("%#hx", cookie) << ") is corrupted"; - return; - } - port->ControlResultHandler(status); - }; - auto session_changed_cb = [port = this](uint16_t cookie) { - if (!port->in_use()) { - LOG(ERROR) << "session_changed_cb: BluetoothAudioPortAidl is not in use"; - return; - } - if (port->cookie_ != cookie) { - LOG(ERROR) << "session_changed_cb: proxy of device port (cookie=" - << StringPrintf("%#hx", cookie) << ") is corrupted"; - return; - } - port->SessionChangedHandler(); - }; - // TODO: Add audio_config_changed_cb - PortStatusCallbacks cbacks = { - .control_result_cb_ = control_result_cb, - .session_changed_cb_ = session_changed_cb, - }; - cookie_ = BluetoothAudioSessionControl::RegisterControlResultCback( - session_type_, cbacks); - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_); - - return ( - cookie_ != - ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined); -} - -bool BluetoothAudioPortAidl::init_session_type(audio_devices_t device) { - switch (device) { - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: - 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; - 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; - break; - case AUDIO_DEVICE_OUT_BLE_HEADSET: - LOG(VERBOSE) << __func__ - << ": device=AUDIO_DEVICE_OUT_BLE_HEADSET (MEDIA/VOICE) (" - << StringPrintf("%#x", device) << ")"; - session_type_ = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH; - break; - case AUDIO_DEVICE_OUT_BLE_SPEAKER: - LOG(VERBOSE) << __func__ - << ": device=AUDIO_DEVICE_OUT_BLE_SPEAKER (MEDIA) (" - << StringPrintf("%#x", device) << ")"; - session_type_ = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH; - break; - case AUDIO_DEVICE_IN_BLE_HEADSET: - LOG(VERBOSE) << __func__ - << ": device=AUDIO_DEVICE_IN_BLE_HEADSET (VOICE) (" - << StringPrintf("%#x", device) << ")"; - session_type_ = SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH; - break; - case AUDIO_DEVICE_OUT_BLE_BROADCAST: - LOG(VERBOSE) << __func__ - << ": device=AUDIO_DEVICE_OUT_BLE_BROADCAST (MEDIA) (" - << StringPrintf("%#x", device) << ")"; - session_type_ = - SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH; - break; - default: - LOG(ERROR) << __func__ - << ": unknown device=" << StringPrintf("%#x", device); - return false; - } - - if (!BluetoothAudioSessionControl::IsSessionReady(session_type_)) { - LOG(ERROR) << __func__ << ": device=" << StringPrintf("%#x", device) - << ", session_type=" << toString(session_type_) - << " is not ready"; - return false; - } - return true; -} - -void BluetoothAudioPortAidl::TearDown() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << " unknown monitor"; - return; - } - - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_); - BluetoothAudioSessionControl::UnregisterControlResultCback(session_type_, - cookie_); - cookie_ = - ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined; -} - -void BluetoothAudioPortAidl::ControlResultHandler( - const BluetoothAudioStatus& status) { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidlis not in use"; - return; - } - std::unique_lock port_lock(cv_mutex_); - BluetoothStreamState previous_state = state_; - LOG(INFO) << "control_result_cb: session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state - << ", status=" << toString(status); - - switch (previous_state) { - case BluetoothStreamState::STARTED: - /* Only Suspend signal can be send in STARTED state*/ - if (status == BluetoothAudioStatus::RECONFIGURATION || - status == BluetoothAudioStatus::SUCCESS) { - state_ = BluetoothStreamState::STANDBY; - } else { - // Set to standby since the stack may be busy switching between outputs - LOG(WARNING) << "control_result_cb: status=" << toString(status) - << " failure for session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - } - break; - case BluetoothStreamState::STARTING: - if (status == BluetoothAudioStatus::SUCCESS) { - state_ = BluetoothStreamState::STARTED; - } else { - // Set to standby since the stack may be busy switching between outputs - LOG(WARNING) << "control_result_cb: status=" << toString(status) - << " failure for session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - state_ = BluetoothStreamState::STANDBY; - } - break; - case BluetoothStreamState::SUSPENDING: - if (status == BluetoothAudioStatus::SUCCESS) { - state_ = BluetoothStreamState::STANDBY; - } else { - // It will be failed if the headset is disconnecting, and set to disable - // to wait for re-init again - LOG(WARNING) << "control_result_cb: status=" << toString(status) - << " failure for session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - state_ = BluetoothStreamState::DISABLED; - } - break; - default: - LOG(ERROR) << "control_result_cb: unexpected status=" << toString(status) - << " for session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - return; - } - port_lock.unlock(); - internal_cv_.notify_all(); -} - -void BluetoothAudioPortAidl::SessionChangedHandler() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; - return; - } - std::unique_lock port_lock(cv_mutex_); - BluetoothStreamState previous_state = state_; - LOG(INFO) << "session_changed_cb: session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - state_ = BluetoothStreamState::DISABLED; - port_lock.unlock(); - internal_cv_.notify_all(); -} - -bool BluetoothAudioPortAidl::in_use() const { - return ( - cookie_ != - ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined); -} - -bool BluetoothAudioPortAidl::GetPreferredDataIntervalUs( - size_t* interval_us) const { - if (!in_use()) { - return false; - } - - const AudioConfiguration& hal_audio_cfg = - BluetoothAudioSessionControl::GetAudioConfig(session_type_); - if (hal_audio_cfg.getTag() != AudioConfiguration::pcmConfig) { - return false; - } - - const PcmConfiguration& pcm_cfg = - hal_audio_cfg.get(); - *interval_us = pcm_cfg.dataIntervalUs; - return true; -} - -bool BluetoothAudioPortAidlOut::LoadAudioConfig( - audio_config_t* audio_cfg) const { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidlOut is not in use"; - audio_cfg->sample_rate = kBluetoothDefaultSampleRate; - audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask; - audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample; - return false; - } - - const AudioConfiguration& hal_audio_cfg = - BluetoothAudioSessionControl::GetAudioConfig(session_type_); - if (hal_audio_cfg.getTag() != AudioConfiguration::pcmConfig) { - audio_cfg->sample_rate = kBluetoothDefaultSampleRate; - audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask; - audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample; - return false; - } - const PcmConfiguration& pcm_cfg = - hal_audio_cfg.get(); - LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << ", PcmConfig=[" << pcm_cfg.toString() - << "]"; - if (pcm_cfg.channelMode == ChannelMode::UNKNOWN) { - return false; - } - audio_cfg->sample_rate = pcm_cfg.sampleRateHz; - audio_cfg->channel_mask = - (is_stereo_to_mono_ - ? AUDIO_CHANNEL_OUT_STEREO - : OutputChannelModeToAudioFormat(pcm_cfg.channelMode)); - audio_cfg->format = - BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample, session_type_); - return true; -} - -bool BluetoothAudioPortAidlIn::LoadAudioConfig( - audio_config_t* audio_cfg) const { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidlIn is not in use"; - audio_cfg->sample_rate = kBluetoothDefaultSampleRate; - audio_cfg->channel_mask = kBluetoothDefaultInputChannelModeMask; - audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample; - return false; - } - - const AudioConfiguration& hal_audio_cfg = - BluetoothAudioSessionControl::GetAudioConfig(session_type_); - if (hal_audio_cfg.getTag() != AudioConfiguration::pcmConfig) { - audio_cfg->sample_rate = kBluetoothDefaultSampleRate; - audio_cfg->channel_mask = kBluetoothDefaultInputChannelModeMask; - audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample; - return false; - } - const PcmConfiguration& pcm_cfg = - hal_audio_cfg.get(); - LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << ", PcmConfig=[" << pcm_cfg.toString() - << "]"; - if (pcm_cfg.channelMode == ChannelMode::UNKNOWN) { - return false; - } - - audio_cfg->sample_rate = pcm_cfg.sampleRateHz; - audio_cfg->channel_mask = InputChannelModeToAudioFormat(pcm_cfg.channelMode); - audio_cfg->format = - BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample, session_type_); - return true; -} - -bool BluetoothAudioPortAidl::CondwaitState(BluetoothStreamState state) { - bool retval; - std::unique_lock port_lock(cv_mutex_); - switch (state) { - case BluetoothStreamState::STARTING: - LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << " waiting for STARTED"; - retval = internal_cv_.wait_for( - port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs), - [this] { return this->state_ != BluetoothStreamState::STARTING; }); - retval = retval && state_ == BluetoothStreamState::STARTED; - break; - case BluetoothStreamState::SUSPENDING: - LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << " waiting for SUSPENDED"; - retval = internal_cv_.wait_for( - port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs), - [this] { return this->state_ != BluetoothStreamState::SUSPENDING; }); - retval = retval && state_ == BluetoothStreamState::STANDBY; - break; - default: - LOG(WARNING) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << " waiting for KNOWN"; - return false; - } - - return retval; // false if any failure like timeout -} - -bool BluetoothAudioPortAidl::Start() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; - return false; - } - - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ - << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") - << " request"; - bool retval = false; - if (state_ == BluetoothStreamState::STANDBY) { - state_ = BluetoothStreamState::STARTING; - if (BluetoothAudioSessionControl::StartStream(session_type_)) { - retval = CondwaitState(BluetoothStreamState::STARTING); - } else { - LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " Hal fails"; - } - } - - if (retval) { - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ - << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") - << " done"; - } else { - LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " failure"; - } - - return retval; // false if any failure like timeout -} - -bool BluetoothAudioPortAidl::Suspend() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; - return false; - } - - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " request"; - bool retval = false; - if (state_ == BluetoothStreamState::STARTED) { - state_ = BluetoothStreamState::SUSPENDING; - if (BluetoothAudioSessionControl::SuspendStream(session_type_)) { - retval = CondwaitState(BluetoothStreamState::SUSPENDING); - } else { - LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " Hal fails"; - } - } - - if (retval) { - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " done"; - } else { - LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " failure"; - } - - return retval; // false if any failure like timeout -} - -void BluetoothAudioPortAidl::Stop() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; - return; - } - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " request"; - state_ = BluetoothStreamState::DISABLED; - BluetoothAudioSessionControl::StopStream(session_type_); - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " done"; -} - -size_t BluetoothAudioPortAidlOut::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); - } - - // WAR to mix the stereo into Mono (16 bits per sample) - const size_t write_frames = bytes >> 2; - if (write_frames == 0) return 0; - auto src = static_cast(buffer); - std::unique_ptr 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; -} - -size_t BluetoothAudioPortAidlIn::ReadData(void* buffer, size_t bytes) const { - if (!in_use()) return 0; - return BluetoothAudioSessionControl::InReadPcmData(session_type_, buffer, - bytes); -} - -bool BluetoothAudioPortAidl::GetPresentationPosition( - uint64_t* delay_ns, uint64_t* bytes, timespec* timestamp) const { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; - return false; - } - PresentationPosition presentation_position; - bool retval = BluetoothAudioSessionControl::GetPresentationPosition( - session_type_, presentation_position); - *delay_ns = presentation_position.remoteDeviceAudioDelayNanos; - *bytes = presentation_position.transmittedOctets; - *timestamp = {.tv_sec = static_cast<__kernel_old_time_t>( - presentation_position.transmittedOctetsTimestamp.tvSec), - .tv_nsec = static_cast( - presentation_position.transmittedOctetsTimestamp.tvNSec)}; - LOG(VERBOSE) << __func__ - << ": session_type=" << StringPrintf("%#hhx", session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << ", delay=" << *delay_ns - << "ns, data=" << *bytes - << " bytes, timestamp=" << timestamp->tv_sec << "." - << StringPrintf("%09ld", timestamp->tv_nsec) << "s"; - - return retval; -} - -void BluetoothAudioPortAidl::UpdateSourceMetadata( - const source_metadata* source_metadata) const { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; - return; - } - 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::UpdateSourceMetadata(session_type_, - *source_metadata); -} - -void BluetoothAudioPortAidl::UpdateSinkMetadata( - const sink_metadata* sink_metadata) const { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; - return; - } - LOG(DEBUG) << __func__ << ": session_type=" << toString(session_type_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << ", " << sink_metadata->track_count - << " track(s)"; - if (sink_metadata->track_count == 0) return; - BluetoothAudioSessionControl::UpdateSinkMetadata(session_type_, - *sink_metadata); -} - -BluetoothStreamState BluetoothAudioPortAidl::GetState() const { return state_; } - -void BluetoothAudioPortAidl::SetState(BluetoothStreamState state) { - state_ = state; -} - -} // namespace aidl -} // namespace audio -} // namespace bluetooth -} // namespace android \ No newline at end of file diff --git a/bluetooth/audio/hw/device_port_proxy.h b/bluetooth/audio/hw/device_port_proxy.h deleted file mode 100644 index dab4970..0000000 --- a/bluetooth/audio/hw/device_port_proxy.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright 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. - * 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 -#include -#include - -#include -#include -#include - -enum class BluetoothStreamState : uint8_t; - -namespace android { -namespace bluetooth { -namespace audio { - -/*** - * Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio - * Session Control. All methods are not thread safe, so users must acquire a - * lock. Note: currently, in stream_apis.cc, if GetState() is only used for - * verbose logging, it is not locked, so the state may not be synchronized. - ***/ -class BluetoothAudioPort { - public: - BluetoothAudioPort(){}; - virtual ~BluetoothAudioPort() = default; - - /*** - * Fetch output control / data path of BluetoothAudioPort and setup - * callbacks into BluetoothAudioProvider. If SetUp() returns false, the audio - * HAL must delete this BluetoothAudioPort and return EINVAL to caller - ***/ - virtual bool SetUp(audio_devices_t) { return false; } - - /*** - * Unregister this BluetoothAudioPort from BluetoothAudioSessionControl. - * Audio HAL must delete this BluetoothAudioPort after calling this. - ***/ - virtual void TearDown() {} - - /*** - * When the Audio framework / HAL tries to query audio config about format, - * channel mask and sample rate, it uses this function to fetch from the - * Bluetooth stack - ***/ - virtual bool LoadAudioConfig(audio_config_t*) const { return false; }; - - /*** - * WAR to support Mono mode / 16 bits per sample - ***/ - virtual void ForcePcmStereoToMono(bool) {} - - /*** - * When the Audio framework / HAL wants to change the stream state, it invokes - * these 3 functions to control the Bluetooth stack (Audio Control Path). - * Note: Both Start() and Suspend() will return true when there are no errors. - * Called by Audio framework / HAL to start the stream - ***/ - virtual bool Start() { return false; } - - /*** - * Called by Audio framework / HAL to suspend the stream - ***/ - virtual bool Suspend() { return false; }; - - /*** - virtual bool Suspend() { return false; } - * Called by Audio framework / HAL to stop the stream - ***/ - virtual void Stop() {} - - /*** - * Called by the Audio framework / HAL to fetch information about audio frames - * presented to an external sink, or frames presented fror an internal sink - ***/ - virtual bool GetPresentationPosition(uint64_t*, uint64_t*, timespec*) const { - return false; - } - - /*** - * Called by the Audio framework / HAL when the metadata of the stream's - * source has been changed. - ***/ - virtual void UpdateSourceMetadata(const source_metadata*) const {}; - - /*** - * Return the current BluetoothStreamState - ***/ - virtual BluetoothStreamState GetState() const { - return static_cast(0); - } - - /*** - * Set the current BluetoothStreamState - ***/ - virtual void SetState(BluetoothStreamState state) {} - - virtual bool IsA2dp() const { return false; } - - virtual bool GetPreferredDataIntervalUs(size_t* interval_us) const { - return false; - }; - - virtual size_t WriteData(const void* buffer, size_t bytes) const { - return 0; - }; - virtual size_t ReadData(void* buffer, size_t bytes) const { return 0; }; -}; - -namespace aidl { - -using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus; -using ::aidl::android::hardware::bluetooth::audio::SessionType; - -class BluetoothAudioPortAidl : public BluetoothAudioPort { - public: - BluetoothAudioPortAidl(); - virtual ~BluetoothAudioPortAidl() = default; - - bool SetUp(audio_devices_t devices) override; - - void TearDown() override; - - void ForcePcmStereoToMono(bool force) override { is_stereo_to_mono_ = force; } - - bool Start() override; - bool Suspend() override; - void Stop() override; - - bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* byte, - timespec* timestamp) const override; - - void UpdateSourceMetadata( - const source_metadata* source_metadata) const override; - - /*** - * Called by the Audio framework / HAL when the metadata of the stream's - * sink has been changed. - ***/ - virtual void UpdateSinkMetadata(const sink_metadata* sink_metadata) const; - - BluetoothStreamState GetState() const override; - - void SetState(BluetoothStreamState state) override; - - bool IsA2dp() const override { - return session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type_ == - SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH; - } - - bool GetPreferredDataIntervalUs(size_t* interval_us) const override; - - protected: - uint16_t cookie_; - BluetoothStreamState state_; - SessionType session_type_; - // WR to support Mono: True if fetching Stereo and mixing into Mono - bool is_stereo_to_mono_ = false; - virtual bool in_use() const; - - private: - mutable std::mutex cv_mutex_; - std::condition_variable internal_cv_; - - // Check and initialize session type for |devices| If failed, this - // BluetoothAudioPortAidl is not initialized and must be deleted. - bool init_session_type(audio_devices_t device); - - bool CondwaitState(BluetoothStreamState state); - - void ControlResultHandler(const BluetoothAudioStatus& status); - void SessionChangedHandler(); -}; - -class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl { - public: - ~BluetoothAudioPortAidlOut(); - - // The audio data path to the Bluetooth stack (Software encoding) - size_t WriteData(const void* buffer, size_t bytes) const override; - bool LoadAudioConfig(audio_config_t* audio_cfg) const override; -}; - -class BluetoothAudioPortAidlIn : public BluetoothAudioPortAidl { - public: - ~BluetoothAudioPortAidlIn(); - - // The audio data path from the Bluetooth stack (Software decoded) - size_t ReadData(void* buffer, size_t bytes) const override; - bool LoadAudioConfig(audio_config_t* audio_cfg) const override; -}; - -} // namespace aidl -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/hw/device_port_proxy_hidl.cc b/bluetooth/audio/hw/device_port_proxy_hidl.cc deleted file mode 100644 index 0f8aa3d..0000000 --- a/bluetooth/audio/hw/device_port_proxy_hidl.cc +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Copyright 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. - * 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. - */ - -#define LOG_TAG "BTAudioHalDeviceProxyHIDL" - -#include "device_port_proxy_hidl.h" - -#include -#include -#include -#include -#include -#include - -#include "BluetoothAudioSessionControl_2_1.h" -#include "stream_apis.h" -#include "utils.h" - -namespace android { -namespace bluetooth { -namespace audio { -namespace hidl { - -using ::android::base::StringPrintf; -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; -using SampleRate = ::android::hardware::bluetooth::audio::V2_0::SampleRate; -using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate; -using BluetoothAudioStatusHidl = - ::android::hardware::bluetooth::audio::V2_0::Status; -using ControlResultCallback = std::function; -using SessionChangedCallback = std::function; - -namespace { - -unsigned int SampleRateToAudioFormat(SampleRate_2_1 sample_rate) { - switch (sample_rate) { - case SampleRate_2_1::RATE_8000: - return 8000; - case SampleRate_2_1::RATE_16000: - return 16000; - case SampleRate_2_1::RATE_24000: - return 24000; - case SampleRate_2_1::RATE_32000: - return 32000; - case SampleRate_2_1::RATE_44100: - return 44100; - case SampleRate_2_1::RATE_48000: - return 48000; - case SampleRate_2_1::RATE_88200: - return 88200; - case SampleRate_2_1::RATE_96000: - return 96000; - case SampleRate_2_1::RATE_176400: - return 176400; - case SampleRate_2_1::RATE_192000: - return 192000; - default: - return kBluetoothDefaultSampleRate; - } -} -audio_channel_mask_t OutputChannelModeToAudioFormat(ChannelMode channel_mode) { - switch (channel_mode) { - case ChannelMode::MONO: - return AUDIO_CHANNEL_OUT_MONO; - case ChannelMode::STEREO: - return AUDIO_CHANNEL_OUT_STEREO; - default: - return kBluetoothDefaultOutputChannelModeMask; - } -} - -audio_channel_mask_t InputChannelModeToAudioFormat(ChannelMode channel_mode) { - switch (channel_mode) { - case ChannelMode::MONO: - return AUDIO_CHANNEL_IN_MONO; - case ChannelMode::STEREO: - return AUDIO_CHANNEL_IN_STEREO; - default: - return kBluetoothDefaultInputChannelModeMask; - } -} - -audio_format_t BitsPerSampleToAudioFormat(BitsPerSample bits_per_sample) { - switch (bits_per_sample) { - case BitsPerSample::BITS_16: - return AUDIO_FORMAT_PCM_16_BIT; - case BitsPerSample::BITS_24: - return AUDIO_FORMAT_PCM_24_BIT_PACKED; - case BitsPerSample::BITS_32: - return AUDIO_FORMAT_PCM_32_BIT; - default: - return kBluetoothDefaultAudioFormatBitsPerSample; - } -} - -// The maximum time to wait in std::condition_variable::wait_for() -constexpr unsigned int kMaxWaitingTimeMs = 4500; - -} // namespace - -BluetoothAudioPortHidl::BluetoothAudioPortHidl() - : session_type_hidl_(SessionType_2_1::UNKNOWN), - cookie_(android::bluetooth::audio::kObserversCookieUndefined), - state_(BluetoothStreamState::DISABLED) {} - -BluetoothAudioPortHidlOut::~BluetoothAudioPortHidlOut() { - if (BluetoothAudioPortHidl::in_use()) BluetoothAudioPortHidl::TearDown(); -} - -BluetoothAudioPortHidlIn::~BluetoothAudioPortHidlIn() { - if (BluetoothAudioPortHidl::in_use()) BluetoothAudioPortHidl::TearDown(); -} - -bool BluetoothAudioPortHidl::SetUp(audio_devices_t devices) { - if (!init_session_type(devices)) return false; - - state_ = BluetoothStreamState::STANDBY; - - auto control_result_cb = [port = this]( - uint16_t cookie, bool start_resp, - const BluetoothAudioStatusHidl& status) { - if (!port->in_use()) { - LOG(ERROR) << "control_result_cb: BluetoothAudioPort is not in use"; - return; - } - if (port->cookie_ != cookie) { - LOG(ERROR) << "control_result_cb: proxy of device port (cookie=" - << StringPrintf("%#hx", cookie) << ") is corrupted"; - return; - } - port->ControlResultHandler(status); - }; - auto session_changed_cb = [port = this](uint16_t cookie) { - if (!port->in_use()) { - LOG(ERROR) << "session_changed_cb: BluetoothAudioPort is not in use"; - return; - } - if (port->cookie_ != cookie) { - LOG(ERROR) << "session_changed_cb: proxy of device port (cookie=" - << StringPrintf("%#hx", cookie) << ") is corrupted"; - return; - } - port->SessionChangedHandler(); - }; - ::android::bluetooth::audio::PortStatusCallbacks cbacks = { - .control_result_cb_ = control_result_cb, - .session_changed_cb_ = session_changed_cb}; - cookie_ = BluetoothAudioSessionControl_2_1::RegisterControlResultCback( - session_type_hidl_, cbacks); - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_); - - return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined); -} - -bool BluetoothAudioPortHidl::init_session_type(audio_devices_t device) { - switch (device) { - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: - case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: - LOG(VERBOSE) - << __func__ - << ": device=AUDIO_DEVICE_OUT_BLUETOOTH_A2DP (HEADPHONES/SPEAKER) (" - << StringPrintf("%#x", device) << ")"; - session_type_hidl_ = 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_hidl_ = - SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH; - break; - case AUDIO_DEVICE_OUT_BLE_HEADSET: - LOG(VERBOSE) << __func__ - << ": device=AUDIO_DEVICE_OUT_BLE_HEADSET (MEDIA/VOICE) (" - << StringPrintf("%#x", device) << ")"; - session_type_hidl_ = SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH; - break; - case AUDIO_DEVICE_OUT_BLE_SPEAKER: - LOG(VERBOSE) << __func__ - << ": device=AUDIO_DEVICE_OUT_BLE_SPEAKER (MEDIA) (" - << StringPrintf("%#x", device) << ")"; - session_type_hidl_ = SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH; - break; - case AUDIO_DEVICE_IN_BLE_HEADSET: - LOG(VERBOSE) << __func__ - << ": device=AUDIO_DEVICE_IN_BLE_HEADSET (VOICE) (" - << StringPrintf("%#x", device) << ")"; - session_type_hidl_ = SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH; - break; - default: - LOG(ERROR) << __func__ - << ": unknown device=" << StringPrintf("%#x", device); - return false; - } - - if (!BluetoothAudioSessionControl_2_1::IsSessionReady(session_type_hidl_)) { - LOG(ERROR) << __func__ << ": device=" << StringPrintf("%#x", device) - << ", session_type=" << toString(session_type_hidl_) - << " is not ready"; - return false; - } - return true; -} - -void BluetoothAudioPortHidl::TearDown() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << " unknown monitor"; - return; - } - - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_); - BluetoothAudioSessionControl_2_1::UnregisterControlResultCback( - session_type_hidl_, cookie_); - cookie_ = android::bluetooth::audio::kObserversCookieUndefined; -} - -void BluetoothAudioPortHidl::ControlResultHandler( - const BluetoothAudioStatusHidl& status) { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortis not in use"; - return; - } - std::unique_lock port_lock(cv_mutex_); - BluetoothStreamState previous_state = state_; - LOG(INFO) << "control_result_cb: session_type=" - << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state - << ", status=" << toString(status); - - switch (previous_state) { - case BluetoothStreamState::STARTED: - /* Only Suspend signal can be send in STARTED state*/ - if (status == BluetoothAudioStatus::SUCCESS) { - state_ = BluetoothStreamState::STANDBY; - } else { - // Set to standby since the stack may be busy switching between outputs - LOG(WARNING) << "control_result_cb: status=" << toString(status) - << " failure for session_type=" - << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - } - break; - case BluetoothStreamState::STARTING: - if (status == BluetoothAudioStatusHidl::SUCCESS) { - state_ = BluetoothStreamState::STARTED; - } else { - // Set to standby since the stack may be busy switching between outputs - LOG(WARNING) << "control_result_cb: status=" << toString(status) - << " failure for session_type=" - << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - state_ = BluetoothStreamState::STANDBY; - } - break; - case BluetoothStreamState::SUSPENDING: - if (status == BluetoothAudioStatusHidl::SUCCESS) { - state_ = BluetoothStreamState::STANDBY; - } else { - // It will be failed if the headset is disconnecting, and set to disable - // to wait for re-init again - LOG(WARNING) << "control_result_cb: status=" << toString(status) - << " failure for session_type=" - << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - state_ = BluetoothStreamState::DISABLED; - } - break; - default: - LOG(ERROR) << "control_result_cb: unexpected status=" << toString(status) - << " for session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - return; - } - port_lock.unlock(); - internal_cv_.notify_all(); -} - -void BluetoothAudioPortHidl::SessionChangedHandler() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use"; - return; - } - std::unique_lock port_lock(cv_mutex_); - BluetoothStreamState previous_state = state_; - LOG(INFO) << "session_changed_cb: session_type=" - << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", previous_state=" << previous_state; - state_ = BluetoothStreamState::DISABLED; - port_lock.unlock(); - internal_cv_.notify_all(); -} - -bool BluetoothAudioPortHidl::in_use() const { - return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined); -} - -bool BluetoothAudioPortHidl::GetPreferredDataIntervalUs( - size_t* interval_us) const { - if (!in_use()) { - return false; - } - - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration& - hal_audio_cfg = - BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_hidl_); - if (hal_audio_cfg.getDiscriminator() != - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: - hidl_discriminator::pcmConfig) { - return false; - } - - const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg = - hal_audio_cfg.pcmConfig(); - *interval_us = pcm_cfg.dataIntervalUs; - return true; -} - -bool BluetoothAudioPortHidl::CondwaitState(BluetoothStreamState state) { - bool retval; - std::unique_lock port_lock(cv_mutex_); - switch (state) { - case BluetoothStreamState::STARTING: - LOG(VERBOSE) << __func__ - << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << " waiting for STARTED"; - retval = internal_cv_.wait_for( - port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs), - [this] { return this->state_ != BluetoothStreamState::STARTING; }); - retval = retval && state_ == BluetoothStreamState::STARTED; - break; - case BluetoothStreamState::SUSPENDING: - LOG(VERBOSE) << __func__ - << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << " waiting for SUSPENDED"; - retval = internal_cv_.wait_for( - port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs), - [this] { return this->state_ != BluetoothStreamState::SUSPENDING; }); - retval = retval && state_ == BluetoothStreamState::STANDBY; - break; - default: - LOG(WARNING) << __func__ - << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << " waiting for KNOWN"; - return false; - } - - return retval; // false if any failure like timeout -} - -bool BluetoothAudioPortHidl::Start() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use"; - return false; - } - - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ - << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") - << " request"; - bool retval = false; - if (state_ == BluetoothStreamState::STANDBY) { - state_ = BluetoothStreamState::STARTING; - if (BluetoothAudioSessionControl_2_1::StartStream(session_type_hidl_)) { - retval = CondwaitState(BluetoothStreamState::STARTING); - } else { - LOG(ERROR) << __func__ - << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " Hal fails"; - } - } - - if (retval) { - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ - << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") - << " done"; - } else { - LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " failure"; - } - - return retval; // false if any failure like timeout -} - -bool BluetoothAudioPortHidl::Suspend() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use"; - return false; - } - - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " request"; - bool retval = false; - if (state_ == BluetoothStreamState::STARTED) { - state_ = BluetoothStreamState::SUSPENDING; - if (BluetoothAudioSessionControl_2_1::SuspendStream(session_type_hidl_)) { - retval = CondwaitState(BluetoothStreamState::SUSPENDING); - } else { - LOG(ERROR) << __func__ - << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " Hal fails"; - } - } - - if (retval) { - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " done"; - } else { - LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " failure"; - } - - return retval; // false if any failure like timeout -} - -void BluetoothAudioPortHidl::Stop() { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use"; - return; - } - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " request"; - state_ = BluetoothStreamState::DISABLED; - BluetoothAudioSessionControl_2_1::StopStream(session_type_hidl_); - LOG(INFO) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << " done"; -} - -bool BluetoothAudioPortHidl::GetPresentationPosition( - uint64_t* delay_ns, uint64_t* bytes, timespec* timestamp) const { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use"; - return false; - } - bool retval = BluetoothAudioSessionControl_2_1::GetPresentationPosition( - session_type_hidl_, delay_ns, bytes, timestamp); - LOG(VERBOSE) << __func__ - << ": session_type=" << StringPrintf("%#hhx", session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << ", delay=" << *delay_ns - << "ns, data=" << *bytes - << " bytes, timestamp=" << timestamp->tv_sec << "." - << StringPrintf("%09ld", timestamp->tv_nsec) << "s"; - - return retval; -} - -void BluetoothAudioPortHidl::UpdateSourceMetadata( - const source_metadata* source_metadata) const { - if (!in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use"; - return; - } - LOG(DEBUG) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" << StringPrintf("%#hx", cookie_) - << ", state=" << state_ << ", " << source_metadata->track_count - << " track(s)"; - if (source_metadata->track_count == 0) return; - BluetoothAudioSessionControl_2_1::UpdateTracksMetadata(session_type_hidl_, - source_metadata); -} - -BluetoothStreamState BluetoothAudioPortHidl::GetState() const { return state_; } - -void BluetoothAudioPortHidl::SetState(BluetoothStreamState state) { - state_ = state; -} - -size_t BluetoothAudioPortHidlOut::WriteData(const void* buffer, - size_t bytes) const { - if (!BluetoothAudioPortHidl::in_use()) return 0; - if (!BluetoothAudioPortHidl::is_stereo_to_mono_) { - return BluetoothAudioSessionControl_2_1::OutWritePcmData(session_type_hidl_, - buffer, bytes); - } - - // WAR to mix the stereo into Mono (16 bits per sample) - const size_t write_frames = bytes >> 2; - if (write_frames == 0) return 0; - auto src = static_cast(buffer); - std::unique_ptr 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_2_1::OutWritePcmData( - session_type_hidl_, dst.get(), write_frames * 2) * - 2; -} - -size_t BluetoothAudioPortHidlIn::ReadData(void* buffer, size_t bytes) const { - if (!BluetoothAudioPortHidl::in_use()) return 0; - return BluetoothAudioSessionControl_2_1::InReadPcmData(session_type_hidl_, - buffer, bytes); -} - -bool BluetoothAudioPortHidlIn::LoadAudioConfig( - audio_config_t* audio_cfg) const { - if (!BluetoothAudioPortHidl::in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortIn is not in use"; - audio_cfg->sample_rate = kBluetoothDefaultSampleRate; - audio_cfg->channel_mask = kBluetoothDefaultInputChannelModeMask; - audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample; - return false; - } - - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration& - hal_audio_cfg = - BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_hidl_); - if (hal_audio_cfg.getDiscriminator() != - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: - hidl_discriminator::pcmConfig) { - audio_cfg->sample_rate = kBluetoothDefaultSampleRate; - audio_cfg->channel_mask = kBluetoothDefaultInputChannelModeMask; - audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample; - return false; - } - const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg = - hal_audio_cfg.pcmConfig(); - LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" - << StringPrintf("%#hx", BluetoothAudioPortHidl::cookie_) - << ", state=" << BluetoothAudioPortHidl::state_ - << ", PcmConfig=[" << toString(pcm_cfg) << "]"; - if (pcm_cfg.sampleRate == SampleRate_2_1::RATE_UNKNOWN || - pcm_cfg.channelMode == ChannelMode::UNKNOWN || - pcm_cfg.bitsPerSample == BitsPerSample::BITS_UNKNOWN) { - return false; - } - - audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate); - audio_cfg->channel_mask = InputChannelModeToAudioFormat(pcm_cfg.channelMode); - audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample); - return true; -} - -bool BluetoothAudioPortHidlOut::LoadAudioConfig( - audio_config_t* audio_cfg) const { - if (!BluetoothAudioPortHidl::in_use()) { - LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use"; - audio_cfg->sample_rate = kBluetoothDefaultSampleRate; - audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask; - audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample; - return false; - } - - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration& - hal_audio_cfg = - BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_hidl_); - if (hal_audio_cfg.getDiscriminator() != - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: - hidl_discriminator::pcmConfig) { - audio_cfg->sample_rate = kBluetoothDefaultSampleRate; - audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask; - audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample; - return false; - } - const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg = - hal_audio_cfg.pcmConfig(); - LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_hidl_) - << ", cookie=" - << StringPrintf("%#hx", BluetoothAudioPortHidl::cookie_) - << ", state=" << BluetoothAudioPortHidl::state_ - << ", PcmConfig=[" << toString(pcm_cfg) << "]"; - if (pcm_cfg.sampleRate == SampleRate_2_1::RATE_UNKNOWN || - pcm_cfg.channelMode == ChannelMode::UNKNOWN || - pcm_cfg.bitsPerSample == BitsPerSample::BITS_UNKNOWN) { - return false; - } - audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate); - audio_cfg->channel_mask = - (BluetoothAudioPortHidl::is_stereo_to_mono_ - ? AUDIO_CHANNEL_OUT_STEREO - : OutputChannelModeToAudioFormat(pcm_cfg.channelMode)); - audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample); - return true; -} - -} // namespace hidl -} // namespace audio -} // namespace bluetooth -} // namespace android \ No newline at end of file diff --git a/bluetooth/audio/hw/device_port_proxy_hidl.h b/bluetooth/audio/hw/device_port_proxy_hidl.h deleted file mode 100644 index f37370d..0000000 --- a/bluetooth/audio/hw/device_port_proxy_hidl.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 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. - * 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 -#include - -#include -#include -#include - -#include "device_port_proxy.h" - -enum class BluetoothStreamState : uint8_t; - -namespace android { -namespace bluetooth { -namespace audio { -namespace hidl { - -using SessionType_2_1 = - ::android::hardware::bluetooth::audio::V2_1::SessionType; - -class BluetoothAudioPortHidl : public BluetoothAudioPort { - public: - BluetoothAudioPortHidl(); - virtual ~BluetoothAudioPortHidl() = default; - - bool SetUp(audio_devices_t devices) override; - - void TearDown() override; - - void ForcePcmStereoToMono(bool force) override { is_stereo_to_mono_ = force; } - - bool Start() override; - - bool Suspend() override; - - void Stop() override; - - bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes, - timespec* timestamp) const override; - - void UpdateSourceMetadata( - const source_metadata* source_metadata) const override; - - BluetoothStreamState GetState() const override; - - void SetState(BluetoothStreamState state) override; - - bool IsA2dp() const override { - return session_type_hidl_ == - SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type_hidl_ == - SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH; - } - - bool GetPreferredDataIntervalUs(size_t* interval_us) const override; - - protected: - SessionType_2_1 session_type_hidl_; - uint16_t cookie_; - BluetoothStreamState state_; - // WR to support Mono: True if fetching Stereo and mixing into Mono - bool is_stereo_to_mono_ = false; - - bool in_use() const; - - private: - mutable std::mutex cv_mutex_; - std::condition_variable internal_cv_; - - bool init_session_type(audio_devices_t device); - - bool CondwaitState(BluetoothStreamState state); - - void ControlResultHandler( - const ::android::hardware::bluetooth::audio::V2_0::Status& status); - - void SessionChangedHandler(); -}; - -class BluetoothAudioPortHidlOut : public BluetoothAudioPortHidl { - public: - ~BluetoothAudioPortHidlOut(); - - size_t WriteData(const void* buffer, size_t bytes) const override; - bool LoadAudioConfig(audio_config_t* audio_cfg) const override; -}; - -class BluetoothAudioPortHidlIn : public BluetoothAudioPortHidl { - public: - ~BluetoothAudioPortHidlIn(); - - size_t ReadData(void* buffer, size_t bytes) const override; - bool LoadAudioConfig(audio_config_t* audio_cfg) const override; -}; - -} // namespace hidl -} // namespace audio -} // namespace bluetooth -} // namespace android \ No newline at end of file diff --git a/bluetooth/audio/hw/stream_apis.cc b/bluetooth/audio/hw/stream_apis.cc deleted file mode 100644 index 1f449fc..0000000 --- a/bluetooth/audio/hw/stream_apis.cc +++ /dev/null @@ -1,1308 +0,0 @@ -/* - * Copyright 2019 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. - */ - -#include "device_port_proxy.h" -#define LOG_TAG "BTAudioHalStream" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "BluetoothAudioSession.h" -#include "stream_apis.h" -#include "utils.h" - -using ::android::base::StringPrintf; -using ::android::bluetooth::audio::utils::GetAudioParamString; -using ::android::bluetooth::audio::utils::ParseAudioParams; - -namespace { - -constexpr unsigned int kMinimumDelayMs = 50; -constexpr unsigned int kMaximumDelayMs = 1000; -constexpr int kExtraAudioSyncMs = 200; - -std::ostream& operator<<(std::ostream& os, const audio_config& config) { - return os << "audio_config[sample_rate=" << config.sample_rate - << ", channels=" << StringPrintf("%#x", config.channel_mask) - << ", format=" << config.format << "]"; -} - -void out_calculate_feeding_delay_ms(const BluetoothStreamOut* out, - uint32_t* latency_ms, - uint64_t* frames = nullptr, - struct timespec* timestamp = nullptr) { - if (latency_ms == nullptr && frames == nullptr && timestamp == nullptr) { - return; - } - - // delay_report is the audio delay from the remote headset receiving data to - // the headset playing sound in units of nanoseconds - uint64_t delay_report_ns = 0; - uint64_t delay_report_ms = 0; - // absorbed_bytes is the total number of bytes sent by the Bluetooth stack to - // a remote headset - uint64_t absorbed_bytes = 0; - // absorbed_timestamp is the ... - struct timespec absorbed_timestamp = {}; - bool timestamp_fetched = false; - - std::unique_lock lock(out->mutex_); - if (out->bluetooth_output_->GetPresentationPosition( - &delay_report_ns, &absorbed_bytes, &absorbed_timestamp)) { - delay_report_ms = delay_report_ns / 1000000; - // assume kMinimumDelayMs (50ms) < delay_report_ns < kMaximumDelayMs - // (1000ms), or it is invalid / ignored and use old delay calculated - // by ourselves. - if (delay_report_ms > kMinimumDelayMs && - delay_report_ms < kMaximumDelayMs) { - timestamp_fetched = true; - } else if (delay_report_ms >= kMaximumDelayMs) { - LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", delay_report=" << delay_report_ns << "ns abnormal"; - } - } - if (!timestamp_fetched) { - // default to old delay if any failure is found when fetching from ports - // audio_a2dp_hw: - // frames_count = buffer_size / frame_size - // latency (sec.) = frames_count / samples_per_second (sample_rate) - // Sync from audio_a2dp_hw to add extra delay kExtraAudioSyncMs(+200ms) - delay_report_ms = - out->frames_count_ * 1000 / out->sample_rate_ + kExtraAudioSyncMs; - if (timestamp != nullptr) { - clock_gettime(CLOCK_MONOTONIC, &absorbed_timestamp); - } - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " uses the legacy delay " << delay_report_ms << " ms"; - } - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", delay=" << delay_report_ms << "ms, data=" << absorbed_bytes - << " bytes, timestamp=" << absorbed_timestamp.tv_sec << "." - << StringPrintf("%09ld", absorbed_timestamp.tv_nsec) << "s"; - - if (latency_ms != nullptr) { - *latency_ms = delay_report_ms; - } - if (frames != nullptr) { - const uint64_t latency_frames = delay_report_ms * out->sample_rate_ / 1000; - *frames = absorbed_bytes / audio_stream_out_frame_size(&out->stream_out_); - if (out->frames_presented_ < *frames) { - // Are we (the audio HAL) reset?! The stack counter is obsoleted. - *frames = out->frames_presented_; - } else if ((out->frames_presented_ - *frames) > latency_frames) { - // Is the Bluetooth output reset / restarted by AVDTP reconfig?! Its - // counter was reset but could not be used. - *frames = out->frames_presented_; - } - // suppose frames would be queued in the headset buffer for delay_report - // period, so those frames in buffers should not be included in the number - // of presented frames at the timestamp. - if (*frames > latency_frames) { - *frames -= latency_frames; - } else { - *frames = 0; - } - } - if (timestamp != nullptr) { - *timestamp = absorbed_timestamp; - } -} - -void in_calculate_starving_delay_ms(const BluetoothStreamIn* in, - int64_t* frames, int64_t* time) { - // delay_report is the audio delay from the remote headset receiving data to - // the headset playing sound in units of nanoseconds - uint64_t delay_report_ns = 0; - uint64_t delay_report_ms = 0; - // dispersed_bytes is the total number of bytes received by the Bluetooth - // stack from a remote headset - uint64_t dispersed_bytes = 0; - struct timespec dispersed_timestamp = {}; - - std::unique_lock lock(in->mutex_); - in->bluetooth_input_->GetPresentationPosition( - &delay_report_ns, &dispersed_bytes, &dispersed_timestamp); - delay_report_ms = delay_report_ns / 1000000; - - const uint64_t latency_frames = delay_report_ms * in->sample_rate_ / 1000; - *frames = dispersed_bytes / audio_stream_in_frame_size(&in->stream_in_); - - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", delay=" << delay_report_ms - << "ms, data=" << dispersed_bytes - << " bytes, timestamp=" << dispersed_timestamp.tv_sec << "." - << StringPrintf("%09ld", dispersed_timestamp.tv_nsec) << "s"; - - if (in->frames_presented_ < *frames) { - // Was audio HAL reset?! The stack counter is obsoleted. - *frames = in->frames_presented_; - } else if ((in->frames_presented_ - *frames) > latency_frames) { - // Is the Bluetooth input reset ?! Its counter was reset but could not be - // used. - *frames = in->frames_presented_; - } - // suppose frames would be queued in the headset buffer for delay_report - // period, so those frames in buffers should not be included in the number - // of presented frames at the timestamp. - if (*frames > latency_frames) { - *frames -= latency_frames; - } else { - *frames = 0; - } - - *time = (dispersed_timestamp.tv_sec * 1000000000LL + - dispersed_timestamp.tv_nsec) / - 1000; -} - -} // namespace - -std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state) { - switch (state) { - case BluetoothStreamState::DISABLED: - return os << "DISABLED"; - case BluetoothStreamState::STANDBY: - return os << "STANDBY"; - case BluetoothStreamState::STARTING: - return os << "STARTING"; - case BluetoothStreamState::STARTED: - return os << "STARTED"; - case BluetoothStreamState::SUSPENDING: - return os << "SUSPENDING"; - case BluetoothStreamState::UNKNOWN: - return os << "UNKNOWN"; - default: - return os << StringPrintf("%#hhx", state); - } -} - -static uint32_t out_get_sample_rate(const struct audio_stream* stream) { - const auto* out = reinterpret_cast(stream); - audio_config_t audio_cfg; - if (out->bluetooth_output_->LoadAudioConfig(&audio_cfg)) { - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " audio_cfg=" << audio_cfg; - return audio_cfg.sample_rate; - } else { - LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", sample_rate=" << out->sample_rate_ << " failed"; - return out->sample_rate_; - } -} - -static int out_set_sample_rate(struct audio_stream* stream, uint32_t rate) { - auto* out = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", sample_rate=" << out->sample_rate_; - return (rate == out->sample_rate_ ? 0 : -1); -} - -static size_t out_get_buffer_size(const struct audio_stream* stream) { - const auto* out = reinterpret_cast(stream); - size_t buffer_size = - out->frames_count_ * audio_stream_out_frame_size(&out->stream_out_); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", buffer_size=" << buffer_size; - return buffer_size; -} - -static audio_channel_mask_t out_get_channels( - const struct audio_stream* stream) { - const auto* out = reinterpret_cast(stream); - audio_config_t audio_cfg; - if (out->bluetooth_output_->LoadAudioConfig(&audio_cfg)) { - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " audio_cfg=" << audio_cfg; - return audio_cfg.channel_mask; - } else { - LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", channels=" << StringPrintf("%#x", out->channel_mask_) - << " failure"; - return out->channel_mask_; - } -} - -static audio_format_t out_get_format(const struct audio_stream* stream) { - const auto* out = reinterpret_cast(stream); - audio_config_t audio_cfg; - if (out->bluetooth_output_->LoadAudioConfig(&audio_cfg)) { - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " audio_cfg=" << audio_cfg; - return audio_cfg.format; - } else { - LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", format=" << out->format_ << " failure"; - return out->format_; - } -} - -static int out_set_format(struct audio_stream* stream, audio_format_t format) { - auto* out = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", format=" << out->format_; - return (format == out->format_ ? 0 : -1); -} - -static int out_standby(struct audio_stream* stream) { - auto* out = reinterpret_cast(stream); - std::unique_lock lock(out->mutex_); - int retval = 0; - - // out->last_write_time_us_ = 0; unnecessary as a stale write time has same - // effect - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " being standby (suspend)"; - if (out->bluetooth_output_->GetState() == BluetoothStreamState::STARTED) { - out->frames_rendered_ = 0; - retval = (out->bluetooth_output_->Suspend() ? 0 : -EIO); - } else if (out->bluetooth_output_->GetState() == - BluetoothStreamState::STARTING || - out->bluetooth_output_->GetState() == - BluetoothStreamState::SUSPENDING) { - LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " NOT ready to be standby"; - retval = -EBUSY; - } else { - LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " standby already"; - } - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " standby (suspend) retval=" << retval; - - return retval; -} - -static int out_dump(const struct audio_stream* stream, int fd) { - const auto* out = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState(); - return 0; -} - -static int out_set_parameters(struct audio_stream* stream, - const char* kvpairs) { - auto* out = reinterpret_cast(stream); - std::unique_lock lock(out->mutex_); - int retval = 0; - - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", kvpairs=[" << kvpairs << "]"; - - std::unordered_map params = - ParseAudioParams(kvpairs); - if (params.empty()) return retval; - - LOG(VERBOSE) << __func__ << ": ParamsMap=[" << GetAudioParamString(params) - << "]"; - - audio_config_t audio_cfg; - if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end() || - params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end() || - params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) { - if (out->bluetooth_output_->LoadAudioConfig(&audio_cfg)) { - out->sample_rate_ = audio_cfg.sample_rate; - out->channel_mask_ = audio_cfg.channel_mask; - out->format_ = audio_cfg.format; - LOG(VERBOSE) << "state=" << out->bluetooth_output_->GetState() - << ", sample_rate=" << out->sample_rate_ - << ", channels=" << StringPrintf("%#x", out->channel_mask_) - << ", format=" << out->format_; - } else { - LOG(WARNING) << __func__ - << ": state=" << out->bluetooth_output_->GetState() - << " failed to get audio config"; - } - } - - if (params.find("routing") != params.end()) { - auto routing_param = params.find("routing"); - LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", stream param '" << routing_param->first.c_str() << "=" - << routing_param->second.c_str() << "'"; - } - - if (params.find("A2dpSuspended") != params.end() && - out->bluetooth_output_->IsA2dp()) { - if (params["A2dpSuspended"] == "true") { - LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " stream param stopped"; - out->frames_rendered_ = 0; - if (out->bluetooth_output_->GetState() == BluetoothStreamState::STARTED) { - out->bluetooth_output_->Suspend(); - out->bluetooth_output_->SetState(BluetoothStreamState::DISABLED); - } else if (out->bluetooth_output_->GetState() != - BluetoothStreamState::DISABLED) { - out->bluetooth_output_->Stop(); - } - } else { - LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " stream param standby"; - if (out->bluetooth_output_->GetState() == - BluetoothStreamState::DISABLED) { - out->bluetooth_output_->SetState(BluetoothStreamState::STANDBY); - } - } - } - - if (params.find("closing") != params.end()) { - if (params["closing"] == "true") { - LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " stream param closing, disallow any writes?"; - if (out->bluetooth_output_->GetState() != - BluetoothStreamState::DISABLED) { - out->frames_rendered_ = 0; - out->frames_presented_ = 0; - out->bluetooth_output_->Stop(); - } - } - } - - if (params.find("exiting") != params.end()) { - if (params["exiting"] == "1") { - LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " stream param exiting"; - if (out->bluetooth_output_->GetState() != - BluetoothStreamState::DISABLED) { - out->frames_rendered_ = 0; - out->frames_presented_ = 0; - out->bluetooth_output_->Stop(); - } - } - } - - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", kvpairs=[" << kvpairs << "], retval=" << retval; - return retval; -} - -static char* out_get_parameters(const struct audio_stream* stream, - const char* keys) { - const auto* out = reinterpret_cast(stream); - std::unique_lock lock(out->mutex_); - - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", keys=[" << keys << "]"; - - std::unordered_map params = ParseAudioParams(keys); - if (params.empty()) return strdup(""); - - audio_config_t audio_cfg; - if (out->bluetooth_output_->LoadAudioConfig(&audio_cfg)) { - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " audio_cfg=" << audio_cfg; - } else { - LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " failed to get audio config"; - } - - std::unordered_map return_params; - if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end()) { - std::string param; - if (audio_cfg.sample_rate == 16000) { - param = "16000"; - } - if (audio_cfg.sample_rate == 24000) { - param = "24000"; - } - if (audio_cfg.sample_rate == 44100) { - param = "44100"; - } - if (audio_cfg.sample_rate == 48000) { - param = "48000"; - } - if (audio_cfg.sample_rate == 88200) { - param = "88200"; - } - if (audio_cfg.sample_rate == 96000) { - param = "96000"; - } - if (audio_cfg.sample_rate == 176400) { - param = "176400"; - } - if (audio_cfg.sample_rate == 192000) { - param = "192000"; - } - return_params[AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES] = param; - } - - if (params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end()) { - std::string param; - if (audio_cfg.channel_mask == AUDIO_CHANNEL_OUT_MONO) { - param = "AUDIO_CHANNEL_OUT_MONO"; - } - if (audio_cfg.channel_mask == AUDIO_CHANNEL_OUT_STEREO) { - param = "AUDIO_CHANNEL_OUT_STEREO"; - } - return_params[AUDIO_PARAMETER_STREAM_SUP_CHANNELS] = param; - } - - if (params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) { - std::string param; - if (audio_cfg.format == AUDIO_FORMAT_PCM_16_BIT) { - param = "AUDIO_FORMAT_PCM_16_BIT"; - } - if (audio_cfg.format == AUDIO_FORMAT_PCM_24_BIT_PACKED) { - param = "AUDIO_FORMAT_PCM_24_BIT_PACKED"; - } - if (audio_cfg.format == AUDIO_FORMAT_PCM_8_24_BIT) { - param = "AUDIO_FORMAT_PCM_8_24_BIT"; - } - if (audio_cfg.format == AUDIO_FORMAT_PCM_32_BIT) { - param = "AUDIO_FORMAT_PCM_32_BIT"; - } - return_params[AUDIO_PARAMETER_STREAM_SUP_FORMATS] = param; - } - - std::string result; - for (const auto& ptr : return_params) { - result += ptr.first + "=" + ptr.second + ";"; - } - - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", result=[" << result << "]"; - return strdup(result.c_str()); -} - -static uint32_t out_get_latency_ms(const struct audio_stream_out* stream) { - const auto* out = reinterpret_cast(stream); - uint32_t latency_ms = 0; - out_calculate_feeding_delay_ms(out, &latency_ms); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", latency=" << latency_ms << "ms"; - return latency_ms; -} - -static int out_set_volume(struct audio_stream_out* stream, float left, - float right) { - auto* out = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", Left=" << left << ", Right=" << right; - return -1; -} - -static ssize_t out_write(struct audio_stream_out* stream, const void* buffer, - size_t bytes) { - auto* out = reinterpret_cast(stream); - std::unique_lock lock(out->mutex_); - size_t totalWritten = 0; - - if (out->bluetooth_output_->GetState() != BluetoothStreamState::STARTED) { - LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " first time bytes=" << bytes; - lock.unlock(); - if (stream->resume(stream)) { - LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " failed to resume"; - if (out->bluetooth_output_->GetState() == - BluetoothStreamState::DISABLED) { - // drop data for cases of A2dpSuspended=true / closing=true - totalWritten = bytes; - } - usleep(out->preferred_data_interval_us); - return totalWritten; - } - lock.lock(); - } - lock.unlock(); - totalWritten = out->bluetooth_output_->WriteData(buffer, bytes); - lock.lock(); - - struct timespec ts = {.tv_sec = 0, .tv_nsec = 0}; - clock_gettime(CLOCK_MONOTONIC, &ts); - if (totalWritten) { - const size_t frames = bytes / audio_stream_out_frame_size(stream); - out->frames_rendered_ += frames; - out->frames_presented_ += frames; - out->last_write_time_us_ = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000; - } else { - const int64_t now = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000; - const int64_t elapsed_time_since_last_write = - now - out->last_write_time_us_; - // frames_count = written_data / frame_size - // play_time (ms) = frames_count / (sample_rate (Sec.) / 1000000) - // sleep_time (ms) = play_time - elapsed_time - int64_t sleep_time = bytes * 1000000LL / - audio_stream_out_frame_size(stream) / - out_get_sample_rate(&stream->common) - - elapsed_time_since_last_write; - if (sleep_time > 0) { - LOG(VERBOSE) << __func__ << ": sleep " << (sleep_time / 1000) - << " ms when writting FMQ datapath"; - lock.unlock(); - usleep(sleep_time); - lock.lock(); - } else { - // we don't sleep when we exit standby (this is typical for a real alsa - // buffer). - sleep_time = 0; - } - out->last_write_time_us_ = now + sleep_time; - } - return totalWritten; -} - -static int out_get_render_position(const struct audio_stream_out* stream, - uint32_t* dsp_frames) { - if (dsp_frames == nullptr) return -EINVAL; - - const auto* out = reinterpret_cast(stream); - // frames = (latency (ms) / 1000) * samples_per_second (sample_rate) - const uint64_t latency_frames = - (uint64_t)out_get_latency_ms(stream) * out->sample_rate_ / 1000; - if (out->frames_rendered_ >= latency_frames) { - *dsp_frames = (uint32_t)(out->frames_rendered_ - latency_frames); - } else { - *dsp_frames = 0; - } - - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", dsp_frames=" << *dsp_frames; - return 0; -} - -static int out_add_audio_effect(const struct audio_stream* stream, - effect_handle_t effect) { - const auto* out = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", effect=" << effect; - return 0; -} - -static int out_remove_audio_effect(const struct audio_stream* stream, - effect_handle_t effect) { - const auto* out = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", effect=" << effect; - return 0; -} - -static int out_get_next_write_timestamp(const struct audio_stream_out* stream, - int64_t* timestamp) { - const auto* out = reinterpret_cast(stream); - *timestamp = 0; - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", timestamp=" << *timestamp; - return -EINVAL; -} - -static int out_pause(struct audio_stream_out* stream) { - auto* out = reinterpret_cast(stream); - std::unique_lock lock(out->mutex_); - int retval = 0; - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", pausing (suspend)"; - if (out->bluetooth_output_->GetState() == BluetoothStreamState::STARTED) { - out->frames_rendered_ = 0; - retval = (out->bluetooth_output_->Suspend() ? 0 : -EIO); - } else if (out->bluetooth_output_->GetState() == - BluetoothStreamState::STARTING || - out->bluetooth_output_->GetState() == - BluetoothStreamState::SUSPENDING) { - LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " NOT ready to pause?!"; - retval = -EBUSY; - } else { - LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " paused already"; - } - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", pausing (suspend) retval=" << retval; - - return retval; -} - -static int out_resume(struct audio_stream_out* stream) { - auto* out = reinterpret_cast(stream); - std::unique_lock lock(out->mutex_); - int retval = 0; - - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", resuming (start)"; - if (out->bluetooth_output_->GetState() == BluetoothStreamState::STANDBY) { - retval = (out->bluetooth_output_->Start() ? 0 : -EIO); - } else if (out->bluetooth_output_->GetState() == - BluetoothStreamState::STARTING || - out->bluetooth_output_->GetState() == - BluetoothStreamState::SUSPENDING) { - LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " NOT ready to resume?!"; - retval = -EBUSY; - } else if (out->bluetooth_output_->GetState() == - BluetoothStreamState::DISABLED) { - LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " NOT allow to resume?!"; - retval = -EINVAL; - } else { - LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " resumed already"; - } - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", resuming (start) retval=" << retval; - - return retval; -} - -static int out_get_presentation_position(const struct audio_stream_out* stream, - uint64_t* frames, - struct timespec* timestamp) { - if (frames == nullptr || timestamp == nullptr) { - return -EINVAL; - } - - const auto* out = reinterpret_cast(stream); - out_calculate_feeding_delay_ms(out, nullptr, frames, timestamp); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", frames=" << *frames << ", timestamp=" << timestamp->tv_sec - << "." << StringPrintf("%09ld", timestamp->tv_nsec) << "s"; - return 0; -} - -static void out_update_source_metadata( - struct audio_stream_out* stream, - const struct source_metadata* source_metadata) { - auto* out = reinterpret_cast(stream); - std::unique_lock lock(out->mutex_); - if (source_metadata == nullptr || source_metadata->track_count == 0) { - return; - } - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", " << source_metadata->track_count << " track(s)"; - out->bluetooth_output_->UpdateSourceMetadata(source_metadata); -} - -static size_t frame_count(size_t microseconds, uint32_t sample_rate) { - return (microseconds * sample_rate) / 1000000; -} - -int adev_open_output_stream(struct audio_hw_device* dev, - audio_io_handle_t handle, audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config* config, - struct audio_stream_out** stream_out, - const char* address __unused) { - *stream_out = nullptr; - auto out = std::make_unique(); - if (::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession:: - IsAidlAvailable()) { - out->bluetooth_output_ = std::make_unique< - ::android::bluetooth::audio::aidl::BluetoothAudioPortAidlOut>(); - out->is_aidl = true; - } else { - out->bluetooth_output_ = std::make_unique< - ::android::bluetooth::audio::hidl::BluetoothAudioPortHidlOut>(); - out->is_aidl = false; - } - if (!out->bluetooth_output_->SetUp(devices)) { - out->bluetooth_output_ = nullptr; - LOG(ERROR) << __func__ << ": cannot init HAL"; - return -EINVAL; - } - LOG(VERBOSE) << __func__ << ": device=" << StringPrintf("%#x", devices); - - out->stream_out_.common.get_sample_rate = out_get_sample_rate; - out->stream_out_.common.set_sample_rate = out_set_sample_rate; - out->stream_out_.common.get_buffer_size = out_get_buffer_size; - out->stream_out_.common.get_channels = out_get_channels; - out->stream_out_.common.get_format = out_get_format; - out->stream_out_.common.set_format = out_set_format; - out->stream_out_.common.standby = out_standby; - out->stream_out_.common.dump = out_dump; - out->stream_out_.common.set_parameters = out_set_parameters; - out->stream_out_.common.get_parameters = out_get_parameters; - out->stream_out_.common.add_audio_effect = out_add_audio_effect; - out->stream_out_.common.remove_audio_effect = out_remove_audio_effect; - out->stream_out_.get_latency = out_get_latency_ms; - out->stream_out_.set_volume = out_set_volume; - out->stream_out_.write = out_write; - out->stream_out_.get_render_position = out_get_render_position; - out->stream_out_.get_next_write_timestamp = out_get_next_write_timestamp; - out->stream_out_.pause = out_pause; - out->stream_out_.resume = out_resume; - out->stream_out_.get_presentation_position = out_get_presentation_position; - out->stream_out_.update_source_metadata = out_update_source_metadata; - - if (!out->bluetooth_output_->LoadAudioConfig(config)) { - LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << " failed to get audio config"; - } - // WAR to support Mono / 16 bits per sample as the Bluetooth stack required - if (config->channel_mask == AUDIO_CHANNEL_OUT_MONO && - config->format == AUDIO_FORMAT_PCM_16_BIT) { - LOG(INFO) << __func__ - << ": force channels=" << StringPrintf("%#x", out->channel_mask_) - << " to be AUDIO_CHANNEL_OUT_STEREO"; - out->bluetooth_output_->ForcePcmStereoToMono(true); - config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; - } - out->sample_rate_ = config->sample_rate; - out->channel_mask_ = config->channel_mask; - out->format_ = config->format; - // frame is number of samples per channel - - size_t preferred_data_interval_us = kBluetoothDefaultOutputBufferMs * 1000; - if (out->bluetooth_output_->GetPreferredDataIntervalUs( - &preferred_data_interval_us) && - preferred_data_interval_us != 0) { - out->preferred_data_interval_us = preferred_data_interval_us; - } else { - out->preferred_data_interval_us = kBluetoothDefaultOutputBufferMs * 1000; - } - - // Ensure minimum buffer duration for spatialized output - if ((flags == (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER) || - flags == AUDIO_OUTPUT_FLAG_SPATIALIZER) && - out->preferred_data_interval_us < - kBluetoothSpatializerOutputBufferMs * 1000) { - out->preferred_data_interval_us = - kBluetoothSpatializerOutputBufferMs * 1000; - LOG(INFO) << __func__ - << ": adjusting to minimum buffer duration for spatializer: " - << StringPrintf("%zu", out->preferred_data_interval_us); - } - - out->frames_count_ = - frame_count(out->preferred_data_interval_us, out->sample_rate_); - - out->frames_rendered_ = 0; - out->frames_presented_ = 0; - - BluetoothStreamOut* out_ptr = out.release(); - { - auto* bluetooth_device = reinterpret_cast(dev); - std::lock_guard guard(bluetooth_device->mutex_); - bluetooth_device->opened_stream_outs_.push_back(out_ptr); - } - - *stream_out = &out_ptr->stream_out_; - LOG(INFO) << __func__ << ": state=" << out_ptr->bluetooth_output_->GetState() - << ", sample_rate=" << out_ptr->sample_rate_ - << ", channels=" << StringPrintf("%#x", out_ptr->channel_mask_) - << ", format=" << out_ptr->format_ - << ", preferred_data_interval_us=" - << out_ptr->preferred_data_interval_us - << ", frames=" << out_ptr->frames_count_; - return 0; -} - -void adev_close_output_stream(struct audio_hw_device* dev, - struct audio_stream_out* stream) { - auto* out = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", stopping"; - { - auto* bluetooth_device = reinterpret_cast(dev); - std::lock_guard guard(bluetooth_device->mutex_); - bluetooth_device->opened_stream_outs_.remove(out); - } - if (out->bluetooth_output_->GetState() != BluetoothStreamState::DISABLED) { - out->frames_rendered_ = 0; - out->frames_presented_ = 0; - out->bluetooth_output_->Stop(); - } - out->bluetooth_output_->TearDown(); - LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_->GetState() - << ", stopped"; - delete out; -} - -size_t adev_get_input_buffer_size(const struct audio_hw_device* dev, - const struct audio_config* config) { - /* TODO: Adjust this value */ - LOG(VERBOSE) << __func__; - return 320; -} - -static uint32_t in_get_sample_rate(const struct audio_stream* stream) { - const auto* in = reinterpret_cast(stream); - - return in->sample_rate_; -} - -static int in_set_sample_rate(struct audio_stream* stream, uint32_t rate) { - const auto* in = reinterpret_cast(stream); - - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", sample_rate=" << in->sample_rate_; - return (rate == in->sample_rate_ ? 0 : -ENOSYS); -} - -static size_t in_get_buffer_size(const struct audio_stream* stream) { - const auto* in = reinterpret_cast(stream); - size_t buffer_size = - in->frames_count_ * audio_stream_in_frame_size(&in->stream_in_); - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", buffer_size=" << buffer_size; - return buffer_size; -} - -static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) { - const auto* in = reinterpret_cast(stream); - audio_config_t audio_cfg; - if (in->bluetooth_input_->LoadAudioConfig(&audio_cfg)) { - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " audio_cfg=" << audio_cfg; - return audio_cfg.channel_mask; - } else { - LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", channels=" << StringPrintf("%#x", in->channel_mask_) - << " failure"; - return in->channel_mask_; - } -} - -static audio_format_t in_get_format(const struct audio_stream* stream) { - const auto* in = reinterpret_cast(stream); - audio_config_t audio_cfg; - if (in->bluetooth_input_->LoadAudioConfig(&audio_cfg)) { - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " audio_cfg=" << audio_cfg; - return audio_cfg.format; - } else { - LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", format=" << in->format_ << " failure"; - return in->format_; - } -} - -static int in_set_format(struct audio_stream* stream, audio_format_t format) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", format=" << in->format_; - return (format == in->format_ ? 0 : -ENOSYS); -} - -static bool in_state_transition_timeout(BluetoothStreamIn* in, - std::unique_lock& lock, - const BluetoothStreamState& state, - uint16_t timeout_ms) { - /* Don't loose suspend request, AF will not retry */ - while (in->bluetooth_input_->GetState() == state) { - lock.unlock(); - usleep(1000); - lock.lock(); - - /* Don't block AF forever */ - if (--timeout_ms <= 0) { - LOG(WARNING) << __func__ << ", can't suspend - stucked in: " - << static_cast(state) << " state"; - return false; - } - } - - return true; -} - -static int in_standby(struct audio_stream* stream) { - auto* in = reinterpret_cast(stream); - std::unique_lock lock(in->mutex_); - int retval = 0; - - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " being standby (suspend)"; - - /* Give some time to start up */ - if (!in_state_transition_timeout(in, lock, BluetoothStreamState::STARTING, - kBluetoothDefaultInputStateTimeoutMs)) { - LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " NOT ready to by standby"; - return retval; - } - - if (in->bluetooth_input_->GetState() == BluetoothStreamState::STARTED) { - retval = (in->bluetooth_input_->Suspend() ? 0 : -EIO); - } else if (in->bluetooth_input_->GetState() != - BluetoothStreamState::SUSPENDING) { - LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " standby already"; - return retval; - } - - /* Give some time to suspend */ - if (!in_state_transition_timeout(in, lock, BluetoothStreamState::SUSPENDING, - kBluetoothDefaultInputStateTimeoutMs)) { - LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " NOT ready to by standby"; - return 0; - } - - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " standby (suspend) retval=" << retval; - - return retval; -} - -static int in_dump(const struct audio_stream* stream, int fd) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState(); - - return 0; -} - -static int in_set_parameters(struct audio_stream* stream, const char* kvpairs) { - auto* in = reinterpret_cast(stream); - std::unique_lock lock(in->mutex_); - int retval = 0; - - LOG(INFO) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState() - << ", kvpairs=[" << kvpairs << "]"; - - std::unordered_map params = - ParseAudioParams(kvpairs); - - if (params.empty()) return retval; - - LOG(INFO) << __func__ << ": ParamsMap=[" << GetAudioParamString(params) - << "]"; - - return retval; -} - -static char* in_get_parameters(const struct audio_stream* stream, - const char* keys) { - const auto* in = reinterpret_cast(stream); - std::unique_lock lock(in->mutex_); - - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState() - << ", keys=[" << keys << "]"; - - std::unordered_map params = ParseAudioParams(keys); - if (params.empty()) return strdup(""); - - audio_config_t audio_cfg; - if (in->bluetooth_input_->LoadAudioConfig(&audio_cfg)) { - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " audio_cfg=" << audio_cfg; - } else { - LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " failed to get audio config"; - } - - std::unordered_map return_params; - - /* TODO: Implement parameter getter */ - - std::string result; - for (const auto& ptr : return_params) { - result += ptr.first + "=" + ptr.second + ";"; - } - - return strdup(result.c_str()); -} - -static int in_add_audio_effect(const struct audio_stream* stream, - effect_handle_t effect) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", effect=" << effect; - return 0; -} - -static int in_remove_audio_effect(const struct audio_stream* stream, - effect_handle_t effect) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", effect=" << effect; - return 0; -} - -static int in_set_gain(struct audio_stream_in* stream, float gain) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return 0; -} - -static ssize_t in_read(struct audio_stream_in* stream, void* buffer, - size_t bytes) { - auto* in = reinterpret_cast(stream); - std::unique_lock lock(in->mutex_); - size_t totalRead = 0; - - /* Give some time to start up */ - if (!in_state_transition_timeout(in, lock, BluetoothStreamState::STARTING, - kBluetoothDefaultInputStateTimeoutMs)) - return -EBUSY; - - if (in->bluetooth_input_->GetState() != BluetoothStreamState::STARTED) { - LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " first time bytes=" << bytes; - - int retval = 0; - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", starting"; - if (in->bluetooth_input_->GetState() == BluetoothStreamState::STANDBY) { - retval = (in->bluetooth_input_->Start() ? 0 : -EIO); - } else if (in->bluetooth_input_->GetState() == - BluetoothStreamState::SUSPENDING) { - LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " NOT ready to start?!"; - retval = -EBUSY; - } else if (in->bluetooth_input_->GetState() == - BluetoothStreamState::DISABLED) { - LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " NOT allow to start?!"; - retval = -EINVAL; - } else { - LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " started already"; - } - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", starting (start) retval=" << retval; - - if (retval) { - LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " failed to start"; - return retval; - } - } - - lock.unlock(); - totalRead = in->bluetooth_input_->ReadData(buffer, bytes); - lock.lock(); - - struct timespec ts = {.tv_sec = 0, .tv_nsec = 0}; - clock_gettime(CLOCK_MONOTONIC, &ts); - in->last_read_time_us_ = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000; - - const size_t frames = totalRead / audio_stream_in_frame_size(stream); - in->frames_presented_ += frames; - - return totalRead; -} - -static uint32_t in_get_input_frames_lost(struct audio_stream_in* stream) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return 0; -} - -static int in_get_capture_position(const struct audio_stream_in* stream, - int64_t* frames, int64_t* time) { - if (stream == NULL || frames == NULL || time == NULL) { - return -EINVAL; - } - const auto* in = reinterpret_cast(stream); - - if (in->bluetooth_input_->GetState() == BluetoothStreamState::STANDBY) { - LOG(WARNING) << __func__ << ": state= " << in->bluetooth_input_->GetState(); - return -ENOSYS; - } - - in_calculate_starving_delay_ms(in, frames, time); - - return 0; -} - -static int in_start(const struct audio_stream_in* stream) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return 0; -} - -static int in_stop(const struct audio_stream_in* stream) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return 0; -} - -static int in_create_mmap_buffer(const struct audio_stream_in* stream, - int32_t min_size_frames, - struct audio_mmap_buffer_info* info) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return -ENOSYS; -} - -static int in_get_mmap_position(const struct audio_stream_in* stream, - struct audio_mmap_position* position) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return -ENOSYS; -} - -static int in_get_active_microphones( - const struct audio_stream_in* stream, - struct audio_microphone_characteristic_t* mic_array, size_t* mic_count) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return -ENOSYS; -} - -static int in_set_microphone_direction(const struct audio_stream_in* stream, - audio_microphone_direction_t direction) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return -ENOSYS; -} - -static int in_set_microphone_field_dimension( - const struct audio_stream_in* stream, float zoom) { - const auto* in = reinterpret_cast(stream); - LOG(VERBOSE) << __func__ - << ": NOT HANDLED! state=" << in->bluetooth_input_->GetState(); - - return -ENOSYS; -} - -static void in_update_sink_metadata(struct audio_stream_in* stream, - const struct sink_metadata* sink_metadata) { - LOG(INFO) << __func__; - if (sink_metadata == nullptr || sink_metadata->track_count == 0) { - return; - } - - const auto* in = reinterpret_cast(stream); - LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", " << sink_metadata->track_count << " track(s)"; - - if (!in->is_aidl) { - LOG(WARNING) << __func__ - << " is only supported in AIDL but using HIDL now!"; - return; - } - static_cast<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl*>( - in->bluetooth_input_.get()) - ->UpdateSinkMetadata(sink_metadata); -} - -int adev_open_input_stream(struct audio_hw_device* dev, - audio_io_handle_t handle, audio_devices_t devices, - struct audio_config* config, - struct audio_stream_in** stream_in, - audio_input_flags_t flags __unused, - const char* address __unused, - audio_source_t source __unused) { - *stream_in = nullptr; - auto in = std::make_unique(); - if (::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession:: - IsAidlAvailable()) { - in->bluetooth_input_ = std::make_unique< - ::android::bluetooth::audio::aidl::BluetoothAudioPortAidlIn>(); - in->is_aidl = true; - } else { - in->bluetooth_input_ = std::make_unique< - ::android::bluetooth::audio::hidl::BluetoothAudioPortHidlIn>(); - in->is_aidl = false; - } - if (!in->bluetooth_input_->SetUp(devices)) { - in->bluetooth_input_ = nullptr; - LOG(ERROR) << __func__ << ": cannot init HAL"; - return -EINVAL; - } - - LOG(INFO) << __func__ << ": device=" << StringPrintf("%#x", devices); - - in->stream_in_.common.get_sample_rate = in_get_sample_rate; - in->stream_in_.common.set_sample_rate = in_set_sample_rate; - in->stream_in_.common.get_buffer_size = in_get_buffer_size; - in->stream_in_.common.get_channels = in_get_channels; - in->stream_in_.common.get_format = in_get_format; - in->stream_in_.common.set_format = in_set_format; - in->stream_in_.common.standby = in_standby; - in->stream_in_.common.dump = in_dump; - in->stream_in_.common.set_parameters = in_set_parameters; - in->stream_in_.common.get_parameters = in_get_parameters; - in->stream_in_.common.add_audio_effect = in_add_audio_effect; - in->stream_in_.common.remove_audio_effect = in_remove_audio_effect; - in->stream_in_.set_gain = in_set_gain; - in->stream_in_.read = in_read; - in->stream_in_.get_input_frames_lost = in_get_input_frames_lost; - in->stream_in_.get_capture_position = in_get_capture_position; - in->stream_in_.start = in_start; - in->stream_in_.stop = in_stop; - in->stream_in_.create_mmap_buffer = in_create_mmap_buffer; - in->stream_in_.get_mmap_position = in_get_mmap_position; - in->stream_in_.get_active_microphones = in_get_active_microphones; - in->stream_in_.set_microphone_direction = in_set_microphone_direction; - in->stream_in_.set_microphone_field_dimension = - in_set_microphone_field_dimension; - in->stream_in_.update_sink_metadata = in_update_sink_metadata; - - if (!in->bluetooth_input_->LoadAudioConfig(config)) { - LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << " failed to get audio config"; - return -EINVAL; - } - - in->sample_rate_ = config->sample_rate; - in->channel_mask_ = config->channel_mask; - in->format_ = config->format; - // frame is number of samples per channel - - size_t preferred_data_interval_us = kBluetoothDefaultInputBufferMs * 1000; - if (in->bluetooth_input_->GetPreferredDataIntervalUs( - &preferred_data_interval_us) && - preferred_data_interval_us != 0) { - in->preferred_data_interval_us = preferred_data_interval_us; - } else { - in->preferred_data_interval_us = kBluetoothDefaultInputBufferMs * 1000; - } - - in->frames_count_ = - frame_count(in->preferred_data_interval_us, in->sample_rate_); - in->frames_presented_ = 0; - - BluetoothStreamIn* in_ptr = in.release(); - *stream_in = &in_ptr->stream_in_; - LOG(INFO) << __func__ << ": state=" << in_ptr->bluetooth_input_->GetState() - << ", sample_rate=" << in_ptr->sample_rate_ - << ", channels=" << StringPrintf("%#x", in_ptr->channel_mask_) - << ", format=" << in_ptr->format_ << ", preferred_data_interval_us=" - << in_ptr->preferred_data_interval_us - << ", frames=" << in_ptr->frames_count_; - - return 0; -} - -void adev_close_input_stream(struct audio_hw_device* dev, - struct audio_stream_in* stream) { - auto* in = reinterpret_cast(stream); - - if (in->bluetooth_input_->GetState() != BluetoothStreamState::DISABLED) { - in->bluetooth_input_->Stop(); - } - - in->bluetooth_input_->TearDown(); - LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_->GetState() - << ", stopped"; - - delete in; -} diff --git a/bluetooth/audio/hw/stream_apis.h b/bluetooth/audio/hw/stream_apis.h deleted file mode 100644 index 36dd589..0000000 --- a/bluetooth/audio/hw/stream_apis.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2019 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 -#include - -#include - -#include "device_port_proxy.h" -#include "device_port_proxy_hidl.h" - -constexpr unsigned int kBluetoothDefaultSampleRate = 44100; -constexpr audio_format_t kBluetoothDefaultAudioFormatBitsPerSample = - AUDIO_FORMAT_PCM_16_BIT; - -constexpr unsigned int kBluetoothDefaultInputBufferMs = 20; -constexpr unsigned int kBluetoothDefaultInputStateTimeoutMs = 20; - -constexpr unsigned int kBluetoothDefaultOutputBufferMs = 10; -constexpr unsigned int kBluetoothSpatializerOutputBufferMs = 10; - -constexpr audio_channel_mask_t kBluetoothDefaultOutputChannelModeMask = - AUDIO_CHANNEL_OUT_STEREO; -constexpr audio_channel_mask_t kBluetoothDefaultInputChannelModeMask = - AUDIO_CHANNEL_IN_MONO; - -enum class BluetoothStreamState : uint8_t { - DISABLED = 0, // This stream is closing or set param "suspend=true" - STANDBY, - STARTING, - STARTED, - SUSPENDING, - UNKNOWN, -}; - -std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state); - -struct BluetoothStreamOut { - // Must be the first member so it can be cast from audio_stream - // or audio_stream_out pointer - audio_stream_out stream_out_{}; - std::unique_ptr<::android::bluetooth::audio::BluetoothAudioPort> - bluetooth_output_; - bool is_aidl; - int64_t last_write_time_us_; - // Audio PCM Configs - uint32_t sample_rate_; - audio_channel_mask_t channel_mask_; - audio_format_t format_; - size_t preferred_data_interval_us; - // frame is the number of samples per channel - // frames count per tick - size_t frames_count_; - // total frames written, reset on standby - uint64_t frames_rendered_; - // total frames written after opened, never reset - uint64_t frames_presented_; - mutable std::mutex mutex_; -}; - -struct BluetoothAudioDevice { - // Important: device must be first as an audio_hw_device* may be cast to - // BluetoothAudioDevice* when the type is implicitly known. - audio_hw_device audio_device_{}; - // protect against device->output and stream_out from being inconsistent - std::mutex mutex_; - std::list opened_stream_outs_ = - std::list(0); -}; - -struct BluetoothStreamIn { - // Must be the first member so it can be cast from audio_stream - // or audio_stream_in pointer - audio_stream_in stream_in_; - std::unique_ptr<::android::bluetooth::audio::BluetoothAudioPort> - bluetooth_input_; - bool is_aidl; - int64_t last_read_time_us_; - // Audio PCM Configs - uint32_t sample_rate_; - audio_channel_mask_t channel_mask_; - audio_format_t format_; - size_t preferred_data_interval_us; - // frame is the number of samples per channel - // frames count per tick - size_t frames_count_; - // total frames read after opened, never reset - uint64_t frames_presented_; - mutable std::mutex mutex_; -}; - -int adev_open_output_stream(struct audio_hw_device* dev, - audio_io_handle_t handle, audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config* config, - struct audio_stream_out** stream_out, - const char* address __unused); - -void adev_close_output_stream(struct audio_hw_device* dev, - struct audio_stream_out* stream); - -size_t adev_get_input_buffer_size(const struct audio_hw_device* dev, - const struct audio_config* config); - -int adev_open_input_stream(struct audio_hw_device* dev, - audio_io_handle_t handle, audio_devices_t devices, - struct audio_config* config, - struct audio_stream_in** stream_in, - audio_input_flags_t flags __unused, - const char* address __unused, - audio_source_t source __unused); - -void adev_close_input_stream(struct audio_hw_device* dev, - struct audio_stream_in* in); diff --git a/bluetooth/audio/hw/utils.cc b/bluetooth/audio/hw/utils.cc deleted file mode 100644 index b3ac7a5..0000000 --- a/bluetooth/audio/hw/utils.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2019 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. - */ - -#define LOG_TAG "BTAudioHalUtils" - -#include "utils.h" - -#include -#include -#include -#include -#include -#include - -namespace android { -namespace bluetooth { -namespace audio { -namespace utils { - -std::unordered_map ParseAudioParams( - const std::string& params) { - std::vector segments = android::base::Split(params, ";"); - std::unordered_map params_map; - for (const auto& segment : segments) { - if (segment.length() == 0) { - continue; - } - std::vector kv = android::base::Split(segment, "="); - if (kv[0].empty()) { - LOG(WARNING) << __func__ << ": Invalid audio parameter " << segment; - continue; - } - params_map[kv[0]] = (kv.size() > 1 ? kv[1] : ""); - } - return params_map; -} - -std::string GetAudioParamString( - std::unordered_map& params_map) { - std::ostringstream sout; - for (const auto& ptr : params_map) { - sout << "key: '" << ptr.first << "' value: '" << ptr.second << "'\n"; - } - return sout.str(); -} - -} // namespace utils -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/hw/utils.h b/bluetooth/audio/hw/utils.h deleted file mode 100644 index 817a432..0000000 --- a/bluetooth/audio/hw/utils.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2019 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 -#include - -namespace android { -namespace bluetooth { -namespace audio { -namespace utils { - -// Creates a hash map based on the |params| string containing key and value -// pairs. Pairs are expected in the form "key=value" separated by the ';' -// character. Both ';' and '=' characters are invalid in keys or values. -// Examples: -// "key0" -> map: [key0]="" -// "key0=value0;key1=value1;" -> map: [key0]="value0" [key1]="value1" -// "key0=;key1=value1;" -> map: [key0]="" [key1]="value1" -// "=value0;key1=value1;" -> map: [key1]="value1" -std::unordered_map ParseAudioParams( - const std::string& params); - -// Dumps the contents of the hash_map to the log for debugging purposes. -// If |map| is not NULL, all entries of |map| will be dumped, otherwise -// nothing will be dumped. Note that this function does not take the ownership -// of the |map|. -std::string GetAudioParamString( - std::unordered_map& params_map); - -} // namespace utils -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp deleted file mode 100644 index 7b054e5..0000000 --- a/bluetooth/audio/utils/Android.bp +++ /dev/null @@ -1,46 +0,0 @@ -cc_library_shared { - name: "libbluetooth_audio_session_system", - defaults: ["hidl_defaults"], - srcs: [ - "session/BluetoothAudioSession.cpp", - "session/BluetoothAudioSession_2_1.cpp", - "session/BluetoothAudioSupportedCodecsDB.cpp", - "session/BluetoothAudioSupportedCodecsDB_2_1.cpp", - ], - export_include_dirs: ["session/"], - header_libs: ["libhardware_headers"], - shared_libs: [ - "android.hardware.audio.common@5.0", - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", - "libbase", - "libcutils", - "libfmq", - "libhidlbase", - "liblog", - "libutils", - "libbluetooth_audio_session_aidl_system", - ], -} - -cc_library_shared { - name: "libbluetooth_audio_session_aidl_system", - srcs: [ - "aidl_session/BluetoothAudioCodecs.cpp", - "aidl_session/BluetoothAudioSession.cpp", - "aidl_session/HidlToAidlMiddleware.cpp", - ], - export_include_dirs: ["aidl_session/"], - header_libs: ["libhardware_headers"], - shared_libs: [ - "android.hardware.bluetooth.audio@2.0", - "android.hardware.bluetooth.audio@2.1", - "libbase", - "libcutils", - "libbinder_ndk", - "libfmq", - "liblog", - "android.hardware.bluetooth.audio-V2-ndk", - "libhidlbase", - ], -} diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp deleted file mode 100644 index b858f50..0000000 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp +++ /dev/null @@ -1,523 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BTAudioCodecsAidl" - -#include "BluetoothAudioCodecs.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -static const PcmCapabilities kDefaultSoftwarePcmCapabilities = { - .sampleRateHz = {16000, 24000, 32000, 44100, 48000, 88200, 96000}, - .channelMode = {ChannelMode::MONO, ChannelMode::STEREO}, - .bitsPerSample = {16, 24, 32}, - .dataIntervalUs = {}, -}; - -static const SbcCapabilities kDefaultOffloadSbcCapability = { - .sampleRateHz = {44100}, - .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO}, - .blockLength = {4, 8, 12, 16}, - .numSubbands = {8}, - .allocMethod = {SbcAllocMethod::ALLOC_MD_L}, - .bitsPerSample = {16}, - .minBitpool = 2, - .maxBitpool = 53}; - -static const AacCapabilities kDefaultOffloadAacCapability = { - .objectType = {AacObjectType::MPEG2_LC}, - .sampleRateHz = {44100}, - .channelMode = {ChannelMode::STEREO}, - .variableBitRateSupported = true, - .bitsPerSample = {16}}; - -static const LdacCapabilities kDefaultOffloadLdacCapability = { - .sampleRateHz = {44100, 48000, 88200, 96000}, - .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO}, - .qualityIndex = {LdacQualityIndex::HIGH}, - .bitsPerSample = {16, 24, 32}}; - -static const AptxCapabilities kDefaultOffloadAptxCapability = { - .sampleRateHz = {44100, 48000}, - .channelMode = {ChannelMode::STEREO}, - .bitsPerSample = {16}, -}; - -static const AptxCapabilities kDefaultOffloadAptxHdCapability = { - .sampleRateHz = {44100, 48000}, - .channelMode = {ChannelMode::STEREO}, - .bitsPerSample = {24}, -}; - -static const OpusCapabilities kDefaultOffloadOpusCapability = { - .samplingFrequencyHz = {48000}, - .frameDurationUs = {10000, 20000}, - .channelMode = {ChannelMode::MONO, ChannelMode::STEREO}, -}; - -const std::vector kDefaultOffloadA2dpCodecCapabilities = { - {.codecType = CodecType::SBC, .capabilities = {}}, - {.codecType = CodecType::AAC, .capabilities = {}}, - {.codecType = CodecType::LDAC, .capabilities = {}}, - {.codecType = CodecType::APTX, .capabilities = {}}, - {.codecType = CodecType::APTX_HD, .capabilities = {}}, - {.codecType = CodecType::OPUS, .capabilities = {}}}; - -std::vector kDefaultOffloadLeAudioCapabilities; - -static const UnicastCapability kInvalidUnicastCapability = { - .codecType = CodecType::UNKNOWN}; - -static const BroadcastCapability kInvalidBroadcastCapability = { - .codecType = CodecType::UNKNOWN}; - -// Default Supported Codecs -// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30 -static const Lc3Capabilities kLc3Capability_16_1 = { - .samplingFrequencyHz = {16000}, - .frameDurationUs = {7500}, - .octetsPerFrame = {30}}; - -// Default Supported Codecs -// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40 -static const Lc3Capabilities kLc3Capability_16_2 = { - .samplingFrequencyHz = {16000}, - .frameDurationUs = {10000}, - .octetsPerFrame = {40}}; - -// Default Supported Codecs -// LC3 24_2: sample rate: 24 kHz, frame duration: 10 ms, octets per frame: 60 -static const Lc3Capabilities kLc3Capability_24_2 = { - .samplingFrequencyHz = {24000}, - .frameDurationUs = {10000}, - .octetsPerFrame = {60}}; - -// Default Supported Codecs -// LC3 32_2: sample rate: 32 kHz, frame duration: 10 ms, octets per frame: 80 -static const Lc3Capabilities kLc3Capability_32_2 = { - .samplingFrequencyHz = {32000}, - .frameDurationUs = {10000}, - .octetsPerFrame = {80}}; - -// Default Supported Codecs -// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120 -static const Lc3Capabilities kLc3Capability_48_4 = { - .samplingFrequencyHz = {48000}, - .frameDurationUs = {10000}, - .octetsPerFrame = {120}}; - -static const std::vector supportedLc3CapabilityList = { - kLc3Capability_48_4, kLc3Capability_32_2, kLc3Capability_24_2, - kLc3Capability_16_2, kLc3Capability_16_1}; - -static AudioLocation stereoAudio = static_cast( - static_cast(AudioLocation::FRONT_LEFT) | - static_cast(AudioLocation::FRONT_RIGHT)); -static AudioLocation monoAudio = AudioLocation::UNKNOWN; - -// Stores the supported setting of audio location, connected device, and the -// channel count for each device -std::vector> - supportedDeviceSetting = { - // Stereo, two connected device, one for L one for R - std::make_tuple(stereoAudio, 2, 1), - // Stereo, one connected device for both L and R - std::make_tuple(stereoAudio, 1, 2), - // Mono - std::make_tuple(monoAudio, 1, 1)}; - -template -bool BluetoothAudioCodecs::ContainedInVector( - const std::vector& vector, const typename identity::type& target) { - return std::find(vector.begin(), vector.end(), target) != vector.end(); -} - -bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << codec_specific.toString(); - return false; - } - const SbcConfiguration sbc_data = - codec_specific.get(); - - if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz, - sbc_data.sampleRateHz) && - ContainedInVector(kDefaultOffloadSbcCapability.blockLength, - sbc_data.blockLength) && - ContainedInVector(kDefaultOffloadSbcCapability.numSubbands, - sbc_data.numSubbands) && - ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample, - sbc_data.bitsPerSample) && - ContainedInVector(kDefaultOffloadSbcCapability.channelMode, - sbc_data.channelMode) && - ContainedInVector(kDefaultOffloadSbcCapability.allocMethod, - sbc_data.allocMethod) && - sbc_data.minBitpool <= sbc_data.maxBitpool && - kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool && - kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << codec_specific.toString(); - return false; -} - -bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << codec_specific.toString(); - return false; - } - const AacConfiguration aac_data = - codec_specific.get(); - - if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz, - aac_data.sampleRateHz) && - ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample, - aac_data.bitsPerSample) && - ContainedInVector(kDefaultOffloadAacCapability.channelMode, - aac_data.channelMode) && - ContainedInVector(kDefaultOffloadAacCapability.objectType, - aac_data.objectType) && - (!aac_data.variableBitRateEnabled || - kDefaultOffloadAacCapability.variableBitRateSupported)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << codec_specific.toString(); - return false; -} - -bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getTag() != - CodecConfiguration::CodecSpecific::ldacConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << codec_specific.toString(); - return false; - } - const LdacConfiguration ldac_data = - codec_specific.get(); - - if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz, - ldac_data.sampleRateHz) && - ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample, - ldac_data.bitsPerSample) && - ContainedInVector(kDefaultOffloadLdacCapability.channelMode, - ldac_data.channelMode) && - ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex, - ldac_data.qualityIndex)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << codec_specific.toString(); - return false; -} - -bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getTag() != - CodecConfiguration::CodecSpecific::aptxConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << codec_specific.toString(); - return false; - } - const AptxConfiguration aptx_data = - codec_specific.get(); - - if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz, - aptx_data.sampleRateHz) && - ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample, - aptx_data.bitsPerSample) && - ContainedInVector(kDefaultOffloadAptxCapability.channelMode, - aptx_data.channelMode)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << codec_specific.toString(); - return false; -} - -bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getTag() != - CodecConfiguration::CodecSpecific::aptxConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << codec_specific.toString(); - return false; - } - const AptxConfiguration aptx_data = - codec_specific.get(); - - if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz, - aptx_data.sampleRateHz) && - ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample, - aptx_data.bitsPerSample) && - ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode, - aptx_data.channelMode)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << codec_specific.toString(); - return false; -} - -bool BluetoothAudioCodecs::IsOffloadOpusConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getTag() != - CodecConfiguration::CodecSpecific::opusConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << codec_specific.toString(); - return false; - } - std::optional opus_data = - codec_specific.get(); - - if (opus_data.has_value() && - ContainedInVector(kDefaultOffloadOpusCapability.samplingFrequencyHz, - opus_data->samplingFrequencyHz) && - ContainedInVector(kDefaultOffloadOpusCapability.frameDurationUs, - opus_data->frameDurationUs) && - ContainedInVector(kDefaultOffloadOpusCapability.channelMode, - opus_data->channelMode)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << codec_specific.toString(); - return false; -} - -bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid( - const SessionType& session_type, const LeAudioConfiguration&) { - if (session_type != - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && - session_type != - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH && - session_type != - SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { - return false; - } - return true; -} - -std::vector -BluetoothAudioCodecs::GetSoftwarePcmCapabilities() { - return {kDefaultSoftwarePcmCapabilities}; -} - -std::vector -BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities( - const SessionType& session_type) { - if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH && - session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - return {}; - } - std::vector offload_a2dp_codec_capabilities = - kDefaultOffloadA2dpCodecCapabilities; - for (auto& codec_capability : offload_a2dp_codec_capabilities) { - switch (codec_capability.codecType) { - case CodecType::SBC: - codec_capability.capabilities - .set( - kDefaultOffloadSbcCapability); - break; - case CodecType::AAC: - codec_capability.capabilities - .set( - kDefaultOffloadAacCapability); - break; - case CodecType::LDAC: - codec_capability.capabilities - .set( - kDefaultOffloadLdacCapability); - break; - case CodecType::APTX: - codec_capability.capabilities - .set( - kDefaultOffloadAptxCapability); - break; - case CodecType::APTX_HD: - codec_capability.capabilities - .set( - kDefaultOffloadAptxHdCapability); - break; - case CodecType::OPUS: - codec_capability.capabilities - .set( - kDefaultOffloadOpusCapability); - break; - case CodecType::UNKNOWN: - case CodecType::VENDOR: - case CodecType::LC3: - case CodecType::APTX_ADAPTIVE: - break; - } - } - return offload_a2dp_codec_capabilities; -} - -bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid( - const PcmConfiguration& pcm_config) { - if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz, - pcm_config.sampleRateHz) && - ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample, - pcm_config.bitsPerSample) && - ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode, - pcm_config.channelMode) - // data interval is not checked for now - // && pcm_config.dataIntervalUs != 0 - ) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << pcm_config.toString(); - return false; -} - -bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid( - const SessionType& session_type, const CodecConfiguration& codec_config) { - if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH && - session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - LOG(ERROR) << __func__ - << ": Invalid SessionType=" << toString(session_type); - return false; - } - const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config; - switch (codec_config.codecType) { - case CodecType::SBC: - if (IsOffloadSbcConfigurationValid(codec_specific)) { - return true; - } - break; - case CodecType::AAC: - if (IsOffloadAacConfigurationValid(codec_specific)) { - return true; - } - break; - case CodecType::LDAC: - if (IsOffloadLdacConfigurationValid(codec_specific)) { - return true; - } - break; - case CodecType::APTX: - if (IsOffloadAptxConfigurationValid(codec_specific)) { - return true; - } - break; - case CodecType::APTX_HD: - if (IsOffloadAptxHdConfigurationValid(codec_specific)) { - return true; - } - break; - case CodecType::OPUS: - if (IsOffloadOpusConfigurationValid(codec_specific)) { - return true; - } - break; - case CodecType::APTX_ADAPTIVE: - case CodecType::LC3: - case CodecType::UNKNOWN: - case CodecType::VENDOR: - break; - } - return false; -} - -UnicastCapability composeUnicastLc3Capability( - AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount, - const Lc3Capabilities& capability) { - return { - .codecType = CodecType::LC3, - .supportedChannel = audioLocation, - .deviceCount = deviceCnt, - .channelCountPerDevice = channelCount, - .leAudioCodecCapabilities = - UnicastCapability::LeAudioCodecCapabilities(capability), - }; -} - -std::vector -BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities( - const SessionType& session_type) { - if (session_type != - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && - session_type != - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH && - session_type != - SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { - return std::vector(0); - } - - if (kDefaultOffloadLeAudioCapabilities.empty()) { - for (auto [audioLocation, deviceCnt, channelCount] : - supportedDeviceSetting) { - for (auto capability : supportedLc3CapabilityList) { - UnicastCapability lc3Capability = composeUnicastLc3Capability( - audioLocation, deviceCnt, channelCount, capability); - UnicastCapability lc3MonoDecodeCapability = - composeUnicastLc3Capability(monoAudio, 1, 1, capability); - - // Adds the capability for encode only - kDefaultOffloadLeAudioCapabilities.push_back( - {.unicastEncodeCapability = lc3Capability, - .unicastDecodeCapability = kInvalidUnicastCapability, - .broadcastCapability = kInvalidBroadcastCapability}); - - // Adds the capability for decode only - kDefaultOffloadLeAudioCapabilities.push_back( - {.unicastEncodeCapability = kInvalidUnicastCapability, - .unicastDecodeCapability = lc3Capability, - .broadcastCapability = kInvalidBroadcastCapability}); - - // Adds the capability for the case that encode and decode exist at the - // same time - kDefaultOffloadLeAudioCapabilities.push_back( - {.unicastEncodeCapability = lc3Capability, - .unicastDecodeCapability = lc3MonoDecodeCapability, - .broadcastCapability = kInvalidBroadcastCapability}); - } - } - } - - return kDefaultOffloadLeAudioCapabilities; -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h deleted file mode 100644 index ed0598b..0000000 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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. - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class BluetoothAudioCodecs { - public: - static std::vector GetSoftwarePcmCapabilities(); - static std::vector GetA2dpOffloadCodecCapabilities( - const SessionType& session_type); - - static bool IsSoftwarePcmConfigurationValid( - const PcmConfiguration& pcm_config); - static bool IsOffloadCodecConfigurationValid( - const SessionType& session_type, const CodecConfiguration& codec_config); - - static bool IsOffloadLeAudioConfigurationValid( - const SessionType& session_type, const LeAudioConfiguration&); - - static std::vector - GetLeAudioOffloadCodecCapabilities(const SessionType& session_type); - - private: - template - struct identity { - typedef T type; - }; - template - static bool ContainedInVector(const std::vector& vector, - const typename identity::type& target); - template - static bool ContainedInBitmask(const T& bitmask, const T& target); - static bool IsSingleBit(uint32_t bitmasks, uint32_t bitfield); - static bool IsOffloadSbcConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); - static bool IsOffloadAacConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); - static bool IsOffloadLdacConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); - static bool IsOffloadAptxConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); - static bool IsOffloadAptxHdConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); - static bool IsOffloadOpusConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp deleted file mode 100644 index 3214bf2..0000000 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp +++ /dev/null @@ -1,618 +0,0 @@ -/* - * 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. - * 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. - */ - -#include -#define LOG_TAG "BTAudioSessionAidl" - -#include -#include -#include - -#include "BluetoothAudioSession.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending -static constexpr int kFmqReceiveTimeoutMs = - 1000; // 1000 ms timeout for receiving -static constexpr int kWritePollMs = 1; // polled non-blocking interval -static constexpr int kReadPollMs = 1; // polled non-blocking interval - -BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type) - : session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) {} - -/*** - * - * Callback methods - * - ***/ - -void BluetoothAudioSession::OnSessionStarted( - const std::shared_ptr stack_iface, - const DataMQDesc* mq_desc, const AudioConfiguration& audio_config, - const std::vector& latency_modes) { - std::lock_guard guard(mutex_); - if (stack_iface == nullptr) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) - << ", IBluetoothAudioPort Invalid"; - } else if (!UpdateAudioConfig(audio_config)) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) - << ", AudioConfiguration=" << audio_config.toString() - << " Invalid"; - } else if (!UpdateDataPath(mq_desc)) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) - << " MqDescriptor Invalid"; - audio_config_ = nullptr; - } else { - stack_iface_ = stack_iface; - latency_modes_ = latency_modes; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << ", AudioConfiguration=" << audio_config.toString(); - ReportSessionStatus(); - } -} - -void BluetoothAudioSession::OnSessionEnded() { - std::lock_guard guard(mutex_); - bool toggled = IsSessionReady(); - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); - audio_config_ = nullptr; - stack_iface_ = nullptr; - UpdateDataPath(nullptr); - if (toggled) { - ReportSessionStatus(); - } -} - -/*** - * - * Util methods - * - ***/ - -const AudioConfiguration BluetoothAudioSession::GetAudioConfig() { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - switch (session_type_) { - case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: - return AudioConfiguration(CodecConfiguration{}); - case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: - return AudioConfiguration(LeAudioConfiguration{}); - case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - return AudioConfiguration(LeAudioBroadcastConfiguration{}); - default: - return AudioConfiguration(PcmConfiguration{}); - } - } - return *audio_config_; -} - -void BluetoothAudioSession::ReportAudioConfigChanged( - const AudioConfiguration& audio_config) { - if (session_type_ != - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && - session_type_ != - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - return; - } - std::lock_guard guard(mutex_); - audio_config_ = std::make_unique(audio_config); - if (observers_.empty()) { - LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO port state observer"; - return; - } - for (auto& observer : observers_) { - uint16_t cookie = observer.first; - std::shared_ptr cb = observer.second; - LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_) - << ", bluetooth_audio=0x" - << ::android::base::StringPrintf("%04x", cookie); - if (cb->audio_configuration_changed_cb_ != nullptr) { - cb->audio_configuration_changed_cb_(cookie); - } - } -} - -bool BluetoothAudioSession::IsSessionReady() { - std::lock_guard guard(mutex_); - - bool is_mq_valid = - (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type_ == - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type_ == - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || - session_type_ == - SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH || - (data_mq_ != nullptr && data_mq_->isValid())); - return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr; -} - -/*** - * - * Status callback methods - * - ***/ - -uint16_t BluetoothAudioSession::RegisterStatusCback( - const PortStatusCallbacks& callbacks) { - std::lock_guard guard(mutex_); - uint16_t cookie = ObserversCookieGetInitValue(session_type_); - uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_); - - while (cookie < cookie_upper_bound) { - if (observers_.find(cookie) == observers_.end()) { - break; - } - ++cookie; - } - if (cookie >= cookie_upper_bound) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) - << " has " << observers_.size() - << " observers already (No Resource)"; - return kObserversCookieUndefined; - } - std::shared_ptr cb = - std::make_shared(); - *cb = callbacks; - observers_[cookie] = cb; - return cookie; -} - -void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) { - std::lock_guard guard(mutex_); - if (observers_.erase(cookie) != 1) { - LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) - << " no such provider=0x" - << ::android::base::StringPrintf("%04x", cookie); - } -} - -/*** - * - * Stream methods - * - ***/ - -bool BluetoothAudioSession::StartStream(bool is_low_latency) { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return false; - } - auto hal_retval = stack_iface_->startStream(is_low_latency); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - return false; - } - return true; -} - -bool BluetoothAudioSession::SuspendStream() { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return false; - } - auto hal_retval = stack_iface_->suspendStream(); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - return false; - } - return true; -} - -void BluetoothAudioSession::StopStream() { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - return; - } - auto hal_retval = stack_iface_->stopStream(); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - } -} - -/*** - * - * Private methods - * - ***/ - -bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) { - if (mq_desc == nullptr) { - // usecase of reset by nullptr - data_mq_ = nullptr; - return true; - } - std::unique_ptr temp_mq; - temp_mq.reset(new DataMQ(*mq_desc)); - if (!temp_mq || !temp_mq->isValid()) { - data_mq_ = nullptr; - return false; - } - data_mq_ = std::move(temp_mq); - return true; -} - -bool BluetoothAudioSession::UpdateAudioConfig( - const AudioConfiguration& audio_config) { - bool is_software_session = - (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH || - session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH || - session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH || - session_type_ == - SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH || - session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH); - bool is_offload_a2dp_session = - (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH); - bool is_offload_le_audio_session = - (session_type_ == - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type_ == - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH); - auto audio_config_tag = audio_config.getTag(); - bool is_software_audio_config = - (is_software_session && - audio_config_tag == AudioConfiguration::pcmConfig); - bool is_a2dp_offload_audio_config = - (is_offload_a2dp_session && - audio_config_tag == AudioConfiguration::a2dpConfig); - bool is_le_audio_offload_audio_config = - (is_offload_le_audio_session && - audio_config_tag == AudioConfiguration::leAudioConfig); - if (!is_software_audio_config && !is_a2dp_offload_audio_config && - !is_le_audio_offload_audio_config) { - return false; - } - audio_config_ = std::make_unique(audio_config); - return true; -} - -void BluetoothAudioSession::ReportSessionStatus() { - // This is locked already by OnSessionStarted / OnSessionEnded - if (observers_.empty()) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO port state observer"; - return; - } - for (auto& observer : observers_) { - uint16_t cookie = observer.first; - std::shared_ptr callback = observer.second; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << " notify to bluetooth_audio=0x" - << ::android::base::StringPrintf("%04x", cookie); - callback->session_changed_cb_(cookie); - } -} - -/*** - * - * PCM methods - * - ***/ - -size_t BluetoothAudioSession::OutWritePcmData(const void* buffer, - size_t bytes) { - if (buffer == nullptr || bytes <= 0) { - return 0; - } - size_t total_written = 0; - int timeout_ms = kFmqSendTimeoutMs; - do { - std::unique_lock lock(mutex_); - if (!IsSessionReady()) { - break; - } - size_t num_bytes_to_write = data_mq_->availableToWrite(); - if (num_bytes_to_write) { - if (num_bytes_to_write > (bytes - total_written)) { - num_bytes_to_write = bytes - total_written; - } - - if (!data_mq_->write( - static_cast(buffer) + total_written, - num_bytes_to_write)) { - LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes - << " failed"; - return total_written; - } - total_written += num_bytes_to_write; - } else if (timeout_ms >= kWritePollMs) { - lock.unlock(); - usleep(kWritePollMs * 1000); - timeout_ms -= kWritePollMs; - } else { - LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow " - << (kFmqSendTimeoutMs - timeout_ms) << " ms"; - return total_written; - } - } while (total_written < bytes); - return total_written; -} - -size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) { - if (buffer == nullptr || bytes <= 0) { - return 0; - } - size_t total_read = 0; - int timeout_ms = kFmqReceiveTimeoutMs; - do { - std::unique_lock lock(mutex_); - if (!IsSessionReady()) { - break; - } - size_t num_bytes_to_read = data_mq_->availableToRead(); - if (num_bytes_to_read) { - if (num_bytes_to_read > (bytes - total_read)) { - num_bytes_to_read = bytes - total_read; - } - if (!data_mq_->read(static_cast(buffer) + total_read, - num_bytes_to_read)) { - LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes - << " failed"; - return total_read; - } - total_read += num_bytes_to_read; - } else if (timeout_ms >= kReadPollMs) { - lock.unlock(); - usleep(kReadPollMs * 1000); - timeout_ms -= kReadPollMs; - continue; - } else { - LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow " - << (kFmqReceiveTimeoutMs - timeout_ms) << " ms"; - return total_read; - } - } while (total_read < bytes); - return total_read; -} - -/*** - * - * Other methods - * - ***/ - -void BluetoothAudioSession::ReportControlStatus(bool start_resp, - BluetoothAudioStatus status) { - std::lock_guard guard(mutex_); - if (observers_.empty()) { - LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO port state observer"; - return; - } - for (auto& observer : observers_) { - uint16_t cookie = observer.first; - std::shared_ptr callback = observer.second; - LOG(INFO) << __func__ << " - status=" << toString(status) - << " for SessionType=" << toString(session_type_) - << ", bluetooth_audio=0x" - << ::android::base::StringPrintf("%04x", cookie) - << (start_resp ? " started" : " suspended"); - callback->control_result_cb_(cookie, start_resp, status); - } -} - -void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) { - std::lock_guard guard(mutex_); - low_latency_allowed_ = allowed; - if (observers_.empty()) { - LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO port state observer"; - return; - } - for (auto& observer : observers_) { - uint16_t cookie = observer.first; - std::shared_ptr callback = observer.second; - LOG(INFO) << __func__ - << " - allowed=" << (allowed ? " allowed" : " disallowed"); - if (callback->low_latency_mode_allowed_cb_ != nullptr) { - callback->low_latency_mode_allowed_cb_(cookie, allowed); - } - } -} - -bool BluetoothAudioSession::GetPresentationPosition( - PresentationPosition& presentation_position) { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return false; - } - bool retval = false; - - if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - return false; - } - return retval; -} - -void BluetoothAudioSession::UpdateSourceMetadata( - const struct source_metadata& source_metadata) { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return; - } - - ssize_t track_count = source_metadata.track_count; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << "," - << track_count << " track(s)"; - if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH || - session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - return; - } - - SourceMetadata hal_source_metadata; - hal_source_metadata.tracks.resize(track_count); - for (int i = 0; i < track_count; i++) { - hal_source_metadata.tracks[i].usage = - static_cast( - source_metadata.tracks[i].usage); - hal_source_metadata.tracks[i].contentType = - static_cast( - source_metadata.tracks[i].content_type); - hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain; - LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_) - << ", usage=" << toString(hal_source_metadata.tracks[i].usage) - << ", content=" - << toString(hal_source_metadata.tracks[i].contentType) - << ", gain=" << hal_source_metadata.tracks[i].gain; - } - - auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - } -} - -void BluetoothAudioSession::UpdateSinkMetadata( - const struct sink_metadata& sink_metadata) { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return; - } - - ssize_t track_count = sink_metadata.track_count; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << "," - << track_count << " track(s)"; - if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH || - session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - return; - } - - SinkMetadata hal_sink_metadata; - hal_sink_metadata.tracks.resize(track_count); - for (int i = 0; i < track_count; i++) { - hal_sink_metadata.tracks[i].source = - static_cast( - sink_metadata.tracks[i].source); - hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << ", source=" << sink_metadata.tracks[i].source - << ", dest_device=" << sink_metadata.tracks[i].dest_device - << ", gain=" << sink_metadata.tracks[i].gain - << ", dest_device_address=" - << sink_metadata.tracks[i].dest_device_address; - } - - auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - } -} - -std::vector BluetoothAudioSession::GetSupportedLatencyModes() { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return std::vector(); - } - if (low_latency_allowed_) return latency_modes_; - std::vector modes; - for (LatencyMode mode : latency_modes_) { - if (mode == LatencyMode::LOW_LATENCY) - // ignore those low latency mode if Bluetooth stack doesn't allow - continue; - modes.push_back(mode); - } - return modes; -} - -void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) { - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return; - } - - auto hal_retval = stack_iface_->setLatencyMode(latency_mode); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - } -} - -bool BluetoothAudioSession::IsAidlAvailable() { - if (is_aidl_checked) return is_aidl_available; - is_aidl_available = - (AServiceManager_checkService( - kDefaultAudioProviderFactoryInterface.c_str()) != nullptr); - is_aidl_checked = true; - return is_aidl_available; -} - -/*** - * - * BluetoothAudioSessionInstance - * - ***/ -std::mutex BluetoothAudioSessionInstance::mutex_; -std::unordered_map> - BluetoothAudioSessionInstance::sessions_map_; - -std::shared_ptr -BluetoothAudioSessionInstance::GetSessionInstance( - const SessionType& session_type) { - std::lock_guard guard(mutex_); - - if (!sessions_map_.empty()) { - auto entry = sessions_map_.find(session_type); - if (entry != sessions_map_.end()) { - return entry->second; - } - } - std::shared_ptr session_ptr = - std::make_shared(session_type); - sessions_map_[session_type] = session_ptr; - return session_ptr; -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h deleted file mode 100644 index bdfaf36..0000000 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * 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. - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -using ::aidl::android::hardware::common::fmq::MQDescriptor; -using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; -using ::android::AidlMessageQueue; - -using ::aidl::android::hardware::audio::common::SinkMetadata; -using ::aidl::android::hardware::audio::common::SourceMetadata; - -using MQDataType = int8_t; -using MQDataMode = SynchronizedReadWrite; -using DataMQ = AidlMessageQueue; -using DataMQDesc = - ::aidl::android::hardware::common::fmq::MQDescriptor; - -static constexpr uint16_t kObserversCookieSize = 0x0010; // 0x0000 ~ 0x000f -static constexpr uint16_t kObserversCookieUndefined = - (static_cast(SessionType::UNKNOWN) << 8 & 0xff00); -inline SessionType ObserversCookieGetSessionType(uint16_t cookie) { - return static_cast(cookie >> 8 & 0x00ff); -} -inline uint16_t ObserversCookieGetInitValue(SessionType session_type) { - return (static_cast(session_type) << 8 & 0xff00); -} -inline uint16_t ObserversCookieGetUpperBound(SessionType session_type) { - return (static_cast(session_type) << 8 & 0xff00) + - kObserversCookieSize; -} - -/*** - * This presents the callbacks of started / suspended and session changed, - * and the bluetooth_audio module uses to receive the status notification - ***/ -struct PortStatusCallbacks { - /*** - * control_result_cb_ - when the Bluetooth stack reports results of - * streamStarted or streamSuspended, the BluetoothAudioProvider will invoke - * this callback to report to the bluetooth_audio module. - * @param: cookie - indicates which bluetooth_audio output should handle - * @param: start_resp - this report is for startStream or not - * @param: status - the result of startStream - ***/ - std::function - control_result_cb_; - /*** - * session_changed_cb_ - when the Bluetooth stack start / end session, the - * BluetoothAudioProvider will invoke this callback to notify to the - * bluetooth_audio module. - * @param: cookie - indicates which bluetooth_audio output should handle - ***/ - std::function session_changed_cb_; - /*** - * audio_configuration_changed_cb_ - when the Bluetooth stack change the audio - * configuration, the BluetoothAudioProvider will invoke this callback to - * notify to the bluetooth_audio module. - * @param: cookie - indicates which bluetooth_audio output should handle - ***/ - std::function audio_configuration_changed_cb_; - /*** - * low_latency_mode_allowed_cb_ - when the Bluetooth stack low latency mode - * allowed or disallowed, the BluetoothAudioProvider will invoke - * this callback to report to the bluetooth_audio module. - * @param: cookie - indicates which bluetooth_audio output should handle - * @param: allowed - indicates if low latency mode is allowed - ***/ - std::function - low_latency_mode_allowed_cb_; -}; - -class BluetoothAudioSession { - public: - BluetoothAudioSession(const SessionType& session_type); - - /*** - * The function helps to check if this session is ready or not - * @return: true if the Bluetooth stack has started the specified session - ***/ - bool IsSessionReady(); - - /*** - * The report function is used to report that the Bluetooth stack has started - * this session without any failure, and will invoke session_changed_cb_ to - * notify those registered bluetooth_audio outputs - ***/ - void OnSessionStarted(const std::shared_ptr stack_iface, - const DataMQDesc* mq_desc, - const AudioConfiguration& audio_config, - const std::vector& latency_modes); - - /*** - * The report function is used to report that the Bluetooth stack has ended - * the session, and will invoke session_changed_cb_ to notify registered - * bluetooth_audio outputs - ***/ - void OnSessionEnded(); - - /*** - * The report function is used to report that the Bluetooth stack has notified - * the result of startStream or suspendStream, and will invoke - * control_result_cb_ to notify registered bluetooth_audio outputs - ***/ - void ReportControlStatus(bool start_resp, BluetoothAudioStatus status); - - /*** - * The control function helps the bluetooth_audio module to register - * PortStatusCallbacks - * @return: cookie - the assigned number to this bluetooth_audio output - ***/ - uint16_t RegisterStatusCback(const PortStatusCallbacks& cbacks); - - /*** - * The control function helps the bluetooth_audio module to unregister - * PortStatusCallbacks - * @param: cookie - indicates which bluetooth_audio output is - ***/ - void UnregisterStatusCback(uint16_t cookie); - - /*** - * The control function is for the bluetooth_audio module to get the current - * AudioConfiguration - ***/ - const AudioConfiguration GetAudioConfig(); - - /*** - * The report function is used to report that the Bluetooth stack has notified - * the audio configuration changed, and will invoke - * audio_configuration_changed_cb_ to notify registered bluetooth_audio - * outputs - ***/ - void ReportAudioConfigChanged(const AudioConfiguration& audio_config); - - /*** - * The report function is used to report that the Bluetooth stack has notified - * the low latency mode allowed changed, and will invoke - * low_latency_mode_allowed_changed_cb to notify registered bluetooth_audio - * outputs - ***/ - void ReportLowLatencyModeAllowedChanged(bool allowed); - /*** - * Those control functions are for the bluetooth_audio module to start, - * suspend, stop stream, to check position, and to update metadata. - ***/ - bool StartStream(bool low_latency); - bool SuspendStream(); - void StopStream(); - bool GetPresentationPosition(PresentationPosition& presentation_position); - void UpdateSourceMetadata(const struct source_metadata& source_metadata); - void UpdateSinkMetadata(const struct sink_metadata& sink_metadata); - - std::vector GetSupportedLatencyModes(); - void SetLatencyMode(const LatencyMode& latency_mode); - - // The control function writes stream to FMQ - size_t OutWritePcmData(const void* buffer, size_t bytes); - // The control function read stream from FMQ - size_t InReadPcmData(void* buffer, size_t bytes); - - // Return if IBluetoothAudioProviderFactory implementation existed - static bool IsAidlAvailable(); - - private: - // using recursive_mutex to allow hwbinder to re-enter again. - std::recursive_mutex mutex_; - SessionType session_type_; - - // audio control path to use for both software and offloading - std::shared_ptr stack_iface_; - // audio data path (FMQ) for software encoding - std::unique_ptr data_mq_; - // audio data configuration for both software and offloading - std::unique_ptr audio_config_; - std::vector latency_modes_; - bool low_latency_allowed_ = true; - - // saving those registered bluetooth_audio's callbacks - std::unordered_map> - observers_; - - bool UpdateDataPath(const DataMQDesc* mq_desc); - bool UpdateAudioConfig(const AudioConfiguration& audio_config); - // invoking the registered session_changed_cb_ - void ReportSessionStatus(); - - static inline std::atomic is_aidl_checked = false; - static inline std::atomic is_aidl_available = false; - static inline const std::string kDefaultAudioProviderFactoryInterface = - std::string() + IBluetoothAudioProviderFactory::descriptor + "/sysbta"; -}; - -class BluetoothAudioSessionInstance { - public: - // The API is to fetch the specified session of A2DP / Hearing Aid - static std::shared_ptr GetSessionInstance( - const SessionType& session_type); - - private: - static std::mutex mutex_; - static std::unordered_map> - sessions_map_; -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h deleted file mode 100644 index 0782c82..0000000 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2018 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 "BluetoothAudioSession.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class BluetoothAudioSessionControl { - public: - /*** - * The control API helps to check if session is ready or not - * @return: true if the Bluetooth stack has started th specified session - ***/ - static bool IsSessionReady(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->IsSessionReady(); - } - - return false; - } - - /*** - * The control API helps the bluetooth_audio module to register - * PortStatusCallbacks - * @return: cookie - the assigned number to this bluetooth_audio output - ***/ - static uint16_t RegisterControlResultCback( - const SessionType& session_type, const PortStatusCallbacks& cbacks) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->RegisterStatusCback(cbacks); - } - return kObserversCookieUndefined; - } - - /*** - * The control API helps the bluetooth_audio module to unregister - * PortStatusCallbacks - * @param: cookie - indicates which bluetooth_audio output is - ***/ - static void UnregisterControlResultCback(const SessionType& session_type, - uint16_t cookie) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->UnregisterStatusCback(cookie); - } - } - - /*** - * The control API for the bluetooth_audio module to get current - * AudioConfiguration - ***/ - static const AudioConfiguration GetAudioConfig( - const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioConfig(); - } - switch (session_type) { - case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH: - return AudioConfiguration(CodecConfiguration{}); - case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH: - return AudioConfiguration(LeAudioConfiguration{}); - case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: - return AudioConfiguration(LeAudioBroadcastConfiguration{}); - default: - return AudioConfiguration(PcmConfiguration{}); - } - } - - /*** - * Those control APIs for the bluetooth_audio module to start / suspend / - stop - * stream, to check position, and to update metadata. - ***/ - static bool StartStream(const SessionType& session_type, - bool low_latency = false) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->StartStream(low_latency); - } - return false; - } - - static bool SuspendStream(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->SuspendStream(); - } - return false; - } - - static void StopStream(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->StopStream(); - } - } - - static bool GetPresentationPosition( - const SessionType& session_type, - PresentationPosition& presentation_position) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetPresentationPosition(presentation_position); - } - return false; - } - - static void UpdateSourceMetadata( - const SessionType& session_type, - const struct source_metadata& source_metadata) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->UpdateSourceMetadata(source_metadata); - } - } - - static void UpdateSinkMetadata(const SessionType& session_type, - const struct sink_metadata& sink_metadata) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->UpdateSinkMetadata(sink_metadata); - } - } - - static std::vector GetSupportedLatencyModes( - const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetSupportedLatencyModes(); - } - return std::vector(); - } - - static void SetLatencyMode(const SessionType& session_type, - const LatencyMode& latency_mode) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->SetLatencyMode(latency_mode); - } - } - - /*** - * The control API writes stream to FMQ - ***/ - static size_t OutWritePcmData(const SessionType& session_type, - const void* buffer, size_t bytes) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->OutWritePcmData(buffer, bytes); - } - return 0; - } - - /*** - * The control API reads stream from FMQ - ***/ - static size_t InReadPcmData(const SessionType& session_type, void* buffer, - size_t bytes) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->InReadPcmData(buffer, bytes); - } - return 0; - } -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h deleted file mode 100644 index 0350259..0000000 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - * 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 "BluetoothAudioSession.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -class BluetoothAudioSessionReport { - public: - /*** - * The API reports the Bluetooth stack has started the session, and will - * inform registered bluetooth_audio outputs - ***/ - static void OnSessionStarted( - const SessionType& session_type, - const std::shared_ptr host_iface, - const DataMQDesc* data_mq, const AudioConfiguration& audio_config, - const std::vector& latency_modes) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->OnSessionStarted(host_iface, data_mq, audio_config, - latency_modes); - } - } - - /*** - * The API reports the Bluetooth stack has ended the session, and will - * inform registered bluetooth_audio outputs - ***/ - static void OnSessionEnded(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->OnSessionEnded(); - } - } - - /*** - * The API reports the Bluetooth stack has replied the result of startStream - * or suspendStream, and will inform registered bluetooth_audio outputs - ***/ - static void ReportControlStatus(const SessionType& session_type, - const bool& start_resp, - BluetoothAudioStatus status) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->ReportControlStatus(start_resp, status); - } - } - /*** - * The API reports the Bluetooth stack has replied the changed of the audio - * configuration, and will inform registered bluetooth_audio outputs - ***/ - static void ReportAudioConfigChanged(const SessionType& session_type, - const AudioConfiguration& audio_config) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->ReportAudioConfigChanged(audio_config); - } - } - /*** - * The API reports the Bluetooth stack has replied the changed of the low - * latency audio allowed, and will inform registered bluetooth_audio outputs - ***/ - static void ReportLowLatencyModeAllowedChanged( - const SessionType& session_type, bool allowed) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->ReportLowLatencyModeAllowedChanged(allowed); - } - } -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp deleted file mode 100644 index a4664f1..0000000 --- a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/* - * 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. - * 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. - */ - -#define LOG_TAG "BtAudioNakahara" - -#include -#include -#include -#include - -#include -#include - -#include "../aidl_session/BluetoothAudioSession.h" -#include "../aidl_session/BluetoothAudioSessionControl.h" -#include "HidlToAidlMiddleware_2_0.h" -#include "HidlToAidlMiddleware_2_1.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -using HidlStatus = ::android::hardware::bluetooth::audio::V2_0::Status; -using PcmConfig_2_0 = - ::android::hardware::bluetooth::audio::V2_0::PcmParameters; -using SampleRate_2_0 = ::android::hardware::bluetooth::audio::V2_0::SampleRate; -using ChannelMode_2_0 = - ::android::hardware::bluetooth::audio::V2_0::ChannelMode; -using BitsPerSample_2_0 = - ::android::hardware::bluetooth::audio::V2_0::BitsPerSample; -using CodecConfig_2_0 = - ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration; -using CodecType_2_0 = ::android::hardware::bluetooth::audio::V2_0::CodecType; -using SbcConfig_2_0 = - ::android::hardware::bluetooth::audio::V2_0::SbcParameters; -using AacConfig_2_0 = - ::android::hardware::bluetooth::audio::V2_0::AacParameters; -using LdacConfig_2_0 = - ::android::hardware::bluetooth::audio::V2_0::LdacParameters; -using AptxConfig_2_0 = - ::android::hardware::bluetooth::audio::V2_0::AptxParameters; -using SbcAllocMethod_2_0 = - ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod; -using SbcBlockLength_2_0 = - ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength; -using SbcChannelMode_2_0 = - ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode; -using SbcNumSubbands_2_0 = - ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands; -using AacObjectType_2_0 = - ::android::hardware::bluetooth::audio::V2_0::AacObjectType; -using AacVarBitRate_2_0 = - ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate; -using LdacChannelMode_2_0 = - ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode; -using LdacQualityIndex_2_0 = - ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex; - -using PcmConfig_2_1 = - ::android::hardware::bluetooth::audio::V2_1::PcmParameters; -using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate; -using Lc3CodecConfig_2_1 = - ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration; -using Lc3Config_2_1 = - ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters; -using Lc3FrameDuration_2_1 = - ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration; - -std::mutex legacy_callback_lock; -std::unordered_map< - SessionType, - std::unordered_map>> - legacy_callback_table; - -const static std::unordered_map - session_type_2_1_to_aidl_map{ - {SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH, - SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH}, - {SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH, - SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH}, - {SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, - SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH}, - {SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH, - SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH}, - {SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH, - SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH}, - {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH, - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH}, - {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH, - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH}, - }; - -const static std::unordered_map - sample_rate_to_hidl_2_1_map{ - {44100, SampleRate_2_1::RATE_44100}, - {48000, SampleRate_2_1::RATE_48000}, - {88200, SampleRate_2_1::RATE_88200}, - {96000, SampleRate_2_1::RATE_96000}, - {176400, SampleRate_2_1::RATE_176400}, - {192000, SampleRate_2_1::RATE_192000}, - {16000, SampleRate_2_1::RATE_16000}, - {24000, SampleRate_2_1::RATE_24000}, - {8000, SampleRate_2_1::RATE_8000}, - {32000, SampleRate_2_1::RATE_32000}, - }; - -const static std::unordered_map - codec_type_to_hidl_2_0_map{ - {CodecType::UNKNOWN, CodecType_2_0::UNKNOWN}, - {CodecType::SBC, CodecType_2_0::SBC}, - {CodecType::AAC, CodecType_2_0::AAC}, - {CodecType::APTX, CodecType_2_0::APTX}, - {CodecType::APTX_HD, CodecType_2_0::APTX_HD}, - {CodecType::LDAC, CodecType_2_0::LDAC}, - {CodecType::LC3, CodecType_2_0::UNKNOWN}, - }; - -const static std::unordered_map - sbc_channel_mode_to_hidl_2_0_map{ - {SbcChannelMode::UNKNOWN, SbcChannelMode_2_0::UNKNOWN}, - {SbcChannelMode::JOINT_STEREO, SbcChannelMode_2_0::JOINT_STEREO}, - {SbcChannelMode::STEREO, SbcChannelMode_2_0::STEREO}, - {SbcChannelMode::DUAL, SbcChannelMode_2_0::DUAL}, - {SbcChannelMode::MONO, SbcChannelMode_2_0::MONO}, - }; - -const static std::unordered_map - sbc_block_length_to_hidl_map{ - {4, SbcBlockLength_2_0::BLOCKS_4}, - {8, SbcBlockLength_2_0::BLOCKS_8}, - {12, SbcBlockLength_2_0::BLOCKS_12}, - {16, SbcBlockLength_2_0::BLOCKS_16}, - }; - -const static std::unordered_map - sbc_subbands_to_hidl_map{ - {4, SbcNumSubbands_2_0::SUBBAND_4}, - {8, SbcNumSubbands_2_0::SUBBAND_8}, - }; - -const static std::unordered_map - sbc_alloc_method_to_hidl_map{ - {SbcAllocMethod::ALLOC_MD_S, SbcAllocMethod_2_0::ALLOC_MD_S}, - {SbcAllocMethod::ALLOC_MD_L, SbcAllocMethod_2_0::ALLOC_MD_L}, - }; - -const static std::unordered_map - aac_object_type_to_hidl_map{ - {AacObjectType::MPEG2_LC, AacObjectType_2_0::MPEG2_LC}, - {AacObjectType::MPEG4_LC, AacObjectType_2_0::MPEG4_LC}, - {AacObjectType::MPEG4_LTP, AacObjectType_2_0::MPEG4_LTP}, - {AacObjectType::MPEG4_SCALABLE, AacObjectType_2_0::MPEG4_SCALABLE}, - }; - -const static std::unordered_map - ldac_channel_mode_to_hidl_map{ - {LdacChannelMode::UNKNOWN, LdacChannelMode_2_0::UNKNOWN}, - {LdacChannelMode::STEREO, LdacChannelMode_2_0::STEREO}, - {LdacChannelMode::DUAL, LdacChannelMode_2_0::DUAL}, - {LdacChannelMode::MONO, LdacChannelMode_2_0::MONO}, - }; - -const static std::unordered_map - ldac_qindex_to_hidl_map{ - {LdacQualityIndex::HIGH, LdacQualityIndex_2_0::QUALITY_HIGH}, - {LdacQualityIndex::MID, LdacQualityIndex_2_0::QUALITY_MID}, - {LdacQualityIndex::LOW, LdacQualityIndex_2_0::QUALITY_LOW}, - {LdacQualityIndex::ABR, LdacQualityIndex_2_0::QUALITY_ABR}, - }; - -inline SessionType from_session_type_2_1( - const SessionType_2_1& session_type_hidl) { - auto it = session_type_2_1_to_aidl_map.find(session_type_hidl); - if (it != session_type_2_1_to_aidl_map.end()) return it->second; - return SessionType::UNKNOWN; -} - -inline SessionType from_session_type_2_0( - const SessionType_2_0& session_type_hidl) { - return from_session_type_2_1(static_cast(session_type_hidl)); -} - -inline HidlStatus to_hidl_status(const BluetoothAudioStatus& status) { - switch (status) { - case BluetoothAudioStatus::SUCCESS: - return HidlStatus::SUCCESS; - case BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION: - return HidlStatus::UNSUPPORTED_CODEC_CONFIGURATION; - default: - return HidlStatus::FAILURE; - } -} - -inline SampleRate_2_1 to_hidl_sample_rate_2_1(const int32_t sample_rate_hz) { - auto it = sample_rate_to_hidl_2_1_map.find(sample_rate_hz); - if (it != sample_rate_to_hidl_2_1_map.end()) return it->second; - return SampleRate_2_1::RATE_UNKNOWN; -} - -inline SampleRate_2_0 to_hidl_sample_rate_2_0(const int32_t sample_rate_hz) { - auto it = sample_rate_to_hidl_2_1_map.find(sample_rate_hz); - if (it != sample_rate_to_hidl_2_1_map.end()) - return static_cast(it->second); - return SampleRate_2_0::RATE_UNKNOWN; -} - -inline BitsPerSample_2_0 to_hidl_bits_per_sample(const int8_t bit_per_sample) { - switch (bit_per_sample) { - case 16: - return BitsPerSample_2_0::BITS_16; - case 24: - return BitsPerSample_2_0::BITS_24; - case 32: - return BitsPerSample_2_0::BITS_32; - default: - return BitsPerSample_2_0::BITS_UNKNOWN; - } -} - -inline ChannelMode_2_0 to_hidl_channel_mode(const ChannelMode channel_mode) { - switch (channel_mode) { - case ChannelMode::MONO: - return ChannelMode_2_0::MONO; - case ChannelMode::STEREO: - return ChannelMode_2_0::STEREO; - default: - return ChannelMode_2_0::UNKNOWN; - } -} - -inline PcmConfig_2_0 to_hidl_pcm_config_2_0( - const PcmConfiguration& pcm_config) { - PcmConfig_2_0 hidl_pcm_config; - hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_0(pcm_config.sampleRateHz); - hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode); - hidl_pcm_config.bitsPerSample = - to_hidl_bits_per_sample(pcm_config.bitsPerSample); - return hidl_pcm_config; -} - -inline CodecType_2_0 to_hidl_codec_type_2_0(const CodecType codec_type) { - auto it = codec_type_to_hidl_2_0_map.find(codec_type); - if (it != codec_type_to_hidl_2_0_map.end()) return it->second; - return CodecType_2_0::UNKNOWN; -} - -inline SbcConfig_2_0 to_hidl_sbc_config(const SbcConfiguration sbc_config) { - SbcConfig_2_0 hidl_sbc_config; - hidl_sbc_config.minBitpool = sbc_config.minBitpool; - hidl_sbc_config.maxBitpool = sbc_config.maxBitpool; - hidl_sbc_config.sampleRate = to_hidl_sample_rate_2_0(sbc_config.sampleRateHz); - hidl_sbc_config.bitsPerSample = - to_hidl_bits_per_sample(sbc_config.bitsPerSample); - if (sbc_channel_mode_to_hidl_2_0_map.find(sbc_config.channelMode) != - sbc_channel_mode_to_hidl_2_0_map.end()) { - hidl_sbc_config.channelMode = - sbc_channel_mode_to_hidl_2_0_map.at(sbc_config.channelMode); - } - if (sbc_block_length_to_hidl_map.find(sbc_config.blockLength) != - sbc_block_length_to_hidl_map.end()) { - hidl_sbc_config.blockLength = - sbc_block_length_to_hidl_map.at(sbc_config.blockLength); - } - if (sbc_subbands_to_hidl_map.find(sbc_config.numSubbands) != - sbc_subbands_to_hidl_map.end()) { - hidl_sbc_config.numSubbands = - sbc_subbands_to_hidl_map.at(sbc_config.numSubbands); - } - if (sbc_alloc_method_to_hidl_map.find(sbc_config.allocMethod) != - sbc_alloc_method_to_hidl_map.end()) { - hidl_sbc_config.allocMethod = - sbc_alloc_method_to_hidl_map.at(sbc_config.allocMethod); - } - return hidl_sbc_config; -} - -inline AacConfig_2_0 to_hidl_aac_config(const AacConfiguration aac_config) { - AacConfig_2_0 hidl_aac_config; - hidl_aac_config.sampleRate = to_hidl_sample_rate_2_0(aac_config.sampleRateHz); - hidl_aac_config.bitsPerSample = - to_hidl_bits_per_sample(aac_config.bitsPerSample); - hidl_aac_config.channelMode = to_hidl_channel_mode(aac_config.channelMode); - if (aac_object_type_to_hidl_map.find(aac_config.objectType) != - aac_object_type_to_hidl_map.end()) { - hidl_aac_config.objectType = - aac_object_type_to_hidl_map.at(aac_config.objectType); - } - hidl_aac_config.variableBitRateEnabled = aac_config.variableBitRateEnabled - ? AacVarBitRate_2_0::ENABLED - : AacVarBitRate_2_0::DISABLED; - return hidl_aac_config; -} - -inline LdacConfig_2_0 to_hidl_ldac_config(const LdacConfiguration ldac_config) { - LdacConfig_2_0 hidl_ldac_config; - hidl_ldac_config.sampleRate = - to_hidl_sample_rate_2_0(ldac_config.sampleRateHz); - hidl_ldac_config.bitsPerSample = - to_hidl_bits_per_sample(ldac_config.bitsPerSample); - if (ldac_channel_mode_to_hidl_map.find(ldac_config.channelMode) != - ldac_channel_mode_to_hidl_map.end()) { - hidl_ldac_config.channelMode = - ldac_channel_mode_to_hidl_map.at(ldac_config.channelMode); - } - if (ldac_qindex_to_hidl_map.find(ldac_config.qualityIndex) != - ldac_qindex_to_hidl_map.end()) { - hidl_ldac_config.qualityIndex = - ldac_qindex_to_hidl_map.at(ldac_config.qualityIndex); - } - return hidl_ldac_config; -} - -inline AptxConfig_2_0 to_hidl_aptx_config(const AptxConfiguration aptx_config) { - AptxConfig_2_0 hidl_aptx_config; - hidl_aptx_config.sampleRate = - to_hidl_sample_rate_2_0(aptx_config.sampleRateHz); - hidl_aptx_config.bitsPerSample = - to_hidl_bits_per_sample(aptx_config.bitsPerSample); - hidl_aptx_config.channelMode = to_hidl_channel_mode(aptx_config.channelMode); - return hidl_aptx_config; -} - -inline CodecConfig_2_0 to_hidl_codec_config_2_0( - const CodecConfiguration& codec_config) { - CodecConfig_2_0 hidl_codec_config; - hidl_codec_config.codecType = to_hidl_codec_type_2_0(codec_config.codecType); - hidl_codec_config.encodedAudioBitrate = - static_cast(codec_config.encodedAudioBitrate); - hidl_codec_config.peerMtu = static_cast(codec_config.peerMtu); - hidl_codec_config.isScmstEnabled = codec_config.isScmstEnabled; - switch (codec_config.config.getTag()) { - case CodecConfiguration::CodecSpecific::sbcConfig: - hidl_codec_config.config.sbcConfig(to_hidl_sbc_config( - codec_config.config - .get())); - break; - case CodecConfiguration::CodecSpecific::aacConfig: - hidl_codec_config.config.aacConfig(to_hidl_aac_config( - codec_config.config - .get())); - break; - case CodecConfiguration::CodecSpecific::ldacConfig: - hidl_codec_config.config.ldacConfig(to_hidl_ldac_config( - codec_config.config - .get())); - break; - case CodecConfiguration::CodecSpecific::aptxConfig: - hidl_codec_config.config.aptxConfig(to_hidl_aptx_config( - codec_config.config - .get())); - break; - default: - break; - } - return hidl_codec_config; -} - -inline AudioConfig_2_0 to_hidl_audio_config_2_0( - const AudioConfiguration& audio_config) { - AudioConfig_2_0 hidl_audio_config; - if (audio_config.getTag() == AudioConfiguration::pcmConfig) { - hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_0( - audio_config.get())); - } else if (audio_config.getTag() == AudioConfiguration::a2dpConfig) { - hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( - audio_config.get())); - } - return hidl_audio_config; -} - -inline PcmConfig_2_1 to_hidl_pcm_config_2_1( - const PcmConfiguration& pcm_config) { - PcmConfig_2_1 hidl_pcm_config; - hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_1(pcm_config.sampleRateHz); - hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode); - hidl_pcm_config.bitsPerSample = - to_hidl_bits_per_sample(pcm_config.bitsPerSample); - hidl_pcm_config.dataIntervalUs = - static_cast(pcm_config.dataIntervalUs); - return hidl_pcm_config; -} - -inline Lc3Config_2_1 to_hidl_lc3_config_2_1( - const Lc3Configuration& lc3_config) { - Lc3Config_2_1 hidl_lc3_config; - hidl_lc3_config.pcmBitDepth = to_hidl_bits_per_sample(lc3_config.pcmBitDepth); - hidl_lc3_config.samplingFrequency = - to_hidl_sample_rate_2_1(lc3_config.samplingFrequencyHz); - if (lc3_config.samplingFrequencyHz == 10000) - hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_10000US; - else if (lc3_config.samplingFrequencyHz == 7500) - hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_7500US; - hidl_lc3_config.octetsPerFrame = - static_cast(lc3_config.octetsPerFrame); - hidl_lc3_config.blocksPerSdu = static_cast(lc3_config.blocksPerSdu); - return hidl_lc3_config; -} - -inline Lc3CodecConfig_2_1 to_hidl_leaudio_config_2_1( - const LeAudioConfiguration& unicast_config) { - Lc3CodecConfig_2_1 hidl_lc3_codec_config = { - .audioChannelAllocation = 0, - }; - if (unicast_config.leAudioCodecConfig.getTag() == - LeAudioCodecConfiguration::lc3Config) { - LOG(FATAL) << __func__ << ": unexpected codec type(vendor?)"; - } - auto& le_codec_config = unicast_config.leAudioCodecConfig - .get(); - - hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config); - - for (const auto& map : unicast_config.streamMap) { - hidl_lc3_codec_config.audioChannelAllocation |= map.audioChannelAllocation; - } - return hidl_lc3_codec_config; -} - -inline Lc3CodecConfig_2_1 to_hidl_leaudio_broadcast_config_2_1( - const LeAudioBroadcastConfiguration& broadcast_config) { - Lc3CodecConfig_2_1 hidl_lc3_codec_config = { - .audioChannelAllocation = 0, - }; - // NOTE: Broadcast is not officially supported in HIDL - if (broadcast_config.streamMap.empty()) { - return hidl_lc3_codec_config; - } - if (broadcast_config.streamMap[0].leAudioCodecConfig.getTag() != - LeAudioCodecConfiguration::lc3Config) { - LOG(FATAL) << __func__ << ": unexpected codec type(vendor?)"; - } - auto& le_codec_config = - broadcast_config.streamMap[0] - .leAudioCodecConfig.get(); - hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config); - - for (const auto& map : broadcast_config.streamMap) { - hidl_lc3_codec_config.audioChannelAllocation |= map.audioChannelAllocation; - } - return hidl_lc3_codec_config; -} - -inline AudioConfig_2_1 to_hidl_audio_config_2_1( - const AudioConfiguration& audio_config) { - AudioConfig_2_1 hidl_audio_config; - switch (audio_config.getTag()) { - case AudioConfiguration::pcmConfig: - hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1( - audio_config.get())); - break; - case AudioConfiguration::a2dpConfig: - hidl_audio_config.codecConfig(to_hidl_codec_config_2_0( - audio_config.get())); - break; - case AudioConfiguration::leAudioConfig: - hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1( - audio_config.get())); - break; - case AudioConfiguration::leAudioBroadcastConfig: - hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_broadcast_config_2_1( - audio_config.get())); - break; - } - return hidl_audio_config; -} - -/*** - * - * 2.0 - * - ***/ - -bool HidlToAidlMiddleware_2_0::IsSessionReady( - const SessionType_2_0& session_type) { - return BluetoothAudioSessionControl::IsSessionReady( - from_session_type_2_0(session_type)); -} - -uint16_t HidlToAidlMiddleware_2_0::RegisterControlResultCback( - const SessionType_2_0& session_type, - const PortStatusCallbacks_2_0& cbacks) { - LOG(INFO) << __func__ << ": " << toString(session_type); - auto aidl_session_type = from_session_type_2_0(session_type); - // Pass the exact reference to the lambda - auto& session_legacy_callback_table = - legacy_callback_table[aidl_session_type]; - PortStatusCallbacks aidl_callbacks{}; - if (cbacks.control_result_cb_) { - aidl_callbacks.control_result_cb_ = - [&session_legacy_callback_table](uint16_t cookie, bool start_resp, - const BluetoothAudioStatus& status) { - if (session_legacy_callback_table.find(cookie) == - session_legacy_callback_table.end()) { - LOG(ERROR) << __func__ << ": Unknown callback invoked!"; - return; - } - auto& cback = session_legacy_callback_table[cookie]; - cback->control_result_cb_(cookie, start_resp, to_hidl_status(status)); - }; - } - if (cbacks.session_changed_cb_) { - aidl_callbacks.session_changed_cb_ = - [&session_legacy_callback_table](uint16_t cookie) { - if (session_legacy_callback_table.find(cookie) == - session_legacy_callback_table.end()) { - LOG(ERROR) << __func__ << ": Unknown callback invoked!"; - return; - } - auto& cback = session_legacy_callback_table[cookie]; - cback->session_changed_cb_(cookie); - }; - }; - auto cookie = BluetoothAudioSessionControl::RegisterControlResultCback( - aidl_session_type, aidl_callbacks); - { - std::lock_guard guard(legacy_callback_lock); - session_legacy_callback_table[cookie] = - std::make_shared(cbacks); - } - return cookie; -} - -void HidlToAidlMiddleware_2_0::UnregisterControlResultCback( - const SessionType_2_0& session_type, uint16_t cookie) { - LOG(INFO) << __func__ << ": " << toString(session_type); - auto aidl_session_type = from_session_type_2_0(session_type); - BluetoothAudioSessionControl::UnregisterControlResultCback(aidl_session_type, - cookie); - auto& session_callback_table = legacy_callback_table[aidl_session_type]; - if (session_callback_table.find(cookie) != session_callback_table.end()) { - std::lock_guard guard(legacy_callback_lock); - session_callback_table.erase(cookie); - } -} - -const AudioConfig_2_0 HidlToAidlMiddleware_2_0::GetAudioConfig( - const SessionType_2_0& session_type) { - return to_hidl_audio_config_2_0(BluetoothAudioSessionControl::GetAudioConfig( - from_session_type_2_0(session_type))); -} - -bool HidlToAidlMiddleware_2_0::StartStream( - const SessionType_2_0& session_type) { - return BluetoothAudioSessionControl::StartStream( - from_session_type_2_0(session_type)); -} - -void HidlToAidlMiddleware_2_0::StopStream(const SessionType_2_0& session_type) { - return BluetoothAudioSessionControl::StopStream( - from_session_type_2_0(session_type)); -} - -bool HidlToAidlMiddleware_2_0::SuspendStream( - const SessionType_2_0& session_type) { - return BluetoothAudioSessionControl::SuspendStream( - from_session_type_2_0(session_type)); -} - -bool HidlToAidlMiddleware_2_0::GetPresentationPosition( - const SessionType_2_0& session_type, uint64_t* remote_delay_report_ns, - uint64_t* total_bytes_readed, timespec* data_position) { - PresentationPosition presentation_position; - auto ret_val = BluetoothAudioSessionControl::GetPresentationPosition( - from_session_type_2_0(session_type), presentation_position); - if (remote_delay_report_ns) - *remote_delay_report_ns = presentation_position.remoteDeviceAudioDelayNanos; - if (total_bytes_readed) - *total_bytes_readed = presentation_position.transmittedOctets; - if (data_position) - *data_position = { - .tv_sec = static_cast<__kernel_old_time_t>( - presentation_position.transmittedOctetsTimestamp.tvSec), - .tv_nsec = static_cast( - presentation_position.transmittedOctetsTimestamp.tvNSec)}; - return ret_val; -} - -void HidlToAidlMiddleware_2_0::UpdateTracksMetadata( - const SessionType_2_0& session_type, - const struct source_metadata* source_metadata) { - return BluetoothAudioSessionControl::UpdateSourceMetadata( - from_session_type_2_0(session_type), *source_metadata); -} - -size_t HidlToAidlMiddleware_2_0::OutWritePcmData( - const SessionType_2_0& session_type, const void* buffer, size_t bytes) { - return BluetoothAudioSessionControl::OutWritePcmData( - from_session_type_2_0(session_type), buffer, bytes); -} - -size_t HidlToAidlMiddleware_2_0::InReadPcmData( - const SessionType_2_0& session_type, void* buffer, size_t bytes) { - return BluetoothAudioSessionControl::InReadPcmData( - from_session_type_2_0(session_type), buffer, bytes); -} - -bool HidlToAidlMiddleware_2_0::IsAidlAvailable() { - return BluetoothAudioSession::IsAidlAvailable(); -} - -/*** - * - * 2.1 - * - ***/ - -const AudioConfig_2_1 HidlToAidlMiddleware_2_1::GetAudioConfig( - const SessionType_2_1& session_type) { - return to_hidl_audio_config_2_1(BluetoothAudioSessionControl::GetAudioConfig( - from_session_type_2_1(session_type))); -} - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h deleted file mode 100644 index b124d8f..0000000 --- a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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. - * 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. - */ - -#include - -#include "../session/BluetoothAudioSession.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -using SessionType_2_0 = - ::android::hardware::bluetooth::audio::V2_0::SessionType; -using PortStatusCallbacks_2_0 = - ::android::bluetooth::audio::PortStatusCallbacks; -using AudioConfig_2_0 = - ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration; - -class HidlToAidlMiddleware_2_0 { - public: - static bool IsAidlAvailable(); - - static bool IsSessionReady(const SessionType_2_0& session_type); - - static uint16_t RegisterControlResultCback( - const SessionType_2_0& session_type, - const PortStatusCallbacks_2_0& cbacks); - - static void UnregisterControlResultCback(const SessionType_2_0& session_type, - uint16_t cookie); - - static const AudioConfig_2_0 GetAudioConfig( - const SessionType_2_0& session_type); - - static bool StartStream(const SessionType_2_0& session_type); - - static void StopStream(const SessionType_2_0& session_type); - - static bool SuspendStream(const SessionType_2_0& session_type); - - static bool GetPresentationPosition(const SessionType_2_0& session_type, - uint64_t* remote_delay_report_ns, - uint64_t* total_bytes_readed, - timespec* data_position); - - static void UpdateTracksMetadata( - const SessionType_2_0& session_type, - const struct source_metadata* source_metadata); - - static size_t OutWritePcmData(const SessionType_2_0& session_type, - const void* buffer, size_t bytes); - - static size_t InReadPcmData(const SessionType_2_0& session_type, void* buffer, - size_t bytes); -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h deleted file mode 100644 index 82dce96..0000000 --- a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - * 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. - */ - -#include - -#include "../session/BluetoothAudioSession.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace bluetooth { -namespace audio { - -using SessionType_2_1 = - ::android::hardware::bluetooth::audio::V2_1::SessionType; -using AudioConfig_2_1 = - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration; - -class HidlToAidlMiddleware_2_1 { - public: - static const AudioConfig_2_1 GetAudioConfig( - const SessionType_2_1& session_type); -}; - -} // namespace audio -} // namespace bluetooth -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp deleted file mode 100644 index 283952e..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright 2018 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. - */ - -#define LOG_TAG "BTAudioProviderSession" - -#include "BluetoothAudioSession.h" - -#include -#include - -#include "../aidl_session/HidlToAidlMiddleware_2_0.h" - -namespace android { -namespace bluetooth { -namespace audio { - -using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0; -using ::android::hardware::audio::common::V5_0::AudioContentType; -using ::android::hardware::audio::common::V5_0::AudioUsage; -using ::android::hardware::audio::common::V5_0::PlaybackTrackMetadata; -using ::android::hardware::audio::common::V5_0::SourceMetadata; -using ::android::hardware::bluetooth::audio::V2_0::CodecType; -using ::android::hardware::bluetooth::audio::V2_0::TimeSpec; - -const CodecConfiguration BluetoothAudioSession::kInvalidCodecConfiguration = { - .codecType = CodecType::UNKNOWN, - .encodedAudioBitrate = 0x00000000, - .peerMtu = 0xffff, - .isScmstEnabled = false, - .config = {}}; -AudioConfiguration BluetoothAudioSession::invalidSoftwareAudioConfiguration = - {}; -AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {}; - -static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending -static constexpr int kFmqReceiveTimeoutMs = - 1000; // 1000 ms timeout for receiving -static constexpr int kWritePollMs = 1; // polled non-blocking interval -static constexpr int kReadPollMs = 1; // polled non-blocking interval - -static inline timespec timespec_convert_from_hal(const TimeSpec& TS) { - return {.tv_sec = static_cast(TS.tvSec), - .tv_nsec = static_cast(TS.tvNSec)}; -} - -BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type) - : session_type_(session_type), stack_iface_(nullptr), mDataMQ(nullptr) { - invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters); - invalidOffloadAudioConfiguration.codecConfig(kInvalidCodecConfiguration); -} - -// The report function is used to report that the Bluetooth stack has started -// this session without any failure, and will invoke session_changed_cb_ to -// notify those registered bluetooth_audio outputs -void BluetoothAudioSession::OnSessionStarted( - const sp stack_iface, const DataMQ::Descriptor* dataMQ, - const AudioConfiguration& audio_config) { - std::lock_guard guard(mutex_); - if (stack_iface == nullptr) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) - << ", IBluetoothAudioPort Invalid"; - } else if (!UpdateAudioConfig(audio_config)) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) - << ", AudioConfiguration=" << toString(audio_config) - << " Invalid"; - } else if (!UpdateDataPath(dataMQ)) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) - << " DataMQ Invalid"; - audio_config_ = - (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH - ? kInvalidOffloadAudioConfiguration - : kInvalidSoftwareAudioConfiguration); - } else { - stack_iface_ = stack_iface; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << ", AudioConfiguration=" << toString(audio_config); - ReportSessionStatus(); - } -} - -// The report function is used to report that the Bluetooth stack has ended the -// session, and will invoke session_changed_cb_ to notify registered -// bluetooth_audio outputs -void BluetoothAudioSession::OnSessionEnded() { - std::lock_guard guard(mutex_); - bool toggled = IsSessionReady(); - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); - audio_config_ = (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH - ? kInvalidOffloadAudioConfiguration - : kInvalidSoftwareAudioConfiguration); - stack_iface_ = nullptr; - UpdateDataPath(nullptr); - if (toggled) { - ReportSessionStatus(); - } -} - -// invoking the registered session_changed_cb_ -void BluetoothAudioSession::ReportSessionStatus() { - // This is locked already by OnSessionStarted / OnSessionEnded - if (observers_.empty()) { - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO port state observer"; - return; - } - for (auto& observer : observers_) { - uint16_t cookie = observer.first; - std::shared_ptr cb = observer.second; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) - << " notify to bluetooth_audio=0x" - << android::base::StringPrintf("%04x", cookie); - cb->session_changed_cb_(cookie); - } -} - -// The report function is used to report that the Bluetooth stack has notified -// the result of startStream or suspendStream, and will invoke -// control_result_cb_ to notify registered bluetooth_audio outputs -void BluetoothAudioSession::ReportControlStatus( - bool start_resp, const BluetoothAudioStatus& status) { - std::lock_guard guard(mutex_); - if (observers_.empty()) { - LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO port state observer"; - return; - } - for (auto& observer : observers_) { - uint16_t cookie = observer.first; - std::shared_ptr cb = observer.second; - LOG(INFO) << __func__ << " - status=" << toString(status) - << " for SessionType=" << toString(session_type_) - << ", bluetooth_audio=0x" - << android::base::StringPrintf("%04x", cookie) - << (start_resp ? " started" : " suspended"); - cb->control_result_cb_(cookie, start_resp, status); - } -} - -// The function helps to check if this session is ready or not -// @return: true if the Bluetooth stack has started the specified session -bool BluetoothAudioSession::IsSessionReady() { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::IsSessionReady(session_type_); - std::lock_guard guard(mutex_); - bool dataMQ_valid = - (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH || - (mDataMQ != nullptr && mDataMQ->isValid())); - return stack_iface_ != nullptr && dataMQ_valid; -} - -bool BluetoothAudioSession::UpdateDataPath(const DataMQ::Descriptor* dataMQ) { - if (dataMQ == nullptr) { - // usecase of reset by nullptr - mDataMQ = nullptr; - return true; - } - std::unique_ptr tempDataMQ; - tempDataMQ.reset(new DataMQ(*dataMQ)); - if (!tempDataMQ || !tempDataMQ->isValid()) { - mDataMQ = nullptr; - return false; - } - mDataMQ = std::move(tempDataMQ); - return true; -} - -bool BluetoothAudioSession::UpdateAudioConfig( - const AudioConfiguration& audio_config) { - bool is_software_session = - (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH); - bool is_offload_session = - (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH); - auto audio_config_discriminator = audio_config.getDiscriminator(); - bool is_software_audio_config = - (is_software_session && - audio_config_discriminator == - AudioConfiguration::hidl_discriminator::pcmConfig); - bool is_offload_audio_config = - (is_offload_session && - audio_config_discriminator == - AudioConfiguration::hidl_discriminator::codecConfig); - if (!is_software_audio_config && !is_offload_audio_config) { - return false; - } - audio_config_ = audio_config; - return true; -} - -// The control function helps the bluetooth_audio module to register -// PortStatusCallbacks -// @return: cookie - the assigned number to this bluetooth_audio output -uint16_t BluetoothAudioSession::RegisterStatusCback( - const PortStatusCallbacks& cbacks) { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::RegisterControlResultCback(session_type_, - cbacks); - std::lock_guard guard(mutex_); - uint16_t cookie = ObserversCookieGetInitValue(session_type_); - uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_); - - while (cookie < cookie_upper_bound) { - if (observers_.find(cookie) == observers_.end()) { - break; - } - ++cookie; - } - if (cookie >= cookie_upper_bound) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_) - << " has " << observers_.size() - << " observers already (No Resource)"; - return kObserversCookieUndefined; - } - std::shared_ptr cb = - std::make_shared(); - *cb = cbacks; - observers_[cookie] = cb; - return cookie; -} - -// The control function helps the bluetooth_audio module to unregister -// PortStatusCallbacks -// @param: cookie - indicates which bluetooth_audio output is -void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::UnregisterControlResultCback(session_type_, - cookie); - std::lock_guard guard(mutex_); - if (observers_.erase(cookie) != 1) { - LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) - << " no such provider=0x" - << android::base::StringPrintf("%04x", cookie); - } -} - -// The control function is for the bluetooth_audio module to get the current -// AudioConfiguration -const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return (audio_config_ = - HidlToAidlMiddleware_2_0::GetAudioConfig(session_type_)); - std::lock_guard guard(mutex_); - if (IsSessionReady()) { - return audio_config_; - } else if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { - return kInvalidOffloadAudioConfiguration; - } else { - return kInvalidSoftwareAudioConfiguration; - } -} - -// Those control functions are for the bluetooth_audio module to start, suspend, -// stop stream, to check position, and to update metadata. -bool BluetoothAudioSession::StartStream() { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::StartStream(session_type_); - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return false; - } - auto hal_retval = stack_iface_->startStream(); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - return false; - } - return true; -} - -bool BluetoothAudioSession::SuspendStream() { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::SuspendStream(session_type_); - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return false; - } - auto hal_retval = stack_iface_->suspendStream(); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - return false; - } - return true; -} - -void BluetoothAudioSession::StopStream() { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::StopStream(session_type_); - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - return; - } - auto hal_retval = stack_iface_->stopStream(); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - } -} - -bool BluetoothAudioSession::GetPresentationPosition( - uint64_t* remote_delay_report_ns, uint64_t* total_bytes_readed, - timespec* data_position) { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::GetPresentationPosition( - session_type_, remote_delay_report_ns, total_bytes_readed, - data_position); - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return false; - } - bool retval = false; - auto hal_retval = stack_iface_->getPresentationPosition( - [&retval, &remote_delay_report_ns, &total_bytes_readed, &data_position]( - BluetoothAudioStatus status, - const uint64_t& remoteDeviceAudioDelayNanos, - uint64_t transmittedOctets, - const TimeSpec& transmittedOctetsTimeStamp) { - if (status == BluetoothAudioStatus::SUCCESS) { - if (remote_delay_report_ns) - *remote_delay_report_ns = remoteDeviceAudioDelayNanos; - if (total_bytes_readed) *total_bytes_readed = transmittedOctets; - if (data_position) - *data_position = - timespec_convert_from_hal(transmittedOctetsTimeStamp); - retval = true; - } - }); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - return false; - } - return retval; -} - -void BluetoothAudioSession::UpdateTracksMetadata( - const struct source_metadata* source_metadata) { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::UpdateTracksMetadata(session_type_, - source_metadata); - std::lock_guard guard(mutex_); - if (!IsSessionReady()) { - LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_) - << " has NO session"; - return; - } - - ssize_t track_count = source_metadata->track_count; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ", " - << track_count << " track(s)"; - if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { - return; - } - - struct playback_track_metadata* track = source_metadata->tracks; - SourceMetadata sourceMetadata; - PlaybackTrackMetadata* halMetadata; - - sourceMetadata.tracks.resize(track_count); - halMetadata = sourceMetadata.tracks.data(); - while (track_count && track) { - halMetadata->usage = static_cast(track->usage); - halMetadata->contentType = - static_cast(track->content_type); - halMetadata->gain = track->gain; - LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_) - << ", usage=" << toString(halMetadata->usage) - << ", content=" << toString(halMetadata->contentType) - << ", gain=" << halMetadata->gain; - --track_count; - ++track; - ++halMetadata; - } - auto hal_retval = stack_iface_->updateMetadata(sourceMetadata); - if (!hal_retval.isOk()) { - LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType=" - << toString(session_type_) << " failed"; - } -} - -// The control function writes stream to FMQ -size_t BluetoothAudioSession::OutWritePcmData(const void* buffer, - size_t bytes) { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::OutWritePcmData(session_type_, buffer, - bytes); - if (buffer == nullptr || !bytes) return 0; - size_t totalWritten = 0; - int ms_timeout = kFmqSendTimeoutMs; - do { - std::unique_lock lock(mutex_); - if (!IsSessionReady()) break; - size_t availableToWrite = mDataMQ->availableToWrite(); - if (availableToWrite) { - if (availableToWrite > (bytes - totalWritten)) { - availableToWrite = bytes - totalWritten; - } - - if (!mDataMQ->write(static_cast(buffer) + totalWritten, - availableToWrite)) { - ALOGE("FMQ datapath writting %zu/%zu failed", totalWritten, bytes); - return totalWritten; - } - totalWritten += availableToWrite; - } else if (ms_timeout >= kWritePollMs) { - lock.unlock(); - usleep(kWritePollMs * 1000); - ms_timeout -= kWritePollMs; - } else { - ALOGD("data %zu/%zu overflow %d ms", totalWritten, bytes, - (kFmqSendTimeoutMs - ms_timeout)); - return totalWritten; - } - } while (totalWritten < bytes); - return totalWritten; -} - -// The control function reads stream from FMQ -size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_0::InReadPcmData(session_type_, buffer, - bytes); - if (buffer == nullptr || !bytes) return 0; - size_t totalRead = 0; - int ms_timeout = kFmqReceiveTimeoutMs; - do { - std::unique_lock lock(mutex_); - if (!IsSessionReady()) break; - size_t availableToRead = mDataMQ->availableToRead(); - if (availableToRead) { - if (availableToRead > (bytes - totalRead)) { - availableToRead = bytes - totalRead; - } - if (!mDataMQ->read(static_cast(buffer) + totalRead, - availableToRead)) { - ALOGE("FMQ datapath reading %zu/%zu failed", totalRead, bytes); - return totalRead; - } - totalRead += availableToRead; - } else if (ms_timeout >= kReadPollMs) { - lock.unlock(); - usleep(kReadPollMs * 1000); - ms_timeout -= kReadPollMs; - continue; - } else { - ALOGD("in data %zu/%zu overflow %d ms", totalRead, bytes, - (kFmqReceiveTimeoutMs - ms_timeout)); - return totalRead; - } - } while (totalRead < bytes); - return totalRead; -} - -std::unique_ptr - BluetoothAudioSessionInstance::instance_ptr = - std::unique_ptr( - new BluetoothAudioSessionInstance()); - -// API to fetch the session of A2DP / Hearing Aid -std::shared_ptr -BluetoothAudioSessionInstance::GetSessionInstance( - const SessionType& session_type) { - std::lock_guard guard(instance_ptr->mutex_); - if (!instance_ptr->sessions_map_.empty()) { - auto entry = instance_ptr->sessions_map_.find(session_type); - if (entry != instance_ptr->sessions_map_.end()) { - return entry->second; - } - } - std::shared_ptr session_ptr = - std::make_shared(session_type); - instance_ptr->sessions_map_[session_type] = session_ptr; - return session_ptr; -} - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.h b/bluetooth/audio/utils/session/BluetoothAudioSession.h deleted file mode 100644 index 3469cc0..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSession.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2018 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 -#include - -#include -#include -#include -#include - -namespace android { -namespace bluetooth { -namespace audio { - -using ::android::sp; -using ::android::hardware::kSynchronizedReadWrite; -using ::android::hardware::MessageQueue; -using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration; -using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample; -using ::android::hardware::bluetooth::audio::V2_0::ChannelMode; -using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration; -using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort; -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 BluetoothAudioStatus = - ::android::hardware::bluetooth::audio::V2_0::Status; - -using DataMQ = MessageQueue; - -static constexpr uint16_t kObserversCookieSize = 0x0010; // 0x0000 ~ 0x000f -constexpr uint16_t kObserversCookieUndefined = - (static_cast(SessionType::UNKNOWN) << 8 & 0xff00); -inline SessionType ObserversCookieGetSessionType(uint16_t cookie) { - return static_cast(cookie >> 8 & 0x00ff); -} -inline uint16_t ObserversCookieGetInitValue(SessionType session_type) { - return (static_cast(session_type) << 8 & 0xff00); -} -inline uint16_t ObserversCookieGetUpperBound(SessionType session_type) { - return (static_cast(session_type) << 8 & 0xff00) + - kObserversCookieSize; -} - -// This presents the callbacks of started / suspended and session changed, -// and the bluetooth_audio module uses to receive the status notification -struct PortStatusCallbacks { - // control_result_cb_ - when the Bluetooth stack reports results of - // streamStarted or streamSuspended, the BluetoothAudioProvider will invoke - // this callback to report to the bluetooth_audio module. - // @param: cookie - indicates which bluetooth_audio output should handle - // @param: start_resp - this report is for startStream or not - // @param: status - the result of startStream - std::function - control_result_cb_; - // session_changed_cb_ - when the Bluetooth stack start / end session, the - // BluetoothAudioProvider will invoke this callback to notify to the - // bluetooth_audio module. - // @param: cookie - indicates which bluetooth_audio output should handle - std::function session_changed_cb_; -}; - -class BluetoothAudioSession { - friend class BluetoothAudioSession_2_1; - friend class BluetoothAudioSession_2_2; - - private: - // using recursive_mutex to allow hwbinder to re-enter agian. - std::recursive_mutex mutex_; - SessionType session_type_; - - // audio control path to use for both software and offloading - sp stack_iface_; - // audio data path (FMQ) for software encoding - std::unique_ptr mDataMQ; - // audio data configuration for both software and offloading - AudioConfiguration audio_config_; - - static AudioConfiguration invalidSoftwareAudioConfiguration; - static AudioConfiguration invalidOffloadAudioConfiguration; - - // saving those registered bluetooth_audio's callbacks - std::unordered_map> - observers_; - - bool UpdateDataPath(const DataMQ::Descriptor* dataMQ); - bool UpdateAudioConfig(const AudioConfiguration& audio_config); - // invoking the registered session_changed_cb_ - void ReportSessionStatus(); - - public: - BluetoothAudioSession(const SessionType& session_type); - - // The function helps to check if this session is ready or not - // @return: true if the Bluetooth stack has started the specified session - bool IsSessionReady(); - - // The report function is used to report that the Bluetooth stack has started - // this session without any failure, and will invoke session_changed_cb_ to - // notify those registered bluetooth_audio outputs - void OnSessionStarted(const sp stack_iface, - const DataMQ::Descriptor* dataMQ, - const AudioConfiguration& audio_config); - - // The report function is used to report that the Bluetooth stack has ended - // the session, and will invoke session_changed_cb_ to notify registered - // bluetooth_audio outputs - void OnSessionEnded(); - - // The report function is used to report that the Bluetooth stack has notified - // the result of startStream or suspendStream, and will invoke - // control_result_cb_ to notify registered bluetooth_audio outputs - void ReportControlStatus(bool start_resp, const BluetoothAudioStatus& status); - - // The control function helps the bluetooth_audio module to register - // PortStatusCallbacks - // @return: cookie - the assigned number to this bluetooth_audio output - uint16_t RegisterStatusCback(const PortStatusCallbacks& cbacks); - - // The control function helps the bluetooth_audio module to unregister - // PortStatusCallbacks - // @param: cookie - indicates which bluetooth_audio output is - void UnregisterStatusCback(uint16_t cookie); - - // The control function is for the bluetooth_audio module to get the current - // AudioConfiguration - const AudioConfiguration& GetAudioConfig(); - - // Those control functions are for the bluetooth_audio module to start, - // suspend, stop stream, to check position, and to update metadata. - bool StartStream(); - bool SuspendStream(); - void StopStream(); - bool GetPresentationPosition(uint64_t* remote_delay_report_ns, - uint64_t* total_bytes_readed, - timespec* data_position); - void UpdateTracksMetadata(const struct source_metadata* source_metadata); - - // The control function writes stream to FMQ - size_t OutWritePcmData(const void* buffer, size_t bytes); - // The control function read stream from FMQ - size_t InReadPcmData(void* buffer, size_t bytes); - - static constexpr PcmParameters kInvalidPcmParameters = { - .sampleRate = SampleRate::RATE_UNKNOWN, - .channelMode = ChannelMode::UNKNOWN, - .bitsPerSample = BitsPerSample::BITS_UNKNOWN, - }; - // can't be constexpr because of non-literal type - static const CodecConfiguration kInvalidCodecConfiguration; - - static constexpr AudioConfiguration& kInvalidSoftwareAudioConfiguration = - invalidSoftwareAudioConfiguration; - static constexpr AudioConfiguration& kInvalidOffloadAudioConfiguration = - invalidOffloadAudioConfiguration; -}; - -class BluetoothAudioSessionInstance { - public: - // The API is to fetch the specified session of A2DP / Hearing Aid - static std::shared_ptr GetSessionInstance( - const SessionType& session_type); - - private: - static std::unique_ptr instance_ptr; - std::mutex mutex_; - std::unordered_map> - sessions_map_; -}; - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl.h deleted file mode 100644 index 6707765..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2018 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 "BluetoothAudioSession.h" - -namespace android { -namespace bluetooth { -namespace audio { - -class BluetoothAudioSessionControl { - public: - // The control API helps to check if session is ready or not - // @return: true if the Bluetooth stack has started th specified session - static bool IsSessionReady(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->IsSessionReady(); - } - return false; - } - - // The control API helps the bluetooth_audio module to register - // PortStatusCallbacks - // @return: cookie - the assigned number to this bluetooth_audio output - static uint16_t RegisterControlResultCback( - const SessionType& session_type, const PortStatusCallbacks& cbacks) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->RegisterStatusCback(cbacks); - } - return kObserversCookieUndefined; - } - - // The control API helps the bluetooth_audio module to unregister - // PortStatusCallbacks - // @param: cookie - indicates which bluetooth_audio output is - static void UnregisterControlResultCback(const SessionType& session_type, - uint16_t cookie) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->UnregisterStatusCback(cookie); - } - } - - // The control API for the bluetooth_audio module to get current - // AudioConfiguration - static const AudioConfiguration& GetAudioConfig( - const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioConfig(); - } else if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { - return BluetoothAudioSession::kInvalidOffloadAudioConfiguration; - } else { - return BluetoothAudioSession::kInvalidSoftwareAudioConfiguration; - } - } - - // Those control APIs for the bluetooth_audio module to start / suspend / stop - // stream, to check position, and to update metadata. - static bool StartStream(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->StartStream(); - } - return false; - } - - static bool SuspendStream(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->SuspendStream(); - } - return false; - } - - static void StopStream(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->StopStream(); - } - } - - static bool GetPresentationPosition(const SessionType& session_type, - uint64_t* remote_delay_report_ns, - uint64_t* total_bytes_readed, - timespec* data_position) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetPresentationPosition( - remote_delay_report_ns, total_bytes_readed, data_position); - } - return false; - } - - static void UpdateTracksMetadata( - const SessionType& session_type, - const struct source_metadata* source_metadata) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->UpdateTracksMetadata(source_metadata); - } - } - - // The control API writes stream to FMQ - static size_t OutWritePcmData(const SessionType& session_type, - const void* buffer, size_t bytes) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->OutWritePcmData(buffer, bytes); - } - return 0; - } -}; - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h deleted file mode 100644 index 4d7be21..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2018 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 "BluetoothAudioSession_2_1.h" - -namespace android { -namespace bluetooth { -namespace audio { - -class BluetoothAudioSessionControl_2_1 { - using SessionType_2_1 = - ::android::hardware::bluetooth::audio::V2_1::SessionType; - using AudioConfiguration_2_1 = - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration; - - public: - // The control API helps to check if session is ready or not - // @return: true if the Bluetooth stack has started th specified session - static bool IsSessionReady(const SessionType_2_1& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioSession()->IsSessionReady(); - } - return false; - } - - // The control API helps the bluetooth_audio module to register - // PortStatusCallbacks - // @return: cookie - the assigned number to this bluetooth_audio output - static uint16_t RegisterControlResultCback( - const SessionType_2_1& session_type, const PortStatusCallbacks& cbacks) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks); - } - return kObserversCookieUndefined; - } - - // The control API helps the bluetooth_audio module to unregister - // PortStatusCallbacks - // @param: cookie - indicates which bluetooth_audio output is - static void UnregisterControlResultCback(const SessionType_2_1& session_type, - uint16_t cookie) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->GetAudioSession()->UnregisterStatusCback(cookie); - } - } - - // The control API for the bluetooth_audio module to get current - // AudioConfiguration - static const AudioConfiguration_2_1 GetAudioConfig( - const SessionType_2_1& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioConfig(); - } else if (session_type == - SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) { - return BluetoothAudioSession_2_1::kInvalidOffloadAudioConfiguration; - } else { - return BluetoothAudioSession_2_1::kInvalidSoftwareAudioConfiguration; - } - } - - // Those control APIs for the bluetooth_audio module to start / suspend / stop - // stream, to check position, and to update metadata. - static bool StartStream(const SessionType_2_1& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioSession()->StartStream(); - } - return false; - } - - static bool SuspendStream(const SessionType_2_1& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioSession()->SuspendStream(); - } - return false; - } - - static void StopStream(const SessionType_2_1& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->GetAudioSession()->StopStream(); - } - } - - static bool GetPresentationPosition(const SessionType_2_1& session_type, - uint64_t* remote_delay_report_ns, - uint64_t* total_bytes_readed, - timespec* data_position) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioSession()->GetPresentationPosition( - remote_delay_report_ns, total_bytes_readed, data_position); - } - return false; - } - - static void UpdateTracksMetadata( - const SessionType_2_1& session_type, - const struct source_metadata* source_metadata) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->GetAudioSession()->UpdateTracksMetadata(source_metadata); - } - } - - // The control API writes stream to FMQ - static size_t OutWritePcmData(const SessionType_2_1& session_type, - const void* buffer, size_t bytes) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioSession()->OutWritePcmData(buffer, bytes); - } - return 0; - } - - // The control API reads stream from FMQ - static size_t InReadPcmData(const SessionType_2_1& session_type, void* buffer, - size_t bytes) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - return session_ptr->GetAudioSession()->InReadPcmData(buffer, bytes); - } - return 0; - } -}; - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionReport.h b/bluetooth/audio/utils/session/BluetoothAudioSessionReport.h deleted file mode 100644 index 5a83ae2..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSessionReport.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2018 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 "BluetoothAudioSession.h" - -namespace android { -namespace bluetooth { -namespace audio { - -class BluetoothAudioSessionReport { - public: - // The API reports the Bluetooth stack has started the session, and will - // inform registered bluetooth_audio outputs - static void OnSessionStarted(const SessionType& session_type, - const sp host_iface, - const DataMQ::Descriptor* dataMQ, - const AudioConfiguration& audio_config) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->OnSessionStarted(host_iface, dataMQ, audio_config); - } - } - // The API reports the Bluetooth stack has ended the session, and will - // inform registered bluetooth_audio outputs - static void OnSessionEnded(const SessionType& session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->OnSessionEnded(); - } - } - // The API reports the Bluetooth stack has replied the result of startStream - // or suspendStream, and will inform registered bluetooth_audio outputs - static void ReportControlStatus(const SessionType& session_type, - const bool& start_resp, - const BluetoothAudioStatus& status) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->ReportControlStatus(start_resp, status); - } - } -}; - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_1.h deleted file mode 100644 index ab30536..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_1.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2018 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 "BluetoothAudioSession_2_1.h" - -namespace android { -namespace bluetooth { -namespace audio { - -class BluetoothAudioSessionReport_2_1 { - public: - // The API reports the Bluetooth stack has started the session, and will - // inform registered bluetooth_audio outputs - static void OnSessionStarted( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type, - const sp host_iface, - const DataMQ::Descriptor* dataMQ, - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration& - audio_config) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->OnSessionStarted(host_iface, dataMQ, audio_config); - } - } - // The API reports the Bluetooth stack has ended the session, and will - // inform registered bluetooth_audio outputs - static void OnSessionEnded( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->GetAudioSession()->OnSessionEnded(); - } - } - // The API reports the Bluetooth stack has replied the result of startStream - // or suspendStream, and will inform registered bluetooth_audio outputs - static void ReportControlStatus( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type, - const bool& start_resp, const BluetoothAudioStatus& status) { - std::shared_ptr session_ptr = - BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type); - if (session_ptr != nullptr) { - session_ptr->GetAudioSession()->ReportControlStatus(start_resp, status); - } - } -}; - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp deleted file mode 100644 index 276a291..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2018 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. - */ - -#define LOG_TAG "BTAudioProviderSession_2_1" - -#include "BluetoothAudioSession_2_1.h" - -#include -#include - -#include "../aidl_session/HidlToAidlMiddleware_2_0.h" -#include "../aidl_session/HidlToAidlMiddleware_2_1.h" - -namespace android { -namespace bluetooth { -namespace audio { -using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0; -using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_1; -using SessionType_2_1 = - ::android::hardware::bluetooth::audio::V2_1::SessionType; -using SessionType_2_0 = - ::android::hardware::bluetooth::audio::V2_0::SessionType; - -::android::hardware::bluetooth::audio::V2_1::AudioConfiguration - BluetoothAudioSession_2_1::invalidSoftwareAudioConfiguration = {}; -::android::hardware::bluetooth::audio::V2_1::AudioConfiguration - BluetoothAudioSession_2_1::invalidOffloadAudioConfiguration = {}; - -namespace { -bool is_2_0_session_type( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type) { - if (session_type == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH || - session_type == SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH) { - return true; - } else { - return false; - } -} - -bool is_unsupported_2_1_session_type( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type) { - if (session_type == - SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type == - SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - return true; - } else { - return false; - } -} -} // namespace - -BluetoothAudioSession_2_1::BluetoothAudioSession_2_1( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type) - : audio_session(BluetoothAudioSessionInstance::GetSessionInstance( - static_cast(session_type))) { - if (is_2_0_session_type(session_type) || - is_unsupported_2_1_session_type(session_type)) { - session_type_2_1_ = (SessionType_2_1::UNKNOWN); - } else { - session_type_2_1_ = (session_type); - } - raw_session_type_ = session_type; -} - -std::shared_ptr -BluetoothAudioSession_2_1::GetAudioSession() { - return audio_session; -} - -// The control function is for the bluetooth_audio module to get the current -// AudioConfiguration -const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration -BluetoothAudioSession_2_1::GetAudioConfig() { - if (HidlToAidlMiddleware_2_0::IsAidlAvailable()) - return HidlToAidlMiddleware_2_1::GetAudioConfig(raw_session_type_); - std::lock_guard guard(audio_session->mutex_); - if (audio_session->IsSessionReady()) { - // If session is unknown it means it should be 2.0 type - if (session_type_2_1_ != SessionType_2_1::UNKNOWN) - return audio_config_2_1_; - - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration toConf; - const AudioConfiguration fromConf = GetAudioSession()->GetAudioConfig(); - // pcmConfig only differs between 2.0 and 2.1 in AudioConfiguration - if (fromConf.getDiscriminator() == - AudioConfiguration::hidl_discriminator::codecConfig) { - toConf.codecConfig(fromConf.codecConfig()); - } else { - toConf.pcmConfig() = { - .sampleRate = static_cast< - ::android::hardware::bluetooth::audio::V2_1::SampleRate>( - fromConf.pcmConfig().sampleRate), - .channelMode = fromConf.pcmConfig().channelMode, - .bitsPerSample = fromConf.pcmConfig().bitsPerSample, - .dataIntervalUs = 0}; - } - return toConf; - } else if (session_type_2_1_ == - SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) { - return kInvalidOffloadAudioConfiguration; - } else { - return kInvalidSoftwareAudioConfiguration; - } -} - -bool BluetoothAudioSession_2_1::UpdateAudioConfig( - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration& - audio_config) { - bool is_software_session = - (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type_2_1_ == - SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH || - session_type_2_1_ == - SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH || - session_type_2_1_ == - SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH); - bool is_offload_a2dp_session = - (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH); - auto audio_config_discriminator = audio_config.getDiscriminator(); - bool is_software_audio_config = - (is_software_session && - audio_config_discriminator == - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: - hidl_discriminator::pcmConfig); - bool is_a2dp_offload_audio_config = - (is_offload_a2dp_session && - audio_config_discriminator == - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: - hidl_discriminator::codecConfig); - if (!is_software_audio_config && !is_a2dp_offload_audio_config) { - return false; - } - audio_config_2_1_ = audio_config; - return true; -} - -// The report function is used to report that the Bluetooth stack has started -// this session without any failure, and will invoke session_changed_cb_ to -// notify those registered bluetooth_audio outputs -void BluetoothAudioSession_2_1::OnSessionStarted( - const sp stack_iface, const DataMQ::Descriptor* dataMQ, - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration& - audio_config) { - if (session_type_2_1_ == SessionType_2_1::UNKNOWN) { - ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration config; - if (audio_config.getDiscriminator() == - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration:: - hidl_discriminator::codecConfig) { - config.codecConfig(audio_config.codecConfig()); - } else { - auto& tmpPcm = audio_config.pcmConfig(); - config.pcmConfig( - ::android::hardware::bluetooth::audio::V2_0::PcmParameters{ - .sampleRate = static_cast(tmpPcm.sampleRate), - .channelMode = tmpPcm.channelMode, - .bitsPerSample = tmpPcm.bitsPerSample - /*dataIntervalUs is not passed to 2.0 */ - }); - } - - audio_session->OnSessionStarted(stack_iface, dataMQ, config); - } else { - std::lock_guard guard(audio_session->mutex_); - if (stack_iface == nullptr) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_) - << ", IBluetoothAudioPort Invalid"; - } else if (!UpdateAudioConfig(audio_config)) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_) - << ", AudioConfiguration=" << toString(audio_config) - << " Invalid"; - } else if (!audio_session->UpdateDataPath(dataMQ)) { - LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_) - << " DataMQ Invalid"; - audio_config_2_1_ = - (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH - ? kInvalidOffloadAudioConfiguration - : kInvalidSoftwareAudioConfiguration); - } else { - audio_session->stack_iface_ = stack_iface; - LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_) - << ", AudioConfiguration=" << toString(audio_config); - audio_session->ReportSessionStatus(); - }; - } -} - -std::unique_ptr - BluetoothAudioSessionInstance_2_1::instance_ptr = - std::unique_ptr( - new BluetoothAudioSessionInstance_2_1()); - -// API to fetch the session of A2DP / Hearing Aid -std::shared_ptr -BluetoothAudioSessionInstance_2_1::GetSessionInstance( - const SessionType_2_1& session_type) { - std::lock_guard guard(instance_ptr->mutex_); - if (!instance_ptr->sessions_map_.empty()) { - auto entry = instance_ptr->sessions_map_.find(session_type); - if (entry != instance_ptr->sessions_map_.end()) { - return entry->second; - } - } - std::shared_ptr session_ptr = - std::make_shared(session_type); - instance_ptr->sessions_map_[session_type] = session_ptr; - return session_ptr; -} - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h deleted file mode 100644 index e634064..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2018 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 -#include "BluetoothAudioSession.h" - -#include -#include - -namespace android { -namespace bluetooth { -namespace audio { - -class BluetoothAudioSession_2_1 { - private: - std::shared_ptr audio_session; - - ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_; - ::android::hardware::bluetooth::audio::V2_1::SessionType raw_session_type_; - - // audio data configuration for both software and offloading - ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration - audio_config_2_1_; - - bool UpdateAudioConfig( - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration& - audio_config); - - static ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration - invalidSoftwareAudioConfiguration; - static ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration - invalidOffloadAudioConfiguration; - - public: - BluetoothAudioSession_2_1( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type); - - std::shared_ptr GetAudioSession(); - - // The report function is used to report that the Bluetooth stack has started - // this session without any failure, and will invoke session_changed_cb_ to - // notify those registered bluetooth_audio outputs - void OnSessionStarted( - const sp stack_iface, - const DataMQ::Descriptor* dataMQ, - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration& - audio_config); - - // The control function is for the bluetooth_audio module to get the current - // AudioConfiguration - const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration - GetAudioConfig(); - - static constexpr ::android::hardware::bluetooth::audio::V2_1:: - AudioConfiguration& kInvalidSoftwareAudioConfiguration = - invalidSoftwareAudioConfiguration; - static constexpr ::android::hardware::bluetooth::audio::V2_1:: - AudioConfiguration& kInvalidOffloadAudioConfiguration = - invalidOffloadAudioConfiguration; -}; - -class BluetoothAudioSessionInstance_2_1 { - public: - // The API is to fetch the specified session of A2DP / Hearing Aid - static std::shared_ptr GetSessionInstance( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type); - - private: - static std::unique_ptr instance_ptr; - std::mutex mutex_; - std::unordered_map<::android::hardware::bluetooth::audio::V2_1::SessionType, - std::shared_ptr> - sessions_map_; -}; - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.cpp deleted file mode 100644 index c368197..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright 2018 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. - */ - -#define LOG_TAG "BTAudioProviderSessionCodecsDB" - -#include "BluetoothAudioSupportedCodecsDB.h" - -#include - -namespace android { -namespace bluetooth { -namespace audio { - -using ::android::hardware::bluetooth::audio::V2_0::AacObjectType; -using ::android::hardware::bluetooth::audio::V2_0::AacParameters; -using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate; -using ::android::hardware::bluetooth::audio::V2_0::AptxParameters; -using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample; -using ::android::hardware::bluetooth::audio::V2_0::ChannelMode; -using ::android::hardware::bluetooth::audio::V2_0::CodecType; -using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode; -using ::android::hardware::bluetooth::audio::V2_0::LdacParameters; -using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex; -using ::android::hardware::bluetooth::audio::V2_0::SampleRate; -using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod; -using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength; -using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode; -using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands; -using ::android::hardware::bluetooth::audio::V2_0::SbcParameters; - -// Default Supported PCM Parameters -static const PcmParameters kDefaultSoftwarePcmCapabilities = { - .sampleRate = static_cast( - SampleRate::RATE_44100 | SampleRate::RATE_48000 | - SampleRate::RATE_88200 | SampleRate::RATE_96000 | - SampleRate::RATE_16000 | SampleRate::RATE_24000), - .channelMode = - static_cast(ChannelMode::MONO | ChannelMode::STEREO), - .bitsPerSample = static_cast(BitsPerSample::BITS_16 | - BitsPerSample::BITS_24 | - BitsPerSample::BITS_32)}; - -// Default Supported Codecs -// SBC: mSampleRate:(44100), mBitsPerSample:(16), mChannelMode:(MONO|STEREO) -// all blocks | subbands 8 | Loudness -static const SbcParameters kDefaultOffloadSbcCapability = { - .sampleRate = SampleRate::RATE_44100, - .channelMode = static_cast(SbcChannelMode::MONO | - SbcChannelMode::JOINT_STEREO), - .blockLength = static_cast( - SbcBlockLength::BLOCKS_4 | SbcBlockLength::BLOCKS_8 | - SbcBlockLength::BLOCKS_12 | SbcBlockLength::BLOCKS_16), - .numSubbands = SbcNumSubbands::SUBBAND_8, - .allocMethod = SbcAllocMethod::ALLOC_MD_L, - .bitsPerSample = BitsPerSample::BITS_16, - .minBitpool = 2, - .maxBitpool = 53}; - -// AAC: mSampleRate:(44100), mBitsPerSample:(16), mChannelMode:(STEREO) -static const AacParameters kDefaultOffloadAacCapability = { - .objectType = AacObjectType::MPEG2_LC, - .sampleRate = SampleRate::RATE_44100, - .channelMode = ChannelMode::STEREO, - .variableBitRateEnabled = AacVariableBitRate::ENABLED, - .bitsPerSample = BitsPerSample::BITS_16}; - -// LDAC: mSampleRate:(44100|48000|88200|96000), mBitsPerSample:(16|24|32), -// mChannelMode:(DUAL|STEREO) -static const LdacParameters kDefaultOffloadLdacCapability = { - .sampleRate = static_cast( - SampleRate::RATE_44100 | SampleRate::RATE_48000 | - SampleRate::RATE_88200 | SampleRate::RATE_96000), - .channelMode = static_cast(LdacChannelMode::DUAL | - LdacChannelMode::STEREO), - .qualityIndex = LdacQualityIndex::QUALITY_HIGH, - .bitsPerSample = static_cast(BitsPerSample::BITS_16 | - BitsPerSample::BITS_24 | - BitsPerSample::BITS_32)}; - -// aptX: mSampleRate:(44100|48000), mBitsPerSample:(16), mChannelMode:(STEREO) -static const AptxParameters kDefaultOffloadAptxCapability = { - .sampleRate = static_cast(SampleRate::RATE_44100 | - SampleRate::RATE_48000), - .channelMode = ChannelMode::STEREO, - .bitsPerSample = BitsPerSample::BITS_16, -}; - -// aptX HD: mSampleRate:(44100|48000), mBitsPerSample:(24), -// mChannelMode:(STEREO) -static const AptxParameters kDefaultOffloadAptxHdCapability = { - .sampleRate = static_cast(SampleRate::RATE_44100 | - SampleRate::RATE_48000), - .channelMode = ChannelMode::STEREO, - .bitsPerSample = BitsPerSample::BITS_24, -}; - -const std::vector kDefaultOffloadA2dpCodecCapabilities = { - {.codecType = CodecType::SBC, .capabilities = {}}, - {.codecType = CodecType::AAC, .capabilities = {}}, - {.codecType = CodecType::LDAC, .capabilities = {}}, - {.codecType = CodecType::APTX, .capabilities = {}}, - {.codecType = CodecType::APTX_HD, .capabilities = {}}}; - -static bool IsSingleBit(uint32_t bitmasks, uint32_t bitfield) { - bool single = false; - uint32_t test_bit = 0x00000001; - while (test_bit <= bitmasks && test_bit <= bitfield) { - if (bitfield & test_bit && bitmasks & test_bit) { - if (single) return false; - single = true; - } - if (test_bit == 0x80000000) break; - test_bit <<= 1; - } - return single; -} - -static bool IsOffloadSbcConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); -static bool IsOffloadAacConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); -static bool IsOffloadLdacConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); -static bool IsOffloadAptxConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); -static bool IsOffloadAptxHdConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific); - -static bool IsOffloadSbcConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getDiscriminator() != - CodecConfiguration::CodecSpecific::hidl_discriminator::sbcConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } - const SbcParameters sbc_data = codec_specific.sbcConfig(); - if (!IsSingleBit(static_cast(sbc_data.sampleRate), 0xff) || - !IsSingleBit(static_cast(sbc_data.channelMode), 0x0f) || - !IsSingleBit(static_cast(sbc_data.blockLength), 0xf0) || - !IsSingleBit(static_cast(sbc_data.numSubbands), 0x0c) || - !IsSingleBit(static_cast(sbc_data.allocMethod), 0x03) || - !IsSingleBit(static_cast(sbc_data.bitsPerSample), 0x07) || - sbc_data.minBitpool > sbc_data.maxBitpool) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } else if ((sbc_data.sampleRate & kDefaultOffloadSbcCapability.sampleRate) && - (sbc_data.channelMode & - kDefaultOffloadSbcCapability.channelMode) && - (sbc_data.blockLength & - kDefaultOffloadSbcCapability.blockLength) && - (sbc_data.numSubbands & - kDefaultOffloadSbcCapability.numSubbands) && - (sbc_data.allocMethod & - kDefaultOffloadSbcCapability.allocMethod) && - (sbc_data.bitsPerSample & - kDefaultOffloadSbcCapability.bitsPerSample) && - (kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool && - sbc_data.maxBitpool <= kDefaultOffloadSbcCapability.maxBitpool)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << toString(codec_specific); - return false; -} - -static bool IsOffloadAacConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getDiscriminator() != - CodecConfiguration::CodecSpecific::hidl_discriminator::aacConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } - const AacParameters aac_data = codec_specific.aacConfig(); - if (!IsSingleBit(static_cast(aac_data.objectType), 0xf0) || - !IsSingleBit(static_cast(aac_data.sampleRate), 0xff) || - !IsSingleBit(static_cast(aac_data.channelMode), 0x03) || - !IsSingleBit(static_cast(aac_data.bitsPerSample), 0x07)) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } else if ((aac_data.objectType & kDefaultOffloadAacCapability.objectType) && - (aac_data.sampleRate & kDefaultOffloadAacCapability.sampleRate) && - (aac_data.channelMode & - kDefaultOffloadAacCapability.channelMode) && - (aac_data.variableBitRateEnabled == AacVariableBitRate::DISABLED || - kDefaultOffloadAacCapability.variableBitRateEnabled == - AacVariableBitRate::ENABLED) && - (aac_data.bitsPerSample & - kDefaultOffloadAacCapability.bitsPerSample)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << toString(codec_specific); - return false; -} - -static bool IsOffloadLdacConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getDiscriminator() != - CodecConfiguration::CodecSpecific::hidl_discriminator::ldacConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } - const LdacParameters ldac_data = codec_specific.ldacConfig(); - if (!IsSingleBit(static_cast(ldac_data.sampleRate), 0xff) || - !IsSingleBit(static_cast(ldac_data.channelMode), 0x07) || - (ldac_data.qualityIndex > LdacQualityIndex::QUALITY_LOW && - ldac_data.qualityIndex != LdacQualityIndex::QUALITY_ABR) || - !IsSingleBit(static_cast(ldac_data.bitsPerSample), 0x07)) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } else if ((ldac_data.sampleRate & - kDefaultOffloadLdacCapability.sampleRate) && - (ldac_data.channelMode & - kDefaultOffloadLdacCapability.channelMode) && - (ldac_data.bitsPerSample & - kDefaultOffloadLdacCapability.bitsPerSample)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << toString(codec_specific); - return false; -} - -static bool IsOffloadAptxConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getDiscriminator() != - CodecConfiguration::CodecSpecific::hidl_discriminator::aptxConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } - const AptxParameters aptx_data = codec_specific.aptxConfig(); - if (!IsSingleBit(static_cast(aptx_data.sampleRate), 0xff) || - !IsSingleBit(static_cast(aptx_data.channelMode), 0x03) || - !IsSingleBit(static_cast(aptx_data.bitsPerSample), 0x07)) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } else if ((aptx_data.sampleRate & - kDefaultOffloadAptxCapability.sampleRate) && - (aptx_data.channelMode & - kDefaultOffloadAptxCapability.channelMode) && - (aptx_data.bitsPerSample & - kDefaultOffloadAptxCapability.bitsPerSample)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << toString(codec_specific); - return false; -} - -static bool IsOffloadAptxHdConfigurationValid( - const CodecConfiguration::CodecSpecific& codec_specific) { - if (codec_specific.getDiscriminator() != - CodecConfiguration::CodecSpecific::hidl_discriminator::aptxConfig) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } - const AptxParameters aptx_data = codec_specific.aptxConfig(); - if (!IsSingleBit(static_cast(aptx_data.sampleRate), 0xff) || - !IsSingleBit(static_cast(aptx_data.channelMode), 0x03) || - !IsSingleBit(static_cast(aptx_data.bitsPerSample), 0x07)) { - LOG(WARNING) << __func__ - << ": Invalid CodecSpecific=" << toString(codec_specific); - return false; - } else if ((aptx_data.sampleRate & - kDefaultOffloadAptxHdCapability.sampleRate) && - (aptx_data.channelMode & - kDefaultOffloadAptxHdCapability.channelMode) && - (aptx_data.bitsPerSample & - kDefaultOffloadAptxHdCapability.bitsPerSample)) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported CodecSpecific=" << toString(codec_specific); - return false; -} - -std::vector GetSoftwarePcmCapabilities() { - return std::vector(1, kDefaultSoftwarePcmCapabilities); -} - -std::vector GetOffloadCodecCapabilities( - const SessionType& session_type) { - if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { - return std::vector(0); - } - std::vector offload_a2dp_codec_capabilities = - kDefaultOffloadA2dpCodecCapabilities; - for (auto& codec_capability : offload_a2dp_codec_capabilities) { - switch (codec_capability.codecType) { - case CodecType::SBC: - codec_capability.capabilities.sbcCapabilities( - kDefaultOffloadSbcCapability); - break; - case CodecType::AAC: - codec_capability.capabilities.aacCapabilities( - kDefaultOffloadAacCapability); - break; - case CodecType::LDAC: - codec_capability.capabilities.ldacCapabilities( - kDefaultOffloadLdacCapability); - break; - case CodecType::APTX: - codec_capability.capabilities.aptxCapabilities( - kDefaultOffloadAptxCapability); - break; - case CodecType::APTX_HD: - codec_capability.capabilities.aptxCapabilities( - kDefaultOffloadAptxHdCapability); - break; - case CodecType::UNKNOWN: - codec_capability = {}; - break; - } - } - return offload_a2dp_codec_capabilities; -} - -bool IsSoftwarePcmConfigurationValid(const PcmParameters& pcm_config) { - if ((pcm_config.sampleRate != SampleRate::RATE_44100 && - pcm_config.sampleRate != SampleRate::RATE_48000 && - pcm_config.sampleRate != SampleRate::RATE_88200 && - pcm_config.sampleRate != SampleRate::RATE_96000 && - pcm_config.sampleRate != SampleRate::RATE_16000 && - pcm_config.sampleRate != SampleRate::RATE_24000) || - (pcm_config.bitsPerSample != BitsPerSample::BITS_16 && - pcm_config.bitsPerSample != BitsPerSample::BITS_24 && - pcm_config.bitsPerSample != BitsPerSample::BITS_32) || - (pcm_config.channelMode != ChannelMode::MONO && - pcm_config.channelMode != ChannelMode::STEREO)) { - LOG(WARNING) << __func__ - << ": Invalid PCM Configuration=" << toString(pcm_config); - return false; - } else if (pcm_config.sampleRate & - kDefaultSoftwarePcmCapabilities.sampleRate && - pcm_config.bitsPerSample & - kDefaultSoftwarePcmCapabilities.bitsPerSample && - pcm_config.channelMode & - kDefaultSoftwarePcmCapabilities.channelMode) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported PCM Configuration=" << toString(pcm_config); - return false; -} - -bool IsOffloadCodecConfigurationValid(const SessionType& session_type, - const CodecConfiguration& codec_config) { - if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) { - LOG(ERROR) << __func__ - << ": Invalid SessionType=" << toString(session_type); - return false; - } else if (codec_config.encodedAudioBitrate < 0x00000001 || - 0x00ffffff < codec_config.encodedAudioBitrate) { - LOG(ERROR) << __func__ << ": Unsupported Codec Configuration=" - << toString(codec_config); - return false; - } - const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config; - switch (codec_config.codecType) { - case CodecType::SBC: - if (IsOffloadSbcConfigurationValid(codec_specific)) { - return true; - } - return false; - case CodecType::AAC: - if (IsOffloadAacConfigurationValid(codec_specific)) { - return true; - } - return false; - case CodecType::LDAC: - if (IsOffloadLdacConfigurationValid(codec_specific)) { - return true; - } - return false; - case CodecType::APTX: - if (IsOffloadAptxConfigurationValid(codec_specific)) { - return true; - } - return false; - case CodecType::APTX_HD: - if (IsOffloadAptxHdConfigurationValid(codec_specific)) { - return true; - } - return false; - case CodecType::UNKNOWN: - return false; - } - return false; -} - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.h deleted file mode 100644 index e71dc8a..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2018 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 - -namespace android { -namespace bluetooth { -namespace audio { - -using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities; -using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration; -using ::android::hardware::bluetooth::audio::V2_0::PcmParameters; -using ::android::hardware::bluetooth::audio::V2_0::SessionType; - -std::vector GetSoftwarePcmCapabilities(); -std::vector GetOffloadCodecCapabilities( - const SessionType& session_type); - -bool IsSoftwarePcmConfigurationValid(const PcmParameters& pcm_config); -bool IsOffloadCodecConfigurationValid(const SessionType& session_type, - const CodecConfiguration& codec_config); - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp deleted file mode 100644 index c90ce6d..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2018 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. - */ - -#define LOG_TAG "BTAudioProviderSessionCodecsDB_2_1" - -#include "BluetoothAudioSupportedCodecsDB_2_1.h" - -#include - -namespace android { -namespace bluetooth { -namespace audio { - -using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample; -using ::android::hardware::bluetooth::audio::V2_0::ChannelMode; - -using SampleRate_2_0 = ::android::hardware::bluetooth::audio::V2_0::SampleRate; -using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate; - -using SessionType_2_1 = - ::android::hardware::bluetooth::audio::V2_1::SessionType; -using SessionType_2_0 = - ::android::hardware::bluetooth::audio::V2_0::SessionType; - -namespace { -bool is_2_0_session_type( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type) { - if (session_type == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH || - session_type == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH || - session_type == SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH) { - return true; - } else { - return false; - } -} -} // namespace - -static const ::android::hardware::bluetooth::audio::V2_1::PcmParameters - kDefaultSoftwarePcmCapabilities_2_1 = { - .sampleRate = static_cast( - SampleRate_2_1::RATE_44100 | SampleRate_2_1::RATE_48000 | - SampleRate_2_1::RATE_88200 | SampleRate_2_1::RATE_96000 | - SampleRate_2_1::RATE_16000 | SampleRate_2_1::RATE_24000), - .channelMode = - static_cast(ChannelMode::MONO | ChannelMode::STEREO), - .bitsPerSample = static_cast(BitsPerSample::BITS_16 | - BitsPerSample::BITS_24 | - BitsPerSample::BITS_32)}; - -std::vector<::android::hardware::bluetooth::audio::V2_1::PcmParameters> -GetSoftwarePcmCapabilities_2_1() { - return std::vector< - ::android::hardware::bluetooth::audio::V2_1::PcmParameters>( - 1, kDefaultSoftwarePcmCapabilities_2_1); -} - -std::vector GetOffloadCodecCapabilities( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type) { - if (is_2_0_session_type(session_type)) { - return GetOffloadCodecCapabilities( - static_cast(session_type)); - } - return std::vector(0); -} - -bool IsSoftwarePcmConfigurationValid_2_1( - const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& - pcm_config) { - if ((pcm_config.sampleRate != SampleRate_2_1::RATE_44100 && - pcm_config.sampleRate != SampleRate_2_1::RATE_48000 && - pcm_config.sampleRate != SampleRate_2_1::RATE_88200 && - pcm_config.sampleRate != SampleRate_2_1::RATE_96000 && - pcm_config.sampleRate != SampleRate_2_1::RATE_16000 && - pcm_config.sampleRate != SampleRate_2_1::RATE_24000) || - (pcm_config.bitsPerSample != BitsPerSample::BITS_16 && - pcm_config.bitsPerSample != BitsPerSample::BITS_24 && - pcm_config.bitsPerSample != BitsPerSample::BITS_32) || - (pcm_config.channelMode != ChannelMode::MONO && - pcm_config.channelMode != ChannelMode::STEREO)) { - LOG(WARNING) << __func__ - << ": Invalid PCM Configuration=" << toString(pcm_config); - return false; - } else if (pcm_config.sampleRate & - kDefaultSoftwarePcmCapabilities_2_1.sampleRate && - pcm_config.bitsPerSample & - kDefaultSoftwarePcmCapabilities_2_1.bitsPerSample && - pcm_config.channelMode & - kDefaultSoftwarePcmCapabilities_2_1.channelMode && - pcm_config.dataIntervalUs != 0) { - return true; - } - LOG(WARNING) << __func__ - << ": Unsupported PCM Configuration=" << toString(pcm_config); - return false; -} - -bool IsOffloadCodecConfigurationValid( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type, - const ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration& - codec_config) { - if (is_2_0_session_type(session_type)) { - return IsOffloadCodecConfigurationValid( - static_cast(session_type), codec_config); - } - - return false; -} - -bool IsOffloadLeAudioConfigurationValid( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type, - const ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration&) { - - if (session_type != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && - session_type != SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) { - return false; - } - - //TODO: perform checks on le_audio_codec_config once we know supported parameters - - return true; -} - -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h deleted file mode 100644 index a52636c..0000000 --- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2020 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 "BluetoothAudioSupportedCodecsDB.h" - -#include - -namespace android { -namespace bluetooth { -namespace audio { - -std::vector<::android::hardware::bluetooth::audio::V2_1::PcmParameters> -GetSoftwarePcmCapabilities_2_1(); -std::vector<::android::hardware::bluetooth::audio::V2_0::CodecCapabilities> -GetOffloadCodecCapabilities( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type); - -bool IsSoftwarePcmConfigurationValid_2_1( - const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& - pcm_config); - -bool IsOffloadCodecConfigurationValid( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type, - const ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration& - codec_config); - -bool IsOffloadLeAudioConfigurationValid( - const ::android::hardware::bluetooth::audio::V2_1::SessionType& - session_type, - const ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration& - le_audio_codec_config); -} // namespace audio -} // namespace bluetooth -} // namespace android diff --git a/bluetooth/include/bdroid_buildcfg.h b/bluetooth/bdroid_buildcfg.h similarity index 100% rename from bluetooth/include/bdroid_buildcfg.h rename to bluetooth/bdroid_buildcfg.h diff --git a/device.mk b/device.mk index 2b9af9e..ff254f0 100644 --- a/device.mk +++ b/device.mk @@ -22,10 +22,6 @@ PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true # Soong namespaces PRODUCT_SOONG_NAMESPACES += device/peter/gsi -# Reuiqred for system-side HALs like sysbta -# TODO: Can we work around this? -SELINUX_IGNORE_NEVERALLOWS := true - # Overlay PRODUCT_PACKAGES += \ GsiFrameworkResTarget \ @@ -56,15 +52,6 @@ PRODUCT_PACKAGES += \ Launcher3QuickStep \ ThemePicker -# Bluetooth Audio (System-side HAL, sysbta) -PRODUCT_PACKAGES += \ - audio.sysbta.default \ - android.hardware.bluetooth.audio-service-system - -PRODUCT_COPY_FILES += \ - device/peter/gsi/bluetooth/audio/config/sysbta_audio_policy_configuration.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/sysbta_audio_policy_configuration.xml \ - device/peter/gsi/bluetooth/audio/config/sysbta_audio_policy_configuration_7_0.xml:$(TARGET_COPY_OUTY_SYSTEM)/etc/sysbta_audio_policy_configuration_7_0.xml - # Enable ro.adb.secure on userdebug and user ifeq (,$(filter eng,$(TARGET_BUILD_VARIANT))) PRODUCT_SYSTEM_EXT_PROPERTIES += \ diff --git a/sepolicy/private/file_contexts b/sepolicy/private/file_contexts index 7ba1280..a319446 100644 --- a/sepolicy/private/file_contexts +++ b/sepolicy/private/file_contexts @@ -1,3 +1,2 @@ /system/system_ext/bin/init_gsi u:object_r:init_gsi_exec:s0 /system/system_ext/quirks(/.*)? u:object_r:system_file:s0 -/system/bin/hw/android\.hardware\.bluetooth\.audio-service-system u:object_r:hal_audio_sysbta_exec:s0 diff --git a/sepolicy/private/hal_audio_sysbta.te b/sepolicy/private/hal_audio_sysbta.te deleted file mode 100644 index d871ed3..0000000 --- a/sepolicy/private/hal_audio_sysbta.te +++ /dev/null @@ -1,10 +0,0 @@ -type hal_audio_sysbta, domain, coredomain; -hal_server_domain(hal_audio_sysbta, hal_audio) - -type hal_audio_sysbta_exec, exec_type, system_file_type, file_type; -init_daemon_domain(hal_audio_sysbta) - -hal_client_domain(hal_audio_sysbta, hal_allocator) - -# allow audioserver to call hal_audio dump with its own fd to retrieve status -allow hal_audio_sysbta audioserver:fifo_file write; diff --git a/sepolicy/private/service_contexts b/sepolicy/private/service_contexts index 73c6722..7680633 100644 --- a/sepolicy/private/service_contexts +++ b/sepolicy/private/service_contexts @@ -8,6 +8,3 @@ irit u:object_r:radio_service:s0 # MTK IMS mwis u:object_r:radio_service:s0 mtkIms u:object_r:radio_service:s0 - -# Audio AIDL interface -android.hardware.bluetooth.audio.IBluetoothAudioProviderFactory/sysbta u:object_r:hal_audio_service:s0 diff --git a/system.prop b/system.prop index a999301..837843e 100644 --- a/system.prop +++ b/system.prop @@ -12,21 +12,3 @@ persist.dbg.wfc_avail_ovr=1 persist.dbg.allow_ims_off=1 # Enable hw keys by default (unless overridden by user) persist.sys.gsi.hw.mainkeys=0 -# Enable system-side generic bluetooth audio HAL -persist.bluetooth.system_audio_hal.enabled=1 -# Set commonly-supported Bluetooth profiles to enabled -# TODO: Enable BLE Audio profiles on newer vendors -bluetooth.profile.asha.central.enabled?=true -bluetooth.profile.a2dp.source.enabled?=true -bluetooth.profile.avrcp.target.enabled?=true -bluetooth.profile.bas.client.enabled?=true -bluetooth.profile.gatt.enabled?=true -bluetooth.profile.hfp.ag.enabled?=true -bluetooth.profile.hid.device.enabled?=true -bluetooth.profile.hid.host.enabled?=true -bluetooth.profile.map.server.enabled?=true -bluetooth.profile.opp.enabled?=true -bluetooth.profile.pan.nap.enabled?=true -bluetooth.profile.pan.panu.enabled?=true -bluetooth.profile.pbap.server.enabled?=true -bluetooth.profile.sap.server.enabled?=true