Loading audio/aidl/common/include/Utils.h +15 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,21 @@ #include <aidl/android/media/audio/common/AudioMode.h> #include <aidl/android/media/audio/common/AudioOutputFlags.h> #include <aidl/android/media/audio/common/PcmType.h> #include <android/binder_auto_utils.h> namespace ndk { // This enables use of 'error/expected_utils' for ScopedAStatus. inline bool errorIsOk(const ScopedAStatus& s) { return s.isOk(); } inline std::string errorToString(const ScopedAStatus& s) { return s.getDescription(); } } // namespace ndk namespace aidl::android::hardware::audio::common { Loading audio/aidl/default/Module.cpp +98 −86 Original line number Diff line number Diff line Loading @@ -18,19 +18,18 @@ #include <set> #define LOG_TAG "AHAL_Module" #include <android-base/logging.h> #include <android/binder_ibinder_platform.h> #include <Utils.h> #include <aidl/android/media/audio/common/AudioInputFlags.h> #include <aidl/android/media/audio/common/AudioOutputFlags.h> #include <android-base/logging.h> #include <android/binder_ibinder_platform.h> #include <error/expected_utils.h> #include "core-impl/Bluetooth.h" #include "core-impl/Module.h" #include "core-impl/ModuleUsb.h" #include "core-impl/SoundDose.h" #include "core-impl/StreamStub.h" #include "core-impl/StreamUsb.h" #include "core-impl/Telephony.h" #include "core-impl/utils.h" Loading Loading @@ -119,30 +118,6 @@ std::shared_ptr<Module> Module::createInstance(Type type) { } } // static StreamIn::CreateInstance Module::getStreamInCreator(Type type) { switch (type) { case Type::USB: return StreamInUsb::createInstance; case Type::DEFAULT: case Type::R_SUBMIX: default: return StreamInStub::createInstance; } } // static StreamOut::CreateInstance Module::getStreamOutCreator(Type type) { switch (type) { case Type::USB: return StreamOutUsb::createInstance; case Type::DEFAULT: case Type::R_SUBMIX: default: return StreamOutStub::createInstance; } } std::ostream& operator<<(std::ostream& os, Module::Type t) { switch (t) { case Module::Type::DEFAULT: Loading Loading @@ -207,7 +182,8 @@ ndk::ScopedAStatus Module::createStreamContext( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, portConfigIt->sampleRate.value().value, flags, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames), asyncCallback, outEventCallback, params); if (temp.isValid()) { Loading Loading @@ -339,30 +315,61 @@ void Module::registerPatch(const AudioPatch& patch) { do_insert(patch.sinkPortConfigIds); } void Module::updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch) { ndk::ScopedAStatus Module::updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch) { // Streams from the old patch need to be disconnected, streams from the new // patch need to be connected. If the stream belongs to both patches, no need // to update it. std::set<int32_t> idsToDisconnect, idsToConnect; auto maybeFailure = ndk::ScopedAStatus::ok(); std::set<int32_t> idsToDisconnect, idsToConnect, idsToDisconnectOnFailure; idsToDisconnect.insert(oldPatch.sourcePortConfigIds.begin(), oldPatch.sourcePortConfigIds.end()); idsToDisconnect.insert(oldPatch.sinkPortConfigIds.begin(), oldPatch.sinkPortConfigIds.end()); idsToConnect.insert(newPatch.sourcePortConfigIds.begin(), newPatch.sourcePortConfigIds.end()); idsToConnect.insert(newPatch.sinkPortConfigIds.begin(), newPatch.sinkPortConfigIds.end()); std::for_each(idsToDisconnect.begin(), idsToDisconnect.end(), [&](const auto& portConfigId) { if (idsToConnect.count(portConfigId) == 0) { LOG(DEBUG) << "The stream on port config id " << portConfigId << " is not connected"; mStreams.setStreamIsConnected(portConfigId, {}); if (idsToConnect.count(portConfigId) == 0 && mStreams.count(portConfigId) != 0) { if (auto status = mStreams.setStreamConnectedDevices(portConfigId, {}); status.isOk()) { LOG(DEBUG) << "updateStreamsConnectedState: The stream on port config id " << portConfigId << " has been disconnected"; } else { // Disconnection is tricky to roll back, just register a failure. maybeFailure = std::move(status); } } }); if (!maybeFailure.isOk()) return maybeFailure; std::for_each(idsToConnect.begin(), idsToConnect.end(), [&](const auto& portConfigId) { if (idsToDisconnect.count(portConfigId) == 0) { if (idsToDisconnect.count(portConfigId) == 0 && mStreams.count(portConfigId) != 0) { const auto connectedDevices = findConnectedDevices(portConfigId); LOG(DEBUG) << "The stream on port config id " << portConfigId << " is connected to: " << ::android::internal::ToString(connectedDevices); mStreams.setStreamIsConnected(portConfigId, connectedDevices); if (connectedDevices.empty()) { // This is important as workers use the vector size to derive the connection status. LOG(FATAL) << "updateStreamsConnectedState: No connected devices found for port " "config id " << portConfigId; } if (auto status = mStreams.setStreamConnectedDevices(portConfigId, connectedDevices); status.isOk()) { LOG(DEBUG) << "updateStreamsConnectedState: The stream on port config id " << portConfigId << " has been connected to: " << ::android::internal::ToString(connectedDevices); } else { maybeFailure = std::move(status); idsToDisconnectOnFailure.insert(portConfigId); } } }); if (!maybeFailure.isOk()) { LOG(WARNING) << __func__ << ": Due to a failure, disconnecting streams on port config ids " << ::android::internal::ToString(idsToDisconnectOnFailure); std::for_each(idsToDisconnectOnFailure.begin(), idsToDisconnectOnFailure.end(), [&](const auto& portConfigId) { auto status = mStreams.setStreamConnectedDevices(portConfigId, {}); (void)status.isOk(); // Can't do much about a failure here. }); return maybeFailure; } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::setModuleDebug( Loading Loading @@ -469,10 +476,7 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA } if (!mDebug.simulateDeviceConnections) { if (ndk::ScopedAStatus status = populateConnectedDevicePort(&connectedPort); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort)); } else { auto& connectedProfiles = getConfig().connectedProfiles; if (auto connectedProfilesIt = connectedProfiles.find(templateId); Loading Loading @@ -647,34 +651,26 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar LOG(DEBUG) << __func__ << ": port config id " << in_args.portConfigId << ", buffer size " << in_args.bufferSizeFrames << " frames"; AudioPort* port = nullptr; if (auto status = findPortIdForNewStream(in_args.portConfigId, &port); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(findPortIdForNewStream(in_args.portConfigId, &port)); if (port->flags.getTag() != AudioIoFlags::Tag::input) { LOG(ERROR) << __func__ << ": port config id " << in_args.portConfigId << " does not correspond to an input mix port"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } StreamContext context; if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr, nullptr, &context); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr, nullptr, &context)); context.fillDescriptor(&_aidl_return->desc); std::shared_ptr<StreamIn> stream; ndk::ScopedAStatus status = getStreamInCreator(mType)(in_args.sinkMetadata, std::move(context), mConfig->microphones, &stream); if (!status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(createInputStream(in_args.sinkMetadata, std::move(context), mConfig->microphones, &stream)); StreamWrapper streamWrapper(stream); if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) { RETURN_STATUS_IF_ERROR( streamWrapper.setConnectedDevices(findConnectedDevices(in_args.portConfigId))); } AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); auto patchIt = mPatches.find(in_args.portConfigId); if (patchIt != mPatches.end()) { streamWrapper.setStreamIsConnected(findConnectedDevices(in_args.portConfigId)); } mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper)); _aidl_return->stream = std::move(stream); return ndk::ScopedAStatus::ok(); Loading @@ -686,9 +682,7 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_ << (in_args.offloadInfo.has_value()) << ", buffer size " << in_args.bufferSizeFrames << " frames"; AudioPort* port = nullptr; if (auto status = findPortIdForNewStream(in_args.portConfigId, &port); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(findPortIdForNewStream(in_args.portConfigId, &port)); if (port->flags.getTag() != AudioIoFlags::Tag::output) { LOG(ERROR) << __func__ << ": port config id " << in_args.portConfigId << " does not correspond to an output mix port"; Loading @@ -709,26 +703,20 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } StreamContext context; if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, RETURN_STATUS_IF_ERROR(createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, isNonBlocking ? in_args.callback : nullptr, in_args.eventCallback, &context); !status.isOk()) { return status; } in_args.eventCallback, &context)); context.fillDescriptor(&_aidl_return->desc); std::shared_ptr<StreamOut> stream; ndk::ScopedAStatus status = getStreamOutCreator(mType)( in_args.sourceMetadata, std::move(context), in_args.offloadInfo, &stream); if (!status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(createOutputStream(in_args.sourceMetadata, std::move(context), in_args.offloadInfo, &stream)); StreamWrapper streamWrapper(stream); if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) { RETURN_STATUS_IF_ERROR( streamWrapper.setConnectedDevices(findConnectedDevices(in_args.portConfigId))); } AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); auto patchIt = mPatches.find(in_args.portConfigId); if (patchIt != mPatches.end()) { streamWrapper.setStreamIsConnected(findConnectedDevices(in_args.portConfigId)); } mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper)); _aidl_return->stream = std::move(stream); return ndk::ScopedAStatus::ok(); Loading Loading @@ -796,10 +784,7 @@ ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPa return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } } if (auto status = checkAudioPatchEndpointsMatch(sources, sinks); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(checkAudioPatchEndpointsMatch(sources, sinks)); auto& patches = getConfig().patches; auto existing = patches.end(); Loading Loading @@ -834,13 +819,20 @@ ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPa if (existing == patches.end()) { _aidl_return->id = getConfig().nextPatchId++; patches.push_back(*_aidl_return); existing = patches.begin() + (patches.size() - 1); } else { oldPatch = *existing; *existing = *_aidl_return; } registerPatch(*existing); updateStreamsConnectedState(oldPatch, *_aidl_return); patchesBackup = mPatches; registerPatch(*_aidl_return); if (auto status = updateStreamsConnectedState(oldPatch, *_aidl_return); !status.isOk()) { mPatches = std::move(*patchesBackup); if (existing == patches.end()) { patches.pop_back(); } else { *existing = oldPatch; } return status; } LOG(DEBUG) << __func__ << ": " << (oldPatch.id == 0 ? "created" : "updated") << " patch " << _aidl_return->toString(); Loading Loading @@ -992,8 +984,12 @@ ndk::ScopedAStatus Module::resetAudioPatch(int32_t in_patchId) { auto& patches = getConfig().patches; auto patchIt = findById<AudioPatch>(patches, in_patchId); if (patchIt != patches.end()) { auto patchesBackup = mPatches; cleanUpPatch(patchIt->id); updateStreamsConnectedState(*patchIt, AudioPatch{}); if (auto status = updateStreamsConnectedState(*patchIt, AudioPatch{}); !status.isOk()) { mPatches = std::move(patchesBackup); return status; } patches.erase(patchIt); LOG(DEBUG) << __func__ << ": erased patch " << in_patchId; return ndk::ScopedAStatus::ok(); Loading Loading @@ -1325,6 +1321,22 @@ bool Module::isMmapSupported() { return mIsMmapSupported.value(); } ndk::ScopedAStatus Module::createInputStream(const SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector<MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) { return createStreamInstance<StreamInStub>(result, sinkMetadata, std::move(context), microphones); } ndk::ScopedAStatus Module::createOutputStream(const SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional<AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) { return createStreamInstance<StreamOutStub>(result, sourceMetadata, std::move(context), offloadInfo); } ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort __unused) { LOG(VERBOSE) << __func__ << ": do nothing and return ok"; return ndk::ScopedAStatus::ok(); Loading audio/aidl/default/Stream.cpp +30 −58 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() { case Tag::halReservedExit: if (const int32_t cookie = command.get<Tag::halReservedExit>(); cookie == mInternalCommandCookie) { mDriver->shutdown(); setClosed(); // This is an internal command, no need to reply. return Status::EXIT; Loading Loading @@ -364,6 +365,7 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() { case Tag::halReservedExit: if (const int32_t cookie = command.get<Tag::halReservedExit>(); cookie == mInternalCommandCookie) { mDriver->shutdown(); setClosed(); // This is an internal command, no need to reply. return Status::EXIT; Loading Loading @@ -567,8 +569,7 @@ bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* rep return !fatal; } template <class Metadata> StreamCommonImpl<Metadata>::~StreamCommonImpl() { StreamCommonImpl::~StreamCommonImpl() { if (!isClosed()) { LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak"; stopWorker(); Loading @@ -576,19 +577,16 @@ StreamCommonImpl<Metadata>::~StreamCommonImpl() { } } template <class Metadata> void StreamCommonImpl<Metadata>::createStreamCommon( ndk::ScopedAStatus StreamCommonImpl::initInstance( const std::shared_ptr<StreamCommonInterface>& delegate) { if (mCommon != nullptr) { LOG(FATAL) << __func__ << ": attempting to create the common interface twice"; } mCommon = ndk::SharedRefBase::make<StreamCommon>(delegate); mCommon = ndk::SharedRefBase::make<StreamCommonDelegator>(delegate); mCommonBinder = mCommon->asBinder(); AIBinder_setMinSchedulerPolicy(mCommonBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); return mWorker->start() ? ndk::ScopedAStatus::ok() : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon( ndk::ScopedAStatus StreamCommonImpl::getStreamCommonCommon( std::shared_ptr<IStreamCommon>* _aidl_return) { if (mCommon == nullptr) { LOG(FATAL) << __func__ << ": the common interface was not created"; Loading @@ -598,30 +596,26 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon( return ndk::ScopedAStatus::ok(); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateHwAvSyncId(int32_t in_hwAvSyncId) { ndk::ScopedAStatus StreamCommonImpl::updateHwAvSyncId(int32_t in_hwAvSyncId) { LOG(DEBUG) << __func__ << ": id " << in_hwAvSyncId; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::getVendorParameters( ndk::ScopedAStatus StreamCommonImpl::getVendorParameters( const std::vector<std::string>& in_ids, std::vector<VendorParameter>* _aidl_return) { LOG(DEBUG) << __func__ << ": id count: " << in_ids.size(); (void)_aidl_return; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::setVendorParameters( ndk::ScopedAStatus StreamCommonImpl::setVendorParameters( const std::vector<VendorParameter>& in_parameters, bool in_async) { LOG(DEBUG) << __func__ << ": parameters count " << in_parameters.size() << ", async: " << in_async; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect( ndk::ScopedAStatus StreamCommonImpl::addEffect( const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) { if (in_effect == nullptr) { LOG(DEBUG) << __func__ << ": null effect"; Loading @@ -631,8 +625,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect( ndk::ScopedAStatus StreamCommonImpl::removeEffect( const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) { if (in_effect == nullptr) { LOG(DEBUG) << __func__ << ": null effect"; Loading @@ -642,8 +635,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() { ndk::ScopedAStatus StreamCommonImpl::close() { LOG(DEBUG) << __func__; if (!isClosed()) { stopWorker(); Loading @@ -659,8 +651,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() { } } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::prepareToClose() { ndk::ScopedAStatus StreamCommonImpl::prepareToClose() { LOG(DEBUG) << __func__; if (!isClosed()) { return ndk::ScopedAStatus::ok(); Loading @@ -669,8 +660,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::prepareToClose() { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } template <class Metadata> void StreamCommonImpl<Metadata>::stopWorker() { void StreamCommonImpl::stopWorker() { if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) { LOG(DEBUG) << __func__ << ": asking the worker to exit..."; auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>( Loading @@ -686,10 +676,12 @@ void StreamCommonImpl<Metadata>::stopWorker() { } } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& metadata) { ndk::ScopedAStatus StreamCommonImpl::updateMetadataCommon(const Metadata& metadata) { LOG(DEBUG) << __func__; if (!isClosed()) { if (metadata.index() != mMetadata.index()) { LOG(FATAL) << __func__ << ": changing metadata variant is not allowed"; } mMetadata = metadata; return ndk::ScopedAStatus::ok(); } Loading @@ -697,12 +689,10 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& me return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } // static ndk::ScopedAStatus StreamIn::initInstance(const std::shared_ptr<StreamIn>& stream) { if (auto status = stream->init(); !status.isOk()) { return status; } stream->createStreamCommon(stream); ndk::ScopedAStatus StreamCommonImpl::setConnectedDevices( const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) { mWorker->setIsConnected(!devices.empty()); mConnectedDevices = devices; return ndk::ScopedAStatus::ok(); } Loading @@ -716,12 +706,8 @@ static std::map<AudioDevice, std::string> transformMicrophones( } } // namespace StreamIn::StreamIn(const SinkMetadata& sinkMetadata, StreamContext&& context, const DriverInterface::CreateInstance& createDriver, const StreamWorkerInterface::CreateInstance& createWorker, const std::vector<MicrophoneInfo>& microphones) : StreamCommonImpl<SinkMetadata>(sinkMetadata, std::move(context), createDriver, createWorker), mMicrophones(transformMicrophones(microphones)) { StreamIn::StreamIn(const std::vector<MicrophoneInfo>& microphones) : mMicrophones(transformMicrophones(microphones)) { LOG(DEBUG) << __func__; } Loading @@ -729,9 +715,9 @@ ndk::ScopedAStatus StreamIn::getActiveMicrophones( std::vector<MicrophoneDynamicInfo>* _aidl_return) { std::vector<MicrophoneDynamicInfo> result; std::vector<MicrophoneDynamicInfo::ChannelMapping> channelMapping{ getChannelCount(mContext.getChannelLayout()), getChannelCount(getContext().getChannelLayout()), MicrophoneDynamicInfo::ChannelMapping::DIRECT}; for (auto it = mConnectedDevices.begin(); it != mConnectedDevices.end(); ++it) { for (auto it = getConnectedDevices().begin(); it != getConnectedDevices().end(); ++it) { if (auto micIt = mMicrophones.find(*it); micIt != mMicrophones.end()) { MicrophoneDynamicInfo dynMic; dynMic.id = micIt->second; Loading Loading @@ -777,22 +763,8 @@ ndk::ScopedAStatus StreamIn::setHwGain(const std::vector<float>& in_channelGains return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } // static ndk::ScopedAStatus StreamOut::initInstance(const std::shared_ptr<StreamOut>& stream) { if (auto status = stream->init(); !status.isOk()) { return status; } stream->createStreamCommon(stream); return ndk::ScopedAStatus::ok(); } StreamOut::StreamOut(const SourceMetadata& sourceMetadata, StreamContext&& context, const DriverInterface::CreateInstance& createDriver, const StreamWorkerInterface::CreateInstance& createWorker, const std::optional<AudioOffloadInfo>& offloadInfo) : StreamCommonImpl<SourceMetadata>(sourceMetadata, std::move(context), createDriver, createWorker), mOffloadInfo(offloadInfo) { StreamOut::StreamOut(const std::optional<AudioOffloadInfo>& offloadInfo) : mOffloadInfo(offloadInfo) { LOG(DEBUG) << __func__; } Loading Loading
audio/aidl/common/include/Utils.h +15 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,21 @@ #include <aidl/android/media/audio/common/AudioMode.h> #include <aidl/android/media/audio/common/AudioOutputFlags.h> #include <aidl/android/media/audio/common/PcmType.h> #include <android/binder_auto_utils.h> namespace ndk { // This enables use of 'error/expected_utils' for ScopedAStatus. inline bool errorIsOk(const ScopedAStatus& s) { return s.isOk(); } inline std::string errorToString(const ScopedAStatus& s) { return s.getDescription(); } } // namespace ndk namespace aidl::android::hardware::audio::common { Loading
audio/aidl/default/Module.cpp +98 −86 Original line number Diff line number Diff line Loading @@ -18,19 +18,18 @@ #include <set> #define LOG_TAG "AHAL_Module" #include <android-base/logging.h> #include <android/binder_ibinder_platform.h> #include <Utils.h> #include <aidl/android/media/audio/common/AudioInputFlags.h> #include <aidl/android/media/audio/common/AudioOutputFlags.h> #include <android-base/logging.h> #include <android/binder_ibinder_platform.h> #include <error/expected_utils.h> #include "core-impl/Bluetooth.h" #include "core-impl/Module.h" #include "core-impl/ModuleUsb.h" #include "core-impl/SoundDose.h" #include "core-impl/StreamStub.h" #include "core-impl/StreamUsb.h" #include "core-impl/Telephony.h" #include "core-impl/utils.h" Loading Loading @@ -119,30 +118,6 @@ std::shared_ptr<Module> Module::createInstance(Type type) { } } // static StreamIn::CreateInstance Module::getStreamInCreator(Type type) { switch (type) { case Type::USB: return StreamInUsb::createInstance; case Type::DEFAULT: case Type::R_SUBMIX: default: return StreamInStub::createInstance; } } // static StreamOut::CreateInstance Module::getStreamOutCreator(Type type) { switch (type) { case Type::USB: return StreamOutUsb::createInstance; case Type::DEFAULT: case Type::R_SUBMIX: default: return StreamOutStub::createInstance; } } std::ostream& operator<<(std::ostream& os, Module::Type t) { switch (t) { case Module::Type::DEFAULT: Loading Loading @@ -207,7 +182,8 @@ ndk::ScopedAStatus Module::createStreamContext( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, portConfigIt->sampleRate.value().value, flags, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames), asyncCallback, outEventCallback, params); if (temp.isValid()) { Loading Loading @@ -339,30 +315,61 @@ void Module::registerPatch(const AudioPatch& patch) { do_insert(patch.sinkPortConfigIds); } void Module::updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch) { ndk::ScopedAStatus Module::updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch) { // Streams from the old patch need to be disconnected, streams from the new // patch need to be connected. If the stream belongs to both patches, no need // to update it. std::set<int32_t> idsToDisconnect, idsToConnect; auto maybeFailure = ndk::ScopedAStatus::ok(); std::set<int32_t> idsToDisconnect, idsToConnect, idsToDisconnectOnFailure; idsToDisconnect.insert(oldPatch.sourcePortConfigIds.begin(), oldPatch.sourcePortConfigIds.end()); idsToDisconnect.insert(oldPatch.sinkPortConfigIds.begin(), oldPatch.sinkPortConfigIds.end()); idsToConnect.insert(newPatch.sourcePortConfigIds.begin(), newPatch.sourcePortConfigIds.end()); idsToConnect.insert(newPatch.sinkPortConfigIds.begin(), newPatch.sinkPortConfigIds.end()); std::for_each(idsToDisconnect.begin(), idsToDisconnect.end(), [&](const auto& portConfigId) { if (idsToConnect.count(portConfigId) == 0) { LOG(DEBUG) << "The stream on port config id " << portConfigId << " is not connected"; mStreams.setStreamIsConnected(portConfigId, {}); if (idsToConnect.count(portConfigId) == 0 && mStreams.count(portConfigId) != 0) { if (auto status = mStreams.setStreamConnectedDevices(portConfigId, {}); status.isOk()) { LOG(DEBUG) << "updateStreamsConnectedState: The stream on port config id " << portConfigId << " has been disconnected"; } else { // Disconnection is tricky to roll back, just register a failure. maybeFailure = std::move(status); } } }); if (!maybeFailure.isOk()) return maybeFailure; std::for_each(idsToConnect.begin(), idsToConnect.end(), [&](const auto& portConfigId) { if (idsToDisconnect.count(portConfigId) == 0) { if (idsToDisconnect.count(portConfigId) == 0 && mStreams.count(portConfigId) != 0) { const auto connectedDevices = findConnectedDevices(portConfigId); LOG(DEBUG) << "The stream on port config id " << portConfigId << " is connected to: " << ::android::internal::ToString(connectedDevices); mStreams.setStreamIsConnected(portConfigId, connectedDevices); if (connectedDevices.empty()) { // This is important as workers use the vector size to derive the connection status. LOG(FATAL) << "updateStreamsConnectedState: No connected devices found for port " "config id " << portConfigId; } if (auto status = mStreams.setStreamConnectedDevices(portConfigId, connectedDevices); status.isOk()) { LOG(DEBUG) << "updateStreamsConnectedState: The stream on port config id " << portConfigId << " has been connected to: " << ::android::internal::ToString(connectedDevices); } else { maybeFailure = std::move(status); idsToDisconnectOnFailure.insert(portConfigId); } } }); if (!maybeFailure.isOk()) { LOG(WARNING) << __func__ << ": Due to a failure, disconnecting streams on port config ids " << ::android::internal::ToString(idsToDisconnectOnFailure); std::for_each(idsToDisconnectOnFailure.begin(), idsToDisconnectOnFailure.end(), [&](const auto& portConfigId) { auto status = mStreams.setStreamConnectedDevices(portConfigId, {}); (void)status.isOk(); // Can't do much about a failure here. }); return maybeFailure; } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::setModuleDebug( Loading Loading @@ -469,10 +476,7 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA } if (!mDebug.simulateDeviceConnections) { if (ndk::ScopedAStatus status = populateConnectedDevicePort(&connectedPort); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort)); } else { auto& connectedProfiles = getConfig().connectedProfiles; if (auto connectedProfilesIt = connectedProfiles.find(templateId); Loading Loading @@ -647,34 +651,26 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar LOG(DEBUG) << __func__ << ": port config id " << in_args.portConfigId << ", buffer size " << in_args.bufferSizeFrames << " frames"; AudioPort* port = nullptr; if (auto status = findPortIdForNewStream(in_args.portConfigId, &port); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(findPortIdForNewStream(in_args.portConfigId, &port)); if (port->flags.getTag() != AudioIoFlags::Tag::input) { LOG(ERROR) << __func__ << ": port config id " << in_args.portConfigId << " does not correspond to an input mix port"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } StreamContext context; if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr, nullptr, &context); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr, nullptr, &context)); context.fillDescriptor(&_aidl_return->desc); std::shared_ptr<StreamIn> stream; ndk::ScopedAStatus status = getStreamInCreator(mType)(in_args.sinkMetadata, std::move(context), mConfig->microphones, &stream); if (!status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(createInputStream(in_args.sinkMetadata, std::move(context), mConfig->microphones, &stream)); StreamWrapper streamWrapper(stream); if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) { RETURN_STATUS_IF_ERROR( streamWrapper.setConnectedDevices(findConnectedDevices(in_args.portConfigId))); } AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); auto patchIt = mPatches.find(in_args.portConfigId); if (patchIt != mPatches.end()) { streamWrapper.setStreamIsConnected(findConnectedDevices(in_args.portConfigId)); } mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper)); _aidl_return->stream = std::move(stream); return ndk::ScopedAStatus::ok(); Loading @@ -686,9 +682,7 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_ << (in_args.offloadInfo.has_value()) << ", buffer size " << in_args.bufferSizeFrames << " frames"; AudioPort* port = nullptr; if (auto status = findPortIdForNewStream(in_args.portConfigId, &port); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(findPortIdForNewStream(in_args.portConfigId, &port)); if (port->flags.getTag() != AudioIoFlags::Tag::output) { LOG(ERROR) << __func__ << ": port config id " << in_args.portConfigId << " does not correspond to an output mix port"; Loading @@ -709,26 +703,20 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } StreamContext context; if (auto status = createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, RETURN_STATUS_IF_ERROR(createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, isNonBlocking ? in_args.callback : nullptr, in_args.eventCallback, &context); !status.isOk()) { return status; } in_args.eventCallback, &context)); context.fillDescriptor(&_aidl_return->desc); std::shared_ptr<StreamOut> stream; ndk::ScopedAStatus status = getStreamOutCreator(mType)( in_args.sourceMetadata, std::move(context), in_args.offloadInfo, &stream); if (!status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(createOutputStream(in_args.sourceMetadata, std::move(context), in_args.offloadInfo, &stream)); StreamWrapper streamWrapper(stream); if (auto patchIt = mPatches.find(in_args.portConfigId); patchIt != mPatches.end()) { RETURN_STATUS_IF_ERROR( streamWrapper.setConnectedDevices(findConnectedDevices(in_args.portConfigId))); } AIBinder_setMinSchedulerPolicy(streamWrapper.getBinder().get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); auto patchIt = mPatches.find(in_args.portConfigId); if (patchIt != mPatches.end()) { streamWrapper.setStreamIsConnected(findConnectedDevices(in_args.portConfigId)); } mStreams.insert(port->id, in_args.portConfigId, std::move(streamWrapper)); _aidl_return->stream = std::move(stream); return ndk::ScopedAStatus::ok(); Loading Loading @@ -796,10 +784,7 @@ ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPa return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } } if (auto status = checkAudioPatchEndpointsMatch(sources, sinks); !status.isOk()) { return status; } RETURN_STATUS_IF_ERROR(checkAudioPatchEndpointsMatch(sources, sinks)); auto& patches = getConfig().patches; auto existing = patches.end(); Loading Loading @@ -834,13 +819,20 @@ ndk::ScopedAStatus Module::setAudioPatch(const AudioPatch& in_requested, AudioPa if (existing == patches.end()) { _aidl_return->id = getConfig().nextPatchId++; patches.push_back(*_aidl_return); existing = patches.begin() + (patches.size() - 1); } else { oldPatch = *existing; *existing = *_aidl_return; } registerPatch(*existing); updateStreamsConnectedState(oldPatch, *_aidl_return); patchesBackup = mPatches; registerPatch(*_aidl_return); if (auto status = updateStreamsConnectedState(oldPatch, *_aidl_return); !status.isOk()) { mPatches = std::move(*patchesBackup); if (existing == patches.end()) { patches.pop_back(); } else { *existing = oldPatch; } return status; } LOG(DEBUG) << __func__ << ": " << (oldPatch.id == 0 ? "created" : "updated") << " patch " << _aidl_return->toString(); Loading Loading @@ -992,8 +984,12 @@ ndk::ScopedAStatus Module::resetAudioPatch(int32_t in_patchId) { auto& patches = getConfig().patches; auto patchIt = findById<AudioPatch>(patches, in_patchId); if (patchIt != patches.end()) { auto patchesBackup = mPatches; cleanUpPatch(patchIt->id); updateStreamsConnectedState(*patchIt, AudioPatch{}); if (auto status = updateStreamsConnectedState(*patchIt, AudioPatch{}); !status.isOk()) { mPatches = std::move(patchesBackup); return status; } patches.erase(patchIt); LOG(DEBUG) << __func__ << ": erased patch " << in_patchId; return ndk::ScopedAStatus::ok(); Loading Loading @@ -1325,6 +1321,22 @@ bool Module::isMmapSupported() { return mIsMmapSupported.value(); } ndk::ScopedAStatus Module::createInputStream(const SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector<MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) { return createStreamInstance<StreamInStub>(result, sinkMetadata, std::move(context), microphones); } ndk::ScopedAStatus Module::createOutputStream(const SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional<AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) { return createStreamInstance<StreamOutStub>(result, sourceMetadata, std::move(context), offloadInfo); } ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort __unused) { LOG(VERBOSE) << __func__ << ": do nothing and return ok"; return ndk::ScopedAStatus::ok(); Loading
audio/aidl/default/Stream.cpp +30 −58 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() { case Tag::halReservedExit: if (const int32_t cookie = command.get<Tag::halReservedExit>(); cookie == mInternalCommandCookie) { mDriver->shutdown(); setClosed(); // This is an internal command, no need to reply. return Status::EXIT; Loading Loading @@ -364,6 +365,7 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() { case Tag::halReservedExit: if (const int32_t cookie = command.get<Tag::halReservedExit>(); cookie == mInternalCommandCookie) { mDriver->shutdown(); setClosed(); // This is an internal command, no need to reply. return Status::EXIT; Loading Loading @@ -567,8 +569,7 @@ bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* rep return !fatal; } template <class Metadata> StreamCommonImpl<Metadata>::~StreamCommonImpl() { StreamCommonImpl::~StreamCommonImpl() { if (!isClosed()) { LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak"; stopWorker(); Loading @@ -576,19 +577,16 @@ StreamCommonImpl<Metadata>::~StreamCommonImpl() { } } template <class Metadata> void StreamCommonImpl<Metadata>::createStreamCommon( ndk::ScopedAStatus StreamCommonImpl::initInstance( const std::shared_ptr<StreamCommonInterface>& delegate) { if (mCommon != nullptr) { LOG(FATAL) << __func__ << ": attempting to create the common interface twice"; } mCommon = ndk::SharedRefBase::make<StreamCommon>(delegate); mCommon = ndk::SharedRefBase::make<StreamCommonDelegator>(delegate); mCommonBinder = mCommon->asBinder(); AIBinder_setMinSchedulerPolicy(mCommonBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); return mWorker->start() ? ndk::ScopedAStatus::ok() : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon( ndk::ScopedAStatus StreamCommonImpl::getStreamCommonCommon( std::shared_ptr<IStreamCommon>* _aidl_return) { if (mCommon == nullptr) { LOG(FATAL) << __func__ << ": the common interface was not created"; Loading @@ -598,30 +596,26 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::getStreamCommon( return ndk::ScopedAStatus::ok(); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateHwAvSyncId(int32_t in_hwAvSyncId) { ndk::ScopedAStatus StreamCommonImpl::updateHwAvSyncId(int32_t in_hwAvSyncId) { LOG(DEBUG) << __func__ << ": id " << in_hwAvSyncId; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::getVendorParameters( ndk::ScopedAStatus StreamCommonImpl::getVendorParameters( const std::vector<std::string>& in_ids, std::vector<VendorParameter>* _aidl_return) { LOG(DEBUG) << __func__ << ": id count: " << in_ids.size(); (void)_aidl_return; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::setVendorParameters( ndk::ScopedAStatus StreamCommonImpl::setVendorParameters( const std::vector<VendorParameter>& in_parameters, bool in_async) { LOG(DEBUG) << __func__ << ": parameters count " << in_parameters.size() << ", async: " << in_async; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect( ndk::ScopedAStatus StreamCommonImpl::addEffect( const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) { if (in_effect == nullptr) { LOG(DEBUG) << __func__ << ": null effect"; Loading @@ -631,8 +625,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::addEffect( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect( ndk::ScopedAStatus StreamCommonImpl::removeEffect( const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) { if (in_effect == nullptr) { LOG(DEBUG) << __func__ << ": null effect"; Loading @@ -642,8 +635,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::removeEffect( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() { ndk::ScopedAStatus StreamCommonImpl::close() { LOG(DEBUG) << __func__; if (!isClosed()) { stopWorker(); Loading @@ -659,8 +651,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::close() { } } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::prepareToClose() { ndk::ScopedAStatus StreamCommonImpl::prepareToClose() { LOG(DEBUG) << __func__; if (!isClosed()) { return ndk::ScopedAStatus::ok(); Loading @@ -669,8 +660,7 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::prepareToClose() { return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } template <class Metadata> void StreamCommonImpl<Metadata>::stopWorker() { void StreamCommonImpl::stopWorker() { if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) { LOG(DEBUG) << __func__ << ": asking the worker to exit..."; auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>( Loading @@ -686,10 +676,12 @@ void StreamCommonImpl<Metadata>::stopWorker() { } } template <class Metadata> ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& metadata) { ndk::ScopedAStatus StreamCommonImpl::updateMetadataCommon(const Metadata& metadata) { LOG(DEBUG) << __func__; if (!isClosed()) { if (metadata.index() != mMetadata.index()) { LOG(FATAL) << __func__ << ": changing metadata variant is not allowed"; } mMetadata = metadata; return ndk::ScopedAStatus::ok(); } Loading @@ -697,12 +689,10 @@ ndk::ScopedAStatus StreamCommonImpl<Metadata>::updateMetadata(const Metadata& me return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } // static ndk::ScopedAStatus StreamIn::initInstance(const std::shared_ptr<StreamIn>& stream) { if (auto status = stream->init(); !status.isOk()) { return status; } stream->createStreamCommon(stream); ndk::ScopedAStatus StreamCommonImpl::setConnectedDevices( const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) { mWorker->setIsConnected(!devices.empty()); mConnectedDevices = devices; return ndk::ScopedAStatus::ok(); } Loading @@ -716,12 +706,8 @@ static std::map<AudioDevice, std::string> transformMicrophones( } } // namespace StreamIn::StreamIn(const SinkMetadata& sinkMetadata, StreamContext&& context, const DriverInterface::CreateInstance& createDriver, const StreamWorkerInterface::CreateInstance& createWorker, const std::vector<MicrophoneInfo>& microphones) : StreamCommonImpl<SinkMetadata>(sinkMetadata, std::move(context), createDriver, createWorker), mMicrophones(transformMicrophones(microphones)) { StreamIn::StreamIn(const std::vector<MicrophoneInfo>& microphones) : mMicrophones(transformMicrophones(microphones)) { LOG(DEBUG) << __func__; } Loading @@ -729,9 +715,9 @@ ndk::ScopedAStatus StreamIn::getActiveMicrophones( std::vector<MicrophoneDynamicInfo>* _aidl_return) { std::vector<MicrophoneDynamicInfo> result; std::vector<MicrophoneDynamicInfo::ChannelMapping> channelMapping{ getChannelCount(mContext.getChannelLayout()), getChannelCount(getContext().getChannelLayout()), MicrophoneDynamicInfo::ChannelMapping::DIRECT}; for (auto it = mConnectedDevices.begin(); it != mConnectedDevices.end(); ++it) { for (auto it = getConnectedDevices().begin(); it != getConnectedDevices().end(); ++it) { if (auto micIt = mMicrophones.find(*it); micIt != mMicrophones.end()) { MicrophoneDynamicInfo dynMic; dynMic.id = micIt->second; Loading Loading @@ -777,22 +763,8 @@ ndk::ScopedAStatus StreamIn::setHwGain(const std::vector<float>& in_channelGains return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } // static ndk::ScopedAStatus StreamOut::initInstance(const std::shared_ptr<StreamOut>& stream) { if (auto status = stream->init(); !status.isOk()) { return status; } stream->createStreamCommon(stream); return ndk::ScopedAStatus::ok(); } StreamOut::StreamOut(const SourceMetadata& sourceMetadata, StreamContext&& context, const DriverInterface::CreateInstance& createDriver, const StreamWorkerInterface::CreateInstance& createWorker, const std::optional<AudioOffloadInfo>& offloadInfo) : StreamCommonImpl<SourceMetadata>(sourceMetadata, std::move(context), createDriver, createWorker), mOffloadInfo(offloadInfo) { StreamOut::StreamOut(const std::optional<AudioOffloadInfo>& offloadInfo) : mOffloadInfo(offloadInfo) { LOG(DEBUG) << __func__; } Loading