Merge "audio: Fix connection between alsa_device_profile and _proxy" into main am: f69e0b6795 am: 4991074eba

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

Change-Id: If5dd74047973428e18cc83d51ab4eae5baca9a77
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Mikhail Naganov 2023-09-25 18:13:49 +00:00 committed by Automerger Merge Worker
commit e6e1a30685
4 changed files with 58 additions and 49 deletions

View file

@ -39,13 +39,14 @@ ndk::ScopedAStatus ModuleAlsa::populateConnectedDevicePort(AudioPort* audioPort)
if (!deviceProfile.has_value()) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
auto profile = alsa::readAlsaDeviceInfo(*deviceProfile);
if (!profile.has_value()) {
auto proxy = alsa::readAlsaDeviceInfo(*deviceProfile);
if (proxy.get() == nullptr) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
std::vector<AudioChannelLayout> channels = alsa::getChannelMasksFromProfile(&profile.value());
std::vector<int> sampleRates = alsa::getSampleRatesFromProfile(&profile.value());
alsa_device_profile* profile = proxy.getProfile();
std::vector<AudioChannelLayout> channels = alsa::getChannelMasksFromProfile(profile);
std::vector<int> sampleRates = alsa::getSampleRatesFromProfile(profile);
for (size_t i = 0; i < std::min(MAX_PROFILE_FORMATS, AUDIO_PORT_MAX_AUDIO_PROFILES) &&
profile->formats[i] != PCM_FORMAT_INVALID;

View file

@ -83,7 +83,7 @@ StreamAlsa::StreamAlsa(StreamContext* context, const Metadata& metadata, int rea
proxy = alsa::openProxyForAttachedDevice(
device, const_cast<struct pcm_config*>(&mConfig.value()), mBufferSizeFrames);
}
if (!proxy) {
if (proxy.get() == nullptr) {
return ::android::NO_INIT;
}
alsaDeviceProxies.push_back(std::move(proxy));

View file

@ -37,6 +37,23 @@ using aidl::android::media::audio::common::PcmType;
namespace aidl::android::hardware::audio::core::alsa {
DeviceProxy::DeviceProxy() : mProfile(nullptr), mProxy(nullptr, alsaProxyDeleter) {}
DeviceProxy::DeviceProxy(const DeviceProfile& deviceProfile)
: mProfile(new alsa_device_profile), mProxy(new alsa_device_proxy, alsaProxyDeleter) {
profile_init(mProfile.get(), deviceProfile.direction);
mProfile->card = deviceProfile.card;
mProfile->device = deviceProfile.device;
memset(mProxy.get(), 0, sizeof(alsa_device_proxy));
}
void DeviceProxy::alsaProxyDeleter(alsa_device_proxy* proxy) {
if (proxy != nullptr) {
proxy_close(proxy);
delete proxy;
}
}
namespace {
using AudioChannelCountToMaskMap = std::map<unsigned int, AudioChannelLayout>;
@ -261,39 +278,24 @@ std::vector<int> getSampleRatesFromProfile(const alsa_device_profile* profile) {
return sampleRates;
}
DeviceProxy makeDeviceProxy() {
DeviceProxy proxy(new alsa_device_proxy, [](alsa_device_proxy* proxy) {
if (proxy != nullptr) {
proxy_close(proxy);
delete proxy;
}
});
memset(proxy.get(), 0, sizeof(alsa_device_proxy));
return proxy;
}
DeviceProxy openProxyForAttachedDevice(const DeviceProfile& deviceProfile,
struct pcm_config* pcmConfig, size_t bufferFrameCount) {
if (deviceProfile.isExternal) {
LOG(FATAL) << __func__ << ": called for an external device, address=" << deviceProfile;
}
alsa_device_profile profile;
profile_init(&profile, deviceProfile.direction);
profile.card = deviceProfile.card;
profile.device = deviceProfile.device;
if (!profile_fill_builtin_device_info(&profile, pcmConfig, bufferFrameCount)) {
DeviceProxy proxy(deviceProfile);
if (!profile_fill_builtin_device_info(proxy.getProfile(), pcmConfig, bufferFrameCount)) {
LOG(FATAL) << __func__ << ": failed to init for built-in device, address=" << deviceProfile;
}
auto proxy = makeDeviceProxy();
if (int err = proxy_prepare_from_default_config(proxy.get(), &profile); err != 0) {
if (int err = proxy_prepare_from_default_config(proxy.get(), proxy.getProfile()); err != 0) {
LOG(FATAL) << __func__ << ": fail to prepare for device address=" << deviceProfile
<< " error=" << err;
return nullptr;
return DeviceProxy();
}
if (int err = proxy_open(proxy.get()); err != 0) {
LOG(ERROR) << __func__ << ": failed to open device, address=" << deviceProfile
<< " error=" << err;
return nullptr;
return DeviceProxy();
}
return proxy;
}
@ -303,42 +305,36 @@ DeviceProxy openProxyForExternalDevice(const DeviceProfile& deviceProfile,
if (!deviceProfile.isExternal) {
LOG(FATAL) << __func__ << ": called for an attached device, address=" << deviceProfile;
}
auto profile = readAlsaDeviceInfo(deviceProfile);
if (!profile.has_value()) {
LOG(ERROR) << __func__ << ": unable to read device info, device address=" << deviceProfile;
return nullptr;
auto proxy = readAlsaDeviceInfo(deviceProfile);
if (proxy.get() == nullptr) {
return proxy;
}
auto proxy = makeDeviceProxy();
if (int err = proxy_prepare(proxy.get(), &profile.value(), pcmConfig, requireExactMatch);
if (int err = proxy_prepare(proxy.get(), proxy.getProfile(), pcmConfig, requireExactMatch);
err != 0) {
LOG(ERROR) << __func__ << ": fail to prepare for device address=" << deviceProfile
<< " error=" << err;
return nullptr;
return DeviceProxy();
}
if (int err = proxy_open(proxy.get()); err != 0) {
LOG(ERROR) << __func__ << ": failed to open device, address=" << deviceProfile
<< " error=" << err;
return nullptr;
return DeviceProxy();
}
return proxy;
}
std::optional<alsa_device_profile> readAlsaDeviceInfo(const DeviceProfile& deviceProfile) {
alsa_device_profile profile;
profile_init(&profile, deviceProfile.direction);
profile.card = deviceProfile.card;
profile.device = deviceProfile.device;
if (!profile_read_device_info(&profile)) {
LOG(ERROR) << __func__ << ": failed to read device info, card=" << profile.card
<< ", device=" << profile.device;
return std::nullopt;
DeviceProxy readAlsaDeviceInfo(const DeviceProfile& deviceProfile) {
DeviceProxy proxy(deviceProfile);
if (!profile_read_device_info(proxy.getProfile())) {
LOG(ERROR) << __func__ << ": unable to read device info, device address=" << deviceProfile;
return DeviceProxy();
}
return profile;
return proxy;
}
void resetTransferredFrames(DeviceProxy& proxy, uint64_t frames) {
if (proxy != nullptr) {
proxy->transferred = frames;
if (proxy.get() != nullptr) {
proxy.get()->transferred = frames;
}
}

View file

@ -43,8 +43,21 @@ struct DeviceProfile {
bool isExternal;
};
std::ostream& operator<<(std::ostream& os, const DeviceProfile& device);
using DeviceProxyDeleter = std::function<void(alsa_device_proxy*)>;
using DeviceProxy = std::unique_ptr<alsa_device_proxy, DeviceProxyDeleter>;
class DeviceProxy {
public:
DeviceProxy(); // Constructs a "null" proxy.
explicit DeviceProxy(const DeviceProfile& deviceProfile);
alsa_device_profile* getProfile() { return mProfile.get(); }
alsa_device_proxy* get() { return mProxy.get(); }
private:
static void alsaProxyDeleter(alsa_device_proxy* proxy);
using AlsaProxy = std::unique_ptr<alsa_device_proxy, decltype(alsaProxyDeleter)*>;
std::unique_ptr<alsa_device_profile> mProfile;
AlsaProxy mProxy;
};
::aidl::android::media::audio::common::AudioChannelLayout getChannelLayoutMaskFromChannelCount(
unsigned int channelCount, int isInput);
@ -60,12 +73,11 @@ std::optional<DeviceProfile> getDeviceProfile(
const ::aidl::android::media::audio::common::AudioPort& audioPort);
std::optional<struct pcm_config> getPcmConfig(const StreamContext& context, bool isInput);
std::vector<int> getSampleRatesFromProfile(const alsa_device_profile* profile);
DeviceProxy makeDeviceProxy();
DeviceProxy openProxyForAttachedDevice(const DeviceProfile& deviceProfile,
struct pcm_config* pcmConfig, size_t bufferFrameCount);
DeviceProxy openProxyForExternalDevice(const DeviceProfile& deviceProfile,
struct pcm_config* pcmConfig, bool requireExactMatch);
std::optional<alsa_device_profile> readAlsaDeviceInfo(const DeviceProfile& deviceProfile);
DeviceProxy readAlsaDeviceInfo(const DeviceProfile& deviceProfile);
void resetTransferredFrames(DeviceProxy& proxy, uint64_t frames);
::aidl::android::media::audio::common::AudioFormatDescription