From a88cf60b87b23d813e9c1ddd32fa892034b5f821 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 13 Dec 2023 14:35:11 -0800 Subject: [PATCH] audio: Fix BT AIDL HAL module implementation In order to align with legacy behavior, when opening a stream, the module must suggest the current configuration of the BT session. For that to work, the BT device proxy must be opened prior to creating a stream, code moved to ModuleBluetooth. Fix minor inconsistencies and bugs found during testing. Bug: 301213930 Bug: 316027906 Test: atest pts-bot Change-Id: I04ddaf73be82f872a3f32a789563c3cbd648eb61 --- .../default/bluetooth/DevicePortProxy.cpp | 37 +-- .../default/bluetooth/ModuleBluetooth.cpp | 232 +++++++++++++-- .../default/bluetooth/StreamBluetooth.cpp | 270 +++++++----------- .../include/core-impl/DevicePortProxy.h | 20 +- .../include/core-impl/ModuleBluetooth.h | 30 ++ .../include/core-impl/StreamBluetooth.h | 49 ++-- .../aidl_session/BluetoothAudioSession.cpp | 4 +- 7 files changed, 397 insertions(+), 245 deletions(-) diff --git a/audio/aidl/default/bluetooth/DevicePortProxy.cpp b/audio/aidl/default/bluetooth/DevicePortProxy.cpp index 1be0875a55..d772c20090 100644 --- a/audio/aidl/default/bluetooth/DevicePortProxy.cpp +++ b/audio/aidl/default/bluetooth/DevicePortProxy.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#define LOG_TAG "AHAL_BluetoothPortProxy" +#define LOG_TAG "AHAL_BluetoothAudioPort" #include #include @@ -254,12 +254,7 @@ bool BluetoothAudioPortAidl::inUse() const { return (mCookie != ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined); } -bool BluetoothAudioPortAidl::getPreferredDataIntervalUs(size_t* interval_us) const { - if (!interval_us) { - LOG(ERROR) << __func__ << ": bad input arg"; - return false; - } - +bool BluetoothAudioPortAidl::getPreferredDataIntervalUs(size_t& interval_us) const { if (!inUse()) { LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; return false; @@ -272,16 +267,11 @@ bool BluetoothAudioPortAidl::getPreferredDataIntervalUs(size_t* interval_us) con return false; } - *interval_us = hal_audio_cfg.get().dataIntervalUs; + interval_us = hal_audio_cfg.get().dataIntervalUs; return true; } -bool BluetoothAudioPortAidl::loadAudioConfig(PcmConfiguration* audio_cfg) const { - if (!audio_cfg) { - LOG(ERROR) << __func__ << ": bad input arg"; - return false; - } - +bool BluetoothAudioPortAidl::loadAudioConfig(PcmConfiguration& audio_cfg) { if (!inUse()) { LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; return false; @@ -293,15 +283,26 @@ bool BluetoothAudioPortAidl::loadAudioConfig(PcmConfiguration* audio_cfg) const LOG(ERROR) << __func__ << ": unsupported audio cfg tag"; return false; } - *audio_cfg = hal_audio_cfg.get(); + audio_cfg = hal_audio_cfg.get(); LOG(VERBOSE) << __func__ << debugMessage() << ", state*=" << getState() << ", PcmConfig=[" - << audio_cfg->toString() << "]"; - if (audio_cfg->channelMode == ChannelMode::UNKNOWN) { + << audio_cfg.toString() << "]"; + if (audio_cfg.channelMode == ChannelMode::UNKNOWN) { return false; } return true; } +bool BluetoothAudioPortAidlOut::loadAudioConfig(PcmConfiguration& audio_cfg) { + if (!BluetoothAudioPortAidl::loadAudioConfig(audio_cfg)) return false; + // WAR to support Mono / 16 bits per sample as the Bluetooth stack requires + if (audio_cfg.channelMode == ChannelMode::MONO && audio_cfg.bitsPerSample == 16) { + mIsStereoToMono = true; + audio_cfg.channelMode = ChannelMode::STEREO; + LOG(INFO) << __func__ << ": force channels = to be AUDIO_CHANNEL_OUT_STEREO"; + } + return true; +} + bool BluetoothAudioPortAidl::standby() { if (!inUse()) { LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use"; @@ -435,7 +436,7 @@ bool BluetoothAudioPortAidl::suspend() { retval = condWaitState(BluetoothStreamState::SUSPENDING); } else { LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState() - << " Hal fails"; + << " failure to suspend stream"; } } } diff --git a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp index 03abd34f4c..9084b3044c 100644 --- a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp +++ b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp @@ -24,13 +24,25 @@ using aidl::android::hardware::audio::common::SinkMetadata; using aidl::android::hardware::audio::common::SourceMetadata; +using aidl::android::hardware::bluetooth::audio::ChannelMode; +using aidl::android::hardware::bluetooth::audio::PcmConfiguration; +using aidl::android::media::audio::common::AudioChannelLayout; +using aidl::android::media::audio::common::AudioConfigBase; using aidl::android::media::audio::common::AudioDeviceDescription; using aidl::android::media::audio::common::AudioDeviceType; +using aidl::android::media::audio::common::AudioFormatDescription; +using aidl::android::media::audio::common::AudioFormatType; +using aidl::android::media::audio::common::AudioIoFlags; using aidl::android::media::audio::common::AudioOffloadInfo; using aidl::android::media::audio::common::AudioPort; +using aidl::android::media::audio::common::AudioPortConfig; using aidl::android::media::audio::common::AudioPortExt; +using aidl::android::media::audio::common::AudioProfile; +using aidl::android::media::audio::common::Int; using aidl::android::media::audio::common::MicrophoneInfo; +using aidl::android::media::audio::common::PcmType; using android::bluetooth::audio::aidl::BluetoothAudioPortAidl; +using android::bluetooth::audio::aidl::BluetoothAudioPortAidlIn; using android::bluetooth::audio::aidl::BluetoothAudioPortAidlOut; // TODO(b/312265159) bluetooth audio should be in its own process @@ -39,6 +51,35 @@ extern "C" binder_status_t createIBluetoothAudioProviderFactory(); namespace aidl::android::hardware::audio::core { +namespace { + +PcmType pcmTypeFromBitsPerSample(int8_t bitsPerSample) { + if (bitsPerSample == 8) + return PcmType::UINT_8_BIT; + else if (bitsPerSample == 16) + return PcmType::INT_16_BIT; + else if (bitsPerSample == 24) + return PcmType::INT_24_BIT; + else if (bitsPerSample == 32) + return PcmType::INT_32_BIT; + ALOGE("Unsupported bitsPerSample: %d", bitsPerSample); + return PcmType::DEFAULT; +} + +AudioChannelLayout channelLayoutFromChannelMode(ChannelMode mode) { + if (mode == ChannelMode::MONO) { + return AudioChannelLayout::make( + AudioChannelLayout::LAYOUT_MONO); + } else if (mode == ChannelMode::STEREO || mode == ChannelMode::DUALMONO) { + return AudioChannelLayout::make( + AudioChannelLayout::LAYOUT_STEREO); + } + ALOGE("Unsupported channel mode: %s", toString(mode).c_str()); + return AudioChannelLayout{}; +} + +} // namespace + ModuleBluetooth::ModuleBluetooth(std::unique_ptr&& config) : Module(Type::BLUETOOTH, std::move(config)) { // TODO(b/312265159) bluetooth audio should be in its own process @@ -95,66 +136,130 @@ ndk::ScopedAStatus ModuleBluetooth::setMicMute(bool in_mute __unused) { return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } +ndk::ScopedAStatus ModuleBluetooth::setAudioPortConfig(const AudioPortConfig& in_requested, + AudioPortConfig* out_suggested, + bool* _aidl_return) { + auto fillConfig = [this](const AudioPort& port, AudioPortConfig* config) { + if (port.ext.getTag() == AudioPortExt::device) { + CachedProxy proxy; + auto status = findOrCreateProxy(port, proxy); + if (status.isOk()) { + const auto& pcmConfig = proxy.pcmConfig; + LOG(DEBUG) << "setAudioPortConfig: suggesting port config from " + << pcmConfig.toString(); + const auto pcmType = pcmTypeFromBitsPerSample(pcmConfig.bitsPerSample); + const auto channelMask = channelLayoutFromChannelMode(pcmConfig.channelMode); + if (pcmType != PcmType::DEFAULT && channelMask != AudioChannelLayout{}) { + config->format = + AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = pcmType}; + config->channelMask = channelMask; + config->sampleRate = Int{.value = pcmConfig.sampleRateHz}; + config->flags = port.flags; + config->ext = port.ext; + return true; + } + } + } + return generateDefaultPortConfig(port, config); + }; + return Module::setAudioPortConfigImpl(in_requested, fillConfig, out_suggested, _aidl_return); +} + +ndk::ScopedAStatus ModuleBluetooth::checkAudioPatchEndpointsMatch( + const std::vector& sources, const std::vector& sinks) { + // Both sources and sinks must be non-empty, this is guaranteed by 'setAudioPatch'. + const bool isInput = sources[0]->ext.getTag() == AudioPortExt::device; + const int32_t devicePortId = isInput ? sources[0]->portId : sinks[0]->portId; + const auto proxyIt = mProxies.find(devicePortId); + if (proxyIt == mProxies.end()) return ndk::ScopedAStatus::ok(); + const auto& pcmConfig = proxyIt->second.pcmConfig; + const AudioPortConfig* mixPortConfig = isInput ? sinks[0] : sources[0]; + if (!StreamBluetooth::checkConfigParams( + pcmConfig, AudioConfigBase{.sampleRate = mixPortConfig->sampleRate->value, + .channelMask = *(mixPortConfig->channelMask), + .format = *(mixPortConfig->format)})) { + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + } + if (int32_t handle = mixPortConfig->ext.get().handle; handle > 0) { + mConnections.insert(std::pair(handle, devicePortId)); + } + return ndk::ScopedAStatus::ok(); +} + +void ModuleBluetooth::onExternalDeviceConnectionChanged(const AudioPort& audioPort, + bool connected) { + if (!connected) mProxies.erase(audioPort.id); +} + ndk::ScopedAStatus ModuleBluetooth::createInputStream( StreamContext&& context, const SinkMetadata& sinkMetadata, const std::vector& microphones, std::shared_ptr* result) { + CachedProxy proxy; + RETURN_STATUS_IF_ERROR(fetchAndCheckProxy(context, proxy)); return createStreamInstance(result, std::move(context), sinkMetadata, - microphones, getBtProfileManagerHandles()); + microphones, getBtProfileManagerHandles(), + proxy.ptr, proxy.pcmConfig); } ndk::ScopedAStatus ModuleBluetooth::createOutputStream( StreamContext&& context, const SourceMetadata& sourceMetadata, const std::optional& offloadInfo, std::shared_ptr* result) { + CachedProxy proxy; + RETURN_STATUS_IF_ERROR(fetchAndCheckProxy(context, proxy)); return createStreamInstance(result, std::move(context), sourceMetadata, - offloadInfo, getBtProfileManagerHandles()); + offloadInfo, getBtProfileManagerHandles(), + proxy.ptr, proxy.pcmConfig); } -ndk::ScopedAStatus ModuleBluetooth::populateConnectedDevicePort(AudioPort* audioPort, int32_t) { +ndk::ScopedAStatus ModuleBluetooth::populateConnectedDevicePort(AudioPort* audioPort, + int32_t nextPortId) { if (audioPort->ext.getTag() != AudioPortExt::device) { LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString(); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } + if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::IsAidlAvailable()) { + LOG(ERROR) << __func__ << ": IBluetoothAudioProviderFactory AIDL service not available"; + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } const auto& devicePort = audioPort->ext.get(); const auto& description = devicePort.device.type; - // Since the configuration of the BT module is static, there is nothing to populate here. - // However, this method must return an error when the device can not be connected, - // this is determined by the status of BT profiles. + // This method must return an error when the device can not be connected. if (description.connection == AudioDeviceDescription::CONNECTION_BT_A2DP) { bool isA2dpEnabled = false; if (!!mBluetoothA2dp) { RETURN_STATUS_IF_ERROR((*mBluetoothA2dp).isEnabled(&isA2dpEnabled)); } LOG(DEBUG) << __func__ << ": isA2dpEnabled: " << isA2dpEnabled; - return isA2dpEnabled ? ndk::ScopedAStatus::ok() - : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + if (!isA2dpEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE) { bool isLeEnabled = false; if (!!mBluetoothLe) { RETURN_STATUS_IF_ERROR((*mBluetoothLe).isEnabled(&isLeEnabled)); } LOG(DEBUG) << __func__ << ": isLeEnabled: " << isLeEnabled; - return isLeEnabled ? ndk::ScopedAStatus::ok() - : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + if (!isLeEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } else if (description.connection == AudioDeviceDescription::CONNECTION_WIRELESS && description.type == AudioDeviceType::OUT_HEARING_AID) { - // Hearing aids can use a number of profiles, thus the only way to check - // connectivity is to try to talk to the BT HAL. - if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession:: - IsAidlAvailable()) { - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); - } - std::shared_ptr proxy = std::shared_ptr( - std::make_shared()); - if (proxy->registerPort(description)) { - LOG(DEBUG) << __func__ << ": registered hearing aid port"; - proxy->unregisterPort(); - return ndk::ScopedAStatus::ok(); - } - LOG(DEBUG) << __func__ << ": failed to register hearing aid port"; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + // Hearing aids can use a number of profiles, no single switch exists. + } else { + LOG(ERROR) << __func__ << ": unsupported device type: " << audioPort->toString(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - LOG(ERROR) << __func__ << ": unsupported device type: " << audioPort->toString(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + CachedProxy proxy; + RETURN_STATUS_IF_ERROR(createProxy(*audioPort, nextPortId, proxy)); + // Since the device is already connected and configured by the BT stack, provide + // the current configuration instead of all possible profiles. + const auto& pcmConfig = proxy.pcmConfig; + audioPort->profiles.clear(); + audioPort->profiles.push_back( + AudioProfile{.format = AudioFormatDescription{.type = AudioFormatType::PCM, + .pcm = pcmTypeFromBitsPerSample( + pcmConfig.bitsPerSample)}, + .channelMasks = std::vector( + {channelLayoutFromChannelMode(pcmConfig.channelMode)}), + .sampleRates = std::vector({pcmConfig.sampleRateHz})}); + LOG(DEBUG) << __func__ << ": " << audioPort->toString(); + return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus ModuleBluetooth::onMasterMuteChanged(bool) { @@ -167,4 +272,77 @@ ndk::ScopedAStatus ModuleBluetooth::onMasterVolumeChanged(float) { return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } +int32_t ModuleBluetooth::getNominalLatencyMs(const AudioPortConfig& portConfig) { + const auto connectionsIt = mConnections.find(portConfig.ext.get().handle); + if (connectionsIt != mConnections.end()) { + const auto proxyIt = mProxies.find(connectionsIt->second); + if (proxyIt != mProxies.end()) { + auto proxy = proxyIt->second.ptr; + size_t dataIntervalUs = 0; + if (!proxy->getPreferredDataIntervalUs(dataIntervalUs)) { + LOG(WARNING) << __func__ << ": could not fetch preferred data interval"; + } + const bool isInput = portConfig.flags->getTag() == AudioIoFlags::input; + return isInput ? StreamInBluetooth::getNominalLatencyMs(dataIntervalUs) + : StreamOutBluetooth::getNominalLatencyMs(dataIntervalUs); + } + } + LOG(ERROR) << __func__ << ": no connection or proxy found for " << portConfig.toString(); + return Module::getNominalLatencyMs(portConfig); +} + +ndk::ScopedAStatus ModuleBluetooth::createProxy(const AudioPort& audioPort, int32_t instancePortId, + CachedProxy& proxy) { + const bool isInput = audioPort.flags.getTag() == AudioIoFlags::input; + proxy.ptr = isInput ? std::shared_ptr( + std::make_shared()) + : std::shared_ptr( + std::make_shared()); + const auto& devicePort = audioPort.ext.get(); + if (const auto device = devicePort.device.type; !proxy.ptr->registerPort(device)) { + LOG(ERROR) << __func__ << ": failed to register BT port for " << device.toString(); + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + if (!proxy.ptr->loadAudioConfig(proxy.pcmConfig)) { + LOG(ERROR) << __func__ << ": state=" << proxy.ptr->getState() + << ", failed to load audio config"; + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + mProxies.insert(std::pair(instancePortId, proxy)); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus ModuleBluetooth::fetchAndCheckProxy(const StreamContext& context, + CachedProxy& proxy) { + const auto connectionsIt = mConnections.find(context.getMixPortHandle()); + if (connectionsIt != mConnections.end()) { + const auto proxyIt = mProxies.find(connectionsIt->second); + if (proxyIt != mProxies.end()) { + proxy = proxyIt->second; + mProxies.erase(proxyIt); + } + mConnections.erase(connectionsIt); + } + if (proxy.ptr != nullptr) { + if (!StreamBluetooth::checkConfigParams( + proxy.pcmConfig, AudioConfigBase{.sampleRate = context.getSampleRate(), + .channelMask = context.getChannelLayout(), + .format = context.getFormat()})) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + } + // Not having a proxy is OK, it may happen in VTS tests when streams are opened on unconnected + // mix ports. + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus ModuleBluetooth::findOrCreateProxy(const AudioPort& audioPort, + CachedProxy& proxy) { + if (auto proxyIt = mProxies.find(audioPort.id); proxyIt != mProxies.end()) { + proxy = proxyIt->second; + return ndk::ScopedAStatus::ok(); + } + return createProxy(audioPort, audioPort.id, proxy); +} + } // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp index 0cee7f4002..a73af1b6b4 100644 --- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp +++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp @@ -14,8 +14,9 @@ * limitations under the License. */ -#define LOG_TAG "AHAL_StreamBluetooth" +#include +#define LOG_TAG "AHAL_StreamBluetooth" #include #include #include @@ -31,6 +32,7 @@ using aidl::android::hardware::bluetooth::audio::ChannelMode; using aidl::android::hardware::bluetooth::audio::PcmConfiguration; using aidl::android::hardware::bluetooth::audio::PresentationPosition; using aidl::android::media::audio::common::AudioChannelLayout; +using aidl::android::media::audio::common::AudioConfigBase; using aidl::android::media::audio::common::AudioDevice; using aidl::android::media::audio::common::AudioDeviceAddress; using aidl::android::media::audio::common::AudioFormatDescription; @@ -48,51 +50,33 @@ namespace aidl::android::hardware::audio::core { constexpr int kBluetoothDefaultInputBufferMs = 20; constexpr int kBluetoothDefaultOutputBufferMs = 10; // constexpr int kBluetoothSpatializerOutputBufferMs = 10; +constexpr int kBluetoothDefaultRemoteDelayMs = 200; -// pcm configuration params are not really used by the module StreamBluetooth::StreamBluetooth(StreamContext* context, const Metadata& metadata, - ModuleBluetooth::BtProfileHandles&& btHandles) + ModuleBluetooth::BtProfileHandles&& btHandles, + const std::shared_ptr& btDeviceProxy, + const PcmConfiguration& pcmConfig) : StreamCommonImpl(context, metadata), - mSampleRate(getContext().getSampleRate()), - mChannelLayout(getContext().getChannelLayout()), - mFormat(getContext().getFormat()), mFrameSizeBytes(getContext().getFrameSize()), mIsInput(isInput(metadata)), mBluetoothA2dp(std::move(std::get(btHandles))), - mBluetoothLe(std::move(std::get(btHandles))) { - mPreferredDataIntervalUs = - (mIsInput ? kBluetoothDefaultInputBufferMs : kBluetoothDefaultOutputBufferMs) * 1000; - mPreferredFrameCount = frameCountFromDurationUs(mPreferredDataIntervalUs, mSampleRate); - mIsInitialized = false; - mIsReadyToClose = false; -} + mBluetoothLe(std::move(std::get(btHandles))), + mPreferredDataIntervalUs(pcmConfig.dataIntervalUs != 0 + ? pcmConfig.dataIntervalUs + : (mIsInput ? kBluetoothDefaultInputBufferMs + : kBluetoothDefaultOutputBufferMs) * + 1000), + mPreferredFrameCount( + frameCountFromDurationUs(mPreferredDataIntervalUs, pcmConfig.sampleRateHz)), + mBtDeviceProxy(btDeviceProxy) {} ::android::status_t StreamBluetooth::init() { - return ::android::OK; // defering this till we get AudioDeviceDescription -} - -const StreamCommonInterface::ConnectedDevices& StreamBluetooth::getConnectedDevices() const { std::lock_guard guard(mLock); - return StreamCommonImpl::getConnectedDevices(); -} - -ndk::ScopedAStatus StreamBluetooth::setConnectedDevices( - const std::vector& connectedDevices) { - if (mIsInput && connectedDevices.size() > 1) { - LOG(ERROR) << __func__ << ": wrong device size(" << connectedDevices.size() - << ") for input stream"; - return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + if (mBtDeviceProxy == nullptr) { + // This is a normal situation in VTS tests. + LOG(INFO) << __func__ << ": no BT HAL proxy, stream is non-functional"; } - for (const auto& connectedDevice : connectedDevices) { - if (connectedDevice.address.getTag() != AudioDeviceAddress::mac) { - LOG(ERROR) << __func__ << ": bad device address" << connectedDevice.address.toString(); - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } - } - std::lock_guard guard(mLock); - RETURN_STATUS_IF_ERROR(StreamCommonImpl::setConnectedDevices(connectedDevices)); - mIsInitialized = false; // updated connected device list, need initialization - return ndk::ScopedAStatus::ok(); + return ::android::OK; } ::android::status_t StreamBluetooth::drain(StreamDescriptor::DrainMode) { @@ -112,167 +96,111 @@ ndk::ScopedAStatus StreamBluetooth::setConnectedDevices( ::android::status_t StreamBluetooth::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount, int32_t* latencyMs) { std::lock_guard guard(mLock); - if (!mIsInitialized || mIsReadyToClose) { - // 'setConnectedDevices' has been called or stream is ready to close, so no transfers + if (mBtDeviceProxy == nullptr || mBtDeviceProxy->getState() == BluetoothStreamState::DISABLED) { *actualFrameCount = 0; *latencyMs = StreamDescriptor::LATENCY_UNKNOWN; return ::android::OK; } *actualFrameCount = 0; *latencyMs = 0; - for (auto proxy : mBtDeviceProxies) { - if (!proxy->start()) { - LOG(ERROR) << __func__ << ": state = " << proxy->getState() << " failed to start "; - return -EIO; - } - const size_t fc = std::min(frameCount, mPreferredFrameCount); - const size_t bytesToTransfer = fc * mFrameSizeBytes; - if (mIsInput) { - const size_t totalRead = proxy->readData(buffer, bytesToTransfer); - *actualFrameCount = std::max(*actualFrameCount, totalRead / mFrameSizeBytes); - } else { - const size_t totalWrite = proxy->writeData(buffer, bytesToTransfer); - *actualFrameCount = std::max(*actualFrameCount, totalWrite / mFrameSizeBytes); - } - PresentationPosition presentation_position; - if (!proxy->getPresentationPosition(presentation_position)) { - LOG(ERROR) << __func__ << ": getPresentationPosition returned error "; - return ::android::UNKNOWN_ERROR; - } - *latencyMs = - std::max(*latencyMs, (int32_t)(presentation_position.remoteDeviceAudioDelayNanos / - NANOS_PER_MILLISECOND)); + if (!mBtDeviceProxy->start()) { + LOG(ERROR) << __func__ << ": state= " << mBtDeviceProxy->getState() << " failed to start"; + return -EIO; } + const size_t fc = std::min(frameCount, mPreferredFrameCount); + const size_t bytesToTransfer = fc * mFrameSizeBytes; + if (mIsInput) { + const size_t totalRead = mBtDeviceProxy->readData(buffer, bytesToTransfer); + *actualFrameCount = std::max(*actualFrameCount, totalRead / mFrameSizeBytes); + } else { + const size_t totalWrite = mBtDeviceProxy->writeData(buffer, bytesToTransfer); + *actualFrameCount = std::max(*actualFrameCount, totalWrite / mFrameSizeBytes); + } + PresentationPosition presentation_position; + if (!mBtDeviceProxy->getPresentationPosition(presentation_position)) { + presentation_position.remoteDeviceAudioDelayNanos = + kBluetoothDefaultRemoteDelayMs * NANOS_PER_MILLISECOND; + LOG(WARNING) << __func__ << ": getPresentationPosition failed, latency info is unavailable"; + } + // TODO(b/317117580): incorporate logic from + // packages/modules/Bluetooth/system/audio_bluetooth_hw/stream_apis.cc + // out_calculate_feeding_delay_ms / in_calculate_starving_delay_ms + *latencyMs = std::max(*latencyMs, (int32_t)(presentation_position.remoteDeviceAudioDelayNanos / + NANOS_PER_MILLISECOND)); return ::android::OK; } -::android::status_t StreamBluetooth::initialize() { - if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::IsAidlAvailable()) { - LOG(ERROR) << __func__ << ": IBluetoothAudioProviderFactory service not available"; - return ::android::UNKNOWN_ERROR; - } - if (StreamCommonImpl::getConnectedDevices().empty()) { - LOG(ERROR) << __func__ << ", has no connected devices"; - return ::android::NO_INIT; - } - // unregister older proxies (if any) - for (auto proxy : mBtDeviceProxies) { - proxy->stop(); - proxy->unregisterPort(); - } - mBtDeviceProxies.clear(); - for (auto it = StreamCommonImpl::getConnectedDevices().begin(); - it != StreamCommonImpl::getConnectedDevices().end(); ++it) { - std::shared_ptr proxy = - mIsInput ? std::shared_ptr( - std::make_shared()) - : std::shared_ptr( - std::make_shared()); - if (proxy->registerPort(it->type)) { - LOG(ERROR) << __func__ << ": cannot init HAL"; - return ::android::UNKNOWN_ERROR; - } - PcmConfiguration config; - if (!proxy->loadAudioConfig(&config)) { - LOG(ERROR) << __func__ << ": state=" << proxy->getState() - << " failed to get audio config"; - return ::android::UNKNOWN_ERROR; - } - // TODO: Ensure minimum duration for spatialized output? - // WAR to support Mono / 16 bits per sample as the Bluetooth stack required - if (!mIsInput && config.channelMode == ChannelMode::MONO && config.bitsPerSample == 16) { - proxy->forcePcmStereoToMono(true); - config.channelMode = ChannelMode::STEREO; - LOG(INFO) << __func__ << ": force channels = to be AUDIO_CHANNEL_OUT_STEREO"; - } - if (!checkConfigParams(config)) { - LOG(ERROR) << __func__ << " checkConfigParams failed"; - return ::android::UNKNOWN_ERROR; - } - mBtDeviceProxies.push_back(std::move(proxy)); - } - mIsInitialized = true; - return ::android::OK; -} - -bool StreamBluetooth::checkConfigParams( - ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& config) { - if ((int)mSampleRate != config.sampleRateHz) { - LOG(ERROR) << __func__ << ": Sample Rate mismatch, stream val = " << mSampleRate - << " hal val = " << config.sampleRateHz; +// static +bool StreamBluetooth::checkConfigParams(const PcmConfiguration& pcmConfig, + const AudioConfigBase& config) { + if ((int)config.sampleRate != pcmConfig.sampleRateHz) { + LOG(ERROR) << __func__ << ": sample rate mismatch, stream value=" << config.sampleRate + << ", BT HAL value=" << pcmConfig.sampleRateHz; return false; } - auto channelCount = aidl::android::hardware::audio::common::getChannelCount(mChannelLayout); - if ((config.channelMode == ChannelMode::MONO && channelCount != 1) || - (config.channelMode == ChannelMode::STEREO && channelCount != 2)) { - LOG(ERROR) << __func__ << ": Channel count mismatch, stream val = " << channelCount - << " hal val = " << toString(config.channelMode); + const auto channelCount = + aidl::android::hardware::audio::common::getChannelCount(config.channelMask); + if ((pcmConfig.channelMode == ChannelMode::MONO && channelCount != 1) || + (pcmConfig.channelMode == ChannelMode::STEREO && channelCount != 2)) { + LOG(ERROR) << __func__ << ": Channel count mismatch, stream value=" << channelCount + << ", BT HAL value=" << toString(pcmConfig.channelMode); return false; } - if (mFormat.type != AudioFormatType::PCM) { - LOG(ERROR) << __func__ << ": unexpected format type " - << aidl::android::media::audio::common::toString(mFormat.type); + if (config.format.type != AudioFormatType::PCM) { + LOG(ERROR) << __func__ + << ": unexpected stream format type: " << toString(config.format.type); return false; } - int8_t bps = aidl::android::hardware::audio::common::getPcmSampleSizeInBytes(mFormat.pcm) * 8; - if (bps != config.bitsPerSample) { - LOG(ERROR) << __func__ << ": bits per sample mismatch, stream val = " << bps - << " hal val = " << config.bitsPerSample; + const int8_t bitsPerSample = + aidl::android::hardware::audio::common::getPcmSampleSizeInBytes(config.format.pcm) * 8; + if (bitsPerSample != pcmConfig.bitsPerSample) { + LOG(ERROR) << __func__ << ": bits per sample mismatch, stream value=" << bitsPerSample + << ", BT HAL value=" << pcmConfig.bitsPerSample; return false; } - if (config.dataIntervalUs > 0) { - mPreferredDataIntervalUs = - std::min((int32_t)mPreferredDataIntervalUs, config.dataIntervalUs); - mPreferredFrameCount = frameCountFromDurationUs(mPreferredDataIntervalUs, mSampleRate); - } return true; } ndk::ScopedAStatus StreamBluetooth::prepareToClose() { std::lock_guard guard(mLock); - mIsReadyToClose = true; + if (mBtDeviceProxy != nullptr) { + if (mBtDeviceProxy->getState() != BluetoothStreamState::DISABLED) { + mBtDeviceProxy->stop(); + } + } return ndk::ScopedAStatus::ok(); } ::android::status_t StreamBluetooth::standby() { std::lock_guard guard(mLock); - if (!mIsInitialized) { - if (auto status = initialize(); status != ::android::OK) return status; - } - for (auto proxy : mBtDeviceProxies) { - if (!proxy->suspend()) { - LOG(ERROR) << __func__ << ": state = " << proxy->getState() << " failed to stand by "; - return -EIO; - } - } + if (mBtDeviceProxy != nullptr) mBtDeviceProxy->suspend(); return ::android::OK; } ::android::status_t StreamBluetooth::start() { std::lock_guard guard(mLock); - if (!mIsInitialized) return initialize(); + if (mBtDeviceProxy != nullptr) mBtDeviceProxy->start(); return ::android::OK; } void StreamBluetooth::shutdown() { std::lock_guard guard(mLock); - for (auto proxy : mBtDeviceProxies) { - proxy->stop(); - proxy->unregisterPort(); + if (mBtDeviceProxy != nullptr) { + mBtDeviceProxy->stop(); + mBtDeviceProxy = nullptr; } - mBtDeviceProxies.clear(); } ndk::ScopedAStatus StreamBluetooth::updateMetadataCommon(const Metadata& metadata) { std::lock_guard guard(mLock); - if (!mIsInitialized) return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + if (mBtDeviceProxy == nullptr) { + return ndk::ScopedAStatus::ok(); + } bool isOk = true; if (isInput(metadata)) { - isOk = mBtDeviceProxies[0]->updateSinkMetadata(std::get(metadata)); + isOk = mBtDeviceProxy->updateSinkMetadata(std::get(metadata)); } else { - for (auto proxy : mBtDeviceProxies) { - if (!proxy->updateSourceMetadata(std::get(metadata))) isOk = false; - } + isOk = mBtDeviceProxy->updateSourceMetadata(std::get(metadata)); } return isOk ? ndk::ScopedAStatus::ok() : ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); @@ -280,7 +208,6 @@ ndk::ScopedAStatus StreamBluetooth::updateMetadataCommon(const Metadata& metadat ndk::ScopedAStatus StreamBluetooth::bluetoothParametersUpdated() { if (mIsInput) { - LOG(WARNING) << __func__ << ": not handled"; return ndk::ScopedAStatus::ok(); } auto applyParam = [](const std::shared_ptr& proxy, @@ -297,15 +224,10 @@ ndk::ScopedAStatus StreamBluetooth::bluetoothParametersUpdated() { bool hasLeParam, enableLe; auto btLe = mBluetoothLe.lock(); hasLeParam = btLe != nullptr && btLe->isEnabled(&enableLe).isOk(); - std::unique_lock lock(mLock); - ::android::base::ScopedLockAssertion lock_assertion(mLock); - if (!mIsInitialized) { - LOG(WARNING) << __func__ << ": init not done"; - return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); - } - for (auto proxy : mBtDeviceProxies) { - if ((hasA2dpParam && proxy->isA2dp() && !applyParam(proxy, enableA2dp)) || - (hasLeParam && proxy->isLeAudio() && !applyParam(proxy, enableLe))) { + std::lock_guard guard(mLock); + if (mBtDeviceProxy != nullptr) { + if ((hasA2dpParam && mBtDeviceProxy->isA2dp() && !applyParam(mBtDeviceProxy, enableA2dp)) || + (hasLeParam && mBtDeviceProxy->isLeAudio() && !applyParam(mBtDeviceProxy, enableLe))) { LOG(DEBUG) << __func__ << ": applyParam failed"; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } @@ -313,11 +235,20 @@ ndk::ScopedAStatus StreamBluetooth::bluetoothParametersUpdated() { return ndk::ScopedAStatus::ok(); } +// static +int32_t StreamInBluetooth::getNominalLatencyMs(size_t dataIntervalUs) { + if (dataIntervalUs == 0) dataIntervalUs = kBluetoothDefaultInputBufferMs * 1000LL; + return dataIntervalUs / 1000LL; +} + StreamInBluetooth::StreamInBluetooth(StreamContext&& context, const SinkMetadata& sinkMetadata, const std::vector& microphones, - ModuleBluetooth::BtProfileHandles&& btProfileHandles) + ModuleBluetooth::BtProfileHandles&& btProfileHandles, + const std::shared_ptr& btDeviceProxy, + const PcmConfiguration& pcmConfig) : StreamIn(std::move(context), microphones), - StreamBluetooth(&mContextInstance, sinkMetadata, std::move(btProfileHandles)) {} + StreamBluetooth(&mContextInstance, sinkMetadata, std::move(btProfileHandles), btDeviceProxy, + pcmConfig) {} ndk::ScopedAStatus StreamInBluetooth::getActiveMicrophones( std::vector* _aidl_return __unused) { @@ -325,11 +256,20 @@ ndk::ScopedAStatus StreamInBluetooth::getActiveMicrophones( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } +// static +int32_t StreamOutBluetooth::getNominalLatencyMs(size_t dataIntervalUs) { + if (dataIntervalUs == 0) dataIntervalUs = kBluetoothDefaultOutputBufferMs * 1000LL; + return dataIntervalUs / 1000LL; +} + StreamOutBluetooth::StreamOutBluetooth(StreamContext&& context, const SourceMetadata& sourceMetadata, const std::optional& offloadInfo, - ModuleBluetooth::BtProfileHandles&& btProfileHandles) + ModuleBluetooth::BtProfileHandles&& btProfileHandles, + const std::shared_ptr& btDeviceProxy, + const PcmConfiguration& pcmConfig) : StreamOut(std::move(context), offloadInfo), - StreamBluetooth(&mContextInstance, sourceMetadata, std::move(btProfileHandles)) {} + StreamBluetooth(&mContextInstance, sourceMetadata, std::move(btProfileHandles), btDeviceProxy, + pcmConfig) {} } // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/include/core-impl/DevicePortProxy.h b/audio/aidl/default/include/core-impl/DevicePortProxy.h index 17a8cf3d9a..ccb23bbe5b 100644 --- a/audio/aidl/default/include/core-impl/DevicePortProxy.h +++ b/audio/aidl/default/include/core-impl/DevicePortProxy.h @@ -73,12 +73,7 @@ class BluetoothAudioPort { * Bluetooth stack */ virtual bool loadAudioConfig( - ::aidl::android::hardware::bluetooth::audio::PcmConfiguration*) const = 0; - - /** - * WAR to support Mono mode / 16 bits per sample - */ - virtual void forcePcmStereoToMono(bool) = 0; + ::aidl::android::hardware::bluetooth::audio::PcmConfiguration&) = 0; /** * When the Audio framework / HAL wants to change the stream state, it invokes @@ -145,7 +140,7 @@ class BluetoothAudioPort { virtual bool isLeAudio() const = 0; - virtual bool getPreferredDataIntervalUs(size_t*) const = 0; + virtual bool getPreferredDataIntervalUs(size_t&) const = 0; virtual size_t writeData(const void*, size_t) const { return 0; } @@ -162,10 +157,8 @@ class BluetoothAudioPortAidl : public BluetoothAudioPort { void unregisterPort() override; - bool loadAudioConfig(::aidl::android::hardware::bluetooth::audio::PcmConfiguration* audio_cfg) - const override; - - void forcePcmStereoToMono(bool force) override { mIsStereoToMono = force; } + bool loadAudioConfig( + ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override; bool standby() override; bool start() override; @@ -193,7 +186,7 @@ class BluetoothAudioPortAidl : public BluetoothAudioPort { bool isLeAudio() const override; - bool getPreferredDataIntervalUs(size_t* interval_us) const override; + bool getPreferredDataIntervalUs(size_t& interval_us) const override; protected: uint16_t mCookie; @@ -228,6 +221,9 @@ class BluetoothAudioPortAidl : public BluetoothAudioPort { class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl { public: + bool loadAudioConfig( + ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override; + // The audio data path to the Bluetooth stack (Software encoding) size_t writeData(const void* buffer, size_t bytes) const override; }; diff --git a/audio/aidl/default/include/core-impl/ModuleBluetooth.h b/audio/aidl/default/include/core-impl/ModuleBluetooth.h index e48526e292..9451411f48 100644 --- a/audio/aidl/default/include/core-impl/ModuleBluetooth.h +++ b/audio/aidl/default/include/core-impl/ModuleBluetooth.h @@ -16,7 +16,10 @@ #pragma once +#include + #include "core-impl/Bluetooth.h" +#include "core-impl/DevicePortProxy.h" #include "core-impl/Module.h" namespace aidl::android::hardware::audio::core { @@ -31,6 +34,11 @@ class ModuleBluetooth final : public Module { ModuleBluetooth(std::unique_ptr&& config); private: + struct CachedProxy { + std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl> ptr; + ::aidl::android::hardware::bluetooth::audio::PcmConfiguration pcmConfig; + }; + ChildInterface& getBtA2dp(); ChildInterface& getBtLe(); BtProfileHandles getBtProfileManagerHandles(); @@ -40,6 +48,17 @@ class ModuleBluetooth final : public Module { ndk::ScopedAStatus getMicMute(bool* _aidl_return) override; ndk::ScopedAStatus setMicMute(bool in_mute) override; + ndk::ScopedAStatus setAudioPortConfig( + const ::aidl::android::media::audio::common::AudioPortConfig& in_requested, + ::aidl::android::media::audio::common::AudioPortConfig* out_suggested, + bool* _aidl_return) override; + + ndk::ScopedAStatus checkAudioPatchEndpointsMatch( + const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources, + const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks) + override; + void onExternalDeviceConnectionChanged( + const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected); ndk::ScopedAStatus createInputStream( StreamContext&& context, const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, @@ -56,9 +75,20 @@ class ModuleBluetooth final : public Module { int32_t nextPortId) override; ndk::ScopedAStatus onMasterMuteChanged(bool mute) override; ndk::ScopedAStatus onMasterVolumeChanged(float volume) override; + int32_t getNominalLatencyMs( + const ::aidl::android::media::audio::common::AudioPortConfig& portConfig) override; + + ndk::ScopedAStatus createProxy( + const ::aidl::android::media::audio::common::AudioPort& audioPort, + int32_t instancePortId, CachedProxy& proxy); + ndk::ScopedAStatus fetchAndCheckProxy(const StreamContext& context, CachedProxy& proxy); + ndk::ScopedAStatus findOrCreateProxy( + const ::aidl::android::media::audio::common::AudioPort& audioPort, CachedProxy& proxy); ChildInterface mBluetoothA2dp; ChildInterface mBluetoothLe; + std::map mProxies; + std::map mConnections; }; } // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/include/core-impl/StreamBluetooth.h b/audio/aidl/default/include/core-impl/StreamBluetooth.h index 1258d3860c..35c3183560 100644 --- a/audio/aidl/default/include/core-impl/StreamBluetooth.h +++ b/audio/aidl/default/include/core-impl/StreamBluetooth.h @@ -31,8 +31,16 @@ namespace aidl::android::hardware::audio::core { class StreamBluetooth : public StreamCommonImpl { public: - StreamBluetooth(StreamContext* context, const Metadata& metadata, - ModuleBluetooth::BtProfileHandles&& btHandles); + static bool checkConfigParams( + const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig, + const ::aidl::android::media::audio::common::AudioConfigBase& config); + + StreamBluetooth( + StreamContext* context, const Metadata& metadata, + ModuleBluetooth::BtProfileHandles&& btHandles, + const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>& + btDeviceProxy, + const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig); // Methods of 'DriverInterface'. ::android::status_t init() override; ::android::status_t drain(StreamDescriptor::DrainMode) override; @@ -47,40 +55,35 @@ class StreamBluetooth : public StreamCommonImpl { // Overridden methods of 'StreamCommonImpl', called on a Binder thread. ndk::ScopedAStatus updateMetadataCommon(const Metadata& metadata) override; ndk::ScopedAStatus prepareToClose() override; - const ConnectedDevices& getConnectedDevices() const override; - ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override; ndk::ScopedAStatus bluetoothParametersUpdated() override; private: - // Audio Pcm Config - const uint32_t mSampleRate; - const ::aidl::android::media::audio::common::AudioChannelLayout mChannelLayout; - const ::aidl::android::media::audio::common::AudioFormatDescription mFormat; const size_t mFrameSizeBytes; const bool mIsInput; const std::weak_ptr mBluetoothA2dp; const std::weak_ptr mBluetoothLe; - size_t mPreferredDataIntervalUs; - size_t mPreferredFrameCount; - + const size_t mPreferredDataIntervalUs; + const size_t mPreferredFrameCount; mutable std::mutex mLock; - bool mIsInitialized GUARDED_BY(mLock); - bool mIsReadyToClose GUARDED_BY(mLock); - std::vector> - mBtDeviceProxies GUARDED_BY(mLock); - - ::android::status_t initialize() REQUIRES(mLock); - bool checkConfigParams(::aidl::android::hardware::bluetooth::audio::PcmConfiguration& config); + // The lock is also used to serialize calls to the proxy. + std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl> mBtDeviceProxy + GUARDED_BY(mLock); // proxy may be null if the stream is not connected to a device }; class StreamInBluetooth final : public StreamIn, public StreamBluetooth { public: friend class ndk::SharedRefBase; + + static int32_t getNominalLatencyMs(size_t dataIntervalUs); + StreamInBluetooth( StreamContext&& context, const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, - ModuleBluetooth::BtProfileHandles&& btHandles); + ModuleBluetooth::BtProfileHandles&& btHandles, + const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>& + btDeviceProxy, + const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig); private: void onClose(StreamDescriptor::State) override { defaultOnClose(); } @@ -92,12 +95,18 @@ class StreamInBluetooth final : public StreamIn, public StreamBluetooth { class StreamOutBluetooth final : public StreamOut, public StreamBluetooth { public: friend class ndk::SharedRefBase; + + static int32_t getNominalLatencyMs(size_t dataIntervalUs); + StreamOutBluetooth( StreamContext&& context, const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& offloadInfo, - ModuleBluetooth::BtProfileHandles&& btHandles); + ModuleBluetooth::BtProfileHandles&& btHandles, + const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>& + btDeviceProxy, + const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig); private: void onClose(StreamDescriptor::State) override { defaultOnClose(); } diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp index c05750538d..67ba93cdd7 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp @@ -500,14 +500,12 @@ bool BluetoothAudioSession::GetPresentationPosition( << " 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; + return true; } void BluetoothAudioSession::UpdateSourceMetadata(