diff --git a/audio/aidl/default/alsa/StreamAlsa.cpp b/audio/aidl/default/alsa/StreamAlsa.cpp index f548903de2..372e38a5b3 100644 --- a/audio/aidl/default/alsa/StreamAlsa.cpp +++ b/audio/aidl/default/alsa/StreamAlsa.cpp @@ -75,6 +75,10 @@ StreamAlsa::~StreamAlsa() { } decltype(mAlsaDeviceProxies) alsaDeviceProxies; for (const auto& device : getDeviceProfiles()) { + if ((device.direction == PCM_OUT && mIsInput) || + (device.direction == PCM_IN && !mIsInput)) { + continue; + } alsa::DeviceProxy proxy; if (device.isExternal) { // Always ask alsa configure as required since the configuration should be supported @@ -92,6 +96,9 @@ StreamAlsa::~StreamAlsa() { } alsaDeviceProxies.push_back(std::move(proxy)); } + if (alsaDeviceProxies.empty()) { + return ::android::NO_INIT; + } mAlsaDeviceProxies = std::move(alsaDeviceProxies); return ::android::OK; } diff --git a/audio/aidl/default/include/core-impl/StreamPrimary.h b/audio/aidl/default/include/core-impl/StreamPrimary.h index 8d5c57da4b..600c3779cd 100644 --- a/audio/aidl/default/include/core-impl/StreamPrimary.h +++ b/audio/aidl/default/include/core-impl/StreamPrimary.h @@ -25,7 +25,8 @@ namespace aidl::android::hardware::audio::core { class StreamPrimary : public StreamAlsa { public: - StreamPrimary(StreamContext* context, const Metadata& metadata); + StreamPrimary(StreamContext* context, const Metadata& metadata, + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices); ::android::status_t start() override; ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount, @@ -39,6 +40,11 @@ class StreamPrimary : public StreamAlsa { int64_t mStartTimeNs = 0; long mFramesSinceStart = 0; bool mSkipNextTransfer = false; + + private: + static std::pair getCardAndDeviceId( + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices); + const std::pair mCardAndDeviceId; }; class StreamInPrimary final : public StreamIn, public StreamSwitcher, public StreamInHwGainHelper { diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp index 7325a91b49..abf3a731ad 100644 --- a/audio/aidl/default/primary/StreamPrimary.cpp +++ b/audio/aidl/default/primary/StreamPrimary.cpp @@ -15,7 +15,11 @@ */ #define LOG_TAG "AHAL_StreamPrimary" + +#include + #include +#include #include #include #include @@ -28,6 +32,7 @@ using aidl::android::hardware::audio::common::SinkMetadata; using aidl::android::hardware::audio::common::SourceMetadata; using aidl::android::media::audio::common::AudioDevice; +using aidl::android::media::audio::common::AudioDeviceAddress; using aidl::android::media::audio::common::AudioDeviceDescription; using aidl::android::media::audio::common::AudioDeviceType; using aidl::android::media::audio::common::AudioOffloadInfo; @@ -36,9 +41,15 @@ using android::base::GetBoolProperty; namespace aidl::android::hardware::audio::core { -StreamPrimary::StreamPrimary(StreamContext* context, const Metadata& metadata) +const static constexpr std::pair kDefaultCardAndDeviceId = { + primary::PrimaryMixer::kAlsaCard, primary::PrimaryMixer::kAlsaDevice}; + +StreamPrimary::StreamPrimary( + StreamContext* context, const Metadata& metadata, + const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) : StreamAlsa(context, metadata, 3 /*readWriteRetries*/), - mIsAsynchronous(!!getContext().getAsyncCallback()) { + mIsAsynchronous(!!getContext().getAsyncCallback()), + mCardAndDeviceId(getCardAndDeviceId(devices)) { context->startStreamDataProcessor(); } @@ -92,17 +103,27 @@ StreamPrimary::StreamPrimary(StreamContext* context, const Metadata& metadata) } std::vector StreamPrimary::getDeviceProfiles() { - static const std::vector kBuiltInSource{ - alsa::DeviceProfile{.card = primary::PrimaryMixer::kAlsaCard, - .device = primary::PrimaryMixer::kAlsaDevice, - .direction = PCM_IN, + return {alsa::DeviceProfile{.card = mCardAndDeviceId.first, + .device = mCardAndDeviceId.second, + .direction = mIsInput ? PCM_IN : PCM_OUT, .isExternal = false}}; - static const std::vector kBuiltInSink{ - alsa::DeviceProfile{.card = primary::PrimaryMixer::kAlsaCard, - .device = primary::PrimaryMixer::kAlsaDevice, - .direction = PCM_OUT, - .isExternal = false}}; - return mIsInput ? kBuiltInSource : kBuiltInSink; +} + +std::pair StreamPrimary::getCardAndDeviceId(const std::vector& devices) { + if (devices.empty() || devices[0].address.getTag() != AudioDeviceAddress::id) { + return kDefaultCardAndDeviceId; + } + std::string deviceAddress = devices[0].address.get(); + std::pair cardAndDeviceId; + if (const size_t suffixPos = deviceAddress.rfind("CARD_"); + suffixPos == std::string::npos || + sscanf(deviceAddress.c_str() + suffixPos, "CARD_%d_DEV_%d", &cardAndDeviceId.first, + &cardAndDeviceId.second) != 2) { + return kDefaultCardAndDeviceId; + } + LOG(DEBUG) << __func__ << ": parsed with card id " << cardAndDeviceId.first << ", device id " + << cardAndDeviceId.second; + return cardAndDeviceId; } StreamInPrimary::StreamInPrimary(StreamContext&& context, const SinkMetadata& sinkMetadata, @@ -145,7 +166,7 @@ std::unique_ptr StreamInPrimary::createNewStream( new InnerStreamWrapper(context, metadata)); } return std::unique_ptr( - new InnerStreamWrapper(context, metadata)); + new InnerStreamWrapper(context, metadata, devices)); } ndk::ScopedAStatus StreamInPrimary::getHwGain(std::vector* _aidl_return) { @@ -217,7 +238,7 @@ std::unique_ptr StreamOutPrimary::createNewStream( new InnerStreamWrapper(context, metadata)); } return std::unique_ptr( - new InnerStreamWrapper(context, metadata)); + new InnerStreamWrapper(context, metadata, devices)); } ndk::ScopedAStatus StreamOutPrimary::getHwVolume(std::vector* _aidl_return) {