audio: Allow Module subclasses to customize stream creation am: 9d16a6ac10 am: 7e18503e54

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2639437

Change-Id: I5a486e7dade405e2c58f94de2566c67f0144178f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Mikhail Naganov
2023-06-27 19:55:32 +00:00
committed by Automerger Merge Worker
9 changed files with 88 additions and 142 deletions

View File

@@ -30,7 +30,6 @@
#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"
@@ -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:
@@ -687,8 +662,8 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar
nullptr, nullptr, &context));
context.fillDescriptor(&_aidl_return->desc);
std::shared_ptr<StreamIn> stream;
RETURN_STATUS_IF_ERROR(getStreamInCreator(mType)(in_args.sinkMetadata, std::move(context),
mConfig->microphones, &stream));
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(
@@ -733,8 +708,8 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_
in_args.eventCallback, &context));
context.fillDescriptor(&_aidl_return->desc);
std::shared_ptr<StreamOut> stream;
RETURN_STATUS_IF_ERROR(getStreamOutCreator(mType)(in_args.sourceMetadata, std::move(context),
in_args.offloadInfo, &stream));
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(
@@ -1346,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();

View File

@@ -87,38 +87,10 @@ StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context)
void StreamStub::shutdown() {}
// static
ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result) {
std::shared_ptr<StreamIn> stream =
ndk::SharedRefBase::make<StreamInStub>(sinkMetadata, std::move(context), microphones);
if (auto status = stream->initInstance(stream); !status.isOk()) {
return status;
}
*result = std::move(stream);
return ndk::ScopedAStatus::ok();
}
StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context,
const std::vector<MicrophoneInfo>& microphones)
: StreamStub(sinkMetadata, std::move(context)), StreamIn(microphones) {}
// static
ndk::ScopedAStatus StreamOutStub::createInstance(const SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<AudioOffloadInfo>& offloadInfo,
std::shared_ptr<StreamOut>* result) {
std::shared_ptr<StreamOut> stream = ndk::SharedRefBase::make<StreamOutStub>(
sourceMetadata, std::move(context), offloadInfo);
if (auto status = stream->initInstance(stream); !status.isOk()) {
return status;
}
*result = std::move(stream);
return ndk::ScopedAStatus::ok();
}
StreamOutStub::StreamOutStub(const SourceMetadata& sourceMetadata, StreamContext&& context,
const std::optional<AudioOffloadInfo>& offloadInfo)
: StreamStub(sourceMetadata, std::move(context)), StreamOut(offloadInfo) {}

View File

@@ -33,11 +33,9 @@ class Module : public BnModule {
static constexpr int32_t kLatencyMs = 10;
enum Type : int { DEFAULT, R_SUBMIX, USB };
explicit Module(Type type) : mType(type) {}
static std::shared_ptr<Module> createInstance(Type type);
static StreamIn::CreateInstance getStreamInCreator(Type type);
static StreamOut::CreateInstance getStreamOutCreator(Type type);
explicit Module(Type type) : mType(type) {}
protected:
// The vendor extension done via inheritance can override interface methods and augment
@@ -182,6 +180,17 @@ class Module : public BnModule {
protected:
// The following virtual functions are intended for vendor extension via inheritance.
virtual ndk::ScopedAStatus createInputStream(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result);
virtual ndk::ScopedAStatus createOutputStream(
const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
offloadInfo,
std::shared_ptr<StreamOut>* result);
// If the module is unable to populate the connected device port correctly, the returned error
// code must correspond to the errors of `IModule.connectedExternalDevice` method.
virtual ndk::ScopedAStatus populateConnectedDevicePort(

View File

@@ -32,6 +32,17 @@ class ModuleUsb : public Module {
ndk::ScopedAStatus setMicMute(bool in_mute) override;
// Module interfaces
ndk::ScopedAStatus createInputStream(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result) override;
ndk::ScopedAStatus createOutputStream(
const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
offloadInfo,
std::shared_ptr<StreamOut>* result) override;
ndk::ScopedAStatus populateConnectedDevicePort(
::aidl::android::media::audio::common::AudioPort* audioPort) override;
ndk::ScopedAStatus checkAudioPatchEndpointsMatch(

View File

@@ -25,6 +25,7 @@
#include <variant>
#include <StreamWorker.h>
#include <Utils.h>
#include <aidl/android/hardware/audio/common/SinkMetadata.h>
#include <aidl/android/hardware/audio/common/SourceMetadata.h>
#include <aidl/android/hardware/audio/core/BnStreamCommon.h>
@@ -37,6 +38,7 @@
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
#include <aidl/android/media/audio/common/MicrophoneInfo.h>
#include <error/expected_utils.h>
#include <fmq/AidlMessageQueue.h>
#include <system/thread_defs.h>
#include <utils/Errors.h>
@@ -482,13 +484,6 @@ class StreamIn : virtual public StreamCommonInterface, public BnStreamIn {
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
const std::map<::aidl::android::media::audio::common::AudioDevice, std::string> mMicrophones;
public:
using CreateInstance = std::function<ndk::ScopedAStatus(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result)>;
};
class StreamOut : virtual public StreamCommonInterface, public BnStreamOut {
@@ -531,16 +526,20 @@ class StreamOut : virtual public StreamCommonInterface, public BnStreamOut {
std::optional<::aidl::android::media::audio::common::AudioOffloadInfo> mOffloadInfo;
std::optional<::aidl::android::hardware::audio::common::AudioOffloadMetadata> mOffloadMetadata;
public:
using CreateInstance = std::function<ndk::ScopedAStatus(
const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
offloadInfo,
std::shared_ptr<StreamOut>* result)>;
};
// The recommended way to create a stream instance.
// 'StreamImpl' is the concrete stream implementation, 'StreamInOrOut' is either 'StreamIn' or
// 'StreamOut', the rest are the arguments forwarded to the constructor of 'StreamImpl'.
template <class StreamImpl, class StreamInOrOut, class... Args>
ndk::ScopedAStatus createStreamInstance(std::shared_ptr<StreamInOrOut>* result, Args&&... args) {
std::shared_ptr<StreamInOrOut> stream =
::ndk::SharedRefBase::make<StreamImpl>(std::forward<Args>(args)...);
RETURN_STATUS_IF_ERROR(stream->initInstance(stream));
*result = std::move(stream);
return ndk::ScopedAStatus::ok();
}
class StreamWrapper {
public:
explicit StreamWrapper(const std::shared_ptr<StreamIn>& streamIn)

View File

@@ -42,13 +42,6 @@ class StreamStub : public StreamCommonImpl {
class StreamInStub final : public StreamStub, public StreamIn {
public:
static ndk::ScopedAStatus createInstance(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result);
private:
friend class ndk::SharedRefBase;
StreamInStub(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
@@ -58,14 +51,6 @@ class StreamInStub final : public StreamStub, public StreamIn {
class StreamOutStub final : public StreamStub, public StreamOut {
public:
static ndk::ScopedAStatus createInstance(
const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
offloadInfo,
std::shared_ptr<StreamOut>* result);
private:
friend class ndk::SharedRefBase;
StreamOutStub(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
StreamContext&& context,

View File

@@ -60,41 +60,28 @@ class StreamUsb : public StreamCommonImpl {
};
class StreamInUsb final : public StreamUsb, public StreamIn {
ndk::ScopedAStatus getActiveMicrophones(
std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
override;
public:
static ndk::ScopedAStatus createInstance(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result);
private:
friend class ndk::SharedRefBase;
StreamInUsb(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
private:
ndk::ScopedAStatus getActiveMicrophones(
std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
override;
};
class StreamOutUsb final : public StreamUsb, public StreamOut {
public:
static ndk::ScopedAStatus createInstance(
const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
offloadInfo,
std::shared_ptr<StreamOut>* result);
private:
friend class ndk::SharedRefBase;
StreamOutUsb(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
offloadInfo);
private:
ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;

View File

@@ -25,11 +25,14 @@
#include "UsbAlsaMixerControl.h"
#include "UsbAlsaUtils.h"
#include "core-impl/ModuleUsb.h"
#include "core-impl/StreamUsb.h"
extern "C" {
#include "alsa_device_profile.h"
}
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceDescription;
@@ -37,10 +40,12 @@ 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::MicrophoneInfo;
namespace aidl::android::hardware::audio::core {
@@ -97,6 +102,25 @@ ndk::ScopedAStatus ModuleUsb::setMicMute(bool in_mute __unused) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
ndk::ScopedAStatus ModuleUsb::createInputStream(const SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result) {
return createStreamInstance<StreamInUsb>(result, sinkMetadata, std::move(context), microphones);
}
ndk::ScopedAStatus ModuleUsb::createOutputStream(const SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<AudioOffloadInfo>& offloadInfo,
std::shared_ptr<StreamOut>* result) {
if (offloadInfo.has_value()) {
LOG(ERROR) << __func__ << ": offload is not supported";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
return createStreamInstance<StreamOutUsb>(result, sourceMetadata, std::move(context),
offloadInfo);
}
ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort) {
if (audioPort->ext.getTag() != AudioPortExt::Tag::device) {
LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a device port";

View File

@@ -205,20 +205,6 @@ void StreamUsb::shutdown() {}
return ::android::OK;
}
// static
ndk::ScopedAStatus StreamInUsb::createInstance(const SinkMetadata& sinkMetadata,
StreamContext&& context,
const std::vector<MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result) {
std::shared_ptr<StreamIn> stream =
ndk::SharedRefBase::make<StreamInUsb>(sinkMetadata, std::move(context), microphones);
if (auto status = stream->initInstance(stream); !status.isOk()) {
return status;
}
*result = std::move(stream);
return ndk::ScopedAStatus::ok();
}
StreamInUsb::StreamInUsb(const SinkMetadata& sinkMetadata, StreamContext&& context,
const std::vector<MicrophoneInfo>& microphones)
: StreamUsb(sinkMetadata, std::move(context)), StreamIn(microphones) {}
@@ -229,24 +215,6 @@ ndk::ScopedAStatus StreamInUsb::getActiveMicrophones(
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
// static
ndk::ScopedAStatus StreamOutUsb::createInstance(const SourceMetadata& sourceMetadata,
StreamContext&& context,
const std::optional<AudioOffloadInfo>& offloadInfo,
std::shared_ptr<StreamOut>* result) {
if (offloadInfo.has_value()) {
LOG(ERROR) << __func__ << ": offload is not supported";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
std::shared_ptr<StreamOut> stream =
ndk::SharedRefBase::make<StreamOutUsb>(sourceMetadata, std::move(context), offloadInfo);
if (auto status = stream->initInstance(stream); !status.isOk()) {
return status;
}
*result = std::move(stream);
return ndk::ScopedAStatus::ok();
}
StreamOutUsb::StreamOutUsb(const SourceMetadata& sourceMetadata, StreamContext&& context,
const std::optional<AudioOffloadInfo>& offloadInfo)
: StreamUsb(sourceMetadata, std::move(context)), StreamOut(offloadInfo) {